[−][src]Macro glsp_proc_macros2::eval
eval!() { /* proc-macro */ }
A convenient way to evaluate simple GameLisp code.
The input must be a single string literal which represents zero or more valid GameLisp forms.
Those forms are evaluated in order, and the final form's result is returned. The return type is
a generic GResult<T>
for any T
which implements
FromVal
- you will usually need to bind it to a local variable with
an explicit type.
let result: Root<Arr> = eval!(r#" (let n (+ 1 2 3 4)) (arr n n n) "#)?;
Rust's local variables can be captured, and/or mutated, using the
unquote
form (abbreviated as ~
).
They are copied into the form using the ToVal
trait.
If they're mutated using the =
form, then
the local variables' values are updated when eval!()
returns, using the
FromVal
trait.
let input = 100_i64; let mut output = "hello".to_string(); let assigned_but_not_read: f32; let result: Val = eval!(r#" (= ~output (str ~input)) (= ~assigned_but_not_read 100.0) "#)?;
Some Rust collection types, such as tuples, slices, Strings
and HashMaps
, will allocate
a new GameLisp array, string or table when captured as a local variable. This is potentially
expensive, especially for large collections. Also, if the resulting collection is mutated,
those changes are not usually copied back into the local variable when eval!()
returns.
let rust_tuple = (60_u8, 120_u16, 240_u32); let glsp_arr = arr![60_u8, 120_u16, 240_u32]; let _: Val = eval!(r#" (= [~rust_tuple 2] 480) (= [~glsp_arr 2] 480) "#)?; //rust collection types make a copy, but glsp collection types are passed in by reference assert!(rust_tuple.2 == 240); assert!(glsp_arr.get::<u32>(2)? == 480);
eval!()
is much faster than GameLisp's own (eval)
function,
because its body is compiled in advance. The first time each eval!()
is executed, it has a
small lazy-initialization cost (usually less than 0.1 milliseconds for small inputs). On each
subsequent execution, the overhead is roughly one microsecond per eval!()
call.
The input is macro-expanded using a generic, empty Runtime
which does not
have access to any of your own macros. The only macros you can use in eval!()
are those provided
by GameLisp's standard library, or those defined within the eval!()
form itself