diff --git a/Cargo.toml b/Cargo.toml index b7580ea4..4ba4d03e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "rhai" version = "0.9.1" +edition = "2018" authors = ["Jonathan Turner", "Lukáš Hozda"] description = "Embedded scripting for Rust" homepage = "https://github.com/jonathandturner/rhai" diff --git a/README.md b/README.md index 114746db..98f4d748 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ use rhai::{Engine, Scope}; fn main() { let mut engine = Engine::new(); - let mut scope: Scope = Vec::new(); + let mut scope = Scope::new(); if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5") { } else { assert!(false); } diff --git a/examples/arrays_and_structs.rs b/examples/arrays_and_structs.rs index 987e177f..215abc8d 100644 --- a/examples/arrays_and_structs.rs +++ b/examples/arrays_and_structs.rs @@ -1,4 +1,3 @@ -extern crate rhai; use rhai::{Engine, RegisterFn}; #[derive(Clone, Debug)] @@ -24,6 +23,12 @@ fn main() { engine.register_fn("update", TestStruct::update); engine.register_fn("new_ts", TestStruct::new); - println!("{:?}", engine.eval::("let x = new_ts(); x.update(); x")); - println!("{:?}", engine.eval::("let x = [new_ts()]; x[0].update(); x[0]")); + println!( + "{:?}", + engine.eval::("let x = new_ts(); x.update(); x") + ); + println!( + "{:?}", + engine.eval::("let x = [new_ts()]; x[0].update(); x[0]") + ); } diff --git a/examples/custom_types_and_methods.rs b/examples/custom_types_and_methods.rs index 65cf3225..85cb2b60 100644 --- a/examples/custom_types_and_methods.rs +++ b/examples/custom_types_and_methods.rs @@ -1,4 +1,3 @@ -extern crate rhai; use rhai::{Engine, RegisterFn}; #[derive(Clone)] diff --git a/examples/hello.rs b/examples/hello.rs index 925902b8..cb889fe5 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -1,4 +1,3 @@ -extern crate rhai; use rhai::Engine; fn main() { diff --git a/examples/repl.rs b/examples/repl.rs index 145c288b..8a75c3d5 100644 --- a/examples/repl.rs +++ b/examples/repl.rs @@ -1,9 +1,7 @@ -extern crate rhai; - -use std::fmt::Display; -use std::process::exit; -use std::io::{stdin, stdout, Write}; use rhai::{Engine, RegisterFn, Scope}; +use std::fmt::Display; +use std::io::{stdin, stdout, Write}; +use std::process::exit; fn showit(x: &mut T) -> () { println!("{}", x) diff --git a/examples/reuse_scope.rs b/examples/reuse_scope.rs index b01ec107..071eb9f3 100644 --- a/examples/reuse_scope.rs +++ b/examples/reuse_scope.rs @@ -1,11 +1,12 @@ -extern crate rhai; use rhai::{Engine, Scope}; fn main() { let mut engine = Engine::new(); - let mut scope: Scope = Vec::new(); + let mut scope = Scope::new(); - assert!(engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5").is_ok()); + assert!(engine + .eval_with_scope::<()>(&mut scope, "let x = 4 + 5") + .is_ok()); if let Ok(result) = engine.eval_with_scope::(&mut scope, "x") { println!("result: {}", result); diff --git a/examples/rhai_runner.rs b/examples/rhai_runner.rs index 6637844a..2e0da794 100644 --- a/examples/rhai_runner.rs +++ b/examples/rhai_runner.rs @@ -1,9 +1,7 @@ +use rhai::{Engine, RegisterFn}; use std::env; use std::fmt::Display; -extern crate rhai; -use rhai::{Engine, RegisterFn}; - fn showit(x: &mut T) -> () { println!("{}", x) } diff --git a/examples/simple_fn.rs b/examples/simple_fn.rs index 04b55b68..ccef105e 100644 --- a/examples/simple_fn.rs +++ b/examples/simple_fn.rs @@ -1,4 +1,3 @@ -extern crate rhai; use rhai::{Engine, RegisterFn}; fn add(x: i64, y: i64) -> i64 { diff --git a/src/any.rs b/src/any.rs index d0b3d8fb..ac2d9f68 100644 --- a/src/any.rs +++ b/src/any.rs @@ -4,7 +4,7 @@ use std::fmt; pub trait Any: StdAny { fn type_id(&self) -> TypeId; - fn box_clone(&self) -> Box; + fn box_clone(&self) -> Box; /// This type may only be implemented by `rhai`. #[doc(hidden)] @@ -12,8 +12,8 @@ pub trait Any: StdAny { } impl Any for T - where - T: Clone + StdAny + ?Sized +where + T: Clone + StdAny + ?Sized, { #[inline] fn type_id(&self) -> TypeId { @@ -21,23 +21,24 @@ impl Any for T } #[inline] - fn box_clone(&self) -> Box { + fn box_clone(&self) -> Box { Box::new(self.clone()) } - fn _closed(&self) -> _Private { _Private } + fn _closed(&self) -> _Private { + _Private + } } -impl Any { - #[inline] - fn box_clone(&self) -> Box { - Any::box_clone(self) - } - +impl dyn Any { + //#[inline] + // fn box_clone(&self) -> Box { + // Any::box_clone(self) + // } #[inline] pub fn is(&self) -> bool { let t = TypeId::of::(); - let boxed = ::type_id(self); + let boxed = ::type_id(self); t == boxed } @@ -45,9 +46,7 @@ impl Any { #[inline] pub fn downcast_ref(&self) -> Option<&T> { if self.is::() { - unsafe { - Some(&*(self as *const Any as *const T)) - } + unsafe { Some(&*(self as *const dyn Any as *const T)) } } else { None } @@ -56,23 +55,21 @@ impl Any { #[inline] pub fn downcast_mut(&mut self) -> Option<&mut T> { if self.is::() { - unsafe { - Some(&mut *(self as *mut Any as *mut T)) - } + unsafe { Some(&mut *(self as *mut dyn Any as *mut T)) } } else { None } } } -impl Clone for Box { +impl Clone for Box { fn clone(&self) -> Self { - Any::box_clone(self.as_ref() as &Any) + Any::box_clone(self.as_ref() as &dyn Any) } } -impl fmt::Debug for Any { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl fmt::Debug for dyn Any { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Any") } } @@ -81,11 +78,11 @@ pub trait AnyExt: Sized { fn downcast(self) -> Result, Self>; } -impl AnyExt for Box { +impl AnyExt for Box { fn downcast(self) -> Result, Self> { if self.is::() { unsafe { - let raw: *mut Any = Box::into_raw(self); + let raw: *mut dyn Any = Box::into_raw(self); Ok(Box::from_raw(raw as *mut T)) } } else { diff --git a/src/call.rs b/src/call.rs index cf3313e3..fa2439e9 100644 --- a/src/call.rs +++ b/src/call.rs @@ -1,10 +1,10 @@ //! Helper module which defines `FnArgs` //! to make function calling easier. -use any::Any; +use crate::any::Any; pub trait FunArgs<'a> { - fn into_vec(self) -> Vec<&'a mut Any>; + fn into_vec(self) -> Vec<&'a mut dyn Any>; } macro_rules! impl_args { @@ -13,11 +13,12 @@ macro_rules! impl_args { where $($p: Any + Clone),* { - fn into_vec(self) -> Vec<&'a mut Any> { + fn into_vec(self) -> Vec<&'a mut dyn Any> { let ($($p,)*) = self; + #[allow(unused_variables, unused_mut)] let mut v = Vec::new(); - $(v.push($p as &mut Any);)* + $(v.push($p as &mut dyn Any);)* v } diff --git a/src/engine.rs b/src/engine.rs index 4bff3753..1186afe1 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,16 +1,15 @@ use std::any::TypeId; -use std::borrow::Borrow; use std::cmp::{PartialEq, PartialOrd}; use std::collections::HashMap; use std::error::Error; use std::fmt; +use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}; use std::sync::Arc; -use std::ops::{Add, BitAnd, BitOr, BitXor, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub}; -use any::{Any, AnyExt}; -use fn_register::{Mut, RegisterFn}; -use parser::{lex, parse, Expr, FnDef, Stmt}; -use call::FunArgs; +use crate::any::{Any, AnyExt}; +use crate::call::FunArgs; +use crate::fn_register::RegisterFn; +use crate::parser::{lex, parse, Expr, FnDef, Stmt}; #[derive(Debug)] pub enum EvalAltResult { @@ -26,7 +25,7 @@ pub enum EvalAltResult { ErrorCantOpenScriptFile, InternalErrorMalformedDotExpression, LoopBreak, - Return(Box), + Return(Box), } impl EvalAltResult { @@ -35,7 +34,7 @@ impl EvalAltResult { EvalAltResult::ErrorVariableNotFound(ref s) => Some(s.as_str()), EvalAltResult::ErrorFunctionNotFound(ref s) => Some(s.as_str()), EvalAltResult::ErrorMismatchOutputType(ref s) => Some(s.as_str()), - _ => None + _ => None, } } } @@ -89,13 +88,13 @@ impl Error for EvalAltResult { } } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { None } } impl fmt::Display for EvalAltResult { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(s) = self.as_str() { write!(f, "{}: {}", self.description(), s) } else { @@ -128,7 +127,7 @@ pub struct FnSpec { pub struct Engine { /// A hashmap containing all functions known to the engine pub fns: HashMap>, - pub type_names: HashMap, + pub type_names: HashMap, } pub enum FnIntExt { @@ -136,7 +135,7 @@ pub enum FnIntExt { Int(FnDef), } -pub type FnAny = Fn(Vec<&mut Any>) -> Result, EvalAltResult>; +pub type FnAny = dyn Fn(Vec<&mut dyn Any>) -> Result, EvalAltResult>; /// A type containing information about current scope. /// Useful for keeping state between `Engine` runs @@ -152,7 +151,7 @@ pub type FnAny = Fn(Vec<&mut Any>) -> Result, EvalAltResult>; /// ``` /// /// Between runs, `Engine` only remembers functions when not using own `Scope`. -pub type Scope = Vec<(String, Box)>; +pub type Scope = Vec<(String, Box)>; impl Engine { pub fn call_fn<'a, I, A, T>(&self, ident: I, args: A) -> Result @@ -174,8 +173,8 @@ impl Engine { pub fn call_fn_raw( &self, ident: String, - args: Vec<&mut Any>, - ) -> Result, EvalAltResult> { + args: Vec<&mut dyn Any>, + ) -> Result, EvalAltResult> { debug_println!( "Trying to call function {:?} with args {:?}", ident, @@ -184,17 +183,27 @@ impl Engine { let spec = FnSpec { ident: ident.clone(), - args: Some(args.iter().map(|a| ::type_id(&**a)).collect()), + args: Some( + args.iter() + .map(|a| ::type_id(&**a)) + .collect(), + ), }; self.fns .get(&spec) .or_else(|| { - let spec1 = FnSpec { ident: ident.clone(), args: None }; + let spec1 = FnSpec { + ident: ident.clone(), + args: None, + }; self.fns.get(&spec1) }) .ok_or_else(|| { - let typenames = args.iter().map(|x| self.nice_type_name((&**x).box_clone())).collect::>(); + let typenames = args + .iter() + .map(|x| self.nice_type_name((&**x).box_clone())) + .collect::>(); EvalAltResult::ErrorFunctionNotFound(format!("{} ({})", ident, typenames.join(","))) }) .and_then(move |f| match **f { @@ -272,14 +281,15 @@ impl Engine { fn get_dot_val_helper( &self, scope: &mut Scope, - this_ptr: &mut Any, + this_ptr: &mut dyn Any, dot_rhs: &Expr, - ) -> Result, EvalAltResult> { + ) -> Result, EvalAltResult> { use std::iter::once; match *dot_rhs { Expr::FnCall(ref fn_name, ref args) => { - let mut args: Vec> = args.iter() + let mut args: Vec> = args + .iter() .map(|arg| self.eval_expr(scope, arg)) .collect::, _>>()?; let args = once(this_ptr) @@ -299,7 +309,7 @@ impl Engine { let mut val = self.call_fn_raw(get_fn_name, vec![this_ptr])?; - ((*val).downcast_mut() as Option<&mut Vec>>) + ((*val).downcast_mut() as Option<&mut Vec>>) .and_then(|arr| idx.downcast_ref::().map(|idx| (arr, *idx as usize))) .map(|(arr, idx)| arr[idx].clone()) .ok_or(EvalAltResult::ErrorIndexMismatch) @@ -322,7 +332,7 @@ impl Engine { map: F, ) -> Result<(usize, T), EvalAltResult> where - F: FnOnce(&'a mut Any) -> Result, + F: FnOnce(&'a mut dyn Any) -> Result, { scope .iter_mut() @@ -338,13 +348,14 @@ impl Engine { scope: &mut Scope, id: &str, idx: &Expr, - ) -> Result<(usize, usize, Box), EvalAltResult> { - let idx_boxed = self.eval_expr(scope, idx)? + ) -> Result<(usize, usize, Box), EvalAltResult> { + let idx_boxed = self + .eval_expr(scope, idx)? .downcast::() .map_err(|_| EvalAltResult::ErrorIndexMismatch)?; let idx = *idx_boxed as usize; let (idx_sc, val) = Self::search_scope(scope, id, |val| { - ((*val).downcast_mut() as Option<&mut Vec>>) + ((*val).downcast_mut() as Option<&mut Vec>>) .map(|arr| arr[idx].clone()) .ok_or(EvalAltResult::ErrorIndexMismatch) })?; @@ -357,7 +368,7 @@ impl Engine { scope: &mut Scope, dot_lhs: &Expr, dot_rhs: &Expr, - ) -> Result, EvalAltResult> { + ) -> Result, EvalAltResult> { match *dot_lhs { Expr::Identifier(ref id) => { let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.box_clone()))?; @@ -375,7 +386,7 @@ impl Engine { // In case the expression mutated `target`, we need to reassign it because // of the above `clone`. - scope[sc_idx].1.downcast_mut::>>().unwrap()[idx] = target; + scope[sc_idx].1.downcast_mut::>>().unwrap()[idx] = target; value } @@ -385,10 +396,10 @@ impl Engine { fn set_dot_val_helper( &self, - this_ptr: &mut Any, + this_ptr: &mut dyn Any, dot_rhs: &Expr, - mut source_val: Box, - ) -> Result, EvalAltResult> { + mut source_val: Box, + ) -> Result, EvalAltResult> { match *dot_rhs { Expr::Identifier(ref id) => { let set_fn_name = "set$".to_string() + id; @@ -419,8 +430,8 @@ impl Engine { scope: &mut Scope, dot_lhs: &Expr, dot_rhs: &Expr, - source_val: Box, - ) -> Result, EvalAltResult> { + source_val: Box, + ) -> Result, EvalAltResult> { match *dot_lhs { Expr::Identifier(ref id) => { let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.box_clone()))?; @@ -438,7 +449,7 @@ impl Engine { // In case the expression mutated `target`, we need to reassign it because // of the above `clone`. - scope[sc_idx].1.downcast_mut::>>().unwrap()[idx] = target; + scope[sc_idx].1.downcast_mut::>>().unwrap()[idx] = target; value } @@ -446,7 +457,7 @@ impl Engine { } } - fn eval_expr(&self, scope: &mut Scope, expr: &Expr) -> Result, EvalAltResult> { + fn eval_expr(&self, scope: &mut Scope, expr: &Expr) -> Result, EvalAltResult> { match *expr { Expr::IntConst(i) => Ok(Box::new(i)), Expr::FloatConst(i) => Ok(Box::new(i)), @@ -484,7 +495,7 @@ impl Engine { if *id == *name { if let Some(i) = idx.downcast_ref::() { if let Some(arr_typed) = - (*val).downcast_mut() as Option<&mut Vec>> + (*val).downcast_mut() as Option<&mut Vec>> { arr_typed[*i as usize] = rhs_val; return Ok(Box::new(())); @@ -520,7 +531,7 @@ impl Engine { fn_name.to_owned(), args.iter() .map(|ex| self.eval_expr(scope, ex)) - .collect::>, _>>()? + .collect::>, _>>()? .iter_mut() .map(|b| b.as_mut()) .collect(), @@ -531,12 +542,12 @@ impl Engine { } } - fn eval_stmt(&self, scope: &mut Scope, stmt: &Stmt) -> Result, EvalAltResult> { + fn eval_stmt(&self, scope: &mut Scope, stmt: &Stmt) -> Result, EvalAltResult> { match *stmt { 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); @@ -621,8 +632,8 @@ impl Engine { } } - fn nice_type_name(&self, b: Box) -> String { - let tid = ::type_id(&*b); + fn nice_type_name(&self, b: Box) -> String { + let tid = ::type_id(&*b); if let Some(name) = self.type_names.get(&tid) { name.to_string() } else { @@ -650,7 +661,7 @@ impl Engine { /// Evaluate a string pub fn eval(&mut self, input: &str) -> Result { - let mut scope: Scope = Vec::new(); + let mut scope = Scope::new(); self.eval_with_scope(&mut scope, input) } @@ -668,7 +679,7 @@ impl Engine { match tree { Ok((ref os, ref fns)) => { - let mut x: Result, EvalAltResult> = Ok(Box::new(())); + let mut x: Result, EvalAltResult> = Ok(Box::new(())); for f in fns { let name = f.name.clone(); @@ -693,7 +704,9 @@ impl Engine { match x.downcast::() { Ok(out) => Ok(*out), - Err(a) => Err(EvalAltResult::ErrorMismatchOutputType(self.nice_type_name(a))), + Err(a) => Err(EvalAltResult::ErrorMismatchOutputType( + self.nice_type_name(a), + )), } } Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch), @@ -786,12 +799,12 @@ impl Engine { engine.register_type_name::("string"); engine.register_type_name::("char"); engine.register_type_name::("boolean"); - engine.register_type_name::>>("array"); + engine.register_type_name::>>("array"); macro_rules! reg_op { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( - $engine.register_fn($x, ($op as fn(x: $y, y: $y)->$y)); + $engine.register_fn($x, $op as fn(x: $y, y: $y)->$y); )* ) } @@ -799,7 +812,7 @@ impl Engine { macro_rules! reg_un { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( - $engine.register_fn($x, ($op as fn(x: $y)->$y)); + $engine.register_fn($x, $op as fn(x: $y)->$y); )* ) } @@ -807,36 +820,86 @@ impl Engine { macro_rules! reg_cmp { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( - $engine.register_fn($x, ($op as fn(x: $y, y: $y)->bool)); + $engine.register_fn($x, $op as fn(x: $y, y: $y)->bool); )* ) } - 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 neg(x: T) -> ::Output { -x } - 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 not(x: bool) -> bool { !x } - fn concat(x: String, y: String) -> String { x + &y } - fn binary_and(x: T, y: T) -> ::Output { x & y } - fn binary_or(x: T, y: T) -> ::Output { x | y } - fn binary_xor(x: T, y: T) -> ::Output { x ^ y } - fn left_shift>(x: T, y: T) -> >::Output { x.shl(y) } - fn right_shift>(x: T, y: T) -> >::Output { x.shr(y) } - fn modulo>(x: T, y: T) -> >::Output { x % y } - fn pow_i64_i64(x: i64, y: i64) -> i64 { x.pow(y as u32) } - fn pow_f64_f64(x: f64, y: f64) -> f64 { x.powf(y) } - fn pow_f64_i64(x: f64, y: i64) -> f64 { x.powi(y as i32) } - fn unit_eq(a: (), b: ()) -> bool { true } + 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 neg(x: T) -> ::Output { + -x + } + 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 not(x: bool) -> bool { + !x + } + fn concat(x: String, y: String) -> String { + x + &y + } + fn binary_and(x: T, y: T) -> ::Output { + x & y + } + fn binary_or(x: T, y: T) -> ::Output { + x | y + } + fn binary_xor(x: T, y: T) -> ::Output { + x ^ y + } + fn left_shift>(x: T, y: T) -> >::Output { + x.shl(y) + } + fn right_shift>(x: T, y: T) -> >::Output { + x.shr(y) + } + fn modulo>(x: T, y: T) -> >::Output { + x % y + } + fn pow_i64_i64(x: i64, y: i64) -> i64 { + x.pow(y as u32) + } + fn pow_f64_f64(x: f64, y: f64) -> f64 { + x.powf(y) + } + fn pow_f64_i64(x: f64, y: i64) -> f64 { + x.powi(y as i32) + } + fn unit_eq(_a: (), _b: ()) -> bool { + true + } reg_op!(engine, "+", add, i32, i64, u32, u64, f32, f64); reg_op!(engine, "-", sub, i32, i64, u32, u64, f32, f64); @@ -874,7 +937,6 @@ impl Engine { // FIXME? Registering array lookups are a special case because we want to return boxes // directly let ent = engine.fns.entry("[]".to_string()).or_insert_with(Vec::new); // (*ent).push(FnType::ExternalFn2(Box::new(idx))); - } /// Make a new engine diff --git a/src/fn_register.rs b/src/fn_register.rs index ad4fbe03..0dcf6fe4 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -1,7 +1,7 @@ use std::any::TypeId; -use any::Any; -use engine::{Engine, EvalAltResult}; +use crate::any::Any; +use crate::engine::{Engine, EvalAltResult}; pub trait RegisterFn { fn register_fn(&mut self, name: &str, f: FN); @@ -27,13 +27,14 @@ macro_rules! def_register { RET: Any, { fn register_fn(&mut self, name: &str, f: FN) { - let fun = move |mut args: Vec<&mut Any>| { + let fun = move |mut args: Vec<&mut dyn Any>| { // Check for length at the beginning to avoid // per-element bound checks. if args.len() != count_args!($($par)*) { return Err(EvalAltResult::ErrorFunctionArgMismatch); } + #[allow(unused_variables, unused_mut)] let mut drain = args.drain(..); $( // Downcast every element, return in case of a type mismatch @@ -43,7 +44,7 @@ macro_rules! def_register { // Call the user-supplied function using ($clone) to // potentially clone the value, otherwise pass the reference. - Ok(Box::new(f($(($clone)($par)),*)) as Box) + Ok(Box::new(f($(($clone)($par)),*)) as Box) }; self.register_fn_raw(name.to_owned(), Some(vec![$(TypeId::of::<$par>()),*]), Box::new(fun)); } diff --git a/src/lib.rs b/src/lib.rs index a012216e..6aa339bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,9 +30,7 @@ //! //! [Check out the README on GitHub for more information!](https://github.com/jonathandturner/rhai) -// lints required by Rhai -#![allow(warnings, unknown_lints, type_complexity, new_without_default_derive, - needless_pass_by_value, too_many_arguments)] +#![allow(non_snake_case)] // needs to be here, because order matters for macros macro_rules! debug_println { @@ -50,4 +48,3 @@ mod parser; pub use any::Any; pub use engine::{Engine, EvalAltResult, Scope}; pub use fn_register::RegisterFn; - diff --git a/src/parser.rs b/src/parser.rs index 34ed60f4..0e82f0f4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,8 +1,8 @@ +use std::char; use std::error::Error; use std::fmt; use std::iter::Peekable; use std::str::Chars; -use std::char; #[derive(Debug, Clone)] pub enum LexError { @@ -10,7 +10,7 @@ pub enum LexError { MalformedEscapeSequence, MalformedNumber, MalformedChar, - Nothing + Nothing, } impl Error for LexError { @@ -20,13 +20,13 @@ impl Error for LexError { LexError::MalformedEscapeSequence => "Unexpected values in escape sequence", LexError::MalformedNumber => "Unexpected characters in number", LexError::MalformedChar => "Char constant not a single character", - LexError::Nothing => "This error is for internal use only" + LexError::Nothing => "This error is for internal use only", } } } impl fmt::Display for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.description()) } } @@ -65,11 +65,13 @@ impl Error for ParseError { } } - fn cause(&self) -> Option<&Error> { None } + fn cause(&self) -> Option<&dyn Error> { + None + } } impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.description()) } } @@ -268,11 +270,7 @@ impl Token { use self::Token::*; match *self { - UnaryPlus | - UnaryMinus | - Equals | - Bang | - Return => true, + UnaryPlus | UnaryMinus | Equals | Bang | Return => true, _ => false, } } @@ -390,14 +388,14 @@ impl<'a> TokenIterator<'a> { fn inner_next(&mut self) -> Option { while let Some(c) = self.char_stream.next() { match c { - '0'...'9' => { + '0'..='9' => { let mut result = Vec::new(); let mut radix_base: Option = None; result.push(c); while let Some(&nxt) = self.char_stream.peek() { match nxt { - '0'...'9' => { + '0'..='9' => { result.push(nxt); self.char_stream.next(); } @@ -406,7 +404,7 @@ impl<'a> TokenIterator<'a> { self.char_stream.next(); while let Some(&nxt_float) = self.char_stream.peek() { match nxt_float { - '0'...'9' => { + '0'..='9' => { result.push(nxt_float); self.char_stream.next(); } @@ -419,7 +417,7 @@ impl<'a> TokenIterator<'a> { self.char_stream.next(); while let Some(&nxt_hex) = self.char_stream.peek() { match nxt_hex { - '0'...'9' | 'a'...'f' | 'A'...'F' => { + '0'..='9' | 'a'..='f' | 'A'..='F' => { result.push(nxt_hex); self.char_stream.next(); } @@ -433,7 +431,7 @@ impl<'a> TokenIterator<'a> { self.char_stream.next(); while let Some(&nxt_oct) = self.char_stream.peek() { match nxt_oct { - '0'...'8' => { + '0'..='8' => { result.push(nxt_oct); self.char_stream.next(); } @@ -461,7 +459,12 @@ impl<'a> TokenIterator<'a> { } if let Some(radix) = radix_base { - let out: String = result.iter().cloned().skip(2).filter(|c| c != &'_').collect(); + let out: String = result + .iter() + .cloned() + .skip(2) + .filter(|c| c != &'_') + .collect(); if let Ok(val) = i64::from_str_radix(&out, radix) { return Some(Token::IntConst(val)); } @@ -476,7 +479,7 @@ impl<'a> TokenIterator<'a> { } return Some(Token::LexErr(LexError::MalformedNumber)); } - 'A'...'Z' | 'a'...'z' | '_' => { + 'A'..='Z' | 'a'..='z' | '_' => { let mut result = Vec::new(); result.push(c); @@ -505,30 +508,26 @@ impl<'a> TokenIterator<'a> { x => return Some(Token::Identifier(x.to_string())), } } - '"' => { - match self.parse_string_const('"') { - Ok(out) => return Some(Token::StringConst(out)), - Err(e) => return Some(Token::LexErr(e)), - } - } - '\'' => { - match self.parse_string_const('\'') { - Ok(result) => { - let mut chars = result.chars(); + '"' => match self.parse_string_const('"') { + Ok(out) => return Some(Token::StringConst(out)), + Err(e) => return Some(Token::LexErr(e)), + }, + '\'' => match self.parse_string_const('\'') { + Ok(result) => { + let mut chars = result.chars(); - 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 { + 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)); } - Err(e) => return Some(Token::LexErr(e)), } - } + Err(e) => return Some(Token::LexErr(e)), + }, '{' => return Some(Token::LCurly), '}' => return Some(Token::RCurly), '(' => return Some(Token::LParen), @@ -540,182 +539,168 @@ impl<'a> TokenIterator<'a> { Some(&'=') => { self.char_stream.next(); Some(Token::PlusAssign) - }, + } _ if self.last.is_next_unary() => Some(Token::UnaryPlus), _ => Some(Token::Plus), } - }, + } '-' => { return match self.char_stream.peek() { Some(&'=') => { self.char_stream.next(); Some(Token::MinusAssign) - }, + } _ if self.last.is_next_unary() => Some(Token::UnaryMinus), _ => Some(Token::Minus), } - }, + } '*' => { return match self.char_stream.peek() { Some(&'=') => { self.char_stream.next(); Some(Token::MultiplyAssign) - }, - _ => Some(Token::Multiply) - } - }, - '/' => { - match self.char_stream.peek() { - Some(&'/') => { - self.char_stream.next(); - while let Some(c) = self.char_stream.next() { - if c == '\n' { break; } - } } - Some(&'*') => { - let mut level = 1; - self.char_stream.next(); - while let Some(c) = self.char_stream.next() { - match c { - '/' => if let Some('*') = self.char_stream.next() { - level+=1; - } - '*' => if let Some('/') = self.char_stream.next() { - level-=1; - } - _ => (), - } - - if level == 0 { - break; - } - } - } - Some(&'=') => { - self.char_stream.next(); - return Some(Token::DivideAssign); - } - _ => return Some(Token::Divide), + _ => Some(Token::Multiply), } } + '/' => match self.char_stream.peek() { + Some(&'/') => { + self.char_stream.next(); + while let Some(c) = self.char_stream.next() { + if c == '\n' { + break; + } + } + } + Some(&'*') => { + let mut level = 1; + self.char_stream.next(); + while let Some(c) = self.char_stream.next() { + match c { + '/' => { + if let Some('*') = self.char_stream.next() { + level += 1; + } + } + '*' => { + if let Some('/') = self.char_stream.next() { + level -= 1; + } + } + _ => (), + } + + if level == 0 { + break; + } + } + } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::DivideAssign); + } + _ => 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), - } - } - '<' => { - match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - return Some(Token::LessThanEqual); - } - Some(&'<') => { - self.char_stream.next(); - return match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - Some(Token::LeftShiftAssign) - }, - _ => { - self.char_stream.next(); - Some(Token::LeftShift) - } - } - } - _ => return Some(Token::LessThan), - } - } - '>' => { - match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - return Some(Token::GreaterThanEqual); - } - Some(&'>') => { - self.char_stream.next(); - return match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - Some(Token::RightShiftAssign) - }, - _ => { - self.char_stream.next(); - Some(Token::RightShift) - } - } - } - _ => return Some(Token::GreaterThan), - } - } - '!' => { - match self.char_stream.peek() { - 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); - } - Some(&'=') => { - self.char_stream.next(); - return Some(Token::OrAssign); - } - _ => return Some(Token::Pipe), - } - } - '&' => { - match self.char_stream.peek() { - Some(&'&') => { - self.char_stream.next(); - return Some(Token::And); - } - Some(&'=') => { - self.char_stream.next(); - return Some(Token::AndAssign); - } - _ => return Some(Token::Ampersand), - } - } - '^' => { - match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - return Some(Token::XOrAssign); - } - _ => return Some(Token::XOr) + '=' => match self.char_stream.peek() { + 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::ModuloAssign); - } - _ => return Some(Token::Modulo) + '<' => match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + return Some(Token::LessThanEqual); } + Some(&'<') => { + self.char_stream.next(); + return match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + Some(Token::LeftShiftAssign) + } + _ => { + self.char_stream.next(); + Some(Token::LeftShift) + } + }; + } + _ => return Some(Token::LessThan), }, - '~' => { - match self.char_stream.peek() { - Some(&'=') => { - self.char_stream.next(); - return Some(Token::PowerOfAssign); - } - _ => return Some(Token::PowerOf) + '>' => match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + return Some(Token::GreaterThanEqual); } + Some(&'>') => { + self.char_stream.next(); + return match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + Some(Token::RightShiftAssign) + } + _ => { + self.char_stream.next(); + Some(Token::RightShift) + } + }; + } + _ => return Some(Token::GreaterThan), + }, + '!' => match self.char_stream.peek() { + 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); + } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::OrAssign); + } + _ => return Some(Token::Pipe), + }, + '&' => match self.char_stream.peek() { + Some(&'&') => { + self.char_stream.next(); + return Some(Token::And); + } + Some(&'=') => { + self.char_stream.next(); + return Some(Token::AndAssign); + } + _ => return Some(Token::Ampersand), + }, + '^' => match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + return Some(Token::XOrAssign); + } + _ => return Some(Token::XOr), + }, + '%' => match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + return Some(Token::ModuloAssign); + } + _ => return Some(Token::Modulo), + }, + '~' => match self.char_stream.peek() { + Some(&'=') => { + self.char_stream.next(); + return Some(Token::PowerOfAssign); + } + _ => return Some(Token::PowerOf), }, _x if _x.is_whitespace() => (), _ => return Some(Token::LexErr(LexError::UnexpectedChar)), @@ -739,8 +724,11 @@ impl<'a> Iterator for TokenIterator<'a> { } } -pub fn lex(input: &str) -> TokenIterator { - TokenIterator { last: Token::LexErr(LexError::Nothing), char_stream: input.chars().peekable() } +pub fn lex(input: &str) -> TokenIterator<'_> { + TokenIterator { + last: Token::LexErr(LexError::Nothing), + char_stream: input.chars().peekable(), + } } fn get_precedence(token: &Token) -> i32 { @@ -757,24 +745,17 @@ fn get_precedence(token: &Token) -> i32 { | Token::XOrAssign | Token::ModuloAssign | Token::PowerOfAssign => 10, - Token::Or - | Token::XOr - | Token::Pipe => 11, - Token::And - | Token::Ampersand => 12, + Token::Or | Token::XOr | Token::Pipe => 11, + Token::And | Token::Ampersand => 12, Token::LessThan | Token::LessThanEqual | Token::GreaterThan | Token::GreaterThanEqual | Token::EqualTo | Token::NotEqualTo => 15, - Token::Plus - | Token::Minus => 20, - Token::Divide - | Token::Multiply - | Token::PowerOf => 40, - Token::LeftShift - | Token::RightShift => 50, + Token::Plus | Token::Minus => 20, + Token::Divide | Token::Multiply | Token::PowerOf => 40, + Token::LeftShift | Token::RightShift => 50, Token::Modulo => 60, Token::Period => 100, _ => -1, @@ -782,7 +763,7 @@ fn get_precedence(token: &Token) -> i32 { } fn parse_paren_expr<'a>(input: &mut Peekable>) -> Result { - let expr = try!(parse_expr(input)); + let expr = parse_expr(input)?; match input.next() { Some(Token::RParen) => Ok(expr), @@ -790,9 +771,10 @@ fn parse_paren_expr<'a>(input: &mut Peekable>) -> Result(id: String, - input: &mut Peekable>) - -> Result { +fn parse_call_expr<'a>( + id: String, + input: &mut Peekable>, +) -> Result { let mut args = Vec::new(); if let Some(&Token::RParen) = input.peek() { @@ -820,9 +802,10 @@ fn parse_call_expr<'a>(id: String, } } -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) => { @@ -836,9 +819,10 @@ fn parse_index_expr<'a>(id: String, } } -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(); @@ -862,12 +846,14 @@ fn parse_array_expr<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result Err(ParseError::MissingRSquare), } - } fn parse_primary<'a>(input: &mut Peekable>) -> Result { @@ -914,17 +899,27 @@ fn parse_unary<'a>(input: &mut Peekable>) -> Result { input.next(); Ok(Expr::FnCall("-".to_string(), vec![parse_primary(input)?])) } - Token::UnaryPlus => { input.next(); parse_primary(input) } - Token::Bang => { input.next(); Ok(Expr::FnCall("!".to_string(), vec![parse_primary(input)?])) } - _ => parse_primary(input) + Token::UnaryMinus => { + input.next(); + Ok(Expr::FnCall("-".to_string(), vec![parse_primary(input)?])) + } + Token::UnaryPlus => { + input.next(); + parse_primary(input) + } + Token::Bang => { + input.next(); + Ok(Expr::FnCall("!".to_string(), vec![parse_primary(input)?])) + } + _ => parse_primary(input), } } -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 { @@ -939,7 +934,7 @@ fn parse_binop<'a>(input: &mut Peekable>, } if let Some(op_token) = input.next() { - let mut rhs = try!(parse_unary(input)); + let mut rhs = parse_unary(input)?; let mut next_prec = -1; @@ -948,10 +943,10 @@ fn parse_binop<'a>(input: &mut Peekable>, } if curr_prec < next_prec { - rhs = try!(parse_binop(input, curr_prec + 1, rhs)); + rhs = 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)); + rhs = parse_binop(input, curr_prec, rhs)?; } lhs_curr = match op_token { @@ -960,31 +955,27 @@ fn parse_binop<'a>(input: &mut Peekable>, Token::Multiply => Expr::FnCall("*".to_string(), vec![lhs_curr, rhs]), Token::Divide => Expr::FnCall("/".to_string(), vec![lhs_curr, rhs]), Token::Equals => Expr::Assignment(Box::new(lhs_curr), Box::new(rhs)), - Token::PlusAssign => { + Token::PlusAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("+".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("+".to_string(), vec![lhs_copy, rhs])), ) - }, - Token::MinusAssign => { + } + Token::MinusAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("-".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("-".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::Period => Expr::Dot(Box::new(lhs_curr), Box::new(rhs)), Token::EqualTo => Expr::FnCall("==".to_string(), vec![lhs_curr, rhs]), Token::NotEqualTo => Expr::FnCall("!=".to_string(), vec![lhs_curr, rhs]), Token::LessThan => Expr::FnCall("<".to_string(), vec![lhs_curr, rhs]), - Token::LessThanEqual => { - Expr::FnCall("<=".to_string(), vec![lhs_curr, rhs]) - } + Token::LessThanEqual => Expr::FnCall("<=".to_string(), vec![lhs_curr, rhs]), Token::GreaterThan => Expr::FnCall(">".to_string(), vec![lhs_curr, rhs]), - Token::GreaterThanEqual => { - Expr::FnCall(">=".to_string(), vec![lhs_curr, rhs]) - } + Token::GreaterThanEqual => Expr::FnCall(">=".to_string(), vec![lhs_curr, rhs]), Token::Or => Expr::FnCall("||".to_string(), vec![lhs_curr, rhs]), Token::And => Expr::FnCall("&&".to_string(), vec![lhs_curr, rhs]), Token::XOr => Expr::FnCall("^".to_string(), vec![lhs_curr, rhs]), @@ -992,73 +983,71 @@ fn parse_binop<'a>(input: &mut Peekable>, let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("|".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("|".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::AndAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("&".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("&".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::XOrAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("^".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("^".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::MultiplyAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("*".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("*".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::DivideAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("/".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("/".to_string(), vec![lhs_copy, rhs])), ) - }, - Token::Pipe => { - Expr::FnCall("|".to_string(), vec![lhs_curr, rhs]) - }, + } + Token::Pipe => Expr::FnCall("|".to_string(), vec![lhs_curr, rhs]), Token::LeftShift => Expr::FnCall("<<".to_string(), vec![lhs_curr, rhs]), Token::RightShift => Expr::FnCall(">>".to_string(), vec![lhs_curr, rhs]), Token::LeftShiftAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("<<".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("<<".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::RightShiftAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall(">>".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall(">>".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::Ampersand => Expr::FnCall("&".to_string(), vec![lhs_curr, rhs]), Token::Modulo => Expr::FnCall("%".to_string(), vec![lhs_curr, rhs]), Token::ModuloAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("%".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("%".to_string(), vec![lhs_copy, rhs])), ) - }, + } Token::PowerOf => Expr::FnCall("~".to_string(), vec![lhs_curr, rhs]), Token::PowerOfAssign => { let lhs_copy = lhs_curr.clone(); Expr::Assignment( Box::new(lhs_curr), - Box::new(Expr::FnCall("~".to_string(), vec![lhs_copy, rhs])) + Box::new(Expr::FnCall("~".to_string(), vec![lhs_copy, rhs])), ) - }, + } _ => return Err(ParseError::UnknownOperator), }; } @@ -1069,7 +1058,7 @@ fn parse_expr<'a>(input: &mut Peekable>) -> Result Ok(Expr::Unit), _ => { - let lhs = try!(parse_unary(input)); + let lhs = parse_unary(input)?; parse_binop(input, 0, lhs) } @@ -1079,14 +1068,18 @@ fn parse_expr<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { input.next(); - let guard = try!(parse_expr(input)); - let body = try!(parse_block(input)); + let guard = parse_expr(input)?; + let body = parse_block(input)?; match input.peek() { 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))) + let else_body = 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))), } @@ -1095,8 +1088,8 @@ fn parse_if<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { input.next(); - let guard = try!(parse_expr(input)); - let body = try!(parse_block(input)); + let guard = parse_expr(input)?; + let body = parse_block(input)?; Ok(Stmt::While(Box::new(guard), Box::new(body))) } @@ -1104,7 +1097,7 @@ fn parse_while<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { input.next(); - let body = try!(parse_block(input)); + let body = parse_block(input)?; Ok(Stmt::Loop(Box::new(body))) } @@ -1120,7 +1113,7 @@ fn parse_var<'a>(input: &mut Peekable>) -> Result { input.next(); - let initializer = try!(parse_expr(input)); + let initializer = parse_expr(input)?; Ok(Stmt::Var(name, Some(Box::new(initializer)))) } _ => Ok(Stmt::Var(name, None)), @@ -1144,13 +1137,15 @@ fn parse_block<'a>(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result(input: &mut Peekable>) -> Result { - let expr = try!(parse_expr(input)); + let expr = parse_expr(input)?; Ok(Stmt::Expr(Box::new(expr))) } @@ -1182,7 +1177,7 @@ fn parse_stmt<'a>(input: &mut Peekable>) -> Result Ok(Stmt::Return), _ => { - let ret = try!(parse_expr(input)); + let ret = parse_expr(input)?; Ok(Stmt::ReturnWithVal(Box::new(ret))) } } @@ -1240,15 +1235,16 @@ fn parse_fn<'a>(input: &mut Peekable>) -> Result(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(parse_fn(input)?), + _ => stmts.push(parse_stmt(input)?), } if let Some(&Token::Semicolon) = input.peek() { @@ -1259,7 +1255,8 @@ fn parse_top_level<'a>(input: &mut Peekable>) 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) } diff --git a/tests/arrays.rs b/tests/arrays.rs index 37a4e823..2845678a 100644 --- a/tests/arrays.rs +++ b/tests/arrays.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; use rhai::RegisterFn; @@ -59,8 +57,10 @@ fn test_array_with_structs() { assert!(false); } - if let Ok(result) = engine.eval::("let a = [new_ts()]; a[0].x = 100; a[0].update(); \ - a[0].x") { + if let Ok(result) = engine.eval::( + "let a = [new_ts()]; a[0].x = 100; a[0].update(); \ + a[0].x", + ) { assert_eq!(result, 1100); } else { assert!(false); diff --git a/tests/binary_ops.rs b/tests/binary_ops.rs index a9cb58e2..611f12d2 100644 --- a/tests/binary_ops.rs +++ b/tests/binary_ops.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/bit_shift.rs b/tests/bit_shift.rs index c35de15d..c0043082 100644 --- a/tests/bit_shift.rs +++ b/tests/bit_shift.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/bool_op.rs b/tests/bool_op.rs index a9ecf84b..4803cf18 100644 --- a/tests/bool_op.rs +++ b/tests/bool_op.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/chars.rs b/tests/chars.rs index 7e0100fe..7352b203 100644 --- a/tests/chars.rs +++ b/tests/chars.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/comments.rs b/tests/comments.rs index 48d25c1b..0b871944 100644 --- a/tests/comments.rs +++ b/tests/comments.rs @@ -1,12 +1,14 @@ -extern crate rhai; - use rhai::Engine; #[test] fn test_comments() { - let mut engine = Engine::new(); + let mut engine = Engine::new(); - assert!(engine.eval::("let x = 5; x // I am a single line comment, yay!").is_ok()); + assert!(engine + .eval::("let x = 5; x // I am a single line comment, yay!") + .is_ok()); - assert!(engine.eval::("let /* I am a multiline comment, yay! */ x = 5; x").is_ok()); + assert!(engine + .eval::("let /* I am a multiline comment, yay! */ x = 5; x") + .is_ok()); } diff --git a/tests/compound_equality.rs b/tests/compound_equality.rs index dc8cc3ed..096756f0 100644 --- a/tests/compound_equality.rs +++ b/tests/compound_equality.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/decrement.rs b/tests/decrement.rs index 87bb8c1f..874e2675 100644 --- a/tests/decrement.rs +++ b/tests/decrement.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/float.rs b/tests/float.rs index eb4003c7..87fd19f1 100644 --- a/tests/float.rs +++ b/tests/float.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; use rhai::RegisterFn; diff --git a/tests/get_set.rs b/tests/get_set.rs index 58076fca..8e76bc27 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; use rhai::RegisterFn; @@ -74,7 +72,9 @@ fn test_big_get_set() { } fn new() -> TestParent { - TestParent { child: TestChild::new() } + TestParent { + child: TestChild::new(), + } } } @@ -88,5 +88,8 @@ fn test_big_get_set() { engine.register_fn("new_tp", TestParent::new); - assert_eq!(engine.eval::("let a = new_tp(); a.child.x = 500; a.child.x"), Ok(500)); + assert_eq!( + engine.eval::("let a = new_tp(); a.child.x = 500; a.child.x"), + Ok(500) + ); } diff --git a/tests/if_block.rs b/tests/if_block.rs index 4202940f..c6de6c8d 100644 --- a/tests/if_block.rs +++ b/tests/if_block.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/increment.rs b/tests/increment.rs index 3dc4593b..3c541802 100644 --- a/tests/increment.rs +++ b/tests/increment.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/internal_fn.rs b/tests/internal_fn.rs index 5dcb37f6..48409635 100644 --- a/tests/internal_fn.rs +++ b/tests/internal_fn.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] @@ -23,8 +21,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 { assert!(false); diff --git a/tests/looping.rs b/tests/looping.rs index 76990dcc..4359df16 100644 --- a/tests/looping.rs +++ b/tests/looping.rs @@ -1,13 +1,12 @@ -extern crate rhai; - use rhai::Engine; #[test] fn test_loop() { - let mut engine = Engine::new(); + let mut engine = Engine::new(); - assert!( - engine.eval::(" + assert!(engine + .eval::( + " let x = 0; let i = 0; @@ -22,6 +21,7 @@ fn test_loop() { } x == 45 - ").unwrap() - ) + " + ) + .unwrap()) } diff --git a/tests/method_call.rs b/tests/method_call.rs index 9208459d..ee6b3dc0 100644 --- a/tests/method_call.rs +++ b/tests/method_call.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; use rhai::RegisterFn; @@ -32,5 +30,4 @@ fn test_method_call() { } else { assert!(false); } - } diff --git a/tests/mismatched_op.rs b/tests/mismatched_op.rs index ef35e3a3..0c455d99 100644 --- a/tests/mismatched_op.rs +++ b/tests/mismatched_op.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::{Engine, EvalAltResult}; #[test] @@ -8,6 +6,8 @@ fn test_mismatched_op() { assert_eq!( engine.eval::("60 + \"hello\""), - Err(EvalAltResult::ErrorFunctionNotFound("+ (integer,string)".into())) + Err(EvalAltResult::ErrorFunctionNotFound( + "+ (integer,string)".into() + )) ); } diff --git a/tests/not.rs b/tests/not.rs index 81c0d217..9a7cafba 100644 --- a/tests/not.rs +++ b/tests/not.rs @@ -1,15 +1,21 @@ -extern crate rhai; - use rhai::Engine; #[test] fn test_not() { - let mut engine = Engine::new(); + let mut engine = Engine::new(); - assert_eq!(engine.eval::("let not_true = !true; not_true").unwrap(), false); + assert_eq!( + engine + .eval::("let not_true = !true; not_true") + .unwrap(), + false + ); - assert_eq!(engine.eval::("fn not(x) { !x } not(false)").unwrap(), true); + assert_eq!( + engine.eval::("fn not(x) { !x } not(false)").unwrap(), + true + ); - // TODO - do we allow stacking unary operators directly? e.g '!!!!!!!true' - assert_eq!(engine.eval::("!(!(!(!(true))))").unwrap(), true) + // TODO - do we allow stacking unary operators directly? e.g '!!!!!!!true' + assert_eq!(engine.eval::("!(!(!(!(true))))").unwrap(), true) } diff --git a/tests/number_literals.rs b/tests/number_literals.rs index 7f9a0cbe..4e5e3d09 100644 --- a/tests/number_literals.rs +++ b/tests/number_literals.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/ops.rs b/tests/ops.rs index 5d30580a..ceb5e6fe 100644 --- a/tests/ops.rs +++ b/tests/ops.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/power_of.rs b/tests/power_of.rs index 14d6a030..bcac45df 100644 --- a/tests/power_of.rs +++ b/tests/power_of.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] @@ -8,7 +6,10 @@ fn test_power_of() { assert_eq!(engine.eval::("2 ~ 3").unwrap(), 8); assert_eq!(engine.eval::("(-2 ~ 3)").unwrap(), -8); - assert_eq!(engine.eval::("2.2 ~ 3.3").unwrap(), 13.489468760533386_f64); + assert_eq!( + engine.eval::("2.2 ~ 3.3").unwrap(), + 13.489468760533386_f64 + ); assert_eq!(engine.eval::("2.0~-2.0").unwrap(), 0.25_f64); assert_eq!(engine.eval::("(-2.0~-2.0)").unwrap(), 0.25_f64); assert_eq!(engine.eval::("(-2.0~-2)").unwrap(), 0.25_f64); @@ -21,9 +22,21 @@ fn test_power_of_equals() { assert_eq!(engine.eval::("let x = 2; x ~= 3; x").unwrap(), 8); assert_eq!(engine.eval::("let x = -2; x ~= 3; x").unwrap(), -8); - assert_eq!(engine.eval::("let x = 2.2; x ~= 3.3; x").unwrap(), 13.489468760533386_f64); - assert_eq!(engine.eval::("let x = 2.0; x ~= -2.0; x").unwrap(), 0.25_f64); - assert_eq!(engine.eval::("let x = -2.0; x ~= -2.0; x").unwrap(), 0.25_f64); - assert_eq!(engine.eval::("let x = -2.0; x ~= -2; x").unwrap(), 0.25_f64); + assert_eq!( + engine.eval::("let x = 2.2; x ~= 3.3; x").unwrap(), + 13.489468760533386_f64 + ); + assert_eq!( + engine.eval::("let x = 2.0; x ~= -2.0; x").unwrap(), + 0.25_f64 + ); + assert_eq!( + engine.eval::("let x = -2.0; x ~= -2.0; x").unwrap(), + 0.25_f64 + ); + assert_eq!( + engine.eval::("let x = -2.0; x ~= -2; x").unwrap(), + 0.25_f64 + ); assert_eq!(engine.eval::("let x =4; x ~= 3; x").unwrap(), 64); } diff --git a/tests/string.rs b/tests/string.rs index 975b7adc..26f97441 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/unary_after_binary.rs b/tests/unary_after_binary.rs index 848ff2c3..0a1cc169 100644 --- a/tests/unary_after_binary.rs +++ b/tests/unary_after_binary.rs @@ -1,12 +1,9 @@ -extern crate rhai; - use rhai::Engine; #[test] // TODO also add test case for unary after compound // Hah, turns out unary + has a good use after all! -fn test_unary_after_binary() -{ +fn test_unary_after_binary() { let mut engine = Engine::new(); if let Ok(result) = engine.eval::("10 % +4") { diff --git a/tests/unary_minus.rs b/tests/unary_minus.rs index 0306067f..21f49ad4 100644 --- a/tests/unary_minus.rs +++ b/tests/unary_minus.rs @@ -1,14 +1,12 @@ -extern crate rhai; - use rhai::Engine; #[test] fn test_unary_minus() { - let mut engine = Engine::new(); + let mut engine = Engine::new(); - assert_eq!(engine.eval::("let x = -5; x").unwrap(), -5); + assert_eq!(engine.eval::("let x = -5; x").unwrap(), -5); - assert_eq!(engine.eval::("fn n(x) { -x } n(5)").unwrap(), -5); + assert_eq!(engine.eval::("fn n(x) { -x } n(5)").unwrap(), -5); - assert_eq!(engine.eval::("5 - -(-5)").unwrap(), 0); + assert_eq!(engine.eval::("5 - -(-5)").unwrap(), 0); } diff --git a/tests/unit.rs b/tests/unit.rs index ad2aff08..0f8fda65 100644 --- a/tests/unit.rs +++ b/tests/unit.rs @@ -1,5 +1,3 @@ -extern crate rhai; - use rhai::Engine; #[test] diff --git a/tests/var_scope.rs b/tests/var_scope.rs index 0243671d..c32cd07d 100644 --- a/tests/var_scope.rs +++ b/tests/var_scope.rs @@ -1,11 +1,9 @@ -extern crate rhai; - use rhai::{Engine, Scope}; #[test] fn test_var_scope() { let mut engine = Engine::new(); - let mut scope: Scope = Vec::new(); + let mut scope = Scope::new(); if let Ok(_) = engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5") { } else { diff --git a/tests/while_loop.rs b/tests/while_loop.rs index c34d72d3..464ff982 100644 --- a/tests/while_loop.rs +++ b/tests/while_loop.rs @@ -1,13 +1,13 @@ -extern crate rhai; - use rhai::Engine; #[test] fn test_while() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval::("let x = 0; while x < 10 { x = x + 1; if x > 5 { \ - break } } x") { + if let Ok(result) = engine.eval::( + "let x = 0; while x < 10 { x = x + 1; if x > 5 { \ + break } } x", + ) { assert_eq!(result, 6); } else { assert!(false);