-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
+package org.simantics.scl.compiler.internal.codegen.writer;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
+import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAObject;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.util.MultiFunction;
+
+public class CodeWriter {
+
+ ModuleWriter moduleWriter;
+ SSABlock block;
+
+ public CodeWriter(ModuleWriter moduleWriter, SSABlock block) {
+ this.moduleWriter = moduleWriter;
+ this.block = block;
+ }
+
+ public IVal apply(long lineNumber, IVal function, IVal ... parameters) {
+ try {
+ MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
+ return applyWithEffect(lineNumber,
+ mfun.effect,
+ mfun.returnType,
+ function, parameters);
+ } catch (MatchException e) {
+ throw new InternalCompilerError(e);
+ }
+ }
+
+ public IVal applyWithEffectChecked(long lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {
+ try {
+ MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
+ if(!Types.equals(effect, mfun.effect))
+ throw new InternalCompilerError();
+ if(!Types.equals(returnType, mfun.returnType))
+ throw new InternalCompilerError();
+ } catch (MatchException e) {
+ throw new InternalCompilerError(e);
+ }
+ return applyWithEffect(lineNumber, effect, returnType, function, parameters);
+ }
+
+ public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) {
+ BoundVar var = new BoundVar(returnType);
+ LetApply apply = new LetApply(var,
+ effect,
+ function.createOccurrence(),
+ ValRef.createOccurrences(parameters));
+ apply.location = location;
+ block.addStatement(apply);
+ return var;
+ }
+
+ public CodeWriter createBlock() {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ return new CodeWriter(moduleWriter, newBlock);
+ }
+
+ public CodeWriter createBlock(Type ... parameterTypes) {
+ SSABlock newBlock = new SSABlock(parameterTypes);
+ block.getParent().addBlock(newBlock);
+ return new CodeWriter(moduleWriter, newBlock);
+ }
+
+ public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {
+ if(SCLCompilerConfiguration.DEBUG)
+ if(effect == null)
+ throw new InternalCompilerError();
+ SSAFunction function = new SSAFunction(typeParameters, effect, returnType);
+ SSABlock block = new SSABlock(parameterTypes);
+ function.addBlock(block);
+ BoundVar target = new BoundVar(function.getType());
+ function.setTarget(target);
+
+ this.block.addStatement(new LetFunctions(function));
+ return new CodeWriter(moduleWriter, block);
+ }
+
+ public RecursiveDefinitionWriter createRecursiveDefinition() {
+ LetFunctions let = new LetFunctions();
+ block.addStatement(let);
+ return new RecursiveDefinitionWriter(moduleWriter, let);
+ }
+
+ public void continueAs(CodeWriter codeWriter) {
+ this.block = codeWriter.block;
+ codeWriter.block = null;
+ }
+
+ public IVal[] getParameters() {
+ return block.getParameters();
+ }
+
+ public ICont getContinuation() {
+ return block;
+ }
+
+ public void jump(ICont cont, IVal ... parameters) {
+ block.setExit(new Jump(cont.createOccurrence(),
+ ValRef.createOccurrences(parameters)));
+ block = null;
+ }
+
+ public void if_(IVal condition, ICont thenTarget, ICont elseTarget) {
+ block.setExit(new If(condition.createOccurrence(),
+ thenTarget.createOccurrence(),
+ elseTarget.createOccurrence()));
+ block = null;
+ }
+
+ public void branchAwayIf(IVal condition, ICont target) {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ block.setExit(new If(condition.createOccurrence(),
+ target.createOccurrence(),
+ newBlock.createOccurrence()));
+ this.block = newBlock;
+ }
+
+ public void branchAwayUnless(IVal condition, ICont target) {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ block.setExit(new If(condition.createOccurrence(),
+ newBlock.createOccurrence(),
+ target.createOccurrence()));
+ this.block = newBlock;
+ }
+
+ public void return_(IVal val) {
+ jump(block.getParent().getReturnCont(), val);
+ }
+
+ public void switch_(IVal val, Branch[] branches) {
+ block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));
+ block = null;
+ }
+
+ public void throw_(long location, TypeDesc exceptionClass, String description) {
+ Throw exit = new Throw(exceptionClass, description);
+ exit.location = location;
+ block.setExit(exit);
+ block = null;
+ }
+
+ public ModuleWriter getModuleWriter() {
+ return moduleWriter;
+ }
+
+ public SSAFunction getFunction() {
+ return block.getParent();
+ }
+
+ public boolean isUnfinished() {
+ return block != null;
+ }
+
+ public void defineObject(SSAObject object) {
+ this.block.addStatement(new LetFunctions(object));
+ }
+}