hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-19 11:35:28 +0200
committerhachem <im@hachem.wtf>2026-09-19 11:35:28 +0200
commitdd52ccd9319aa847cddc486519075b806c9e9092 (patch)
treedf290f8972aa6eb164fad7258002ccb95cf648bf /eval.c
parent768bbdd137f5b205e4282bd79572681aef4514e3 (diff)
feat: emmit a decltype of a difference
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/eval.c b/eval.c
new file mode 100644
index 0000000..5841566
--- /dev/null
+++ b/eval.c
@@ -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;
+}