This commit is contained in:
me 2025-12-18 09:30:51 +02:00
parent 4f13870182
commit 09e74bd48f
4 changed files with 34 additions and 28 deletions

View file

@ -27,6 +27,8 @@ pub enum Expr {
expr: Box<Expr>, expr: Box<Expr>,
field: Label, field: Label,
}, },
Record(BTreeMap<Label, Expr>),
Vector(Vec<Expr>),
/* /*
Loop { Loop {
body: Box<Expr>, body: Box<Expr>,
@ -101,10 +103,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, Expr>); pub struct Record(pub BTreeMap<Label, Value>);
#[derive(PartialEq, PartialOrd, Debug, Clone)] #[derive(PartialEq, PartialOrd, Debug, Clone)]
pub struct Vector(pub Vec<Expr>); pub struct Vector(pub Vec<Value>);
/// 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; use crate::ast::{self, Record};
pub fn run( pub fn run(
program: ast::Program, program: ast::Program,
@ -151,7 +151,6 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
eval_expr(expr_env, state, &ast::UNIT) eval_expr(expr_env, state, &ast::UNIT)
} }
/*
// access via labels // access via labels
ast::Expr::Access { expr, field } => { ast::Expr::Access { expr, field } => {
let rhs = eval_expr(expr_env, state, rhs)?; let rhs = eval_expr(expr_env, state, rhs)?;
@ -162,7 +161,7 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
} else { } else {
todo!() // error nested field unreachable todo!() // error nested field unreachable
} }
} */ }
_ => todo!(), _ => todo!(),
}, },
_ => { _ => {
@ -173,29 +172,34 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
}, },
} }
} }
/* fn access_nested_field(
fn access_nested_field<'a>( expr_env: &Env,
expr_env_name: &Env, state: &mut State,
state: &'a mut State,
expr: &ast::Expr, expr: &ast::Expr,
label: &ast::Label, labels: &[ast::Label],
) -> Result<&'a mut ast::Value, Error> { ) -> Result<ast::Value, Error> {
//let lhs = eval_expr(expr_env, state, expr)?; let lhs = eval_expr(&expr_env, state, expr)?;
match expr { match lhs {
ast::Expr::Var(var) => { ast::Value::Ref(reference) => {
if let Some(mut value) = state.envs.get(&expr_env.name)?.get(&var)? { let mut current: ast::Value = (*state.get_variable(&reference)).clone();
match &value { for label in labels {
&ast::Value::Record(record) => { match current {
record. ast::Value::Record(record) => {
if let Some(next) = record.0.get(label) {
current = eval_expr(&expr_env, state, &ast::Expr::Value(next.clone()))?;
} else {
todo!()
}
}
// vector, closure
_ => todo!(), // unexpected
}
}
Ok(current)
} }
_ => todo!(), _ => todo!(),
} }
} }
}
_ => todo!(),
}
}
*/
fn defs_to_env( fn defs_to_env(
defs: Vec<ast::Definition>, defs: Vec<ast::Definition>,

View file

@ -3,6 +3,7 @@
use crate::ast; use crate::ast;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
#[derive(PartialEq, Debug, thiserror::Error)] #[derive(PartialEq, Debug, thiserror::Error)]
pub enum Error { pub enum Error {
@ -58,7 +59,7 @@ pub struct State {
pub variables: Variables, pub variables: Variables,
} }
pub struct Variables(pub HashMap<ast::Ref, ast::Value>); pub struct Variables(pub HashMap<ast::Ref, Rc<ast::Value>>);
impl State { impl State {
pub fn new(name: String) -> State { pub fn new(name: String) -> State {
@ -78,9 +79,12 @@ impl State {
pub fn insert_variable(&mut self, value: ast::Value) -> ast::Ref { pub fn insert_variable(&mut self, value: ast::Value) -> ast::Ref {
let name = ast::Ref(self.variable_namer.next()); let name = ast::Ref(self.variable_namer.next());
self.variables.0.insert(name.clone(), value); self.variables.0.insert(name.clone(), Rc::new(value));
name name
} }
pub fn get_variable<'a>(&self, reference: &ast::Ref) -> Rc<ast::Value> {
self.variables.0.get(reference).unwrap().clone()
}
} }
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]

View file

@ -200,9 +200,7 @@ fn parse_record(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
if let Some(vect) = tokens.between(&Token::OpenCurly, &Token::CloseCurly, |tokens| { if let Some(vect) = tokens.between(&Token::OpenCurly, &Token::CloseCurly, |tokens| {
tokens.many_sep_by(&Token::Comma, parse_record_field_expr) tokens.many_sep_by(&Token::Comma, parse_record_field_expr)
})? { })? {
Ok(Some(ast::Expr::Value(ast::Value::Record(ast::Record( Ok(Some(ast::Expr::Record(vect.into_iter().collect())))
vect.into_iter().collect(),
)))))
} else { } else {
Ok(None) Ok(None)
} }
@ -212,9 +210,7 @@ fn parse_vector(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
if let Some(vect) = tokens.between(&Token::OpenBracket, &Token::CloseBracket, |tokens| { if let Some(vect) = tokens.between(&Token::OpenBracket, &Token::CloseBracket, |tokens| {
tokens.many_sep_by(&Token::Comma, parse_expr) tokens.many_sep_by(&Token::Comma, parse_expr)
})? { })? {
Ok(Some(ast::Expr::Value(ast::Value::Vector(ast::Vector( Ok(Some(ast::Expr::Vector(vect)))
vect,
)))))
} else { } else {
Ok(None) Ok(None)
} }