public Void VisitFunctionStmt(Stmt.Function stmt) { ElizFunction function = new ElizFunction(stmt, environment, false); environment.Define(stmt.name.Lexeme, function); return(null); }
public object VisitBaseExpr(Expr.Base expr) { int distance = locals[expr]; ElizClass superclass = (ElizClass)environment.GetAt(distance, "base"); // "this" is always one level nearer than "super"'s environment. ElizInstance @object = (ElizInstance)environment.GetAt(distance - 1, "this"); ElizFunction method = superclass.FindMethod(expr.method.Lexeme); if (method == null) { throw new RuntimeError(expr.method, $"Undefined property '{expr.method.Lexeme}'."); } return(method.Bind(@object)); }
public Void VisitClassStmt(Stmt.Class stmt) { object baseclass = null; if (stmt.baseclass != null) { baseclass = Evaluate(stmt.baseclass); if (!(baseclass is ElizClass)) { throw new RuntimeError(stmt.baseclass.name, "Baseclass must be a class."); } } environment.Define(stmt.name.Lexeme, null); if (stmt.baseclass != null) { environment = new Environment(environment); environment.Define("base", baseclass); } Dictionary <string, ElizFunction> methods = new Dictionary <string, ElizFunction>(); foreach (Stmt.Function method in stmt.methods) { ElizFunction function = new ElizFunction(method, environment, method.name.Lexeme.Equals("init")); methods[method.name.Lexeme] = function; } ElizClass klass = new ElizClass(stmt.name.Lexeme, (ElizClass)baseclass, methods); if (baseclass != null) { environment = environment.enclosing; } environment.Assign(stmt.name, klass); return(null); }