]> gerrit.simantics Code Review - simantics/platform.git/blob
4a8969f14a835345bff004bf7eb899cd4549939d
[simantics/platform.git] /
1 package org.simantics.scl.compiler.internal.codegen.utils;\r
2 \r
3 import gnu.trove.map.hash.THashMap;\r
4 import gnu.trove.set.hash.THashSet;\r
5 \r
6 import java.util.ArrayDeque;\r
7 import java.util.ArrayList;\r
8 \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
20 \r
21 public class PrintingContext {\r
22 \r
23     THashMap<Object, String> names = new THashMap<Object, String>(); \r
24     int nameId = 0;\r
25     int indentation = 0;\r
26     StringBuilder stringBuilder = new StringBuilder();\r
27     TypeUnparsingContext typeUnparsingContext = \r
28             new TypeUnparsingContext();\r
29     Object errorMarker;\r
30     THashMap<BoundVar, LetApply> inlineExpressions = new THashMap<BoundVar, LetApply>(); \r
31     \r
32     private static class BlockEntry {        \r
33         ArrayDeque<SSABlock> blockQueue = new ArrayDeque<SSABlock>(); \r
34         THashSet<SSABlock> blockSet = new THashSet<SSABlock>();\r
35     }  \r
36     private ArrayList<BlockEntry> blockQueueStack = new ArrayList<BlockEntry>(2); \r
37     \r
38     public void pushBlockQueue() {\r
39         blockQueueStack.add(new BlockEntry());\r
40     }\r
41     \r
42     public void popBlockQueue() {\r
43         blockQueueStack.remove(blockQueueStack.size()-1);\r
44     }\r
45     \r
46     public SSABlock pollBlock() {\r
47         BlockEntry entry = blockQueueStack.get(blockQueueStack.size()-1);\r
48         return entry.blockQueue.poll();\r
49     }\r
50     \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
55     }\r
56     \r
57     public void append(Constant val) {\r
58         append(val.toString());\r
59     }\r
60     \r
61     public void append(ReturnCont val) {\r
62         append("return");\r
63     }\r
64     \r
65     public void append(Type type) {\r
66         append(type.toString(typeUnparsingContext));\r
67     }\r
68     \r
69     public void append(Type[] types) {\r
70         append('[');\r
71         boolean first = true;\r
72         for(Type type : types) {\r
73             if(first)\r
74                 first = false;\r
75             else\r
76                 append(", ");\r
77             append(type);\r
78         }\r
79         append(']');\r
80     }\r
81     \r
82     public void append(ValRef ref) {\r
83         append(ref.getBinding());\r
84         if(ref.getTypeParameters().length > 0) {\r
85             append("<");\r
86             for(int i=0;i<ref.getTypeParameters().length;++i) {\r
87                 if(i > 0)\r
88                     append(",");\r
89                 append(ref.getTypeParameters()[i]);\r
90             }\r
91             append(">");\r
92         }\r
93     }\r
94     \r
95     public void append(Val val) {\r
96         if(val instanceof Constant) {\r
97             append((Constant)val);\r
98         }\r
99         else if(val instanceof BoundVar) {\r
100             BoundVar var = (BoundVar)val;\r
101             \r
102             LetApply inlineExpression = inlineExpressions.remove(var);\r
103             if(inlineExpression != null) {\r
104                 append('(');\r
105                 inlineExpression.bodyToString(this);\r
106                 append(')');\r
107             }\r
108             else {\r
109                 String label = var.getLabel();\r
110                 if(label == null)\r
111                     label = getName(val);\r
112                 append(label);\r
113             }\r
114         }\r
115         else {\r
116             append(getName(val));\r
117         }\r
118         /*append('{');\r
119         append(val.getType());\r
120         append('}');*/\r
121     }\r
122 \r
123     public void append(ContRef ref) {\r
124         append(ref.getBinding());\r
125     }\r
126     \r
127     public void append(Cont cont) {\r
128         if(cont instanceof ReturnCont)\r
129             append((ReturnCont)cont);\r
130         else\r
131             append("[" + getName(cont) + "]");\r
132     }\r
133 \r
134     private String getName(Object var) {\r
135         if(var == null)\r
136             return "NULL";\r
137         String name = names.get(var);\r
138         if(name == null) {\r
139             name = idToName(nameId++);\r
140             names.put(var, name);\r
141         }\r
142         return name;\r
143     }\r
144 \r
145     private static final int alphabetCount = 'z'-'a'+1;\r
146     \r
147     private static String idToName(int id) {\r
148         String name = Character.toString((char)('a' + id % alphabetCount));\r
149         id /= alphabetCount;\r
150         if(id > 0)\r
151             name = idToName(id-1) + name;\r
152         return name;\r
153     }\r
154     \r
155     public PrintingContext append(String str) {\r
156         stringBuilder.append(str);\r
157         return this;\r
158     }\r
159     \r
160     public PrintingContext append(char c) {\r
161         stringBuilder.append(c);\r
162         return this;\r
163     }\r
164     \r
165     public void indentation() {\r
166         for(int i=0;i<indentation;++i)\r
167             stringBuilder.append("    ");\r
168     }\r
169     \r
170     @Override\r
171     public String toString() {\r
172         return stringBuilder.toString();\r
173     }\r
174 \r
175     public void indent() {\r
176         ++indentation;\r
177     }\r
178 \r
179     public void dedent() {\r
180         --indentation;\r
181     }\r
182 \r
183     public void setErrorMarker(Object errorMarker) {\r
184         this.errorMarker = errorMarker;                \r
185     }\r
186     \r
187     public Object getErrorMarker() {\r
188         return errorMarker;\r
189     }\r
190 \r
191     public void addInlineExpression(BoundVar target, LetApply letApply) {\r
192         inlineExpressions.put(target, letApply);\r
193     }\r
194 \r
195 }\r