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

View file

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

View file

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