-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.ILet;\r
-import org.simantics.scl.compiler.internal.interpreted.ISeq;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ESimpleLet extends Expression {\r
- Variable variable; // may be null\r
- Expression value;\r
- Expression in;\r
- \r
- public ESimpleLet(Variable variable, Expression value, Expression in) {\r
- if(value == null)\r
- throw new NullPointerException();\r
- if(in == null)\r
- throw new NullPointerException();\r
- this.variable = variable;\r
- this.value = value;\r
- this.in = in;\r
- }\r
-\r
- public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {\r
- super(loc);\r
- if(value == null)\r
- throw new NullPointerException();\r
- if(in == null)\r
- throw new NullPointerException();\r
- this.variable = variable;\r
- this.value = value;\r
- this.in = in;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- value.collectRefs(allRefs, refs);\r
- in.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- value.collectVars(allVars, vars);\r
- in.collectVars(allVars, vars);\r
- }\r
-\r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(in.getType());\r
- }\r
- \r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- IVal valueVal = value.toVal(env, w);\r
- if(variable != null)\r
- variable.setVal(valueVal);\r
- return in.toVal(env, w);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- value.collectFreeVariables(vars);\r
- in.collectFreeVariables(vars);\r
- vars.remove(variable);\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- value = value.simplify(context);\r
- if(value instanceof EConstant || value instanceof ELiteral) {\r
- context.addInlinedVariable(variable, value);\r
- return in.simplify(context);\r
- }\r
- in = in.simplify(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- value = value.resolve(context);\r
- in = in.resolve(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- if(variable == null)\r
- return new ESimpleLet(location,\r
- null, \r
- value.replace(context), \r
- in.replace(context));\r
- else {\r
- Variable newVariable = variable.copy();\r
- context.varMap.put(variable, new EVariable(newVariable));\r
- ESimpleLet result = new ESimpleLet(location, newVariable, \r
- value.replace(context), \r
- in.replace(context));\r
- context.varMap.remove(variable);\r
- return result;\r
- }\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- value.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
-\r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext context) {\r
- if(variable == null) {\r
- IExpression valueI = value.toIExpression(context);\r
- IExpression inI = in.toIExpression(context);\r
- return new ISeq(valueI, inI);\r
- }\r
- else {\r
- IExpression valueI = value.toIExpression(context);\r
- int variableId = context.push(variable);\r
- IExpression inI = in.toIExpression(context);\r
- context.pop(variable);\r
- return new ILet(variableId, valueI, inI);\r
- }\r
- }\r
-\r
- private void checkBinding(TypingContext context) {\r
- if(variable == null)\r
- value = value.inferType(context);\r
- else if(variable.getType() == null) {\r
- value = value.inferType(context);\r
- variable.setType(value.getType());\r
- }\r
- else\r
- value = value.checkType(context, variable.type);\r
- /*else {\r
- if(variable.getType() == null)\r
- variable.setType(Types.metaVar(Kinds.STAR));\r
- value = value.checkType(context, variable.type);\r
- }*/\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- checkBinding(context);\r
- in = in.inferType(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- checkBinding(context);\r
- in = in.checkType(context, requiredType);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- value = value.decorate(decorator);\r
- in = in.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- value.collectEffects(effects);\r
- in.collectEffects(effects);\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- public Expression getValue() {\r
- return value;\r
- }\r
- \r
- public Variable getVariable() {\r
- return variable;\r
- }\r
- \r
- public Expression getIn() {\r
- return in;\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- value.forVariables(procedure);\r
- in.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.ILet;
+import org.simantics.scl.compiler.internal.interpreted.ISeq;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+
+public class ESimpleLet extends Expression {
+ public Variable variable; // may be null
+ public Expression value;
+ public Expression in;
+
+ public ESimpleLet(Variable variable, Expression value, Expression in) {
+ if(value == null)
+ throw new NullPointerException();
+ if(in == null)
+ throw new NullPointerException();
+ this.variable = variable;
+ this.value = value;
+ this.in = in;
+ }
+
+ public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
+ super(loc);
+ if(value == null)
+ throw new NullPointerException();
+ if(in == null)
+ throw new NullPointerException();
+ this.variable = variable;
+ this.value = value;
+ this.in = in;
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(in.getType());
+ }
+
+ @Override
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ IVal valueVal = value.toVal(context, w);
+ if(variable != null)
+ variable.setVal(valueVal);
+ return in.toVal(context, w);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ value = value.simplify(context);
+ if(value instanceof EConstant || value instanceof ELiteral) {
+ context.addInlinedVariable(variable, value);
+ return in.simplify(context);
+ }
+ in = in.simplify(context);
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ value = value.resolve(context);
+ in = in.resolve(context);
+ return this;
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ if(variable == null)
+ return new ESimpleLet(location,
+ null,
+ value.replace(context),
+ in.replace(context));
+ else {
+ Variable newVariable = variable.copy();
+ context.varMap.put(variable, new EVariable(newVariable));
+ ESimpleLet result = new ESimpleLet(location, newVariable,
+ value.replace(context),
+ in.replace(context));
+ context.varMap.remove(variable);
+ return result;
+ }
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ value.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext context) {
+ if(variable == null) {
+ IExpression valueI = value.toIExpression(context);
+ IExpression inI = in.toIExpression(context);
+ return new ISeq(valueI, inI);
+ }
+ else {
+ IExpression valueI = value.toIExpression(context);
+ int variableId = context.push(variable);
+ IExpression inI = in.toIExpression(context);
+ context.pop(variable);
+ return new ILet(variableId, valueI, inI);
+ }
+ }
+
+ private void checkBinding(TypingContext context) {
+ if(variable == null)
+ value = value.checkIgnoredType(context);
+ else if(variable.getType() == null) {
+ value = value.inferType(context);
+ variable.setType(value.getType());
+ }
+ else
+ value = value.checkType(context, variable.type);
+ /*else {
+ if(variable.getType() == null)
+ variable.setType(Types.metaVar(Kinds.STAR));
+ value = value.checkType(context, variable.type);
+ }*/
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ checkBinding(context);
+ in = in.inferType(context);
+ return this;
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ checkBinding(context);
+ in = in.checkType(context, requiredType);
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ checkBinding(context);
+ in = in.checkIgnoredType(context);
+ return this;
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ public Expression getValue() {
+ return value;
+ }
+
+ public Variable getVariable() {
+ return variable;
+ }
+
+ public Expression getIn() {
+ return in;
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+}