public override bool Reduce(IVariableMap<Expression> Map, ref Expression Reduced) { // Beta reduction (substituting an argument in a function definition) FunctionDefineExpression fde = this.Function as FunctionDefineExpression; if (fde != null) { Reduced = fde.SubstituteCall(this.Argument); return true; } // Recursive reduction Expression fre = this.Function; Expression are = this.Argument; if (fre.Reduce(Map, ref fre) | are.Reduce(Map, ref are)) { Reduced = new FunctionCallExpression(fre, are); return true; } return false; }
public override void TypeCheck( IVariableStack<Expression> TypeStack, IVariableStack<Expression> Stack, out Expression TypeSafeExpression, out Expression Type) { int li = TypeStack.NextFreeIndex; Expression sfunc; Expression functype; this.Function.TypeCheck(TypeStack, Stack, out sfunc, out functype); FunctionDefineExpression fte; while ((fte = functype as FunctionDefineExpression) == null && functype.Reduce(Stack, ref functype)) ; if (fte == null) { throw new NotCallableException(this); } Expression sarg; Expression argtype; this.Argument.TypeCheck(TypeStack, Stack, out sarg, out argtype); FuzzyBool typeokay = Expression.Equivalent(ref argtype, ref fte.ArgumentType, Stack); if (typeokay != FuzzyBool.True) { throw new TypeCheckException(this); } TypeSafeExpression = new FunctionCallExpression(sfunc, sarg); Type = fte.Function.SubstituteOne(Stack.NextFreeIndex, sarg); }
/// <summary> /// Parses an expression that can not be broken apart with an operator. /// </summary> public static bool AcceptTightExpression(string Text, int Start, out Expression Expression, out int LastChar) { // Normal if (AcceptAtom(Text, Start, out Expression, out LastChar)) { int nc = 0; while (true) { // Try to get a function if (AcceptString(Text, LastChar, "(", out nc)) { List<Expression> exps; AcceptExpressions(Text, nc, out exps, out nc); if (AcceptString(Text, nc, ")", out nc)) { LastChar = nc; Expression = new FunctionCallExpression(Expression, exps); continue; } } // Try to get an accessor if (AcceptString(Text, LastChar, ".", out nc)) { string accessname; if (AcceptWord(Text, nc, out accessname, out nc)) { LastChar = nc; Expression = new AccessorExpression(Expression, accessname); continue; } } break; } return true; } // Lambda if (AcceptString(Text, Start, "(", out LastChar)) { AcceptWhitespace(Text, LastChar, out LastChar); List<KeyValuePair<Expression, string>> arglist; AcceptArgumentList(Text, LastChar, out arglist, out LastChar); AcceptWhitespace(Text, LastChar, out LastChar); if (AcceptString(Text, LastChar, ")", out LastChar)) { AcceptWhitespace(Text, LastChar, out LastChar); if (AcceptString(Text, LastChar, "=>", out LastChar)) { AcceptWhitespace(Text, LastChar, out LastChar); Expression def; if (AcceptExpression(Text, LastChar, out def, out LastChar)) { Expression = new FunctionDefineExpression(arglist, def); return true; } } } } Expression = null; return false; }