arithmetic expressions

main
Ziyang Hu 2 years ago
parent 50f844f8e4
commit c9c7447bb8

@ -14,6 +14,8 @@ use crate::error::CozoError::UnexpectedDataKind;
use crate::relation::data::DataKind;
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
use crate::relation::value;
use crate::relation::value::Value::Apply;
pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<u32>;
@ -240,10 +242,10 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
Value::Apply(op, args) => {
use crate::relation::value;
Ok(match op.as_ref() {
value::OP_ADD => add_values(args)?,
value::OP_SUB => sub_values(args)?,
value::OP_MUL => { todo!() }
value::OP_DIV => { todo!() }
value::OP_ADD => self.add_values(args)?,
value::OP_SUB => self.sub_values(args)?,
value::OP_MUL => self.mul_values(args)?,
value::OP_DIV => self.div_values(args)?,
value::OP_EQ => { todo!() }
value::OP_NE => { todo!() }
value::OP_OR => { todo!() }
@ -262,14 +264,78 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
}
}
}
}
fn add_values(args: Vec<Value>) -> Result<(bool, Value)> {
todo!()
fn add_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
fn sub_values(args: Vec<Value>) -> Result<(bool, Value)> {
todo!()
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l + r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l + (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) + r.into_inner()).into()),
(Value::Text(l), Value::Text(r)) => (true, (l.to_string() + r.as_ref()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn sub_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l - r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l - (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) - r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn mul_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l * r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l * (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) * r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn div_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l as f64 / r as f64).into()),
(Value::Float(l), Value::Int(r)) => (true, (l / (r as f64)).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) / r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
}
pub struct MemoryEnv {
root: BTreeMap<String, OwnTuple>,

@ -64,6 +64,9 @@ pub enum CozoError {
// #[error("Database already closed")]
// DatabaseClosed,
#[error("InvalidArgument")]
InvalidArgument,
#[error(transparent)]
ParseInt(#[from] std::num::ParseIntError),

@ -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 {

Loading…
Cancel
Save