summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-06-09 14:05:16 +0200
committerkdx <kikoodx@paranoici.org>2023-06-09 14:05:16 +0200
commitb951fda40057cca936867f9d8240f676fa3639ec (patch)
tree524659ec145fa41ef0ee2fdd5032fb6f3532cf95
parent7f017de4d005d4d394848c0f788d8c1f4b99d65f (diff)
downloadgolem-b951fda40057cca936867f9d8240f676fa3639ec.tar.gz
whatever
-rw-r--r--src/main.c149
1 files changed, 135 insertions, 14 deletions
diff --git a/src/main.c b/src/main.c
index a38a66a..bc40806 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);