Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
feat: add basic eval for deref
Browse files Browse the repository at this point in the history
  • Loading branch information
aripiprazole committed Nov 23, 2023
1 parent 51baa65 commit 83619ae
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 22 deletions.
29 changes: 21 additions & 8 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use std::{
sync::{Arc, RwLock},
};

use Trampoline::{Continue, Done, Raise};

use crate::{
semantic::{self, Expr},
semantic::{self, defmacro::keyword, Expr},
SrcPos,
};

Expand Down Expand Up @@ -52,9 +54,12 @@ pub fn eval(expr: Expr, environment: Environment) -> Trampoline<Value> {
Expr::Quote(_) => todo!(),
Expr::Recur(_) => todo!(),
Expr::Deref(deref) => {
let value = eval(deref.value()?, environment)?;
let Value::Atomic(atomic) = eval(deref.value()?, environment)? else {
bail!(keyword!("eval.error/atomic-expected"))
};
let guard = atomic.read().expect("poisoned atomic");

todo!()
Done(guard.clone())
}
Expr::Atomic(_) => todo!(),
Expr::Set(_) => todo!(),
Expand All @@ -70,16 +75,16 @@ impl<T> Try for Trampoline<T, Expr> {
type Residual = Result<Infallible, Expr>;

fn from_output(output: Self::Output) -> Self {
Trampoline::Done(output)
Done(output)
}

fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
let mut value: Trampoline<T, Expr> = self;
loop {
match value {
Trampoline::Done(done) => return ControlFlow::Continue(done),
Trampoline::Raise(error) => return ControlFlow::Break(Err(error)),
Trampoline::Continue(f) => {
Done(done) => return ControlFlow::Continue(done),
Raise(error) => return ControlFlow::Break(Err(error)),
Continue(f) => {
value = f();
}
}
Expand All @@ -90,8 +95,16 @@ impl<T> Try for Trampoline<T, Expr> {
impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Trampoline<T, F> {
fn from_residual(residual: Result<Infallible, E>) -> Self {
match residual {
Err(error) => Trampoline::Raise(From::from(error)),
Err(error) => Raise(From::from(error)),
_ => unreachable!(),
}
}
}

macro_rules! bail {
($expr:expr) => {
return $crate::eval::Trampoline::Raise($expr.into())
};
}

use bail;
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ impl Display for Term {
}
}

impl From<usize> for Term {
fn from(n: usize) -> Self {
Term::Int(n as u64)
}
}

impl From<Vec<Term>> for Term {
fn from(terms: Vec<Term>) -> Self {
Term::List(terms)
Expand Down
70 changes: 56 additions & 14 deletions src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,6 @@ pub mod quote {

/// Literal expression construct, it's a literal value.
pub mod literal {
use std::fmt::Display;

use super::*;

impl ExpressionKind for Literal {
Expand All @@ -255,8 +253,20 @@ pub mod literal {
}
}

impl From<u64> for Expr {
fn from(value: u64) -> Self {
Expr::Literal(Literal(Term::Int(value)))
}
}

impl From<usize> for Expr {
fn from(value: usize) -> Self {
Expr::Literal(Literal(Term::Int(value as u64)))
}
}

impl Expr {
pub fn new_keyword(keyword: impl Display) -> Self {
pub fn new_keyword(keyword: &str) -> Self {
Expr::Literal(Literal(Term::Atom(keyword.to_string())))
}

Expand Down Expand Up @@ -303,16 +313,18 @@ pub enum SemanticError {
impl From<SemanticError> for Expr {
fn from(value: SemanticError) -> Self {
match value {
SemanticError::InvalidExpression => Expr::new_keyword("error/invalid-expression"),
SemanticError::InvalidList => Expr::new_keyword("error/invalid-list"),
SemanticError::InvalidArguments => Expr::new_keyword("error/invalid-arguments"),
SemanticError::MissingParameters => Expr::new_keyword("error/missing-parameters"),
SemanticError::MissingBody => Expr::new_keyword("error/missing-body"),
SemanticError::MissingHead => Expr::new_keyword("error/missing-head"),
SemanticError::ExpectedString => Expr::new_keyword("error/expected-string"),
SemanticError::ExpectedVectorWithSize(_) => Expr::new_keyword("error/expected-vector"),
SemanticError::InvalidExpression => keyword!("error/invalid-expression"),
SemanticError::InvalidList => keyword!("error/invalid-list"),
SemanticError::InvalidArguments => keyword!("error/invalid-arguments"),
SemanticError::MissingParameters => keyword!("error/missing-parameters"),
SemanticError::MissingBody => keyword!("error/missing-body"),
SemanticError::MissingHead => keyword!("error/missing-head"),
SemanticError::ExpectedString => keyword!("error/expected-string"),
SemanticError::ExpectedVectorWithSize(size) => {
soft_vec![keyword!("error/expected-vector"), size]
}
SemanticError::ExpectedQuoteExpression => {
Expr::new_keyword("error/expected-quote-expression")
keyword!("error/expected-quote-expression")
}
}
}
Expand Down Expand Up @@ -396,6 +408,16 @@ macro_rules! define_ast {
),+
}

impl From<$name> for $crate::Term {
fn from(value: $name) -> Self {
match value {
$(
$name::$variant(value) => value.into(),
)+
}
}
}

$(
impl From<$variant> for $name {
fn from(value: $variant) -> Self {
Expand All @@ -405,10 +427,16 @@ macro_rules! define_ast {

$(#[$field_outer])*
#[derive(Debug, Clone)]
pub struct $variant(crate::Term);
pub struct $variant($crate::Term);

impl From<$variant> for $crate::Term {
fn from(value: $variant) -> Self {
value.0
}
}

impl std::ops::Deref for $variant {
type Target = crate::Term;
type Target = $crate::Term;

fn deref(&self) -> &Self::Target {
&self.0
Expand All @@ -418,5 +446,19 @@ macro_rules! define_ast {
};
}

macro_rules! soft_vec {
($($expr:expr),*) => {
$crate::semantic::Expr::List($crate::semantic::List($crate::Term::Vec(vec![$($expr.into()),*])))
};
}

macro_rules! keyword {
($str:literal) => {
$crate::semantic::Expr::new_keyword($str)
};
}

use define_ast;
use define_builtin;
use soft_vec;
pub(crate) use keyword;

0 comments on commit 83619ae

Please sign in to comment.