Remove Option from source and use empty string as no source.
This commit is contained in:
parent
8329baea29
commit
135b1f54c2
@ -209,9 +209,8 @@ impl Engine {
|
||||
level: usize,
|
||||
) -> RhaiResult {
|
||||
let mut state = EvalState::new();
|
||||
if ast.source_raw().is_some() {
|
||||
global.source = ast.source_raw().cloned();
|
||||
}
|
||||
global.source = ast.source_raw().clone();
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
{
|
||||
global.embedded_module_resolver = ast.resolver().cloned();
|
||||
|
@ -46,9 +46,8 @@ impl Engine {
|
||||
pub fn run_ast_with_scope(&self, scope: &mut Scope, ast: &AST) -> RhaiResultOf<()> {
|
||||
let global = &mut GlobalRuntimeState::new();
|
||||
let mut state = EvalState::new();
|
||||
if ast.source_raw().is_some() {
|
||||
global.source = ast.source_raw().cloned();
|
||||
}
|
||||
global.source = ast.source_raw().clone();
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
{
|
||||
global.embedded_module_resolver = ast.resolver().cloned();
|
||||
|
@ -17,7 +17,8 @@ use std::{
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AST {
|
||||
/// Source of the [`AST`].
|
||||
source: Option<Identifier>,
|
||||
/// No source if string is empty.
|
||||
source: Identifier,
|
||||
/// Global statements.
|
||||
body: StmtBlock,
|
||||
/// Script-defined functions.
|
||||
@ -45,7 +46,7 @@ impl AST {
|
||||
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::Shared<crate::Module>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
body: StmtBlock::new(statements, Position::NONE),
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
functions: functions.into(),
|
||||
@ -63,7 +64,7 @@ impl AST {
|
||||
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::Shared<crate::Module>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
body: StmtBlock::new(statements, Position::NONE),
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
functions: functions.into(),
|
||||
@ -111,7 +112,7 @@ impl AST {
|
||||
#[must_use]
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
body: StmtBlock::NONE,
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
functions: crate::Module::new().into(),
|
||||
@ -123,13 +124,17 @@ impl AST {
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn source(&self) -> Option<&str> {
|
||||
self.source.as_ref().map(|s| s.as_str())
|
||||
if self.source.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(&self.source)
|
||||
}
|
||||
}
|
||||
/// Get a reference to the source.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub(crate) fn source_raw(&self) -> Option<&Identifier> {
|
||||
self.source.as_ref()
|
||||
pub(crate) fn source_raw(&self) -> &Identifier {
|
||||
&self.source
|
||||
}
|
||||
/// Set the source.
|
||||
#[inline]
|
||||
@ -139,13 +144,13 @@ impl AST {
|
||||
crate::Shared::get_mut(&mut self.functions)
|
||||
.as_mut()
|
||||
.map(|m| m.set_id(source.clone()));
|
||||
self.source = Some(source);
|
||||
self.source = source;
|
||||
self
|
||||
}
|
||||
/// Clear the source.
|
||||
#[inline(always)]
|
||||
pub fn clear_source(&mut self) -> &mut Self {
|
||||
self.source = None;
|
||||
self.source.clear();
|
||||
self
|
||||
}
|
||||
/// Get the statements.
|
||||
@ -467,8 +472,6 @@ impl AST {
|
||||
(true, true) => StmtBlock::NONE,
|
||||
};
|
||||
|
||||
let source = other.source.clone().or_else(|| self.source.clone());
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
let functions = {
|
||||
let mut functions = self.functions.as_ref().clone();
|
||||
@ -476,12 +479,12 @@ impl AST {
|
||||
functions
|
||||
};
|
||||
|
||||
if let Some(source) = source {
|
||||
if !other.source.is_empty() {
|
||||
Self::new_with_source(
|
||||
merged,
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
functions,
|
||||
source,
|
||||
other.source.clone(),
|
||||
)
|
||||
} else {
|
||||
Self::new(
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use crate::api::custom_syntax::CustomSyntax;
|
||||
use crate::ast::{Expr, FnCallExpr, Ident, OpAssignment, Stmt, AST_OPTION_FLAGS::*};
|
||||
use crate::func::call::FnResolutionCache;
|
||||
use crate::func::native::{OnDebugCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback};
|
||||
use crate::func::{get_hasher, CallableFunction, IteratorFn};
|
||||
use crate::module::Namespace;
|
||||
@ -507,7 +508,8 @@ pub struct GlobalRuntimeState {
|
||||
/// Stack of imported [modules][Module].
|
||||
modules: StaticVec<Shared<Module>>,
|
||||
/// Source of the current context.
|
||||
pub source: Option<Identifier>,
|
||||
/// No source if the string is empty.
|
||||
pub source: Identifier,
|
||||
/// Number of operations performed.
|
||||
pub num_operations: u64,
|
||||
/// Number of modules loaded.
|
||||
@ -539,7 +541,7 @@ impl GlobalRuntimeState {
|
||||
Self {
|
||||
keys: StaticVec::new_const(),
|
||||
modules: StaticVec::new_const(),
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
num_operations: 0,
|
||||
num_modules_loaded: 0,
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
@ -629,11 +631,11 @@ impl GlobalRuntimeState {
|
||||
/// Get the specified function via its hash key from the stack of globally-imported [modules][Module].
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&Identifier>)> {
|
||||
pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&str>)> {
|
||||
self.modules
|
||||
.iter()
|
||||
.rev()
|
||||
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
||||
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id())))
|
||||
}
|
||||
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in the stack of
|
||||
/// globally-imported [modules][Module]?
|
||||
@ -746,20 +748,6 @@ impl fmt::Debug for GlobalRuntimeState {
|
||||
}
|
||||
}
|
||||
|
||||
/// _(internals)_ An entry in a function resolution cache.
|
||||
/// Exported under the `internals` feature only.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FnResolutionCacheEntry {
|
||||
/// Function.
|
||||
pub func: CallableFunction,
|
||||
/// Optional source.
|
||||
pub source: Option<Box<str>>,
|
||||
}
|
||||
|
||||
/// _(internals)_ A function resolution cache.
|
||||
/// Exported under the `internals` feature only.
|
||||
pub type FnResolutionCache = BTreeMap<u64, Option<Box<FnResolutionCacheEntry>>>;
|
||||
|
||||
/// _(internals)_ A type that holds all the current states of the [`Engine`].
|
||||
/// Exported under the `internals` feature only.
|
||||
#[derive(Debug, Clone)]
|
||||
@ -844,7 +832,11 @@ impl<'x, 'px, 'pt> EvalContext<'_, 'x, 'px, '_, '_, '_, '_, 'pt> {
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn source(&self) -> Option<&str> {
|
||||
self.global.source.as_ref().map(|s| s.as_str())
|
||||
if self.global.source.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(&self.global.source)
|
||||
}
|
||||
}
|
||||
/// The current [`Scope`].
|
||||
#[inline(always)]
|
||||
@ -3041,8 +3033,8 @@ impl Engine {
|
||||
|
||||
err_map.insert("message".into(), err.to_string().into());
|
||||
|
||||
if let Some(ref source) = global.source {
|
||||
err_map.insert("source".into(), source.as_str().into());
|
||||
if !global.source.is_empty() {
|
||||
err_map.insert("source".into(), global.source.clone().into());
|
||||
}
|
||||
|
||||
if err_pos.is_none() {
|
||||
@ -3174,7 +3166,11 @@ impl Engine {
|
||||
{
|
||||
use crate::ModuleResolver;
|
||||
|
||||
let source = global.source.as_ref().map(|s| s.as_str());
|
||||
let source = if global.source.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(global.source.as_str())
|
||||
};
|
||||
let path_pos = expr.position();
|
||||
|
||||
let module = global
|
||||
|
@ -6,9 +6,8 @@ use super::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn};
|
||||
use crate::api::default_limits::MAX_DYNAMIC_PARAMETERS;
|
||||
use crate::ast::{Expr, FnCallHashes, Stmt};
|
||||
use crate::engine::{
|
||||
EvalState, FnResolutionCacheEntry, GlobalRuntimeState, KEYWORD_DEBUG, KEYWORD_EVAL,
|
||||
KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT,
|
||||
KEYWORD_TYPE_OF,
|
||||
EvalState, GlobalRuntimeState, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
|
||||
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
||||
};
|
||||
use crate::module::Namespace;
|
||||
use crate::tokenizer::Token;
|
||||
@ -20,6 +19,7 @@ use crate::{
|
||||
use std::prelude::v1::*;
|
||||
use std::{
|
||||
any::{type_name, TypeId},
|
||||
collections::BTreeMap,
|
||||
convert::TryFrom,
|
||||
mem,
|
||||
};
|
||||
@ -125,6 +125,24 @@ pub fn ensure_no_data_race(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// _(internals)_ An entry in a function resolution cache.
|
||||
/// Exported under the `internals` feature only.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FnResolutionCacheEntry {
|
||||
/// Function.
|
||||
pub func: CallableFunction,
|
||||
/// Optional source.
|
||||
/// No source if the string is empty.
|
||||
pub source: Identifier,
|
||||
}
|
||||
|
||||
/// _(internals)_ A function resolution cache.
|
||||
/// Exported under the `internals` feature only.
|
||||
///
|
||||
/// [`FnResolutionCacheEntry`] is [`Box`]ed in order to pack as many entries inside a single B-Tree
|
||||
/// level as possible.
|
||||
pub type FnResolutionCache = BTreeMap<u64, Option<Box<FnResolutionCacheEntry>>>;
|
||||
|
||||
impl Engine {
|
||||
/// Generate the signature for a function call.
|
||||
#[inline]
|
||||
@ -206,14 +224,14 @@ impl Engine {
|
||||
.find_map(|m| {
|
||||
m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
|
||||
func,
|
||||
source: m.id_raw().map(|s| s.to_string().into_boxed_str()),
|
||||
source: m.id_raw().clone(),
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
self.global_modules.iter().find_map(|m| {
|
||||
m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
|
||||
func,
|
||||
source: m.id_raw().map(|s| s.to_string().into_boxed_str()),
|
||||
source: m.id_raw().clone(),
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -222,7 +240,8 @@ impl Engine {
|
||||
.get_fn(hash)
|
||||
.map(|(func, source)| FnResolutionCacheEntry {
|
||||
func: func.clone(),
|
||||
source: source.map(|s| s.to_string().into_boxed_str()),
|
||||
source: source
|
||||
.map_or_else(|| Identifier::new_const(), Into::into),
|
||||
})
|
||||
})
|
||||
.or_else(|| {
|
||||
@ -230,7 +249,7 @@ impl Engine {
|
||||
m.get_qualified_fn(hash).cloned().map(|func| {
|
||||
FnResolutionCacheEntry {
|
||||
func,
|
||||
source: m.id_raw().map(|s| s.to_string().into_boxed_str()),
|
||||
source: m.id_raw().clone(),
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -253,7 +272,7 @@ impl Engine {
|
||||
func: CallableFunction::from_method(
|
||||
Box::new(f) as Box<FnAny>
|
||||
),
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -265,7 +284,7 @@ impl Engine {
|
||||
func: CallableFunction::from_method(
|
||||
Box::new(f) as Box<FnAny>
|
||||
),
|
||||
source: None,
|
||||
source: Identifier::new_const(),
|
||||
})
|
||||
}
|
||||
.map(Box::new)
|
||||
@ -353,10 +372,15 @@ impl Engine {
|
||||
}
|
||||
|
||||
// Run external function
|
||||
let source = source
|
||||
.as_ref()
|
||||
.map(|s| &**s)
|
||||
.or_else(|| parent_source.as_ref().map(|s| s.as_str()));
|
||||
let source = if source.is_empty() {
|
||||
if parent_source.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(parent_source.as_str())
|
||||
}
|
||||
} else {
|
||||
Some(source.as_str())
|
||||
};
|
||||
|
||||
let context = (self, name, source, &*global, lib, pos).into();
|
||||
|
||||
@ -400,7 +424,11 @@ impl Engine {
|
||||
pos,
|
||||
)
|
||||
})?;
|
||||
let source = global.source.as_ref().map(|s| s.as_str());
|
||||
let source = if global.source.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(global.source.as_str())
|
||||
};
|
||||
(debug(&text, source, pos).into(), false)
|
||||
} else {
|
||||
(Dynamic::UNIT, false)
|
||||
@ -572,7 +600,7 @@ impl Engine {
|
||||
|
||||
// Script-defined function call?
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
if let Some(FnResolutionCacheEntry { func, source }) = self
|
||||
if let Some(FnResolutionCacheEntry { func, mut source }) = self
|
||||
.resolve_fn(
|
||||
global,
|
||||
state,
|
||||
@ -603,13 +631,12 @@ impl Engine {
|
||||
}
|
||||
};
|
||||
|
||||
mem::swap(&mut global.source, &mut source);
|
||||
|
||||
let result = if _is_method_call {
|
||||
// Method call of script function - map first argument to `this`
|
||||
let (first_arg, rest_args) = args.split_first_mut().expect("not empty");
|
||||
|
||||
let orig_source = global.source.take();
|
||||
global.source = source.map(Into::into);
|
||||
|
||||
let level = _level + 1;
|
||||
|
||||
let result = self.call_script_fn(
|
||||
@ -625,9 +652,6 @@ impl Engine {
|
||||
level,
|
||||
);
|
||||
|
||||
// Restore the original source
|
||||
global.source = orig_source;
|
||||
|
||||
result?
|
||||
} else {
|
||||
// Normal call of script function
|
||||
@ -641,18 +665,12 @@ impl Engine {
|
||||
.change_first_arg_to_copy(args);
|
||||
}
|
||||
|
||||
let orig_source = global.source.take();
|
||||
global.source = source.map(Into::into);
|
||||
|
||||
let level = _level + 1;
|
||||
|
||||
let result = self.call_script_fn(
|
||||
scope, global, state, lib, &mut None, func, args, pos, true, level,
|
||||
);
|
||||
|
||||
// Restore the original source
|
||||
global.source = orig_source;
|
||||
|
||||
// Restore the original reference
|
||||
if let Some(bk) = backup {
|
||||
bk.restore_first_arg(args)
|
||||
@ -661,6 +679,9 @@ impl Engine {
|
||||
result?
|
||||
};
|
||||
|
||||
// Restore the original source
|
||||
mem::swap(&mut global.source, &mut source);
|
||||
|
||||
return Ok((result, false));
|
||||
}
|
||||
|
||||
@ -1058,11 +1079,7 @@ impl Engine {
|
||||
return result.map_err(|err| {
|
||||
ERR::ErrorInFunctionCall(
|
||||
KEYWORD_EVAL.to_string(),
|
||||
global
|
||||
.source
|
||||
.as_ref()
|
||||
.map(Identifier::to_string)
|
||||
.unwrap_or_default(),
|
||||
global.source.to_string(),
|
||||
err,
|
||||
pos,
|
||||
)
|
||||
@ -1265,7 +1282,7 @@ impl Engine {
|
||||
} else {
|
||||
let new_scope = &mut Scope::new();
|
||||
|
||||
let mut source = module.id_raw().cloned();
|
||||
let mut source = module.id_raw().clone();
|
||||
mem::swap(&mut global.source, &mut source);
|
||||
|
||||
let level = level + 1;
|
||||
|
@ -90,7 +90,7 @@ impl<'a, M: AsRef<[&'a Module]> + ?Sized, S: AsRef<str> + 'a + ?Sized>
|
||||
Self {
|
||||
engine: value.0,
|
||||
fn_name: value.1.as_ref(),
|
||||
source: value.2.map(|v| v.as_ref()),
|
||||
source: value.2.map(S::as_ref),
|
||||
global: Some(value.3),
|
||||
lib: value.4.as_ref(),
|
||||
pos: value.5,
|
||||
@ -156,7 +156,7 @@ impl<'a> NativeCallContext<'a> {
|
||||
Self {
|
||||
engine,
|
||||
fn_name: fn_name.as_ref(),
|
||||
source: source.map(|v| v.as_ref()),
|
||||
source: source.map(S::as_ref),
|
||||
global: Some(global),
|
||||
lib,
|
||||
pos,
|
||||
|
@ -47,9 +47,8 @@ impl Engine {
|
||||
fn_def
|
||||
.lib
|
||||
.as_ref()
|
||||
.and_then(|m| m.id().map(|id| id.to_string()))
|
||||
.or_else(|| global.source.as_ref().map(|s| s.to_string()))
|
||||
.unwrap_or_default(),
|
||||
.and_then(|m| m.id().map(str::to_string))
|
||||
.unwrap_or_else(|| global.source.to_string()),
|
||||
err,
|
||||
pos,
|
||||
)
|
||||
|
@ -247,7 +247,10 @@ pub use ast::{
|
||||
pub use ast::FloatWrapper;
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
pub use engine::{EvalState, FnResolutionCache, FnResolutionCacheEntry, GlobalRuntimeState};
|
||||
pub use engine::{EvalState, GlobalRuntimeState};
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
pub use func::call::{FnResolutionCache, FnResolutionCacheEntry};
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
pub use module::Namespace;
|
||||
|
@ -131,7 +131,8 @@ pub fn calc_native_fn_hash(
|
||||
#[derive(Clone)]
|
||||
pub struct Module {
|
||||
/// ID identifying the module.
|
||||
id: Option<Identifier>,
|
||||
/// No ID if string is empty.
|
||||
id: Identifier,
|
||||
/// Is this module internal?
|
||||
pub(crate) internal: bool,
|
||||
/// Is this module part of a standard library?
|
||||
@ -170,8 +171,9 @@ impl fmt::Debug for Module {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut d = f.debug_struct("Module");
|
||||
|
||||
self.id.as_ref().map(|id| d.field("id", id));
|
||||
|
||||
if !self.id.is_empty() {
|
||||
d.field("id", &self.id);
|
||||
}
|
||||
if !self.modules.is_empty() {
|
||||
d.field(
|
||||
"modules",
|
||||
@ -241,7 +243,7 @@ impl Module {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: None,
|
||||
id: Identifier::new_const(),
|
||||
internal: false,
|
||||
standard: false,
|
||||
modules: BTreeMap::new(),
|
||||
@ -270,18 +272,24 @@ impl Module {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn id(&self) -> Option<&str> {
|
||||
self.id_raw().map(|s| s.as_str())
|
||||
if self.id_raw().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.id_raw())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the ID of the [`Module`] as an [`Identifier`], if any.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub(crate) const fn id_raw(&self) -> Option<&Identifier> {
|
||||
self.id.as_ref()
|
||||
pub(crate) const fn id_raw(&self) -> &Identifier {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// Set the ID of the [`Module`].
|
||||
///
|
||||
/// If the string is empty, it is equivalent to clearing the ID.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -292,7 +300,7 @@ impl Module {
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_id(&mut self, id: impl Into<Identifier>) -> &mut Self {
|
||||
self.id = Some(id.into());
|
||||
self.id = id.into();
|
||||
self
|
||||
}
|
||||
/// Clear the ID of the [`Module`].
|
||||
@ -309,7 +317,7 @@ impl Module {
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn clear_id(&mut self) -> &mut Self {
|
||||
self.id = None;
|
||||
self.id.clear();
|
||||
self
|
||||
}
|
||||
|
||||
@ -1616,11 +1624,7 @@ impl Module {
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(s) = ast.source_raw() {
|
||||
module.set_id(s.clone());
|
||||
} else {
|
||||
module.clear_id();
|
||||
}
|
||||
module.set_id(ast.source_raw().clone());
|
||||
|
||||
module.build_index();
|
||||
|
||||
|
@ -80,21 +80,21 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", ast),
|
||||
"AST { source: None, body: Block[Expr(123 @ 1:53)], functions: Module, resolver: None }"
|
||||
"AST { source: \"\", body: Block[Expr(123 @ 1:53)], functions: Module, resolver: None }"
|
||||
);
|
||||
|
||||
let ast = engine.compile("const DECISION = false; if DECISION { 42 } else { 123 }")?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", ast),
|
||||
r#"AST { source: None, body: Block[Var(false @ 1:18, "DECISION" @ 1:7, (Constant), 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"#
|
||||
r#"AST { source: "", body: Block[Var(false @ 1:18, "DECISION" @ 1:7, (Constant), 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"#
|
||||
);
|
||||
|
||||
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", ast),
|
||||
"AST { source: None, body: Block[], functions: Module, resolver: None }"
|
||||
"AST { source: \"\", body: Block[], functions: Module, resolver: None }"
|
||||
);
|
||||
|
||||
engine.set_optimization_level(OptimizationLevel::Full);
|
||||
@ -103,7 +103,7 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
||||
|
||||
assert_eq!(
|
||||
format!("{:?}", ast),
|
||||
"AST { source: None, body: Block[Expr(42 @ 1:1)], functions: Module, resolver: None }"
|
||||
"AST { source: \"\", body: Block[Expr(42 @ 1:1)], functions: Module, resolver: None }"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user