]> gerrit.simantics Code Review - simantics/platform.git/blob
f11babe06bd3ef8e110fc00d4a719cf72b424293
[simantics/platform.git] /
1 package org.simantics.scl.compiler.internal.codegen.writer;\r
2 \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
24 \r
25 public class CodeWriter {\r
26 \r
27     ModuleWriter moduleWriter;\r
28     SSABlock block;\r
29     \r
30     CodeWriter(ModuleWriter moduleWriter, SSABlock block) {\r
31         this.moduleWriter = moduleWriter;\r
32         this.block = block;\r
33     }\r
34 \r
35     public IVal apply(int lineNumber, IVal function, IVal ... parameters) {\r
36         try {\r
37             MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
38             return applyWithEffect(lineNumber,\r
39                     mfun.effect,\r
40                     mfun.returnType,\r
41                     function, parameters);\r
42         } catch (MatchException e) {\r
43             throw new InternalCompilerError(e);\r
44         }\r
45     }\r
46     \r
47     public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {\r
48         try {\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
56         }            \r
57         return applyWithEffect(lineNumber, effect, returnType, function, parameters);\r
58     }\r
59     \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
63                 effect,\r
64                 function.createOccurrence(), \r
65                 ValRef.createOccurrences(parameters));\r
66         apply.location = location;\r
67         block.addStatement(apply);\r
68         return var;\r
69     }\r
70     \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
75     }\r
76     \r
77     public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {\r
78         if(SCLCompilerConfiguration.DEBUG)\r
79             if(effect == null)\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
86         \r
87         this.block.addStatement(new LetFunctions(function));\r
88         return new CodeWriter(moduleWriter, block);\r
89     }\r
90     \r
91     public RecursiveDefinitionWriter createRecursiveDefinition() {\r
92         LetFunctions let = new LetFunctions();\r
93         block.addStatement(let);\r
94         return new RecursiveDefinitionWriter(moduleWriter, let);\r
95     }\r
96     \r
97     public void continueAs(CodeWriter codeWriter) {\r
98         this.block = codeWriter.block;\r
99         codeWriter.block = null;\r
100     }\r
101     \r
102     public IVal[] getParameters() {\r
103         return block.getParameters();\r
104     }\r
105     \r
106     public ICont getContinuation() {\r
107         return block;\r
108     }\r
109     \r
110     public void jump(ICont cont, IVal ... parameters) {\r
111         block.setExit(new Jump(cont.createOccurrence(), \r
112                 ValRef.createOccurrences(parameters)));\r
113         block = null;\r
114     }\r
115     \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
120         block = null;\r
121     }\r
122 \r
123     public void return_(IVal val) {\r
124         jump(block.getParent().getReturnCont(), val);\r
125     }\r
126 \r
127     public void switch_(IVal val, Branch[] branches) {\r
128         block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));\r
129         block = null;\r
130     }\r
131 \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
136         block = null;\r
137     }\r
138     \r
139     public ModuleWriter getModuleWriter() {\r
140                 return moduleWriter;\r
141         }\r
142 \r
143     public SSAFunction getFunction() {\r
144         return block.getParent();\r
145     }        \r
146 }\r