aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doer.c65
-rw-r--r--src/include/doer.h8
-rw-r--r--src/stack.c2
3 files changed, 65 insertions, 10 deletions
diff --git a/src/doer.c b/src/doer.c
index 096ab94..5262fb1 100644
--- a/src/doer.c
+++ b/src/doer.c
@@ -116,23 +116,53 @@ char* doer_eval_str(doer_t* doer) {
}
}
+int doer_eval_lint(doer_t* doer) {
+ switch (doer->tree->type) {
+ case TREE_TYPE_CALL:
+ doer_do_call(doer);
+ return doer_eval_lint(doer);
+ case TREE_TYPE_DEF:
+ doer->tree = doer->tree->data.def.val;
+ return doer_eval_lint(doer);
+ case TREE_TYPE_LINT:
+ // Already done \o/.
+ return doer->tree->data.lint.val;
+ default:
+ DIE("Wrong type, FOOL!");
+ }
+}
+
tree_t* blin_die(doer_t* doer) {
exit(1);
return NULL; // Doesn't really matter what happens here.
}
tree_t* blin_print(doer_t* doer) {
+ tree_t* oldt = doer->tree;
doer->tree = doer->tree->data.call.arg->data.carg.val;
- char* strval = doer_eval_str(doer);
+ tree_t* arg = doer_eval_prim(doer);
- printf(
- "%s",
- strval
- );
+ char* rval;
- tree_t* lstr = tree_init(TREE_TYPE_LSTR, doer->tree->parent);
- lstr->data.lstr.val = strval;
- lstr->data.lstr.len = strlen(strval);
+ switch (arg->type) {
+ case TREE_TYPE_LINT:
+ printf("%d", arg->data.lint.val);
+ rval = ecalloc(64, sizeof(char));
+ sprintf(rval, "%d", arg->data.lint.val);
+ break;
+ case TREE_TYPE_LSTR:
+ printf("%s", arg->data.lstr.val);
+ rval = ecalloc(arg->data.lstr.len + 1, sizeof(char));
+ sprintf(rval, "%s", arg->data.lstr.val);
+ break;
+ default:
+ rval = ecalloc(1, sizeof(char));
+ rval[0] = '\0';
+ }
+
+ tree_t* lstr = tree_init(TREE_TYPE_LSTR, oldt->parent);
+ lstr->data.lstr.val = rval;
+ lstr->data.lstr.len = strlen(rval);
return lstr;
}
@@ -192,6 +222,25 @@ tree_t* blin_str_cat(doer_t* doer) {
return doer->tree;
}
+tree_t* blin_add(doer_t* doer) {
+ tree_t* tree = doer->tree;
+
+ tree_t* args = tree->data.call.arg;
+ tree_t* arg1 = args;
+ tree_t* arg2 = arg1->data.carg.nxt;
+
+ doer->tree = arg1;
+ int a = doer_eval_lint(doer);
+ doer->tree = arg2;
+ int b = doer_eval_lint(doer);
+
+ tree_t* newt = tree_init(TREE_TYPE_LINT, tree->parent);
+
+ newt->data.lint.val = a + b;
+
+ return newt;
+}
+
void doer_do_block(doer_t* doer) {
if (!doer->tree) return;
diff --git a/src/include/doer.h b/src/include/doer.h
index 4292ff7..30b514e 100644
--- a/src/include/doer.h
+++ b/src/include/doer.h
@@ -53,11 +53,11 @@ tree_t* doer_find_target_from_call(doer_t* doer);
tree_t* doer_eval_prim(doer_t* doer);
// Given a tree, evaluate it to a string (or type error).
char* doer_eval_str(doer_t* doer);
+int doer_eval_lint(doer_t* doer);
// Built-in functions.
// `die`: dies. Does not accept any arguments, returns int (if a tree falls in
-// the forest, but it burns down before anyone can hear it, did it ever make a
-// sound at all?) TODO: Make this actually clean up afterwards.
+// the forest, &c &c.) TODO: Make this actually clean up afterwards.
tree_t* blin_die(doer_t* doer);
// `print`: print a string.
tree_t* blin_print(doer_t* doer);
@@ -69,6 +69,9 @@ static tree_type_t blin_printl_args[] = { TREE_TYPE_LSTR };
// Returns a tree pointer to a lstr.
tree_t* blin_str_cat(doer_t* doer);
static tree_type_t blin_str_cat_args[] = { TREE_TYPE_LSTR, TREE_TYPE_LSTR };
+// `+`: Add two integers.
+tree_t* blin_add(doer_t* doer);
+static tree_type_t blin_add_args[] = { TREE_TYPE_LINT, TREE_TYPE_LINT };
void doer_do_call(doer_t* doer);
tree_t* doer_do_call_blin(doer_t* doer);
@@ -87,6 +90,7 @@ static blinf_t blinfs[] = {
{ blin_print, TREE_TYPE_LSTR, blin_print_args, "print" },
{ blin_printl, TREE_TYPE_LSTR, blin_printl_args, "printl" },
{ blin_str_cat, TREE_TYPE_LSTR, blin_str_cat_args, "str_cat" },
+ { blin_add, TREE_TYPE_LINT, blin_add_args, "+" },
};
#endif
diff --git a/src/stack.c b/src/stack.c
index 1d8a6fa..c6360e7 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -1,5 +1,7 @@
#include "include/stack.h"
+// Not actually used anywhere, might be name collision on clang.
+
stack_t* stack_init() {
stack_t* stack = emalloc(sizeof(stack_t));