add constructors for value
This commit is contained in:
parent
d269425943
commit
08962bfba6
2 changed files with 33 additions and 25 deletions
46
src/ast.rs
46
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<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();
|
||||
|
|
12
src/eval.rs
12
src/eval.rs
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue