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>,
field: Label,
},
Record(BTreeMap<Label, Expr>),
Vector(Vec<Expr>),
/*
Loop {
body: Box<Expr>,
@ -101,10 +103,10 @@ pub struct Label(pub String);
pub struct EnvName(pub String);
#[derive(PartialEq, PartialOrd, Debug, Clone)]
pub struct Record(pub BTreeMap<Label, Expr>);
pub struct Record(pub BTreeMap<Label, Value>);
#[derive(PartialEq, PartialOrd, Debug, Clone)]
pub struct Vector(pub Vec<Expr>);
pub struct Vector(pub Vec<Value>);
/// A Program.
#[derive(PartialEq, PartialOrd, Debug)]

View file

@ -2,7 +2,7 @@
use super::types::*;
use crate::ast;
use crate::ast::{self, Record};
pub fn run(
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)
}
/*
// access via labels
ast::Expr::Access { expr, field } => {
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 {
todo!() // error nested field unreachable
}
} */
}
_ => todo!(),
},
_ => {
@ -173,29 +172,34 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
},
}
}
/*
fn access_nested_field<'a>(
expr_env_name: &Env,
state: &'a mut State,
fn access_nested_field(
expr_env: &Env,
state: &mut State,
expr: &ast::Expr,
label: &ast::Label,
) -> Result<&'a mut ast::Value, Error> {
//let lhs = eval_expr(expr_env, state, expr)?;
match expr {
ast::Expr::Var(var) => {
if let Some(mut value) = state.envs.get(&expr_env.name)?.get(&var)? {
match &value {
&ast::Value::Record(record) => {
record.
}
_ => todo!(),
labels: &[ast::Label],
) -> Result<ast::Value, 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();
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()))?;
} else {
todo!()
}
}
// vector, closure
_ => todo!(), // unexpected
}
}
Ok(current)
}
_ => todo!(),
}
}
*/
fn defs_to_env(
defs: Vec<ast::Definition>,

View file

@ -3,6 +3,7 @@
use crate::ast;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::rc::Rc;
#[derive(PartialEq, Debug, thiserror::Error)]
pub enum Error {
@ -58,7 +59,7 @@ pub struct State {
pub variables: Variables,
}
pub struct Variables(pub HashMap<ast::Ref, ast::Value>);
pub struct Variables(pub HashMap<ast::Ref, Rc<ast::Value>>);
impl State {
pub fn new(name: String) -> State {
@ -78,9 +79,12 @@ impl State {
pub fn insert_variable(&mut self, value: ast::Value) -> ast::Ref {
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
}
pub fn get_variable<'a>(&self, reference: &ast::Ref) -> Rc<ast::Value> {
self.variables.0.get(reference).unwrap().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| {
tokens.many_sep_by(&Token::Comma, parse_record_field_expr)
})? {
Ok(Some(ast::Expr::Value(ast::Value::Record(ast::Record(
vect.into_iter().collect(),
)))))
Ok(Some(ast::Expr::Record(vect.into_iter().collect())))
} else {
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| {
tokens.many_sep_by(&Token::Comma, parse_expr)
})? {
Ok(Some(ast::Expr::Value(ast::Value::Vector(ast::Vector(
vect,
)))))
Ok(Some(ast::Expr::Vector(vect)))
} else {
Ok(None)
}