summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/eval.c b/eval.c
new file mode 100644
index 0000000..4f4b1e2
--- /dev/null
+++ b/eval.c
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include "parser.h"
+#include "builtin.h"
+#include "eval.h"
+
+int varcount = 0;
+luckyvar *variables[10000];
+
+int funccount= 0;
+luckytree *functions[10000];
+
+int argcount(luckyval *tree){
+ if (tree == NULL) return 0;
+ else return 1 + argcount(tree->nextelement);
+}
+
+bool checkargcount(luckytree *tree, int i){
+ return !(argcount(tree->arguments) == i);
+}
+
+void argcounterror(luckytree *tree, int expected){
+ if (checkargcount(tree, expected)) {
+ printf("expected %d args to function %s, got %d\n",expected, tree->function, argcount(tree->arguments));
+ exit(1);
+ }
+}
+
+luckyval *lookupvar(char *name){
+ for (int i = 0; i < 10000; i++){
+ if (variables[i] != NULL && strcmp(variables[i]->name, name) == 0){
+ return variables[i]->val;
+ }
+ }
+ printf("no such variable %s exists!\n", name);
+ exit(1);
+}
+
+luckyval *eval(luckytree *tree){
+ int i = 0;
+ for (luckyval *current = tree->arguments; i < argcount(tree->arguments); current = current->nextelement){
+ if (current->type == LUCKYTREE){
+ luckyval *var = malloc(sizeof(luckyval));
+ var = eval(current->tree);
+ memcpy(&current->d, &var->d, sizeof(double));
+ current->type = var->type;
+ free(var);
+ }
+ else if (strcmp(tree->function, "let") != 0) {
+ if (current->type == LUCKYVAR){
+ luckyval *tmp = lookupvar(current->var);
+ memcpy(&current->d, &tmp->d, sizeof(double));
+ current->type = tmp->type;
+ }
+ }
+ i++;
+ }
+
+ luckyval *out = malloc(sizeof(luckyval));
+
+ if (arithmetic(tree, out)) return out;
+ else if (io(tree, out)) return out;
+ else if (variableops(tree, out)) return out;
+
+ printf("Unknown function!\n");
+ exit(1);
+}