diff --git a/src/api.rs b/src/api.rs index dc0a26d0..5a683d4a 100644 --- a/src/api.rs +++ b/src/api.rs @@ -7,7 +7,7 @@ use crate::fn_call::FuncArgs; use crate::fn_native::{IteratorFn, SendSync}; use crate::fn_register::RegisterFn; use crate::optimize::{optimize_into_ast, OptimizationLevel}; -use crate::parser::{parse, parse_global_expr, AST}; +use crate::parser::AST; use crate::result::EvalAltResult; use crate::scope::Scope; use crate::token::{lex, Position}; @@ -449,14 +449,7 @@ impl Engine { optimization_level: OptimizationLevel, ) -> Result { let stream = lex(scripts); - - parse( - &mut stream.peekable(), - self, - scope, - optimization_level, - (self.max_expr_depth, self.max_function_expr_depth), - ) + self.parse(&mut stream.peekable(), scope, optimization_level) } /// Read the contents of a file into a string. @@ -578,13 +571,8 @@ impl Engine { // Trims the JSON string and add a '#' in front let scripts = ["#", json.trim()]; let stream = lex(&scripts); - let ast = parse_global_expr( - &mut stream.peekable(), - self, - &scope, - OptimizationLevel::None, - self.max_expr_depth, - )?; + let ast = + self.parse_global_expr(&mut stream.peekable(), &scope, OptimizationLevel::None)?; // Handle null - map to () if has_null { @@ -667,13 +655,7 @@ impl Engine { { let mut peekable = stream.peekable(); - parse_global_expr( - &mut peekable, - self, - scope, - self.optimization_level, - self.max_expr_depth, - ) + self.parse_global_expr(&mut peekable, scope, self.optimization_level) } } @@ -825,12 +807,10 @@ impl Engine { let scripts = [script]; let stream = lex(&scripts); - let ast = parse_global_expr( + let ast = self.parse_global_expr( &mut stream.peekable(), - self, scope, OptimizationLevel::None, // No need to optimize a lone expression - self.max_expr_depth, )?; self.eval_ast_with_scope(scope, &ast) @@ -957,13 +937,7 @@ impl Engine { let scripts = [script]; let stream = lex(&scripts); - let ast = parse( - &mut stream.peekable(), - self, - scope, - self.optimization_level, - (self.max_expr_depth, self.max_function_expr_depth), - )?; + let ast = self.parse(&mut stream.peekable(), scope, self.optimization_level)?; self.consume_ast_with_scope(scope, &ast) } diff --git a/src/parser.rs b/src/parser.rs index 5ff5e692..b2c4c1cf 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2478,44 +2478,15 @@ fn parse_fn<'a>( }) } -pub fn parse_global_expr<'a>( - input: &mut Peekable>, - engine: &Engine, - scope: &Scope, - optimization_level: OptimizationLevel, - max_expr_depth: usize, -) -> Result { - let mut state = ParseState::new(max_expr_depth); - let expr = parse_expr(input, &mut state, 0, false, false)?; - - match input.peek().unwrap() { - (Token::EOF, _) => (), - // Return error if the expression doesn't end - (token, pos) => { - return Err(PERR::BadInput(format!("Unexpected '{}'", token.syntax())).into_err(*pos)) - } - } - - Ok( - // Optimize AST - optimize_into_ast( - engine, - scope, - vec![Stmt::Expr(Box::new(expr))], - vec![], - optimization_level, - ), - ) -} - /// Parse the global level statements. fn parse_global_level<'a>( input: &mut Peekable>, - max_expr_depth: (usize, usize), + max_expr_depth: usize, + max_function_expr_depth: usize, ) -> Result<(Vec, Vec), ParseError> { let mut statements = Vec::::new(); let mut functions = HashMap::::with_hasher(StraightHasherBuilder); - let mut state = ParseState::new(max_expr_depth.0); + let mut state = ParseState::new(max_expr_depth); while !input.peek().unwrap().0.is_eof() { // Collect all the function definitions @@ -2530,7 +2501,7 @@ fn parse_global_level<'a>( match input.peek().unwrap() { #[cfg(not(feature = "no_function"))] (Token::Fn, _) => { - let mut state = ParseState::new(max_expr_depth.1); + let mut state = ParseState::new(max_function_expr_depth); let func = parse_fn(input, &mut state, access, 0, true, true)?; // Qualifiers (none) + function name + number of arguments. @@ -2586,20 +2557,49 @@ fn parse_global_level<'a>( Ok((statements, functions.into_iter().map(|(_, v)| v).collect())) } -/// Run the parser on an input stream, returning an AST. -pub fn parse<'a>( - input: &mut Peekable>, - engine: &Engine, - scope: &Scope, - optimization_level: OptimizationLevel, - max_expr_depth: (usize, usize), -) -> Result { - let (statements, lib) = parse_global_level(input, max_expr_depth)?; +impl Engine { + pub(crate) fn parse_global_expr<'a>( + &self, + input: &mut Peekable>, + scope: &Scope, + optimization_level: OptimizationLevel, + ) -> Result { + let mut state = ParseState::new(self.max_expr_depth); + let expr = parse_expr(input, &mut state, 0, false, false)?; - Ok( - // Optimize AST - optimize_into_ast(engine, scope, statements, lib, optimization_level), - ) + match input.peek().unwrap() { + (Token::EOF, _) => (), + // Return error if the expression doesn't end + (token, pos) => { + return Err( + PERR::BadInput(format!("Unexpected '{}'", token.syntax())).into_err(*pos) + ) + } + } + + let expr = vec![Stmt::Expr(Box::new(expr))]; + + Ok( + // Optimize AST + optimize_into_ast(self, scope, expr, Default::default(), optimization_level), + ) + } + + /// Run the parser on an input stream, returning an AST. + pub(crate) fn parse<'a>( + &self, + input: &mut Peekable>, + scope: &Scope, + optimization_level: OptimizationLevel, + ) -> Result { + let (statements, lib) = + parse_global_level(input, self.max_expr_depth, self.max_function_expr_depth)?; + + Ok( + // Optimize AST + optimize_into_ast(self, scope, statements, lib, optimization_level), + ) + } } /// Map a `Dynamic` value to an expression.