1 package org.simantics.scl.compiler.internal.codegen.writer;
\r
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
\r
4 import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
\r
5 import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
\r
6 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
\r
7 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
\r
8 import org.simantics.scl.compiler.internal.codegen.references.IVal;
\r
9 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
\r
10 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
\r
11 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
\r
12 import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;
\r
13 import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
\r
14 import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;
\r
15 import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
\r
16 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
\r
17 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;
\r
18 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
\r
19 import org.simantics.scl.compiler.types.TVar;
\r
20 import org.simantics.scl.compiler.types.Type;
\r
21 import org.simantics.scl.compiler.types.Types;
\r
22 import org.simantics.scl.compiler.types.exceptions.MatchException;
\r
23 import org.simantics.scl.compiler.types.util.MultiFunction;
\r
25 public class CodeWriter {
\r
27 ModuleWriter moduleWriter;
\r
30 CodeWriter(ModuleWriter moduleWriter, SSABlock block) {
\r
31 this.moduleWriter = moduleWriter;
\r
35 public IVal apply(int lineNumber, IVal function, IVal ... parameters) {
\r
37 MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
\r
38 return applyWithEffect(lineNumber,
\r
41 function, parameters);
\r
42 } catch (MatchException e) {
\r
43 throw new InternalCompilerError(e);
\r
47 public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {
\r
49 MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
\r
50 if(!Types.equals(effect, mfun.effect))
\r
51 throw new InternalCompilerError();
\r
52 if(!Types.equals(returnType, mfun.returnType))
\r
53 throw new InternalCompilerError();
\r
54 } catch (MatchException e) {
\r
55 throw new InternalCompilerError(e);
\r
57 return applyWithEffect(lineNumber, effect, returnType, function, parameters);
\r
60 public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) {
\r
61 BoundVar var = new BoundVar(returnType);
\r
62 LetApply apply = new LetApply(var,
\r
64 function.createOccurrence(),
\r
65 ValRef.createOccurrences(parameters));
\r
66 apply.location = location;
\r
67 block.addStatement(apply);
\r
71 public CodeWriter createBlock(Type ... parameterTypes) {
\r
72 SSABlock newBlock = new SSABlock(parameterTypes);
\r
73 block.getParent().addBlock(newBlock);
\r
74 return new CodeWriter(moduleWriter, newBlock);
\r
77 public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {
\r
78 if(SCLCompilerConfiguration.DEBUG)
\r
80 throw new InternalCompilerError();
\r
81 SSAFunction function = new SSAFunction(typeParameters, effect, returnType);
\r
82 SSABlock block = new SSABlock(parameterTypes);
\r
83 function.addBlock(block);
\r
84 BoundVar target = new BoundVar(function.getType());
\r
85 function.setTarget(target);
\r
87 this.block.addStatement(new LetFunctions(function));
\r
88 return new CodeWriter(moduleWriter, block);
\r
91 public RecursiveDefinitionWriter createRecursiveDefinition() {
\r
92 LetFunctions let = new LetFunctions();
\r
93 block.addStatement(let);
\r
94 return new RecursiveDefinitionWriter(moduleWriter, let);
\r
97 public void continueAs(CodeWriter codeWriter) {
\r
98 this.block = codeWriter.block;
\r
99 codeWriter.block = null;
\r
102 public IVal[] getParameters() {
\r
103 return block.getParameters();
\r
106 public ICont getContinuation() {
\r
110 public void jump(ICont cont, IVal ... parameters) {
\r
111 block.setExit(new Jump(cont.createOccurrence(),
\r
112 ValRef.createOccurrences(parameters)));
\r
116 public void if_(IVal condition, ICont thenTarget, ICont elseTarget) {
\r
117 block.setExit(new If(condition.createOccurrence(),
\r
118 thenTarget.createOccurrence(),
\r
119 elseTarget.createOccurrence()));
\r
123 public void return_(IVal val) {
\r
124 jump(block.getParent().getReturnCont(), val);
\r
127 public void switch_(IVal val, Branch[] branches) {
\r
128 block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));
\r
132 public void throw_(long location, String description) {
\r
133 Throw exit = new Throw(description);
\r
134 exit.location = location;
\r
135 block.setExit(exit);
\r
139 public ModuleWriter getModuleWriter() {
\r
140 return moduleWriter;
\r
143 public SSAFunction getFunction() {
\r
144 return block.getParent();
\r