diff --git a/Cargo.toml b/Cargo.toml index 8a5c3ede..cb99d7d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rhai" -version = "0.3.0" +version = "0.3.1" authors = ["Jonathan Turner"] description = "Embedded scripting for Rust" homepage = "https://github.com/jonathandturner/rhai" diff --git a/src/engine.rs b/src/engine.rs index e0e95ad4..4283ff80 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -4,7 +4,7 @@ use std::any::Any; use std::boxed::Box; use std::fmt; -use parser::{lex, parse, Expr, Stmt, FnDef }; +use parser::{lex, parse, Expr, Stmt, FnDef}; use fn_register::FnRegister; use std::ops::{Add, Sub, Mul, Div}; @@ -24,7 +24,7 @@ pub enum EvalAltResult { ErrorCantOpenScriptFile, InternalErrorMalformedDotExpression, LoopBreak, - Return(Box) + Return(Box), } @@ -33,17 +33,25 @@ impl Error for EvalAltResult { match *self { EvalAltResult::ErrorFunctionNotFound => "Function not found", EvalAltResult::ErrorFunctionArgMismatch => "Function argument types do not match", - EvalAltResult::ErrorFunctionCallNotSupported => "Function call with > 2 argument not supported", + EvalAltResult::ErrorFunctionCallNotSupported => { + "Function call with > 2 argument not supported" + } EvalAltResult::ErrorIndexMismatch => "Index does not match array", EvalAltResult::ErrorIfGuardMismatch => "If guards expect boolean expression", EvalAltResult::ErrorVariableNotFound(_) => "Variable not found", - EvalAltResult::ErrorFunctionArityNotSupported => "Functions of more than 3 parameters are not yet supported", - EvalAltResult::ErrorAssignmentToUnknownLHS => "Assignment to an unsupported left-hand side", + EvalAltResult::ErrorFunctionArityNotSupported => { + "Functions of more than 3 parameters are not yet supported" + } + EvalAltResult::ErrorAssignmentToUnknownLHS => { + "Assignment to an unsupported left-hand side" + } EvalAltResult::ErrorMismatchOutputType => "Cast of output failed", EvalAltResult::ErrorCantOpenScriptFile => "Cannot open script file", - EvalAltResult::InternalErrorMalformedDotExpression => "[Internal error] Unexpected expression in dot expression", + EvalAltResult::InternalErrorMalformedDotExpression => { + "[Internal error] Unexpected expression in dot expression" + } EvalAltResult::LoopBreak => "Loop broken before completion (not an error)", - EvalAltResult::Return(_) => "Function returned value (not an error)" + EvalAltResult::Return(_) => "Function returned value (not an error)", } } @@ -59,49 +67,112 @@ impl fmt::Display for EvalAltResult { } pub enum FnType { - ExternalFn0(BoxResult, EvalAltResult>>), - ExternalFn1(Box)->Result, EvalAltResult>>), - ExternalFn2(Box, &mut Box)->Result, EvalAltResult>>), - ExternalFn3(Box, &mut Box, &mut Box)->Result, EvalAltResult>>), - ExternalFn4(Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>>), - ExternalFn5(Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>>), - ExternalFn6(Box, &mut Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>>), + ExternalFn0(Box Result, EvalAltResult>>), + ExternalFn1(Box) -> Result, EvalAltResult>>), + ExternalFn2(Box, &mut Box) -> Result, EvalAltResult>>), + ExternalFn3(Box, &mut Box, &mut Box) + -> Result, EvalAltResult>>), + ExternalFn4(Box, &mut Box, &mut Box, &mut Box) + -> Result, EvalAltResult>>), + ExternalFn5(Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>>), + ExternalFn6(Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>>), - InternalFn(FnDef) + InternalFn(FnDef), } pub struct Engine { - pub fns: HashMap> + pub fns: HashMap>, } pub type Scope = Vec<(String, Box)>; impl Engine { - fn call_fn(&self, name: &str, arg1: Option<&mut Box>, arg2: Option<&mut Box>, arg3: Option<&mut Box>, - arg4: Option<&mut Box>, arg5: Option<&mut Box>, arg6: Option<&mut Box>) -> Result, EvalAltResult> { + fn call_fn(&self, + name: &str, + arg1: Option<&mut Box>, + arg2: Option<&mut Box>, + arg3: Option<&mut Box>, + arg4: Option<&mut Box>, + arg5: Option<&mut Box>, + arg6: Option<&mut Box>) + -> Result, EvalAltResult> { match self.fns.get(name) { Some(ref vf) => { match (arg1, arg2, arg3, arg4, arg5, arg6) { - (Some(ref mut a1), Some(ref mut a2), Some(ref mut a3), Some(ref mut a4), Some(ref mut a5), Some(ref mut a6)) => { + (Some(ref mut a1), + Some(ref mut a2), + Some(ref mut a3), + Some(ref mut a4), + Some(ref mut a5), + Some(ref mut a6)) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn6(ref f) => { + &FnType::ExternalFn6(ref f) => { match f(*a1, *a2, *a3, *a4, *a5, *a6) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 6 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 6 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); - let result2 = self.call_fn("clone", Some(a2), None, None, None, None, None); - let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None); - let result4 = self.call_fn("clone", Some(a4), None, None, None, None, None); - let result5 = self.call_fn("clone", Some(a5), None, None, None, None, None); - let result6 = self.call_fn("clone", Some(a6), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); + let result2 = self.call_fn("clone", + Some(a2), + None, + None, + None, + None, + None); + let result3 = self.call_fn("clone", + Some(a3), + None, + None, + None, + None, + None); + let result4 = self.call_fn("clone", + Some(a4), + None, + None, + None, + None, + None); + let result5 = self.call_fn("clone", + Some(a5), + None, + None, + None, + None, + None); + let result6 = self.call_fn("clone", + Some(a6), + None, + None, + None, + None, + None); match (result1, result2, result3, result4, result5, result6) { (Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5), Ok(r6)) => { @@ -111,37 +182,74 @@ impl Engine { new_scope.push((f.params[3].clone(), r4)); new_scope.push((f.params[4].clone(), r5)); new_scope.push((f.params[5].clone(), r6)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); } - (Some(ref mut a1), Some(ref mut a2), Some(ref mut a3), Some(ref mut a4), Some(ref mut a5), None) => { + (Some(ref mut a1), + Some(ref mut a2), + Some(ref mut a3), + Some(ref mut a4), + Some(ref mut a5), + None) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn5(ref f) => { + &FnType::ExternalFn5(ref f) => { match f(*a1, *a2, *a3, *a4, *a5) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 5 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 5 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); - let result2 = self.call_fn("clone", Some(a2), None, None, None, None, None); - let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None); - let result4 = self.call_fn("clone", Some(a4), None, None, None, None, None); - let result5 = self.call_fn("clone", Some(a5), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); + let result2 = self.call_fn("clone", + Some(a2), + None, + None, + None, + None, + None); + let result3 = self.call_fn("clone", + Some(a3), + None, + None, + None, + None, + None); + let result4 = self.call_fn("clone", + Some(a4), + None, + None, + None, + None, + None); + let result5 = self.call_fn("clone", + Some(a5), + None, + None, + None, + None, + None); match (result1, result2, result3, result4, result5) { (Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5)) => { @@ -150,51 +258,82 @@ impl Engine { new_scope.push((f.params[2].clone(), r3)); new_scope.push((f.params[3].clone(), r4)); new_scope.push((f.params[4].clone(), r5)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); } - (Some(ref mut a1), Some(ref mut a2), Some(ref mut a3), Some(ref mut a4), None, None) => { + (Some(ref mut a1), + Some(ref mut a2), + Some(ref mut a3), + Some(ref mut a4), + None, + None) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn4(ref f) => { + &FnType::ExternalFn4(ref f) => { match f(*a1, *a2, *a3, *a4) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 4 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 4 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); - let result2 = self.call_fn("clone", Some(a2), None, None, None, None, None); - let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None); - let result4 = self.call_fn("clone", Some(a4), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); + let result2 = self.call_fn("clone", + Some(a2), + None, + None, + None, + None, + None); + let result3 = self.call_fn("clone", + Some(a3), + None, + None, + None, + None, + None); + let result4 = self.call_fn("clone", + Some(a4), + None, + None, + None, + None, + None); match (result1, result2, result3, result4) { (Ok(r1), Ok(r2), Ok(r3), Ok(r4)) => { new_scope.push((f.params[0].clone(), r1)); new_scope.push((f.params[1].clone(), r2)); new_scope.push((f.params[2].clone(), r3)); new_scope.push((f.params[3].clone(), r4)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); @@ -202,33 +341,53 @@ impl Engine { (Some(ref mut a1), Some(ref mut a2), Some(ref mut a3), None, None, None) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn3(ref f) => { + &FnType::ExternalFn3(ref f) => { match f(*a1, *a2, *a3) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 3 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 3 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); - let result2 = self.call_fn("clone", Some(a2), None, None, None, None, None); - let result3 = self.call_fn("clone", Some(a3), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); + let result2 = self.call_fn("clone", + Some(a2), + None, + None, + None, + None, + None); + let result3 = self.call_fn("clone", + Some(a3), + None, + None, + None, + None, + None); match (result1, result2, result3) { (Ok(r1), Ok(r2), Ok(r3)) => { new_scope.push((f.params[0].clone(), r1)); new_scope.push((f.params[1].clone(), r2)); new_scope.push((f.params[2].clone(), r3)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); @@ -236,31 +395,45 @@ impl Engine { (Some(ref mut a1), Some(ref mut a2), None, None, None, None) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn2(ref f) => { + &FnType::ExternalFn2(ref f) => { match f(*a1, *a2) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 2 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 2 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); - let result2 = self.call_fn("clone", Some(a2), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); + let result2 = self.call_fn("clone", + Some(a2), + None, + None, + None, + None, + None); match (result1, result2) { (Ok(r1), Ok(r2)) => { new_scope.push((f.params[0].clone(), r1)); new_scope.push((f.params[1].clone(), r2)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); @@ -268,29 +441,37 @@ impl Engine { (Some(ref mut a1), None, None, None, None, None) => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn1(ref f) => { + &FnType::ExternalFn1(ref f) => { match f(*a1) { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 1 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 1 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); - let result1 = self.call_fn("clone", Some(a1), None, None, None, None, None); + let result1 = self.call_fn("clone", + Some(a1), + None, + None, + None, + None, + None); match result1 { Ok(r1) => { new_scope.push((f.params[0].clone(), r1)); - }, - _ => return Err(EvalAltResult::ErrorFunctionArgMismatch) + } + _ => return Err(EvalAltResult::ErrorFunctionArgMismatch), } match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); @@ -298,103 +479,140 @@ impl Engine { _ => { for arr_f in *vf { match arr_f { - & FnType::ExternalFn0(ref f) => { + &FnType::ExternalFn0(ref f) => { match f() { Ok(v) => return Ok(v), - _ => () + _ => (), } } - & FnType::InternalFn(ref f) => { - if f.params.len() != 0 { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + &FnType::InternalFn(ref f) => { + if f.params.len() != 0 { + return Err(EvalAltResult::ErrorFunctionArgMismatch); + } let mut new_scope: Scope = Vec::new(); match self.eval_stmt(&mut new_scope, &*f.body) { Err(EvalAltResult::Return(x)) => return Ok(x), - x => return x + x => return x, } } - _ => () + _ => (), } } return Err(EvalAltResult::ErrorFunctionArgMismatch); } } } - None => Err(EvalAltResult::ErrorFunctionNotFound) + None => Err(EvalAltResult::ErrorFunctionNotFound), } } - pub fn register_type(&mut self) { - fn clone_helper(t:T)->T { t.clone() }; + pub fn register_type(&mut self) { + fn clone_helper(t: T) -> T { + t.clone() + }; - self.register_fn("clone", clone_helper as fn(T)->T); + self.register_fn("clone", clone_helper as fn(T) -> T); } - pub fn register_get(&mut self, name: &str, get_fn: F) - where F : 'static+Fn(&mut T)->U { + pub fn register_get(&mut self, name: &str, get_fn: F) + where F: 'static + Fn(&mut T) -> U + { let get_name = "get$".to_string() + name; self.register_fn(&get_name, get_fn); } - pub fn register_set(&mut self, name: &str, set_fn: F) - where F : 'static+Fn(&mut T, U)->() { + pub fn register_set(&mut self, name: &str, set_fn: F) + where F: 'static + Fn(&mut T, U) -> () + { let set_name = "set$".to_string() + name; self.register_fn(&set_name, set_fn); } - pub fn register_get_set(&mut self, name: &str, get_fn: F, set_fn: G) - where F : 'static+Fn(&mut T)->U, G : 'static+Fn(&mut T, U)->() { + pub fn register_get_set(&mut self, + name: &str, + get_fn: F, + set_fn: G) + where F: 'static + Fn(&mut T) -> U, + G: 'static + Fn(&mut T, U) -> () + { self.register_get(name, get_fn); self.register_set(name, set_fn); } - fn get_dot_val_helper(&self, scope: &mut Scope, this_ptr: &mut Box, dot_rhs: &Expr) -> Result, EvalAltResult> { + fn get_dot_val_helper(&self, + scope: &mut Scope, + this_ptr: &mut Box, + dot_rhs: &Expr) + -> Result, EvalAltResult> { match *dot_rhs { Expr::FnCall(ref fn_name, ref args) => { if args.len() == 0 { return self.call_fn(&fn_name, Some(this_ptr), None, None, None, None, None); - } - else if args.len() == 1 { + } else if args.len() == 1 { let mut arg = try!(self.eval_expr(scope, &args[0])); - return self.call_fn(&fn_name, Some(this_ptr), Some(&mut arg), None, None, None, None); - } - else if args.len() == 2 { + return self.call_fn(&fn_name, + Some(this_ptr), + Some(&mut arg), + None, + None, + None, + None); + } else if args.len() == 2 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); - return self.call_fn(&fn_name, Some(this_ptr), Some(&mut arg1), Some(&mut arg2), None, None, None); - } - else if args.len() == 3 { + return self.call_fn(&fn_name, + Some(this_ptr), + Some(&mut arg1), + Some(&mut arg2), + None, + None, + None); + } else if args.len() == 3 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); - return self.call_fn(&fn_name, Some(this_ptr), Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), None, None); - } - else if args.len() == 4 { + return self.call_fn(&fn_name, + Some(this_ptr), + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + None, + None); + } else if args.len() == 4 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); let mut arg4 = try!(self.eval_expr(scope, &args[3])); - return self.call_fn(&fn_name, Some(this_ptr), Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), - Some(&mut arg4), None); - } - else if args.len() == 5 { + return self.call_fn(&fn_name, + Some(this_ptr), + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + Some(&mut arg4), + None); + } else if args.len() == 5 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); let mut arg4 = try!(self.eval_expr(scope, &args[3])); let mut arg5 = try!(self.eval_expr(scope, &args[4])); - return self.call_fn(&fn_name, Some(this_ptr), Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), - Some(&mut arg4), Some(&mut arg5)); - } - else { + return self.call_fn(&fn_name, + Some(this_ptr), + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + Some(&mut arg4), + Some(&mut arg5)); + } else { Err(EvalAltResult::ErrorFunctionCallNotSupported) } } @@ -407,20 +625,30 @@ impl Engine { let get_fn_name = "get$".to_string() + id; - if let Ok(mut val) = self.call_fn(&get_fn_name, Some(this_ptr), None, None, None, None, None) { + if let Ok(mut val) = self.call_fn(&get_fn_name, + Some(this_ptr), + None, + None, + None, + None, + None) { if let Ok(i) = idx.downcast::() { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { - return self.call_fn("clone", Some(&mut arr_typed[*i as usize]), None, None, None, None, None); - } - else { + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { + return self.call_fn("clone", + Some(&mut arr_typed[*i as usize]), + None, + None, + None, + None, + None); + } else { return Err(EvalAltResult::ErrorIndexMismatch); } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } } @@ -428,24 +656,34 @@ impl Engine { match **inner_lhs { Expr::Identifier(ref id) => { let get_fn_name = "get$".to_string() + id; - let result = self.call_fn(&get_fn_name, Some(this_ptr), None, None, None, None, None); + let result = self.call_fn(&get_fn_name, + Some(this_ptr), + None, + None, + None, + None, + None); match result { Ok(mut v) => return self.get_dot_val_helper(scope, &mut v, inner_rhs), - e => return e + e => return e, } } - _ => Err(EvalAltResult::InternalErrorMalformedDotExpression) + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } - _ => Err(EvalAltResult::InternalErrorMalformedDotExpression) + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } - fn get_dot_val(&self, scope: &mut Scope, dot_lhs: &Expr, dot_rhs: &Expr) -> Result, EvalAltResult> { + fn get_dot_val(&self, + scope: &mut Scope, + dot_lhs: &Expr, + dot_rhs: &Expr) + -> Result, EvalAltResult> { match *dot_lhs { Expr::Identifier(ref id) => { - let mut target : Option> = None; + let mut target: Option> = None; for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { @@ -454,8 +692,7 @@ impl Engine { if let Ok(clone) = result { target = Some(clone); break; - } - else { + } else { return result; } } @@ -477,25 +714,33 @@ impl Engine { } Expr::Index(ref id, ref idx_raw) => { let idx_boxed = try!(self.eval_expr(scope, idx_raw)); - let idx = if let Ok(i) = idx_boxed.downcast::() { i } else { return Err(EvalAltResult::ErrorIndexMismatch); }; + let idx = if let Ok(i) = idx_boxed.downcast::() { + i + } else { + return Err(EvalAltResult::ErrorIndexMismatch); + }; - let mut target : Option> = None; + let mut target: Option> = None; for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { - let result = self.call_fn("clone", Some(&mut arr_typed[*idx as usize]), - None, None, None, None, None); + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { + let result = self.call_fn("clone", + Some(&mut arr_typed[*idx as usize]), + None, + None, + None, + None, + None); if let Ok(clone) = result { target = Some(clone); break; - } - else { + } else { return result; } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } } @@ -505,7 +750,8 @@ impl Engine { let result = self.get_dot_val_helper(scope, &mut t, dot_rhs); for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { arr_typed[*idx as usize] = t; break; } @@ -516,21 +762,37 @@ impl Engine { Err(EvalAltResult::ErrorVariableNotFound(id.clone())) } - _ => Err(EvalAltResult::InternalErrorMalformedDotExpression) + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } - fn set_dot_val_helper(&self, this_ptr: &mut Box, dot_rhs: &Expr, mut source_val: Box) -> Result, EvalAltResult> { + fn set_dot_val_helper(&self, + this_ptr: &mut Box, + dot_rhs: &Expr, + mut source_val: Box) + -> Result, EvalAltResult> { match *dot_rhs { Expr::Identifier(ref id) => { let set_fn_name = "set$".to_string() + id; - self.call_fn(&set_fn_name, Some(this_ptr), Some(&mut source_val), None, None, None, None) + self.call_fn(&set_fn_name, + Some(this_ptr), + Some(&mut source_val), + None, + None, + None, + None) } Expr::Dot(ref inner_lhs, ref inner_rhs) => { match **inner_lhs { Expr::Identifier(ref id) => { let get_fn_name = "get$".to_string() + id; - let result = self.call_fn(&get_fn_name, Some(this_ptr), None, None, None, None, None); + let result = self.call_fn(&get_fn_name, + Some(this_ptr), + None, + None, + None, + None, + None); match result { Ok(mut v) => { @@ -538,36 +800,50 @@ impl Engine { Ok(_) => { let set_fn_name = "set$".to_string() + id; - self.call_fn(&set_fn_name, Some(this_ptr), Some(&mut v), None, None, None, None) + self.call_fn(&set_fn_name, + Some(this_ptr), + Some(&mut v), + None, + None, + None, + None) } - e => e + e => e, } - }, - e => e + } + e => e, } } - _ => Err(EvalAltResult::InternalErrorMalformedDotExpression) + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } - _ => { - Err(EvalAltResult::InternalErrorMalformedDotExpression) - } + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } - fn set_dot_val(&self, scope: &mut Scope, dot_lhs: &Expr, dot_rhs: &Expr, source_val: Box) -> Result, EvalAltResult> { + fn set_dot_val(&self, + scope: &mut Scope, + dot_lhs: &Expr, + dot_rhs: &Expr, + source_val: Box) + -> Result, EvalAltResult> { match *dot_lhs { Expr::Identifier(ref id) => { - let mut target : Option> = None; + let mut target: Option> = None; for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { - if let Ok(clone) = self.call_fn("clone", Some(val), None, None, None, None, None) { + if let Ok(clone) = self.call_fn("clone", + Some(val), + None, + None, + None, + None, + None) { target = Some(clone); break; - } - else { + } else { return Err(EvalAltResult::ErrorVariableNotFound(id.clone())); } } @@ -589,25 +865,33 @@ impl Engine { } Expr::Index(ref id, ref idx_raw) => { let idx_boxed = try!(self.eval_expr(scope, idx_raw)); - let idx = if let Ok(i) = idx_boxed.downcast::() { i } else { return Err(EvalAltResult::ErrorIndexMismatch); }; + let idx = if let Ok(i) = idx_boxed.downcast::() { + i + } else { + return Err(EvalAltResult::ErrorIndexMismatch); + }; - let mut target : Option> = None; + let mut target: Option> = None; for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { - let result = self.call_fn("clone", Some(&mut arr_typed[*idx as usize]), - None, None, None, None, None); + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { + let result = self.call_fn("clone", + Some(&mut arr_typed[*idx as usize]), + None, + None, + None, + None, + None); if let Ok(clone) = result { target = Some(clone); break; - } - else { + } else { return result; } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } } @@ -617,7 +901,8 @@ impl Engine { let result = self.set_dot_val_helper(&mut t, dot_rhs, source_val); for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { arr_typed[*idx as usize] = t; break; } @@ -628,7 +913,7 @@ impl Engine { Err(EvalAltResult::ErrorVariableNotFound(id.clone())) } - _ => Err(EvalAltResult::InternalErrorMalformedDotExpression) + _ => Err(EvalAltResult::InternalErrorMalformedDotExpression), } } @@ -651,14 +936,19 @@ impl Engine { for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { if let Ok(i) = idx.downcast::() { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { - return self.call_fn("clone", Some(&mut arr_typed[*i as usize]), None, None, None, None, None); - } - else { + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { + return self.call_fn("clone", + Some(&mut arr_typed[*i as usize]), + None, + None, + None, + None, + None); + } else { return Err(EvalAltResult::ErrorIndexMismatch); } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } } @@ -687,15 +977,14 @@ impl Engine { for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { if *id == *name { if let Ok(i) = idx.downcast::() { - if let Some(arr_typed) = (*val).downcast_mut() as Option<&mut Vec>> { + if let Some(arr_typed) = + (*val).downcast_mut() as Option<&mut Vec>> { arr_typed[*i as usize] = rhs_val; return Ok(Box::new(())); - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } - } - else { + } else { return Err(EvalAltResult::ErrorIndexMismatch); } } @@ -706,12 +995,10 @@ impl Engine { Expr::Dot(ref dot_lhs, ref dot_rhs) => { self.set_dot_val(scope, dot_lhs, dot_rhs, rhs_val) } - _ => Err(EvalAltResult::ErrorAssignmentToUnknownLHS) + _ => Err(EvalAltResult::ErrorAssignmentToUnknownLHS), } } - Expr::Dot(ref lhs, ref rhs) => { - self.get_dot_val(scope, lhs, rhs) - } + Expr::Dot(ref lhs, ref rhs) => self.get_dot_val(scope, lhs, rhs), Expr::Array(ref contents) => { let mut arr = Vec::new(); @@ -725,44 +1012,61 @@ impl Engine { Expr::FnCall(ref fn_name, ref args) => { if args.len() == 0 { self.call_fn(&fn_name, None, None, None, None, None, None) - } - else if args.len() == 1 { + } else if args.len() == 1 { let mut arg = try!(self.eval_expr(scope, &args[0])); self.call_fn(&fn_name, Some(&mut arg), None, None, None, None, None) - } - else if args.len() == 2 { + } else if args.len() == 2 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); - self.call_fn(&fn_name, Some(&mut arg1), Some(&mut arg2), None, None, None, None) - } - else if args.len() == 3 { + self.call_fn(&fn_name, + Some(&mut arg1), + Some(&mut arg2), + None, + None, + None, + None) + } else if args.len() == 3 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); - self.call_fn(&fn_name, Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), None, None, None) - } - else if args.len() == 4 { + self.call_fn(&fn_name, + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + None, + None, + None) + } else if args.len() == 4 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); let mut arg4 = try!(self.eval_expr(scope, &args[3])); - self.call_fn(&fn_name, Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), Some(&mut arg4), None, None) - } - else if args.len() == 5 { + self.call_fn(&fn_name, + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + Some(&mut arg4), + None, + None) + } else if args.len() == 5 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); let mut arg4 = try!(self.eval_expr(scope, &args[3])); let mut arg5 = try!(self.eval_expr(scope, &args[4])); - self.call_fn(&fn_name, Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), Some(&mut arg4), - Some(&mut arg5), None) - } - else if args.len() == 6 { + self.call_fn(&fn_name, + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + Some(&mut arg4), + Some(&mut arg5), + None) + } else if args.len() == 6 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); let mut arg3 = try!(self.eval_expr(scope, &args[2])); @@ -770,36 +1074,37 @@ impl Engine { let mut arg5 = try!(self.eval_expr(scope, &args[4])); let mut arg6 = try!(self.eval_expr(scope, &args[5])); - self.call_fn(&fn_name, Some(&mut arg1), Some(&mut arg2), Some(&mut arg3), Some(&mut arg4), - Some(&mut arg5), Some(&mut arg6)) - } - else { + self.call_fn(&fn_name, + Some(&mut arg1), + Some(&mut arg2), + Some(&mut arg3), + Some(&mut arg4), + Some(&mut arg5), + Some(&mut arg6)) + } else { Err(EvalAltResult::ErrorFunctionCallNotSupported) } } - Expr::True => { - Ok(Box::new(true)) - } - Expr::False => { - Ok(Box::new(false)) - } + Expr::True => Ok(Box::new(true)), + Expr::False => Ok(Box::new(false)), } } fn eval_stmt(&self, scope: &mut Scope, stmt: &Stmt) -> Result, EvalAltResult> { match *stmt { - Stmt::Expr(ref e) => { - self.eval_expr(scope, e) - } + Stmt::Expr(ref e) => self.eval_expr(scope, e), Stmt::Block(ref b) => { let prev_len = scope.len(); - let mut last_result : Result, EvalAltResult> = Ok(Box::new(())); + let mut last_result: Result, EvalAltResult> = Ok(Box::new(())); for s in b.iter() { last_result = self.eval_stmt(scope, s); match last_result { - Err(x) => {last_result = Err(x); break}, - _ => () + Err(x) => { + last_result = Err(x); + break; + } + _ => (), } } @@ -815,12 +1120,11 @@ impl Engine { Ok(g) => { if *g { self.eval_stmt(scope, body) - } - else { + } else { Ok(Box::new(())) } } - Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch) + Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch), } } Stmt::IfElse(ref guard, ref body, ref else_body) => { @@ -829,12 +1133,11 @@ impl Engine { Ok(g) => { if *g { self.eval_stmt(scope, body) - } - else { + } else { self.eval_stmt(scope, else_body) } } - Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch) + Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch), } } Stmt::While(ref guard, ref body) => { @@ -844,16 +1147,19 @@ impl Engine { Ok(g) => { if *g { match self.eval_stmt(scope, body) { - Err(EvalAltResult::LoopBreak) => { return Ok(Box::new(())); } - Err(x) => { return Err(x); } - _ => () + Err(EvalAltResult::LoopBreak) => { + return Ok(Box::new(())); + } + Err(x) => { + return Err(x); + } + _ => (), } - } - else { + } else { return Ok(Box::new(())); } } - Err(_) => return Err(EvalAltResult::ErrorIfGuardMismatch) + Err(_) => return Err(EvalAltResult::ErrorIfGuardMismatch), } } } @@ -865,11 +1171,11 @@ impl Engine { } Stmt::Var(ref name, ref init) => { match init { - & Some(ref v) => { + &Some(ref v) => { let i = try!(self.eval_expr(scope, v)); scope.push((name.clone(), i)); - }, - & None => { + } + &None => { scope.push((name.clone(), Box::new(()))); } }; @@ -878,7 +1184,7 @@ impl Engine { } } - pub fn eval_file(&mut self, fname: &str) -> Result { + pub fn eval_file(&mut self, fname: &str) -> Result { use std::fs::File; use std::io::prelude::*; @@ -887,23 +1193,24 @@ impl Engine { if let Ok(_) = f.read_to_string(&mut contents) { self.eval::(&contents) - } - else { + } else { Err(EvalAltResult::ErrorCantOpenScriptFile) } - } - else { + } else { Err(EvalAltResult::ErrorCantOpenScriptFile) } } - pub fn eval(&mut self, input: &str) -> Result { + pub fn eval(&mut self, input: &str) -> Result { let mut scope: Scope = Vec::new(); self.eval_with_scope(&mut scope, input) } - pub fn eval_with_scope(&mut self, scope: &mut Scope, input: &str) -> Result { + pub fn eval_with_scope(&mut self, + scope: &mut Scope, + input: &str) + -> Result { let tokens = lex(input); let mut peekables = tokens.peekable(); @@ -926,7 +1233,7 @@ impl Engine { for o in os { x = match self.eval_stmt(scope, &o) { Ok(v) => Ok(v), - Err(e) => return Err(e) + Err(e) => return Err(e), } } @@ -934,13 +1241,13 @@ impl Engine { Ok(v) => { match v.downcast::() { Ok(out) => Ok(*out), - Err(_) => Err(EvalAltResult::ErrorMismatchOutputType) + Err(_) => Err(EvalAltResult::ErrorMismatchOutputType), } } - Err(e) => Err(e) + Err(e) => Err(e), } } - Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch) + Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch), } } @@ -971,18 +1278,42 @@ impl Engine { ) } - fn add(x: T, y: T) -> ::Output { x + y } - fn sub(x: T, y: T) -> ::Output { x - y } - fn mul(x: T, y: T) -> ::Output { x * y } - fn div(x: T, y: T) -> ::Output { x / y } - fn lt(x: T, y: T) -> bool { x < y } - fn lte(x: T, y: T) -> bool { x <= y } - fn gt(x: T, y: T) -> bool { x > y } - fn gte(x: T, y: T) -> bool { x >= y } - fn eq(x: T, y: T) -> bool { x == y } - fn ne(x: T, y: T) -> bool { x != y } - fn and(x: bool, y: bool) -> bool { x && y } - fn or(x: bool, y: bool) -> bool { x || y } + fn add(x: T, y: T) -> ::Output { + x + y + } + fn sub(x: T, y: T) -> ::Output { + x - y + } + fn mul(x: T, y: T) -> ::Output { + x * y + } + fn div(x: T, y: T) -> ::Output { + x / y + } + fn lt(x: T, y: T) -> bool { + x < y + } + fn lte(x: T, y: T) -> bool { + x <= y + } + fn gt(x: T, y: T) -> bool { + x > y + } + fn gte(x: T, y: T) -> bool { + x >= y + } + fn eq(x: T, y: T) -> bool { + x == y + } + fn ne(x: T, y: T) -> bool { + x != y + } + fn and(x: bool, y: bool) -> bool { + x && y + } + fn or(x: bool, y: bool) -> bool { + x || y + } reg_op!(engine, "+", add, i32, i64, u32, u64, f32, f64); reg_op!(engine, "-", sub, i32, i64, u32, u64, f32, f64); @@ -999,17 +1330,15 @@ impl Engine { reg_op!(engine, "||", or, bool); reg_op!(engine, "&&", and, bool); - //engine.register_fn("[]", idx); - //FIXME? Registering array lookups are a special case because we want to return boxes directly - //let ent = engine.fns.entry("[]".to_string()).or_insert(Vec::new()); - //(*ent).push(FnType::ExternalFn2(Box::new(idx))); + // engine.register_fn("[]", idx); + // FIXME? Registering array lookups are a special case because we want to return boxes + // directly let ent = engine.fns.entry("[]".to_string()).or_insert(Vec::new()); + // (*ent).push(FnType::ExternalFn2(Box::new(idx))); } pub fn new() -> Engine { - let mut engine = Engine { - fns: HashMap::new() - }; + let mut engine = Engine { fns: HashMap::new() }; Engine::register_default_lib(&mut engine); @@ -1024,8 +1353,7 @@ fn test_number_literal() { if let Ok(result) = engine.eval::("65") { assert_eq!(result, 65); - } - else { + } else { assert!(false); } } @@ -1036,21 +1364,19 @@ fn test_chars() { if let Ok(result) = engine.eval::("'y'") { assert_eq!(result, 'y'); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("'\\u2764'") { assert_eq!(result, '❤'); - } - else { + } else { assert!(false); } match engine.eval::("''") { Err(_) => (), - _ => assert!(false) + _ => assert!(false), } } @@ -1060,15 +1386,13 @@ fn test_ops() { if let Ok(result) = engine.eval::("60 + 5") { assert_eq!(result, 65); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("(1 + 2) * (6 - 4) / 2") { assert_eq!(result, 3); - } - else { + } else { assert!(false); } } @@ -1079,7 +1403,7 @@ fn test_mismatched_op() { match engine.eval::("60 + \"hello\"") { Err(EvalAltResult::ErrorFunctionArgMismatch) => (), - _ => assert!(false) + _ => assert!(false), } } @@ -1089,8 +1413,7 @@ fn test_bool_op1() { if let Ok(result) = engine.eval::("true && (false || true)") { assert_eq!(result, true); - } - else { + } else { assert!(false); } } @@ -1101,8 +1424,7 @@ fn test_bool_op2() { if let Ok(result) = engine.eval::("false && (false || true)") { assert_eq!(result, false); - } - else { + } else { assert!(false); } } @@ -1113,8 +1435,7 @@ fn test_op_prec() { if let Ok(result) = engine.eval::("var x = 0; if x == 10 || true { x = 1} x") { assert_eq!(result, 1); - } - else { + } else { assert!(false); } } @@ -1125,22 +1446,19 @@ fn test_if() { if let Ok(result) = engine.eval::("if true { 55 }") { assert_eq!(result, 55); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("if false { 55 } else { 44 }") { assert_eq!(result, 44); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("if true { 55 } else { 44 }") { assert_eq!(result, 55); - } - else { + } else { assert!(false); } } @@ -1149,10 +1467,10 @@ fn test_if() { fn test_while() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval::("var x = 0; while x < 10 { x = x + 1; if x > 5 { break } } x") { + if let Ok(result) = engine.eval::("var x = 0; while x < 10 { x = x + 1; if x > 5 { \ + break } } x") { assert_eq!(result, 6); - } - else { + } else { assert!(false); } } @@ -1162,30 +1480,36 @@ fn test_var_scope() { let mut engine = Engine::new(); let mut scope: Scope = Vec::new(); - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "var x = 4 + 5") { } else { assert!(false); } + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "var x = 4 + 5") { + } else { + assert!(false); + } if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { assert_eq!(result, 9); - } - else { + } else { assert!(false); } - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "x = x + 1; x = x + 2;") { } else { assert!(false); } - - if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { - assert_eq!(result, 12); - } - else { + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "x = x + 1; x = x + 2;") { + } else { assert!(false); } - if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "{var x = 3}") { } else { assert!(false); } + if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { + assert_eq!(result, 12); + } else { + assert!(false); + } + + if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "{var x = 3}") { + } else { + assert!(false); + } if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { assert_eq!(result, 12); - } - else { + } else { assert!(false); } } @@ -1194,7 +1518,7 @@ fn test_var_scope() { fn test_method_call() { #[derive(Clone)] struct TestStruct { - x: i64 + x: i64, } impl TestStruct { @@ -1216,8 +1540,7 @@ fn test_method_call() { if let Ok(result) = engine.eval::("var x = new_ts(); x.update(); x") { assert_eq!(result.x, 1001); - } - else { + } else { assert!(false); } @@ -1227,7 +1550,7 @@ fn test_method_call() { fn test_get_set() { #[derive(Clone)] struct TestStruct { - x: i64 + x: i64, } impl TestStruct { @@ -1253,8 +1576,7 @@ fn test_get_set() { if let Ok(result) = engine.eval::("var a = new_ts(); a.x = 500; a.x") { assert_eq!(result, 500); - } - else { + } else { assert!(false); } } @@ -1263,7 +1585,7 @@ fn test_get_set() { fn test_big_get_set() { #[derive(Clone)] struct TestChild { - x: i64 + x: i64, } impl TestChild { @@ -1282,7 +1604,7 @@ fn test_big_get_set() { #[derive(Clone)] struct TestParent { - child: TestChild + child: TestChild, } impl TestParent { @@ -1297,7 +1619,6 @@ fn test_big_get_set() { fn new() -> TestParent { TestParent { child: TestChild::new() } } - } let mut engine = Engine::new(); @@ -1312,8 +1633,7 @@ fn test_big_get_set() { if let Ok(result) = engine.eval::("var a = new_tp(); a.child.x = 500; a.child.x") { assert_eq!(result, 500); - } - else { + } else { assert!(false); } } @@ -1324,15 +1644,13 @@ fn test_internal_fn() { if let Ok(result) = engine.eval::("fn addme(a, b) { a+b } addme(3, 4)") { assert_eq!(result, 7); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("fn bob() { return 4; 5 } bob()") { assert_eq!(result, 4); - } - else { + } else { assert!(false); } } @@ -1341,10 +1659,10 @@ fn test_internal_fn() { fn test_big_internal_fn() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval::("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f } mathme(100, 5, 2, 9, 6, 32)") { + if let Ok(result) = engine.eval::("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f \ + } mathme(100, 5, 2, 9, 6, 32)") { assert_eq!(result, 112); - } - else { + } else { assert!(false); } } @@ -1355,8 +1673,7 @@ fn test_string() { if let Ok(result) = engine.eval::("\"Test string: \\u2764\"") { assert_eq!(result, "Test string: ❤"); - } - else { + } else { assert!(false); } } @@ -1367,15 +1684,13 @@ fn test_arrays() { if let Ok(result) = engine.eval::("var x = [1, 2, 3]; x[1]") { assert_eq!(result, 2); - } - else { + } else { assert!(false); } if let Ok(result) = engine.eval::("var y = [1, 2, 3]; y[1] = 5; y[1]") { assert_eq!(result, 5); - } - else { + } else { assert!(false); } } @@ -1384,7 +1699,7 @@ fn test_arrays() { fn test_array_with_structs() { #[derive(Clone)] struct TestStruct { - x: i64 + x: i64, } impl TestStruct { @@ -1415,17 +1730,14 @@ fn test_array_with_structs() { if let Ok(result) = engine.eval::("var a = [new_ts()]; a[0].x") { assert_eq!(result, 1); - } - else { + } else { assert!(false); } - if let Ok(result) = engine.eval::("var a = [new_ts()]; a[0].x = 100; a[0].update(); a[0].x") { + if let Ok(result) = engine.eval::("var a = [new_ts()]; a[0].x = 100; a[0].update(); \ + a[0].x") { assert_eq!(result, 1100); - } - else { + } else { assert!(false); } } - - diff --git a/src/fn_register.rs b/src/fn_register.rs index d3d4cb15..29e70637 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -8,31 +8,49 @@ pub trait FnRegister { } impl<'a, A, T, U, V, W, X, Y, Z> FnRegister for Engine - where A: 'static+Fn(&mut T, U, V, W, X, Y) -> Z, T: Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, - X: Clone+Any, Y: Clone+Any, Z: Any + where A: 'static + Fn(&mut T, U, V, W, X, Y) -> Z, + T: Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Clone + Any, + Y: Clone + Any, + Z: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box, - &mut Box)->Result, EvalAltResult>> = + let wrapped: Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box, + arg5: &mut Box, + arg6: &mut Box| { - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, - arg5: &mut Box, arg6: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + let inside6 = (*arg6).downcast_mut() as Option<&mut Y>; - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - let inside5 = (*arg5).downcast_mut() as Option<&mut X>; - let inside6 = (*arg6).downcast_mut() as Option<&mut Y>; - - match (inside1, inside2, inside3, inside4, inside5, inside6) { - (Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(fun(b, c.clone(), d.clone(), - e.clone(), f.clone(), g.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4, inside5, inside6) { + (Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => { + Ok(Box::new(fun(b, + c.clone(), + d.clone(), + e.clone(), + f.clone(), + g.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn6(wrapped)); @@ -40,31 +58,49 @@ impl<'a, A, T, U, V, W, X, Y, Z> FnRegister fo } impl<'a, A, T, U, V, W, X, Y, Z> FnRegister for Engine - where A: 'static+Fn(T, U, V, W, X, Y) -> Z, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, - X: Clone+Any, Y: Clone+Any, Z: Any + where A: 'static + Fn(T, U, V, W, X, Y) -> Z, + T: Clone + Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Clone + Any, + Y: Clone + Any, + Z: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box, - &mut Box)->Result, EvalAltResult>> = + let wrapped: Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box, + arg5: &mut Box, + arg6: &mut Box| { - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, - arg5: &mut Box, arg6: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + let inside6 = (*arg6).downcast_mut() as Option<&mut Y>; - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - let inside5 = (*arg5).downcast_mut() as Option<&mut X>; - let inside6 = (*arg6).downcast_mut() as Option<&mut Y>; - - match (inside1, inside2, inside3, inside4, inside5, inside6) { - (Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), - e.clone(), f.clone(), g.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4, inside5, inside6) { + (Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => { + Ok(Box::new(fun(b.clone(), + c.clone(), + d.clone(), + e.clone(), + f.clone(), + g.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn6(wrapped)); @@ -72,27 +108,40 @@ impl<'a, A, T, U, V, W, X, Y, Z> FnRegister for En } impl<'a, A, T, U, V, W, X, Y> FnRegister for Engine - where A: 'static+Fn(&mut T, U, V, W, X) -> Y, T: Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any, Y: Any + where A: 'static + Fn(&mut T, U, V, W, X) -> Y, + T: Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Clone + Any, + Y: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, - arg5: &mut Box| { + let wrapped: Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box, + arg5: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; - match (inside1, inside2, inside3, inside4, inside5) { - (Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(fun(b, c.clone(), d.clone(), - e.clone(), f.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4, inside5) { + (Some(b), Some(c), Some(d), Some(e), Some(f)) => { + Ok(Box::new(fun(b, c.clone(), d.clone(), e.clone(), f.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn5(wrapped)); @@ -100,27 +149,44 @@ impl<'a, A, T, U, V, W, X, Y> FnRegister for Engi } impl<'a, A, T, U, V, W, X, Y> FnRegister for Engine - where A: 'static+Fn(T, U, V, W, X) -> Y, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any, Y: Any + where A: 'static + Fn(T, U, V, W, X) -> Y, + T: Clone + Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Clone + Any, + Y: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, - arg5: &mut Box| { + let wrapped: Box, + &mut Box, + &mut Box, + &mut Box, + &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box, + arg5: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; - match (inside1, inside2, inside3, inside4, inside5) { - (Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), - e.clone(), f.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4, inside5) { + (Some(b), Some(c), Some(d), Some(e), Some(f)) => { + Ok(Box::new(fun(b.clone(), + c.clone(), + d.clone(), + e.clone(), + f.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn5(wrapped)); @@ -128,23 +194,32 @@ impl<'a, A, T, U, V, W, X, Y> FnRegister for Engine } impl<'a, A, T, U, V, W, X> FnRegister for Engine - where A: 'static+Fn(&mut T, U, V, W) -> X, T: Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Any + where A: 'static + Fn(&mut T, U, V, W) -> X, + T: Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let wrapped: Box, &mut Box, &mut Box, &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - match (inside1, inside2, inside3, inside4) { - (Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b, c.clone(), d.clone(), e.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4) { + (Some(b), Some(c), Some(d), Some(e)) => { + Ok(Box::new(fun(b, c.clone(), d.clone(), e.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn4(wrapped)); @@ -152,23 +227,32 @@ impl<'a, A, T, U, V, W, X> FnRegister for Engine } impl<'a, A, T, U, V, W, X> FnRegister for Engine - where A: 'static+Fn(T, U, V, W) -> X, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Any + where A: 'static + Fn(T, U, V, W) -> X, + T: Clone + Any, + U: Clone + Any, + V: Clone + Any, + W: Clone + Any, + X: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let wrapped: Box, &mut Box, &mut Box, &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, + arg2: &mut Box, + arg3: &mut Box, + arg4: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; - match (inside1, inside2, inside3, inside4) { - (Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), e.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3, inside4) { + (Some(b), Some(c), Some(d), Some(e)) => { + Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), e.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn4(wrapped)); @@ -176,22 +260,27 @@ impl<'a, A, T, U, V, W, X> FnRegister for Engine } impl<'a, A, T, U, V, W> FnRegister for Engine - where A: 'static+Fn(&mut T, U, V) -> W, T: Any, U: Clone+Any, V: Clone+Any, W: Any + where A: 'static + Fn(&mut T, U, V) -> W, + T: Any, + U: Clone + Any, + V: Clone + Any, + W: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let wrapped: Box, &mut Box, &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - match (inside1, inside2, inside3) { - (Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b, c.clone(), d.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3) { + (Some(b), Some(c), Some(d)) => { + Ok(Box::new(fun(b, c.clone(), d.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn3(wrapped)); @@ -199,22 +288,27 @@ impl<'a, A, T, U, V, W> FnRegister for Engine } impl<'a, A, T, U, V, W> FnRegister for Engine - where A: 'static+Fn(T, U, V) -> W, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Any + where A: 'static + Fn(T, U, V) -> W, + T: Clone + Any, + U: Clone + Any, + V: Clone + Any, + W: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let wrapped: Box, &mut Box, &mut Box) + -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; - match (inside1, inside2, inside3) { - (Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) + match (inside1, inside2, inside3) { + (Some(b), Some(c), Some(d)) => { + Ok(Box::new(fun(b.clone(), c.clone(), d.clone())) as Box) } + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn3(wrapped)); @@ -222,21 +316,22 @@ impl<'a, A, T, U, V, W> FnRegister for Engine } impl<'a, A, T, U, V> FnRegister for Engine - where A: 'static+Fn(&mut T, U) -> V, T: Any, U: Clone+Any, V: Any + where A: 'static + Fn(&mut T, U) -> V, + T: Any, + U: Clone + Any, + V: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let wrapped: Box, &mut Box) -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, arg2: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - match (inside1, inside2) { - (Some(b), Some(c)) => Ok(Box::new(fun(b, c.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) - } + match (inside1, inside2) { + (Some(b), Some(c)) => Ok(Box::new(fun(b, c.clone())) as Box), + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn2(wrapped)); @@ -244,21 +339,22 @@ impl<'a, A, T, U, V> FnRegister for Engine } impl<'a, A, T, U, V> FnRegister for Engine - where A: 'static+Fn(T, U) -> V, T: Clone+Any, U: Clone+Any, V: Any + where A: 'static + Fn(T, U) -> V, + T: Clone + Any, + U: Clone + Any, + V: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box, &mut Box)->Result, EvalAltResult>> = - Box::new( - move |arg1: &mut Box, arg2: &mut Box| { - let inside1 = (*arg1).downcast_mut() as Option<&mut T>; - let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let wrapped: Box, &mut Box) -> Result, EvalAltResult>> = + Box::new(move |arg1: &mut Box, arg2: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; - match (inside1, inside2) { - (Some(b), Some(c)) => Ok(Box::new(fun(b.clone(), c.clone())) as Box), - _ => Err(EvalAltResult::ErrorFunctionArgMismatch) - } + match (inside1, inside2) { + (Some(b), Some(c)) => Ok(Box::new(fun(b.clone(), c.clone())) as Box), + _ => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn2(wrapped)); @@ -266,20 +362,20 @@ impl<'a, A, T, U, V> FnRegister for Engine } impl<'a, A, T, U> FnRegister for Engine - where A: 'static+Fn(&mut T) -> U, T: Any, U: Any + where A: 'static + Fn(&mut T) -> U, + T: Any, + U: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box)->Result, EvalAltResult>> = - Box::new( - move |arg: &mut Box| { - let inside = (*arg).downcast_mut() as Option<&mut T>; + let wrapped: Box) -> Result, EvalAltResult>> = + Box::new(move |arg: &mut Box| { + let inside = (*arg).downcast_mut() as Option<&mut T>; - match inside { - Some(b) => Ok(Box::new(fun(b)) as Box), - None => Err(EvalAltResult::ErrorFunctionArgMismatch) - } + match inside { + Some(b) => Ok(Box::new(fun(b)) as Box), + None => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn1(wrapped)); @@ -288,19 +384,19 @@ impl<'a, A, T, U> FnRegister for Engine impl<'a, A, T, U> FnRegister for Engine - where A: 'static+Fn(T) -> U, T: Clone+Any, U: Any + where A: 'static + Fn(T) -> U, + T: Clone + Any, + U: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : Box)->Result, EvalAltResult>> = - Box::new( - move |arg: &mut Box| { - let inside = (*arg).downcast_mut() as Option<&mut T>; - match inside { - Some(b) => Ok(Box::new(fun(b.clone())) as Box), - None => Err(EvalAltResult::ErrorFunctionArgMismatch) - } + let wrapped: Box) -> Result, EvalAltResult>> = + Box::new(move |arg: &mut Box| { + let inside = (*arg).downcast_mut() as Option<&mut T>; + match inside { + Some(b) => Ok(Box::new(fun(b.clone())) as Box), + None => Err(EvalAltResult::ErrorFunctionArgMismatch), } - ); + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn1(wrapped)); @@ -308,13 +404,13 @@ impl<'a, A, T, U> FnRegister for Engine } impl FnRegister for Engine - where A: 'static+Fn() -> T, T: Any + where A: 'static + Fn() -> T, + T: Any { fn register_fn(&mut self, name: &str, fun: A) { - let wrapped : BoxResult, EvalAltResult>> = - Box::new( - move || { Ok(Box::new(fun()) as Box) } - ); + let wrapped: Box Result, EvalAltResult>> = Box::new(move || { + Ok(Box::new(fun()) as Box) + }); let ent = self.fns.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(FnType::ExternalFn0(wrapped)); diff --git a/src/parser.rs b/src/parser.rs index cf19f9d8..9a559db5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,7 +10,7 @@ pub enum LexError { UnexpectedChar, MalformedEscapeSequence, MalformedNumber, - MalformedChar + MalformedChar, } impl Error for LexError { @@ -19,7 +19,7 @@ impl Error for LexError { LexError::UnexpectedChar => "Unexpected character in input", LexError::MalformedEscapeSequence => "Unexpected values in escape sequence", LexError::MalformedNumber => "Unexpected characters in number", - LexError::MalformedChar => "Char constant not a single character" + LexError::MalformedChar => "Char constant not a single character", } } @@ -47,7 +47,7 @@ pub enum ParseError { MalformedIndexExpr, VarExpectsIdentifier, FnMissingName, - FnMissingParams + FnMissingParams, } impl Error for ParseError { @@ -64,7 +64,7 @@ impl Error for ParseError { ParseError::MalformedIndexExpr => "Indexing expression missing correct index", ParseError::VarExpectsIdentifier => "'var' expects the name of a variable", ParseError::FnMissingName => "Function declaration is missing name", - ParseError::FnMissingParams => "Function declaration is missing parameters" + ParseError::FnMissingParams => "Function declaration is missing parameters", } } @@ -83,28 +83,188 @@ impl fmt::Display for ParseError { pub struct FnDef { pub name: String, pub params: Vec, - pub body: Box + pub body: Box, } #[derive(Debug, Clone)] -pub enum Stmt { If(Box, Box), IfElse(Box, Box, Box), While(Box, - Box), Var(String, Option>), Block(Box>), Expr(Box), Break, - Return, ReturnWithVal(Box) } +pub enum Stmt { + If(Box, Box), + IfElse(Box, Box, Box), + While(Box, Box), + Var(String, Option>), + Block(Box>), + Expr(Box), + Break, + Return, + ReturnWithVal(Box), +} #[derive(Debug, Clone)] -pub enum Expr { IntConst(i64), Identifier(String), CharConst(char), StringConst(String), - FnCall(String, Box>),Assignment(Box, Box), Dot(Box, Box), - Index(String, Box), Array(Box>), True, False } +pub enum Expr { + IntConst(i64), + Identifier(String), + CharConst(char), + StringConst(String), + FnCall(String, Box>), + Assignment(Box, Box), + Dot(Box, Box), + Index(String, Box), + Array(Box>), + True, + False, +} #[derive(Debug)] -pub enum Token { IntConst(i64), Identifier(String), CharConst(char), StringConst(String), - LCurly, RCurly, LParen, RParen, LSquare, RSquare, Plus, Minus, Multiply, Divide, Semicolon, - Colon, Comma, Period, Equals, True, False, Var, If, Else, While, LessThan, GreaterThan, - Bang, LessThanEqual, GreaterThanEqual, EqualTo, NotEqualTo, Pipe, Or, Ampersand, And, Fn, - Break, Return, LexErr(LexError) } +pub enum Token { + IntConst(i64), + Identifier(String), + CharConst(char), + StringConst(String), + LCurly, + RCurly, + LParen, + RParen, + LSquare, + RSquare, + Plus, + Minus, + Multiply, + Divide, + Semicolon, + Colon, + Comma, + Period, + Equals, + True, + False, + Var, + If, + Else, + While, + LessThan, + GreaterThan, + Bang, + LessThanEqual, + GreaterThanEqual, + EqualTo, + NotEqualTo, + Pipe, + Or, + Ampersand, + And, + Fn, + Break, + Return, + LexErr(LexError), +} pub struct TokenIterator<'a> { - char_stream: Peekable> + char_stream: Peekable>, +} + +impl<'a> TokenIterator<'a> { + pub fn parse_string_const(&mut self, enclosing_char: char) -> Result { + let mut result = Vec::new(); + let mut escape = false; + + while let Some(nxt) = self.char_stream.next() { + match nxt { + '\\' if !escape => escape = true, + '\\' if escape => { + escape = false; + result.push('\\'); + } + 't' if escape => { + escape = false; + result.push('\t'); + } + 'n' if escape => { + escape = false; + result.push('\n'); + } + 'r' if escape => { + escape = false; + result.push('\r'); + } + 'x' if escape => { + escape = false; + let mut out_val: u32 = 0; + for _ in 0..2 { + if let Some(c) = self.char_stream.next() { + if let Some(d1) = c.to_digit(16) { + out_val *= 16; + out_val += d1; + } else { + return Err(LexError::MalformedEscapeSequence); + } + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + + if let Some(r) = char::from_u32(out_val) { + result.push(r); + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + 'u' if escape => { + escape = false; + let mut out_val: u32 = 0; + for _ in 0..4 { + if let Some(c) = self.char_stream.next() { + if let Some(d1) = c.to_digit(16) { + out_val *= 16; + out_val += d1; + } else { + return Err(LexError::MalformedEscapeSequence); + } + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + + if let Some(r) = char::from_u32(out_val) { + result.push(r); + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + 'U' if escape => { + escape = false; + let mut out_val: u32 = 0; + for _ in 0..8 { + if let Some(c) = self.char_stream.next() { + if let Some(d1) = c.to_digit(16) { + out_val *= 16; + out_val += d1; + } else { + return Err(LexError::MalformedEscapeSequence); + } + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + + if let Some(r) = char::from_u32(out_val) { + result.push(r); + } else { + return Err(LexError::MalformedEscapeSequence); + } + } + x if enclosing_char == x && escape => result.push(x), + x if enclosing_char == x && !escape => break, + _ if escape => return Err(LexError::MalformedEscapeSequence), + _ => { + escape = false; + result.push(nxt); + } + } + } + + let out: String = result.iter().cloned().collect(); + Ok(out) + } } impl<'a> Iterator for TokenIterator<'a> { @@ -119,18 +279,21 @@ impl<'a> Iterator for TokenIterator<'a> { while let Some(&nxt) = self.char_stream.peek() { match nxt { - '0'...'9' => { result.push(nxt); self.char_stream.next(); }, - _ => break + '0'...'9' => { + result.push(nxt); + self.char_stream.next(); + } + _ => break, } } - let out : String = result.iter().cloned().collect(); + let out: String = result.iter().cloned().collect(); if let Ok(val) = out.parse::() { return Some(Token::IntConst(val)); } return Some(Token::LexErr(LexError::MalformedNumber)); - }, + } 'A'...'Z' | 'a'...'z' | '_' => { let mut result = Vec::new(); result.push(c); @@ -138,294 +301,171 @@ impl<'a> Iterator for TokenIterator<'a> { while let Some(&nxt) = self.char_stream.peek() { match nxt { '0'...'9' | 'A'...'Z' | 'a'...'z' | '_' => { - result.push(nxt); self.char_stream.next(); }, - _ => break + result.push(nxt); + self.char_stream.next(); + } + _ => break, } } - let out : String = result.iter().cloned().collect(); + let out: String = result.iter().cloned().collect(); if out == "true" { return Some(Token::True); - } - else if out == "false" { + } else if out == "false" { return Some(Token::False); - } - else if out == "var" { + } else if out == "var" { return Some(Token::Var); - } - else if out == "if" { + } else if out == "if" { return Some(Token::If); - } - else if out == "else" { + } else if out == "else" { return Some(Token::Else); - } - else if out == "while" { + } else if out == "while" { return Some(Token::While); - } - else if out == "break" { + } else if out == "break" { return Some(Token::Break); - } - else if out == "return" { + } else if out == "return" { return Some(Token::Return); - } - else if out == "fn" { + } else if out == "fn" { return Some(Token::Fn); - } - else { + } else { return Some(Token::Identifier(out)); } - }, + } '"' => { - let mut result = Vec::new(); - let mut escape = false; - - while let Some(nxt) = self.char_stream.next() { - match nxt { - '"' if !escape => break, - '\\' if !escape => escape = true, - '\\' if escape => {escape = false; result.push('\\'); }, - 't' if escape => {escape = false; result.push('\t'); }, - 'n' if escape => {escape = false; result.push('\n'); }, - 'r' if escape => {escape = false; result.push('\r'); }, - 'x' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..2 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - 'u' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..4 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - 'U' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..8 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - _ if escape => return Some(Token::LexErr(LexError::MalformedEscapeSequence)), - _ => { escape = false; result.push(nxt); }, - } + match self.parse_string_const('"') { + Ok(out) => return Some(Token::StringConst(out)), + Err(e) => return Some(Token::LexErr(e)), } - - let out : String = result.iter().cloned().collect(); - return Some(Token::StringConst(out)) } '\'' => { - let mut result = Vec::new(); - let mut escape = false; + match self.parse_string_const('\'') { + Ok(result) => { + let mut chars = result.chars(); - while let Some(nxt) = self.char_stream.next() { - match nxt { - '\'' if !escape => break, - '\\' if !escape => escape = true, - '\\' if escape => {escape = false; result.push('\\'); }, - 't' if escape => {escape = false; result.push('\t'); }, - 'n' if escape => {escape = false; result.push('\n'); }, - 'r' if escape => {escape = false; result.push('\r'); }, - 'x' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..2 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); + if let Some(out) = chars.next() { + println!("result: {}", result); + if chars.count() != 0 { + return Some(Token::LexErr(LexError::MalformedChar)); } + return Some(Token::CharConst(out)); + } else { + return Some(Token::LexErr(LexError::MalformedChar)); } - 'u' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..4 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - 'U' if escape => { - escape = false; - let mut out_val: u32 = 0; - for _ in 0..8 { - if let Some(c) = self.char_stream.next() { - if let Some(d1) = c.to_digit(16) { - out_val *= 16; - out_val += d1; - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - - if let Some(r) = char::from_u32(out_val) { - result.push(r); - } - else { - return Some(Token::LexErr(LexError::MalformedEscapeSequence)); - } - } - _ if escape => return Some(Token::LexErr(LexError::MalformedEscapeSequence)), - _ => { escape = false; result.push(nxt); }, } - } - - if result.len() != 1 { - return Some(Token::LexErr(LexError::MalformedChar)); - } - - if let Some(&out) = result.first() { - return Some(Token::CharConst(out)); - } - else { - return Some(Token::CharConst('\0')); + Err(e) => return Some(Token::LexErr(e)), } } - '{' => { return Some(Token::LCurly); }, - '}' => { return Some(Token::RCurly); }, - '(' => { return Some(Token::LParen); }, - ')' => { return Some(Token::RParen); }, - '[' => { return Some(Token::LSquare); }, - ']' => { return Some(Token::RSquare); }, - '+' => { return Some(Token::Plus); }, - '-' => { return Some(Token::Minus); }, - '*' => { return Some(Token::Multiply); }, - '/' => { return Some(Token::Divide); }, - ';' => { return Some(Token::Semicolon); }, - ':' => { return Some(Token::Colon); }, - ',' => { return Some(Token::Comma); }, - '.' => { return Some(Token::Period); }, + '{' => { + return Some(Token::LCurly); + } + '}' => { + return Some(Token::RCurly); + } + '(' => { + return Some(Token::LParen); + } + ')' => { + return Some(Token::RParen); + } + '[' => { + return Some(Token::LSquare); + } + ']' => { + return Some(Token::RSquare); + } + '+' => { + return Some(Token::Plus); + } + '-' => { + return Some(Token::Minus); + } + '*' => { + return Some(Token::Multiply); + } + '/' => { + return Some(Token::Divide); + } + ';' => { + return Some(Token::Semicolon); + } + ':' => { + return Some(Token::Colon); + } + ',' => { + return Some(Token::Comma); + } + '.' => { + return Some(Token::Period); + } '=' => { match self.char_stream.peek() { - Some(&'=') => {self.char_stream.next(); return Some(Token::EqualTo); }, - _ => { return Some(Token::Equals); } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::EqualTo); + } + _ => { + return Some(Token::Equals); + } } - }, + } '<' => { match self.char_stream.peek() { - Some(&'=') => {self.char_stream.next(); return Some(Token::LessThanEqual); }, - _ => { return Some(Token::LessThan); } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::LessThanEqual); + } + _ => { + return Some(Token::LessThan); + } } } '>' => { match self.char_stream.peek() { - Some(&'=') => {self.char_stream.next(); return Some(Token::GreaterThanEqual); }, - _ => { return Some(Token::GreaterThan); } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::GreaterThanEqual); + } + _ => { + return Some(Token::GreaterThan); + } } - }, + } '!' => { match self.char_stream.peek() { - Some(&'=') => {self.char_stream.next(); return Some(Token::NotEqualTo); }, - _ => { return Some(Token::Bang); } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::NotEqualTo); + } + _ => { + return Some(Token::Bang); + } } - }, + } '|' => { match self.char_stream.peek() { - Some(&'|') => {self.char_stream.next(); return Some(Token::Or); }, - _ => { return Some(Token::Pipe); } + Some(&'|') => { + self.char_stream.next(); + return Some(Token::Or); + } + _ => { + return Some(Token::Pipe); + } } - }, + } '&' => { match self.char_stream.peek() { - Some(&'&') => {self.char_stream.next(); return Some(Token::And); }, - _ => { return Some(Token::Ampersand); } + Some(&'&') => { + self.char_stream.next(); + return Some(Token::And); + } + _ => { + return Some(Token::Ampersand); + } } - }, + } ' ' | '\n' | '\r' => (), - _ => return Some(Token::LexErr(LexError::UnexpectedChar)) + _ => return Some(Token::LexErr(LexError::UnexpectedChar)), } } @@ -453,7 +493,7 @@ fn get_precedence(token: &Token) -> i32 { Token::Divide => 40, Token::Multiply => 40, Token::Period => 100, - _ => -1 + _ => -1, } } @@ -462,62 +502,72 @@ fn parse_paren_expr<'a>(input: &mut Peekable>) -> Result Ok(expr), - _ => Err(ParseError::MissingRParen) + _ => Err(ParseError::MissingRParen), } } -fn parse_call_expr<'a>(id: String, input: &mut Peekable>) -> Result { +fn parse_call_expr<'a>(id: String, + input: &mut Peekable>) + -> Result { let mut args = Vec::new(); match input.peek() { Some(&Token::RParen) => { input.next(); - return Ok(Expr::FnCall(id, Box::new(args))) - }, - _ => () + return Ok(Expr::FnCall(id, Box::new(args))); + } + _ => (), } loop { if let Ok(arg) = parse_expr(input) { args.push(arg); - } - else { + } else { return Err(ParseError::MalformedCallExpr); } match input.peek() { Some(&Token::RParen) => { input.next(); - return Ok(Expr::FnCall(id, Box::new(args))) - }, + return Ok(Expr::FnCall(id, Box::new(args))); + } Some(&Token::Comma) => (), - _ => return Err(ParseError::MalformedCallExpr) + _ => return Err(ParseError::MalformedCallExpr), } input.next(); } } -fn parse_index_expr<'a>(id: String, input: &mut Peekable>) -> Result { +fn parse_index_expr<'a>(id: String, + input: &mut Peekable>) + -> Result { if let Ok(idx) = parse_expr(input) { match input.peek() { Some(&Token::RSquare) => { input.next(); - return Ok(Expr::Index(id, Box::new(idx))) - }, - _ => return Err(ParseError::MalformedIndexExpr) + return Ok(Expr::Index(id, Box::new(idx))); + } + _ => return Err(ParseError::MalformedIndexExpr), } - } - else { + } else { return Err(ParseError::MalformedIndexExpr); } } -fn parse_ident_expr<'a>(id: String, input: &mut Peekable>) -> Result { +fn parse_ident_expr<'a>(id: String, + input: &mut Peekable>) + -> Result { match input.peek() { - Some(&Token::LParen) => {input.next(); parse_call_expr(id, input)}, - Some(&Token::LSquare) => {input.next(); parse_index_expr(id, input)}, - _ => return Ok(Expr::Identifier(id)) + Some(&Token::LParen) => { + input.next(); + parse_call_expr(id, input) + } + Some(&Token::LSquare) => { + input.next(); + parse_index_expr(id, input) + } + _ => return Ok(Expr::Identifier(id)), } } @@ -525,28 +575,33 @@ fn parse_array_expr<'a>(input: &mut Peekable>) -> Result true, - _ => false + Some(&Token::RSquare) => true, + _ => false, }; if !skip_contents { while let Some(_) = input.peek() { arr.push(try!(parse_expr(input))); match input.peek() { - Some(& Token::Comma) => {input.next();}, - _ => () + Some(&Token::Comma) => { + input.next(); + } + _ => (), } match input.peek() { - Some(& Token::RSquare) => break, - _ => () + Some(&Token::RSquare) => break, + _ => (), } } } match input.peek() { - Some(& Token::RSquare) => {input.next(); Ok(Expr::Array(Box::new(arr)))}, - _ => Err(ParseError::MissingRSquare) + Some(&Token::RSquare) => { + input.next(); + Ok(Expr::Array(Box::new(arr))) + } + _ => Err(ParseError::MissingRSquare), } } @@ -554,26 +609,32 @@ fn parse_array_expr<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { if let Some(token) = input.next() { match token { - Token::IntConst(ref x) => {Ok(Expr::IntConst(x.clone()))}, - Token::StringConst(ref s) => {Ok(Expr::StringConst(s.clone()))}, - Token::CharConst(ref c) => {Ok(Expr::CharConst(c.clone()))}, - Token::Identifier(ref s) => {parse_ident_expr(s.clone(), input)}, - Token::LParen => {parse_paren_expr(input)}, - Token::LSquare => {parse_array_expr(input)}, - Token::True => {Ok(Expr::True)}, - Token::False => {Ok(Expr::False)}, - Token::LexErr(le) => {println!("Error: {}", le); Err(ParseError::BadInput)} - _ => {println!("Can't parse: {:?}", token); Err(ParseError::BadInput)} + Token::IntConst(ref x) => Ok(Expr::IntConst(x.clone())), + Token::StringConst(ref s) => Ok(Expr::StringConst(s.clone())), + Token::CharConst(ref c) => Ok(Expr::CharConst(c.clone())), + Token::Identifier(ref s) => parse_ident_expr(s.clone(), input), + Token::LParen => parse_paren_expr(input), + Token::LSquare => parse_array_expr(input), + Token::True => Ok(Expr::True), + Token::False => Ok(Expr::False), + Token::LexErr(le) => { + println!("Error: {}", le); + Err(ParseError::BadInput) + } + _ => { + println!("Can't parse: {:?}", token); + Err(ParseError::BadInput) + } } - } - else { + } else { Err(ParseError::InputPastEndOfFile) } } -fn parse_binop<'a>(input: &mut Peekable>, prec: i32, lhs: Expr) - -> Result -{ +fn parse_binop<'a>(input: &mut Peekable>, + prec: i32, + lhs: Expr) + -> Result { let mut lhs_curr = lhs; loop { @@ -597,10 +658,9 @@ fn parse_binop<'a>(input: &mut Peekable>, prec: i32, lhs: Expr } if curr_prec < next_prec { - rhs = try!(parse_binop(input, curr_prec+1, rhs)); - } - else if curr_prec >= 100 { - //Always bind right to left for precedence over 100 + rhs = try!(parse_binop(input, curr_prec + 1, rhs)); + } else if curr_prec >= 100 { + // Always bind right to left for precedence over 100 rhs = try!(parse_binop(input, curr_prec, rhs)); } @@ -614,12 +674,16 @@ fn parse_binop<'a>(input: &mut Peekable>, prec: i32, lhs: Expr Token::EqualTo => Expr::FnCall("==".to_string(), Box::new(vec![lhs_curr, rhs])), Token::NotEqualTo => Expr::FnCall("!=".to_string(), Box::new(vec![lhs_curr, rhs])), Token::LessThan => Expr::FnCall("<".to_string(), Box::new(vec![lhs_curr, rhs])), - Token::LessThanEqual => Expr::FnCall("<=".to_string(), Box::new(vec![lhs_curr, rhs])), + Token::LessThanEqual => { + Expr::FnCall("<=".to_string(), Box::new(vec![lhs_curr, rhs])) + } Token::GreaterThan => Expr::FnCall(">".to_string(), Box::new(vec![lhs_curr, rhs])), - Token::GreaterThanEqual => Expr::FnCall(">=".to_string(), Box::new(vec![lhs_curr, rhs])), + Token::GreaterThanEqual => { + Expr::FnCall(">=".to_string(), Box::new(vec![lhs_curr, rhs])) + } Token::Or => Expr::FnCall("||".to_string(), Box::new(vec![lhs_curr, rhs])), Token::And => Expr::FnCall("&&".to_string(), Box::new(vec![lhs_curr, rhs])), - _ => return Err(ParseError::UnknownOperator) + _ => return Err(ParseError::UnknownOperator), }; } } @@ -638,14 +702,12 @@ fn parse_if<'a>(input: &mut Peekable>) -> Result { + Some(&Token::Else) => { input.next(); let else_body = try!(parse_block(input)); Ok(Stmt::IfElse(Box::new(guard), Box::new(body), Box::new(else_body))) } - _ => { - Ok(Stmt::If(Box::new(guard), Box::new(body))) - } + _ => Ok(Stmt::If(Box::new(guard), Box::new(body))), } } @@ -663,7 +725,7 @@ fn parse_var<'a>(input: &mut Peekable>) -> Result s.clone(), - _ => return Err(ParseError::VarExpectsIdentifier) + _ => return Err(ParseError::VarExpectsIdentifier), }; match input.peek() { @@ -672,14 +734,14 @@ fn parse_var<'a>(input: &mut Peekable>) -> Result Ok(Stmt::Var(name, None)) + _ => Ok(Stmt::Var(name, None)), } } fn parse_block<'a>(input: &mut Peekable>) -> Result { match input.peek() { - Some(& Token::LCurly) => (), - _ => return Err(ParseError::MissingLCurly) + Some(&Token::LCurly) => (), + _ => return Err(ParseError::MissingLCurly), } input.next(); @@ -687,28 +749,33 @@ fn parse_block<'a>(input: &mut Peekable>) -> Result true, - _ => false + Some(&Token::RCurly) => true, + _ => false, }; if !skip_body { while let Some(_) = input.peek() { stmts.push(try!(parse_stmt(input))); match input.peek() { - Some(& Token::Semicolon) => {input.next();}, - _ => () + Some(&Token::Semicolon) => { + input.next(); + } + _ => (), } match input.peek() { - Some(& Token::RCurly) => break, - _ => () + Some(&Token::RCurly) => break, + _ => (), } } } match input.peek() { - Some(& Token::RCurly) => {input.next(); Ok(Stmt::Block(Box::new(stmts)))}, - _ => Err(ParseError::MissingRCurly) + Some(&Token::RCurly) => { + input.next(); + Ok(Stmt::Block(Box::new(stmts))) + } + _ => Err(ParseError::MissingRCurly), } } @@ -719,19 +786,25 @@ fn parse_expr_stmt<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { match input.peek() { - Some(& Token::If) => parse_if(input), - Some(& Token::While) => parse_while(input), - Some(& Token::Break) => {input.next(); Ok(Stmt::Break)}, - Some(& Token::Return) => { + Some(&Token::If) => parse_if(input), + Some(&Token::While) => parse_while(input), + Some(&Token::Break) => { + input.next(); + Ok(Stmt::Break) + } + Some(&Token::Return) => { input.next(); match input.peek() { - Some(& Token::Semicolon) => Ok(Stmt::Return), - _ => {let ret = try!(parse_expr(input)); Ok(Stmt::ReturnWithVal(Box::new(ret))) } + Some(&Token::Semicolon) => Ok(Stmt::Return), + _ => { + let ret = try!(parse_expr(input)); + Ok(Stmt::ReturnWithVal(Box::new(ret))) + } } } - Some(& Token::LCurly) => parse_block(input), - Some(& Token::Var) => parse_var(input), - _ => parse_expr_stmt(input) + Some(&Token::LCurly) => parse_block(input), + Some(&Token::Var) => parse_var(input), + _ => parse_expr_stmt(input), } } @@ -740,56 +813,71 @@ fn parse_fn<'a>(input: &mut Peekable>) -> Result s.clone(), - _ => return Err(ParseError::FnMissingName) + _ => return Err(ParseError::FnMissingName), }; match input.peek() { - Some(&Token::LParen) => {input.next();}, - _ => return Err(ParseError::FnMissingParams) + Some(&Token::LParen) => { + input.next(); + } + _ => return Err(ParseError::FnMissingParams), } let mut params = Vec::new(); let skip_params = match input.peek() { - Some(&Token::RParen) => { input.next(); true } - _ => false + Some(&Token::RParen) => { + input.next(); + true + } + _ => false, }; if !skip_params { loop { match input.next() { - Some(Token::RParen) => { break }, + Some(Token::RParen) => break, Some(Token::Comma) => (), - Some(Token::Identifier(ref s)) => { params.push(s.clone()); }, - _ => return Err(ParseError::MalformedCallExpr) + Some(Token::Identifier(ref s)) => { + params.push(s.clone()); + } + _ => return Err(ParseError::MalformedCallExpr), } } } let body = try!(parse_block(input)); - Ok(FnDef{name: name, params: params, body: Box::new(body)}) + Ok(FnDef { + name: name, + params: params, + body: Box::new(body), + }) } -fn parse_top_level<'a>(input: &mut Peekable>) -> Result<(Vec, Vec), ParseError> { +fn parse_top_level<'a>(input: &mut Peekable>) + -> Result<(Vec, Vec), ParseError> { let mut stmts = Vec::new(); let mut fndefs = Vec::new(); while let Some(_) = input.peek() { match input.peek() { - Some(& Token::Fn) => fndefs.push(try!(parse_fn(input))), - _ => stmts.push(try!(parse_stmt(input))) + Some(&Token::Fn) => fndefs.push(try!(parse_fn(input))), + _ => stmts.push(try!(parse_stmt(input))), } match input.peek() { - Some(& Token::Semicolon) => {input.next();}, - _ => () + Some(&Token::Semicolon) => { + input.next(); + } + _ => (), } } Ok((stmts, fndefs)) } -pub fn parse<'a>(input: &mut Peekable>) -> Result<(Vec, Vec), ParseError> { +pub fn parse<'a>(input: &mut Peekable>) + -> Result<(Vec, Vec), ParseError> { parse_top_level(input) }