Move boxing of ParseError into ParseErrorType.

This commit is contained in:
Stephen Chung 2020-05-22 18:28:13 +08:00
parent 2f0ab18b70
commit e224550861
7 changed files with 59 additions and 65 deletions

View File

@ -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);

View File

@ -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)?;

View File

@ -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 })?
}

View File

@ -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))
}

View File

@ -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();

View File

@ -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