From 6dedb1ed9f69337196c560b3d2bcd67525e91e0e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 11 Jan 2022 11:33:54 +0800 Subject: [PATCH] Fix no_std builds. --- CHANGELOG.md | 1 + src/eval/expr.rs | 10 ++++++---- src/types/error.rs | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1574404..74369277 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ New features ------------ * Added support for integer _ranges_ via the `..` and `..=` operators. +* Added `EvalAltResult::ErrorCustomSyntax` to catch errors in custom syntax, which should not happen unless an `AST` is compiled on one `Engine` but evaluated on another unrelated `Engine`. Enhancements ------------ diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 2a0e580f..775bb8ae 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -416,14 +416,16 @@ impl Engine { .into()) } - Expr::Custom(custom, _) => { + Expr::Custom(custom, pos) => { let expressions: StaticVec<_> = custom.inputs.iter().map(Into::into).collect(); + // The first token acts as the custom syntax's key let key_token = custom.tokens.first().unwrap(); + // The key should exist, unless the AST is compiled in a different Engine let custom_def = self.custom_syntax.get(key_token).ok_or_else(|| { - let code: Vec<_> = custom.tokens.iter().map(|s| s.as_str()).collect(); - Box::new(ERR::ErrorSystem( + Box::new(ERR::ErrorCustomSyntax( format!("Invalid custom syntax prefix: {}", key_token), - code.join(" ").into(), + custom.tokens.iter().map(|s| s.to_string()).collect(), + *pos, )) })?; let mut context = EvalContext { diff --git a/src/types/error.rs b/src/types/error.rs index 93e7f3d1..4be7e573 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -71,6 +71,7 @@ pub enum EvalAltResult { ErrorDotExpr(String, Position), /// Arithmetic error encountered. Wrapped value is the error message. ErrorArithmetic(String, Position), + /// Number of operations over maximum limit. ErrorTooManyOperations(Position), /// [Modules][crate::Module] over maximum limit. @@ -81,6 +82,14 @@ pub enum EvalAltResult { ErrorDataTooLarge(String, Position), /// The script is prematurely terminated. Wrapped value is the termination token. ErrorTerminated(Dynamic, Position), + + /// Error encountered for a custom syntax. Wrapped values are the error message and + /// custom syntax symbols stream. + /// + /// Normally this should never happen, unless an [`AST`][crate::AST] is compiled on one + /// [`Engine`][crate::Engine] but evaluated on another unrelated [`Engine`][crate::Engine]. + ErrorCustomSyntax(String, Vec, Position), + /// Run-time error encountered. Wrapped value is the error token. ErrorRuntime(Dynamic, Position), @@ -204,6 +213,8 @@ impl fmt::Display for EvalAltResult { index, max )?, Self::ErrorDataTooLarge(typ, _) => write!(f, "{} exceeds maximum limit", typ)?, + + Self::ErrorCustomSyntax(s, tokens, _) => write!(f, "{}: {}", s, tokens.join(" "))?, } // Do not write any position if None @@ -266,7 +277,8 @@ impl EvalAltResult { | Self::ErrorArithmetic(_, _) | Self::ErrorRuntime(_, _) => true, - Self::ErrorTooManyOperations(_) + Self::ErrorCustomSyntax(_, _, _) + | Self::ErrorTooManyOperations(_) | Self::ErrorTooManyModules(_) | Self::ErrorStackOverflow(_) | Self::ErrorDataTooLarge(_, _) @@ -282,7 +294,8 @@ impl EvalAltResult { Self::ErrorSystem(_, _) => true, Self::ErrorParsing(_, _) => true, - Self::ErrorTooManyOperations(_) + Self::ErrorCustomSyntax(_, _, _) + | Self::ErrorTooManyOperations(_) | Self::ErrorTooManyModules(_) | Self::ErrorStackOverflow(_) | Self::ErrorDataTooLarge(_, _) => true, @@ -295,6 +308,8 @@ impl EvalAltResult { /// Get the [position][Position] of this error. #[cfg(not(feature = "no_object"))] pub(crate) fn dump_fields(&self, map: &mut crate::Map) { + use std::str::FromStr; + map.insert( "error".into(), format!("{:?}", self) @@ -358,6 +373,17 @@ impl EvalAltResult { Self::ErrorTerminated(t, _) => { map.insert("token".into(), t.clone()); } + Self::ErrorCustomSyntax(_, tokens, _) => { + map.insert( + "tokens".into(), + Dynamic::from_array( + tokens + .iter() + .map(|s| Dynamic::from_str(s).unwrap()) + .collect(), + ), + ); + } }; } /// Get the [position][Position] of this error. @@ -389,6 +415,7 @@ impl EvalAltResult { | Self::ErrorStackOverflow(pos) | Self::ErrorDataTooLarge(_, pos) | Self::ErrorTerminated(_, pos) + | Self::ErrorCustomSyntax(_, _, pos) | Self::ErrorRuntime(_, pos) | Self::LoopBreak(_, pos) | Self::Return(_, pos) => *pos, @@ -436,6 +463,7 @@ impl EvalAltResult { | Self::ErrorStackOverflow(pos) | Self::ErrorDataTooLarge(_, pos) | Self::ErrorTerminated(_, pos) + | Self::ErrorCustomSyntax(_, _, pos) | Self::ErrorRuntime(_, pos) | Self::LoopBreak(_, pos) | Self::Return(_, pos) => *pos = new_position,