summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-06-10 04:15:11 +0200
committerkdx <kikoodx@paranoici.org>2023-06-10 04:15:11 +0200
commit0e97b7a73a142c91268a605e3b0cf024a9a48981 (patch)
treec369bb288126dde063da4517e1126ff9b085dd3e
parent1f5785079299da2f3485203eceb7bc7038d8dc45 (diff)
downloadgolem-0e97b7a73a142c91268a605e3b0cf024a9a48981.tar.gz
move stack pointer
-rw-r--r--src/main.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/main.c b/src/main.c
index fb90340..3944956 100644
--- a/src/main.c
+++ b/src/main.c
@@ -164,6 +164,7 @@ typedef enum {
NOD_WORD,
NOD_FNCALL,
NOD_GLOBAL,
+ NOD_LOCAL,
} NodeType;
typedef struct Node Node;
@@ -188,6 +189,14 @@ node_size(const Node *node)
return size;
}
+static Node *
+node_tail(Node *node)
+{
+ while (node != NULL && node->next != NULL)
+ node = node->next;
+ return node;
+}
+
static bool
node_equal(const Node *node, const char *op)
{
@@ -241,6 +250,7 @@ new_num(int val)
static Node *stmt(Token **rest, Token *tok);
static Node *function(Token **rest, Token *tok);
static Node *global(Token **rest, Token *tok);
+static Node *local(Token **rest, Token *tok);
static Node *expr(Token **rest, Token *tok);
static Node *expr_stmt(Token **rest, Token *tok);
static Node *return_stmt(Token **rest, Token *tok);
@@ -276,6 +286,10 @@ function(Token **rest, Token *tok)
head.next = NULL;
cur = &head;
+
+ while (tok->type != TOK_EOF && equal(tok, "local"))
+ cur = cur->next = local(&tok, tok);
+
while (tok->type != TOK_EOF && !equal(tok, "}"))
cur = cur->next = stmt(&tok, tok);
tok = skip(tok, "}");
@@ -305,6 +319,15 @@ global(Token **rest, Token *tok)
}
static Node *
+local(Token **rest, Token *tok)
+{
+ tok = skip(tok, "local");
+ Node *const node = new_unary(NOD_LOCAL, new_word(tok));
+ *rest = skip(tok->next, ";");
+ return node;
+}
+
+static Node *
expr(Token **rest, Token *tok)
{
return equality(rest, tok);
@@ -600,13 +623,26 @@ gen_globalget(Node *node)
static void
gen_function(Node *node)
{
+ Node *const ognode = node;
printf("@__fn_%.*s\n", node->lhs->len, node->lhs->loc);
/* GOTO */
locals = node->lhs->next;
- fprintf(stderr, "argcount %d\n", node_size(locals));
+ const int argcount = node_size(locals);
+ Node *cur = node_tail(locals);
node = node->rhs;
+ while (node->type == NOD_LOCAL) {
+ cur = cur->next = node->lhs;
+ node = node->next;
+ }
+
+ const int locals_size = node_size(locals);
+
+ printf("\tLIT ,__stack_ptr LDA\n");
+ printf("\tLIT %04x ADD\n", locals_size);
+ printf("\tLIT ,__stack_ptr STA\n");
+
while (node != NULL) {
switch (node->type) {
case NOD_EXPR_STMT:
@@ -616,7 +652,7 @@ gen_function(Node *node)
break;
case NOD_RETURN_STMT:
gen_expr(node->lhs);
- printf("\tRET\n");
+ printf("\tJMP ,__fnret_%.*s\n", ognode->lhs->len, ognode->lhs->loc);
depth -= 1;
break;
case NOD_WRT_STMT:
@@ -636,7 +672,12 @@ gen_function(Node *node)
node = node->next;
}
- printf("\tLIT 0000 ( default return )\n\tRET\n");
+ printf("\tLIT 0000 ( default return )\n");
+ printf("@__fnret_%.*s\n", ognode->lhs->len, ognode->lhs->loc);
+ printf("\tLIT ,__stack_ptr LDA\n");
+ printf("\tLIT %04x SUB\n", locals_size);
+ printf("\tLIT ,__stack_ptr STA\n");
+ printf("\tRET\n");
}
static void