Fix bug in custom syntax starting with disabled stardard keyword.
This commit is contained in:
parent
c1b4c81e75
commit
114c93f430
@ -4,6 +4,11 @@ Rhai Release Notes
|
|||||||
Version 1.1.0
|
Version 1.1.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Custom syntax starting with a disabled standard keyword now works properly.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -16,6 +21,7 @@ Enhancements
|
|||||||
* `parse_float()`, `PI()` and `E()` now defer to `Decimal` under `no_float` if `decimal` is turned on.
|
* `parse_float()`, `PI()` and `E()` now defer to `Decimal` under `no_float` if `decimal` is turned on.
|
||||||
* Added `log10()` for `Decimal`.
|
* Added `log10()` for `Decimal`.
|
||||||
* `ln` for `Decimal` is now checked and won't panic.
|
* `ln` for `Decimal` is now checked and won't panic.
|
||||||
|
* `Scope::set_value` now takes anything that implements `Into<Cow<str>>`.
|
||||||
|
|
||||||
|
|
||||||
Version 1.0.2
|
Version 1.0.2
|
||||||
|
@ -230,11 +230,10 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
s.into()
|
s.into()
|
||||||
}
|
}
|
||||||
// Standard keyword in first position
|
// Standard keyword in first position but not disabled
|
||||||
s if segments.is_empty()
|
_ if segments.is_empty()
|
||||||
&& token
|
&& token.as_ref().map_or(false, |v| v.is_standard_keyword())
|
||||||
.as_ref()
|
&& !self.disabled_symbols.contains(s) =>
|
||||||
.map_or(false, |v| v.is_standard_keyword() || v.is_reserved()) =>
|
|
||||||
{
|
{
|
||||||
return Err(LexError::ImproperSymbol(
|
return Err(LexError::ImproperSymbol(
|
||||||
s.to_string(),
|
s.to_string(),
|
||||||
@ -247,14 +246,14 @@ impl Engine {
|
|||||||
.into_err(Position::NONE));
|
.into_err(Position::NONE));
|
||||||
}
|
}
|
||||||
// Identifier in first position
|
// Identifier in first position
|
||||||
s if segments.is_empty() && is_valid_identifier(s.chars()) => {
|
_ if segments.is_empty() && is_valid_identifier(s.chars()) => {
|
||||||
// Make it a custom keyword/symbol if it is disabled or reserved
|
// Make it a custom keyword/symbol if it is disabled or reserved
|
||||||
if (self.disabled_symbols.contains(s)
|
if self.disabled_symbols.contains(s) || token.map_or(false, |v| v.is_reserved())
|
||||||
|| matches!(token, Some(Token::Reserved(_))))
|
|
||||||
&& !self.custom_keywords.contains_key(s)
|
|
||||||
{
|
{
|
||||||
|
if !self.custom_keywords.contains_key(s) {
|
||||||
self.custom_keywords.insert(s.into(), None);
|
self.custom_keywords.insert(s.into(), None);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s.into()
|
s.into()
|
||||||
}
|
}
|
||||||
// Anything else is an error
|
// Anything else is an error
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use rhai::{
|
use rhai::{
|
||||||
Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseErrorType, Position, INT,
|
Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseErrorType, Position, Scope, INT,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -146,6 +146,42 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(engine.eval::<INT>("test2 } 42")?, 42);
|
assert_eq!(engine.eval::<INT>("test2 } 42")?, 42);
|
||||||
assert_eq!(engine.eval::<INT>("test3; 42")?, 42);
|
assert_eq!(engine.eval::<INT>("test3; 42")?, 42);
|
||||||
|
|
||||||
|
// Register the custom syntax: var x = ???
|
||||||
|
engine.register_custom_syntax(
|
||||||
|
&["var", "$ident$", "=", "$expr$"],
|
||||||
|
true,
|
||||||
|
|context, inputs| {
|
||||||
|
let var_name = inputs[0].get_variable_name().unwrap().to_string();
|
||||||
|
let expr = &inputs[1];
|
||||||
|
|
||||||
|
// Evaluate the expression
|
||||||
|
let value = context.eval_expression_tree(expr)?;
|
||||||
|
|
||||||
|
// Push new variable into the scope if it doesn't already exist.
|
||||||
|
// Otherwise set its value.
|
||||||
|
// WARNING - This panics if 'var_name' already exists and is constant!
|
||||||
|
// - In a real implementation, check this before doing anything!
|
||||||
|
context.scope_mut().set_value(var_name, value);
|
||||||
|
|
||||||
|
Ok(Dynamic::UNIT)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval_with_scope::<INT>(&mut scope, "var foo = 42; foo")?,
|
||||||
|
42
|
||||||
|
);
|
||||||
|
assert_eq!(scope.get_value::<INT>("foo"), Some(42));
|
||||||
|
assert_eq!(scope.len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval_with_scope::<INT>(&mut scope, "var foo = 123; foo")?,
|
||||||
|
123
|
||||||
|
);
|
||||||
|
assert_eq!(scope.get_value::<INT>("foo"), Some(123));
|
||||||
|
assert_eq!(scope.len(), 1);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user