This commit is contained in:
me 2025-12-18 22:04:11 +02:00
parent 09e74bd48f
commit 9618575f7a
3 changed files with 18 additions and 11 deletions

View file

@ -1,6 +1,7 @@
//! Ast definition for Ayin.
use std::collections::BTreeMap;
use std::rc;
/// An expression.
#[derive(PartialEq, PartialOrd, Debug, Clone)]
@ -103,10 +104,10 @@ pub struct Label(pub String);
pub struct EnvName(pub String);
#[derive(PartialEq, PartialOrd, Debug, Clone)]
pub struct Record(pub BTreeMap<Label, Value>);
pub struct Record(pub BTreeMap<Label, Ref>);
#[derive(PartialEq, PartialOrd, Debug, Clone)]
pub struct Vector(pub Vec<Value>);
pub struct Vector(pub Vec<Ref>);
/// A Program.
#[derive(PartialEq, PartialOrd, Debug)]

View file

@ -2,7 +2,7 @@
use super::types::*;
use crate::ast::{self, Record};
use crate::ast;
pub fn run(
program: ast::Program,
@ -153,6 +153,7 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
// access via labels
ast::Expr::Access { expr, field } => {
let lhs = eval_expr(expr_env, state, lhs)?;
let rhs = eval_expr(expr_env, state, rhs)?;
if let Some(mut nested_field) =
access_nested_field(expr_env, state, expr, field)?
@ -174,19 +175,21 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
}
fn access_nested_field(
expr_env: &Env,
state: &mut State,
state: &State,
expr: &ast::Expr,
labels: &[ast::Label],
) -> Result<ast::Value, Error> {
) -> Result<ast::Ref, Error> {
let lhs = eval_expr(&expr_env, state, expr)?;
match lhs {
ast::Value::Ref(reference) => {
let mut current: ast::Value = (*state.get_variable(&reference)).clone();
let mut current_ref = reference.clone();
let mut current: ast::Value = state.get_variable(&reference);
for label in labels {
match current {
ast::Value::Record(record) => {
if let Some(next) = record.0.get(label) {
current = eval_expr(&expr_env, state, &ast::Expr::Value(next.clone()))?;
current_ref = next;
current = state.get_variable(&current_ref);
} else {
todo!()
}
@ -195,7 +198,7 @@ fn access_nested_field(
_ => todo!(), // unexpected
}
}
Ok(current)
Ok(current_ref)
}
_ => todo!(),
}

View file

@ -59,7 +59,7 @@ pub struct State {
pub variables: Variables,
}
pub struct Variables(pub HashMap<ast::Ref, Rc<ast::Value>>);
pub struct Variables(pub HashMap<ast::Ref, ast::Value>);
impl State {
pub fn new(name: String) -> State {
@ -82,8 +82,11 @@ impl State {
self.variables.0.insert(name.clone(), Rc::new(value));
name
}
pub fn get_variable<'a>(&self, reference: &ast::Ref) -> Rc<ast::Value> {
self.variables.0.get(reference).unwrap().clone()
pub fn get_variable<'a>(&'a self, reference: &ast::Ref) -> &'a ast::Value {
self.variables.0.get(reference).unwrap()
}
pub fn set_variable(&mut self, reference: ast::Ref, new_value: ast::Value) {
self.variables.0.insert(reference, new_value)
}
}