diff options
author | kdx <kikoodx@paranoici.org> | 2023-06-09 14:05:16 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-06-09 14:05:16 +0200 |
commit | b951fda40057cca936867f9d8240f676fa3639ec (patch) | |
tree | 524659ec145fa41ef0ee2fdd5032fb6f3532cf95 | |
parent | 7f017de4d005d4d394848c0f788d8c1f4b99d65f (diff) | |
download | golem-b951fda40057cca936867f9d8240f676fa3639ec.tar.gz |
whatever
-rw-r--r-- | src/main.c | 149 |
1 files changed, 135 insertions, 14 deletions
@@ -80,10 +80,13 @@ new_token(TokenType type, char *start, char *end) return tok; } -static bool -is_punct(int c) +static int +is_punct(const char *p) { - return (strchr("+-/*();", c) != NULL); + if (strchr("=!<>", p[0]) != NULL && p[1] == '=') + return 2; + + return (strchr("+-/*()<>;", p[0]) != NULL); } static Token * @@ -106,9 +109,10 @@ tokenize(char *p) continue; } - if (is_punct(*p)) { - cur = cur->next = new_token(TOK_PUNCT, p, p + 1); - p += 1; + const int punct = is_punct(p); + if (punct) { + cur = cur->next = new_token(TOK_PUNCT, p, p + punct); + p += punct; continue; } @@ -128,11 +132,16 @@ tokenize(char *p) } typedef enum { - NOD_ADD, - NOD_SUB, - NOD_MUL, - NOD_DIV, - NOD_NUM, + NOD_ADD, // + + NOD_SUB, // - + NOD_MUL, // * + NOD_DIV, // / + NOD_EQU, // == + NOD_NEQ, // != + NOD_LT, // < + NOD_LE, // <= + NOD_NUM, // integer + NOD_EXPR_STMT, } NodeType; typedef struct Node Node; @@ -140,6 +149,7 @@ struct Node { NodeType type; Node *lhs; Node *rhs; + Node *next; int val; }; @@ -163,6 +173,12 @@ new_binary(NodeType type, Node *lhs, Node *rhs) } static Node * +new_unary(NodeType type, Node *node) +{ + return new_binary(type, node, NULL); +} + +static Node * new_num(int val) { Node *const node = new_node(NOD_NUM); @@ -171,12 +187,74 @@ new_num(int val) } static Node *expr(Token **rest, Token *tok); +static Node *expr_stmt(Token **rest, Token *tok); +static Node *equality(Token **rest, Token *tok); +static Node *relational(Token **rest, Token *tok); +static Node *add(Token **rest, Token *tok); static Node *mul(Token **rest, Token *tok); static Node *primary(Token **rest, Token *tok); -// expr = mul ("+" mul | "-" mul)* +static Node +*expr(Token **rest, Token *tok) +{ + return equality(rest, tok); +} + +static Node +*equality(Token **rest, Token *tok) +{ + Node *node = relational(&tok, tok); + +for (;;) { + if (equal(tok, "==")) { + node = new_binary(NOD_EQU, node, relational(&tok, tok->next)); + continue; + } + + if (equal(tok, "!=")) { + node = new_binary(NOD_NEQ, node, relational(&tok, tok->next)); + continue; + } + + *rest = tok; + return node; + } +} + +static Node +*relational(Token **rest, Token *tok) +{ + Node *node = add(&tok, tok); + + for (;;) { + if (equal(tok, "<")) { + node = new_binary(NOD_LT, node, add(&tok, tok->next)); + continue; + } + + if (equal(tok, "<=")) { + node = new_binary(NOD_LE, node, add(&tok, tok->next)); + continue; + } + + if (equal(tok, ">")) { + node = new_binary(NOD_LT, add(&tok, tok->next), node); + continue; + } + + if (equal(tok, ">=")) { + node = new_binary(NOD_LE, add(&tok, tok->next), node); + continue; + } + + *rest = tok; + return node; + } +} + +// add = mul ("+" mul | "-" mul)* static Node * -expr(Token **rest, Token *tok) +add(Token **rest, Token *tok) { Node *node = mul(&tok, tok); @@ -237,6 +315,20 @@ primary(Token **rest, Token *tok) return NULL; } +static Node * +stmt(Token **rest, Token *tok) +{ + return expr_stmt(rest, tok); +} + +static Node +*expr_stmt(Token **rest, Token *tok) +{ + Node *const node = new_unary(NOD_EXPR_STMT, expr(&tok, tok)); + *rest = skip(tok, ";"); + return node; +} + // code generator static int depth; @@ -267,6 +359,18 @@ gen_expr(Node *node) case NOD_DIV: printf("\tDIV\n"); return; + case NOD_EQU: + printf("\tEQU\n"); + return; + case NOD_NEQ: + printf("\tNEQ\n"); + return; + case NOD_LT: + printf("\tLTH\n"); + return; + case NOD_LE: + printf("\tGTH NOT\n"); + return; default: break; } @@ -274,6 +378,23 @@ gen_expr(Node *node) error("invalid expression %d", node->type); } +static void +codegen(Node *node) +{ + gen_expr(node); +} + +// program = stmt* +static Node * +parse(Token *tok) +{ + Node head = {0}; + Node *cur = &head; + while (tok->type != TOK_EOF) + cur = cur->next = stmt(&tok, tok); + return head.next; +} + int main(int argc, char **argv) { @@ -288,7 +409,7 @@ main(int argc, char **argv) error("extra token"); printf("main:\n"); - gen_expr(node); + codegen(node); printf("\tRET\n"); assert(depth == 1); |