public void VisitClassStmt(ClassStmt stmt) { Declare(stmt.Name); Define(stmt.Name); var enclosingClass = currentClass; currentClass = ClassType.Class; if (stmt.SuperClass != null) { currentClass = ClassType.SubClass; Resolve(stmt.SuperClass); BeginScope(); scopes.Peek().Add("super", new VariableData { Defined = true, Line = stmt.Name.Line, Used = true }); } BeginScope(); scopes.Peek().Add("this", new VariableData { Defined = true, Line = stmt.Name.Line, Used = true }); foreach (var method in stmt.Methods) { var declaration = FunctionType.Method; if (method.Name.Lexeme.Equals("init")) { declaration = FunctionType.Initializer; } ResolveFunction(method, declaration); } EndScope(); if (stmt.SuperClass != null) { EndScope(); } currentClass = enclosingClass; }
public void VisitClassStmt(ClassStmt stmt) { environment.Define(stmt.Name.Lexeme, null); object superClass = null; if (stmt.SuperClass != null) { superClass = Evaluate(stmt.SuperClass); if (!(superClass is LoxClass)) { throw new RuntimeError(stmt.SuperClass.Name, "Superclass must be class."); } environment = new Environment(environment); environment.Define("super", superClass); } var methods = new Dictionary <string, LoxFunction>(); foreach (var method in stmt.Methods) { var function = new LoxFunction(method, environment, method.Name.Lexeme.Equals("init")); methods.Add(method.Name.Lexeme, function); } var klass = new LoxClass(stmt.Name.Lexeme, (LoxClass)superClass, methods); if (stmt.SuperClass != null) { environment = environment.Enclosing; } environment.Assign(stmt.Name, klass); }