aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorc2024-03-04 13:11:29 -0500
committerc2024-03-04 13:11:29 -0500
commit9a7e88e33213135da7c8fa3607ca455d997f4a39 (patch)
treecb0f7af69ff765656378eb69dd4cf63e9f86934f /src
parent96c63e2fc4d70f20c8e2bac79e3547dfd6a5fcb8 (diff)
One can now load simple variables into memory.
Diffstat (limited to 'src')
-rw-r--r--src/doer.c53
-rw-r--r--src/include/doer.h36
-rw-r--r--src/main.c2
3 files changed, 83 insertions, 8 deletions
diff --git a/src/doer.c b/src/doer.c
index f446011..11aaeac 100644
--- a/src/doer.c
+++ b/src/doer.c
@@ -1,6 +1,28 @@
#include "include/doer.h"
#include "include/tree.h"
-#include "include/util.h"
+#include "include/util.h"
+
+target_t* target_init(char* name, tree_t* tree) {
+ target_t* target = emalloc(sizeof(target_t));
+ target->name = name;
+ target->tree = tree;
+ target->nxt = NULL;
+ return target;
+}
+
+void target_destroy(target_t* target) {
+ if (target) {
+ target_destroy(target->nxt);
+ free(target->name);
+ free(target);
+ }
+}
+
+void target_print(target_t* target) {
+ if (!target) return;
+ LOG_DBGF("target: %s; points to tree: %p", target->name, target->tree);
+ target_print(target->nxt);
+}
/* Creates a new doer from a tree. */
doer_t* doer_init(tree_t* tree) {
@@ -9,6 +31,8 @@ doer_t* doer_init(tree_t* tree) {
doer = emalloc(sizeof(doer_t));
doer->tree = tree;
+ doer->targets = NULL;
+ doer->ltarget = doer->targets;
return doer;
}
@@ -21,20 +45,27 @@ void doer_destroy(doer_t* doer) {
free(doer);
}
-void doer_do_blin_print(doer_t* doer) {
+void doer_add_target(doer_t* doer, target_t* target) {
+ // First target being added.
+ if (!doer->targets) doer->targets = doer->ltarget = target;
+ else doer->ltarget->nxt = target;
+}
+
+void blin_print(doer_t* doer) {
printf(
"%s",
doer->tree->data.call.arg->data.carg.val->data.lstr.val
);
}
-void doer_do_blin_printl(doer_t* doer) {
+void blin_printl(doer_t* doer) {
printf(
"%s\n",
doer->tree->data.call.arg->data.carg.val->data.lstr.val
);
}
+
void doer_do_block(doer_t* doer) {
if (!doer->tree) return;
@@ -52,11 +83,27 @@ void doer_do_expr(doer_t* doer) {
/* Assume only call is `print` for now. */
doer_do_call(doer);
break;
+ case TREE_TYPE_DEF:
+ doer_do_def(doer);
+ break;
default:
LOG_WARF("unknown tree type: %d", doer->tree->type);
}
}
+void doer_do_def(doer_t* doer) {
+ 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,
+ doer->tree
+ );
+
+ doer_add_target(doer, target);
+}
+
void doer_do_call(doer_t* doer) {
/* Search through built-in functions first. */
for (int i = 0; i < sizeof(blinfs) / sizeof(blinf_t); i++) {
diff --git a/src/include/doer.h b/src/include/doer.h
index 8f51266..afa80dd 100644
--- a/src/include/doer.h
+++ b/src/include/doer.h
@@ -4,8 +4,29 @@
#include "util.h"
#include "tree.h"
+typedef struct TARGET {
+ char* name; // The name of the target (unique).
+ tree_t* tree; // The tree to which the target refers.
+ struct TARGET* nxt; // The next target in the list.
+} target_t;
+
+target_t* target_init(char* name, tree_t* tree);
+/*
+ Destroy a target.
+ - Destroys all subsequent targets.
+ - Frees `name`.
+ - Does not free `tree`.
+ Remember to NULL a parent target's `nxt`.
+*/
+void target_destroy(target_t* target);
+// Print out the target list. Useful for debugging.
+void target_print(target_t* target);
+
typedef struct DOER {
- tree_t* tree;
+ tree_t* tree; // The tree the doer is reading from.
+ target_t* targets; // The targets the doer must remember.
+ target_t* ltarget; // The last target in the list (after which new
+ // targets will be appended.)
} doer_t;
/* Creates a new parser. */
@@ -23,8 +44,13 @@ typedef struct BLINF {
char name[24];
} blinf_t;
-void doer_do_blin_print(doer_t* tree); // Built-in function `print`.
-void doer_do_blin_printl(doer_t* tree); // Built-in function `print`.
+void doer_add_target(doer_t* doer, target_t* target);
+
+// Built-in functions.
+// `print`: print a string.
+void blin_print(doer_t* tree);
+// `printl`: print a string, and add a newline.
+void blin_printl(doer_t* tree);
void doer_do_block(doer_t* tree);
void doer_do_expr(doer_t* tree);
@@ -37,8 +63,8 @@ void doer_do_def(doer_t* tree);
void doer_do_call(doer_t* tree);
const static blinf_t blinfs[] = {
- { doer_do_blin_print, "print" },
- { doer_do_blin_printl, "printl" }
+ { blin_print, "print" },
+ { blin_printl, "printl" }
};
#endif
diff --git a/src/main.c b/src/main.c
index e7d345d..2a1507e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,5 @@
#include "include/main.h"
+#include "include/doer.h"
/* FIXME: Segfaults ~30% of the time. No idea why. Thx future self <3. */
int main(int argc, char* argv[]) {
@@ -42,6 +43,7 @@ int main(int argc, char* argv[]) {
doer_t* doer = doer_init(parser->tree);
doer_do_block(doer);
+ target_print(doer->targets);
/* Clean up. */
doer_destroy(doer);