add constructors for value

This commit is contained in:
Matthieu Jolimaitre 2024-10-25 16:34:15 +02:00
parent d269425943
commit 08962bfba6
2 changed files with 33 additions and 25 deletions

View file

@ -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<char>;
#[allow(unused)]
use chumsky::error::{Cheap, Simple};
pub type ParseError = Simple<char>;
pub trait Parse<O>: Parser<char, O, Error = ParseError> + Clone + 'static {}
impl<T: Parser<char, O, Error = ParseError> + Clone + 'static, O> Parse<O> for T {}
@ -26,7 +27,6 @@ fn pad<O: 'static>(parser: impl Parse<O>) -> impl Parse<O> {
.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<Value, EvalError> {
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();

View file

@ -178,6 +178,18 @@ impl Value {
Self::Function(_f) => "<function>".to_string(),
}
}
pub fn array(items: Vec<Self>) -> Self {
Self::Array(Rc::new(RefCell::new(items)))
}
pub fn object(entries: impl Iterator<Item = (String, Value)>) -> Self {
Self::Object(Rc::new(RefCell::new(entries.collect())))
}
pub fn str(text: impl ToString) -> Self {
Self::Str(text.to_string())
}
}
pub enum InstrOutput {