diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 56 |
1 files changed, 54 insertions, 2 deletions
@@ -90,6 +90,8 @@ is_punct(const char *p) { if (strchr("=!<>", p[0]) != NULL && p[1] == '=') return 2; + if (strchr("-+", p[0]) != NULL && p[0] == p[1]) + return 2; return (strchr("+-/*()<>,;{}[]=&^|", p[0]) != NULL); } @@ -198,6 +200,7 @@ typedef enum { NOD_DBG_STMT, NOD_WRT_STMT, NOD_ASSIGN_STMT, + NOD_POSTFIX_STMT, NOD_IFELSE_STMT, NOD_LOOP_STMT, NOD_FUN, @@ -280,8 +283,6 @@ new_node(NodeType type) static Node * new_word(Token *tok) { - expect(tok, TOK_WORD); - Node *const node = new_node(NOD_WORD); node->loc = tok->loc; node->len = tok->len; @@ -324,6 +325,7 @@ static Node *break_stmt(Token **rest, Token *tok); static Node *slp_stmt(Token **rest, Token *tok); static Node *dbg_stmt(Token **rest, Token *tok); static Node *wrt_stmt(Token **rest, Token *tok); +static Node *postfix_stmt(Token **rest, Token *tok); static Node *assign_stmt(Token **rest, Token *tok); static Node *ifelse_stmt(Token **rest, Token *tok); static Node *loop_stmt(Token **rest, Token *tok); @@ -652,6 +654,8 @@ stmt(Token **rest, Token *tok) } if (equal(tok->next, "=")) return assign_stmt(rest, tok); + if (equal(tok->next, "++") || equal(tok->next, "--")) + return postfix_stmt(rest, tok); return expr_stmt(rest, tok); } @@ -728,6 +732,19 @@ wrt_stmt(Token **rest, Token *tok) } static Node * +postfix_stmt(Token **rest, Token *tok) +{ + Node *lhs; + expect(tok, TOK_WORD); + lhs = new_word(tok); + tok = tok->next; + expect(tok, TOK_PUNCT); + Node *const node = new_binary(NOD_POSTFIX_STMT, lhs, new_word(tok)); + *rest = skip(tok->next, ";"); + return node; +} + +static Node * assign_stmt(Token **rest, Token *tok) { Node *lhs; @@ -942,6 +959,38 @@ gen_assign_stmt(Node *node) } static void +gen_postfix_stmt(Node *node) +{ + const int found = node_find(locals, node->lhs); + + if (found != -1) { + printf("\tLIT ,__stack_ptr LDA\n"); + if (locals_size - found - 1) + printf("\tLIT %04x SUB\n", + locals_size - found - 1); + } else + printf("\tLIT ,__gl_%.*s\n", + node->lhs->len, node->lhs->loc); + printf("\tLDA\n"); + + if (node_equal(node->rhs, "++")) + printf("\tINC\n"); + else if (node_equal(node->rhs, "--")) + printf("\tDEC\n"); + + if (found != -1) { + printf("\tLIT ,__stack_ptr LDA\n"); + if (locals_size - found - 1) + printf("\tLIT %04x SUB\n", + locals_size - found - 1); + } else + printf("\tLIT ,__gl_%.*s\n", + node->lhs->len, node->lhs->loc); + + printf("\tSTA\n"); +} + +static void gen_stmt(Node *node, Node *fname, int break_lbl) { static int label = 0; @@ -989,6 +1038,9 @@ gen_stmt(Node *node, Node *fname, int break_lbl) case NOD_ASSIGN_STMT: gen_assign_stmt(node); break; + case NOD_POSTFIX_STMT: + gen_postfix_stmt(node); + break; case NOD_IFELSE_STMT: lbl = label; label += 1 + (node->rhs->next != NULL); |