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