X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fexpressions%2FESimpleLet.java;h=1a084b3666283ae79e6fa5758e6fec82d047aceb;hp=8e73b2392fd3add380c8e656df2eae19777c2211;hb=2f63e7a58e49a233b28c6968b848281060117c43;hpb=3303fe4a3b363e88662ac75a4f7e873ddb3ab352 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java old mode 100755 new mode 100644 index 8e73b2392..1a084b366 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java @@ -1,220 +1,210 @@ -package org.simantics.scl.compiler.elaboration.expressions; - -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.environment.Environment; -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.elaboration.utils.ExpressionDecorator; -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; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -public class ESimpleLet extends Expression { - Variable variable; // may be null - Expression value; - 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; - } - - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); - in.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - in.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { - setType(in.getType()); - } - - @Override - public IVal toVal(Environment env, CodeWriter w) { - IVal valueVal = value.toVal(env, w); - if(variable != null) - variable.setVal(valueVal); - return in.toVal(env, w); - } - - @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - in.collectFreeVariables(vars); - vars.remove(variable); - } - - @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 Expression decorate(ExpressionDecorator decorator) { - value = value.decorate(decorator); - in = in.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - value.collectEffects(effects); - in.collectEffects(effects); - } - - @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 void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - in.forVariables(procedure); - } - - @Override - public Expression accept(ExpressionTransformer transformer) { - return transformer.transform(this); - } - -} +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; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + +public class ESimpleLet extends Expression { + Variable variable; // may be null + Expression value; + 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; + } + + public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + value.collectRefs(allRefs, refs); + in.collectRefs(allRefs, refs); + } + + @Override + public void collectVars(TObjectIntHashMap allVars, + TIntHashSet vars) { + value.collectVars(allVars, vars); + in.collectVars(allVars, vars); + } + + @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 void collectFreeVariables(THashSet vars) { + value.collectFreeVariables(vars); + in.collectFreeVariables(vars); + vars.remove(variable); + } + + @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 collectEffects(THashSet effects) { + value.collectEffects(effects); + in.collectEffects(effects); + } + + @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(); + } +}