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:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c836 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_expr_build(expression, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{: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

OperationReturnsSummary
stardust_expr_buildStatus. program through outputbuild(expression) borrows the expression document and returns an owned program.
stardust_macro_buildStatus. program through outputbuild_macro(title, authored, arguments) binds AST arguments into an unstored macro and returns an owned program.
stardust_macro_expandStatus. document through outputexpand_macro(title, authored, arguments) returns the expanded expression document without building it.
stardust_expr_evaluateStatus. document through outputprogram.evaluate(input) returns an independent owned result document.
stardust_expr_program_releasevoidRelease the program handle.
stardust_db_expression_buildStatus. program through outputBuild an owned program from a path or inline expression, expanding stored macros.

stardust_expr_build

c132 B
uint32_t stardust_expr_build(const stardust_document *source, stardust_expr_build_explain *explain, stardust_expr_program **output);
c109 B
uint32_t stardust_expr_program_error(const stardust_expr_program *program, stardust_diagnostic_view *output);

Parameters

stardust_expr_build

ParameterTypeOwnershipDefaultMeaning
sourceconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
explainstardust_expr_build_explain *Caller-owned outputNULLReceives a record. Its pointer fields follow the record's ownership contract.
outputstardust_expr_program **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_expr_program_error

ParameterTypeOwnershipDefaultMeaning
programconst stardust_expr_program *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

Errors

StatusWhen
STARDUST_COMPILE_FAILEDthe expression does not compile
STARDUST_OUT_OF_MEMORYnative memory is exhausted
STARDUST_INVALID_ARGUMENTa required input or output pointer is NULL, or an input owner is not ready

Notes

Expression documents.

Examples

Build an expression and evaluate its input

expression_text holds this document:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c836 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_expr_build(expression, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{:value 42}

Inspect one measured cost stage

expression_text holds this document:

edn10 B
["+" ?x 1]
c445 B
stardust_document *expression = NULL;
stardust_expr_build_explain explain = {0};
stardust_expr_program *program = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_expr_build(expression, &explain, &program);
stardust_expr_program_release(program);
stardust_document_release(expression);
if (status != STARDUST_OK) return status;
stardust_cost result = explain.total;
Result / 75 B
{:value {:cpu         12
         :wall        13
         :arena_bytes 0}}

Explain expression compilation

expression_text holds this document:

edn10 B
["+" ?x 1]
c453 B
stardust_document *expression = NULL;
stardust_expr_build_explain explain = {0};
stardust_expr_program *program = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_expr_build(expression, &explain, &program);
stardust_expr_program_release(program);
stardust_document_release(expression);
if (status != STARDUST_OK) return status;
stardust_expr_build_explain result = explain;
Result / 511 B
{:value {:prepare_expression {:cpu         2
                              :wall        2
                              :arena_bytes 0}
         :compile            {:cpu         8
                              :wall        7
                              :arena_bytes 0}
         :total              {:cpu         12
                              :wall        12
                              :arena_bytes 0}
         :arena_capacity     65536
         :stages_completed   2
         :cache_hit          true}}

Also calls: stardust_expr_program_error

stardust_macro_build

c155 B
uint32_t stardust_macro_build(stardust_bytes title, const stardust_document *authored, const stardust_document *arguments, stardust_expr_program **output);
c109 B
uint32_t stardust_expr_program_error(const stardust_expr_program *program, stardust_diagnostic_view *output);

Parameters

stardust_macro_build

ParameterTypeOwnershipDefaultMeaning
titlestardust_bytesValueRequiredThe diagnostic title of this unstored macro.
authoredconst stardust_document *Borrowed handleRequiredThe native authored macro definition with its declared parameters and expression body.
argumentsconst stardust_document *Borrowed handleRequiredNative AST arguments bound to the macro's declared parameters before expansion.
outputstardust_expr_program **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_expr_program_error

ParameterTypeOwnershipDefaultMeaning
programconst stardust_expr_program *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTthe arguments include an undeclared macro parameter
STARDUST_INVALID_DEFINITIONthe macro is invalid or expands recursively
STARDUST_NOT_FOUNDthe macro refers to an unknown macro
STARDUST_COMPILE_FAILEDthe expansion does not compile
STARDUST_OUT_OF_MEMORYnative memory is exhausted

Notes

Macro documents.

Examples

Bind an unstored macro and evaluate it

macro_text holds this document:

edn56 B
{:params  ["input"]
 :expands ["+" {:insert "input"} 1]}

arguments_text holds this document:

edn24 B
{:input ["*" ?amount 2]}

input_text holds this document:

edn12 B
{:amount 10}
c1.1 kB
stardust_document *authored = NULL;
stardust_document *arguments = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
stardust_bytes title = {(const uint8_t *)"twice-plus-one", 14};
uint32_t status = stardust_parse(macro_text, STARDUST_EDN, &authored);
if (status == STARDUST_OK) status = stardust_parse(arguments_text, STARDUST_EDN, &arguments);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_macro_build(title, authored, arguments, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(arguments);
stardust_document_release(authored);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{:value 21}

Also calls: stardust_expr_program_error

stardust_macro_expand

c152 B
uint32_t stardust_macro_expand(stardust_bytes title, const stardust_document *authored, const stardust_document *arguments, stardust_document **output);
c97 B
uint32_t stardust_document_error(const stardust_document *doc, stardust_diagnostic_view *output);

Parameters

stardust_macro_expand

ParameterTypeOwnershipDefaultMeaning
titlestardust_bytesValueRequiredThe diagnostic title of this unstored macro.
authoredconst stardust_document *Borrowed handleRequiredThe native authored macro definition with its declared parameters and expression body.
argumentsconst stardust_document *Borrowed handleRequiredNative AST arguments bound to the macro's declared parameters before expansion.
outputstardust_document **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_document_error

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTthe arguments include an undeclared macro parameter
STARDUST_INVALID_DEFINITIONthe macro is invalid or expands recursively
STARDUST_NOT_FOUNDthe macro refers to an unknown macro
STARDUST_OUT_OF_MEMORYnative memory is exhausted

Notes

Macro documents.

Examples

Expand an unstored macro as a native document

macro_text holds this document:

edn56 B
{:params  ["input"]
 :expands ["+" {:insert "input"} 1]}

arguments_text holds this document:

edn24 B
{:input ["*" ?amount 2]}
c585 B
stardust_document *authored = NULL;
stardust_document *arguments = NULL;
stardust_document *result = NULL;
stardust_bytes title = {(const uint8_t *)"twice-plus-one", 14};
uint32_t status = stardust_parse(macro_text, STARDUST_EDN, &authored);
if (status == STARDUST_OK) status = stardust_parse(arguments_text, STARDUST_EDN, &arguments);
if (status == STARDUST_OK) status = stardust_macro_expand(title, authored, arguments, &result);
stardust_document_release(arguments);
stardust_document_release(authored);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 32 B
{:value ["+" ["*" ?amount 2] 1]}

Also calls: stardust_document_error

stardust_expr_evaluate

c163 B
uint32_t stardust_expr_evaluate(stardust_expr_program *program, const stardust_document *variables, stardust_expr_eval_explain *explain, stardust_result **output);
c92 B
uint32_t stardust_result_take_document(stardust_result *result, stardust_document **output);
c96 B
uint32_t stardust_result_error(const stardust_result *result, stardust_diagnostic_view *output);
c54 B
void stardust_result_release(stardust_result *result);

Parameters

stardust_expr_evaluate

ParameterTypeOwnershipDefaultMeaning
programstardust_expr_program *Borrowed handleRequiredKeep the handle alive until the call returns.
variablesconst stardust_document *Borrowed handleNULLKeep the handle alive until the call returns.
explainstardust_expr_eval_explain *Caller-owned outputNULLReceives a record. Its pointer fields follow the record's ownership contract.
outputstardust_result **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_result_take_document

ParameterTypeOwnershipDefaultMeaning
resultstardust_result *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_document **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_result_error

ParameterTypeOwnershipDefaultMeaning
resultconst stardust_result *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

stardust_result_release

ParameterTypeOwnershipDefaultMeaning
resultstardust_result *Consumed handleNULLEnds ownership. Do not use the handle after this call.

Errors

StatusWhen
STARDUST_EVALUATION_FAILEDthe expression fails on the input
STARDUST_OUT_OF_MEMORYnative memory is exhausted
STARDUST_INVALID_ARGUMENTa required input or output pointer is NULL, or an input owner is not ready

Notes

Expression evaluation.

Examples

Build an expression and evaluate its input

expression_text holds this document:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c836 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_expr_build(expression, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{:value 42}

Explain expression evaluation

expression_text holds this document:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c760 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *output = NULL;
stardust_expr_eval_explain explain = {0};
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_expr_build(expression, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, &explain, &output);
stardust_result_release(output);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) return status;
stardust_expr_eval_explain result = explain;
Result / 632 B
{:value {:prepare_variables {:cpu         2
                             :wall        2
                             :arena_bytes 0}
         :evaluate          {:cpu         23
                             :wall        23
                             :arena_bytes 0}
         :adopt_document    {:cpu         2
                             :wall        2
                             :arena_bytes 0}
         :total             {:cpu         30
                             :wall        30
                             :arena_bytes 0}
         :arena_capacity    65536
         :document_bytes    42
         :stages_completed  3}}

Also calls: stardust_result_take_document, stardust_result_error, stardust_result_release

stardust_expr_program_release

c67 B
void stardust_expr_program_release(stardust_expr_program *program);

Consumes the receiver handle.

Parameters

ParameterTypeOwnershipDefaultMeaning
programstardust_expr_program *Consumed handleNULLEnds ownership. Do not use the handle after this call.

Examples

Build an expression and evaluate its input

expression_text holds this document:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c836 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_expr_build(expression, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{:value 42}

stardust_db_expression_build

c159 B
uint32_t stardust_db_expression_build(stardust_db *db, const stardust_db_source *source, stardust_expr_build_explain *explain, stardust_expr_program **output);
c109 B
uint32_t stardust_expr_program_error(const stardust_expr_program *program, stardust_diagnostic_view *output);

Parameters

stardust_db_expression_build

ParameterTypeOwnershipDefaultMeaning
dbstardust_db *Borrowed handleRequiredKeep the handle alive until the call returns.
sourceconst stardust_db_source *Borrowed inputRequiredAn inline native definition or a stored definition path.
explainstardust_expr_build_explain *Caller-owned outputNULLReceives a record. Its pointer fields follow the record's ownership contract.
outputstardust_expr_program **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_expr_program_error

ParameterTypeOwnershipDefaultMeaning
programconst stardust_expr_program *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

Errors

StatusWhen
STARDUST_NOT_FOUNDno expression is stored at the path
STARDUST_INVALID_DEFINITIONa macro it calls is invalid or expands recursively
STARDUST_COMPILE_FAILEDthe expanded expression does not compile
STARDUST_CLOSEDthe database is closed
STARDUST_OUT_OF_MEMORYnative memory is exhausted
STARDUST_INVALID_ARGUMENTa required input or output pointer is NULL, or an input owner is not ready

Notes

The program keeps the expression and macros selected at build time and survives database closure. Build again to use later definition changes.

Expression documents.

Examples

Build an expression with the database's macros and evaluate it

expression_text holds this document:

edn10 B
["+" ?x 1]

input_text holds this document:

edn7 B
{:x 41}
c934 B
stardust_document *expression = NULL;
stardust_document *input = NULL;
stardust_expr_program *program = NULL;
stardust_result *evaluated = NULL;
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &expression);
stardust_db_source source = {.kind = STARDUST_SOURCE_DOCUMENT, .document = expression};
if (status == STARDUST_OK) status = stardust_parse(input_text, STARDUST_EDN, &input);
if (status == STARDUST_OK) status = stardust_db_expression_build(db, &source, NULL, &program);
if (status == STARDUST_OK) status = stardust_expr_evaluate(program, input, NULL, &evaluated);
if (status == STARDUST_OK) status = stardust_result_take_document(evaluated, &result);
stardust_result_release(evaluated);
stardust_expr_program_release(program);
stardust_document_release(input);
stardust_document_release(expression);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 11 B
{:value 42}

Also calls: stardust_expr_program_error