From 08962bfba6da1c08d901d843a537c564069541a2 Mon Sep 17 00:00:00 2001 From: Matthieu Jolimaitre Date: Fri, 25 Oct 2024 16:34:15 +0200 Subject: [PATCH] add constructors for value --- src/ast.rs | 46 +++++++++++++++++++++------------------------- src/eval.rs | 12 ++++++++++++ 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 0370519..6bc75c3 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -8,7 +8,6 @@ use crate::{ util::Boxable, }; use chumsky::{ - error::{Cheap, Simple}, prelude::{end, filter, just, none_of, one_of, recursive, Recursive}, text::whitespace, Parser, @@ -17,7 +16,9 @@ use hashbrown::HashMap; extern crate alloc; -pub type ParseError = Cheap; +#[allow(unused)] +use chumsky::error::{Cheap, Simple}; +pub type ParseError = Simple; pub trait Parse: Parser + Clone + 'static {} impl + Clone + 'static, O> Parse for T {} @@ -26,7 +27,6 @@ fn pad(parser: impl Parse) -> impl Parse { .ignore_then(none_of("\n").repeated()) .ignore_then(just("\n")) .ignored(); - let padding = filter(|c| char::is_whitespace(*c)) .ignored() .or(comment) @@ -272,7 +272,6 @@ impl Expr { .or((lx("(").ignore_then(expr.clone()).then_ignore(lx(")"))).map(|e| Self::Parens(e.to_box()))) .or((UniOp::parser().then(expr.clone())).map(|(o, e)| Self::UniOp(o, e.to_box()))) .or(pad(id()).map(Self::Var)); - let method = atom .clone() .then_ignore(lx(".")) @@ -282,14 +281,12 @@ impl Expr { .then_ignore(lx(")")) .map(|((i, m), a)| Self::Method(i.to_box(), m, a)) .or(atom); - let access = method .clone() .then_ignore(lx(".")) .then(pad(id())) .map(|(e, a)| Self::Access(e.to_box(), a)) .or(method); - let call = access .clone() .then_ignore(lx("(")) @@ -297,7 +294,6 @@ impl Expr { .then_ignore(lx(")")) .map(|(e, a)| Self::Call(e.to_box(), a)) .or(access); - let index = call .clone() .then_ignore(lx("[")) @@ -305,7 +301,6 @@ impl Expr { .then_ignore(lx("]")) .map(|(e, i)| Self::Index(e.to_box(), i.to_box())) .or(call); - let ops = index .clone() .then(Op::parser().then(expr.clone()).repeated().at_least(1)) @@ -399,23 +394,24 @@ impl Op { } pub fn apply(&self, l: &Value, r: &Value) -> Result { + use Value::*; Ok(match (self, l, r) { - (Self::Add, Value::Str(l), Value::Str(r)) => Value::Str(format!("{l}{r}")), - (Self::Add, Value::Num(l), Value::Num(r)) => Value::Num(l + r), - (Self::Sub, Value::Num(l), Value::Num(r)) => Value::Num(l - r), - (Self::Div, Value::Num(l), Value::Num(r)) => Value::Num(l / r), - (Self::Prod, Value::Num(l), Value::Num(r)) => Value::Num(l * r), - (Self::Lt, Value::Num(l), Value::Num(r)) => Value::Bool(l < r), - (Self::Gt, Value::Num(l), Value::Num(r)) => Value::Bool(l > r), - (Self::Leq, Value::Num(l), Value::Num(r)) => Value::Bool(l <= r), - (Self::Geq, Value::Num(l), Value::Num(r)) => Value::Bool(l >= r), - (Self::Eq, Value::None, Value::None) => Value::Bool(true), - (Self::Eq, Value::Num(l), Value::Num(r)) => Value::Bool(l == r), - (Self::Eq, Value::Str(l), Value::Str(r)) => Value::Bool(l == r), - (Self::Eq, Value::Array(l), Value::Array(r)) => Value::Bool(Rc::ptr_eq(l, r)), - (Self::Eq, Value::Object(l), Value::Object(r)) => Value::Bool(Rc::ptr_eq(l, r)), - (Self::Eq, Value::Function(l), Value::Function(r)) => Value::Bool(Rc::ptr_eq(l, r)), - (Self::Eq, _, _) => Value::Bool(false), + (Self::Add, Str(l), Str(r)) => Str(format!("{l}{r}")), + (Self::Add, Num(l), Num(r)) => Num(l + r), + (Self::Sub, Num(l), Num(r)) => Num(l - r), + (Self::Div, Num(l), Num(r)) => Num(l / r), + (Self::Prod, Num(l), Num(r)) => Num(l * r), + (Self::Lt, Num(l), Num(r)) => Bool(l < r), + (Self::Gt, Num(l), Num(r)) => Bool(l > r), + (Self::Leq, Num(l), Num(r)) => Bool(l <= r), + (Self::Geq, Num(l), Num(r)) => Bool(l >= r), + (Self::Eq, None, Value::None) => Bool(true), + (Self::Eq, Num(l), Num(r)) => Bool(l == r), + (Self::Eq, Str(l), Str(r)) => Bool(l == r), + (Self::Eq, Array(l), Array(r)) => Bool(Rc::ptr_eq(l, r)), + (Self::Eq, Object(l), Object(r)) => Bool(Rc::ptr_eq(l, r)), + (Self::Eq, Function(l), Function(r)) => Bool(Rc::ptr_eq(l, r)), + (Self::Eq, _, _) => Bool(false), (Self::Neq, _, _) => UniOp::Inv.apply(&Self::Eq.apply(l, r)?)?, _ => Err(EvalError::WrongType)?, }) @@ -505,7 +501,7 @@ impl Litteral { let item = expr.eval(context)?; res.push(item); } - Value::Array(Rc::new(RefCell::new(res))) + Value::array(res) } Self::Function(def) => { let capturing = context.scope().clone(); diff --git a/src/eval.rs b/src/eval.rs index 0bf2495..39e19a5 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -178,6 +178,18 @@ impl Value { Self::Function(_f) => "".to_string(), } } + + pub fn array(items: Vec) -> Self { + Self::Array(Rc::new(RefCell::new(items))) + } + + pub fn object(entries: impl Iterator) -> Self { + Self::Object(Rc::new(RefCell::new(entries.collect()))) + } + + pub fn str(text: impl ToString) -> Self { + Self::Str(text.to_string()) + } } pub enum InstrOutput {