diff --git a/src/ast/types.rs b/src/ast/types.rs index dee1b05..ca3a086 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -27,6 +27,8 @@ pub enum Expr { expr: Box, field: Label, }, + Record(BTreeMap), + Vector(Vec), /* Loop { body: Box, @@ -101,10 +103,10 @@ pub struct Label(pub String); pub struct EnvName(pub String); #[derive(PartialEq, PartialOrd, Debug, Clone)] -pub struct Record(pub BTreeMap); +pub struct Record(pub BTreeMap); #[derive(PartialEq, PartialOrd, Debug, Clone)] -pub struct Vector(pub Vec); +pub struct Vector(pub Vec); /// A Program. #[derive(PartialEq, PartialOrd, Debug)] diff --git a/src/interpret/interpret.rs b/src/interpret/interpret.rs index 93c7f0b..3f7f81c 100644 --- a/src/interpret/interpret.rs +++ b/src/interpret/interpret.rs @@ -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 { 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 todo!(), }, _ => { @@ -173,29 +172,34 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result( - 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. + labels: &[ast::Label], +) -> Result { + 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!() + } } - _ => todo!(), + // vector, closure + _ => todo!(), // unexpected } } + Ok(current) } _ => todo!(), } } -*/ fn defs_to_env( defs: Vec, diff --git a/src/interpret/types.rs b/src/interpret/types.rs index b20f27a..6a0d2f9 100644 --- a/src/interpret/types.rs +++ b/src/interpret/types.rs @@ -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); +pub struct Variables(pub HashMap>); 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 { + self.variables.0.get(reference).unwrap().clone() + } } #[derive(PartialEq, Debug, Clone)] diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 8eacc90..bd37e91 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -200,9 +200,7 @@ fn parse_record(tokens: &mut Tokens) -> ParseResult { 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 { 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) }