private void ResolveClassStatement(ClassStatement expr) { ClassType enclosingClass = _currentClass; _currentClass = ClassType.Class; Declare(expr.Name); Define(expr.Name); if (expr.SuperClass != null && expr.Name.Lexeme.Equals(expr.SuperClass.Name.Lexeme)) { Error(expr.SuperClass.Name, "A class cannot inherit from itself."); } if (expr.SuperClass != null) { _currentClass = ClassType.SubClass; Resolve(expr.SuperClass); } if (expr.SuperClass != null) { BeginScope(); _scopes[_scopes.Count - 1].Add("super", true); } BeginScope(); _scopes[_scopes.Count - 1].Add("this", true); foreach (FunctionStatement method in expr.Methods) { FunctionType declaration = FunctionType.Method; if (method.Name.Lexeme.Equals("init")) { declaration = FunctionType.Initializer; } ResolveFunction(method, declaration); } EndScope(); if (expr.SuperClass != null) { EndScope(); } _currentClass = enclosingClass; }
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); }