|
|
|
@ -1,275 +1,5 @@
|
|
|
|
|
// use std::borrow::{Borrow, Cow};
|
|
|
|
|
// use std::sync::Arc;
|
|
|
|
|
// use crate::ast::Expr;
|
|
|
|
|
// use crate::ast::Expr::*;
|
|
|
|
|
// use crate::error::Result;
|
|
|
|
|
// use crate::error::CozoError;
|
|
|
|
|
// use crate::error::CozoError::*;
|
|
|
|
|
// use crate::value::Value::*;
|
|
|
|
|
// use crate::ast::*;
|
|
|
|
|
// use crate::env::{Env, Environment, LayeredEnv};
|
|
|
|
|
// use crate::storage::{DummyStorage, RocksStorage, Storage};
|
|
|
|
|
// use crate::typing::Structured;
|
|
|
|
|
//
|
|
|
|
|
// pub struct Evaluator<S: Storage> {
|
|
|
|
|
// pub env_stack: Vec<Environment>,
|
|
|
|
|
// pub storage: S,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// impl Env<Structured> for Evaluator<DummyStorage> {
|
|
|
|
|
// fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
// None
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
// false
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn resolve(&self, name: &str) -> Option<Cow<Structured>> {
|
|
|
|
|
// None
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
|
|
|
|
|
// None
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
// None
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// impl Env<Structured> for Evaluator<RocksStorage> {
|
|
|
|
|
// fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
// self.env_stack.last_mut().unwrap().define(name, value)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
// if self.env_stack.is_empty() {
|
|
|
|
|
// self.env_stack.push(Environment::default());
|
|
|
|
|
// }
|
|
|
|
|
// self.env_stack.last_mut().unwrap().define_new(name, value)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn resolve(&self, name: &str) -> Option<Cow<Structured>> {
|
|
|
|
|
// let mut res = None;
|
|
|
|
|
// for item in self.env_stack.iter().rev() {
|
|
|
|
|
// res = item.resolve(name);
|
|
|
|
|
// if res.is_some() {
|
|
|
|
|
// return res;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// // Unwrap here because read() only fails if lock is poisoned
|
|
|
|
|
// let env = self.storage.root_env.read().expect("Root environment is poisoned");
|
|
|
|
|
// env.resolve(name).map(|v| Cow::Owned(v.into_owned()))
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
|
|
|
|
|
// // Cannot obtain root elements this way
|
|
|
|
|
// let mut res = None;
|
|
|
|
|
// for item in self.env_stack.iter_mut().rev() {
|
|
|
|
|
// res = item.resolve_mut(name);
|
|
|
|
|
// if res.is_some() {
|
|
|
|
|
// return res;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// res
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
// // Cannot undef root elements this way
|
|
|
|
|
// let mut res = None;
|
|
|
|
|
// for item in self.env_stack.iter_mut().rev() {
|
|
|
|
|
// res = item.undef(name);
|
|
|
|
|
// if res.is_some() {
|
|
|
|
|
// return res;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// res
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// impl LayeredEnv<Structured> for Evaluator<RocksStorage> {
|
|
|
|
|
// fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
// self.storage.root_env.write().expect("Root environment is poisoned")
|
|
|
|
|
// .define(name, value)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn root_define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
// self.storage.root_env.write().expect("Root environment is poisoned")
|
|
|
|
|
// .define_new(name, value)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn root_resolve(&self, name: &str) -> Option<Cow<Structured>> {
|
|
|
|
|
// let env = self.storage.root_env.read().expect("Root environment is poisoned");
|
|
|
|
|
// env.resolve(name).map(|v| Cow::Owned(v.into_owned()))
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn root_undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
// self.storage.root_env.write().expect("Root environment is poisoned")
|
|
|
|
|
// .undef(name)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// pub type EvaluatorWithStorage = Evaluator<RocksStorage>;
|
|
|
|
|
// pub type BareEvaluator = Evaluator<DummyStorage>;
|
|
|
|
|
//
|
|
|
|
|
// impl<S: Storage> Evaluator<S> {
|
|
|
|
|
// pub fn new(storage: S) -> Result<Self> {
|
|
|
|
|
// Ok(Self {
|
|
|
|
|
// env_stack: vec![Environment::default()],
|
|
|
|
|
// storage,
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// impl<'a, S: Storage> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator<S>
|
|
|
|
|
// where Evaluator<S>: Env<Structured> {
|
|
|
|
|
// fn visit_expr(&self, ex: &Expr<'a>) -> Result<Expr<'a>> {
|
|
|
|
|
// match ex {
|
|
|
|
|
// Apply(op, args) => {
|
|
|
|
|
// match op {
|
|
|
|
|
// Op::Add => self.add_exprs(args),
|
|
|
|
|
// Op::Sub => self.sub_exprs(args),
|
|
|
|
|
// Op::Mul => self.mul_exprs(args),
|
|
|
|
|
// Op::Div => self.div_exprs(args),
|
|
|
|
|
// Op::Eq => self.eq_exprs(args),
|
|
|
|
|
// Op::Neq => self.ne_exprs(args),
|
|
|
|
|
// Op::Gt => self.gt_exprs(args),
|
|
|
|
|
// Op::Lt => self.lt_exprs(args),
|
|
|
|
|
// Op::Ge => self.ge_exprs(args),
|
|
|
|
|
// Op::Le => self.le_exprs(args),
|
|
|
|
|
// Op::Neg => self.negate_expr(args),
|
|
|
|
|
// Op::Minus => self.minus_expr(args),
|
|
|
|
|
// Op::Mod => self.mod_exprs(args),
|
|
|
|
|
// Op::Or => self.or_expr(args),
|
|
|
|
|
// Op::And => self.and_expr(args),
|
|
|
|
|
// Op::Coalesce => self.coalesce_exprs(args),
|
|
|
|
|
// Op::Pow => self.pow_exprs(args),
|
|
|
|
|
// Op::IsNull => self.test_null_expr(args),
|
|
|
|
|
// Op::NotNull => self.not_null_expr(args),
|
|
|
|
|
// Op::Call => unimplemented!(),
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// Const(v) => Ok(Const(v.clone())),
|
|
|
|
|
// Expr::List(_) => { unimplemented!() }
|
|
|
|
|
// Expr::Dict(_, _) => { unimplemented!() }
|
|
|
|
|
// Ident(ident) => {
|
|
|
|
|
// let resolved = self.resolve(ident).ok_or(UndefinedParam)?;
|
|
|
|
|
// match resolved.borrow() {
|
|
|
|
|
// Structured::Value(v) => {
|
|
|
|
|
// Ok(Const(v.clone()))
|
|
|
|
|
// }
|
|
|
|
|
// _ => return Err(ValueRequired)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// impl<S: Storage> Evaluator<S>
|
|
|
|
|
// where Evaluator<S>: Env<Structured> {
|
|
|
|
|
// fn add_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
|
|
|
|
|
// match exprs {
|
|
|
|
|
// [a, b] => {
|
|
|
|
|
// let a = self.visit_expr(a)?;
|
|
|
|
|
// let b = self.visit_expr(b)?;
|
|
|
|
|
// if a == Const(Null) || b == Const(Null) {
|
|
|
|
|
// return Ok(Const(Null));
|
|
|
|
|
// }
|
|
|
|
|
// Ok(Const(match (a, b) {
|
|
|
|
|
// (Const(a), Const(b)) => {
|
|
|
|
|
// match (a, b) {
|
|
|
|
|
// (Int(va), Int(vb)) => Int(va + vb),
|
|
|
|
|
// (Float(va), Int(vb)) => Float(va + vb as f64),
|
|
|
|
|
// (Int(va), Float(vb)) => Float(va as f64 + vb),
|
|
|
|
|
// (Float(va), Float(vb)) => Float(va + vb),
|
|
|
|
|
// (Text(va), Text(vb)) =>
|
|
|
|
|
// Text(Arc::new(Cow::Owned(va.clone().to_string() + &vb))),
|
|
|
|
|
// (_, _) => return Err(CozoError::TypeError)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// (a, b) => return Ok(Apply(Op::Add, vec![a, b]))
|
|
|
|
|
// }))
|
|
|
|
|
// }
|
|
|
|
|
// _ => unreachable!()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn sub_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
|
|
|
|
|
// match exprs {
|
|
|
|
|
// [a, b] => {
|
|
|
|
|
// let a = self.visit_expr(a)?;
|
|
|
|
|
// let b = self.visit_expr(b)?;
|
|
|
|
|
// if a == Const(Null) || b == Const(Null) {
|
|
|
|
|
// return Ok(Const(Null));
|
|
|
|
|
// }
|
|
|
|
|
// Ok(Const(match (a, b) {
|
|
|
|
|
// (Const(a), Const(b)) => {
|
|
|
|
|
// match (a, b) {
|
|
|
|
|
// (Int(va), Int(vb)) => Int(va - vb),
|
|
|
|
|
// (Float(va), Int(vb)) => Float(va - vb as f64),
|
|
|
|
|
// (Int(va), Float(vb)) => Float(va as f64 - vb),
|
|
|
|
|
// (Float(va), Float(vb)) => Float(va - vb),
|
|
|
|
|
// (_, _) => return Err(CozoError::TypeError)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// (a, b) => return Ok(Apply(Op::Sub, vec![a, b]))
|
|
|
|
|
// }))
|
|
|
|
|
// }
|
|
|
|
|
// _ => unreachable!()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn mul_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
|
|
|
|
|
// match exprs {
|
|
|
|
|
// [a, b] => {
|
|
|
|
|
// let a = self.visit_expr(a)?;
|
|
|
|
|
// let b = self.visit_expr(b)?;
|
|
|
|
|
// if a == Const(Null) || b == Const(Null) {
|
|
|
|
|
// return Ok(Const(Null));
|
|
|
|
|
// }
|
|
|
|
|
// Ok(Const(match (a, b) {
|
|
|
|
|
// (Const(a), Const(b)) => {
|
|
|
|
|
// match (a, b) {
|
|
|
|
|
// (Int(va), Int(vb)) => Int(va * vb),
|
|
|
|
|
// (Float(va), Int(vb)) => Float(va * vb as f64),
|
|
|
|
|
// (Int(va), Float(vb)) => Float(va as f64 * vb),
|
|
|
|
|
// (Float(va), Float(vb)) => Float(va * vb),
|
|
|
|
|
// (_, _) => return Err(CozoError::TypeError)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// (a, b) => return Ok(Apply(Op::Mul, vec![a, b]))
|
|
|
|
|
// }))
|
|
|
|
|
// }
|
|
|
|
|
// _ => unreachable!()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn div_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
|
|
|
|
|
// match exprs {
|
|
|
|
|
// [a, b] => {
|
|
|
|
|
// let a = self.visit_expr(a)?;
|
|
|
|
|
// let b = self.visit_expr(b)?;
|
|
|
|
|
// if a == Const(Null) || b == Const(Null) {
|
|
|
|
|
// return Ok(Const(Null));
|
|
|
|
|
// }
|
|
|
|
|
// Ok(Const(match (a, b) {
|
|
|
|
|
// (Const(a), Const(b)) => {
|
|
|
|
|
// match (a, b) {
|
|
|
|
|
// (Int(va), Int(vb)) => Float(va as f64 / vb as f64),
|
|
|
|
|
// (Float(va), Int(vb)) => Float(va / vb as f64),
|
|
|
|
|
// (Int(va), Float(vb)) => Float(va as f64 / vb),
|
|
|
|
|
// (Float(va), Float(vb)) => Float(va / vb),
|
|
|
|
|
// (_, _) => return Err(CozoError::TypeError)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// (a, b) => return Ok(Apply(Op::Div, vec![a, b]))
|
|
|
|
|
// }))
|
|
|
|
|
// }
|
|
|
|
|
// _ => unreachable!()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// fn mod_exprs<'a>(&self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
|
|
|
|
|
// match exprs {
|
|
|
|
|