public object visitFunctionStmt(Stmt.Function stmt) { LoxFunction function = new LoxFunction(function: stmt, closure: environment, false); environment.Define(function); return(null); }
public LoxClass(string name, LoxClass superclass, Dictionary <string, LoxFunction> staticMethods, Dictionary <string, LoxFunction> methods) { this.name = name; this.superclass = superclass; this.staticMethods = staticMethods; this.methods = methods; initializer = FindMethod("init"); }
public object visitSuperExpr(Expr.Super expr) { var exprLocationData = locals[expr]; LoxClass superclass = (LoxClass)environment.GetAt(exprLocationData.depth, exprLocationData.index); // We know "this" is one environment removed from "super" because of the way we set the environments up // in visitClassStmt. Hacky fix but it works. We also know its index is 0 because "this" is the only variable // in its environment. LoxInstance instance = (LoxInstance)environment.GetAt(exprLocationData.depth - 1, 0); LoxFunction method = superclass.FindMethod(expr.method.lexeme); if (method == null) { throw new RuntimeError(expr.method, "Undefined superclass property '" + expr.method.lexeme + "'."); } return(method.Bind(instance)); }
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."); } } int classIndex = environment.Define(null); if (stmt.superclass != null) { environment = new Environment(enclosing: environment); environment.Define(superclass); } Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>(); foreach (Stmt.Function method in stmt.methods) { LoxFunction loxFunc = new LoxFunction(method, closure: environment, method.name.lexeme == "init"); methods.Add(method.name.lexeme, loxFunc); } Dictionary <string, LoxFunction> staticMethods = new Dictionary <string, LoxFunction>(); foreach (Stmt.Function method in stmt.staticMethods) { LoxFunction loxFunc = new LoxFunction(method, closure: environment, false); staticMethods.Add(method.name.lexeme, loxFunc); } LoxClass loxClass = new LoxClass(stmt.name.lexeme, (LoxClass)superclass, staticMethods, methods); if (stmt.superclass != null) { environment = environment.enclosing; } environment.Assign(classIndex, loxClass); return(null); }
public object Get(Token name) { // Fields shadow properties if (fields.TryGetValue(name.lexeme, out object value)) { return(value); } // Property LoxFunction method = loxClass.FindMethod(name.lexeme); if (method != null) { return(method.Bind(this)); } throw new RuntimeError(name, "Undefined property '" + name.data + "'."); }