From c5f099340bbfa83c2f6cb552e9e7e738bb02c44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Wed, 4 Jan 2023 07:58:44 +0100 Subject: [PATCH] Errors refactoring - Code compiles. --- src/errors.rs | 7 +------ src/interpreter/callable.rs | 8 ++------ src/interpreter/environment.rs | 31 +++++++++++++++++++------------ src/interpreter/functions.rs | 8 ++------ src/interpreter/native_fn.rs | 8 ++------ src/parser.rs | 6 +++++- src/scanner.rs | 8 +++----- 7 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 3766978..6f20f1f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -114,11 +114,6 @@ pub struct ErrorHandler { } impl ErrorHandler { - /// Check whether this handler reported an error. - pub fn had_error(&self) -> Option { - self.had_error - } - /// Report an error. pub fn report(&mut self, error: SloxError) { self.had_error = Some(error.kind); @@ -131,8 +126,8 @@ impl ErrorHandler { match result { Ok(v) => Ok(v), Err(e) => { - self.report(e); let fe = SloxError::stage_failed(e.kind); + self.report(e); println!("{fe}"); Err(fe) } diff --git a/src/interpreter/callable.rs b/src/interpreter/callable.rs index 695f300..20ac38e 100644 --- a/src/interpreter/callable.rs +++ b/src/interpreter/callable.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, fmt::Debug, rc::Rc}; -use crate::errors::InterpreterError; +use crate::errors::SloxResult; use super::{EnvironmentRef, Value}; @@ -11,11 +11,7 @@ pub trait Callable: Debug + ToString { /// Run the callable in the execution environment with the specified /// arguments. - fn call( - &self, - environment: &EnvironmentRef, - arguments: Vec, - ) -> Result; + fn call(&self, environment: &EnvironmentRef, arguments: Vec) -> SloxResult; } /// A reference to a callable. diff --git a/src/interpreter/environment.rs b/src/interpreter/environment.rs index eeaf8c7..f68d47a 100644 --- a/src/interpreter/environment.rs +++ b/src/interpreter/environment.rs @@ -1,6 +1,9 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; -use crate::{errors::InterpreterError, tokens::Token}; +use crate::{ + errors::{ErrorKind, SloxError, SloxResult}, + tokens::Token, +}; use super::{native_fn, CallableRef, Value}; @@ -45,11 +48,12 @@ impl Environment { } /// Define a new variable. - pub fn define(&mut self, name: &Token, value: Variable) -> Result<(), InterpreterError> { + pub fn define(&mut self, name: &Token, value: Variable) -> SloxResult<()> { if self.values.contains_key(&name.lexeme as &str) { - Err(InterpreterError::new( + Err(SloxError::with_token( + ErrorKind::Runtime, name, - &format!("variable '{}' already defined in scope", name.lexeme), + format!("variable '{}' already defined in scope", name.lexeme), )) } else { self.values.insert(name.lexeme.clone(), value); @@ -58,33 +62,36 @@ impl Environment { } /// Get the value of a variable. - pub fn get(&self, name: &Token) -> Result { + pub fn get(&self, name: &Token) -> SloxResult { match self.values.get(&name.lexeme as &str) { None => match &self.enclosing { - None => Err(InterpreterError::new( + None => Err(SloxError::with_token( + ErrorKind::Runtime, name, - &format!("undefined variable '{}'", name.lexeme), + format!("undefined variable '{}'", name.lexeme), )), Some(parent) => parent.borrow().get(name), }, - Some(None) => Err(InterpreterError::new( + Some(None) => Err(SloxError::with_token( + ErrorKind::Runtime, name, - &format!("variable '{}' has not been initialized", name.lexeme), + format!("variable '{}' has not been initialized", name.lexeme), )), Some(Some(value)) => Ok(value.clone()), } } /// Assign a value to an existing variable. - pub fn assign(&mut self, name: &Token, value: Value) -> Result<(), InterpreterError> { + pub fn assign(&mut self, name: &Token, value: Value) -> SloxResult<()> { if self.values.contains_key(&name.lexeme as &str) { self.values.insert(name.lexeme.clone(), Some(value)); Ok(()) } else { match &mut self.enclosing { - None => Err(InterpreterError::new( + None => Err(SloxError::with_token( + ErrorKind::Runtime, name, - &format!("undefined variable '{}'", name.lexeme), + format!("undefined variable '{}'", name.lexeme), )), Some(parent) => parent.borrow_mut().assign(name, value), } diff --git a/src/interpreter/functions.rs b/src/interpreter/functions.rs index 40d7daa..5fab45c 100644 --- a/src/interpreter/functions.rs +++ b/src/interpreter/functions.rs @@ -4,7 +4,7 @@ use itertools::izip; use crate::{ ast, - errors::InterpreterError, + errors::SloxResult, interpreter::{Environment, Interpretable, InterpreterFlowControl}, tokens::Token, }; @@ -39,11 +39,7 @@ impl Callable for Function { self.params.len() } - fn call( - &self, - environment: &EnvironmentRef, - arguments: Vec, - ) -> Result { + fn call(&self, environment: &EnvironmentRef, arguments: Vec) -> SloxResult { assert_eq!(arguments.len(), self.arity()); let param_env = Environment::create_child(environment); for (arg, value) in izip!(self.params.iter(), arguments.into_iter()) { diff --git a/src/interpreter/native_fn.rs b/src/interpreter/native_fn.rs index 2a1ee18..988edb1 100644 --- a/src/interpreter/native_fn.rs +++ b/src/interpreter/native_fn.rs @@ -4,7 +4,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use crate::errors::InterpreterError; +use crate::errors::SloxResult; use super::{Callable, CallableRef, EnvironmentRef, Value}; @@ -20,11 +20,7 @@ impl Callable for Clock { 0 } - fn call( - &self, - _environment: &EnvironmentRef, - _arguments: Vec, - ) -> Result { + fn call(&self, _environment: &EnvironmentRef, _arguments: Vec) -> SloxResult { let now = SystemTime::now(); let since_epoch = now .duration_since(UNIX_EPOCH) diff --git a/src/parser.rs b/src/parser.rs index 6e66e6c..b5ca6e6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -517,7 +517,11 @@ impl Parser { value: Box::new(value), }) } else { - self.error("invalid assignment target") + Err(SloxError::with_token( + ErrorKind::Parse, + &equals, + "invalid assignment target".to_owned(), + )) } } else { Ok(expr) diff --git a/src/scanner.rs b/src/scanner.rs index bd64dde..f49c782 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -145,7 +145,7 @@ impl Scanner { // Identifiers ch if ch.is_ascii_alphabetic() => self.identifier(), // Anything else is an error - ch => return self.error("unexpected character".to_owned()), + _ => return self.error("unexpected character".to_owned()), } } @@ -167,8 +167,7 @@ impl Scanner { } else { self.current += 1; // Last '"' let value = self.get_substring(self.start + 1, self.current - 1); - self.add_token(TokenType::String(value)); - Ok(()) + self.add_token(TokenType::String(value)) } } @@ -187,8 +186,7 @@ impl Scanner { let tok_string = self.get_substring(self.start, self.current); match tok_string.parse::() { Ok(value) => { - self.add_token(TokenType::Number(value)); - Ok(()) + self.add_token(TokenType::Number(value)) } Err(e) => self.error(format!( "Could not parse {} as a floating point number: {:?}",