1 package org.simantics.scl.compiler.elaboration.java;
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;
49 public class Builtins extends ConcreteModule {
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];
54 public static final Builtins INSTANCE = new Builtins();
56 public static SCLValue Nothing;
57 public static SCLValue Just;
62 TVar A = Types.var(Kinds.STAR);
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,
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)));
93 addTypeConstructor("Array", new StandardTypeConstructor(Types.con(Types.BUILTIN, "Array"), Kinds.STAR_TO_STAR, TypeDesc.forClass(Object[].class)));
95 addTypeConstructor("Maybe", MaybeType.INSTANCE);
97 addTypeConstructor("Variant", new StandardTypeConstructor(Types.VARIANT, Kinds.STAR, TypeDesc.forClass(Variant.class)));
99 addEffectConstructor("Proc", new EffectConstructor(Types.PROC));
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]));
108 Kind tupleKind = Kinds.STAR;
109 for(int arity=0;arity<=Constants.MAX_TUPLE_LENGTH;++arity) {
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);
121 String javaName = "org/simantics/scl/runtime/tuple/Tuple"+arity;
123 cons = new NoRepConstant(returnType);
124 typeConstructor.setConstructors(new Constructor(Locations.NO_LOCATION, typeConstructor,
125 Name.create(Types.BUILTIN, constructor.name),
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),
138 typeConstructor.isOpen = false;
139 SCLValue value = new SCLValue(Name.create(Types.BUILTIN, constructor.name), cons);
141 TUPLE_CONSTRUCTORS[arity] = value;
143 tupleKind = Kinds.arrow(Kinds.STAR, tupleKind);
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)
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)
163 Boolean.isOpen = false;
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)
176 TypeClass VecCompC = new TypeClass(Locations.NO_LOCATION,
182 addTypeClass("VecComp", VecCompC);
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);
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);
199 addValue("fail", FailFunction.INSTANCE).documentation =
200 "Throws a runtime exeception with the given string as a description.";
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();
212 BoundVar x = new BoundVar(a);
213 LetApply apply = new LetApply(x, Types.PROC, parameters[0].createOccurrence(),
214 new NoRepConstant(Types.PUNIT).createOccurrence()
216 block.addStatement(apply);
218 block.setExit(new Jump(runProcFunction.getReturnCont().createOccurrence(),
219 x.createOccurrence()));
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);
235 TypeClass TypeableC = new TypeClass(Locations.NO_LOCATION,
238 Type.class.getName(),
241 TypeableC.documentation = "A class of types that can be reified with `typeOf` function.";
242 addTypeClass("Typeable", TypeableC);
244 /* data Type = TCon String String
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('.', '/'),
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",
257 TypeDesc.forClass(TApply.class), new TypeDesc[] {TypeD, TypeD},
259 addValue("TFun", new JavaStaticMethod(
260 "org/simantics/scl/compiler/types/Types",
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",
268 TypeDesc.forClass(TUnion.class),
270 /*addValue("TUnion", new JavaStaticMethod(
271 "org/simantics/scl/compiler/types/Types",
274 Type, Types.list(Type)));*/
276 StandardTypeConstructor TypeC = new StandardTypeConstructor(Type, Kinds.STAR,
277 TypeDesc.forClass("org/simantics/scl/compiler/types/Type"));
280 TypeC.documentation = "Represents an SCL data type.";
281 addTypeConstructor("Type", TypeC);
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);
291 // *** Serializable ***
294 /* class Serializable a
296 TypeClass SerializableC = new TypeClass(Locations.NO_LOCATION,
299 "org/simantics/databoard/binding/Binding",
302 SerializableC.documentation = "A class of types having a `Binding`";
303 addTypeClass("Serializable", SerializableC);
305 /* data TypeRep = TCon String
306 * | TApply TypeRep TypeRep
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);
316 // typeOf :: Typeable a => a -> TypeReps
317 addValue("binding", BindingConstant.INSTANCE)
318 .documentation = "Gives a binding for the required type.";
325 addRelation("Eq", EqRelation.INSTANCE);
326 addRelation("Optional", OptionalRelation.INSTANCE);
327 addRelation("Execute", new ExecuteRelation(0));
328 addRelation("Execute10", new ExecuteRelation(10));
331 addValue("newEq", EqualsFunction.INSTANCE);
332 addValue("newHash", HashCodeFunction.INSTANCE);
335 StandardTypeConstructor branchPoint = new StandardTypeConstructor(Types.BRANCH_POINT, Kinds.STAR,
336 TypeDesc.forClass(BranchPoint.class));
337 addTypeConstructor("BranchPoint", branchPoint);
339 addValue("visitBranchPoint", VisitBranchPoint.INSTANCE);
344 public Documentation getDocumentation() {
345 return documentation;