From 647a095a05e566a23023cd4887d80ac82900be2c Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Sat, 28 Jan 2023 21:11:01 +0100 Subject: [PATCH] Interpreter finish --- frontend/src/parser/stmt.rs | 2 +- interpreter/src/environment.rs | 17 +++++++++++------ interpreter/src/error.rs | 2 +- interpreter/src/interpret.rs | 22 +++++++++++++--------- interpreter/src/run.rs | 7 +++---- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/frontend/src/parser/stmt.rs b/frontend/src/parser/stmt.rs index dc7299b..db0506a 100644 --- a/frontend/src/parser/stmt.rs +++ b/frontend/src/parser/stmt.rs @@ -82,7 +82,7 @@ impl Stmt { impl Display for Stmt { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Stmt::Print { expr } => write!(f, "print {expr};"), + Stmt::Print { expr } => write!(f, "(print {expr});"), Stmt::IfStmt { condition, then_branch, diff --git a/interpreter/src/environment.rs b/interpreter/src/environment.rs index f118e5f..11809a6 100644 --- a/interpreter/src/environment.rs +++ b/interpreter/src/environment.rs @@ -36,22 +36,27 @@ impl<'a> Environment<'a> { self.local_scopes.push(Scope::new()); } - pub fn push_scope(&mut self, scope: Scope) { - self.local_scopes.push(scope); - } - pub fn exit_scope(&mut self) { // self.current_frame_mut().exit_scope(); self.local_scopes.pop().expect("Tried to pop global scope"); } + pub fn insert_closure(&mut self, closure: Scope) { + let scope = self.local_scopes.last_mut().unwrap(); + + for (name, value) in closure { + scope.insert(name, value); + } + } + pub fn get_global(&self, name: &str) -> Result { self.runtime.get_global(name) } pub fn get_local(&self, name: &str, level: usize) -> Result { - if let Some(scope) = self.local_scopes.iter().rev().nth(level) { - if let Some(heap_value) = scope.get(name) { + let len = self.local_scopes.len(); + if level < len { + if let Some(heap_value) = self.local_scopes[len - level - 1].get(name) { return Ok(heap_value.get_clone()); } } diff --git a/interpreter/src/error.rs b/interpreter/src/error.rs index 6efdf5b..1467393 100644 --- a/interpreter/src/error.rs +++ b/interpreter/src/error.rs @@ -16,7 +16,7 @@ pub enum RuntimeError { BinaryOpInvalidArguments { left: Value, op: BinaryOp, right: Value }, #[error("Division by zero")] DivisionByZero, - #[error("Name {name} is not defined")] + #[error("Local {name} is not defined")] NameNotDefined { name: String }, #[error("Global {name} is not defined")] GlobalNotDefined { name: String }, diff --git a/interpreter/src/interpret.rs b/interpreter/src/interpret.rs index fcf995e..61065f2 100644 --- a/interpreter/src/interpret.rs +++ b/interpreter/src/interpret.rs @@ -133,7 +133,7 @@ impl Eval for Expr { .collect::>>()?; match callee { - Value::Function(fun) => fun.call(args, env), + Value::Function(fun) => LoxFunction::call(fun, args, env), Value::ExternFunction(ext_fun) => ext_fun.call(args, env), Value::Class(class) => LoxClass::call(class, args, env), _ => Err(RuntimeError::NotCallable { callee }), @@ -286,22 +286,26 @@ impl Eval for Stmt { /*====================================================================================================================*/ impl LoxFunction { - pub fn call(&self, args: Vec, env: &mut Environment) -> EvalResult { - if args.len() != self.arity() { + pub fn call(fun: Rc, args: Vec, env: &mut Environment) -> EvalResult { + if args.len() != fun.arity() { return Err(RuntimeError::WrongArity { - name: self.name().to_owned(), - arity: self.arity(), + name: fun.name().to_owned(), + arity: fun.arity(), given: args.len(), }); } - env.push_scope(self.closure().clone()); + env.enter_scope(); - for (name, value) in std::iter::zip(self.param_names(), args) { + env.define(fun.name(), Value::Function(fun.clone())); + + env.insert_closure(fun.closure().clone()); + + for (name, value) in std::iter::zip(fun.param_names(), args) { env.define(name, value); } - let ret_val = match self.body().eval(env) { + let ret_val = match fun.body().eval(env) { Ok(_) => Ok(Value::Nil), Err(RuntimeError::Return { value }) => Ok(value), Err(err) => Err(err), @@ -343,7 +347,7 @@ impl LoxClass { // object.init(args, env)?; if let Some(Value::Function(method)) = object.get("init") { - method.call(args, env)?; + LoxFunction::call(method, args, env)?; } Ok(Value::Object(object)) diff --git a/interpreter/src/run.rs b/interpreter/src/run.rs index 2de073b..5828ed3 100644 --- a/interpreter/src/run.rs +++ b/interpreter/src/run.rs @@ -103,12 +103,11 @@ fn run(code_string: &str, runtime: &mut Runtime) -> Result<(), LoxError> { println!("{statement}"); } */ - /* for statement in statements.iter() { - println!("{statement}"); - } */ - for mut statement in statements { resolve(&mut statement, runtime)?; + + // println!("{statement}"); + execute(statement, runtime)?; }