Expressions and macros
An expression is a document. The example builds an expression program once and evaluates it with an input document. The macro example expands an expression before compilation and evaluation.
Example
Build an expression and evaluate it
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = stardust::build(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;{:value 42}Reusing programs
A program keeps the expression that you built, independently of any one evaluation.
- You can evaluate one program concurrently with separate input documents.
- Keep the program until its evaluations finish.
- Then release it under the ownership rule of its operation.
Operations
| Operation | Returns | Summary |
|---|---|---|
| build | program | build(expression) borrows the expression document and returns an owned program. |
| build_macro | program | build_macro(title, authored, arguments) binds AST arguments into an unstored macro and returns an owned program. |
| expand_macro | document | expand_macro(title, authored, arguments) returns the expanded expression document without building it. |
| Program::evaluate | document | program.evaluate(input) returns an independent owned result document. |
| Program::close | none | Release the program handle. |
| Database::expression | program | Build an owned program from a path or inline expression, expanding stored macros. |
build
pub fn build(expression: &Document, explain: Option<&mut BuildExplain>) -> Result<Program>Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
expression | &Document | Borrowed for the call | Required | The native expression AST to compile. The call borrows this document. |
explain | Option<&mut BuildExplain> | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for build. |
Errors
| Status | When |
|---|---|
Status::COMPILE_FAILED | the expression does not compile |
Status::OUT_OF_MEMORY | native memory is exhausted |
Notes
Examples
Build an expression and evaluate its input
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = stardust::build(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;{:value 42}Inspect one measured cost stage
expression_text holds this document:
["+" ?x 1]let expression = stardust::parse(expression_text, Format::EDN)?;
let mut explain = stardust::BuildExplain::default();
let _program = stardust::build(&expression, Some(&mut explain))?;
let result = explain.total;{:value {:cpu 22
:wall 23
:arena_bytes 0}}Explain expression compilation
expression_text holds this document:
["+" ?x 1]let expression = stardust::parse(expression_text, Format::EDN)?;
let mut explain = stardust::BuildExplain::default();
let _program = stardust::build(&expression, Some(&mut explain))?;
let result = explain;{:value {:prepare_expression {:cpu 4
:wall 4
:arena_bytes 0}
:compile {:cpu 15
:wall 15
:arena_bytes 0}
:total {:cpu 23
:wall 23
:arena_bytes 0}
:arena_capacity 65536
:stages_completed 2
:cache_hit true}}C exports: stardust_expr_build, stardust_expr_program_error
build_macro
pub fn build_macro(title: &str, authored: &Document, arguments: &Document) -> Result<Program>Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
title | &str | Value | Required | The diagnostic title of this unstored macro. |
authored | &Document | Borrowed for the call | Required | The native authored macro definition with its declared parameters and expression body. |
arguments | &Document | Borrowed for the call | Required | Native AST arguments bound to the macro's declared parameters before expansion. |
Errors
| Status | When |
|---|---|
Status::INVALID_ARGUMENT | the arguments include an undeclared macro parameter |
Status::INVALID_DEFINITION | the macro is invalid or expands recursively |
Status::NOT_FOUND | the macro refers to an unknown macro |
Status::COMPILE_FAILED | the expansion does not compile |
Status::OUT_OF_MEMORY | native memory is exhausted |
Notes
Examples
Bind an unstored macro and evaluate it
macro_text holds this document:
{:params ["input"]
:expands ["+" {:insert "input"} 1]}arguments_text holds this document:
{:input ["*" ?amount 2]}input_text holds this document:
{:amount 10}let authored = stardust::parse(macro_text, Format::EDN)?;
let arguments = stardust::parse(arguments_text, Format::EDN)?;
let program = stardust::build_macro("twice-plus-one", &authored, &arguments)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;{:value 21}C exports: stardust_macro_build, stardust_expr_program_error
expand_macro
pub fn expand_macro(title: &str, authored: &Document, arguments: &Document) -> Result<Document>Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
title | &str | Value | Required | The diagnostic title of this unstored macro. |
authored | &Document | Borrowed for the call | Required | The native authored macro definition with its declared parameters and expression body. |
arguments | &Document | Borrowed for the call | Required | Native AST arguments bound to the macro's declared parameters before expansion. |
Errors
| Status | When |
|---|---|
Status::INVALID_ARGUMENT | the arguments include an undeclared macro parameter |
Status::INVALID_DEFINITION | the macro is invalid or expands recursively |
Status::NOT_FOUND | the macro refers to an unknown macro |
Status::OUT_OF_MEMORY | native memory is exhausted |
Notes
Examples
Expand an unstored macro as a native document
macro_text holds this document:
{:params ["input"]
:expands ["+" {:insert "input"} 1]}arguments_text holds this document:
{:input ["*" ?amount 2]}let authored = stardust::parse(macro_text, Format::EDN)?;
let arguments = stardust::parse(arguments_text, Format::EDN)?;
let result = stardust::expand_macro("twice-plus-one", &authored, &arguments)?;{:value ["+" ["*" ?amount 2] 1]}C exports: stardust_macro_expand, stardust_document_error
Program::evaluate
pub fn evaluate(
&self,
input: Option<&Document>,
explain: Option<&mut EvalExplain>,
) -> Result<Document>Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
self | &Self | Borrowed for the call | Required | The program owner for this operation. Keep it alive during the call. |
input | Option<&Document> | Borrowed for the call | Absent | Variables for evaluation. Absent input uses an empty object. |
explain | Option<&mut EvalExplain> | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for evaluate. |
Errors
Close consumes this owner. Rust ownership prevents later access. Thus, the safe API does not report closed for this receiver.
| Status | When |
|---|---|
Status::EVALUATION_FAILED | the expression fails on the input |
Status::OUT_OF_MEMORY | native memory is exhausted |
Notes
Examples
Build an expression and evaluate its input
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = stardust::build(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;{:value 42}Explain expression evaluation
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = stardust::build(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let mut explain = stardust::EvalExplain::default();
let _output = program.evaluate(Some(&input), Some(&mut explain))?;
let result = explain;{:value {:prepare_variables {:cpu 4
:wall 5
:arena_bytes 0}
:evaluate {:cpu 50
:wall 50
:arena_bytes 0}
:adopt_document {:cpu 5
:wall 5
:arena_bytes 0}
:total {:cpu 64
:wall 65
:arena_bytes 0}
:arena_capacity 65536
:document_bytes 42
:stages_completed 3}}C exports: stardust_expr_evaluate, stardust_result_take_document, stardust_result_error, stardust_result_release
Program::close
pub fn close(self)Consumes the receiver handle.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
self | Self | Consumed owner | Required | The program owner to release. Do not use it after this call. |
Errors
Close consumes this owner. Rust ownership prevents later access. Thus, the safe API does not report closed for this receiver.
Examples
Build an expression and evaluate its input
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = stardust::build(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;
program.close();{:value 42}C exports: stardust_expr_program_release
Database::expression
pub fn expression<'a>(
&self,
source: impl Into<Source<'a>>,
explain: Option<&mut BuildExplain>,
) -> Result<Program>Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
self | &Self | Borrowed for the call | Required | The database owner for this operation. Keep it alive during the call. |
source | impl Into<Source<'a>> | Value | Required | An inline native definition or a stored definition path. |
explain | Option<&mut BuildExplain> | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for build. |
Errors
| Status | When |
|---|---|
Status::NOT_FOUND | no expression is stored at the path |
Status::INVALID_DEFINITION | a macro it calls is invalid or expands recursively |
Status::COMPILE_FAILED | the expanded expression does not compile |
Status::CLOSED | the database is closed |
Status::OUT_OF_MEMORY | native memory is exhausted |
Notes
The program keeps the expression and macros selected at build time and survives database closure. Build again to use later definition changes.
Examples
Build an expression with the database's macros and evaluate it
expression_text holds this document:
["+" ?x 1]input_text holds this document:
{:x 41}let expression = stardust::parse(expression_text, Format::EDN)?;
let program = db.expression(&expression, None)?;
let input = stardust::parse(input_text, Format::EDN)?;
let result = program.evaluate(Some(&input), None)?;{:value 42}C exports: stardust_db_expression_build, stardust_expr_program_error