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.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;
57 public class Builtins extends ConcreteModule {
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];
62 public static Builtins INSTANCE = new Builtins();
64 public static SCLValue Nothing;
65 public static SCLValue Just;
67 public static SCLValue EQUALS;
72 TVar A = Types.var(Kinds.STAR);
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,
94 addTypeDescriptor("Array", new StandardTypeConstructor(Types.con(Types.BUILTIN, "Array"), Kinds.STAR_TO_STAR, TypeDesc.forClass(Object[].class)));
96 addTypeDescriptor("Maybe", MaybeType.INSTANCE);
98 addTypeDescriptor("Variant", new StandardTypeConstructor(Types.VARIANT, Kinds.STAR, TypeDesc.forClass(Variant.class)));
100 addEffectConstructor("Proc", new EffectConstructor(Types.PROC));
101 addEffectConstructor("Exception", new EffectConstructor(Types.EXCEPTION));
103 addTypeAlias("Pure", TVar.EMPTY_ARRAY, Types.NO_EFFECTS);
105 //addTypeDescriptor("->", new StandardTypeConstructor(Kinds.STAR_TO_STAR_TO_STAR, Constants.FUNCTION));
106 addTypeDescriptor("[]", new StandardTypeConstructor(Types.LIST, Kinds.STAR_TO_STAR, Constants.LIST));
107 addTypeDescriptor("@", new StandardTypeConstructor(Types.PUNIT, Kinds.STAR, Constants.TUPLE[0]));
108 addTypeDescriptor("TypeProxy", new StandardTypeConstructor(Types.TYPE_PROXY, Kinds.STAR_TO_STAR, Constants.TUPLE[0]));
112 Kind tupleKind = Kinds.STAR;
113 for(int arity=0;arity<=Constants.MAX_TUPLE_LENGTH;++arity) {
115 TVar[] vars = new TVar[arity];
116 for(int i=0;i<vars.length;++i)
117 vars[i] = Types.var(Kinds.STAR);
118 TCon constructor = Types.tupleConstructor(arity);
119 StandardTypeConstructor typeConstructor =
120 new StandardTypeConstructor(constructor, tupleKind, Constants.TUPLE[arity]);
121 addTypeDescriptor(constructor.name, typeConstructor);
122 Type returnType = Types.apply(constructor, vars);
123 typeConstructor.setType(constructor, vars);
125 String javaName = "org/simantics/scl/runtime/tuple/Tuple"+arity;
127 cons = new NoRepConstant(returnType);
128 typeConstructor.setConstructors(new Constructor(Locations.NO_LOCATION, typeConstructor,
129 Name.create(Types.BUILTIN, constructor.name),
134 cons = new SCLConstructor(constructor.name,
135 javaName, vars, 0, returnType, vars);
136 typeConstructor.setConstructors(
137 new Constructor(Locations.NO_LOCATION, typeConstructor,
138 Name.create(Types.BUILTIN, constructor.name),
142 typeConstructor.isOpen = false;
143 SCLValue value = new SCLValue(Name.create(Types.BUILTIN, constructor.name), cons);
145 TUPLE_CONSTRUCTORS[arity] = value;
147 tupleKind = Kinds.arrow(Kinds.STAR, tupleKind);
152 for(int arity=0;arity<=Constants.MAX_LIST_LITERAL_LENGTH;++arity) {
153 SCLValue value = addValue("_list_literal_" + arity + "_",
154 arity == 0 ? new EmptyListConstructor() :
155 new ListConstructor(arity)
157 value.addProperty(PrivateProperty.INSTANCE);
158 LIST_CONSTRUCTORS[arity] = value;
163 SCLValue True = addValue("True", new BooleanConstant(true));
164 SCLValue False = addValue("False", new BooleanConstant(false));
165 Boolean.setConstructors(
166 new Constructor(Locations.NO_LOCATION, Boolean, False.getName(), Type.EMPTY_ARRAY, null),
167 new Constructor(Locations.NO_LOCATION, Boolean, True.getName(), Type.EMPTY_ARRAY, null)
169 Boolean.isOpen = false;
173 Nothing = addValue("Nothing", NothingConstant.INSTANCE);
174 Just = addValue("Just", JustConstant.INSTANCE);
175 MaybeType.INSTANCE.setConstructors(
176 new Constructor(Locations.NO_LOCATION, MaybeType.INSTANCE, Nothing.getName(), Type.EMPTY_ARRAY, null),
177 new Constructor(Locations.NO_LOCATION, MaybeType.INSTANCE, Just.getName(), new Type[] {MaybeType.INSTANCE.parameters[0]}, null)
182 addValue("Dynamic", DynamicConstructor.INSTANCE);
186 TypeClass VecCompC = new TypeClass(Locations.NO_LOCATION,
192 addTypeClass("VecComp", VecCompC);
194 addTypeDescriptor("Vector", new VectorType(Types.VECTOR));
195 addValue("getVector", new GetVector(Types.NO_EFFECTS, Types.VECTOR));
196 addValue("lengthVector", new LengthVector(Types.VECTOR));
197 //addValue("createVectorFromList", CreateVectorFromList.INSTANCE);
199 addTypeDescriptor("MVector", new VectorType(Types.MVECTOR));
200 addValue("createMVector", CreateMVector.INSTANCE);
201 addValue("createMVectorProto", CreateMVectorProto.INSTANCE);
202 addValue("getMVector", new GetVector(Types.PROC, Types.MVECTOR));
203 addValue("lengthMVector", new LengthVector(Types.MVECTOR));
204 addValue("freezeMVector", new FreezeMVector());
205 addValue("setMVector", SetMVector.INSTANCE);
207 StandardTypeConstructor ClassC = new StandardTypeConstructor(Types.CLASS, Kinds.STAR_TO_STAR,
208 TypeDesc.forClass("java/lang/Class"));
209 ClassC.setType(Types.CLASS, A);
210 addTypeDescriptor("Class", ClassC);
211 addValue("classObject", ClassConstant.INSTANCE);
215 addValue("fail", FailFunction.INSTANCE).documentation =
216 "Throws a runtime exeception with the given string as a description.";
217 addValue("throw", ThrowFunction.INSTANCE).documentation =
218 "Throws a given exception.";
223 TVar a = Types.var(Kinds.STAR);
224 TVar e = Types.var(Kinds.EFFECT);
225 SSAFunction runProcFunction = new SSAFunction(new TVar[] {a,e}, e, a);
226 Type parameterType = Types.functionE(Types.PUNIT, Types.union(new Type[] {Types.PROC,e}), a);
227 SSABlock block = new SSABlock(parameterType);
228 BoundVar[] parameters = block.getParameters();
230 BoundVar x = new BoundVar(a);
231 LetApply apply = new LetApply(x, Types.PROC, parameters[0].createOccurrence(),
232 new NoRepConstant(Types.PUNIT).createOccurrence()
234 block.addStatement(apply);
236 block.setExit(new Jump(-1, runProcFunction.getReturnCont().createOccurrence(),
237 x.createOccurrence()));
239 runProcFunction.addBlock(block);
240 SCLConstant runProc = new SCLConstant(Names.Builtin_runProc, runProcFunction.getType());
241 runProc.setDefinition(runProcFunction);
242 runProc.setInlineArity(1, 0xffffffff);
243 runProc.setBase(new JavaStaticMethod("org/simantics/scl/runtime/procedure/Procedures",
244 "runProc", a, parameterType));
245 addValue("runProc", runProc);
253 TypeClass TypeableC = new TypeClass(Locations.NO_LOCATION,
256 Type.class.getName(),
259 TypeableC.documentation = "A class of types that can be reified with `typeOf` function.";
260 addTypeClass("Typeable", TypeableC);
262 /* data Type = TCon String String
265 final TCon Type = Types.con(Types.BUILTIN, "Type");
266 final TypeDesc TypeD = TypeDesc.forClass(Type.class);
267 addValue("TCon", new JavaStaticMethod(
268 Types.class.getName().replace('.', '/'),
270 TypeDesc.forClass(TCon.class), new TypeDesc[] {TypeDesc.STRING, TypeDesc.STRING},
271 Type, Types.STRING, Types.STRING));
272 addValue("TApply", new JavaStaticMethod(
273 "org/simantics/scl/compiler/types/Types",
275 TypeDesc.forClass(TApply.class), new TypeDesc[] {TypeD, TypeD},
277 addValue("TFun", new JavaStaticMethod(
278 "org/simantics/scl/compiler/types/Types",
280 TypeDesc.forClass(TFun.class), new TypeDesc[] {TypeD, TypeD, TypeD},
281 Type, Type, Type, Type));
282 addValue("TPure", new JavaStaticField(
283 "org/simantics/scl/compiler/types/Types",
286 TypeDesc.forClass(TUnion.class),
288 addValue("TUnion2", new JavaStaticMethod(
289 "org/simantics/scl/compiler/types/Types",
293 addValue("TUnion3", new JavaStaticMethod(
294 "org/simantics/scl/compiler/types/Types",
297 Type, Type, Type, Type));
299 StandardTypeConstructor TypeC = new StandardTypeConstructor(Type, Kinds.STAR,
300 TypeDesc.forClass("org/simantics/scl/compiler/types/Type"));
303 TypeC.documentation = "Represents an SCL data type.";
304 addTypeDescriptor("Type", TypeC);
306 // typeOf :: Typeable a => a -> Type
307 addValue("typeOf", TypeOfConstant.INSTANCE)
308 .documentation = "Returns the type of the value given as a parameter.";
309 addValue("typeValue", TypeValueConstant.INSTANCE);
310 addValue("typeOfProxy", TypeOfProxyConstant.INSTANCE)
311 .documentation = "Returns the type of the type proxy given as a parameter.";
312 addValue("TypeProxy", TypeProxyConstant.INSTANCE);
315 // *** Serializable ***
318 /* class Serializable a
320 TypeClass SerializableC = new TypeClass(Locations.NO_LOCATION,
323 "org/simantics/databoard/binding/Binding",
326 SerializableC.documentation = "A class of types having a `Binding`";
327 addTypeClass("Serializable", SerializableC);
329 /* data TypeRep = TCon String
330 * | TApply TypeRep TypeRep
333 StandardTypeConstructor BindingC = new StandardTypeConstructor(Types.BINDING, Kinds.STAR_TO_STAR,
334 TypeDesc.forClass("org/simantics/databoard/binding/Binding"));
335 BindingC.setType(Types.BINDING, A);
336 BindingC.documentation = "`Binding` represents a data type in the form supported by Databoard library. " +
337 "It is used to serialize and deserialize values.";
338 addTypeDescriptor("Binding", BindingC);
340 // typeOf :: Typeable a => a -> TypeReps
341 addValue("binding", BindingConstant.INSTANCE)
342 .documentation = "Gives a binding for the required type.";
349 addRelation("Eq", EqRelation.INSTANCE);
350 addRelation("Optional", OptionalRelation.INSTANCE);
351 addRelation("Execute", new ExecuteRelation(0));
352 addRelation("Execute10", new ExecuteRelation(10));
356 EQUALS = new SCLValue(Names.Builtin_equals, EqualsFunction.INSTANCE);
357 EQUALS.setPrecedence(new Precedence(4, Associativity.NONASSOC));
359 addValue("hashCode", HashCodeFunction.INSTANCE);
364 StandardTypeConstructor branchPoint = new StandardTypeConstructor(Types.BRANCH_POINT, Kinds.STAR,
365 TypeDesc.forClass(BranchPoint.class));
366 addTypeDescriptor("BranchPoint", branchPoint);
368 addValue("visitBranchPoint", VisitBranchPoint.INSTANCE);
371 setParentClassLoader(getClass().getClassLoader());
375 addTypeDescriptor("CHRContext", new StandardTypeConstructor(Types.CHRContext, Kinds.STAR, TypeDesc.forClass(CHRContext.class)));
379 public Documentation getDocumentation() {
380 return documentation;
383 public static void flush() {
384 INSTANCE = new Builtins();