public LoxFunction Bind(LoxInstance instance) { Environment environment = new Environment(_closure); environment.Define("this", instance); return(new LoxFunction(_declaration, environment, _isInitializer)); }
public object Call(Interpreter interpreter, List <object> arguments) { Environment environment = new Environment(_closure); for (int i = 0; i < _declaration.Parameter.Count; i++) { environment.Define(_declaration.Parameter[i].Lexeme, arguments[i]); } try { interpreter.ExecuteBlock(_declaration.Body, environment); } catch (Return returnValue) { if (_isInitializer) { return(_closure.GetAt(0, "this")); } return(returnValue.Value); } if (_isInitializer) { return(_closure.GetAt(0, "this")); } return(null); }
internal Interpreter() { Globals = new Environment(); _environment = Globals; Globals.Define("clock", new Globals.Clock() as ILoxCallable); }
public LoxVoid VisitClassStmt(Stmt.Class stmt) { Option <LoxClass> superclassOption = stmt.Superclass.Match( some: variableStmt => { object superclassObj = Evalutate(variableStmt); if (superclassObj is LoxClass superclass) { return(superclass.Some()); } throw new RuntimeError(variableStmt.Name, "Superclass must be a class"); }, none: Option.None <LoxClass> ); _environment.Define(stmt.Name.Lexeme, null); superclassOption.MatchSome(super => { _environment = new Environment(_environment); _environment.Define("super", super); }); Dictionary <string, LoxFunction> methods = stmt.Methods .Select(method => ( name: method.Name.Lexeme, method: new LoxFunction(method, _environment, method.Name.Lexeme == "init") )) .ToDictionary( x => x.name, x => x.method ); LoxClass @class = new LoxClass(stmt.Name.Lexeme, superclassOption, methods); superclassOption.MatchSome(super => { _environment = _environment.Enclosing.Match( some: env => env, none: () => throw new Exception("Expected enclosing scope none found") ); }); _environment.Assign(stmt.Name, @class); return(null); }
internal void ExecuteBlock(List <Stmt> statments, Environment environment) { Environment previous = _environment; try { _environment = environment; foreach (Stmt statement in statments) { Execute(statement); } } finally { this._environment = previous; } }
public LoxFunction(Stmt.Function declaration, Environment closure, bool isInitializer) { _closure = closure; _declaration = declaration; _isInitializer = isInitializer; }
internal LoxLambda(Expr.Lambda declaration, Environment closure) { _closure = closure; _declaration = declaration; }