]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / PrintingContext.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java
new file mode 100644 (file)
index 0000000..4a8969f
--- /dev/null
@@ -0,0 +1,195 @@
+package org.simantics.scl.compiler.internal.codegen.utils;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+import java.util.ArrayDeque;\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
+\r
+public class PrintingContext {\r
+\r
+    THashMap<Object, String> names = new THashMap<Object, String>(); \r
+    int nameId = 0;\r
+    int indentation = 0;\r
+    StringBuilder stringBuilder = new StringBuilder();\r
+    TypeUnparsingContext typeUnparsingContext = \r
+            new TypeUnparsingContext();\r
+    Object errorMarker;\r
+    THashMap<BoundVar, LetApply> inlineExpressions = new THashMap<BoundVar, LetApply>(); \r
+    \r
+    private static class BlockEntry {        \r
+        ArrayDeque<SSABlock> blockQueue = new ArrayDeque<SSABlock>(); \r
+        THashSet<SSABlock> blockSet = new THashSet<SSABlock>();\r
+    }  \r
+    private ArrayList<BlockEntry> blockQueueStack = new ArrayList<BlockEntry>(2); \r
+    \r
+    public void pushBlockQueue() {\r
+        blockQueueStack.add(new BlockEntry());\r
+    }\r
+    \r
+    public void popBlockQueue() {\r
+        blockQueueStack.remove(blockQueueStack.size()-1);\r
+    }\r
+    \r
+    public SSABlock pollBlock() {\r
+        BlockEntry entry = blockQueueStack.get(blockQueueStack.size()-1);\r
+        return entry.blockQueue.poll();\r
+    }\r
+    \r
+    public void addBlock(SSABlock block) {\r
+        BlockEntry entry = blockQueueStack.get(blockQueueStack.size()-1);\r
+        if(entry.blockSet.add(block))\r
+            entry.blockQueue.add(block);\r
+    }\r
+    \r
+    public void append(Constant val) {\r
+        append(val.toString());\r
+    }\r
+    \r
+    public void append(ReturnCont val) {\r
+        append("return");\r
+    }\r
+    \r
+    public void append(Type type) {\r
+        append(type.toString(typeUnparsingContext));\r
+    }\r
+    \r
+    public void append(Type[] types) {\r
+        append('[');\r
+        boolean first = true;\r
+        for(Type type : types) {\r
+            if(first)\r
+                first = false;\r
+            else\r
+                append(", ");\r
+            append(type);\r
+        }\r
+        append(']');\r
+    }\r
+    \r
+    public void append(ValRef ref) {\r
+        append(ref.getBinding());\r
+        if(ref.getTypeParameters().length > 0) {\r
+            append("<");\r
+            for(int i=0;i<ref.getTypeParameters().length;++i) {\r
+                if(i > 0)\r
+                    append(",");\r
+                append(ref.getTypeParameters()[i]);\r
+            }\r
+            append(">");\r
+        }\r
+    }\r
+    \r
+    public void append(Val val) {\r
+        if(val instanceof Constant) {\r
+            append((Constant)val);\r
+        }\r
+        else if(val instanceof BoundVar) {\r
+            BoundVar var = (BoundVar)val;\r
+            \r
+            LetApply inlineExpression = inlineExpressions.remove(var);\r
+            if(inlineExpression != null) {\r
+                append('(');\r
+                inlineExpression.bodyToString(this);\r
+                append(')');\r
+            }\r
+            else {\r
+                String label = var.getLabel();\r
+                if(label == null)\r
+                    label = getName(val);\r
+                append(label);\r
+            }\r
+        }\r
+        else {\r
+            append(getName(val));\r
+        }\r
+        /*append('{');\r
+        append(val.getType());\r
+        append('}');*/\r
+    }\r
+\r
+    public void append(ContRef ref) {\r
+        append(ref.getBinding());\r
+    }\r
+    \r
+    public void append(Cont cont) {\r
+        if(cont instanceof ReturnCont)\r
+            append((ReturnCont)cont);\r
+        else\r
+            append("[" + getName(cont) + "]");\r
+    }\r
+\r
+    private String getName(Object var) {\r
+        if(var == null)\r
+            return "NULL";\r
+        String name = names.get(var);\r
+        if(name == null) {\r
+            name = idToName(nameId++);\r
+            names.put(var, name);\r
+        }\r
+        return name;\r
+    }\r
+\r
+    private static final int alphabetCount = 'z'-'a'+1;\r
+    \r
+    private static String idToName(int id) {\r
+        String name = Character.toString((char)('a' + id % alphabetCount));\r
+        id /= alphabetCount;\r
+        if(id > 0)\r
+            name = idToName(id-1) + name;\r
+        return name;\r
+    }\r
+    \r
+    public PrintingContext append(String str) {\r
+        stringBuilder.append(str);\r
+        return this;\r
+    }\r
+    \r
+    public PrintingContext append(char c) {\r
+        stringBuilder.append(c);\r
+        return this;\r
+    }\r
+    \r
+    public void indentation() {\r
+        for(int i=0;i<indentation;++i)\r
+            stringBuilder.append("    ");\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        return stringBuilder.toString();\r
+    }\r
+\r
+    public void indent() {\r
+        ++indentation;\r
+    }\r
+\r
+    public void dedent() {\r
+        --indentation;\r
+    }\r
+\r
+    public void setErrorMarker(Object errorMarker) {\r
+        this.errorMarker = errorMarker;                \r
+    }\r
+    \r
+    public Object getErrorMarker() {\r
+        return errorMarker;\r
+    }\r
+\r
+    public void addInlineExpression(BoundVar target, LetApply letApply) {\r
+        inlineExpressions.put(target, letApply);\r
+    }\r
+\r
+}\r