reference arrays

This commit is contained in:
me 2025-12-25 01:12:13 +02:00
parent 25a4f1d7dd
commit 6dea19e55b
3 changed files with 25 additions and 0 deletions

View file

@ -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: Expr = Expr::Value(UNIT_VALUE);
pub enum Error {
LabelNotFound(Label),
IndexOutOfBounds(usize),
}
impl std::fmt::Display for Error {
@ -257,6 +267,9 @@ impl std::fmt::Display for Error {
Error::LabelNotFound(a) => {
write!(f, "Label not found: {a:?}")
}
Error::IndexOutOfBounds(a) => {
write!(f, "Indexout of bounds: {a:?}")
}
}
}
}

View file

@ -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::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())),
},
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::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())),
},
_ => eval_expr(expr_env, state, expr),

View file

@ -10,6 +10,7 @@ pub enum Error {
DuplicateEnvNames(ast::EnvName, Backtrace),
DuplicateNames(ast::Name, Backtrace),
NameNotFound(ast::Name, Env, Backtrace),
IndexOutOfBounds(usize, Backtrace),
FieldNotFound(ast::Label, Backtrace),
EnvNotFound(ast::EnvName, Backtrace),
LastStatementNotAnExpr(Backtrace),
@ -26,6 +27,7 @@ impl PartialEq for Error {
match (self, other) {
(Error::DuplicateEnvNames(a1, _), Error::DuplicateEnvNames(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::FieldNotFound(a1, _), Error::FieldNotFound(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::IndexOutOfBounds(a, b) => write!(f, "Index out of bounds: {a:?}\n{b}"),
Error::NameNotFound(a, e, b) => write!(
f,
"Name not found: {a:?} in {:#?}\n{b}",
@ -86,6 +89,7 @@ impl From<ast::Error> for Error {
fn from(error: ast::Error) -> Error {
match error {
ast::Error::LabelNotFound(l) => Error::FieldNotFound(l, Backtrace::capture()),
ast::Error::IndexOutOfBounds(i) => Error::IndexOutOfBounds(i, Backtrace::capture()),
}
}
}