]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / writer / CodeWriter.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java
new file mode 100644 (file)
index 0000000..f11babe
--- /dev/null
@@ -0,0 +1,146 @@
+package org.simantics.scl.compiler.internal.codegen.writer;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\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.SSAFunction;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+import org.simantics.scl.compiler.types.util.MultiFunction;\r
+\r
+public class CodeWriter {\r
+\r
+    ModuleWriter moduleWriter;\r
+    SSABlock block;\r
+    \r
+    CodeWriter(ModuleWriter moduleWriter, SSABlock block) {\r
+        this.moduleWriter = moduleWriter;\r
+        this.block = block;\r
+    }\r
+\r
+    public IVal apply(int lineNumber, IVal function, IVal ... parameters) {\r
+        try {\r
+            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
+            return applyWithEffect(lineNumber,\r
+                    mfun.effect,\r
+                    mfun.returnType,\r
+                    function, parameters);\r
+        } catch (MatchException e) {\r
+            throw new InternalCompilerError(e);\r
+        }\r
+    }\r
+    \r
+    public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {\r
+        try {\r
+            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
+            if(!Types.equals(effect, mfun.effect))\r
+                throw new InternalCompilerError();\r
+            if(!Types.equals(returnType, mfun.returnType))\r
+                throw new InternalCompilerError();\r
+        } catch (MatchException e) {\r
+            throw new InternalCompilerError(e);\r
+        }            \r
+        return applyWithEffect(lineNumber, effect, returnType, function, parameters);\r
+    }\r
+    \r
+    public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) {\r
+        BoundVar var = new BoundVar(returnType);\r
+        LetApply apply = new LetApply(var,\r
+                effect,\r
+                function.createOccurrence(), \r
+                ValRef.createOccurrences(parameters));\r
+        apply.location = location;\r
+        block.addStatement(apply);\r
+        return var;\r
+    }\r
+    \r
+    public CodeWriter createBlock(Type ... parameterTypes) {\r
+        SSABlock newBlock = new SSABlock(parameterTypes);\r
+        block.getParent().addBlock(newBlock);\r
+        return new CodeWriter(moduleWriter, newBlock);\r
+    }\r
+    \r
+    public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {\r
+        if(SCLCompilerConfiguration.DEBUG)\r
+            if(effect == null)\r
+                throw new InternalCompilerError();\r
+        SSAFunction function = new SSAFunction(typeParameters, effect, returnType);\r
+        SSABlock block = new SSABlock(parameterTypes);\r
+        function.addBlock(block);\r
+        BoundVar target = new BoundVar(function.getType());\r
+        function.setTarget(target);\r
+        \r
+        this.block.addStatement(new LetFunctions(function));\r
+        return new CodeWriter(moduleWriter, block);\r
+    }\r
+    \r
+    public RecursiveDefinitionWriter createRecursiveDefinition() {\r
+        LetFunctions let = new LetFunctions();\r
+        block.addStatement(let);\r
+        return new RecursiveDefinitionWriter(moduleWriter, let);\r
+    }\r
+    \r
+    public void continueAs(CodeWriter codeWriter) {\r
+        this.block = codeWriter.block;\r
+        codeWriter.block = null;\r
+    }\r
+    \r
+    public IVal[] getParameters() {\r
+        return block.getParameters();\r
+    }\r
+    \r
+    public ICont getContinuation() {\r
+        return block;\r
+    }\r
+    \r
+    public void jump(ICont cont, IVal ... parameters) {\r
+        block.setExit(new Jump(cont.createOccurrence(), \r
+                ValRef.createOccurrences(parameters)));\r
+        block = null;\r
+    }\r
+    \r
+    public void if_(IVal condition, ICont thenTarget, ICont elseTarget) {\r
+        block.setExit(new If(condition.createOccurrence(), \r
+                thenTarget.createOccurrence(), \r
+                elseTarget.createOccurrence()));\r
+        block = null;\r
+    }\r
+\r
+    public void return_(IVal val) {\r
+        jump(block.getParent().getReturnCont(), val);\r
+    }\r
+\r
+    public void switch_(IVal val, Branch[] branches) {\r
+        block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));\r
+        block = null;\r
+    }\r
+\r
+    public void throw_(long location, String description) {\r
+        Throw exit = new Throw(description);\r
+        exit.location = location;\r
+        block.setExit(exit);\r
+        block = null;\r
+    }\r
+    \r
+    public ModuleWriter getModuleWriter() {\r
+               return moduleWriter;\r
+       }\r
+\r
+    public SSAFunction getFunction() {\r
+        return block.getParent();\r
+    }        \r
+}\r