wip
This commit is contained in:
parent
09e74bd48f
commit
9618575f7a
3 changed files with 18 additions and 11 deletions
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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(¤t_ref);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
|
|
@ -195,7 +198,7 @@ fn access_nested_field(
|
|||
_ => todo!(), // unexpected
|
||||
}
|
||||
}
|
||||
Ok(current)
|
||||
Ok(current_ref)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue