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.
|
//! 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)]
|
||||||
|
|
|
||||||
|
|
@ -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(¤t_ref);
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +198,7 @@ fn access_nested_field(
|
||||||
_ => todo!(), // unexpected
|
_ => todo!(), // unexpected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(current)
|
Ok(current_ref)
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue