format code.

This commit is contained in:
fengcen 2016-11-17 23:53:17 +08:00
parent 3729348632
commit 3c19414593
7 changed files with 237 additions and 155 deletions

View File

@ -20,7 +20,7 @@ impl BuiltIn {
#[derive(PartialEq)] #[derive(PartialEq)]
enum Compare { enum Compare {
Min, Min,
Max Max,
} }
fn create_min_fuction() -> Function { fn create_min_fuction() -> Function {
@ -36,7 +36,8 @@ fn compare(compare: Compare) -> Function {
max_args: None, max_args: None,
min_args: Some(1), min_args: Some(1),
compiled: Box::new(move |values| { compiled: Box::new(move |values| {
let mut prev: Result<Value, Error> = Err(Error::Custom("can't find min value.".to_owned())); let mut prev: Result<Value, Error> = Err(Error::Custom("can't find min value."
.to_owned()));
for value in values { for value in values {
match value { match value {
@ -56,7 +57,7 @@ fn compare(compare: Compare) -> Function {
prev = Ok(value); prev = Ok(value);
} }
} }
}, }
_ => { _ => {
if prev.is_ok() { if prev.is_ok() {
if compare == Compare::Min { if compare == Compare::Min {
@ -75,7 +76,7 @@ fn compare(compare: Compare) -> Function {
} }
} }
prev prev
}) }),
} }
} }
@ -84,18 +85,18 @@ fn create_is_empty_fuction() -> Function {
Function { Function {
max_args: Some(1), max_args: Some(1),
min_args: Some(1), min_args: Some(1),
compiled: Box::new(|values|{ compiled: Box::new(|values| {
match *values.first().unwrap() { match *values.first().unwrap() {
Value::String(ref string) => Ok(Value::Bool(string.is_empty())), Value::String(ref string) => Ok(Value::Bool(string.is_empty())),
Value::Array(ref array) => Ok(Value::Bool(array.is_empty())), Value::Array(ref array) => Ok(Value::Bool(array.is_empty())),
Value::Object(ref object) => Ok(Value::Bool(object.is_empty())), Value::Object(ref object) => Ok(Value::Bool(object.is_empty())),
Value::Null => Ok(Value::Bool(true)), Value::Null => Ok(Value::Bool(true)),
_ => Ok(Value::Bool(false)) _ => Ok(Value::Bool(false)),
} }
}) }),
} }
} }
fn create_array_function() -> Function { fn create_array_function() -> Function {
Function::new(|values|Ok(to_value(values))) Function::new(|values| Ok(to_value(values)))
} }

View File

@ -15,15 +15,12 @@ pub struct Expression {
pub raw: String, pub raw: String,
pub pos: Vec<usize>, pub pos: Vec<usize>,
pub operators: Vec<Operator>, pub operators: Vec<Operator>,
pub node: Option<Node> pub node: Option<Node>,
} }
impl Expression { impl Expression {
pub fn new<T: Into<String>>(raw: T) -> Result<Expression, Error> { pub fn new<T: Into<String>>(raw: T) -> Result<Expression, Error> {
let mut expr = Expression { let mut expr = Expression { raw: raw.into(), ..Default::default() };
raw: raw.into(),
..Default::default()
};
expr.parse_pos()?; expr.parse_pos()?;
expr.parse_operators()?; expr.parse_operators()?;
@ -36,19 +33,19 @@ impl Expression {
for (index, cur) in self.raw.chars().enumerate() { for (index, cur) in self.raw.chars().enumerate() {
match cur { match cur {
'(' | ')' | '+' | '-' | '*' | '/' | ',' | ' ' | '!' | '=' | '(' | ')' | '+' | '-' | '*' | '/' | ',' | ' ' | '!' | '=' | '>' | '<' | '\'' |
'>' | '<' | '\'' | '[' | ']' | '%' | '&' | '|' => { '[' | ']' | '%' | '&' | '|' => {
if ! found_quote { if !found_quote {
self.pos.push(index); self.pos.push(index);
self.pos.push(index + 1); self.pos.push(index + 1);
} }
}, }
'"' => { '"' => {
found_quote = ! found_quote; found_quote = !found_quote;
self.pos.push(index); self.pos.push(index);
self.pos.push(index + 1); self.pos.push(index + 1);
}, }
_ => () _ => (),
} }
} }
@ -90,8 +87,8 @@ impl Expression {
prev.clear(); prev.clear();
continue; continue;
} }
}, }
_ => () _ => (),
}; };
if quote.is_some() { if quote.is_some() {
@ -147,11 +144,11 @@ impl Expression {
operators.push(Operator::Function("array".to_owned())); operators.push(Operator::Function("array".to_owned()));
operators.push(operator); operators.push(operator);
continue; continue;
}, }
Operator::LeftParenthesis => { Operator::LeftParenthesis => {
parenthesis += 1; parenthesis += 1;
if ! operators.is_empty() { if !operators.is_empty() {
let prev_operator = operators.pop().unwrap(); let prev_operator = operators.pop().unwrap();
if prev_operator.is_identifier() { if prev_operator.is_identifier() {
operators.push(Operator::Function(prev_operator.get_identifier())); operators.push(Operator::Function(prev_operator.get_identifier()));
@ -161,11 +158,11 @@ impl Expression {
operators.push(prev_operator); operators.push(prev_operator);
} }
} }
}, }
Operator::RightParenthesis => parenthesis -= 1, Operator::RightParenthesis => parenthesis -= 1,
Operator::RightSquareBracket => square_brackets -= 1, Operator::RightSquareBracket => square_brackets -= 1,
Operator::WhiteSpace => continue, Operator::WhiteSpace => continue,
_ => () _ => (),
} }
prev = raw; prev = raw;
@ -185,17 +182,24 @@ impl Expression {
for operator in &self.operators { for operator in &self.operators {
match *operator { match *operator {
Operator::Add(priority) | Operator::Sub(priority) | Operator::Add(priority) |
Operator::Mul(priority) | Operator::Div(priority) | Operator::Sub(priority) |
Operator::Not(priority) | Operator::Eq(priority) | Operator::Mul(priority) |
Operator::Ne(priority) | Operator::Gt(priority) | Operator::Div(priority) |
Operator::Lt(priority) | Operator::Ge(priority) | Operator::Not(priority) |
Operator::And(priority) | Operator::Or(priority) | Operator::Eq(priority) |
Operator::Le(priority) | Operator::Rem(priority) => { Operator::Ne(priority) |
if ! parsing_nodes.is_empty() { Operator::Gt(priority) |
Operator::Lt(priority) |
Operator::Ge(priority) |
Operator::And(priority) |
Operator::Or(priority) |
Operator::Le(priority) |
Operator::Rem(priority) => {
if !parsing_nodes.is_empty() {
let prev = parsing_nodes.pop().unwrap(); let prev = parsing_nodes.pop().unwrap();
if prev.is_value_or_enough() { if prev.is_value_or_enough() {
if prev.operator.get_priority() < priority && ! prev.closed { if prev.operator.get_priority() < priority && !prev.closed {
parsing_nodes.extend_from_slice(&rob_to(prev, operator.to_node())); parsing_nodes.extend_from_slice(&rob_to(prev, operator.to_node()));
} else { } else {
parsing_nodes.push(operator.children_to_node(vec![prev])); parsing_nodes.push(operator.children_to_node(vec![prev]));
@ -211,12 +215,18 @@ impl Expression {
} else { } else {
return Err(Error::StartWithNonValueOperator); return Err(Error::StartWithNonValueOperator);
} }
}, }
Operator::Function(_) | Operator::LeftParenthesis | Operator::LeftSquareBracket => parsing_nodes.push(operator.to_node()), Operator::Function(_) |
Operator::LeftParenthesis |
Operator::LeftSquareBracket => parsing_nodes.push(operator.to_node()),
Operator::Comma => close_comma(&mut parsing_nodes)?, Operator::Comma => close_comma(&mut parsing_nodes)?,
Operator::RightParenthesis | Operator::RightSquareBracket => close_bracket(&mut parsing_nodes, operator.get_left())?, Operator::RightParenthesis |
Operator::Value(_) | Operator::Identifier(_) => append_child_to_last_node(&mut parsing_nodes, operator)?, Operator::RightSquareBracket => {
_ => () close_bracket(&mut parsing_nodes, operator.get_left())?
}
Operator::Value(_) |
Operator::Identifier(_) => append_child_to_last_node(&mut parsing_nodes, operator)?,
_ => (),
} }
} }
@ -230,21 +240,75 @@ impl Expression {
Box::new(move |contexts, buildin, functions| -> Result<Value, Error> { Box::new(move |contexts, buildin, functions| -> Result<Value, Error> {
return exec_node(&node, contexts, buildin, functions); return exec_node(&node, contexts, buildin, functions);
fn exec_node(node: &Node, contexts: ContextsRef, buildin: &Functions, functions: &Functions) -> Result<Value, Error> { fn exec_node(node: &Node,
contexts: ContextsRef,
buildin: &Functions,
functions: &Functions)
-> Result<Value, Error> {
match node.operator { match node.operator {
Operator::Add(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.add(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), Operator::Add(_) => {
Operator::Mul(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.mul(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), exec_node(&node.get_first_child(), contexts, buildin, functions)
Operator::Sub(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.sub(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), ?
Operator::Div(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.div(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), .add(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
Operator::Rem(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.rem(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), }
Operator::Eq(_) => Math::eq(&exec_node(&node.get_first_child(), contexts, buildin, functions)?, &exec_node(&node.get_last_child(), contexts, buildin, functions)?), Operator::Mul(_) => {
Operator::Ne(_) => Math::ne(&exec_node(&node.get_first_child(), contexts, buildin, functions)?, &exec_node(&node.get_last_child(), contexts, buildin, functions)?), exec_node(&node.get_first_child(), contexts, buildin, functions)
Operator::Gt(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.gt(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), ?
Operator::Lt(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.lt(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), .mul(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
Operator::Ge(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.ge(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), }
Operator::Le(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.le(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), Operator::Sub(_) => {
Operator::And(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.and(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), exec_node(&node.get_first_child(), contexts, buildin, functions)
Operator::Or(_) => exec_node(&node.get_first_child(), contexts, buildin, functions)?.or(&exec_node(&node.get_last_child(), contexts, buildin, functions)?), ?
.sub(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Div(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.div(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Rem(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.rem(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Eq(_) => {
Math::eq(&exec_node(&node.get_first_child(), contexts, buildin, functions)?,
&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Ne(_) => {
Math::ne(&exec_node(&node.get_first_child(), contexts, buildin, functions)?,
&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Gt(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.gt(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Lt(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.lt(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Ge(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.ge(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Le(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.le(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::And(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.and(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Or(_) => {
exec_node(&node.get_first_child(), contexts, buildin, functions)
?
.or(&exec_node(&node.get_last_child(), contexts, buildin, functions)?)
}
Operator::Function(ref ident) => { Operator::Function(ref ident) => {
let function_option = if functions.contains_key(ident) { let function_option = if functions.contains_key(ident) {
functions.get(ident) functions.get(ident)
@ -263,16 +327,17 @@ impl Expression {
} else { } else {
Err(Error::FunctionNotExists(ident.to_owned())) Err(Error::FunctionNotExists(ident.to_owned()))
} }
}, }
Operator::Value(ref value) => Ok(value.clone()), Operator::Value(ref value) => Ok(value.clone()),
Operator::Not(_) => { Operator::Not(_) => {
let value = exec_node(&node.get_first_child(), contexts, buildin, functions)?; let value =
exec_node(&node.get_first_child(), contexts, buildin, functions)?;
match value { match value {
Value::Bool(boolean) => Ok(Value::Bool(!boolean)), Value::Bool(boolean) => Ok(Value::Bool(!boolean)),
Value::Null => Ok(Value::Bool(true)), Value::Null => Ok(Value::Bool(true)),
_ => Err(Error::NotBoolean(value)) _ => Err(Error::NotBoolean(value)),
} }
}, }
Operator::Identifier(ref ident) => { Operator::Identifier(ref ident) => {
let number = parse_number(ident); let number = parse_number(ident);
if number.is_some() { if number.is_some() {
@ -282,18 +347,20 @@ impl Expression {
} else { } else {
match find(contexts, ident) { match find(contexts, ident) {
Some(value) => Ok(value), Some(value) => Ok(value),
None => Ok(Value::Null) None => Ok(Value::Null),
} }
} }
}, }
_ => Err(Error::CanNotExec(node.operator.clone())) _ => Err(Error::CanNotExec(node.operator.clone())),
} }
} }
}) })
} }
} }
fn append_child_to_last_node(parsing_nodes: &mut Vec<Node>, operator: &Operator) -> Result<(), Error> { fn append_child_to_last_node(parsing_nodes: &mut Vec<Node>,
operator: &Operator)
-> Result<(), Error> {
let mut node = operator.to_node(); let mut node = operator.to_node();
node.closed = true; node.closed = true;
@ -316,7 +383,7 @@ fn append_child_to_last_node(parsing_nodes: &mut Vec<Node>, operator: &Operator)
fn get_final_node(mut parsing_nodes: Vec<Node>) -> Result<Node, Error> { fn get_final_node(mut parsing_nodes: Vec<Node>) -> Result<Node, Error> {
if parsing_nodes.is_empty() { if parsing_nodes.is_empty() {
return Err(Error::NoFinalNode) return Err(Error::NoFinalNode);
} }
while parsing_nodes.len() != 1 { while parsing_nodes.len() != 1 {
@ -343,7 +410,7 @@ fn close_bracket(parsing_nodes: &mut Vec<Node>, bracket: Operator) -> Result<(),
return Err(Error::BracketNotWithFunction); return Err(Error::BracketNotWithFunction);
} }
} else if prev.operator == bracket { } else if prev.operator == bracket {
if ! current.closed { if !current.closed {
current.closed = true; current.closed = true;
} }
@ -361,13 +428,13 @@ fn close_bracket(parsing_nodes: &mut Vec<Node>, bracket: Operator) -> Result<(),
} }
break; break;
} else { } else {
if ! prev.closed { if !prev.closed {
prev.add_child(current); prev.add_child(current);
if prev.is_enough() { if prev.is_enough() {
prev.closed = true; prev.closed = true;
} }
if ! parsing_nodes.is_empty() { if !parsing_nodes.is_empty() {
parsing_nodes.push(prev); parsing_nodes.push(prev);
} else { } else {
return Err(Error::StartWithNonValueOperator); return Err(Error::StartWithNonValueOperator);
@ -410,13 +477,13 @@ fn close_comma(parsing_nodes: &mut Vec<Node>) -> Result<(), Error> {
return Err(Error::CommaNotWithFunction); return Err(Error::CommaNotWithFunction);
} }
} else { } else {
if ! prev.closed { if !prev.closed {
prev.add_child(current); prev.add_child(current);
if prev.is_enough() { if prev.is_enough() {
prev.closed = true; prev.closed = true;
} }
if ! parsing_nodes.is_empty() { if !parsing_nodes.is_empty() {
parsing_nodes.push(prev); parsing_nodes.push(prev);
} else { } else {
return Err(Error::StartWithNonValueOperator); return Err(Error::StartWithNonValueOperator);
@ -440,7 +507,7 @@ fn find(contexts: ContextsRef, key: &str) -> Option<Value> {
let value = get(context, key); let value = get(context, key);
match value { match value {
Some(_) => return value, Some(_) => return value,
None => continue None => continue,
} }
} }
@ -454,10 +521,10 @@ fn get(context: &Context, key: &str) -> Option<Value> {
if context_value_option.is_none() { if context_value_option.is_none() {
None None
} else if ! keys.is_empty() { } else if !keys.is_empty() {
match context_value_option.unwrap().search(&keys.join(".")) { match context_value_option.unwrap().search(&keys.join(".")) {
Some(value) => Some(value.clone()), Some(value) => Some(value.clone()),
None => None None => None,
} }
} else { } else {
Some(context_value_option.unwrap().clone()) Some(context_value_option.unwrap().clone())

View File

@ -11,22 +11,27 @@ pub struct Function {
/// Minimum number of arguments. /// Minimum number of arguments.
pub min_args: Option<usize>, pub min_args: Option<usize>,
/// Accept values and return a result which contains a value. /// Accept values and return a result which contains a value.
pub compiled: Box<Fn(Vec<Value>) -> Result<Value, Error> + Sync + Send> pub compiled: Box<Fn(Vec<Value>) -> Result<Value, Error> + Sync + Send>,
} }
impl Function { impl Function {
/// Create a function with a closure. /// Create a function with a closure.
pub fn new<F>(closure: F) -> Function where F: 'static + Fn(Vec<Value>) -> Result<Value, Error> + Sync + Send { pub fn new<F>(closure: F) -> Function
where F: 'static + Fn(Vec<Value>) -> Result<Value, Error> + Sync + Send
{
Function { Function {
max_args: None, max_args: None,
min_args: None, min_args: None,
compiled: Box::new(closure) compiled: Box::new(closure),
} }
} }
} }
impl fmt::Debug for Function { impl fmt::Debug for Function {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Function {{ max_args: {:?}, min_args: {:?} }}", self.max_args, self.min_args) write!(f,
"Function {{ max_args: {:?}, min_args: {:?} }}",
self.max_args,
self.min_args)
} }
} }

View File

@ -117,7 +117,10 @@ pub fn eval_with_functions(expr: &str, functions: &Functions) -> Result<Value, E
} }
/// Evaluates the value of an expression with the given context and functions. /// Evaluates the value of an expression with the given context and functions.
pub fn eval_with_context_and_functions(expr: &str, context: &Context, functions: &Functions) -> Result<Value, Error> { pub fn eval_with_context_and_functions(expr: &str,
context: &Context,
functions: &Functions)
-> Result<Value, Error> {
let mut contexts = Contexts::new(); let mut contexts = Contexts::new();
contexts.push(context.clone()); contexts.push(context.clone());
eval_with_contexts_and_functions(expr, &contexts, functions) eval_with_contexts_and_functions(expr, &contexts, functions)
@ -125,7 +128,10 @@ pub fn eval_with_context_and_functions(expr: &str, context: &Context, functions:
/// Evaluates the value of an expression with the given contexts and functions.<br> /// Evaluates the value of an expression with the given contexts and functions.<br>
/// The value of the last context is searched first. /// The value of the last context is searched first.
pub fn eval_with_contexts_and_functions(expr: &str, contexts: ContextsRef, functions: &Functions) -> Result<Value, Error> { pub fn eval_with_contexts_and_functions(expr: &str,
contexts: ContextsRef,
functions: &Functions)
-> Result<Value, Error> {
Expression::new(expr)?.compile()(contexts, &BuiltIn::new(), functions) Expression::new(expr)?.compile()(contexts, &BuiltIn::new(), functions)
} }
@ -194,7 +200,8 @@ mod tests {
#[test] #[test]
fn test_min_brackets() { fn test_min_brackets() {
assert_eq!(eval("(min(30, 5, 245, 20) * 10 + (5 + 5) * 5)"), Ok(to_value(100))); assert_eq!(eval("(min(30, 5, 245, 20) * 10 + (5 + 5) * 5)"),
Ok(to_value(100)));
} }
#[test] #[test]
@ -209,7 +216,8 @@ mod tests {
#[test] #[test]
fn test_max_brackets() { fn test_max_brackets() {
assert_eq!(eval("(max(30, 5, 245, 20) * 10 + (5 + 5) * 5)"), Ok(to_value(2500))); assert_eq!(eval("(max(30, 5, 245, 20) * 10 + (5 + 5) * 5)"),
Ok(to_value(2500)));
} }
#[test] #[test]
@ -301,12 +309,14 @@ mod tests {
#[test] #[test]
fn test_single_and_double_quote() { fn test_single_and_double_quote() {
assert_eq!(eval(r#"' """" ' + ' """" '"#), Ok(to_value(r#" """" """" "#))); assert_eq!(eval(r#"' """" ' + ' """" '"#),
Ok(to_value(r#" """" """" "#)));
} }
#[test] #[test]
fn test_double_and_single_quote() { fn test_double_and_single_quote() {
assert_eq!(eval(r#"" '''' " + " '''' ""#), Ok(to_value(r#" '''' '''' "#))); assert_eq!(eval(r#"" '''' " + " '''' ""#),
Ok(to_value(r#" '''' '''' "#)));
} }
#[test] #[test]
@ -398,7 +408,8 @@ mod tests {
fn test_buildin_is_empty() { fn test_buildin_is_empty() {
let mut context = Context::new(); let mut context = Context::new();
context.insert("array".to_owned(), to_value(Vec::<String>::new())); context.insert("array".to_owned(), to_value(Vec::<String>::new()));
assert_eq!(eval_with_context("is_empty(array)", &context), Ok(to_value(true))); assert_eq!(eval_with_context("is_empty(array)", &context),
Ok(to_value(true)));
} }
#[test] #[test]
@ -411,8 +422,10 @@ mod tests {
#[test] #[test]
fn test_custom_function() { fn test_custom_function() {
let mut functions = Functions::new(); let mut functions = Functions::new();
functions.insert("output".to_owned(), Function::new(|_|Ok(to_value("This is custom function's output")))); functions.insert("output".to_owned(),
assert_eq!(eval_with_functions("output()", &functions), Ok(to_value("This is custom function's output"))); Function::new(|_| Ok(to_value("This is custom function's output"))));
assert_eq!(eval_with_functions("output()", &functions),
Ok(to_value("This is custom function's output")));
} }
#[test] #[test]
@ -421,7 +434,7 @@ mod tests {
raw: "+ + 5".to_owned(), raw: "+ + 5".to_owned(),
pos: Vec::new(), pos: Vec::new(),
operators: Vec::new(), operators: Vec::new(),
node: None node: None,
}; };
expr.parse_pos().unwrap(); expr.parse_pos().unwrap();
@ -432,10 +445,7 @@ mod tests {
#[test] #[test]
fn test_error_duplicate_operator() { fn test_error_duplicate_operator() {
let mut expr = Expression { let mut expr = Expression { raw: "5 + + 5".to_owned(), ..Default::default() };
raw: "5 + + 5".to_owned(),
..Default::default()
};
expr.parse_pos().unwrap(); expr.parse_pos().unwrap();
expr.parse_operators().unwrap(); expr.parse_operators().unwrap();
@ -445,10 +455,7 @@ mod tests {
#[test] #[test]
fn test_error_duplicate_value() { fn test_error_duplicate_value() {
let mut expr = Expression { let mut expr = Expression { raw: "2 + 6 5".to_owned(), ..Default::default() };
raw: "2 + 6 5".to_owned(),
..Default::default()
};
expr.parse_pos().unwrap(); expr.parse_pos().unwrap();
expr.parse_operators().unwrap(); expr.parse_operators().unwrap();
@ -458,10 +465,7 @@ mod tests {
#[test] #[test]
fn test_error_unpaired_brackets() { fn test_error_unpaired_brackets() {
let mut expr = Expression { let mut expr = Expression { raw: "(2 + 3)) * 5".to_owned(), ..Default::default() };
raw: "(2 + 3)) * 5".to_owned(),
..Default::default()
};
expr.parse_pos().unwrap(); expr.parse_pos().unwrap();
@ -470,10 +474,7 @@ mod tests {
#[test] #[test]
fn test_error_comma() { fn test_error_comma() {
let mut expr = Expression { let mut expr = Expression { raw: ", 2 + 5".to_owned(), ..Default::default() };
raw: ", 2 + 5".to_owned(),
..Default::default()
};
expr.parse_pos().unwrap(); expr.parse_pos().unwrap();
expr.parse_operators().unwrap(); expr.parse_operators().unwrap();

View File

@ -165,7 +165,7 @@ impl Type for Value {
Value::F64(f) => f, Value::F64(f) => f,
Value::I64(f) => f as f64, Value::I64(f) => f as f64,
Value::U64(f) => f as f64, Value::U64(f) => f as f64,
_ => panic!("not a number") _ => panic!("not a number"),
} }
} }

View File

@ -8,7 +8,7 @@ use Function;
pub struct Node { pub struct Node {
pub operator: Operator, pub operator: Operator,
pub children: Vec<Node>, pub children: Vec<Node>,
pub closed: bool pub closed: bool,
} }
impl Node { impl Node {
@ -16,7 +16,7 @@ impl Node {
Node { Node {
operator: operator, operator: operator,
children: Vec::new(), children: Vec::new(),
closed: false closed: false,
} }
} }
@ -51,11 +51,7 @@ impl Node {
if self.operator.is_value_or_ident() { if self.operator.is_value_or_ident() {
true true
} else if self.operator.can_have_child() { } else if self.operator.can_have_child() {
if self.closed { if self.closed { true } else { self.is_enough() }
true
} else {
self.is_enough()
}
} else { } else {
false false
} }
@ -63,8 +59,8 @@ impl Node {
pub fn is_unclosed_function(&self) -> bool { pub fn is_unclosed_function(&self) -> bool {
match self.operator { match self.operator {
Operator::Function(_) => ! self.closed, Operator::Function(_) => !self.closed,
_ => false _ => false,
} }
} }

View File

@ -31,65 +31,68 @@ pub enum Operator {
Comma, Comma,
Function(String), Function(String),
Identifier(String), Identifier(String),
Value(Value) Value(Value),
} }
impl Operator { impl Operator {
pub fn is_identifier(&self) -> bool { pub fn is_identifier(&self) -> bool {
match *self { match *self {
Operator::Identifier(_) => true, Operator::Identifier(_) => true,
_ => false _ => false,
} }
} }
pub fn can_at_beginning(&self) -> bool { pub fn can_at_beginning(&self) -> bool {
match *self { match *self {
Operator::Not(_) | Operator::Function(_) | Operator::LeftParenthesis => true, Operator::Not(_) |
_ => false Operator::Function(_) |
Operator::LeftParenthesis => true,
_ => false,
} }
} }
pub fn get_max_args(&self) -> Option<usize> { pub fn get_max_args(&self) -> Option<usize> {
match *self { match *self {
Operator::Add(_) | Operator::Sub(_) | Operator::Add(_) | Operator::Sub(_) | Operator::Mul(_) | Operator::Div(_) |
Operator::Mul(_) | Operator::Div(_) | Operator::Eq(_) | Operator::Ne(_) | Operator::Gt(_) | Operator::Lt(_) |
Operator::Eq(_) | Operator::Ne(_) | Operator::Ge(_) | Operator::Le(_) | Operator::And(_) | Operator::Or(_) |
Operator::Gt(_) | Operator::Lt(_) | Operator::Rem(_) => Some(2),
Operator::Ge(_) | Operator::Le(_) |
Operator::And(_) | Operator::Or(_) |
Operator::Rem(_)=> Some(2),
Operator::Not(_) => Some(1), Operator::Not(_) => Some(1),
Operator::Function(_) => None, Operator::Function(_) => None,
_ => Some(0) _ => Some(0),
} }
} }
pub fn get_min_args(&self) -> Option<usize> { pub fn get_min_args(&self) -> Option<usize> {
match *self { match *self {
Operator::Add(_) | Operator::Sub(_) | Operator::Add(_) | Operator::Sub(_) | Operator::Mul(_) | Operator::Div(_) |
Operator::Mul(_) | Operator::Div(_) | Operator::Eq(_) | Operator::Ne(_) | Operator::Gt(_) | Operator::Lt(_) |
Operator::Eq(_) | Operator::Ne(_) | Operator::Ge(_) | Operator::Le(_) | Operator::And(_) | Operator::Or(_) |
Operator::Gt(_) | Operator::Lt(_) |
Operator::Ge(_) | Operator::Le(_) |
Operator::And(_) | Operator::Or(_) |
Operator::Rem(_) => Some(2), Operator::Rem(_) => Some(2),
Operator::Not(_) => Some(1), Operator::Not(_) => Some(1),
Operator::Function(_) => None, Operator::Function(_) => None,
_ => Some(0) _ => Some(0),
} }
} }
pub fn get_priority(&self) -> u8 { pub fn get_priority(&self) -> u8 {
match *self { match *self {
Operator::Add(priority) | Operator::Sub(priority) | Operator::Add(priority) |
Operator::Div(priority) | Operator::Mul(priority) | Operator::Sub(priority) |
Operator::Eq(priority) | Operator::Ne(priority) | Operator::Div(priority) |
Operator::Gt(priority) | Operator::Lt(priority) | Operator::Mul(priority) |
Operator::Ge(priority) | Operator::Le(priority) | Operator::Eq(priority) |
Operator::And(priority) | Operator::Or(priority) | Operator::Ne(priority) |
Operator::Gt(priority) |
Operator::Lt(priority) |
Operator::Ge(priority) |
Operator::Le(priority) |
Operator::And(priority) |
Operator::Or(priority) |
Operator::Rem(priority) => priority, Operator::Rem(priority) => priority,
Operator::Value(_) | Operator::Identifier(_) => 0, Operator::Value(_) |
_ => 99 Operator::Identifier(_) => 0,
_ => 99,
} }
} }
@ -100,34 +103,43 @@ impl Operator {
pub fn is_not(&self) -> bool { pub fn is_not(&self) -> bool {
match *self { match *self {
Operator::Not(_) => true, Operator::Not(_) => true,
_ => false _ => false,
} }
} }
pub fn is_value_or_ident(&self) -> bool { pub fn is_value_or_ident(&self) -> bool {
match *self { match *self {
Operator::Value(_) | Operator::Identifier(_) => true, Operator::Value(_) |
_ => false Operator::Identifier(_) => true,
_ => false,
} }
} }
pub fn can_have_child(&self) -> bool { pub fn can_have_child(&self) -> bool {
match *self { match *self {
Operator::Function(_) | Operator::Add(_) | Operator::Function(_) |
Operator::Sub(_) | Operator::Div(_) | Operator::Add(_) |
Operator::Mul(_) | Operator::Rem(_) | Operator::Sub(_) |
Operator::Eq(_) | Operator::Ne(_) | Operator::Div(_) |
Operator::Gt(_) | Operator::Lt(_) | Operator::Mul(_) |
Operator::And(_) | Operator::Or(_) | Operator::Rem(_) |
Operator::Ge(_) | Operator::Le(_) => true, Operator::Eq(_) |
_ => false Operator::Ne(_) |
Operator::Gt(_) |
Operator::Lt(_) |
Operator::And(_) |
Operator::Or(_) |
Operator::Ge(_) |
Operator::Le(_) => true,
_ => false,
} }
} }
pub fn is_left(&self) -> bool { pub fn is_left(&self) -> bool {
match *self { match *self {
Operator::LeftParenthesis | Operator::LeftSquareBracket => true, Operator::LeftParenthesis |
_ => false Operator::LeftSquareBracket => true,
_ => false,
} }
} }
@ -135,12 +147,12 @@ impl Operator {
match *self { match *self {
Operator::RightParenthesis => Operator::LeftParenthesis, Operator::RightParenthesis => Operator::LeftParenthesis,
Operator::RightSquareBracket => Operator::LeftSquareBracket, Operator::RightSquareBracket => Operator::LeftSquareBracket,
_ => panic!("not bracket") _ => panic!("not bracket"),
} }
} }
pub fn to_node(&self) -> Node { pub fn to_node(&self) -> Node {
Node::new(self.clone()) Node::new(self.clone())
} }
pub fn children_to_node(&self, children: Vec<Node>) -> Node { pub fn children_to_node(&self, children: Vec<Node>) -> Node {
@ -152,7 +164,7 @@ impl Operator {
pub fn get_identifier(&self) -> String { pub fn get_identifier(&self) -> String {
match *self { match *self {
Operator::Identifier(ref ident) => ident.to_owned(), Operator::Identifier(ref ident) => ident.to_owned(),
_ => panic!("not identifier") _ => panic!("not identifier"),
} }
} }
} }
@ -186,7 +198,7 @@ impl FromStr for Operator {
"<=" => Ok(Operator::Le(6)), "<=" => Ok(Operator::Le(6)),
"&&" => Ok(Operator::And(4)), "&&" => Ok(Operator::And(4)),
"||" => Ok(Operator::Or(2)), "||" => Ok(Operator::Or(2)),
_ => Ok(Operator::Identifier(raw.to_owned())) _ => Ok(Operator::Identifier(raw.to_owned())),
} }
} }
} }