def visit_class_stmt(self, stmt: Class) -> object: environment = self.env superclass = None if stmt.superclass: superclass = self.evaluate(stmt.superclass) if not isinstance(superclass, LoxClass): msg = "Superclass must be a class." raise PloxRuntimeError(stmt.superclass.name, msg) environment.define(stmt.name.lexeme, None) if stmt.superclass: environment = Environment(environment) environment.define('super', superclass) methods = {} for method in stmt.methods: is_initializer = method.name.lexeme == 'init' is_getter = method.getter function = LoxFunction(method, environment, is_initializer, is_getter) methods[method.name.lexeme] = function klass = LoxClass(stmt.name.lexeme, superclass, methods) if superclass: environment = environment.enclosing environment.assign(stmt.name, klass) return None
def call(self, interpreter, arguments): environment = Environment(self.closure) for param, arg in zip(self.declaration.params, arguments): environment.define(param.lexeme, None) environment.assign(param, arg) try: interpreter._execute_block(self.declaration.body, environment) except PloxReturnException as return_value: if self.is_initializer: return self.closure.get_at(0, 'this') return return_value.value if self.is_initializer: return self.closure.get_at(0, "this") return None