aboutsummaryrefslogtreecommitdiff
path: root/src/doer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/doer.c')
-rw-r--r--src/doer.c76
1 files changed, 59 insertions, 17 deletions
diff --git a/src/doer.c b/src/doer.c
index 19de0d8..2968882 100644
--- a/src/doer.c
+++ b/src/doer.c
@@ -74,7 +74,8 @@ char* doer_eval_str(doer_t* doer) {
switch (doer->tree->type) {
case TREE_TYPE_CALL:
- doer->tree = doer_find_target_from_call(doer->targets, doer->tree);
+ // doer->tree = doer_find_target_from_call(doer->targets, doer->tree);
+ doer->tree = doer_do_call(doer);
return doer_eval_str(doer);
case TREE_TYPE_DEF:
doer->tree = doer->tree->data.def.val;
@@ -87,38 +88,68 @@ char* doer_eval_str(doer_t* doer) {
}
}
-void blin_die(doer_t* doer) {
+tree_t* blin_die(doer_t* doer) {
exit(1);
+ return NULL; // Doesn't really matter what happens here.
}
-void blin_print(doer_t* doer) {
+tree_t* blin_print(doer_t* doer) {
doer->tree = doer->tree->data.call.arg->data.carg.val;
+ char* strval = doer_eval_str(doer);
printf(
"%s",
- doer_eval_str(doer)
+ strval
);
+
+ tree_t* lstr = tree_init(TREE_TYPE_LSTR, doer->tree->parent);
+ lstr->data.lstr.val = strval;
+ lstr->data.lstr.len = strlen(strval);
+
+ return lstr;
}
-void blin_printl(doer_t* doer) {
+tree_t* blin_printl(doer_t* doer) {
doer->tree = doer->tree->data.call.arg->data.carg.val;
+ char* strval = doer_eval_str(doer);
printf(
"%s\n",
- doer_eval_str(doer)
+ strval
);
+
+ tree_t* lstr = tree_init(TREE_TYPE_LSTR, doer->tree->parent);
+ lstr->data.lstr.val = strval;
+ lstr->data.lstr.len = strlen(strval);
+
+ return doer->tree;
}
-void blin_str_cat(doer_t* doer) {
+tree_t* blin_str_cat(doer_t* doer) {
tree_t* oldt = doer->tree;
doer->tree = doer->tree->data.call.arg->data.carg.val;
char* str1 = doer_eval_str(doer);
doer->tree = oldt->data.call.arg->data.carg.nxt->data.carg.val;
char* str2 = doer_eval_str(doer);
- tree_destroy(doer->tree);
+ char* val = emalloc(
+ sizeof(str1) +
+ sizeof(str2) -
+ sizeof(char)
+ );
+
+ strcpy(val, str1);
+ strcat(val, str2);
+
+ free(str1);
+ free(str2);
-// doer->tree = tree_init(TREE_TYPE_LSTR);
+ doer->tree = tree_init(TREE_TYPE_LSTR, oldt->parent);
+
+ doer->tree->data.lstr.val = val;
+ doer->tree->data.lstr.len = strlen(val);
+
+ return doer->tree;
}
void doer_do_block(doer_t* doer) {
@@ -146,27 +177,38 @@ void doer_do_expr(doer_t* doer) {
}
void doer_do_def(doer_t* doer) {
+ tree_t* tag2 = doer->tree->data.def.tag->data.tag.nxt;
target_t* target = target_init(
- doer->tree-> // HACK: Grab the 2nd tag's value (w/o checking if
- // it's actually there…).
- data.def.tag->
- data.tag.nxt->
- data.tag.val,
+ tag2->data.tag.val, // HACK: Grab the 2nd tag's value, without
+ // checking if it's actually there…
doer->tree
);
doer_add_target(doer, target);
}
-void doer_do_call(doer_t* doer) {
+tree_t* doer_do_call(doer_t* doer) {
+ tree_t* blin = doer_do_call_blin(doer);
+ if (!blin) return doer_find_target_from_call(doer->targets, doer->tree);
+ else return blin;
+}
+
+tree_t* doer_do_call_blin(doer_t* doer) {
// Search through built-in functions first.
for (int i = 0; i < sizeof(blinfs) / sizeof(blinf_t); i++) {
if (!strcmp(blinfs[i].name, doer->tree->data.call.target)) {
- (blinfs[i].fp)(doer);
- return;
+ return (blinfs[i].fp)(doer);
}
}
// Search through targets next.
LOG_DBGF("got %s", doer->ltarget->tree->data.def.tag->data.tag.nxt->data.tag.val);
+
+ return NULL;
}
+
+// TODO: doer_do_call will check first doer_do_call_blin and then
+// doer_do_call_def for user-defined functions. Will return a tree, which will
+// replace the call in the tree.
+//
+// Maybe the parent should be set by the looping function?