public object VisitCallExpr(Expr.Call expr) { object callee = Evaluate(expr.callee); List <object> arguments = new List <object>(); foreach (Expr argument in expr.arguments) { arguments.Add(Evaluate(argument)); } if (!(callee is ICallable)) { throw new RuntimeError(expr.paren, "Can only call functions and classes."); } ICallable function = (ICallable)callee; if (arguments.Count != function.Arity()) { throw new RuntimeError(expr.paren, "Expected " + function.Arity() + " arguments but got " + arguments.Count + "."); } return(function.Call(this, arguments)); }
public object Visit(Call expr) { object callee = Evaluate(expr.callee); List <object> arguments = new List <object>(); foreach (Expr argument in expr.arguments) { arguments.Add(Evaluate(argument)); } if (!(callee is ICallable)) { throw new ErrorHandler.RuntimeError(expr.paren, "Can't call this datatype: " + (callee == null ? "null" : callee.ToString())); } ICallable called = (ICallable)callee; if (arguments.Count != called.Arity()) { throw new ErrorHandler.RuntimeError(expr.paren, "Expected " + called.Arity() + " arguments but received " + arguments.Count); } return(called.Call(this, expr.paren, arguments)); }
public object VisitCallExpression(CallExpression expression) { object callee = Evaluate(expression.callee); List <object> arguments = new List <object>(); foreach (IExpression argument in expression.arguments) { arguments.Add(Evaluate(argument)); } // Incorrect call, the calle cannot be called (ie. "some string"() ) if (callee is ICallable == false) { throw new RuntimeError(expression.paren, "Can only call functions and classes."); } ICallable function = (ICallable)callee; // Not correct number of arguments if (arguments.Count != function.Arity()) { // TODO: Might want to make it like JavaScript where it uses null when not enough, and discards when too many throw new RuntimeError(expression.paren, $"Expected {function.Arity()} arguments but got {arguments.Count}."); } return(function.Call(this, expression, arguments)); }