]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expressions.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / Expressions.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expressions.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expressions.java
new file mode 100644 (file)
index 0000000..10d9bcb
--- /dev/null
@@ -0,0 +1,247 @@
+package org.simantics.scl.compiler.elaboration.expressions;\r
+\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.constants.IntegerConstant;\r
+import org.simantics.scl.compiler.constants.JavaComparisonToZeroOperation;\r
+import org.simantics.scl.compiler.constants.JavaMathOperation;\r
+import org.simantics.scl.compiler.constants.NoRepConstant;\r
+import org.simantics.scl.compiler.constants.StringConstant;\r
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
+import org.simantics.scl.compiler.elaboration.java.Builtins;\r
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
+import org.simantics.scl.compiler.elaboration.query.Query;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+import org.simantics.scl.compiler.types.util.MultiFunction;\r
+\r
+public class Expressions {\r
+    public static Expression apply(Expression function, Expression ... parameters) {\r
+        if(parameters.length == 0)\r
+            return function;\r
+        Type ftype = function.getType();\r
+        try {\r
+            MultiFunction mfun = Types.matchFunction(ftype, parameters.length);\r
+            EApply apply = new EApply(Locations.NO_LOCATION, mfun.effect, function, parameters);\r
+            apply.setType(mfun.returnType);\r
+            return apply;\r
+        } catch (MatchException e) {\r
+            throw new InternalCompilerError("Type of the function " + ftype + " is not compatible with the number of parameters.");\r
+        }\r
+    }\r
+    \r
+    public static Expression apply(Type effect, Expression function, Expression ... parameters) {\r
+        return new EApply(Locations.NO_LOCATION, effect, function, parameters);\r
+    }\r
+    \r
+    public static Expression apply(EnvironmentalContext context, Type effect, Name name, Expression ... parameters) {\r
+        return apply(effect, constant(context, name), parameters);\r
+    }\r
+    \r
+    public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Expression ... parameters) {\r
+        return apply(effect, constant(context, name, typeParameter1), parameters);\r
+    }\r
+    \r
+    public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Type typeParameter2, Expression ... parameters) {\r
+        return apply(effect, constant(context, name, typeParameter1, typeParameter2), parameters);\r
+    }\r
+\r
+    public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Type typeParameter2, Type typeParameter3, Expression ... parameters) {\r
+        return apply(effect, constant(context, name, typeParameter1, typeParameter2, typeParameter3), parameters);\r
+    }\r
+\r
+    public static Expression constant(SCLValue value) {\r
+        return new EConstant(value);\r
+    }\r
+    \r
+    public static Expression constant(EnvironmentalContext context, Name name) {\r
+        return new EConstant(context.getValue(name));\r
+    }\r
+    \r
+    public static Expression constant(EnvironmentalContext context, Name name, Type ... typeParameters) {\r
+        return new EConstant(context.getValue(name), typeParameters);\r
+    }\r
+\r
+    public static Expression if_(Expression condition, Expression then_, Expression else_) {\r
+        return new EIf(condition, then_, else_);\r
+    }\r
+    \r
+    public static Expression var(Variable variable) {\r
+        return new EVariable(variable);\r
+    }\r
+    \r
+    public static Variable newVar(String name, Type type) {\r
+        return new Variable(name, type);\r
+    }\r
+    \r
+    public static Variable newBlankVar(Type type) {\r
+        return new Variable("_", type);\r
+    }\r
+    \r
+    public static Expression computation(Type effect, Expression value) {\r
+        return new ESimpleLambda(\r
+                effect,\r
+                newBlankVar(Types.PUNIT),\r
+                value);\r
+    }\r
+    \r
+    public static Expression blank(Type type) {\r
+        return new EVariable(newBlankVar(type));\r
+    }\r
+    public static Expression integer(int value) {\r
+        return new ELiteral(new IntegerConstant(value));\r
+    }\r
+\r
+    public static Expression string(String value) {\r
+        return new ELiteral(new StringConstant(value));\r
+    }\r
+\r
+    public static Expression tuple() {\r
+        return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);\r
+    }\r
+    \r
+    public static Expression punit() {\r
+        return new ELiteral(NoRepConstant.PUNIT);\r
+    }\r
+    \r
+    public static Expression tuple(Expression ... cs) {\r
+        if(cs.length == 1)\r
+            return cs[0];\r
+        Type[] typeParameters = new Type[cs.length];\r
+        for(int i=0;i<cs.length;++i)\r
+            typeParameters[i] = cs[i].getType();\r
+        EApply result = new EApply(\r
+                new EConstant(Builtins.TUPLE_CONSTRUCTORS[cs.length], typeParameters),\r
+                cs);\r
+        result.setType(Types.tuple(Types.getTypes(cs)));\r
+        return result;\r
+    }\r
+    \r
+    public static Expression[] vars(Variable ... variables) {\r
+        Expression[] expressions = new Expression[variables.length];\r
+        for(int i=0;i<variables.length;++i)\r
+            expressions[i] = new EVariable(variables[i]);\r
+        return expressions;\r
+    }\r
+    \r
+    public static Expression[] vars(List<Variable> variables) {\r
+        Expression[] expressions = new Expression[variables.size()];\r
+        for(int i=0;i<variables.size();++i)\r
+            expressions[i] = new EVariable(variables.get(i));\r
+        return expressions;\r
+    }\r
+    \r
+    public static Expression match(Expression scrutinee,\r
+            Expression pattern1, Expression value1) {\r
+        return new EMatch(scrutinee, new Case(pattern1, value1));\r
+    }\r
+    \r
+    public static Expression match(Expression scrutinee,\r
+            Expression pattern1, Expression value1,\r
+            Expression pattern2, Expression value2) {\r
+        return new EMatch(scrutinee, new Case(pattern1, value1), new Case(pattern2, value2));\r
+    }\r
+    \r
+    public static Expression matchWithDefault(Expression scrutinee,\r
+            Expression pattern1, Expression value1,\r
+            Expression default_) {\r
+        return new EMatch(scrutinee, new Case(pattern1, value1), new Case(blank(pattern1.getType()), default_));\r
+    }\r
+    \r
+    public static Expression let(Variable target, Expression value, Expression in) {\r
+        return new ESimpleLet(target, value, in);\r
+    }\r
+    \r
+    public static Expression letRec(Variable target, Expression value, Expression in) {\r
+        return new ELet(Locations.NO_LOCATION, new Assignment[] {new Assignment(var(target), value)}, in);\r
+    }\r
+    \r
+    public static Expression letRec(Variable[] targets, Expression[] values, Expression in) {\r
+        if(targets.length != values.length)\r
+            throw new InternalCompilerError();\r
+        Assignment[] assignments = new Assignment[targets.length];\r
+        for(int i=0;i<targets.length;++i)\r
+            assignments[i] = new Assignment(var(targets[i]), values[i]);\r
+        return new ELet(Locations.NO_LOCATION, assignments, in);\r
+    }\r
+    \r
+    public static Expression lambda(Type effect, Variable var, Expression value) {\r
+        return new ESimpleLambda(effect, var, value);\r
+    }\r
+    \r
+    public static Expression lambda(Variable var, Expression value) {\r
+        return new ESimpleLambda(value.getEffect(), var, value);\r
+    }\r
+    \r
+    public static Expression lambda(Type effect, Variable[] vars, Expression value) {\r
+        for(int i=vars.length-1;i>=0;--i) {\r
+            value = new ESimpleLambda(effect, vars[i], value);\r
+            effect = Types.NO_EFFECTS;\r
+        }\r
+        return value;\r
+    }\r
+    \r
+    public static Expression lambda(Type effect, List<Variable> vars, Expression value) {\r
+        for(int i=vars.size()-1;i>=0;--i) {\r
+            value = new ESimpleLambda(effect, vars.get(i), value);\r
+            effect = Types.NO_EFFECTS;\r
+        }\r
+        return value;\r
+    }\r
+    \r
+    public static Expression lambda(Variable[] vars, Expression value) {\r
+        return lambda(value.getEffect(), vars, value);\r
+    }\r
+    \r
+    public static Expression lambda(List<Variable> vars, Expression value) {\r
+        return lambda(value.getEffect(), vars, value);\r
+    }\r
+    \r
+    public static Expression Nothing(Type type) {\r
+        return new EConstant(Builtins.Nothing, type);\r
+    }\r
+    \r
+    public static Expression Just(Expression expression) {\r
+        return apply(Types.NO_EFFECTS, new EConstant(Builtins.Just, expression.getType()), expression);\r
+    }\r
+    \r
+    public static Expression seq(Expression first, Expression second) {\r
+        return let(newBlankVar(first.getType()), first, second);\r
+    }\r
+    \r
+    public static Expression as(Variable var, Expression value) {\r
+        return new EAsPattern(var, value);\r
+    }\r
+    \r
+    public static Expression loc(long location, Expression expression) {\r
+        expression.setLocationDeep(location);\r
+        return expression;\r
+    }\r
+    \r
+    public static Query loc(long location, Query query) {\r
+        query.setLocationDeep(location);\r
+        return query;\r
+    }\r
+\r
+    public static Expression applyTypes(Expression expression, Type[] types) {\r
+        for(Type type : types)\r
+            expression = new EApplyType(expression, type);\r
+        return expression;\r
+    }\r
+    \r
+    public static Expression isZeroInteger(Expression value) {\r
+        return apply(Types.NO_EFFECTS, new ELiteral(new JavaComparisonToZeroOperation("==")), value);\r
+    }\r
+    \r
+    public static Expression addInteger(Expression a, Expression b) {\r
+        return apply(Types.NO_EFFECTS, new ELiteral(JavaMathOperation.IADD), a, b);\r
+    }\r
+\r
+    public static Expression externalConstant(Object value, Type type) {\r
+        return new EExternalConstant(value, type);\r
+    }\r
+}\r