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