Previous: Cleaning Up, Up: Crash Introduction
The wrapped up simple expression evaluator code is:
union state_type { X1f4_E4_C_MODE mode; X1f4_E4_C_REAL real; X1f4_E4_C_TEXT text; }; static int select_function(const char *f, unsigned length, const void *context, const struct x1f4_function_type **function) { int status = X1f4_E4_PARSE_ERROR; const struct x1f4_function_type *function_data; function_data = context; if (function_data) { while (function_data->name) { if (length == function_data->length && !memcmp((void *) f, function_data->name, length)) { break; } function_data++; } if (function_data->name) { status = 0; *function = function_data; } } return status; } static int select_variable(const char *f, unsigned length, const void *context, const struct x1f4_variable_type **variable, void **state) { return 1; } ... struct x1f4_attributes_type attributes; unsigned flags = 0; void *x1f4_expression; ... attributes.function_set.get = select_function; attributes.function_set.context = x1f4_e4_defaults; attributes.variable_set.get = select_variable; attributes.variable_set.context = NULL; attributes.terminator = 0; x1f4_llink_operator1s(&attributes.operator1s); x1f4_llink_operator2s(&attributes.operator2s); status = x1f4_init_expression (&x1f4_expression, expression, flags, &attributes); if (!status) { union state_type output; status = x1f4_link_expression(x1f4_expression, context, &output); if (!status) { unsigned type; type = x1f4_type_expression(x1f4_expression); if (type == X1f4_E4_MODE) { ... *(X1f4_E4_C_MODE *) &output ... } else { if (type == X1f4_E4_REAL) { ... *(X1f4_E4_C_REAL *) &output ... } else { if (type == X1f4_E4_TEXT) { ... *(X1f4_E4_C_TEXT *) &output ... } else { no result, the expression evaluated void } } } } x1f4_fini_expression(&x1f4_expression); } ...
Note that this code was never tested as such. It may very well not work.