From e224550861d6dc448e97221c9f1ab024266fa7ee Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 22 May 2020 18:28:13 +0800 Subject: [PATCH] Move boxing of ParseError into ParseErrorType. --- src/api.rs | 12 ++++---- src/engine.rs | 9 +++--- src/error.rs | 10 +++---- src/fn_func.rs | 4 +-- src/parser.rs | 78 +++++++++++++++++++++++++------------------------- src/result.rs | 7 +---- tests/stack.rs | 4 +-- 7 files changed, 59 insertions(+), 65 deletions(-) diff --git a/src/api.rs b/src/api.rs index 555141cf..05dc5ec3 100644 --- a/src/api.rs +++ b/src/api.rs @@ -341,7 +341,7 @@ impl Engine { /// # Ok(()) /// # } /// ``` - pub fn compile(&self, script: &str) -> Result> { + pub fn compile(&self, script: &str) -> Result { self.compile_with_scope(&Scope::new(), script) } @@ -383,7 +383,7 @@ impl Engine { /// # Ok(()) /// # } /// ``` - pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result> { + pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result { self.compile_scripts_with_scope(scope, &[script]) } @@ -437,7 +437,7 @@ impl Engine { &self, scope: &Scope, scripts: &[&str], - ) -> Result> { + ) -> Result { self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level) } @@ -447,7 +447,7 @@ impl Engine { scope: &Scope, scripts: &[&str], optimization_level: OptimizationLevel, - ) -> Result> { + ) -> Result { let stream = lex(scripts); parse( @@ -614,7 +614,7 @@ impl Engine { /// # Ok(()) /// # } /// ``` - pub fn compile_expression(&self, script: &str) -> Result> { + pub fn compile_expression(&self, script: &str) -> Result { self.compile_expression_with_scope(&Scope::new(), script) } @@ -661,7 +661,7 @@ impl Engine { &self, scope: &Scope, script: &str, - ) -> Result> { + ) -> Result { let scripts = [script]; let stream = lex(&scripts); diff --git a/src/engine.rs b/src/engine.rs index 2fa8348f..cbb7dc02 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -465,8 +465,7 @@ fn default_print(s: &str) { fn search_scope<'a>( scope: &'a mut Scope, name: &str, - #[cfg(not(feature = "no_module"))] modules: Option<(&Box, u64)>, - #[cfg(feature = "no_module")] _: Option<(&ModuleRef, u64)>, + modules: Option<(&ModuleRef, u64)>, index: Option, pos: Position, ) -> Result<(&'a mut Dynamic, ScopeEntryType), Box> { @@ -1146,7 +1145,7 @@ impl Engine { Expr::Variable(x) => { let ((name, pos), modules, hash_var, index) = x.as_ref(); let index = if state.always_search { None } else { *index }; - let mod_and_hash = modules.as_ref().map(|m| (m, *hash_var)); + let mod_and_hash = modules.as_ref().map(|m| (m.as_ref(), *hash_var)); let (target, typ) = search_scope(scope, &name, mod_and_hash, index, *pos)?; self.inc_operations(state, *pos)?; @@ -1393,7 +1392,7 @@ impl Engine { Expr::Variable(x) => { let ((name, pos), modules, hash_var, index) = x.as_ref(); let index = if state.always_search { None } else { *index }; - let mod_and_hash = modules.as_ref().map(|m| (m, *hash_var)); + let mod_and_hash = modules.as_ref().map(|m| (m.as_ref(), *hash_var)); let (val, _) = search_scope(scope, name, mod_and_hash, index, *pos)?; Ok(val.clone()) } @@ -1412,7 +1411,7 @@ impl Engine { Expr::Variable(x) => { let ((name, pos), modules, hash_var, index) = x.as_ref(); let index = if state.always_search { None } else { *index }; - let mod_and_hash = modules.as_ref().map(|m| (m, *hash_var)); + let mod_and_hash = modules.as_ref().map(|m| (m.as_ref(), *hash_var)); let (lhs_ptr, typ) = search_scope(scope, name, mod_and_hash, index, *pos)?; self.inc_operations(state, *pos)?; diff --git a/src/error.rs b/src/error.rs index 8e180c25..7bc60a1c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -120,14 +120,14 @@ pub enum ParseErrorType { impl ParseErrorType { /// Make a `ParseError` using the current type and position. - pub(crate) fn into_err(self, pos: Position) -> Box { - Box::new(ParseError(self, pos)) + pub(crate) fn into_err(self, pos: Position) -> ParseError { + ParseError(Box::new(self), pos) } } /// Error when parsing a script. #[derive(Debug, Eq, PartialEq, Clone, Hash)] -pub struct ParseError(pub(crate) ParseErrorType, pub(crate) Position); +pub struct ParseError(pub(crate) Box, pub(crate) Position); impl ParseError { /// Get the parse error. @@ -141,7 +141,7 @@ impl ParseError { } pub(crate) fn desc(&self) -> &str { - match &self.0 { + match self.0.as_ref() { ParseErrorType::BadInput(p) => p, ParseErrorType::UnexpectedEOF => "Script is incomplete", ParseErrorType::UnknownOperator(_) => "Unknown operator", @@ -173,7 +173,7 @@ impl Error for ParseError {} impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.0 { + match self.0.as_ref() { ParseErrorType::BadInput(s) | ParseErrorType::MalformedCallExpr(s) => { write!(f, "{}", if s.is_empty() { self.desc() } else { s })? } diff --git a/src/fn_func.rs b/src/fn_func.rs index f606b794..bbbab4aa 100644 --- a/src/fn_func.rs +++ b/src/fn_func.rs @@ -80,7 +80,7 @@ pub trait Func { self, script: &str, entry_point: &str, - ) -> Result>; + ) -> Result; } macro_rules! def_anonymous_fn { @@ -103,7 +103,7 @@ macro_rules! def_anonymous_fn { }) } - fn create_from_script(self, script: &str, entry_point: &str) -> Result> { + fn create_from_script(self, script: &str, entry_point: &str) -> Result { let ast = self.compile(script)?; Ok(Func::<($($par,)*), RET>::create_from_ast(self, ast, entry_point)) } diff --git a/src/parser.rs b/src/parser.rs index e03f3686..3c3581eb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -361,11 +361,6 @@ impl Stmt { } } -#[cfg(not(feature = "no_module"))] -type MRef = Option>; -#[cfg(feature = "no_module")] -type MRef = Option; - /// An expression. /// /// Each variant is at most one pointer in size (for speed), @@ -382,7 +377,14 @@ pub enum Expr { /// String constant. StringConstant(Box<(String, Position)>), /// Variable access - ((variable name, position), optional modules, hash, optional index) - Variable(Box<((String, Position), MRef, u64, Option)>), + Variable( + Box<( + (String, Position), + Option>, + u64, + Option, + )>, + ), /// Property access. Property(Box<((String, String, String), Position)>), /// { stmt } @@ -393,7 +395,7 @@ pub enum Expr { FnCall( Box<( (Cow<'static, str>, Position), - MRef, + Option>, u64, StaticVec, Option, @@ -661,7 +663,7 @@ fn eat_token(input: &mut Peekable, token: Token) -> Position { } /// Match a particular token, consuming it if matched. -fn match_token(input: &mut Peekable, token: Token) -> Result> { +fn match_token(input: &mut Peekable, token: Token) -> Result { let (t, _) = input.peek().unwrap(); if *t == token { eat_token(input, token); @@ -678,7 +680,7 @@ fn parse_paren_expr<'a>( pos: Position, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { if level > state.max_expr_depth { return Err(PERR::ExprTooDeep.into_err(pos)); } @@ -713,7 +715,7 @@ fn parse_call_expr<'a>( begin: Position, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (token, pos) = input.peek().unwrap(); if level > state.max_expr_depth { @@ -844,7 +846,7 @@ fn parse_index_chain<'a>( pos: Position, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { if level > state.max_expr_depth { return Err(PERR::ExprTooDeep.into_err(pos)); } @@ -1033,7 +1035,7 @@ fn parse_array_literal<'a>( pos: Position, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { if level > state.max_expr_depth { return Err(PERR::ExprTooDeep.into_err(pos)); } @@ -1081,7 +1083,7 @@ fn parse_map_literal<'a>( pos: Position, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { if level > state.max_expr_depth { return Err(PERR::ExprTooDeep.into_err(pos)); } @@ -1182,7 +1184,7 @@ fn parse_primary<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (token, pos) = input.peek().unwrap(); let pos = *pos; @@ -1290,7 +1292,7 @@ fn parse_unary<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (token, pos) = input.peek().unwrap(); let pos = *pos; @@ -1388,7 +1390,7 @@ fn make_assignment_stmt<'a>( lhs: Expr, rhs: Expr, pos: Position, -) -> Result> { +) -> Result { match &lhs { Expr::Variable(x) if x.3.is_none() => Ok(Expr::Assignment(Box::new((lhs, rhs, pos)))), Expr::Variable(x) => { @@ -1431,7 +1433,7 @@ fn parse_op_assignment_stmt<'a>( lhs: Expr, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (token, pos) = input.peek().unwrap(); let pos = *pos; @@ -1482,7 +1484,7 @@ fn make_dot_expr( rhs: Expr, op_pos: Position, is_index: bool, -) -> Result> { +) -> Result { Ok(match (lhs, rhs) { // idx_lhs[idx_rhs].rhs // Attach dot chain to the bottom level of indexing chain @@ -1544,7 +1546,7 @@ fn make_dot_expr( } /// Make an 'in' expression. -fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result> { +fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result { match (&lhs, &rhs) { (_, Expr::IntegerConstant(x)) => { return Err(PERR::MalformedInExpr( @@ -1717,7 +1719,7 @@ fn parse_binary_op<'a>( lhs: Expr, mut level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { if level > state.max_expr_depth { return Err(PERR::ExprTooDeep.into_err(lhs.position())); } @@ -1836,7 +1838,7 @@ fn parse_expr<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (_, pos) = input.peek().unwrap(); if level > state.max_expr_depth { @@ -1851,7 +1853,7 @@ fn parse_expr<'a>( fn ensure_not_statement_expr<'a>( input: &mut Peekable>, type_name: &str, -) -> Result<(), Box> { +) -> Result<(), ParseError> { match input.peek().unwrap() { // Disallow statement expressions (Token::LeftBrace, pos) | (Token::EOF, pos) => { @@ -1863,9 +1865,7 @@ fn ensure_not_statement_expr<'a>( } /// Make sure that the expression is not a mis-typed assignment (i.e. `a = b` instead of `a == b`). -fn ensure_not_assignment<'a>( - input: &mut Peekable>, -) -> Result<(), Box> { +fn ensure_not_assignment<'a>(input: &mut Peekable>) -> Result<(), ParseError> { match input.peek().unwrap() { (Token::Equals, pos) => { return Err(PERR::BadInput("Possibly a typo of '=='?".to_string()).into_err(*pos)) @@ -1898,7 +1898,7 @@ fn parse_if<'a>( breakable: bool, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // if ... let pos = eat_token(input, Token::If); @@ -1934,7 +1934,7 @@ fn parse_while<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // while ... let pos = eat_token(input, Token::While); @@ -1957,7 +1957,7 @@ fn parse_loop<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // loop ... let pos = eat_token(input, Token::Loop); @@ -1977,7 +1977,7 @@ fn parse_for<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // for ... let pos = eat_token(input, Token::For); @@ -2030,7 +2030,7 @@ fn parse_let<'a>( var_type: ScopeEntryType, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // let/const... (specified in `var_type`) let (_, pos) = input.next().unwrap(); @@ -2091,7 +2091,7 @@ fn parse_import<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // import ... let pos = eat_token(input, Token::Import); @@ -2129,7 +2129,7 @@ fn parse_export<'a>( input: &mut Peekable>, state: &mut ParseState, level: usize, -) -> Result> { +) -> Result { let pos = eat_token(input, Token::Export); if level > state.max_expr_depth { @@ -2196,7 +2196,7 @@ fn parse_block<'a>( breakable: bool, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { // Must start with { let pos = match input.next().unwrap() { (Token::LeftBrace, pos) => pos, @@ -2267,7 +2267,7 @@ fn parse_expr_stmt<'a>( state: &mut ParseState, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let (_, pos) = input.peek().unwrap(); if level > state.max_expr_depth { @@ -2287,7 +2287,7 @@ fn parse_stmt<'a>( is_global: bool, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { use ScopeEntryType::{Constant, Normal}; let (token, pos) = match input.peek().unwrap() { @@ -2376,7 +2376,7 @@ fn parse_fn<'a>( access: FnAccess, level: usize, allow_stmt_expr: bool, -) -> Result> { +) -> Result { let pos = eat_token(input, Token::Fn); if level > state.max_expr_depth { @@ -2467,7 +2467,7 @@ pub fn parse_global_expr<'a>( scope: &Scope, optimization_level: OptimizationLevel, max_expr_depth: usize, -) -> Result> { +) -> Result { let mut state = ParseState::new(max_expr_depth); let expr = parse_expr(input, &mut state, 0, false)?; @@ -2495,7 +2495,7 @@ pub fn parse_global_expr<'a>( fn parse_global_level<'a>( input: &mut Peekable>, max_expr_depth: (usize, usize), -) -> Result<(Vec, HashMap), Box> { +) -> Result<(Vec, HashMap), ParseError> { let mut statements = Vec::::new(); let mut functions = HashMap::::new(); let mut state = ParseState::new(max_expr_depth.0); @@ -2577,7 +2577,7 @@ pub fn parse<'a>( scope: &Scope, optimization_level: OptimizationLevel, max_expr_depth: (usize, usize), -) -> Result> { +) -> Result { let (statements, functions) = parse_global_level(input, max_expr_depth)?; let fn_lib = functions.into_iter().map(|(_, v)| v).collect(); diff --git a/src/result.rs b/src/result.rs index af55535a..2589016b 100644 --- a/src/result.rs +++ b/src/result.rs @@ -23,7 +23,7 @@ use crate::stdlib::path::PathBuf; #[derive(Debug)] pub enum EvalAltResult { /// Syntax error. - ErrorParsing(Box), + ErrorParsing(ParseError), /// Error reading from a script file. Wrapped value is the path of the script file. /// @@ -241,11 +241,6 @@ impl fmt::Display for EvalAltResult { impl From for Box { fn from(err: ParseError) -> Self { - Box::new(EvalAltResult::ErrorParsing(Box::new(err))) - } -} -impl From> for Box { - fn from(err: Box) -> Self { Box::new(EvalAltResult::ErrorParsing(err)) } } diff --git a/tests/stack.rs b/tests/stack.rs index ee7eedc4..c0cb8a38 100644 --- a/tests/stack.rs +++ b/tests/stack.rs @@ -33,7 +33,7 @@ fn test_stack_overflow_parsing() -> Result<(), Box> { let mut engine = Engine::new(); assert!(matches!( - *engine.compile(r" + engine.compile(r" let a = (1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ").expect_err("should error"), err if err.error_type() == &ParseErrorType::ExprTooDeep @@ -58,7 +58,7 @@ fn test_stack_overflow_parsing() -> Result<(), Box> { )?; assert!(matches!( - *engine.compile(r" + engine.compile(r" 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 +