From c26c65dcf836a86ff3374a3e92e57ec61568e8c9 Mon Sep 17 00:00:00 2001 From: c Date: Sat, 30 Mar 2024 09:24:53 -0400 Subject: Nested functions and transitivity works. Added a `str_cat` function. --- src/doer.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'src/doer.c') 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? -- cgit v1.2.3