public void Visit(Stmt.Class 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.name, "Superclass must be a class."); } environment = new Environment(environment); environment.Define("super", superclass); } Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>(); foreach (Stmt.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); }
public void Visit(Stmt.Class stmt) { Declare(stmt.name); Define(stmt.name); ClassType enclosingClass = currentClass; currentClass = ClassType.Class; if (stmt.superclass != null) { currentClass = ClassType.Subclass; Resolve(stmt.superclass); BeginScope(); Token superToken = new Token(TokenType.Super, "super", null, stmt.name.line); scopes.Peek().Add("super", new Tracker(superToken, true, 1)); } BeginScope(); Token thisToken = new Token(TokenType.This, "this", null, stmt.name.line); scopes.Peek().Add("this", new Tracker(thisToken, true, 1)); // implicit reference in case 'this' is never used foreach (Stmt.Function method in stmt.methods) { FunctionType declaration = FunctionType.Method; if (method.name.lexeme == "init") { declaration = FunctionType.Initializer; } ResolveFunction(method, declaration); } EndScope(); if (stmt.superclass != null) { EndScope(); } currentClass = enclosingClass; }