package org.simantics.scl.compiler.elaboration.expressions;\r
\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
import java.util.ArrayList;\r
\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.constants.NoRepConstant;\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.internal.interpreted.IExpression;\r
import org.simantics.scl.compiler.internal.interpreted.IListLiteral;\r
import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
+import org.simantics.scl.compiler.types.Skeletons;\r
+import org.simantics.scl.compiler.types.TFun;\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.kinds.Kinds;\r
import org.simantics.scl.compiler.types.util.MultiFunction;\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 EApply extends Expression {\r
- Expression function;\r
- Expression[] parameters;\r
+ public Expression function;\r
+ public Expression[] parameters;\r
Type effect = Types.NO_EFFECTS;\r
\r
public EApply(Expression function, Expression ... parameters) {\r
return new IApply(function.toIExpression(target), parametersI);\r
}\r
\r
- @Override\r
- public Expression inferType(TypingContext context) {\r
+ private void inferType(TypingContext context, boolean ignoreResult) {\r
function = function.inferType(context);\r
function = context.instantiate(function);\r
MultiFunction mfun;\r
setType(Types.metaVar(Kinds.STAR));\r
for(int i=0;i<parameters.length;++i)\r
parameters[i] = parameters[i].inferType(context);\r
- return this;\r
+ return;\r
+ }\r
+ if((ignoreResult && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun &&\r
+ Types.canonical(mfun.effect) == Types.NO_EFFECTS) ||\r
+ (context.isInPattern() && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun)) {\r
+ context.getErrorLog().log(location, "The function is applied with too few parameters.");\r
}\r
\r
// Check parameter types\r
\r
context.declareEffect(location, mfun.effect);\r
setType(mfun.returnType);\r
-\r
+ }\r
+ \r
+ @Override\r
+ public Expression inferType(TypingContext context) {\r
+ inferType(context, false);\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public Expression checkIgnoredType(TypingContext context) {\r
+ inferType(context, true);\r
+ if(Types.canonical(getType()) != Types.UNIT)\r
+ return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT));\r
return this;\r
}\r
\r
public Expression accept(ExpressionTransformer transformer) {\r
return transformer.transform(this);\r
}\r
+ \r
+ @Override\r
+ public boolean equalsExpression(Expression expression) {\r
+ if(expression.getClass() != getClass())\r
+ return false;\r
+ EApply other = (EApply)expression;\r
+ if(parameters.length != other.parameters.length)\r
+ return false;\r
+ if(!function.equalsExpression(other.function))\r
+ return false;\r
+ for(int i=0;i<parameters.length;++i)\r
+ if(!parameters[i].equalsExpression(other.parameters[i]))\r
+ return false;\r
+ return true;\r
+ }\r
}\r