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%2FEApply.java;h=c7bce466759d62eaf154c4a0a415b634249903cf;hp=8df327362560bc8574eefc96542d9e6f4da4de4a;hb=862c09c9608329f326404342d12da61792eece2c;hpb=eecd74faded034bd067094b42bbac0d286d8d9fa diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java old mode 100755 new mode 100644 index 8df327362..c7bce4667 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java @@ -1,400 +1,420 @@ -package org.simantics.scl.compiler.elaboration.expressions; - -import java.util.ArrayList; - -import org.simantics.scl.compiler.common.names.Name; -import org.simantics.scl.compiler.constants.NoRepConstant; -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.elaboration.errors.NotPatternException; -import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; -import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs; -import org.simantics.scl.compiler.elaboration.java.ListConstructor; -import org.simantics.scl.compiler.elaboration.macros.MacroRule; -import org.simantics.scl.compiler.elaboration.modules.SCLValue; -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.IApply; -import org.simantics.scl.compiler.internal.interpreted.IExpression; -import org.simantics.scl.compiler.internal.interpreted.IListLiteral; -import org.simantics.scl.compiler.top.ExpressionInterpretationContext; -import org.simantics.scl.compiler.types.Skeletons; -import org.simantics.scl.compiler.types.TFun; -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.exceptions.UnificationException; -import org.simantics.scl.compiler.types.kinds.Kinds; -import org.simantics.scl.compiler.types.util.MultiFunction; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -public class EApply extends Expression { - Expression function; - Expression[] parameters; - Type effect = Types.NO_EFFECTS; - - public EApply(Expression function, Expression ... parameters) { - this.function = function; - this.parameters = parameters; - } - - public EApply(Expression function, Expression parameter) { - this(function, new Expression[] {parameter}); - } - - public EApply(long loc, Expression function, Expression ... parameters) { - super(loc); - this.function = function; - this.parameters = parameters; - } - - public EApply(long loc, Type effect, Expression function, Expression ... parameters) { - super(loc); - this.effect = effect; - this.function = function; - this.parameters = parameters; - } - - public void set(Expression function, Expression[] parameters) { - this.function = function; - this.parameters = parameters; - } - - public Expression getFunction() { - return function; - } - - public Expression[] getParameters() { - return parameters; - } - - - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - function.collectRefs(allRefs, refs); - for(Expression parameter : parameters) - parameter.collectRefs(allRefs, refs); - } - - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - function.collectVars(allVars, vars); - for(Expression parameter : parameters) - parameter.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { - MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); - /*for(int i=0;i vars) { - function.collectFreeVariables(vars); - for(Expression parameter : parameters) - parameter.collectFreeVariables(vars); - } - - private void combineApplications() { - if(function instanceof EApply) { - EApply apply = (EApply)function; - if(Types.canonical(apply.effect) == Types.NO_EFFECTS) { - function = apply.function; - parameters = Expression.concat(apply.parameters, parameters); - } - } - } - - @Override - public Expression simplify(SimplificationContext context) { - function = function.simplify(context); - for(int i=0;i parameters) { - function.getParameters(context, parameters); - for(Expression parameter : this.parameters) - parameters.add(parameter); - } - - @Override - public void removeFreeVariables(THashSet vars) { - function.removeFreeVariables(vars); - for(Expression parameter : parameters) - parameter.removeFreeVariables(vars); - } - - @Override - public Expression replace(ReplaceContext context) { - return new EApply( - getLocation(), - effect.replace(context.tvarMap), - function.replace(context), - replace(context, parameters)); - } - - @Override - public void setLocationDeep(long loc) { - if(location == Locations.NO_LOCATION) { - location = loc; - function.setLocationDeep(loc); - for(Expression parameter : parameters) - parameter.setLocationDeep(loc); - } - } - - @Override - public int getFunctionDefinitionArity() throws NotPatternException { - return function.getFunctionDefinitionArity() + parameters.length; - } - - @Override - public IExpression toIExpression(ExpressionInterpretationContext target) { - IExpression[] parametersI = toIExpressions(target, parameters); - - Expression function = this.function; - while(function instanceof EApplyType) - function = ((EApplyType)function).expression; - - // Special cases - if(function instanceof EConstant) { - SCLValue functionValue = ((EConstant)function).value; - Name name = functionValue.getName(); - if(name.module.equals("Builtin")) { - IVal val = functionValue.getValue(); - if(val instanceof ListConstructor) { - if(((ListConstructor)val).arity == parametersI.length) - return new IListLiteral(parametersI); - } - } - } - //System.out.println("--> " + function + " " + function.getClass().getSimpleName()); - - // The basic case - return new IApply(function.toIExpression(target), parametersI); - } - - private void inferType(TypingContext context, boolean ignoreResult) { - function = function.inferType(context); - function = context.instantiate(function); - MultiFunction mfun; - try { - mfun = Types.unifyFunction(function.getType(), parameters.length); - } catch (UnificationException e) { - int arity = Types.getArity(function.getType()); - if(arity == 0) - context.getErrorLog().log(location, "Application of non-function."); - else - context.getErrorLog().log(location, "Function of arity " + arity + - " is applied with " + parameters.length + " parameters."); - setType(Types.metaVar(Kinds.STAR)); - for(int i=0;i=0;--i) { - Expression parameter = parameters[i]; - if(parameter.isEffectful()) { - Variable var = new Variable("aNormalTemp" + i, parameter.getType()); - expression = new ESimpleLet(var, parameter, expression); - parameters[i] = new EVariable(var); - } - } - if(function.isEffectful()) { - Variable var = new Variable("aNormalTempF", function.getType()); - expression = new ESimpleLet(var, function, expression); - function = new EVariable(var); - } - return expression; - } - - @Override - public boolean isEffectful() { - if(effect != Types.NO_EFFECTS) - return true; - for(Expression parameter : parameters) - if(parameter.isEffectful()) - return true; - if(function.isEffectful()) - return true; - return false; - } - - @Override - public boolean isFunctionPattern() { - return !isConstructorApplication(); - } - - @Override - public boolean isConstructorApplication() { - return function.isConstructorApplication(); - } - - @Override - public void collectEffects(THashSet effects) { - effects.add(effect); - function.collectEffects(effects); - for(Expression parameter : parameters) - parameter.collectEffects(effects); - } - - @Override - public void accept(ExpressionVisitor visitor) { - visitor.visit(this); - } - - @Override - public boolean isFunctionDefinitionLhs() { - try { - EVar patternHead = function.getPatternHead(); - return !Character.isUpperCase(patternHead.name.charAt(0)); - } catch(NotPatternException e) { - return false; - } - } - - @Override - public void forVariables(VariableProcedure procedure) { - function.forVariables(procedure); - for(Expression parameter : parameters) - parameter.forVariables(procedure); - } - - @Override - public boolean isPattern(int arity) { - if(!function.isPattern(arity+parameters.length)) - return false; - for(Expression parameter : parameters) - if(!parameter.isPattern(0)) - return false; - return true; - } - - @Override - public Expression accept(ExpressionTransformer transformer) { - return transformer.transform(this); - } -} +package org.simantics.scl.compiler.elaboration.expressions; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.common.names.Names; +import org.simantics.scl.compiler.compilation.CompilationContext; +import org.simantics.scl.compiler.constants.NoRepConstant; +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.elaboration.errors.NotPatternException; +import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; +import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs; +import org.simantics.scl.compiler.elaboration.java.ListConstructor; +import org.simantics.scl.compiler.elaboration.macros.MacroRule; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +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.IApply; +import org.simantics.scl.compiler.internal.interpreted.IExpression; +import org.simantics.scl.compiler.internal.interpreted.IListLiteral; +import org.simantics.scl.compiler.top.ExpressionInterpretationContext; +import org.simantics.scl.compiler.types.Skeletons; +import org.simantics.scl.compiler.types.TFun; +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.exceptions.UnificationException; +import org.simantics.scl.compiler.types.kinds.Kinds; +import org.simantics.scl.compiler.types.util.MultiFunction; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + +public class EApply extends Expression { + public Expression function; + public Expression[] parameters; + Type effect = Types.NO_EFFECTS; + + public EApply(Expression function, Expression ... parameters) { + this.function = function; + this.parameters = parameters; + } + + public EApply(Expression function, Expression parameter) { + this(function, new Expression[] {parameter}); + } + + public EApply(long loc, Expression function, Expression ... parameters) { + super(loc); + this.function = function; + this.parameters = parameters; + } + + public EApply(long loc, Type effect, Expression function, Expression ... parameters) { + super(loc); + this.effect = effect; + this.function = function; + this.parameters = parameters; + } + + public void set(Expression function, Expression[] parameters) { + this.function = function; + this.parameters = parameters; + } + + public Expression getFunction() { + return function; + } + + public Expression[] getParameters() { + return parameters; + } + + + public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + function.collectRefs(allRefs, refs); + for(Expression parameter : parameters) + parameter.collectRefs(allRefs, refs); + } + + public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { + function.collectVars(allVars, vars); + for(Expression parameter : parameters) + parameter.collectVars(allVars, vars); + } + + @Override + protected void updateType() throws MatchException { + MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); + /*for(int i=0;i vars) { + function.collectFreeVariables(vars); + for(Expression parameter : parameters) + parameter.collectFreeVariables(vars); + } + + private void combineApplications() { + if(function instanceof EApply) { + EApply apply = (EApply)function; + if(Types.canonical(apply.effect) == Types.NO_EFFECTS) { + function = apply.function; + parameters = Expression.concat(apply.parameters, parameters); + } + } + } + + @Override + public Expression simplify(SimplificationContext context) { + function = function.simplify(context); + for(int i=0;i parameters) { + function.getParameters(context, parameters); + for(Expression parameter : this.parameters) + parameters.add(parameter); + } + + @Override + public void removeFreeVariables(THashSet vars) { + function.removeFreeVariables(vars); + for(Expression parameter : parameters) + parameter.removeFreeVariables(vars); + } + + @Override + public Expression replace(ReplaceContext context) { + return new EApply( + getLocation(), + effect.replace(context.tvarMap), + function.replace(context), + replace(context, parameters)); + } + + @Override + public void setLocationDeep(long loc) { + if(location == Locations.NO_LOCATION) { + location = loc; + function.setLocationDeep(loc); + for(Expression parameter : parameters) + parameter.setLocationDeep(loc); + } + } + + @Override + public int getFunctionDefinitionPatternArity() throws NotPatternException { + return function.getFunctionDefinitionPatternArity() + parameters.length; + } + + @Override + public IExpression toIExpression(ExpressionInterpretationContext target) { + IExpression[] parametersI = toIExpressions(target, parameters); + + Expression function = this.function; + while(function instanceof EApplyType) + function = ((EApplyType)function).expression; + + // Special cases + if(function instanceof EConstant) { + SCLValue functionValue = ((EConstant)function).value; + Name name = functionValue.getName(); + if(name.module.equals("Builtin")) { + IVal val = functionValue.getValue(); + if(val instanceof ListConstructor) { + if(((ListConstructor)val).arity == parametersI.length) + return new IListLiteral(parametersI); + } + } + } + //System.out.println("--> " + function + " " + function.getClass().getSimpleName()); + + // The basic case + return new IApply(function.toIExpression(target), parametersI); + } + + private void inferType(TypingContext context, boolean ignoreResult) { + function = function.inferType(context); + function = context.instantiate(function); + MultiFunction mfun; + try { + mfun = Types.unifyFunction(function.getType(), parameters.length); + } catch (UnificationException e) { + int arity = Types.getArity(function.getType()); + if(arity == 0) + context.getErrorLog().log(location, "Application of non-function."); + else + context.getErrorLog().log(location, "Function of arity " + arity + + " is applied with " + parameters.length + " parameters."); + setType(Types.metaVar(Kinds.STAR)); + for(int i=0;i=0;--i) { + Expression parameter = parameters[i]; + if(parameter.isEffectful()) { + Variable var = new Variable("aNormalTemp" + i, parameter.getType()); + expression = new ESimpleLet(var, parameter, expression); + parameters[i] = new EVariable(var); + } + } + if(function.isEffectful()) { + Variable var = new Variable("aNormalTempF", function.getType()); + expression = new ESimpleLet(var, function, expression); + function = new EVariable(var); + } + return expression; + } + + @Override + public boolean isEffectful() { + if(effect != Types.NO_EFFECTS) + return true; + for(Expression parameter : parameters) + if(parameter.isEffectful()) + return true; + if(function.isEffectful()) + return true; + return false; + } + + @Override + public boolean isFunctionPattern() { + return !isConstructorApplication(); + } + + @Override + public boolean isConstructorApplication() { + return function.isConstructorApplication(); + } + + @Override + public void collectEffects(THashSet effects) { + effects.add(effect); + function.collectEffects(effects); + for(Expression parameter : parameters) + parameter.collectEffects(effects); + } + + @Override + public void accept(ExpressionVisitor visitor) { + visitor.visit(this); + } + + @Override + public boolean isFunctionDefinitionLhs() { + try { + EVar patternHead = function.getPatternHead(); + return !Character.isUpperCase(patternHead.name.charAt(0)); + } catch(NotPatternException e) { + return false; + } + } + + @Override + public void forVariables(VariableProcedure procedure) { + function.forVariables(procedure); + for(Expression parameter : parameters) + parameter.forVariables(procedure); + } + + @Override + public boolean isPattern(int arity) { + if(!function.isPattern(arity+parameters.length)) + return false; + for(Expression parameter : parameters) + if(!parameter.isPattern(0)) + return false; + return true; + } + + @Override + public Expression accept(ExpressionTransformer transformer) { + return transformer.transform(this); + } + + @Override + public boolean equalsExpression(Expression expression) { + if(expression.getClass() != getClass()) + return false; + EApply other = (EApply)expression; + if(parameters.length != other.parameters.length) + return false; + if(!function.equalsExpression(other.function)) + return false; + for(int i=0;i