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