1 package org.simantics.scl.compiler.internal.codegen.utils;
3 import java.util.ArrayDeque;
4 import java.util.ArrayList;
6 import org.simantics.scl.compiler.constants.Constant;
7 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
8 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
9 import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont;
10 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
11 import org.simantics.scl.compiler.internal.codegen.references.Val;
12 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
13 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
14 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
18 import gnu.trove.map.hash.THashMap;
19 import gnu.trove.set.hash.THashSet;
21 public class PrintingContext {
23 THashMap<Object, String> names = new THashMap<Object, String>();
26 StringBuilder stringBuilder = new StringBuilder();
27 TypeUnparsingContext typeUnparsingContext =
28 new TypeUnparsingContext();
30 THashMap<BoundVar, LetApply> inlineExpressions = new THashMap<BoundVar, LetApply>();
32 private static class BlockEntry {
33 ArrayDeque<SSABlock> blockQueue = new ArrayDeque<SSABlock>();
34 THashSet<SSABlock> blockSet = new THashSet<SSABlock>();
36 private ArrayList<BlockEntry> blockQueueStack = new ArrayList<BlockEntry>(2);
38 public void pushBlockQueue() {
39 blockQueueStack.add(new BlockEntry());
42 public void popBlockQueue() {
43 blockQueueStack.remove(blockQueueStack.size()-1);
46 public SSABlock pollBlock() {
47 BlockEntry entry = blockQueueStack.get(blockQueueStack.size()-1);
48 return entry.blockQueue.poll();
51 public void addBlock(SSABlock block) {
52 BlockEntry entry = blockQueueStack.get(blockQueueStack.size()-1);
53 if(entry.blockSet.add(block))
54 entry.blockQueue.add(block);
57 public void append(Constant val) {
58 append(val.toString());
61 public void append(ReturnCont val) {
65 public void append(Type type) {
66 append(type.toString(typeUnparsingContext));
69 public void append(Type[] types) {
72 for(Type type : types) {
82 public void append(ValRef ref) {
83 append(ref.getBinding());
84 if(ref.getTypeParameters().length > 0) {
86 for(int i=0;i<ref.getTypeParameters().length;++i) {
89 append(ref.getTypeParameters()[i]);
95 public void append(Val val) {
96 if(val instanceof Constant) {
97 append((Constant)val);
99 else if(val instanceof BoundVar) {
100 BoundVar var = (BoundVar)val;
102 LetApply inlineExpression = inlineExpressions.remove(var);
103 if(inlineExpression != null) {
105 inlineExpression.bodyToString(this);
109 String label = var.getLabel();
111 label = getName(val);
116 append(getName(val));
119 append(val.getType());
123 public void append(ContRef ref) {
124 append(ref.getBinding());
127 public void append(Cont cont) {
128 if(cont instanceof ReturnCont)
129 append((ReturnCont)cont);
131 append("[" + getName(cont) + "]");
134 private String getName(Object var) {
137 String name = names.get(var);
139 name = idToName(nameId++);
140 names.put(var, name);
145 private static final int alphabetCount = 'z'-'a'+1;
147 private static String idToName(int id) {
148 String name = Character.toString((char)('a' + id % alphabetCount));
151 name = idToName(id-1) + name;
155 public PrintingContext append(String str) {
156 stringBuilder.append(str);
160 public PrintingContext append(char c) {
161 stringBuilder.append(c);
165 public void indentation() {
166 for(int i=0;i<indentation;++i)
167 stringBuilder.append(" ");
171 public String toString() {
172 return stringBuilder.toString();
175 public void indent() {
179 public void dedent() {
183 public void setErrorMarker(Object errorMarker) {
184 this.errorMarker = errorMarker;
187 public Object getErrorMarker() {
191 public void addInlineExpression(BoundVar target, LetApply letApply) {
192 inlineExpressions.put(target, letApply);