public object visitSuperExpr(Expr.Super super) { int distance = -1; locals.TryGetValue(super, out distance); List <LoxClass> superClasses = (List <LoxClass>)environment.getAt(distance, "super"); LoxInstance _object = (LoxInstance)environment.getAt(distance - 1, "this"); LoxFunction method = null; LoxClass foundInClass = null; foreach (LoxClass superClass in superClasses) { LoxFunction methodFind = superClass.findMethod(super.method.lexeme); if (methodFind != null) { if (method != null) { throw new Exceptions.RuntimeError(super.method, "Error: Found '" + super.method.lexeme + "' in " + foundInClass.name + " and " + superClass.name + "."); } method = methodFind; foundInClass = superClass; } } if (method == null) { throw new Exceptions.RuntimeError(super.method, "Undefined property '" + super.method.lexeme + "'."); } return(method.bind(_object)); }
public object VisitFunctionStmt(Stmt.Function stmt) { LoxFunction function = new LoxFunction(stmt, environment, false); environment.Define(stmt.name.lexeme, function); return(null); }
private object EvaluateFunctionStatement(FunctionStatement expr) { LoxFunction function = new LoxFunction(expr, _environment, false); _environment.Define(expr.Name.Lexeme, function); return(null); }
public int arity() { LoxFunction initializer = findMethod("init"); if (initializer == null) { return(0); } return(initializer.arity()); }
public int arity() { LoxFunction initializer = methods.ContainsKey("init") ? methods["init"] : null; if (initializer == null) { return(0); } return(initializer.arity()); }
public object call(Interpreter interpreter, List <object> arguments) { LoxInstance instance = new LoxInstance(this); LoxFunction initializer = findMethod("init"); if (initializer != null) { initializer.bind(instance).call(interpreter, arguments); } return(instance); }
public object call(Interpreter interpreter, List <object> arguments) { LoxInstance instance = new LoxInstance(this); LoxFunction initializer = methods.ContainsKey("init") ? methods["init"] : null; if (initializer != null) { initializer.bind(instance).call(interpreter, arguments); } return(instance); }
public object VisitSuperExpr(Expr.Super expr) { int distance = locals[expr]; // Find reference to the superclass and current instance ("this"). IClass superclass = (IClass)environment.GetAt(distance, "super"); LoxInstance thisInstance = (LoxInstance)environment.GetAt(distance, "this"); // Find method from superclass. LoxFunction method = superclass.FindMethod(thisInstance, expr.method.lexeme); return(method); }
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 }
public object Call(Evaluator evaluator, List <object> arguments) { LoxInstance instance = new LoxInstance(this); LoxFunction initializer = FindMethod("init"); if (initializer != null) { initializer.Bind(instance).Call(evaluator, arguments); } return(instance); }
private object EvaluateSuperExpression(SuperExpression expr) { int distance = _locals[expr]; LoxClass superclass = _environment.GetAt(distance, new Token(SyntaxKind.Super, "super", null, 0)) as LoxClass; LoxInstance obj = _environment.GetAt(distance - 1, new Token(SyntaxKind.This, "this", null, 0)) as LoxInstance; LoxFunction method = superclass.FindMethod(expr.Method.Lexeme); if (method is null) { throw new RuntimeError(expr.Method, $"Undefine property {expr.Method.Lexeme}"); } return(method.Bind(obj)); }
public object get(Token name) { if (fields.ContainsKey(name.lexeme)) { return(fields[name.lexeme]); } LoxFunction method = _class.findMethod(name.lexeme); if (method != null) { return(method.bind(this)); } throw new Exceptions.RuntimeError(name, "Undefined property '" + name.lexeme + "'."); }
public object VisitSuperExpr(Super expr) { int distance = locals[expr]; LoxClass superclass = (LoxClass)environment.GetAt(distance, "super"); LoxInstance obj = (LoxInstance)environment.GetAt(distance - 1, "this"); LoxFunction method = superclass.FindMethod(expr.Method.Lexeme); if (method == null) { throw new RuntimeError(expr.Method, "Undefined property '" + expr.Method.Lexeme + "'."); } return(method.Bind(obj)); }
public object Get(Token name) { if (fields.ContainsKey(name.Lexeme)) { return(fields[name.Lexeme]); } LoxFunction method = klass.FindMethod(name.Lexeme); if (method != null) { return(method.Bind(this)); } throw new RuntimeError(name, "Undefined property '" + name.Lexeme + "'."); }
public object get(Token name) { if (fields.ContainsKey(name.lexeme)) { return(fields[name.lexeme]); } LoxFunction method = klass.findMethod(this, name.lexeme); if (method != null) { return(method); } throw new RuntimeError(name, $"Undefined properrty '{name.lexeme}'."); }
public object visit_Super_Expr(GExpr.Super expr) { int distance = locals[expr]; LoxClass superClass = (LoxClass)environment.getAt(distance, "super"); // "this" is always 1 level nearer than "super's" environment LoxInstance obj = (LoxInstance)environment.getAt(distance - 1, "this"); LoxFunction method = superClass.findMethod(obj, expr.method.lexeme); if (method == null) { throw new RuntimeError(expr.method, $"Undefined property '{expr.method.lexeme}'"); } return(method); }
object Expr.IVisitor <object> .Visit(Expr.Super _super) { int distance = _locals[_super]; LoxClass superclass = (LoxClass)_environment.GetAt(distance, "super"); // "this" is always one level nearer than "super"'s environment. LoxInstance _object = (LoxInstance)_environment.GetAt(distance - 1, "this"); LoxFunction method = superclass.FindMethod(_super.method.lexeme); if (method == null) { throw new RuntimeError(_super.method, "Undefined property '" + _super.method.lexeme + "'."); } return(method.Bind(_object)); }
public Void VisitClassStmt(Stmt.Class stmt) { object superclass = null; if (stmt.Superclass != null) { superclass = Evaluate(stmt.Superclass); if (!(superclass is LoxClass)) { throw new RuntimeError(stmt.Superclass.Name, "Superclass must be a class"); } } _environment.Define(stmt.Name.Lexeme, null); if (stmt.Superclass != null) { _environment = new LoxEnvironment(_environment); _environment.Define("super", superclass); } var methods = new Dictionary <string, LoxFunction>(); foreach (var method in stmt.Methods) { var isInitializer = method.Name.Lexeme.Equals("init", StringComparison.Ordinal); var function = new LoxFunction(method, _environment, isInitializer); methods[method.Name.Lexeme] = function; } var lclass = new LoxClass(stmt.Name.Lexeme, superclass as LoxClass, methods); if (superclass != null) { _environment = _environment.Enclosing; } _environment.Assign(stmt.Name, lclass); return(null); }
public object visit_Class_Stmt(GStmt.Class stmt) { Object superclass = null; if (stmt.superclass != null) { superclass = evaluate(stmt.superclass); if (!(superclass is LoxClass)) { throw new RuntimeError(stmt.superclass.name, "Superclass must be a class"); } } environment.define(stmt.name.lexeme, null); if (stmt.superclass != null) { environment = new Environment(environment); environment.define("super", superclass); } Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>(); foreach (GStmt.Function method in stmt.methods) { LoxFunction function = new LoxFunction(method, environment, method.name.lexeme == "init"); methods.Add(method.name.lexeme, function); } LoxClass klass = new LoxClass(stmt.name.lexeme, (LoxClass)superclass, methods); if (superclass != null) { environment = environment.enclosing; } environment.assign(stmt.name, klass); return(null); }
public object VisitClassStmt(Stmt.Class stmt) { object superclass = null; if (stmt.Superclass != null) { superclass = Evaluate(stmt.Superclass); if (!(superclass is LoxClass)) { throw new RuntimeError(stmt.Superclass.Name, "Superclass must be a class."); } } environment.Define(stmt.Name.Lexeme, null); if (stmt.Superclass != null) { environment = new Environment(environment); environment.Define("super", superclass); } Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>(); foreach (var method in stmt.Methods) { LoxFunction function = new LoxFunction(method, environment, method.Name.Lexeme.Equals("init")); methods[method.Name.Lexeme] = function; } LoxClass klass = new LoxClass(stmt.Name.Lexeme, (LoxClass)superclass, methods); if (superclass != null) { environment = environment.Enclosing; } environment.Assign(stmt.Name, klass); return(null); }
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)); }
private object EvaluateClassStatement(ClassStatement expr) { object superclass = null; if (expr.SuperClass != null) { superclass = Evaluate(expr.SuperClass); if (!(superclass is LoxClass)) { throw new RuntimeError(expr.SuperClass.Name, "Superclass must be a class"); } } _environment.Define(expr.Name.Lexeme, null); if (expr.SuperClass != null) { _environment = new Environment(_environment); _environment.Define("super", superclass); } var methods = new Dictionary <string, LoxFunction>(); foreach (var method in expr.Methods) { var function = new LoxFunction(method, _environment, method.Name.Lexeme.Equals("init")); methods.Add(method.Name.Lexeme, function); } LoxClass klass = new LoxClass(expr.Name.Lexeme, (LoxClass)superclass, methods); if (superclass != null) { _environment = _environment.Enclosing; } _environment.Assign(expr.Name, klass); return(null); }
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); }
public object visitLambdaFunction(Expr.Lambda lambdaFunction) { LoxFunction function = new LoxFunction(lambdaFunction, environment, false); return(function); //If the function is lambda }