Assign read syntax

This commit is contained in:
Alex Bethel 2021-11-05 17:09:53 -06:00
parent 99f84dfd5b
commit 8a04d9d1e0

View file

@ -20,7 +20,7 @@ use std::{
use rand::random; use rand::random;
use crate::{ use crate::{
ast::{AssignableKind, Expr, ExprKind, Ident, Stmt, StmtKind}, ast::{Assignable, AssignableKind, Expr, ExprKind, Ident, Stmt, StmtKind},
base_55, base_55,
consts::ablescript_consts, consts::ablescript_consts,
error::{Error, ErrorKind}, error::{Error, ErrorKind},
@ -246,45 +246,7 @@ impl ExecEnv {
} }
}, },
StmtKind::Assign { assignable, value } => { StmtKind::Assign { assignable, value } => {
let value = self.eval_expr(value)?; self.assign(assignable, 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);
}
}
} }
StmtKind::Break => { StmtKind::Break => {
return Ok(HaltStatus::Break(stmt.span.clone())); return Ok(HaltStatus::Break(stmt.span.clone()));
@ -312,20 +274,55 @@ impl ExecEnv {
value += self.get_bit()? as i32; value += self.get_bit()? as i32;
} }
match assignable.kind { self.assign(assignable, Value::Int(value))?;
AssignableKind::Variable => {
self.get_var_mut(&assignable.ident)?
.value
.replace(Value::Int(value));
}
AssignableKind::Index { .. } => todo!(),
}
} }
} }
Ok(HaltStatus::Finished) 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 /// Call a function with the given arguments (i.e., actual
/// parameters). If the function invocation fails for some reason, /// parameters). If the function invocation fails for some reason,
/// report the error at `span`. /// report the error at `span`.