Previous: Cleaning Up, Up: Crash Introduction [Index]
The wrapped up simple expression evaluator code is:
union state_type {
X1f4_E4_C_BILL bill;
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_e4_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, &output);
if (!status) {
unsigned type;
type = x1f4_type_expression(x1f4_expression);
if (type == X1f4_E4_BILL) {
... *(X1f4_E4_C_BILL *) &output ...
} else {
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.