From 8a04d9d1e06f28538c5334fa45c8344ec6607358 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Fri, 5 Nov 2021 17:09:53 -0600 Subject: [PATCH] Assign read syntax --- ablescript/src/interpret.rs | 93 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 8ea04722..e1c3af51 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -20,7 +20,7 @@ use std::{ use rand::random; use crate::{ - ast::{AssignableKind, Expr, ExprKind, Ident, Stmt, StmtKind}, + ast::{Assignable, AssignableKind, Expr, ExprKind, Ident, Stmt, StmtKind}, base_55, consts::ablescript_consts, error::{Error, ErrorKind}, @@ -246,45 +246,7 @@ impl ExecEnv { } }, StmtKind::Assign { assignable, value } => { - let value = self.eval_expr(value)?; - match assignable.kind { - AssignableKind::Variable => { - self.get_var_mut(&assignable.ident)?.value.replace(value); - } - AssignableKind::Index { ref indices } => { - let mut cell = self.get_var_rc(&assignable.ident)?; - for index in indices { - let index = self.eval_expr(index)?; - - let next_cell; - match &mut *cell.borrow_mut() { - Value::Cart(c) => { - if let Some(x) = c.get(&index) { - next_cell = Rc::clone(x); - } else { - next_cell = - Rc::new(RefCell::new(Value::Cart(Default::default()))); - c.insert(index, Rc::clone(&next_cell)); - } - } - x => { - // Annoying borrow checker dance - // to move *x. - let mut tmp = Value::Nul; - swap(&mut tmp, x); - - let mut c = tmp.into_cart(); - next_cell = - Rc::new(RefCell::new(Value::Cart(Default::default()))); - c.insert(index, Rc::clone(&next_cell)); - *x = Value::Cart(c); - } - } - cell = next_cell; - } - cell.replace(value); - } - } + self.assign(assignable, self.eval_expr(value)?)?; } StmtKind::Break => { return Ok(HaltStatus::Break(stmt.span.clone())); @@ -312,20 +274,55 @@ impl ExecEnv { value += self.get_bit()? as i32; } - match assignable.kind { - AssignableKind::Variable => { - self.get_var_mut(&assignable.ident)? - .value - .replace(Value::Int(value)); - } - AssignableKind::Index { .. } => todo!(), - } + self.assign(assignable, Value::Int(value))?; } } Ok(HaltStatus::Finished) } + /// Assign a value to an Assignable. + fn assign(&mut self, dest: &Assignable, value: Value) -> Result<(), Error> { + match dest.kind { + AssignableKind::Variable => { + self.get_var_mut(&dest.ident)?.value.replace(value); + } + AssignableKind::Index { ref indices } => { + let mut cell = self.get_var_rc(&dest.ident)?; + for index in indices { + let index = self.eval_expr(index)?; + + let next_cell; + match &mut *cell.borrow_mut() { + Value::Cart(c) => { + if let Some(x) = c.get(&index) { + next_cell = Rc::clone(x); + } else { + next_cell = Rc::new(RefCell::new(Value::Cart(Default::default()))); + c.insert(index, Rc::clone(&next_cell)); + } + } + x => { + // Annoying borrow checker dance + // to move *x. + let mut tmp = Value::Nul; + swap(&mut tmp, x); + + let mut c = tmp.into_cart(); + next_cell = Rc::new(RefCell::new(Value::Cart(Default::default()))); + c.insert(index, Rc::clone(&next_cell)); + *x = Value::Cart(c); + } + } + cell = next_cell; + } + cell.replace(value); + } + } + + Ok(()) + } + /// Call a function with the given arguments (i.e., actual /// parameters). If the function invocation fails for some reason, /// report the error at `span`.