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