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