From bbcda663d5b2b2f055de12107e0abab536e5beea Mon Sep 17 00:00:00 2001 From: c Date: Sat, 23 Mar 2024 10:52:52 -0400 Subject: Doubly-linked the abstract syntax tree. --- src/doer.c | 13 +++++++++++-- src/include/doer.h | 8 ++++---- src/include/parser.h | 3 +++ src/include/tree.h | 5 +++-- src/main.c | 2 -- src/parser.c | 50 +++++++++++++++++++++++++++++++++++--------------- src/tree.c | 6 ++++-- 7 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/doer.c b/src/doer.c index ab1ca4d..19de0d8 100644 --- a/src/doer.c +++ b/src/doer.c @@ -1,6 +1,7 @@ #include "include/doer.h" #include "include/tree.h" #include "include/util.h" +#include target_t* target_init(char* name, tree_t* tree) { target_t* target = emalloc(sizeof(target_t)); @@ -108,8 +109,16 @@ void blin_printl(doer_t* doer) { ); } -void blin_to_str(doer_t* doer) { - // TODO +void 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); + +// doer->tree = tree_init(TREE_TYPE_LSTR); } void doer_do_block(doer_t* doer) { diff --git a/src/include/doer.h b/src/include/doer.h index 641abed..2bdad56 100644 --- a/src/include/doer.h +++ b/src/include/doer.h @@ -63,9 +63,9 @@ static tree_type_t blin_print_args[] = { TREE_TYPE_LSTR }; // `printl`: print a string, and add a newline. void blin_printl(doer_t* doer); static tree_type_t blin_printl_args[] = { TREE_TYPE_LSTR }; -// `to_str`: convert any (primitive) type to a string. -void blin_to_str(doer_t* doer); -static tree_type_t blin_to_str_args[] = { TREE_TYPE_CALL }; +// `str_cat`: concatenate strings. +void blin_str_cat(doer_t* doer); +static tree_type_t blin_str_cat_args[] = { TREE_TYPE_LSTR, TREE_TYPE_LSTR }; void doer_do_block(doer_t* tree); void doer_do_expr(doer_t* tree); @@ -81,7 +81,7 @@ static blinf_t blinfs[] = { { blin_die, TREE_TYPE_LINT, NULL, "die" }, { blin_print, TREE_TYPE_LSTR, blin_print_args, "print" }, { blin_printl, TREE_TYPE_LSTR, blin_printl_args, "printl" }, - { blin_to_str, TREE_TYPE_LSTR, blin_to_str_args, "to_str" }, + { blin_str_cat, TREE_TYPE_LSTR, blin_str_cat_args, "str_cat" }, }; #endif diff --git a/src/include/parser.h b/src/include/parser.h index 6961be8..3891a5c 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -27,6 +27,9 @@ typedef struct PARSER { /* The AST being produced. */ tree_t* tree; + + /* The current parent tree node. */ + tree_t* ltree; } parser_t; /* Creates a new parser. */ diff --git a/src/include/tree.h b/src/include/tree.h index 2a62f26..e1adf85 100644 --- a/src/include/tree.h +++ b/src/include/tree.h @@ -19,6 +19,8 @@ typedef enum TREE_TYPE { typedef struct TREE { tree_type_t type; + struct TREE* parent; + union TREE_DATA{ /* Block. */ struct TREE_DATA_BLOCK { @@ -77,12 +79,11 @@ typedef struct TREE { char* target; struct TREE* arg; /* CARG */ } call; - } data; } tree_t; /* Create a new AST. */ -tree_t* tree_init(tree_type_t type); +tree_t* tree_init(tree_type_t type, tree_t* parent); /* Destroy the AST (if it exists). */ void tree_destroy(tree_t* tree); diff --git a/src/main.c b/src/main.c index 38a4269..d54e7a5 100644 --- a/src/main.c +++ b/src/main.c @@ -47,8 +47,6 @@ int main(int argc, char* argv[]) { doer_do_block(doer); target_print(doer->targets); - sudden_death: - /* Clean up. */ doer_destroy(doer); token_destroy(lexer->tokenl); diff --git a/src/parser.c b/src/parser.c index 2dcf96b..384d8ea 100644 --- a/src/parser.c +++ b/src/parser.c @@ -8,6 +8,7 @@ parser_t* parser_init(token_t* token) { parser = emalloc(sizeof(struct PARSER)); parser->token = token; parser->tree = NULL; + parser->ltree = NULL; return parser; } @@ -26,6 +27,7 @@ int parser_nxt_token(parser_t* parser) { return parser->token ? 1 : 0; } +#if 0 /* TODO: This seems like it might be useful?? tree_t* parser_parse_init(parser_t* parser) { /* There is nothing to do. */ if (!parser->token) { @@ -33,13 +35,14 @@ tree_t* parser_parse_init(parser_t* parser) { } tree_t* block; - block = tree_init(TREE_TYPE_BLOCK); + block = tree_init(TREE_TYPE_BLOCK, NULL); block->data.block.val = parser_parse_expr(parser); block->data.block.nxt = parser_parse_block(parser); return block; } +#endif tree_t* parser_parse_block(parser_t* parser) { /* There is nothing to do. */ @@ -49,9 +52,12 @@ tree_t* parser_parse_block(parser_t* parser) { } tree_t* block; - block = tree_init(TREE_TYPE_BLOCK); + block = tree_init(TREE_TYPE_BLOCK, parser->ltree); + parser->ltree = block; block->data.block.val = parser_parse_expr(parser); + + parser->ltree = block; block->data.block.nxt = parser_parse_block(parser); return block; @@ -68,12 +74,12 @@ tree_t* parser_parse_expr(parser_t* parser) { expr = parser_parse_lstr(parser); break; case TOKEN_TYPE_LBLOCK: - /* TODO: Move this into parser_parse_block, parser_parse_init exists now. */ + /* TODO: Move this into parser_parse_block, parser_parse_init exists + * now. */ parser_nxt_token(parser); /* Skip over opening curly bracket. */ expr = parser_parse_block(parser); break; case TOKEN_TYPE_KWD: -// expr = parser_parse_kwd(parser); expr = parser_parse_call(parser); break; case TOKEN_TYPE_TAG: @@ -88,12 +94,15 @@ tree_t* parser_parse_expr(parser_t* parser) { } tree_t* parser_parse_def(parser_t* parser) { - tree_t* def = tree_init(TREE_TYPE_DEF); + tree_t* def = tree_init(TREE_TYPE_DEF, parser->ltree); + parser->ltree = def; def->data.def.tag = parser_parse_tag(parser); if (parser->token->type == TOKEN_TYPE_APPLY) { parser_nxt_token(parser); /* Skip over apply. */ + + parser->ltree = def; def->data.def.arg = parser_parse_darg(parser); } else { def->data.def.arg = NULL; @@ -101,6 +110,8 @@ tree_t* parser_parse_def(parser_t* parser) { if (parser->token->type == TOKEN_TYPE_SET) { parser_nxt_token(parser); /* Skip over set. */ + + parser->ltree = def; def->data.def.val = parser_parse_expr(parser); } else { def->data.def.val = NULL; @@ -115,25 +126,29 @@ tree_t* parser_parse_tag(parser_t* parser) { parser->token->type != TOKEN_TYPE_TAG ) { return NULL; } - tree_t* tag = tree_init(TREE_TYPE_TAG); + tree_t* tag = tree_init(TREE_TYPE_TAG, parser->ltree); tag->data.tag.val = parser->token->val; parser->token->val = NULL; parser_nxt_token(parser); + parser->ltree = tag; tag->data.tag.nxt = parser_parse_tag(parser); return tag; } tree_t* parser_parse_darg(parser_t* parser) { - tree_t* darg = tree_init(TREE_TYPE_DARG); + tree_t* darg = tree_init(TREE_TYPE_DARG, parser->ltree); + parser->ltree = darg; darg->data.darg.tag = parser_parse_tag(parser); if (parser->token->type == TOKEN_TYPE_LIST_DELIM) { parser_nxt_token(parser); /* Skip over list delim. */ + + parser->ltree = darg; darg->data.darg.nxt = parser_parse_darg(parser); } else { darg->data.darg.nxt = NULL; @@ -145,11 +160,9 @@ tree_t* parser_parse_darg(parser_t* parser) { tree_t* parser_parse_carg(parser_t* parser) { tree_t* carg; - /* - f.x,y,z; - */ + carg = tree_init(TREE_TYPE_CARG, parser->ltree); - carg = tree_init(TREE_TYPE_CARG); + parser->ltree = carg; carg->data.carg.val = parser_parse_expr(parser); if ( @@ -157,6 +170,7 @@ tree_t* parser_parse_carg(parser_t* parser) { && parser->token->type == TOKEN_TYPE_LIST_DELIM && parser_nxt_token(parser) ) { + parser->ltree = carg; carg->data.carg.nxt = parser_parse_carg(parser); } else { carg->data.carg.nxt = NULL; @@ -168,7 +182,7 @@ tree_t* parser_parse_carg(parser_t* parser) { tree_t* parser_parse_kwd(parser_t* parser) { tree_t* call; - call = tree_init(TREE_TYPE_CALL); + call = tree_init(TREE_TYPE_CALL, parser->ltree); call->data.call.target = parser->token->val; parser->token->val = NULL; @@ -180,6 +194,8 @@ tree_t* parser_parse_kwd(parser_t* parser) { ) { /* Expect some arguments. */ parser_nxt_token(parser); + + parser->ltree = call; call->data.call.arg = parser_parse_carg(parser); } else { /* There're no arguments. */ @@ -202,7 +218,7 @@ int parser_nxt_token_match(parser_t* parser, token_type_t type) { tree_t* parser_parse_lint(parser_t* parser) { tree_t* lint; - lint = tree_init(TREE_TYPE_LINT); + lint = tree_init(TREE_TYPE_LINT, parser->ltree); lint->data.lint.val = atoi(parser->token->val); parser_nxt_token(parser); @@ -212,7 +228,7 @@ tree_t* parser_parse_lint(parser_t* parser) { tree_t* parser_parse_lstr(parser_t* parser) { tree_t* lstr; - lstr = tree_init(TREE_TYPE_LSTR); + lstr = tree_init(TREE_TYPE_LSTR, parser->ltree); lstr->data.lstr.len = strlen(parser->token->val); /* Move token value to tree, to allow for future token destruction. */ @@ -226,7 +242,7 @@ tree_t* parser_parse_lstr(parser_t* parser) { tree_t* parser_parse_call(parser_t* parser) { tree_t* call; - call = tree_init(TREE_TYPE_CALL); + call = tree_init(TREE_TYPE_CALL, parser->ltree); call->data.call.target = parser->token->val; parser->token->val = NULL; @@ -240,6 +256,7 @@ tree_t* parser_parse_call(parser_t* parser) { && parser->token->type == TOKEN_TYPE_APPLY && parser_nxt_token(parser) ) { + parser->ltree = call; call->data.call.arg = parser_parse_carg(parser); } else { call->data.call.arg = NULL; @@ -248,6 +265,7 @@ tree_t* parser_parse_call(parser_t* parser) { return call; } +#if 0 /* ??? */ void parser_parse(parser_t* parser) { while (parser->token) { switch (parser->token->type) { @@ -260,7 +278,9 @@ void parser_parse(parser_t* parser) { } } +#endif void parser_run(parser_t* parser) { + parser->ltree = NULL; parser->tree = parser_parse_block(parser); } diff --git a/src/tree.c b/src/tree.c index 58fba36..84334be 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1,11 +1,13 @@ #include "include/tree.h" -tree_t* tree_init(tree_type_t type) { +tree_t* tree_init(tree_type_t type, tree_t* parent) { tree_t* tree; tree = emalloc(sizeof(tree_t)); tree->type = type; + + tree->parent = parent; switch (tree->type) { case TREE_TYPE_BLOCK: @@ -153,7 +155,7 @@ void tree_print(tree_t* tree, int nest) { "\x1b[%dm",nc);sprintf(bc,"\x1b[%d;1m" ,nc);NULL;NULL;0x0;0;0;0;0;NULL;0x0;0; #define NEST0(T)LOG_RAWF("%s%s"T"\x1b"\ - """""""""""""""""""""""""[0m\n",bc,sp) + "[0m -> %d\n",bc,sp,tree->parent?tree->parent->type:-1) #define NEST1(T)LOG_RAWF("%s%s"T"\x1b"\ """""""""""""""""""""""""[0m\n",c,sp); #define NEST2(T)LOG_RAWF("%s \x1b[39;"\ -- cgit v1.2.3