reference arrays
This commit is contained in:
parent
25a4f1d7dd
commit
6dea19e55b
3 changed files with 25 additions and 0 deletions
|
|
@ -244,11 +244,21 @@ impl Record {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Vector {
|
||||||
|
pub fn get(&self, index: usize) -> Result<&Ref, Error> {
|
||||||
|
match self.0.get(index) {
|
||||||
|
Some(v) => Ok(v),
|
||||||
|
None => Err(Error::IndexOutOfBounds(index)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const UNIT_VALUE: Value = Value::Record(Record(BTreeMap::new()));
|
pub const UNIT_VALUE: Value = Value::Record(Record(BTreeMap::new()));
|
||||||
pub const UNIT: Expr = Expr::Value(UNIT_VALUE);
|
pub const UNIT: Expr = Expr::Value(UNIT_VALUE);
|
||||||
|
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
LabelNotFound(Label),
|
LabelNotFound(Label),
|
||||||
|
IndexOutOfBounds(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
|
|
@ -257,6 +267,9 @@ impl std::fmt::Display for Error {
|
||||||
Error::LabelNotFound(a) => {
|
Error::LabelNotFound(a) => {
|
||||||
write!(f, "Label not found: {a:?}")
|
write!(f, "Label not found: {a:?}")
|
||||||
}
|
}
|
||||||
|
Error::IndexOutOfBounds(a) => {
|
||||||
|
write!(f, "Indexout of bounds: {a:?}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,10 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
|
||||||
}
|
}
|
||||||
ast::Expr::Access { expr, field } => match eval_expr(expr_env, state, expr)? {
|
ast::Expr::Access { expr, field } => match eval_expr(expr_env, state, expr)? {
|
||||||
ast::Value::Record(record) => Ok(state.variables.get(record.get(&field)?).clone()),
|
ast::Value::Record(record) => Ok(state.variables.get(record.get(&field)?).clone()),
|
||||||
|
ast::Value::Vector(vec) if field.0.chars().all(char::is_numeric) => {
|
||||||
|
let index = field.0.parse::<usize>().unwrap();
|
||||||
|
Ok(state.variables.get(vec.get(index)?).clone())
|
||||||
|
}
|
||||||
v => Err(Error::NotARecord(v, Backtrace::capture())),
|
v => Err(Error::NotARecord(v, Backtrace::capture())),
|
||||||
},
|
},
|
||||||
ast::Expr::Var(var) => {
|
ast::Expr::Var(var) => {
|
||||||
|
|
@ -412,6 +416,10 @@ fn eval_expr_shallow(
|
||||||
}
|
}
|
||||||
ast::Expr::Access { expr, field } => match eval_expr(expr_env, state, expr)? {
|
ast::Expr::Access { expr, field } => match eval_expr(expr_env, state, expr)? {
|
||||||
ast::Value::Record(record) => Ok(ast::Value::Ref(record.get(&field)?.clone())),
|
ast::Value::Record(record) => Ok(ast::Value::Ref(record.get(&field)?.clone())),
|
||||||
|
ast::Value::Vector(vec) if field.0.chars().all(char::is_numeric) => {
|
||||||
|
let index = field.0.parse::<usize>().unwrap();
|
||||||
|
Ok(ast::Value::Ref(vec.get(index)?.clone()))
|
||||||
|
}
|
||||||
v => Err(Error::NotARecord(v, Backtrace::capture())),
|
v => Err(Error::NotARecord(v, Backtrace::capture())),
|
||||||
},
|
},
|
||||||
_ => eval_expr(expr_env, state, expr),
|
_ => eval_expr(expr_env, state, expr),
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ pub enum Error {
|
||||||
DuplicateEnvNames(ast::EnvName, Backtrace),
|
DuplicateEnvNames(ast::EnvName, Backtrace),
|
||||||
DuplicateNames(ast::Name, Backtrace),
|
DuplicateNames(ast::Name, Backtrace),
|
||||||
NameNotFound(ast::Name, Env, Backtrace),
|
NameNotFound(ast::Name, Env, Backtrace),
|
||||||
|
IndexOutOfBounds(usize, Backtrace),
|
||||||
FieldNotFound(ast::Label, Backtrace),
|
FieldNotFound(ast::Label, Backtrace),
|
||||||
EnvNotFound(ast::EnvName, Backtrace),
|
EnvNotFound(ast::EnvName, Backtrace),
|
||||||
LastStatementNotAnExpr(Backtrace),
|
LastStatementNotAnExpr(Backtrace),
|
||||||
|
|
@ -26,6 +27,7 @@ impl PartialEq for Error {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Error::DuplicateEnvNames(a1, _), Error::DuplicateEnvNames(a2, _)) => a1 == a2,
|
(Error::DuplicateEnvNames(a1, _), Error::DuplicateEnvNames(a2, _)) => a1 == a2,
|
||||||
(Error::DuplicateNames(a1, _), Error::DuplicateNames(a2, _)) => a1 == a2,
|
(Error::DuplicateNames(a1, _), Error::DuplicateNames(a2, _)) => a1 == a2,
|
||||||
|
(Error::IndexOutOfBounds(a1, _), Error::IndexOutOfBounds(a2, _)) => a1 == a2,
|
||||||
(Error::NameNotFound(a1, _, _), Error::NameNotFound(a2, _, _)) => a1 == a2,
|
(Error::NameNotFound(a1, _, _), Error::NameNotFound(a2, _, _)) => a1 == a2,
|
||||||
(Error::FieldNotFound(a1, _), Error::FieldNotFound(a2, _)) => a1 == a2,
|
(Error::FieldNotFound(a1, _), Error::FieldNotFound(a2, _)) => a1 == a2,
|
||||||
(Error::EnvNotFound(a1, _), Error::EnvNotFound(a2, _)) => a1 == a2,
|
(Error::EnvNotFound(a1, _), Error::EnvNotFound(a2, _)) => a1 == a2,
|
||||||
|
|
@ -56,6 +58,7 @@ impl std::fmt::Display for Error {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Error::DuplicateNames(a, b) => write!(f, "Duplicate names: {a:?}\n{b}"),
|
Error::DuplicateNames(a, b) => write!(f, "Duplicate names: {a:?}\n{b}"),
|
||||||
|
Error::IndexOutOfBounds(a, b) => write!(f, "Index out of bounds: {a:?}\n{b}"),
|
||||||
Error::NameNotFound(a, e, b) => write!(
|
Error::NameNotFound(a, e, b) => write!(
|
||||||
f,
|
f,
|
||||||
"Name not found: {a:?} in {:#?}\n{b}",
|
"Name not found: {a:?} in {:#?}\n{b}",
|
||||||
|
|
@ -86,6 +89,7 @@ impl From<ast::Error> for Error {
|
||||||
fn from(error: ast::Error) -> Error {
|
fn from(error: ast::Error) -> Error {
|
||||||
match error {
|
match error {
|
||||||
ast::Error::LabelNotFound(l) => Error::FieldNotFound(l, Backtrace::capture()),
|
ast::Error::LabelNotFound(l) => Error::FieldNotFound(l, Backtrace::capture()),
|
||||||
|
ast::Error::IndexOutOfBounds(i) => Error::IndexOutOfBounds(i, Backtrace::capture()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue