]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java
SCL compiler generates line numbers to bytecode
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / java / Builtins.java
1 package org.simantics.scl.compiler.elaboration.java;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.databoard.binding.mutable.Variant;
5 import org.simantics.scl.compiler.common.datatypes.Constructor;
6 import org.simantics.scl.compiler.common.names.Name;
7 import org.simantics.scl.compiler.common.names.Names;
8 import org.simantics.scl.compiler.common.precedence.Associativity;
9 import org.simantics.scl.compiler.common.precedence.Precedence;
10 import org.simantics.scl.compiler.constants.BooleanConstant;
11 import org.simantics.scl.compiler.constants.Constant;
12 import org.simantics.scl.compiler.constants.JavaStaticField;
13 import org.simantics.scl.compiler.constants.JavaStaticMethod;
14 import org.simantics.scl.compiler.constants.NoRepConstant;
15 import org.simantics.scl.compiler.constants.SCLConstant;
16 import org.simantics.scl.compiler.constants.SCLConstructor;
17 import org.simantics.scl.compiler.constants.singletons.BindingConstant;
18 import org.simantics.scl.compiler.constants.singletons.ClassConstant;
19 import org.simantics.scl.compiler.constants.singletons.FailFunction;
20 import org.simantics.scl.compiler.constants.singletons.JustConstant;
21 import org.simantics.scl.compiler.constants.singletons.NothingConstant;
22 import org.simantics.scl.compiler.constants.singletons.ThrowFunction;
23 import org.simantics.scl.compiler.constants.singletons.TypeOfConstant;
24 import org.simantics.scl.compiler.constants.singletons.TypeOfProxyConstant;
25 import org.simantics.scl.compiler.constants.singletons.TypeProxyConstant;
26 import org.simantics.scl.compiler.constants.singletons.TypeValueConstant;
27 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
28 import org.simantics.scl.compiler.elaboration.modules.Documentation;
29 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
30 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
31 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
32 import org.simantics.scl.compiler.errors.Locations;
33 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
34 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
35 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
36 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
37 import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
38 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
39 import org.simantics.scl.compiler.internal.codegen.types.MaybeType;
40 import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
41 import org.simantics.scl.compiler.internal.codegen.types.VectorType;
42 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
43 import org.simantics.scl.compiler.module.ConcreteModule;
44 import org.simantics.scl.compiler.types.TApply;
45 import org.simantics.scl.compiler.types.TCon;
46 import org.simantics.scl.compiler.types.TFun;
47 import org.simantics.scl.compiler.types.TPred;
48 import org.simantics.scl.compiler.types.TUnion;
49 import org.simantics.scl.compiler.types.TVar;
50 import org.simantics.scl.compiler.types.Type;
51 import org.simantics.scl.compiler.types.Types;
52 import org.simantics.scl.compiler.types.kinds.Kind;
53 import org.simantics.scl.compiler.types.kinds.Kinds;
54 import org.simantics.scl.runtime.chr.CHRContext;
55 import org.simantics.scl.runtime.profiling.BranchPoint;
56
57 public class Builtins extends ConcreteModule {
58
59     public static final SCLValue[] TUPLE_CONSTRUCTORS = new SCLValue[Constants.MAX_TUPLE_LENGTH+1];
60     public static final SCLValue[] LIST_CONSTRUCTORS = new SCLValue[Constants.MAX_LIST_LITERAL_LENGTH+1];
61     
62     public static Builtins INSTANCE = new Builtins();
63     
64     public static SCLValue Nothing;
65     public static SCLValue Just;
66     
67     public static SCLValue EQUALS;
68     
69     private Builtins() {      
70         super(Types.BUILTIN);
71         
72         TVar A = Types.var(Kinds.STAR);
73         
74         StandardTypeConstructor Boolean = new StandardTypeConstructor(Types.BOOLEAN, Kinds.STAR, TypeDesc.BOOLEAN);
75         Boolean.documentation = "Data type representing truth values `True` and `False`.";
76         addTypeDescriptor("Boolean", Boolean);
77         addTypeDescriptor("Byte", new StandardTypeConstructor(Types.BYTE, Kinds.STAR, TypeDesc.BYTE,
78                 "8-bit signed integer"));
79         addTypeDescriptor("Character", new StandardTypeConstructor(Types.CHARACTER, Kinds.STAR, TypeDesc.CHAR,
80                 "16-bit Unicode character."));
81         addTypeDescriptor("Short", new StandardTypeConstructor(Types.SHORT, Kinds.STAR, TypeDesc.SHORT,
82                 "16-bit signed integer"));
83         addTypeDescriptor("Integer", new StandardTypeConstructor(Types.INTEGER, Kinds.STAR, TypeDesc.INT,
84                 "32-bit signed integer"));
85         addTypeDescriptor("Long", new StandardTypeConstructor(Types.LONG, Kinds.STAR, TypeDesc.LONG,
86                 "64-bit signed integer"));
87         addTypeDescriptor("Float", new StandardTypeConstructor(Types.FLOAT, Kinds.STAR, TypeDesc.FLOAT,
88                 "32-bit floating point number"));
89         addTypeDescriptor("Double", new StandardTypeConstructor(Types.DOUBLE, Kinds.STAR, TypeDesc.DOUBLE,
90                 "64-bit floating point number"));
91         addTypeDescriptor("String", new StandardTypeConstructor(Types.STRING, Kinds.STAR, TypeDesc.STRING,
92                 "Unicode string"));
93
94         addTypeDescriptor("Array", new StandardTypeConstructor(Types.con(Types.BUILTIN, "Array"), Kinds.STAR_TO_STAR, TypeDesc.forClass(Object[].class)));
95         
96         addTypeDescriptor("Maybe", MaybeType.INSTANCE);
97         
98         addTypeDescriptor("Variant", new StandardTypeConstructor(Types.VARIANT, Kinds.STAR, TypeDesc.forClass(Variant.class)));
99         
100         addEffectConstructor("Proc", new EffectConstructor(Types.PROC));
101         addEffectConstructor("Exception", new EffectConstructor(Types.EXCEPTION));
102         
103         //addTypeDescriptor("->", new StandardTypeConstructor(Kinds.STAR_TO_STAR_TO_STAR, Constants.FUNCTION));
104         addTypeDescriptor("[]", new StandardTypeConstructor(Types.LIST, Kinds.STAR_TO_STAR, Constants.LIST));        
105         addTypeDescriptor("@", new StandardTypeConstructor(Types.PUNIT, Kinds.STAR, Constants.TUPLE[0]));
106         addTypeDescriptor("TypeProxy", new StandardTypeConstructor(Types.TYPE_PROXY, Kinds.STAR_TO_STAR, Constants.TUPLE[0]));
107         
108         // *** Tuples ***
109         
110         Kind tupleKind = Kinds.STAR;
111         for(int arity=0;arity<=Constants.MAX_TUPLE_LENGTH;++arity) {
112             if(arity != 1) {
113                 TVar[] vars = new TVar[arity];
114                 for(int i=0;i<vars.length;++i)
115                     vars[i] = Types.var(Kinds.STAR);
116                 TCon constructor = Types.tupleConstructor(arity);
117                 StandardTypeConstructor typeConstructor = 
118                         new StandardTypeConstructor(constructor, tupleKind, Constants.TUPLE[arity]);
119                 addTypeDescriptor(constructor.name, typeConstructor);
120                 Type returnType = Types.apply(constructor, vars);
121                 typeConstructor.setType(constructor, vars);
122                 Constant cons;
123                 String javaName = "org/simantics/scl/runtime/tuple/Tuple"+arity;
124                 if(arity == 0) {
125                     cons = new NoRepConstant(returnType);
126                     typeConstructor.setConstructors(new Constructor(Locations.NO_LOCATION, typeConstructor,
127                             Name.create(Types.BUILTIN, constructor.name), 
128                             vars, javaName)
129                             );
130                 }
131                 else { 
132                     cons = new SCLConstructor(constructor.name, 
133                             javaName, vars, 0, returnType, vars);
134                     typeConstructor.setConstructors(
135                             new Constructor(Locations.NO_LOCATION, typeConstructor, 
136                                     Name.create(Types.BUILTIN, constructor.name), 
137                                     vars, javaName)
138                             );
139                 }
140                 typeConstructor.isOpen = false;
141                 SCLValue value = new SCLValue(Name.create(Types.BUILTIN, constructor.name), cons);
142                 addValue(value);
143                 TUPLE_CONSTRUCTORS[arity] = value;
144             }
145             tupleKind = Kinds.arrow(Kinds.STAR, tupleKind);
146         }
147         
148         // *** Lists ***
149         
150         for(int arity=0;arity<=Constants.MAX_LIST_LITERAL_LENGTH;++arity) {
151             SCLValue value = addValue("_list_literal_" + arity + "_",
152                     arity == 0 ? new EmptyListConstructor() : 
153                         new ListConstructor(arity)
154                     );
155             value.addProperty(PrivateProperty.INSTANCE);
156             LIST_CONSTRUCTORS[arity] = value;
157         }
158         
159         // *** Boolean ***
160         
161         SCLValue True = addValue("True", new BooleanConstant(true));
162         SCLValue False = addValue("False", new BooleanConstant(false));
163         Boolean.setConstructors(
164                 new Constructor(Locations.NO_LOCATION, Boolean, False.getName(), Type.EMPTY_ARRAY, null),
165                 new Constructor(Locations.NO_LOCATION, Boolean, True.getName(), Type.EMPTY_ARRAY, null)
166                 );
167         Boolean.isOpen = false;
168         
169         // *** Maybe ***
170         
171         Nothing = addValue("Nothing", NothingConstant.INSTANCE);
172         Just = addValue("Just", JustConstant.INSTANCE);
173         MaybeType.INSTANCE.setConstructors(
174                 new Constructor(Locations.NO_LOCATION, MaybeType.INSTANCE, Nothing.getName(), Type.EMPTY_ARRAY, null),
175                 new Constructor(Locations.NO_LOCATION, MaybeType.INSTANCE, Just.getName(), new Type[] {MaybeType.INSTANCE.parameters[0]}, null)
176                 );
177
178         // *** Dynamic ***
179         
180         addValue("Dynamic", DynamicConstructor.INSTANCE);
181         
182         // *** Vector ***
183         
184         TypeClass VecCompC = new TypeClass(Locations.NO_LOCATION, 
185                 TPred.EMPTY_ARRAY, 
186                 Types.VEC_COMP, 
187                 "java/lang/Class",
188                 new TVar[] {A},
189                 Fundep.EMPTY_ARRAY);
190         addTypeClass("VecComp", VecCompC);
191         
192         addTypeDescriptor("Vector", new VectorType(Types.VECTOR));
193         addValue("getVector", new GetVector(Types.NO_EFFECTS, Types.VECTOR));
194         addValue("lengthVector", new LengthVector(Types.VECTOR));
195         //addValue("createVectorFromList", CreateVectorFromList.INSTANCE);
196         
197         addTypeDescriptor("MVector", new VectorType(Types.MVECTOR));
198         addValue("createMVector", CreateMVector.INSTANCE);
199         addValue("createMVectorProto", CreateMVectorProto.INSTANCE);
200         addValue("getMVector", new GetVector(Types.PROC, Types.MVECTOR));
201         addValue("lengthMVector", new LengthVector(Types.MVECTOR));
202         addValue("freezeMVector", new FreezeMVector());
203         addValue("setMVector", SetMVector.INSTANCE);       
204         
205         StandardTypeConstructor ClassC = new StandardTypeConstructor(Types.CLASS, Kinds.STAR_TO_STAR, 
206                 TypeDesc.forClass("java/lang/Class"));
207         ClassC.setType(Types.CLASS, A);
208         addTypeDescriptor("Class", ClassC);
209         addValue("classObject", ClassConstant.INSTANCE);
210         
211         // *** fail ***
212         
213         addValue("fail", FailFunction.INSTANCE).documentation =
214                 "Throws a runtime exeception with the given string as a description.";
215         addValue("throw", ThrowFunction.INSTANCE).documentation =
216                 "Throws a given exception.";
217                 
218         // *** runProc ***
219         
220         {
221             TVar a = Types.var(Kinds.STAR);
222             TVar e = Types.var(Kinds.EFFECT);
223             SSAFunction runProcFunction = new SSAFunction(new TVar[] {a,e}, e, a);
224             Type parameterType = Types.functionE(Types.PUNIT, Types.union(new Type[] {Types.PROC,e}), a);
225             SSABlock block = new SSABlock(parameterType);
226             BoundVar[] parameters = block.getParameters();
227             
228             BoundVar x = new BoundVar(a);
229             LetApply apply = new LetApply(x, Types.PROC, parameters[0].createOccurrence(), 
230                     new NoRepConstant(Types.PUNIT).createOccurrence()
231                     );
232             block.addStatement(apply);
233             
234             block.setExit(new Jump(-1, runProcFunction.getReturnCont().createOccurrence(), 
235                     x.createOccurrence()));
236             
237             runProcFunction.addBlock(block);
238             SCLConstant runProc = new SCLConstant(Names.Builtin_runProc, runProcFunction.getType());
239             runProc.setDefinition(runProcFunction);            
240             runProc.setInlineArity(1, 0xffffffff);
241             runProc.setBase(new JavaStaticMethod("org/simantics/scl/runtime/procedure/Procedures",
242                     "runProc", a, parameterType));
243             addValue("runProc", runProc);
244         }
245         
246         // *** Typeable ***
247         
248         {
249             /* class Typeable a 
250              */
251             TypeClass TypeableC = new TypeClass(Locations.NO_LOCATION, 
252                     TPred.EMPTY_ARRAY, 
253                     Types.TYPEABLE, 
254                     Type.class.getName(),
255                     new TVar[] {A},
256                     Fundep.EMPTY_ARRAY);
257             TypeableC.documentation = "A class of types that can be reified with `typeOf` function.";
258             addTypeClass("Typeable", TypeableC);
259         
260             /* data Type = TCon String String
261              *           | TApply Type Type
262              */
263             final TCon Type = Types.con(Types.BUILTIN, "Type");
264             final TypeDesc TypeD = TypeDesc.forClass(Type.class);
265             addValue("TCon", new JavaStaticMethod(
266                     Types.class.getName().replace('.', '/'),
267                     "con",
268                     TypeDesc.forClass(TCon.class), new TypeDesc[] {TypeDesc.STRING, TypeDesc.STRING},
269                     Type, Types.STRING, Types.STRING)); 
270             addValue("TApply", new JavaStaticMethod(
271                     "org/simantics/scl/compiler/types/Types",
272                     "apply",
273                     TypeDesc.forClass(TApply.class), new TypeDesc[] {TypeD, TypeD},
274                     Type, Type, Type));
275             addValue("TFun", new JavaStaticMethod(
276                     "org/simantics/scl/compiler/types/Types",
277                     "functionE",
278                     TypeDesc.forClass(TFun.class), new TypeDesc[] {TypeD, TypeD, TypeD},
279                     Type, Type, Type, Type));
280             addValue("TPure", new JavaStaticField(
281                     "org/simantics/scl/compiler/types/Types",
282                     "NO_EFFECTS",
283                     Types.NO_EFFECTS,
284                     TypeDesc.forClass(TUnion.class),
285                     Type, -1));
286             addValue("TUnion2", new JavaStaticMethod(
287                     "org/simantics/scl/compiler/types/Types",
288                     "union",
289                     Types.NO_EFFECTS,
290                     Type, Type, Type));
291             addValue("TUnion3", new JavaStaticMethod(
292                     "org/simantics/scl/compiler/types/Types",
293                     "union",
294                     Types.NO_EFFECTS,
295                     Type, Type, Type, Type));
296             
297             StandardTypeConstructor TypeC = new StandardTypeConstructor(Type, Kinds.STAR, 
298                     TypeDesc.forClass("org/simantics/scl/compiler/types/Type"));
299             TypeC.setType(Type);
300             TypeC.isOpen = true;
301             TypeC.documentation = "Represents an SCL data type.";
302             addTypeDescriptor("Type", TypeC);
303
304             // typeOf :: Typeable a => a -> Type
305             addValue("typeOf", TypeOfConstant.INSTANCE)
306             .documentation = "Returns the type of the value given as a parameter.";
307             addValue("typeValue", TypeValueConstant.INSTANCE);
308             addValue("typeOfProxy", TypeOfProxyConstant.INSTANCE)
309             .documentation = "Returns the type of the type proxy given as a parameter.";
310             addValue("TypeProxy", TypeProxyConstant.INSTANCE);
311         }
312         
313         // *** Serializable ***
314         
315         {
316             /* class Serializable a 
317              */
318             TypeClass SerializableC = new TypeClass(Locations.NO_LOCATION, 
319                     TPred.EMPTY_ARRAY, 
320                     Types.SERIALIZABLE, 
321                     "org/simantics/databoard/binding/Binding",
322                     new TVar[] {A},
323                     Fundep.EMPTY_ARRAY);
324             SerializableC.documentation = "A class of types having a `Binding`";
325             addTypeClass("Serializable", SerializableC);
326         
327             /* data TypeRep = TCon String
328              *              | TApply TypeRep TypeRep
329              */           
330
331             StandardTypeConstructor BindingC = new StandardTypeConstructor(Types.BINDING, Kinds.STAR_TO_STAR, 
332                     TypeDesc.forClass("org/simantics/databoard/binding/Binding"));
333             BindingC.setType(Types.BINDING, A);
334             BindingC.documentation = "`Binding` represents a data type in the form supported by Databoard library. " + 
335                     "It is used to serialize and deserialize values.";
336             addTypeDescriptor("Binding", BindingC);
337             
338             // typeOf :: Typeable a => a -> TypeReps
339             addValue("binding", BindingConstant.INSTANCE)
340             .documentation = "Gives a binding for the required type.";
341             
342         }
343         
344         // Relations
345         
346         {
347             addRelation("Eq", EqRelation.INSTANCE);
348             addRelation("Optional", OptionalRelation.INSTANCE);
349             addRelation("Execute", new ExecuteRelation(0));
350             addRelation("Execute10", new ExecuteRelation(10));
351         }
352         
353         {
354             EQUALS = new SCLValue(Names.Builtin_equals, EqualsFunction.INSTANCE);
355             EQUALS.setPrecedence(new Precedence(4, Associativity.NONASSOC));
356             addValue(EQUALS);
357             addValue("hashCode", HashCodeFunction.INSTANCE);
358         }
359         
360         // Coverage
361         {
362             StandardTypeConstructor branchPoint = new StandardTypeConstructor(Types.BRANCH_POINT, Kinds.STAR,
363                     TypeDesc.forClass(BranchPoint.class)); 
364             addTypeDescriptor("BranchPoint", branchPoint);
365             
366             addValue("visitBranchPoint", VisitBranchPoint.INSTANCE);
367         }
368         
369         setParentClassLoader(getClass().getClassLoader());
370         
371         // CHR
372         
373         addTypeDescriptor("CHRContext", new StandardTypeConstructor(Types.CHRContext, Kinds.STAR, TypeDesc.forClass(CHRContext.class)));
374     }
375     
376     @Override
377     public Documentation getDocumentation() {
378         return documentation;
379     }
380
381         public static void flush() {
382                 INSTANCE = new Builtins();
383         }
384
385 }