Refine error display.
This commit is contained in:
parent
549193f49b
commit
fcc7589ffc
@ -33,7 +33,7 @@ Standard features
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
* Simple language similar to JavaScript+Rust with [dynamic](https://rhai.rs/book/language/dynamic.html) typing.
|
* Simple language similar to JavaScript+Rust with [dynamic](https://rhai.rs/book/language/dynamic.html) typing.
|
||||||
* Fairly efficient evaluation (1 million iterations in 0.15 sec on a single-core 2.6 GHz Linux VM).
|
* Fairly efficient evaluation (1 million iterations in 0.14 sec on a single-core 2.6 GHz Linux VM).
|
||||||
* Tight integration with native Rust [functions](https://rhai.rs/book/rust/functions.html) and [types](https://rhai.rs/book/rust/custom-types.html), including [getters/setters](https://rhai.rs/book/rust/getters-setters.html), [methods](https://rhai.rs/book/rust/methods.html) and [indexers](https://rhai.rs/book/rust/indexers.html).
|
* Tight integration with native Rust [functions](https://rhai.rs/book/rust/functions.html) and [types](https://rhai.rs/book/rust/custom-types.html), including [getters/setters](https://rhai.rs/book/rust/getters-setters.html), [methods](https://rhai.rs/book/rust/methods.html) and [indexers](https://rhai.rs/book/rust/indexers.html).
|
||||||
* Freely pass Rust values into a script as [variables](https://rhai.rs/book/language/variables.html)/[constants](https://rhai.rs/book/language/constants.html) via an external [`Scope`](https://rhai.rs/book/engine/scope.html) - all clonable Rust types are supported; no need to implement any special trait. Or tap directly into the [variable resolution process](https://rhai.rs/book/engine/var.html).
|
* Freely pass Rust values into a script as [variables](https://rhai.rs/book/language/variables.html)/[constants](https://rhai.rs/book/language/constants.html) via an external [`Scope`](https://rhai.rs/book/engine/scope.html) - all clonable Rust types are supported; no need to implement any special trait. Or tap directly into the [variable resolution process](https://rhai.rs/book/engine/var.html).
|
||||||
* Built-in support for most common [data types](https://rhai.rs/book/language/values-and-types.html) including booleans, [integers](https://rhai.rs/book/language/numbers.html), [floating-point numbers](https://rhai.rs/book/language/numbers.html) (including [`Decimal`](https://crates.io/crates/rust_decimal)), [strings](https://rhai.rs/book/language/strings-chars.html), [Unicode characters](https://rhai.rs/book/language/strings-chars.html), [arrays](https://rhai.rs/book/language/arrays.html) (including packed [byte arrays](https://rhai.rs/book/language/blobs.html)) and [object maps](https://rhai.rs/book/language/object-maps.html).
|
* Built-in support for most common [data types](https://rhai.rs/book/language/values-and-types.html) including booleans, [integers](https://rhai.rs/book/language/numbers.html), [floating-point numbers](https://rhai.rs/book/language/numbers.html) (including [`Decimal`](https://crates.io/crates/rust_decimal)), [strings](https://rhai.rs/book/language/strings-chars.html), [Unicode characters](https://rhai.rs/book/language/strings-chars.html), [arrays](https://rhai.rs/book/language/arrays.html) (including packed [byte arrays](https://rhai.rs/book/language/blobs.html)) and [object maps](https://rhai.rs/book/language/object-maps.html).
|
||||||
|
@ -127,9 +127,13 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let statements = ast.statements();
|
let statements = ast.statements();
|
||||||
if !statements.is_empty() {
|
|
||||||
self.eval_global_statements(global, caches, scope, statements)?;
|
let result = if !statements.is_empty() {
|
||||||
}
|
self.eval_global_statements(global, caches, scope, statements)
|
||||||
|
.map(|_| ())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.is_debugger_registered() {
|
if self.is_debugger_registered() {
|
||||||
@ -139,7 +143,7 @@ impl Engine {
|
|||||||
self.run_debugger(global, caches, scope, &mut this, node)?;
|
self.run_debugger(global, caches, scope, &mut this, node)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,19 +100,21 @@ fn print_error(input: &str, mut err: EvalAltResult) {
|
|||||||
// Print error position
|
// Print error position
|
||||||
if pos.is_none() {
|
if pos.is_none() {
|
||||||
// No position
|
// No position
|
||||||
println!("{err}");
|
println!("\x1b[31m{err}\x1b[39m");
|
||||||
} else {
|
} else {
|
||||||
// Specific position - print line text
|
// Specific position - print line text
|
||||||
println!("{line_no}{}", lines[pos.line().unwrap() - 1]);
|
println!("{line_no}{}", lines[pos.line().unwrap() - 1]);
|
||||||
|
|
||||||
|
for (i, err_line) in err.to_string().split('\n').enumerate() {
|
||||||
// Display position marker
|
// Display position marker
|
||||||
println!(
|
println!(
|
||||||
"{0:>1$} {err}",
|
"\x1b[31m{0:>1$}{err_line}\x1b[39m",
|
||||||
"^",
|
if i > 0 { " " } else { "^ " },
|
||||||
line_no.len() + pos.position().unwrap(),
|
line_no.len() + pos.position().unwrap() + 1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Print debug help.
|
/// Print debug help.
|
||||||
fn print_debug_help() {
|
fn print_debug_help() {
|
||||||
@ -237,7 +239,13 @@ fn debug_callback(
|
|||||||
) -> Result<DebuggerCommand, Box<EvalAltResult>> {
|
) -> Result<DebuggerCommand, Box<EvalAltResult>> {
|
||||||
// Check event
|
// Check event
|
||||||
match event {
|
match event {
|
||||||
|
DebuggerEvent::Start if source.is_some() => {
|
||||||
|
println!("\x1b[32m! Script '{}' start\x1b[39m", source.unwrap())
|
||||||
|
}
|
||||||
DebuggerEvent::Start => println!("\x1b[32m! Script start\x1b[39m"),
|
DebuggerEvent::Start => println!("\x1b[32m! Script start\x1b[39m"),
|
||||||
|
DebuggerEvent::End if source.is_some() => {
|
||||||
|
println!("\x1b[31m! Script '{}' end\x1b[39m", source.unwrap())
|
||||||
|
}
|
||||||
DebuggerEvent::End => println!("\x1b[31m! Script end\x1b[39m"),
|
DebuggerEvent::End => println!("\x1b[31m! Script end\x1b[39m"),
|
||||||
DebuggerEvent::Step => (),
|
DebuggerEvent::Step => (),
|
||||||
DebuggerEvent::BreakPoint(n) => {
|
DebuggerEvent::BreakPoint(n) => {
|
||||||
@ -572,7 +580,7 @@ fn debug_callback(
|
|||||||
break Err(EvalAltResult::ErrorRuntime(msg.trim().into(), pos).into());
|
break Err(EvalAltResult::ErrorRuntime(msg.trim().into(), pos).into());
|
||||||
}
|
}
|
||||||
["run" | "r"] => {
|
["run" | "r"] => {
|
||||||
println!("Restarting script...");
|
println!("Terminating current run...");
|
||||||
break Err(EvalAltResult::ErrorTerminated(Dynamic::UNIT, pos).into());
|
break Err(EvalAltResult::ErrorTerminated(Dynamic::UNIT, pos).into());
|
||||||
}
|
}
|
||||||
_ => eprintln!(
|
_ => eprintln!(
|
||||||
@ -630,10 +638,13 @@ fn main() {
|
|||||||
while let Err(err) = engine.run_ast_with_scope(&mut Scope::new(), &ast) {
|
while let Err(err) = engine.run_ast_with_scope(&mut Scope::new(), &ast) {
|
||||||
match *err {
|
match *err {
|
||||||
// Loop back to restart
|
// Loop back to restart
|
||||||
EvalAltResult::ErrorTerminated(..) => (),
|
EvalAltResult::ErrorTerminated(..) => {
|
||||||
|
println!("Restarting script...");
|
||||||
|
}
|
||||||
// Break evaluation
|
// Break evaluation
|
||||||
_ => {
|
_ => {
|
||||||
print_error(&script, *err);
|
print_error(&script, *err);
|
||||||
|
println!();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,14 +31,16 @@ fn print_error(input: &str, mut err: EvalAltResult) {
|
|||||||
// Specific position - print line text
|
// Specific position - print line text
|
||||||
println!("{line_no}{}", lines[pos.line().unwrap() - 1]);
|
println!("{line_no}{}", lines[pos.line().unwrap() - 1]);
|
||||||
|
|
||||||
|
for (i, err_line) in err.to_string().split('\n').enumerate() {
|
||||||
// Display position marker
|
// Display position marker
|
||||||
println!(
|
println!(
|
||||||
"{0:>1$} {err}",
|
"{0:>1$}{err_line}",
|
||||||
"^",
|
if i > 0 { " " } else { "^ " },
|
||||||
line_no.len() + pos.position().unwrap(),
|
line_no.len() + pos.position().unwrap() + 1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Print help text.
|
/// Print help text.
|
||||||
fn print_help() {
|
fn print_help() {
|
||||||
|
@ -8,11 +8,15 @@ fn eprint_error(input: &str, mut err: EvalAltResult) {
|
|||||||
let line_no = format!("{line}: ");
|
let line_no = format!("{line}: ");
|
||||||
|
|
||||||
eprintln!("{line_no}{}", lines[line - 1]);
|
eprintln!("{line_no}{}", lines[line - 1]);
|
||||||
eprintln!(
|
|
||||||
"{:>1$} {err_msg}",
|
for (i, err_line) in err_msg.to_string().split('\n').enumerate() {
|
||||||
"^",
|
// Display position marker
|
||||||
line_no.len() + pos.position().unwrap(),
|
println!(
|
||||||
|
"{0:>1$}{err_line}",
|
||||||
|
if i > 0 { " " } else { "^ " },
|
||||||
|
line_no.len() + pos.position().unwrap() + 1,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
eprintln!();
|
eprintln!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use super::call::FnCallArgs;
|
use super::call::FnCallArgs;
|
||||||
use crate::ast::ScriptFnDef;
|
use crate::ast::ScriptFnDef;
|
||||||
use crate::eval::{Caches, GlobalRuntimeState};
|
use crate::eval::{Caches, GlobalRuntimeState};
|
||||||
use crate::{Dynamic, Engine, Position, RhaiError, RhaiResult, Scope, ERR};
|
use crate::{Dynamic, Engine, Position, RhaiResult, Scope, ERR};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -33,32 +33,6 @@ impl Engine {
|
|||||||
rewind_scope: bool,
|
rewind_scope: bool,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn make_error(
|
|
||||||
name: String,
|
|
||||||
_fn_def: &ScriptFnDef,
|
|
||||||
global: &GlobalRuntimeState,
|
|
||||||
err: RhaiError,
|
|
||||||
pos: Position,
|
|
||||||
) -> RhaiResult {
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
|
||||||
let source = _fn_def
|
|
||||||
.environ
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|environ| environ.lib.id().map(str::to_string));
|
|
||||||
#[cfg(feature = "no_module")]
|
|
||||||
let source = None;
|
|
||||||
|
|
||||||
Err(ERR::ErrorInFunctionCall(
|
|
||||||
name,
|
|
||||||
source.unwrap_or_else(|| global.source().unwrap_or("").to_string()),
|
|
||||||
err,
|
|
||||||
pos,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(fn_def.params.len() == args.len());
|
assert!(fn_def.params.len() == args.len());
|
||||||
|
|
||||||
self.track_operation(global, pos)?;
|
self.track_operation(global, pos)?;
|
||||||
@ -97,14 +71,13 @@ impl Engine {
|
|||||||
// Push a new call stack frame
|
// Push a new call stack frame
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.is_debugger_registered() {
|
if self.is_debugger_registered() {
|
||||||
|
let fn_name = fn_def.name.clone();
|
||||||
|
let args = scope.iter().skip(orig_scope_len).map(|(.., v)| v).collect();
|
||||||
let source = global.source.clone();
|
let source = global.source.clone();
|
||||||
|
|
||||||
global.debugger_mut().push_call_stack_frame(
|
global
|
||||||
fn_def.name.clone(),
|
.debugger_mut()
|
||||||
scope.iter().skip(orig_scope_len).map(|(.., v)| v).collect(),
|
.push_call_stack_frame(fn_name, args, source, pos);
|
||||||
source,
|
|
||||||
pos,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge in encapsulated environment, if any
|
// Merge in encapsulated environment, if any
|
||||||
@ -137,27 +110,32 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the function
|
// Evaluate the function
|
||||||
let mut _result = self
|
let mut _result: RhaiResult = self
|
||||||
.eval_stmt_block(global, caches, scope, this_ptr, &fn_def.body, rewind_scope)
|
.eval_stmt_block(global, caches, scope, this_ptr, &fn_def.body, rewind_scope)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Convert return statement to return value
|
// Convert return statement to return value
|
||||||
ERR::Return(x, ..) => Ok(x),
|
ERR::Return(x, ..) => Ok(x),
|
||||||
// Error in sub function call
|
|
||||||
ERR::ErrorInFunctionCall(name, src, err, ..) => {
|
|
||||||
let fn_name = if src.is_empty() {
|
|
||||||
format!("{name} < {}", fn_def.name)
|
|
||||||
} else {
|
|
||||||
format!("{name} @ '{src}' < {}", fn_def.name)
|
|
||||||
};
|
|
||||||
make_error(fn_name, fn_def, global, err, pos)
|
|
||||||
}
|
|
||||||
// System errors are passed straight-through
|
// System errors are passed straight-through
|
||||||
mut err if err.is_system_exception() => {
|
mut err if err.is_system_exception() => {
|
||||||
err.set_position(pos);
|
err.set_position(pos);
|
||||||
Err(err.into())
|
Err(err.into())
|
||||||
}
|
}
|
||||||
// Other errors are wrapped in `ErrorInFunctionCall`
|
// Other errors are wrapped in `ErrorInFunctionCall`
|
||||||
_ => make_error(fn_def.name.to_string(), fn_def, global, err, pos),
|
_ => Err(ERR::ErrorInFunctionCall(
|
||||||
|
fn_def.name.to_string(),
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
fn_def
|
||||||
|
.environ
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|environ| environ.lib.id())
|
||||||
|
.unwrap_or_else(|| global.source().unwrap_or(""))
|
||||||
|
.to_string(),
|
||||||
|
#[cfg(feature = "no_module")]
|
||||||
|
global.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
pos,
|
||||||
|
)
|
||||||
|
.into()),
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
|
@ -135,22 +135,20 @@ impl fmt::Display for EvalAltResult {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
Self::ErrorInFunctionCall(s, src, err, ..) if crate::parser::is_anonymous_fn(s) => {
|
Self::ErrorInFunctionCall(s, src, err, ..) if crate::parser::is_anonymous_fn(s) => {
|
||||||
write!(f, "{err} in call to closure")?;
|
write!(f, "{err}\n| in closure call")?;
|
||||||
if !src.is_empty() {
|
if !src.is_empty() {
|
||||||
write!(f, " @ '{src}'")?;
|
write!(f, " @ '{src}'")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::ErrorInFunctionCall(s, src, err, ..) => {
|
Self::ErrorInFunctionCall(s, src, err, ..) => {
|
||||||
write!(f, "{err} in call to function {s}")?;
|
write!(f, "{err}\n| in call to function '{s}'")?;
|
||||||
if !src.is_empty() {
|
if !src.is_empty() {
|
||||||
write!(f, " @ '{src}'")?;
|
write!(f, " @ '{src}'")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::ErrorInModule(s, err, ..) if s.is_empty() => {
|
Self::ErrorInModule(s, err, ..) if s.is_empty() => write!(f, "{err}\n| in module")?,
|
||||||
write!(f, "Error in module > {err}")?
|
Self::ErrorInModule(s, err, ..) => write!(f, "{err}\n| in module '{s}'")?,
|
||||||
}
|
|
||||||
Self::ErrorInModule(s, err, ..) => write!(f, "Error in module '{s}' > {err}")?,
|
|
||||||
|
|
||||||
Self::ErrorVariableExists(s, ..) => write!(f, "Variable already defined: {s}")?,
|
Self::ErrorVariableExists(s, ..) => write!(f, "Variable already defined: {s}")?,
|
||||||
Self::ErrorForbiddenVariable(s, ..) => write!(f, "Forbidden variable name: {s}")?,
|
Self::ErrorForbiddenVariable(s, ..) => write!(f, "Forbidden variable name: {s}")?,
|
||||||
@ -159,16 +157,14 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorIndexNotFound(s, ..) => write!(f, "Invalid index: {s}")?,
|
Self::ErrorIndexNotFound(s, ..) => write!(f, "Invalid index: {s}")?,
|
||||||
Self::ErrorFunctionNotFound(s, ..) => write!(f, "Function not found: {s}")?,
|
Self::ErrorFunctionNotFound(s, ..) => write!(f, "Function not found: {s}")?,
|
||||||
Self::ErrorModuleNotFound(s, ..) => write!(f, "Module not found: {s}")?,
|
Self::ErrorModuleNotFound(s, ..) => write!(f, "Module not found: {s}")?,
|
||||||
Self::ErrorDataRace(s, ..) => {
|
Self::ErrorDataRace(s, ..) => write!(f, "Data race detected on variable '{s}'")?,
|
||||||
write!(f, "Data race detected when accessing variable: {s}")?
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::ErrorDotExpr(s, ..) if s.is_empty() => f.write_str("Malformed dot expression")?,
|
Self::ErrorDotExpr(s, ..) if s.is_empty() => f.write_str("Malformed dot expression")?,
|
||||||
Self::ErrorDotExpr(s, ..) => f.write_str(s)?,
|
Self::ErrorDotExpr(s, ..) => f.write_str(s)?,
|
||||||
|
|
||||||
Self::ErrorIndexingType(s, ..) => write!(f, "Indexer unavailable: {s}")?,
|
Self::ErrorIndexingType(s, ..) => write!(f, "Indexer unavailable: {s}")?,
|
||||||
Self::ErrorUnboundThis(..) => f.write_str("'this' not bound")?,
|
Self::ErrorUnboundThis(..) => f.write_str("'this' not bound")?,
|
||||||
Self::ErrorFor(..) => f.write_str("For loop expects an iterable type")?,
|
Self::ErrorFor(..) => f.write_str("For loop expects iterable type")?,
|
||||||
Self::ErrorTooManyOperations(..) => f.write_str("Too many operations")?,
|
Self::ErrorTooManyOperations(..) => f.write_str("Too many operations")?,
|
||||||
Self::ErrorTooManyModules(..) => f.write_str("Too many modules imported")?,
|
Self::ErrorTooManyModules(..) => f.write_str("Too many modules imported")?,
|
||||||
Self::ErrorStackOverflow(..) => f.write_str("Stack overflow")?,
|
Self::ErrorStackOverflow(..) => f.write_str("Stack overflow")?,
|
||||||
@ -188,31 +184,25 @@ impl fmt::Display for EvalAltResult {
|
|||||||
if s.starts_with(crate::engine::FN_GET) =>
|
if s.starts_with(crate::engine::FN_GET) =>
|
||||||
{
|
{
|
||||||
let prop = &s[crate::engine::FN_GET.len()..];
|
let prop = &s[crate::engine::FN_GET.len()..];
|
||||||
write!(
|
write!(f, "Non-pure property {prop} cannot be accessed on constant")?
|
||||||
f,
|
|
||||||
"Property {prop} is not pure and cannot be accessed on a constant"
|
|
||||||
)?
|
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Self::ErrorNonPureMethodCallOnConstant(s, ..)
|
Self::ErrorNonPureMethodCallOnConstant(s, ..)
|
||||||
if s.starts_with(crate::engine::FN_SET) =>
|
if s.starts_with(crate::engine::FN_SET) =>
|
||||||
{
|
{
|
||||||
let prop = &s[crate::engine::FN_SET.len()..];
|
let prop = &s[crate::engine::FN_SET.len()..];
|
||||||
write!(f, "Cannot modify property '{prop}' of a constant")?
|
write!(f, "Cannot modify property '{prop}' of constant")?
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::ErrorNonPureMethodCallOnConstant(s, ..) if s == crate::engine::FN_IDX_GET => {
|
Self::ErrorNonPureMethodCallOnConstant(s, ..) if s == crate::engine::FN_IDX_GET => {
|
||||||
write!(
|
write!(f, "Non-pure indexer cannot be accessed on constant")?
|
||||||
f,
|
|
||||||
"Indexer is not pure and cannot be accessed on a constant"
|
|
||||||
)?
|
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::ErrorNonPureMethodCallOnConstant(s, ..) if s == crate::engine::FN_IDX_SET => {
|
Self::ErrorNonPureMethodCallOnConstant(s, ..) if s == crate::engine::FN_IDX_SET => {
|
||||||
write!(f, "Cannot assign to the indexer of a constant")?
|
write!(f, "Cannot assign to indexer of constant")?
|
||||||
}
|
}
|
||||||
Self::ErrorNonPureMethodCallOnConstant(s, ..) => {
|
Self::ErrorNonPureMethodCallOnConstant(s, ..) => {
|
||||||
write!(f, "Non-pure method '{s}' cannot be called on a constant")?
|
write!(f, "Non-pure method '{s}' cannot be called on constant")?
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant {s}")?,
|
Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant {s}")?,
|
||||||
@ -230,8 +220,8 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorArithmetic(s, ..) if s.is_empty() => f.write_str("Arithmetic error")?,
|
Self::ErrorArithmetic(s, ..) if s.is_empty() => f.write_str("Arithmetic error")?,
|
||||||
Self::ErrorArithmetic(s, ..) => f.write_str(s)?,
|
Self::ErrorArithmetic(s, ..) => f.write_str(s)?,
|
||||||
|
|
||||||
Self::LoopBreak(true, ..) => f.write_str("'break' must be inside a loop")?,
|
Self::LoopBreak(true, ..) => f.write_str("'break' must be within a loop")?,
|
||||||
Self::LoopBreak(false, ..) => f.write_str("'continue' must be inside a loop")?,
|
Self::LoopBreak(false, ..) => f.write_str("'continue' must be within a loop")?,
|
||||||
|
|
||||||
Self::Return(..) => f.write_str("NOT AN ERROR - function returns value")?,
|
Self::Return(..) => f.write_str("NOT AN ERROR - function returns value")?,
|
||||||
|
|
||||||
@ -261,7 +251,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
f,
|
f,
|
||||||
"Bit-field index {index} out of bounds: only {max} bits in bit-field",
|
"Bit-field index {index} out of bounds: only {max} bits in bit-field",
|
||||||
)?,
|
)?,
|
||||||
Self::ErrorDataTooLarge(typ, ..) => write!(f, "{typ} exceeds maximum limit")?,
|
Self::ErrorDataTooLarge(typ, ..) => write!(f, "{typ} too large")?,
|
||||||
|
|
||||||
Self::ErrorCustomSyntax(s, tokens, ..) => write!(f, "{s}: {}", tokens.join(" "))?,
|
Self::ErrorCustomSyntax(s, tokens, ..) => write!(f, "{s}: {}", tokens.join(" "))?,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user