diff options
Diffstat (limited to 'eval.c')
| -rw-r--r-- | eval.c | 73 |
1 files changed, 73 insertions, 0 deletions
@@ -0,0 +1,73 @@ +#include <assert.h> +#include <stdio.h> + +#include "eval.h" + +static int evaluate_value(const struct Node* node, long* out) +{ + switch (node->kind) + { + case VALUE_DIFFERENCE: + *out = (long)node->first->character - (long)node->second->character; + return 0; + default: break; + } + + assert(!"the parser handed a non-value where a value goes"); + return 1; +} + +static int evaluate_type(const struct Node* node, struct Type* out) +{ + out->kind = KIND_VOID; + out->number = 0; + switch (node->kind) + { + case TYPE_DECLTYPE: + if (evaluate_value(node->first, &out->number)) + return 1; + out->kind = KIND_VALUE; + return 0; + default: break; + } + + assert(!"the parser handed a non-type where a type goes"); + return 1; +} + +static enum RunStatus emit(const struct Node* node) +{ + struct Type type; + if (evaluate_type(node->first, &type)) + return RUN_FAILED; + + if (type.kind == KIND_VALUE) + (void)printf("%ld\n", type.number); + return RUN_DONE; +} + +static enum RunStatus execute_one(const struct Node* node) +{ + switch (node->kind) + { + case STMT_EMIT: return emit(node); + default: break; + } + + assert(!"the parser handed a non-statement where a statement goes"); + return RUN_FAILED; +} + +enum RunStatus execute(const struct Node* statement) +{ + while (statement != NULL) + { + enum RunStatus status = execute_one(statement); + if (status != RUN_DONE) + return status; + + statement = statement->next; + } + + return RUN_DONE; +} |
