summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/eval.c b/eval.c
new file mode 100644
index 0000000..9e1e946
--- /dev/null
+++ b/eval.c
@@ -0,0 +1,92 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "types.h"
+
+typedef struct val {
+ type t;
+ char *name;
+ union {
+ int i;
+ };
+} val;
+
+val *vars[4096];
+int varcount = 0;
+
+values *eval(ast *a);
+
+values *getval(ast *a, int index, type t) {
+ values *tmp;
+ if (t == INT && a->vals->ts[index] == INT)
+ return a->vals;
+ else if ((tmp = eval(a->vals->as[index]))->ts[0] == t)
+ return tmp;
+ else
+ fprintf(stderr, "expected value, but got nothing\n");
+}
+
+void checkcount(ast *a, int argc) {
+ if (a->vals->argc != argc)
+ fprintf(stderr, "incorrect number of args given!\n");
+}
+
+values *eval(ast *a) {
+ values *v = malloc(sizeof(values));
+
+ if (strcmp(a->fname, "print") == 0) {
+ checkcount(a, 1);
+ printf("%d\n", getval(a, 0, INT)->is[0]);
+ return NULL;
+ }
+
+ else if (strcmp(a->fname, "set") == 0) {
+ checkcount(a, 2);
+ printf("%d\n", getval(a, 0, INT)->is[0]);
+ return NULL;
+ }
+
+ else if (strcmp(a->fname, "+") == 0) {
+ v->is[0] = getval(a, 0, INT)->is[0];
+ for (int i = 1; i < a->vals->argc; i++)
+ v->is[0] += getval(a, i, INT)->is[i];
+
+ v->ts[0] = INT;
+ v->argc++;
+ }
+ else if (strcmp(a->fname, "-") == 0) {
+ if (a->vals->argc == 1)
+ v->is[0] = -getval(a, 0, INT)->is[0];
+ else {
+ v->is[0] = getval(a, 0, INT)->is[0];
+ for (int i = 1; i < a->vals->argc; i++)
+ v->is[0] -= getval(a, i, INT)->is[i];
+ }
+
+ v->ts[0] = INT;
+ v->argc++;
+ }
+ else if (strcmp(a->fname, "*") == 0) {
+ v->is[0] = getval(a, 0, INT)->is[0];
+ for (int i = 1; i < a->vals->argc; i++)
+ v->is[0] *= getval(a, i, INT)->is[i];
+
+ v->ts[0] = INT;
+ v->argc++;
+ }
+ else if (strcmp(a->fname, "/") == 0) {
+ v->is[0] = getval(a, 0, INT)->is[0];
+ for (int i = 1; i < a->vals->argc; i++)
+ v->is[0] /= getval(a, i, INT)->is[i];
+
+ v->ts[0] = INT;
+ v->argc++;
+ }
+ else if (strcmp(a->fname, "%") == 0) {
+ v->is[0] = getval(a, 0, INT)->is[0] % getval(a, 1, INT)->is[1];
+ v->ts[0] = INT;
+ v->argc++;
+ }
+
+ return v;
+}