diff options
author | kdx <kikoodx@paranoici.org> | 2023-06-10 04:15:11 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-06-10 04:15:11 +0200 |
commit | 0e97b7a73a142c91268a605e3b0cf024a9a48981 (patch) | |
tree | c369bb288126dde063da4517e1126ff9b085dd3e | |
parent | 1f5785079299da2f3485203eceb7bc7038d8dc45 (diff) | |
download | golem-0e97b7a73a142c91268a605e3b0cf024a9a48981.tar.gz |
move stack pointer
-rw-r--r-- | src/main.c | 47 |
1 files changed, 44 insertions, 3 deletions
@@ -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 |