aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorc2024-03-23 10:52:52 -0400
committerc2024-03-23 10:52:52 -0400
commitbbcda663d5b2b2f055de12107e0abab536e5beea (patch)
treea70ec5edb9912ca3bbbf230fba6196741b2c8394 /src
parent53d5c419bdfaa58c2cf7c30e51e4515f66fa85a1 (diff)
Doubly-linked the abstract syntax tree.
Diffstat (limited to 'src')
-rw-r--r--src/doer.c13
-rw-r--r--src/include/doer.h8
-rw-r--r--src/include/parser.h3
-rw-r--r--src/include/tree.h5
-rw-r--r--src/main.c2
-rw-r--r--src/parser.c50
-rw-r--r--src/tree.c6
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 <string.h>
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;"\