Allow initialization of EvalState tag and separate debugger state into separate variable.
This commit is contained in:
parent
5435fdb8c8
commit
1abec0a8a8
@ -21,6 +21,8 @@ Enhancements
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
* `EvalAltResult::IndexNotFound` is added to aid in raising errors for indexers.
|
* `EvalAltResult::IndexNotFound` is added to aid in raising errors for indexers.
|
||||||
|
* `Engine::def_tag`, `Engine::def_tag_mut` and `Engine::set_tag` are added to manage a default value for the custom evaluation state, accessible via `EvalState::tag()` (which is the same as `NativeCallContext::tag()`).
|
||||||
|
* Originally, the debugger's custom state uses the same state as `EvalState::tag()` (which is the same as `NativeCallContext::tag()`). It is now split into its own variable accessible under `Debugger::state()`.
|
||||||
|
|
||||||
|
|
||||||
Version 1.7.0
|
Version 1.7.0
|
||||||
|
@ -201,7 +201,7 @@ impl Engine {
|
|||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
scripts: impl AsRef<[S]>,
|
scripts: impl AsRef<[S]>,
|
||||||
) -> ParseResult<AST> {
|
) -> ParseResult<AST> {
|
||||||
self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level)
|
self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level())
|
||||||
}
|
}
|
||||||
/// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level.
|
/// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level.
|
||||||
///
|
///
|
||||||
@ -292,6 +292,6 @@ impl Engine {
|
|||||||
|
|
||||||
let mut peekable = stream.peekable();
|
let mut peekable = stream.peekable();
|
||||||
let mut state = ParseState::new(self, scope, tokenizer_control);
|
let mut state = ParseState::new(self, scope, tokenizer_control);
|
||||||
self.parse_global_expr(&mut peekable, &mut state, self.optimization_level)
|
self.parse_global_expr(&mut peekable, &mut state, self.optimization_level())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ impl Engine {
|
|||||||
let ast = self.compile_with_scope_and_optimization_level(
|
let ast = self.compile_with_scope_and_optimization_level(
|
||||||
scope,
|
scope,
|
||||||
&[script],
|
&[script],
|
||||||
self.optimization_level,
|
self.optimization_level(),
|
||||||
)?;
|
)?;
|
||||||
self.eval_ast_with_scope(scope, &ast)
|
self.eval_ast_with_scope(scope, &ast)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub mod deprecated;
|
|||||||
|
|
||||||
use crate::engine::Precedence;
|
use crate::engine::Precedence;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::{Engine, Identifier};
|
use crate::{Dynamic, Engine, Identifier};
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -195,4 +195,23 @@ impl Engine {
|
|||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the default value of the custom state for each evaluation run.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn default_tag(&self) -> &Dynamic {
|
||||||
|
&self.def_tag
|
||||||
|
}
|
||||||
|
/// Get a mutable reference to the default value of the custom state for each evaluation run.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn default_tag_mut(&mut self) -> &mut Dynamic {
|
||||||
|
&mut self.def_tag
|
||||||
|
}
|
||||||
|
/// Set the default value of the custom state for each evaluation run.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn set_default_tag(&mut self, value: impl Into<Dynamic>) -> &mut Self {
|
||||||
|
self.def_tag = value.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,11 @@ impl Engine {
|
|||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(Box::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(Box::as_ref));
|
||||||
let mut state = ParseState::new(self, scope, tokenizer_control);
|
let mut state = ParseState::new(self, scope, tokenizer_control);
|
||||||
|
|
||||||
let ast = self.parse(&mut stream.peekable(), &mut state, self.optimization_level)?;
|
let ast = self.parse(
|
||||||
|
&mut stream.peekable(),
|
||||||
|
&mut state,
|
||||||
|
self.optimization_level(),
|
||||||
|
)?;
|
||||||
|
|
||||||
self.run_ast_with_scope(scope, &ast)
|
self.run_ast_with_scope(scope, &ast)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,12 @@ fn print_current_source(
|
|||||||
lines: &[String],
|
lines: &[String],
|
||||||
window: (usize, usize),
|
window: (usize, usize),
|
||||||
) {
|
) {
|
||||||
let current_source = &mut *context.tag_mut().write_lock::<ImmutableString>().unwrap();
|
let current_source = &mut *context
|
||||||
|
.global_runtime_state_mut()
|
||||||
|
.debugger
|
||||||
|
.state_mut()
|
||||||
|
.write_lock::<ImmutableString>()
|
||||||
|
.unwrap();
|
||||||
let src = source.unwrap_or("");
|
let src = source.unwrap_or("");
|
||||||
if src != current_source {
|
if src != current_source {
|
||||||
println!(
|
println!(
|
||||||
|
@ -132,8 +132,11 @@ pub struct Engine {
|
|||||||
/// Language options.
|
/// Language options.
|
||||||
pub(crate) options: LangOptions,
|
pub(crate) options: LangOptions,
|
||||||
|
|
||||||
|
/// Default value for the custom state.
|
||||||
|
pub(crate) def_tag: Dynamic,
|
||||||
|
|
||||||
/// Script optimization level.
|
/// Script optimization level.
|
||||||
pub optimization_level: OptimizationLevel,
|
pub(crate) optimization_level: OptimizationLevel,
|
||||||
|
|
||||||
/// Max limits.
|
/// Max limits.
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -280,6 +283,8 @@ impl Engine {
|
|||||||
|
|
||||||
options: LangOptions::new(),
|
options: LangOptions::new(),
|
||||||
|
|
||||||
|
def_tag: Dynamic::UNIT,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
optimization_level: OptimizationLevel::Simple,
|
optimization_level: OptimizationLevel::Simple,
|
||||||
#[cfg(feature = "no_optimize")]
|
#[cfg(feature = "no_optimize")]
|
||||||
|
@ -253,17 +253,20 @@ pub struct Debugger {
|
|||||||
break_points: Vec<BreakPoint>,
|
break_points: Vec<BreakPoint>,
|
||||||
/// The current function call stack.
|
/// The current function call stack.
|
||||||
call_stack: Vec<CallStackFrame>,
|
call_stack: Vec<CallStackFrame>,
|
||||||
|
/// The current state.
|
||||||
|
state: Dynamic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debugger {
|
impl Debugger {
|
||||||
/// Create a new [`Debugger`].
|
/// Create a new [`Debugger`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(status: DebuggerStatus) -> Self {
|
pub fn new(status: DebuggerStatus, state: Dynamic) -> Self {
|
||||||
Self {
|
Self {
|
||||||
status,
|
status,
|
||||||
break_points: Vec::new(),
|
break_points: Vec::new(),
|
||||||
call_stack: Vec::new(),
|
call_stack: Vec::new(),
|
||||||
|
state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the current call stack.
|
/// Get the current call stack.
|
||||||
@ -374,6 +377,23 @@ impl Debugger {
|
|||||||
pub fn break_points_mut(&mut self) -> &mut Vec<BreakPoint> {
|
pub fn break_points_mut(&mut self) -> &mut Vec<BreakPoint> {
|
||||||
&mut self.break_points
|
&mut self.break_points
|
||||||
}
|
}
|
||||||
|
/// Get the custom state.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn state(&self) -> &Dynamic {
|
||||||
|
&self.state
|
||||||
|
}
|
||||||
|
/// Get a mutable reference to the custom state.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn state_mut(&mut self) -> &mut Dynamic {
|
||||||
|
&mut self.state
|
||||||
|
}
|
||||||
|
/// Set the custom state.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn set_state(&mut self, state: impl Into<Dynamic>) {
|
||||||
|
self.state = state.into();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
|
@ -78,8 +78,6 @@ impl GlobalRuntimeState<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(engine: &Engine) -> Self {
|
pub fn new(engine: &Engine) -> Self {
|
||||||
let _engine = engine;
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
keys: crate::StaticVec::new_const(),
|
keys: crate::StaticVec::new_const(),
|
||||||
@ -98,21 +96,21 @@ impl GlobalRuntimeState<'_> {
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
constants: None,
|
constants: None,
|
||||||
|
|
||||||
#[cfg(not(feature = "debugging"))]
|
tag: engine.default_tag().clone(),
|
||||||
tag: Dynamic::UNIT,
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
tag: if let Some((ref init, ..)) = engine.debugger {
|
debugger: crate::eval::Debugger::new(
|
||||||
|
if engine.debugger.is_some() {
|
||||||
|
crate::eval::DebuggerStatus::Init
|
||||||
|
} else {
|
||||||
|
crate::eval::DebuggerStatus::CONTINUE
|
||||||
|
},
|
||||||
|
if let Some((ref init, ..)) = engine.debugger {
|
||||||
init()
|
init()
|
||||||
} else {
|
} else {
|
||||||
Dynamic::UNIT
|
Dynamic::UNIT
|
||||||
},
|
},
|
||||||
|
),
|
||||||
#[cfg(feature = "debugging")]
|
|
||||||
debugger: crate::eval::Debugger::new(if engine.debugger.is_some() {
|
|
||||||
crate::eval::DebuggerStatus::Init
|
|
||||||
} else {
|
|
||||||
crate::eval::DebuggerStatus::CONTINUE
|
|
||||||
}),
|
|
||||||
|
|
||||||
dummy: PhantomData::default(),
|
dummy: PhantomData::default(),
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,18 @@ fn test_debugger_state() -> Result<(), Box<EvalAltResult>> {
|
|||||||
},
|
},
|
||||||
|mut context, _, _, _, _| {
|
|mut context, _, _, _, _| {
|
||||||
// Print debugger state - which is an object map
|
// Print debugger state - which is an object map
|
||||||
println!("Current state = {}", context.tag());
|
println!(
|
||||||
|
"Current state = {}",
|
||||||
|
context.global_runtime_state_mut().debugger.state()
|
||||||
|
);
|
||||||
|
|
||||||
// Modify state
|
// Modify state
|
||||||
let mut state = context.tag_mut().write_lock::<Map>().unwrap();
|
let mut state = context
|
||||||
|
.global_runtime_state_mut()
|
||||||
|
.debugger
|
||||||
|
.state_mut()
|
||||||
|
.write_lock::<Map>()
|
||||||
|
.unwrap();
|
||||||
let hello = state.get("hello").unwrap().as_int().unwrap();
|
let hello = state.get("hello").unwrap().as_int().unwrap();
|
||||||
state.insert("hello".into(), (hello + 1).into());
|
state.insert("hello".into(), (hello + 1).into());
|
||||||
state.insert("foo".into(), true.into());
|
state.insert("foo".into(), true.into());
|
||||||
|
Loading…
Reference in New Issue
Block a user