Refine custom syntax.
This commit is contained in:
parent
e49bfebac5
commit
2a8d63fd5f
@ -21,7 +21,7 @@ num-traits = { version = "0.2.11", default-features = false }
|
||||
|
||||
[features]
|
||||
#default = ["unchecked", "sync", "no_optimize", "no_float", "only_i32", "no_index", "no_object", "no_function", "no_module"]
|
||||
default = ["internals"]
|
||||
default = []
|
||||
plugins = []
|
||||
unchecked = [] # unchecked arithmetic
|
||||
sync = [] # restrict to only types that implement Send + Sync
|
||||
|
@ -1,5 +1,5 @@
|
||||
Extending Rhai with Custom Syntax
|
||||
================================
|
||||
Extend Rhai with Custom Syntax
|
||||
=============================
|
||||
|
||||
{{#include ../links.md}}
|
||||
|
||||
@ -131,7 +131,7 @@ Fn(
|
||||
state: &mut State,
|
||||
lib: &Module,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
inputs: &[Expr],
|
||||
inputs: &[Expression],
|
||||
level: usize
|
||||
) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
```
|
||||
@ -144,7 +144,7 @@ where:
|
||||
* `state : &mut State` - mutable reference to the current evaluation state; **do not touch**.
|
||||
* `lib : &Module` - reference to the current collection of script-defined functions.
|
||||
* `this_ptr : &mut Option<&mut Dynamic>` - mutable reference to the current binding of the `this` pointer; **do not touch**.
|
||||
* `inputs : &[Expr]` - a list of input expression trees.
|
||||
* `inputs : &[Expression]` - a list of input expression trees.
|
||||
* `level : usize` - the current function call level.
|
||||
|
||||
There are a lot of parameters, most of which should not be touched or Bad Things Happen™.
|
||||
@ -158,11 +158,11 @@ and statement blocks (`$block$) are provided.
|
||||
|
||||
To access a particular argument, use the following patterns:
|
||||
|
||||
| Argument type | Pattern (`n` = slot in `inputs`) | Result type | Description |
|
||||
| :-----------: | ---------------------------------------- | :---------: | ------------------ |
|
||||
| `$ident$` | `inputs[n].get_variable_name().unwrap()` | `&str` | name of a variable |
|
||||
| `$expr$` | `inputs.get(n).unwrap()` | `Expr` | an expression tree |
|
||||
| `$block$` | `inputs.get(n).unwrap()` | `Expr` | an expression tree |
|
||||
| Argument type | Pattern (`n` = slot in `inputs`) | Result type | Description |
|
||||
| :-----------: | ---------------------------------------- | :----------: | ------------------ |
|
||||
| `$ident$` | `inputs[n].get_variable_name().unwrap()` | `&str` | name of a variable |
|
||||
| `$expr$` | `inputs.get(n).unwrap()` | `Expression` | an expression tree |
|
||||
| `$block$` | `inputs.get(n).unwrap()` | `Expression` | an expression tree |
|
||||
|
||||
### Evaluate an Expression Tree
|
||||
|
||||
@ -213,7 +213,7 @@ fn implementation_func(
|
||||
state: &mut State,
|
||||
lib: &Module,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
inputs: &[Expr],
|
||||
inputs: &[Expression],
|
||||
level: usize
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let var_name = inputs[0].get_variable_name().unwrap().to_string();
|
||||
|
@ -76,9 +76,9 @@ For its evaluation, the callback function will receive the following list of par
|
||||
|
||||
`exprs[0] = "sum"` - math operator
|
||||
`exprs[1] = "price"` - field name
|
||||
`exprs[2] = Expr(table)` - data source
|
||||
`exprs[2] = Expression(table)` - data source
|
||||
`exprs[3] = "row"` - loop variable name
|
||||
`exprs[4] = Expr(row.wright > 50)` - expression
|
||||
`exprs[4] = Expression(row.wright > 50)` - expression
|
||||
|
||||
The other identified, such as `"select"`, `"from"`, as as as symbols `->` and `:` are
|
||||
parsed in the order defined within the custom syntax.
|
||||
|
@ -95,6 +95,36 @@ pub const MARKER_BLOCK: &str = "$block$";
|
||||
#[cfg(feature = "internals")]
|
||||
pub const MARKER_IDENT: &str = "$ident$";
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
pub struct Expression<'a>(&'a Expr);
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
impl<'a> From<&'a Expr> for Expression<'a> {
|
||||
fn from(expr: &'a Expr) -> Self {
|
||||
Self(expr)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
impl Expression<'_> {
|
||||
/// If this expression is a variable name, return it. Otherwise `None`.
|
||||
#[cfg(feature = "internals")]
|
||||
pub fn get_variable_name(&self) -> Option<&str> {
|
||||
match self.0 {
|
||||
Expr::Variable(x) => Some((x.0).0.as_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Get the expression.
|
||||
pub(crate) fn expr(&self) -> &Expr {
|
||||
&self.0
|
||||
}
|
||||
/// Get the position of this expression.
|
||||
pub fn position(&self) -> Position {
|
||||
self.0.position()
|
||||
}
|
||||
}
|
||||
|
||||
/// A type specifying the method of chaining.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
enum ChainType {
|
||||
@ -1691,10 +1721,10 @@ impl Engine {
|
||||
state: &mut State,
|
||||
lib: &Module,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
expr: &Expr,
|
||||
expr: &Expression,
|
||||
level: usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)
|
||||
self.eval_expr(scope, mods, state, lib, this_ptr, expr.expr(), level)
|
||||
}
|
||||
|
||||
/// Evaluate an expression
|
||||
@ -2131,8 +2161,8 @@ impl Engine {
|
||||
#[cfg(feature = "internals")]
|
||||
Expr::Custom(x) => {
|
||||
let func = (x.0).1.as_ref();
|
||||
let exprs = (x.0).0.as_ref();
|
||||
func(self, scope, mods, state, lib, this_ptr, exprs, level)
|
||||
let ep: StaticVec<_> = (x.0).0.iter().map(|e| e.into()).collect();
|
||||
func(self, scope, mods, state, lib, this_ptr, ep.as_ref(), level)
|
||||
}
|
||||
|
||||
_ => unreachable!(),
|
||||
|
@ -169,7 +169,7 @@ pub use parser::{CustomExpr, Expr, ReturnType, ScriptFnDef, Stmt};
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
#[deprecated(note = "this type is volatile and may change")]
|
||||
pub use engine::{Imports, State as EvalState};
|
||||
pub use engine::{Expression, Imports, State as EvalState};
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
#[deprecated(note = "this type is volatile and may change")]
|
||||
|
@ -342,7 +342,11 @@ impl Module {
|
||||
/// Set a Rust function into the module, returning a hash key.
|
||||
///
|
||||
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||
pub(crate) fn set_fn(
|
||||
///
|
||||
/// ## WARNING - Low Level API
|
||||
///
|
||||
/// This function is very low level.
|
||||
pub fn set_fn(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
access: FnAccess,
|
||||
|
@ -908,14 +908,6 @@ impl Expr {
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
pub fn get_variable_name(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Variable(x) => Some((x.0).0.as_str()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume a particular token, checking that it is the expected one.
|
||||
|
@ -2,11 +2,10 @@
|
||||
#![cfg(feature = "internals")]
|
||||
|
||||
use crate::any::Dynamic;
|
||||
use crate::engine::{Engine, Imports, State, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||
use crate::engine::{Engine, Expression, Imports, State, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||
use crate::error::LexError;
|
||||
use crate::fn_native::{SendSync, Shared};
|
||||
use crate::module::Module;
|
||||
use crate::parser::Expr;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::Scope;
|
||||
use crate::token::{is_valid_identifier, Token};
|
||||
@ -28,7 +27,7 @@ pub type FnCustomSyntaxEval = dyn Fn(
|
||||
&mut State,
|
||||
&Module,
|
||||
&mut Option<&mut Dynamic>,
|
||||
&[Expr],
|
||||
&[Expression],
|
||||
usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>>;
|
||||
/// A general function trail object.
|
||||
@ -71,7 +70,7 @@ impl Engine {
|
||||
&mut State,
|
||||
&Module,
|
||||
&mut Option<&mut Dynamic>,
|
||||
&[Expr],
|
||||
&[Expression],
|
||||
usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
+ SendSync
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![cfg(feature = "internals")]
|
||||
use rhai::{
|
||||
Dynamic, Engine, EvalAltResult, EvalState, Expr, Imports, LexError, Module, Scope, INT,
|
||||
Dynamic, Engine, EvalAltResult, EvalState, Expression, Imports, LexError, Module, Scope, INT,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -24,7 +24,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
||||
state: &mut EvalState,
|
||||
lib: &Module,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
inputs: &[Expr],
|
||||
inputs: &[Expression],
|
||||
level: usize| {
|
||||
let var_name = inputs[0].get_variable_name().unwrap().to_string();
|
||||
let stmt = inputs.get(1).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user