evaluator_rs 0.1.5

A evaluation engine library for Rust
Documentation
use std::str::FromStr;
use crate::ast::{
    expr::Expr,
    op::{AdditiveOp, LogicalOp, MultiplicativeOp, Op, RelationalOp},
    value::Value,
};
use crate::parser::parser::parse_parameter_name;

grammar;

pub Expr: Box<Expr> = {
    Expr LogicalOp RelationalExpr => Box::new(Expr::Op(<>)),
    RelationalExpr,
};

pub Op: Op = {
    LogicalOp,
    RelationalOp,
    AdditiveOp,
    MultiplicativeOp,
}

pub RelationalExpr: Box<Expr> = {
    RelationalExpr RelationalOp AdditiveExpr => Box::new(Expr::Op(<>)),
    AdditiveExpr,
}

pub AdditiveExpr: Box<Expr> = {
    AdditiveExpr AdditiveOp MultiplicativeExpr => Box::new(Expr::Op(<>)),
    MultiplicativeExpr,
}

pub MultiplicativeExpr: Box<Expr> = {
    MultiplicativeExpr MultiplicativeOp Term => Box::new(Expr::Op(<>)),
    Term,
}

LogicalOp: Op = {
    "&&" => Op::Logical(LogicalOp::And),
    "||" => Op::Logical(LogicalOp::Or),
};

RelationalOp: Op = {
    ">" => Op::Relational(RelationalOp::Gt),
    "<" => Op::Relational(RelationalOp::Lt),
    ">=" => Op::Relational(RelationalOp::Gte),
    "<=" => Op::Relational(RelationalOp::Lte),
    "==" => Op::Relational(RelationalOp::Eq),
    "!=" => Op::Relational(RelationalOp::Neq),
    "in" => Op::Relational(RelationalOp::In),
};

AdditiveOp: Op = {
    "+" => Op::Additive(AdditiveOp::Add),
    "-" => Op::Additive(AdditiveOp::Sub),
};

MultiplicativeOp: Op = {
    "*" => Op::Multiplicative(MultiplicativeOp::Mul),
    "/" => Op::Multiplicative(MultiplicativeOp::Div),
    "%" => Op::Multiplicative(MultiplicativeOp::Mod),
};

Value: Value = {
    StringValue => Value::String(<>),
    NumberValue => Value::Number(<>),
    BoolValue => Value::Bool(<>),
}

Term: Box<Expr> = {
    Value => Box::new(Expr::Value(<>)),
    Array<Value> => Box::new(Expr::Value(Value::Array(<>))),
    Identifier => Box::new(Expr::Identifier(parse_parameter_name(&<>))),
    "(" <Expr> ")",
}

Array<T>: Vec<T> = {
    "[" <v:(<T> ",")*> <e:T?> "]" => match e {
        None => v,
        Some(e) => {
            let mut v = v;
            v.push(e);
            v
        }
    }
};

pub Identifier: String = r#"\{[a-z][a-z0-9_]*\}"# => <>.to_string();
BoolValue: bool = {
    "true" => true,
    "false" => false,
}
NumberValue: f64 = {
    FloatValue,
    IntegerValue => <> as f64,
}
StringValue: String = r#"'[^']*'"# => <>.to_string();
IntegerValue: i64 = r#"[0-9]+"# => i64::from_str(<>).unwrap();
FloatValue: f64 = r#"[0-9]+\.[0-9]+"# => f64::from_str(<>).unwrap();