aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doer.c106
-rw-r--r--src/include/doer.h1
-rw-r--r--src/include/tree.h3
-rw-r--r--src/main.c39
-rw-r--r--src/tree.c57
5 files changed, 162 insertions, 44 deletions
diff --git a/src/doer.c b/src/doer.c
index 6d38bd3..14d7d02 100644
--- a/src/doer.c
+++ b/src/doer.c
@@ -351,66 +351,84 @@ void doer_do_call(doer_t* doer) {
if (!resolved) {
doer->tree = the_call;
- target_def = doer_find_target_from_call(doer); // Is def.
-
- tree_t* darg = target_def->data.def.arg;
- LOG_DBGF("------------------------------");
- tree_print(darg, 0);
+ resolved = doer_do_call_target(doer);
+ }
+
+ target_print(doer->targets);
+
+ tree_swp_call(the_call, resolved);
+ tree_destroy(the_call);
+ doer->tree = resolved;
+}
+tree_t* doer_do_call_target(doer_t* doer) {
+ tree_t* the_call = doer->tree;
+ tree_t* target_def = doer_find_target_from_call(doer); // Is def.
- tree_t* carg = the_call->data.call.arg;
+ tree_t* resolution;
- target_t
- * targs = NULL, // Pointer to first target.
- * targ = targs; // Pointer to where new targets will be added.
+ tree_t* darg = target_def->data.def.arg;
+ tree_t* carg = the_call->data.call.arg;
- // Evaluate arguments.
- while (darg) {
- doer->tree = carg->data.carg.val;
- // HACK: Assume already a primitive.
- tree_t* carg_resolved = doer->tree; //doer_eval_prim(doer);
+ LOG_DBG("DARG:\n");
+ tree_print(darg, 0);
- char
- * darg_type = darg->data.darg.tag->data.tag.val,
- * carg_type = tree_type2str(carg_resolved->type);
+ LOG_DBG("CARG:\n");
+ tree_print(carg, 0);
- if (strcmp(darg_type, carg_type)) DIE("Type mismatch.");
+ target_t
+ * targs = NULL, // Pointer to first target.
+ * targ = targs; // Pointer to where new targets will be added.
- targ = target_init(
- "This field doesn't actually do anything but I can't be bothered to remove it :P",
- carg_resolved
- );
+ // Evaluate arguments.
+ while (darg) {
+ doer->tree = carg->data.carg.val;
+ // HACK: Assume already a primitive.
+ tree_t* carg_resolved = doer->tree; //doer_eval_prim(doer);
- targ = targ->nxt;
- darg = darg->data.darg.nxt;
+ char
+ * darg_type = darg->data.darg.tag->data.tag.val,
+ * carg_type = tree_type2str(carg_resolved->type);
- printf("\n\n[---\n");
- for (target_t* t = doer->targets; t; printf("%s\n", t->tree->data.def.tag->data.tag.nxt->data.tag.val) && (t = t->nxt));
- printf("---]\n");
- }
+ if (strcmp(darg_type, carg_type)) DIE("Type mismatch.");
+
+ tree_t* carg_tree_def = tree_init(TREE_TYPE_DEF, NULL);
+ tree_t* carg_tree_def_arg1 = carg_tree_def->data.def.tag = tree_init(TREE_TYPE_TAG, carg_tree_def); // Type.
+ carg_tree_def_arg1->data.tag.val = darg_type; // Get type of the definition arg.
+ tree_t* carg_tree_def_arg2 = carg_tree_def_arg1->data.tag.nxt = tree_init(TREE_TYPE_TAG, carg_tree_def_arg1); // Name.
+ carg_tree_def_arg2->data.tag.val = darg->data.darg.tag->data.tag.nxt->data.tag.val; // Get the name of the definition arg.
- target_t* old_ltarget = doer->ltarget;
+ targ = target_init(
+ "This field doesn't actually do anything but I can't be bothered to remove it :P",
+ carg_tree_def
+ );
- // Append the new targets from the args.
- doer->ltarget->nxt = targs;
- doer->ltarget = targ;
+ targ = targ->nxt;
+ darg = darg->data.darg.nxt;
- // Execute the call.
- doer->tree = target_def->data.def.val;
- printf("[---\n");
+ printf("\n\n[---\n");
for (target_t* t = doer->targets; t; printf("%s\n", t->tree->data.def.tag->data.tag.nxt->data.tag.val) && (t = t->nxt));
printf("---]\n");
- resolved = doer_eval_prim(doer);
-
- // Clean up temporary targets.
- target_destroy(targs);
- old_ltarget->nxt = NULL;
- doer->ltarget = old_ltarget;
}
- tree_swp_call(the_call, resolved);
- tree_destroy(the_call);
- doer->tree = resolved;
+ target_t* old_ltarget = doer->ltarget;
+
+ // Append the new targets from the args.
+ doer->ltarget->nxt = targs;
+ doer->ltarget = targ;
+
+ // Execute the call.
+ doer->tree = target_def->data.def.val;
+ printf("[---\n");
+ for (target_t* t = doer->targets; t; printf("%s\n", t->tree->data.def.tag->data.tag.nxt->data.tag.val) && (t = t->nxt));
+ printf("---]\n");
+
+ // Clean up temporary targets.
+ target_destroy(targs);
+ old_ltarget->nxt = NULL;
+ doer->ltarget = old_ltarget;
+
+ return doer_eval_prim(doer);
}
tree_t* doer_do_call_blin(doer_t* doer) {
diff --git a/src/include/doer.h b/src/include/doer.h
index 24f3911..4cc2391 100644
--- a/src/include/doer.h
+++ b/src/include/doer.h
@@ -82,6 +82,7 @@ static tree_type_t blin_mul_args[] = { TREE_TYPE_LINT, TREE_TYPE_LINT };
void doer_do_call(doer_t* doer);
tree_t* doer_do_call_blin(doer_t* doer);
tree_t* doer_do_call_def(doer_t* doer);
+tree_t* doer_do_call_target(doer_t* doer);
tree_t* doer_do_carg(doer_t* doer);
void doer_do_block(doer_t* tree);
void doer_do_expr(doer_t* tree);
diff --git a/src/include/tree.h b/src/include/tree.h
index d22efc1..5208080 100644
--- a/src/include/tree.h
+++ b/src/include/tree.h
@@ -92,6 +92,9 @@ void tree_rm(tree_t* t);
tree_t* tree_copy_out(tree_t* tree);
+// Copies a tree to `dest`.
+void tree_cpy(tree_t** dest, tree_t* src);
+
/*
Compare two trees. For testing.
Returns 1 if the same, otherwise 0.
diff --git a/src/main.c b/src/main.c
index d54e7a5..20eb42e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,8 +1,47 @@
#include "include/main.h"
#include "include/doer.h"
+#include "../test/include/test.h"
+
+void test_tree_cpy() {
+ tree_t* tree_block = tree_init(TREE_TYPE_BLOCK, NULL);
+ tree_t* tree_lstr = tree_block->data.block.val = tree_init(TREE_TYPE_LSTR, tree_block);
+ char* char_lstr = tree_lstr->data.lstr.val = calloc(12, sizeof(char));
+ strcpy(char_lstr, "hello world");
+ tree_lstr->data.lstr.len = 11;
+ tree_t* tree_block2 = tree_block->data.block.nxt = tree_init(TREE_TYPE_BLOCK, tree_block);
+ tree_t* tree_def = tree_block2->data.block.val = tree_init(TREE_TYPE_DEF, tree_block2);
+ tree_t* tree_tag = tree_def->data.def.tag = tree_init(TREE_TYPE_TAG, tree_def);
+ char* char_tag = tree_tag->data.tag.val = calloc(4, sizeof(char));
+ strcpy(char_tag, "int");
+ tree_tag->data.tag.nxt = NULL;
+ tree_t* tree_darg = tree_def->data.def.arg = tree_init(TREE_TYPE_DARG, tree_def);
+ tree_t* tree_tag2 = tree_darg->data.darg.tag = tree_init(TREE_TYPE_TAG, tree_darg);
+ char* char_tag2 = tree_tag2->data.tag.val = calloc(4, sizeof(char));
+ strcpy(char_tag2, "int");
+ tree_tag2->data.tag.nxt = NULL;
+ tree_darg->data.darg.nxt = NULL;
+ tree_t* tree_lint = tree_def->data.def.val = tree_init(TREE_TYPE_LINT, tree_def);
+ tree_lint->data.lint.val = 42;
+ tree_block2->data.block.nxt = NULL;
+
+ tree_t* t2 = malloc(sizeof(tree_t));
+
+ tree_cpy(&t2, tree_block);
+
+ printf(tree_cmp(tree_block, t2)?"yes":"no");
+
+ tree_print(tree_block, 0);
+ tree_print(t2, 0);
+
+
+ printf(&t2 != &tree_block ?"yes":"no");
+}
+
/* FIXME: Segfaults ~30% of the time. No idea why. Thx future self <3. */
int main(int argc, char* argv[]) {
+ test_tree_cpy();
+ return 0;
char* src;
pp_t* pp;
lexer_t* lexer;
diff --git a/src/tree.c b/src/tree.c
index 916936d..beef0b7 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -113,11 +113,68 @@ void tree_destroy(tree_t* tree) {
free(tree);
}
+void tree_cpy(tree_t** dest, tree_t* src) {
+ if (!src) { *dest = NULL; return; }
+
+ *dest = malloc(sizeof(tree_t));
+
+ memcpy(&(*dest)->data, &src->data, sizeof(union TREE_DATA));
+
+ switch (src->type) {
+ case TREE_TYPE_BLOCK:
+ tree_cpy(&(*dest)->data.block.val, src->data.block.val);
+ tree_cpy(&(*dest)->data.block.nxt, src->data.block.nxt);
+ break;
+ case TREE_TYPE_EXPR:
+ // TODO: fix.
+ DIE("this shouldn't be here");
+ tree_cpy(&(*dest)->data.expr.val, src->data.expr.val);
+ break;
+ case TREE_TYPE_LINT:
+ break;
+ case TREE_TYPE_LSTR:
+ (*dest)->data.lstr.val = malloc(
+ (src->data.lstr.len + 1) * sizeof(char)
+ );
+
+ strcpy((*dest)->data.lstr.val, src->data.lstr.val);
+ break;
+ case TREE_TYPE_TAG:
+ (*dest)->data.tag.val = malloc(sizeof(src->data.tag.val));
+ strcpy((*dest)->data.tag.val, src->data.tag.val);
+
+ tree_cpy(&(*dest)->data.tag.nxt, src->data.tag.nxt);
+ break;
+ case TREE_TYPE_DARG:
+ tree_cpy(&(*dest)->data.darg.tag, src->data.darg.tag);
+ tree_cpy(&(*dest)->data.darg.nxt, src->data.darg.nxt);
+ break;
+ case TREE_TYPE_CARG:
+ tree_cpy(&(*dest)->data.carg.val, src->data.carg.val);
+ tree_cpy(&(*dest)->data.carg.nxt, src->data.carg.nxt);
+ break;
+ case TREE_TYPE_DEF:
+ tree_cpy(&(*dest)->data.def.tag, src->data.def.tag);
+ tree_cpy(&(*dest)->data.def.arg, src->data.def.arg);
+ tree_cpy(&(*dest)->data.def.val, src->data.def.val);
+ break;
+ case TREE_TYPE_CALL:
+ (*dest)->data.call.target = malloc(sizeof(src->data.call.target));
+ strcpy((*dest)->data.call.target, src->data.call.target);
+
+ tree_cpy(&(*dest)->data.call.arg, src->data.call.arg);
+ break;
+ }
+}
+
+// TODO: Does this function actually do anything??
+#if 0
tree_t* tree_copy_out(tree_t* tree) {
tree_t* newt = tree_init(tree->type, tree->parent);
memcpy(&newt->data, &tree->data, sizeof(newt->data));
return newt;
}
+#endif
int tree_cmp(tree_t* tree_0, tree_t* tree_1) {
if ((tree_0 && !tree_1) || (!tree_0 && tree_1)) { return 0; } /* Only 1 is defined (failure). */