Move boxing of ParseError into ParseErrorType.
This commit is contained in:
parent
2f0ab18b70
commit
e224550861
12
src/api.rs
12
src/api.rs
@ -341,7 +341,7 @@ impl Engine {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn compile(&self, script: &str) -> Result<AST, Box<ParseError>> {
|
||||
pub fn compile(&self, script: &str) -> Result<AST, ParseError> {
|
||||
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<AST, Box<ParseError>> {
|
||||
pub fn compile_with_scope(&self, scope: &Scope, script: &str) -> Result<AST, ParseError> {
|
||||
self.compile_scripts_with_scope(scope, &[script])
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ impl Engine {
|
||||
&self,
|
||||
scope: &Scope,
|
||||
scripts: &[&str],
|
||||
) -> Result<AST, Box<ParseError>> {
|
||||
) -> Result<AST, ParseError> {
|
||||
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<AST, Box<ParseError>> {
|
||||
) -> Result<AST, ParseError> {
|
||||
let stream = lex(scripts);
|
||||
|
||||
parse(
|
||||
@ -614,7 +614,7 @@ impl Engine {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn compile_expression(&self, script: &str) -> Result<AST, Box<ParseError>> {
|
||||
pub fn compile_expression(&self, script: &str) -> Result<AST, ParseError> {
|
||||
self.compile_expression_with_scope(&Scope::new(), script)
|
||||
}
|
||||
|
||||
@ -661,7 +661,7 @@ impl Engine {
|
||||
&self,
|
||||
scope: &Scope,
|
||||
script: &str,
|
||||
) -> Result<AST, Box<ParseError>> {
|
||||
) -> Result<AST, ParseError> {
|
||||
let scripts = [script];
|
||||
let stream = lex(&scripts);
|
||||
|
||||
|
@ -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<ModuleRef>, u64)>,
|
||||
#[cfg(feature = "no_module")] _: Option<(&ModuleRef, u64)>,
|
||||
modules: Option<(&ModuleRef, u64)>,
|
||||
index: Option<NonZeroUsize>,
|
||||
pos: Position,
|
||||
) -> Result<(&'a mut Dynamic, ScopeEntryType), Box<EvalAltResult>> {
|
||||
@ -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)?;
|
||||
|
||||
|
10
src/error.rs
10
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<ParseError> {
|
||||
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<ParseErrorType>, 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 })?
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ pub trait Func<ARGS, RET> {
|
||||
self,
|
||||
script: &str,
|
||||
entry_point: &str,
|
||||
) -> Result<Self::Output, Box<ParseError>>;
|
||||
) -> Result<Self::Output, ParseError>;
|
||||
}
|
||||
|
||||
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<Self::Output, Box<ParseError>> {
|
||||
fn create_from_script(self, script: &str, entry_point: &str) -> Result<Self::Output, ParseError> {
|
||||
let ast = self.compile(script)?;
|
||||
Ok(Func::<($($par,)*), RET>::create_from_ast(self, ast, entry_point))
|
||||
}
|
||||
|
@ -361,11 +361,6 @@ impl Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
type MRef = Option<Box<ModuleRef>>;
|
||||
#[cfg(feature = "no_module")]
|
||||
type MRef = Option<ModuleRef>;
|
||||
|
||||
/// 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<NonZeroUsize>)>),
|
||||
Variable(
|
||||
Box<(
|
||||
(String, Position),
|
||||
Option<Box<ModuleRef>>,
|
||||
u64,
|
||||
Option<NonZeroUsize>,
|
||||
)>,
|
||||
),
|
||||
/// Property access.
|
||||
Property(Box<((String, String, String), Position)>),
|
||||
/// { stmt }
|
||||
@ -393,7 +395,7 @@ pub enum Expr {
|
||||
FnCall(
|
||||
Box<(
|
||||
(Cow<'static, str>, Position),
|
||||
MRef,
|
||||
Option<Box<ModuleRef>>,
|
||||
u64,
|
||||
StaticVec<Expr>,
|
||||
Option<Dynamic>,
|
||||
@ -661,7 +663,7 @@ fn eat_token(input: &mut Peekable<TokenIterator>, token: Token) -> Position {
|
||||
}
|
||||
|
||||
/// Match a particular token, consuming it if matched.
|
||||
fn match_token(input: &mut Peekable<TokenIterator>, token: Token) -> Result<bool, Box<ParseError>> {
|
||||
fn match_token(input: &mut Peekable<TokenIterator>, token: Token) -> Result<bool, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<Expr, Box<ParseError>> {
|
||||
) -> Result<Expr, ParseError> {
|
||||
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<TokenIterator<'a>>,
|
||||
type_name: &str,
|
||||
) -> Result<(), Box<ParseError>> {
|
||||
) -> 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<TokenIterator<'a>>,
|
||||
) -> Result<(), Box<ParseError>> {
|
||||
fn ensure_not_assignment<'a>(input: &mut Peekable<TokenIterator<'a>>) -> 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// import ...
|
||||
let pos = eat_token(input, Token::Import);
|
||||
|
||||
@ -2129,7 +2129,7 @@ fn parse_export<'a>(
|
||||
input: &mut Peekable<TokenIterator<'a>>,
|
||||
state: &mut ParseState,
|
||||
level: usize,
|
||||
) -> Result<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
// 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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
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<Stmt, Box<ParseError>> {
|
||||
) -> Result<Stmt, ParseError> {
|
||||
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<FnDef, Box<ParseError>> {
|
||||
) -> Result<FnDef, ParseError> {
|
||||
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<AST, Box<ParseError>> {
|
||||
) -> Result<AST, ParseError> {
|
||||
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<TokenIterator<'a>>,
|
||||
max_expr_depth: (usize, usize),
|
||||
) -> Result<(Vec<Stmt>, HashMap<u64, FnDef>), Box<ParseError>> {
|
||||
) -> Result<(Vec<Stmt>, HashMap<u64, FnDef>), ParseError> {
|
||||
let mut statements = Vec::<Stmt>::new();
|
||||
let mut functions = HashMap::<u64, FnDef>::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<AST, Box<ParseError>> {
|
||||
) -> Result<AST, ParseError> {
|
||||
let (statements, functions) = parse_global_level(input, max_expr_depth)?;
|
||||
|
||||
let fn_lib = functions.into_iter().map(|(_, v)| v).collect();
|
||||
|
@ -23,7 +23,7 @@ use crate::stdlib::path::PathBuf;
|
||||
#[derive(Debug)]
|
||||
pub enum EvalAltResult {
|
||||
/// Syntax error.
|
||||
ErrorParsing(Box<ParseError>),
|
||||
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<ParseError> for Box<EvalAltResult> {
|
||||
fn from(err: ParseError) -> Self {
|
||||
Box::new(EvalAltResult::ErrorParsing(Box::new(err)))
|
||||
}
|
||||
}
|
||||
impl From<Box<ParseError>> for Box<EvalAltResult> {
|
||||
fn from(err: Box<ParseError>) -> Self {
|
||||
Box::new(EvalAltResult::ErrorParsing(err))
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user