private Expression ParseExpression() { Expression first = ParseExpressionAtom(); while (IsOperator(_lookahead.Kind)) { Token token = ReadToken(); string name = TokenKindToOperatorName(token.Position, token.Kind); Expression other = ParseExpressionAtom(); first = new FunctionExpression(token.Position, name, new Expression[] { first, other }); } return first; }
public void visit(FunctionExpression that) { Console.Write("{0}(", that.Name); foreach (Expression argument in that.Arguments) { argument.visit(this); if (argument != that.Arguments[that.Arguments.Length - 1]) Console.Write(", "); } Console.Write(")"); }
public void visit(FunctionExpression that) { // let the arguments resolve their types foreach (Expression argument in that.Arguments) argument.visit(this); // mangle the parameter list so as to be able to look up the mangled symbol System.Text.StringBuilder mangled = new System.Text.StringBuilder(64); that.Encode(mangled); string name = mangled.ToString(); // look up the function declaration Declaration declaration = _symbols.Lookup(name); if (declaration == null) throw new CheckerError(that.Position, "Unknown function name '" + Demangler.Decode(name) + "' in function call"); // check that the symbol is actually a function switch (declaration.Kind) { case SymbolKind.Constant: throw new CheckerError(that.Position, "Cannot call constant"); case SymbolKind.Function: break; case SymbolKind.Parameter: throw new CheckerError(that.Position, "Cannot call parameter"); case SymbolKind.Variable: throw new CheckerError(that.Position, "Cannot call variable"); default: throw new CheckerError(declaration.Position, "Unknown symbol kind: " + declaration.Kind.ToString()); } // check that the number of arguments match the number of parameters FunctionDeclaration function = (FunctionDeclaration) declaration; if (that.Arguments.Length != function.Parameters.Length) throw new CheckerError(that.Position, "Incorrect number of parameters in function call"); // check that the argument types match the parameter types for (int i = 0; i < that.Arguments.Length; i++) { if (that.Arguments[i].Type.Kind != function.Parameters[i].Type.Kind) throw new CheckerError(that.Arguments[i].Position, "Type mismatch in argument to function"); } that.Type = declaration.Type; }