public LoxFunction(Statement.function decl, Environment enclosure, bool isIn, bool isGetter) { declaration = decl; closure = enclosure; isInitializer = isIn; this.isGet = isGetter; }
public LoxFunction(Expr.Lambda decl, Environment enclosure, bool isIn) { declaration = new Statement.function(decl.keyword, decl._params, decl.body); closure = enclosure; isInitializer = isIn; isGet = false; }
public LoxFunction(Statement.function decl, Environment enclosure, bool isIn) { declaration = decl; closure = enclosure; isInitializer = isIn; isGet = false; }
public object visitFunction(Statement.function func) { declare(func.name); define(func.name); resolveFunction(func, FunctionType.FUNCTION); return(null); }
public object visitFunction(Statement.function func) { LoxFunction function = new LoxFunction(func, environment, false); if (func.name != null) //If the function is named { environment.define(func.name.lexeme, function, func.name); return(null); } return(function); //If the function is lambda }
private void resolveFunction(Statement.function function, FunctionType type) { FunctionType enclosingFunction = currentFunction; currentFunction = type; beginScope(); foreach (Token _param in function._params) { declare(_param); define(_param); } resolve(function.body); endScope(); currentFunction = enclosingFunction; }
public string visitCallExpr(Expr.Call call) { Expr[] expressions = new Expr[call.expressionArguments.Count]; for (int i = 0; i < call.expressionArguments.Count; i++) { if (call.expressionArguments[i] is Expr) { expressions[i] = (Expr)call.expressionArguments[i]; } else if (call.expressionArguments[i] is Statement.function) { Statement.function lambda = (Statement.function)call.expressionArguments[i]; expressions[i] = new Expr.Lambda(lambda.name, lambda._params, lambda.body); } } return(parenthesize(call.callee.ToString(), expressions)); }
public object visitCallExpr(Expr.Call call) { Object callee = evaluate(call.callee); List <Object> arguments = new List <Object>(); foreach (Object argument in call.expressionArguments) { if (argument is Expr) { arguments.Add(evaluate((Expr)argument)); } else if (argument is Statement.function) { arguments.Add((Statement.function)argument); } } if (!(callee is LoxCallable) && !(callee is Statement.function)) { throw new Exceptions.RuntimeError(call.paren, "Can only call functions and classes."); } else if (callee is Statement.function) { Statement.function staticFunction = (Statement.function)callee; LoxFunction classStaticFunction = new LoxFunction(staticFunction, globals, false); return(classStaticFunction.call(this, arguments)); } LoxCallable function = (LoxCallable)callee; if (arguments.Count != function.arity()) { throw new Exceptions.RuntimeError(call.paren, "Expected " + function.arity() + " arguments but got " + arguments.Count + "."); } return(function.call(this, arguments)); }
public object visitClassStatement(Statement.Class classStatement) { List <LoxClass> superClasses = new List <LoxClass>(); if (classStatement.superclass.Count != 0) { foreach (Object superClass in classStatement.superclass) { Object eval = evaluate((Expr.Variable)superClass); if (!(eval is LoxClass)) { throw new Exceptions.RuntimeError(new HelperFunctions.GetToken().evaluate((Expr)superClass), "Superclass must be a class."); } else { superClasses.Add((LoxClass)eval); } } } environment.define(classStatement.name.lexeme, null, classStatement.name); if (classStatement.superclass.Count != 0) { environment = new Environment(environment); environment.define("super", superClasses); } Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>(); Dictionary <LoxFunction, Token> getters = new Dictionary <LoxFunction, Token>(); List <Statement.function> methodsList = classStatement.methods; foreach (Statement.function method in methodsList) { if (method._params.Count == 1 && method._params.ElementAt(0).type == TokenType.SEMICOLON && method._params.ElementAt(0).lexeme.Equals("getter")) { Statement.function noParams = new Statement.function(method.name, new List <Token>(), method.body); LoxFunction getter = new LoxFunction(noParams, environment, false, true); methods.Add(method.name.lexeme, getter); getters[getter] = method.name; } else { LoxFunction function = new LoxFunction(method, environment, method.name.lexeme.Equals("init")); if (!methods.ContainsKey(method.name.lexeme)) { methods.Add(method.name.lexeme, function); } else { throw new Exceptions.RuntimeError(method.name, "Cannot have two functions with the same name in the same class."); } } } LoxClass _class = new LoxClass(classStatement.name.lexeme, superClasses, methods); foreach (Statement.function staticFunction in classStatement.staticFunctions) { _class.set(staticFunction.name, staticFunction); } foreach (LoxFunction getter in getters.Keys) { _class.set(getters[getter], getter); } if (superClasses.Count != 0) { environment = environment.enclosing; } environment.assign(classStatement.name, _class); return(null); }