/// <summary> /// ClassStmt /// CLASS ID LBRACES DeclarationStmt* RBRACES /// </summary> /// <returns></returns> private ClassStmt ParseClassStmt() { Consume(TokenType.CLASS); ClassStmt ret = new ClassStmt(Consume(TokenType.ID).Literal); FuncStmt fs = null; FuncStmt fcur = null; VarStmt vs = null; VarStmt vcur = null; Consume(TokenType.LBRACES); while (!Check(TokenType.RBRACES)) { DeclarationStmt stmt = ParseDeclOrDefStmt(); if (stmt is FuncStmt) { AppendASTLinkedList(ref fs, ref fcur, (FuncStmt)stmt); } else { AppendASTLinkedList(ref vs, ref vcur, (VarStmt)stmt); } } Consume(TokenType.RBRACES); ret.Methods = fs; ret.Fields = vs; return(ret); }
protected override void MatchClassStmt(ClassStmt stmt) { var enclosingClass = _currentClass; _currentClass = ClassType.CLASS; Declare(stmt.Name); if (stmt.Superclass != null) { _currentClass = ClassType.SUBCLASS; Resolve(stmt.Superclass); } Define(stmt.Name); if (stmt.Superclass != null) { BeginScope(); _scopes.Peek()["super"] = true; } BeginScope(); _scopes.Peek()["this"] = true; foreach (var method in stmt.Methods) { var declaration = FunctionType.METHOD; if (method.Name.Lexeme == "init") { declaration = FunctionType.INITIALIZER; } ResolveFunction(method, declaration); } foreach (var method in stmt.StaticMethods) { var declaration = FunctionType.STATIC; if (method.Name.Lexeme == "init") { Lox.Error(method.Name, "Cannot declare init as static."); } ResolveFunction(method, declaration); } if (stmt.Superclass != null) { EndScope(); } EndScope(); _currentClass = enclosingClass; }
public void Visit(ClassStmt t, IEnvironment env) { ClassInfo ci; try { ci = new ClassInfo(t, env); } catch (Exception e) { result = new ErrorValue(e.Message); return; } env.Put(t.Name, ci); result = t.Name; return; }
public ClassInfo(ClassStmt cs, IEnvironment env) { definition = cs; environment = env; object obj = cs.SuperClass != null?env.Get(cs.SuperClass) : null; if (obj == null) { superClass = null; } else if (obj is ClassInfo) { superClass = obj as ClassInfo; } else { throw new EvalException("unknown super class: " + cs.SuperClass, cs); } }
public void visit_class(ClassStmt class_stmt) { object superclass = null; // Check if we have a superclass, and if so, evaluate that if (class_stmt.superclass != null) { superclass = evaluate(class_stmt.superclass); if (!(superclass is PlutoClass)) { throw new RuntimeException("Superclass must be a class type"); } } this.local_scope.define((string)class_stmt.name.value, null); if (class_stmt.superclass != null) { // Create a new scope for the superclass class local_scope = new Scope(local_scope); // Define super as the superclass local_scope.define("super", superclass); } // Create a dictionary of methods for the class Dictionary <string, PlutoFunction> methods = new Dictionary <string, PlutoFunction>(); foreach (FunctionStmt method in class_stmt.methods) { bool is_constructor = ((string)method.name.value) == (string)class_stmt.name.value; PlutoFunction function = new PlutoFunction(method, this.local_scope, is_constructor); methods.Add((string)method.name.value, function); } // Create the class object and assign it to the scope PlutoClass p_class = new PlutoClass((string)class_stmt.name.value, (PlutoClass)superclass, methods); if (superclass != null) { // Reset the scope local_scope = local_scope.enclosing_scope; } local_scope.assign(class_stmt.name, p_class); }
public void visit_class(ClassStmt class_stmt) { ClassType enclosing_class = class_type; class_type = ClassType.Class; declare(class_stmt.name); if (class_stmt.superclass != null) { resolve(class_stmt.superclass); } define(class_stmt.name); // Add the scope of the superclass if (class_stmt.superclass != null) { class_type = ClassType.SubClass; start_scope(); scopes.Peek()["super"] = true; } // Start the scope of this class start_scope(); scopes.Peek()["this"] = true; foreach (FunctionStmt method in class_stmt.methods) { FunctionType decleration = FunctionType.Method; // Check if we have a constructor if ((string)method.name.value == (string)class_stmt.name.value) { decleration = FunctionType.Constructor; } resolve_function(method, decleration); } end_scope(); if (class_stmt.superclass != null) { end_scope(); } class_type = enclosing_class; }
protected abstract void MatchClassStmt(ClassStmt classStmt);