diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/doer.c | 65 | ||||
-rw-r--r-- | src/include/doer.h | 8 | ||||
-rw-r--r-- | src/stack.c | 2 |
3 files changed, 65 insertions, 10 deletions
@@ -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)); |