Skip to content

Commit

Permalink
fix: Interpreter refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Feb 23, 2024
1 parent 1d60353 commit 3f7124b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
12 changes: 12 additions & 0 deletions server/src/runtime/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ pub enum ExecutionError {
Interpret(InterpretError),
}

impl From<ParseError> for ExecutionError {
fn from(err: ParseError) -> Self {
ExecutionError::Parse(err)
}
}

impl From<ScanError> for ExecutionError {
fn from(err: ScanError) -> Self {
ExecutionError::Scan(err)
}
}

pub fn report_error(filename: &str, source: &str, error: ExecutionError) {
use ariadne::{Color, Label, Report, ReportKind, Source};

Expand Down
2 changes: 1 addition & 1 deletion server/src/runtime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl Interpreter {

fn eval_unary(&mut self, operation: &Operation, eidx: ExprId) -> Result<RV, HaltReason> {
if *operation == Operation::Subtract {
if let Some(num) = self.visit_expr(eidx)?.coerce_to_number() {
if let Some(num) = self.visit_expr(eidx)?.as_number() {
return Ok(RV::Num(-num));
}
Ok(RV::NaN)
Expand Down
25 changes: 9 additions & 16 deletions server/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,21 @@ impl Runtime {
Runtime { mode, out: None }
}

pub fn ast(&mut self, source: &str) -> Result<Value, ParseError> {
let tokens = Scanner::scan(source).unwrap();
pub fn ast(&mut self, source: &str) -> Result<Value, ExecutionError> {
let tokens = Scanner::scan(source)?;
let program = Parser::parse(&tokens)?;
Ok(program.to_json())
}

pub fn interpret(&mut self, source: &str) -> Result<RV, ExecutionError> {
let tokens = Scanner::scan(source);
if tokens.is_err() {
let error = error::ExecutionError::Scan(tokens.err().unwrap());
return Err(error);
}
let program = Parser::parse(&tokens.unwrap());
if program.is_err() {
let error = error::ExecutionError::Parse(program.err().unwrap());
return Err(error);
}
let program_unw = program.unwrap();
let arena: Arc<AstArena> = Arc::clone(&program_unw.arena);
let tokens = Scanner::scan(source)?;
//
let program = Parser::parse(&tokens)?;
//
let arena: Arc<AstArena> = Arc::clone(&program.arena);
//
let mut resolver = Resolver::new(arena.clone());
resolver.resolve_stmt(program_unw.root);
resolver.resolve_stmt(program.root);
//
let mut env_man = Environment::new();
let env = env_man.top();
Expand All @@ -73,7 +66,7 @@ impl Runtime {
}

let mut interpreter = Interpreter::new(env_man, env, arena, Arc::new(resolver));
let out = interpreter.visit_stmt(program_unw.root);
let out = interpreter.visit_stmt(program.root);

if self.mode == RuntimeMode::Repl {
info!("{:?}", out);
Expand Down
28 changes: 14 additions & 14 deletions server/src/runtime/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,13 @@ impl RV {
}

pub fn partial_cmp_str_bool(&self, other: bool) -> Option<std::cmp::Ordering> {
if let Some(num) = self.coerce_to_number() {
if let Some(num) = self.as_number() {
return num.partial_cmp(&if other { 1.0 } else { 0.0 });
}
self.is_truthy().partial_cmp(&other)
}

pub fn coerce_to_number(&self) -> Option<f64> {
pub fn as_number(&self) -> Option<f64> {
match self {
RV::Num(value) => Some(*value),
RV::Bool(true) => Some(1.0),
Expand Down Expand Up @@ -283,7 +283,7 @@ impl ops::Add for RV {
(RV::NaN, _) | (_, RV::NaN) => RV::NaN,
//
(RV::Bool(_), RV::Bool(_)) | (RV::Num(_), RV::Bool(_)) | (RV::Bool(_), RV::Num(_)) => {
RV::Num(self.coerce_to_number().unwrap() + rhs.coerce_to_number().unwrap())
RV::Num(self.as_number().unwrap() + rhs.as_number().unwrap())
}

(RV::Num(l), RV::Num(r)) => RV::Num(l + r),
Expand All @@ -310,8 +310,8 @@ impl ops::Sub for RV {
(RV::NaN, _) | (_, RV::NaN) => RV::NaN,
(RV::Null, _) | (_, RV::Null) => RV::Num(0.0),
(l, r) => l
.coerce_to_number()
.and_then(|a| r.coerce_to_number().map(|b| (a, b)))
.as_number()
.and_then(|a| r.as_number().map(|b| (a, b)))
.map(|(a, b)| RV::Num(a - b))
.unwrap_or(RV::NaN),
}
Expand All @@ -327,8 +327,8 @@ impl ops::Mul for RV {
(RV::NaN, _) | (_, RV::NaN) => RV::NaN,
(RV::Null, _) | (_, RV::Null) => RV::Num(0.0),
(l, r) => l
.coerce_to_number()
.and_then(|a| r.coerce_to_number().map(|b| (a, b)))
.as_number()
.and_then(|a| r.as_number().map(|b| (a, b)))
.map(|(a, b)| RV::Num(a * b))
.unwrap_or(RV::NaN),
}
Expand All @@ -344,8 +344,8 @@ impl ops::Div for RV {
(RV::NaN, _) | (_, RV::NaN) => RV::NaN,
(RV::Null, _) | (_, RV::Null) => RV::Num(0.0),
(l, r) => l
.coerce_to_number()
.and_then(|a| r.coerce_to_number().map(|b| (a, b)))
.as_number()
.and_then(|a| r.as_number().map(|b| (a, b)))
.map(|(a, b)| {
if a == 0.0 && b == 0.0 {
RV::NaN
Expand Down Expand Up @@ -428,11 +428,11 @@ mod test {
}

#[test]
fn test_coerce2number() {
assert_eq!((RV::Num(1.0)).coerce_to_number(), Some(1.0));
assert_eq!((RV::Bool(false)).coerce_to_number(), Some(0.0));
assert_eq!((RV::Bool(true)).coerce_to_number(), Some(1.0));
assert_eq!((RV::Str(Arc::new("".to_owned()))).coerce_to_number(), None);
fn test_as_number() {
assert_eq!((RV::Num(1.0)).as_number(), Some(1.0));
assert_eq!((RV::Bool(false)).as_number(), Some(0.0));
assert_eq!((RV::Bool(true)).as_number(), Some(1.0));
assert_eq!((RV::Str(Arc::new("".to_owned()))).as_number(), None);
}

#[test]
Expand Down

0 comments on commit 3f7124b

Please sign in to comment.