# expression_language.h ## Overview
Implements a simple "expression language" for quickly evaluating simple dynamic (user-entered) mathematical expressions, such as `(2 * sin(t) + 3)`. Expressions are compiled to byte code using `compile()` which can later be evaluated by calling `run()`. When you compile, you specify a list of variables. The current values of these variables are then specified when calling `run()`. Variables and stack values can either be floats or `tm_vec4_t`. To use `tm_vec4_t`, call the `run_vec4()` function instead of `run()`. Note that the `tm_vec4_t` evaluation context can also be used for `tm_vec3_t` and `tm_vec2_t` operations. The byte code is automatically constant-folded. I.e. operations on constants are replaced with the value of the evaluated operation. `is_constant()` can be used to determine if the final value is a constant or not.
## Index
`struct tm_expression_language_api`
`compile()`
`is_error()`
`is_constant()`
`is_constant_vec4()`
`used_variables()`
`has_vec4_constants()`
`size()`
`run()`
`run_vec4()`

`tm_expression_language_api_version`
## API
### `struct tm_expression_language_api`
API for performing Expression Language calculations. #### `compile()` ~~~c char *(*compile)(const char *source, const tm_strhash_t *variables, uint16_t num_variables, struct tm_temp_allocator_i *ta); ~~~ Compiles the source expression `source` into byte code and returns it as a carray, allocated using `ta`. `variables` is a list of hashed variable names that can be used in the expression. These variables will have their values defined at runtime, when the expression is evaluated. #### `is_error()` ~~~c const char *(*is_error)(const char *byte_code); ~~~ If the compile resulted in an error, this will return the resulting error message, otherwise it will return NULL. #### `is_constant()` ~~~c bool (*is_constant)(const char *byte_code, float *value); ~~~ Returns *true* if the `byte_code` represents a constant value and *false* otherwise. The constant value represented by the bytecode is returned in *value*. #### `is_constant_vec4()` ~~~c bool (*is_constant_vec4)(const char *byte_code, tm_vec4_t *value); ~~~ As `is_constant()`, but checks for a constant `tm_vec4_t` value. #### `used_variables()` ~~~c uint16_t *(*used_variables)(const char *byte_code, struct tm_temp_allocator_i *ta); ~~~ Returns a carray of all the variables used in the byte code. The values in the array are indices into the `variables` table passed to `compile()`. #### `has_vec4_constants()` ~~~c bool (*has_vec4_constants)(const char *byte_code); ~~~ Returns *true* if the `byte_code` has any `tm_vec4_t` constants, *false* if it can all be represented as floats. Note that a `tm_vec4_t` with identical values for all components (e.g. `(tm_vec4_t){0,0,0,0}`) is represented as a float in the byte code. #### `size()` ~~~c uint32_t (*size)(const char *byte_code); ~~~ Returns the size (in bytes) of the byte code. #### `run()` ~~~c float (*run)(const char *byte_code, const float *variables); ~~~ Runs the `byte_code`. `variables` is an array of variable values. These values should match the variables that were passed to the `compile()` function. Returns the result of running the byte code. #### `run_vec4()` ~~~c tm_vec4_t (*run_vec4)(const char *byte_code, const tm_vec4_t *variables); ~~~ As `run()`, but runs the bytecode in a `tm_vec4_t` context.
### `tm_expression_language_api_version`
~~~c #define tm_expression_language_api_version ~~~