nooc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit ed10245b257fdcd941de78728a9f43645843dd07
parent 4aa0cda826d1446ab4001907042a2db0f3293b56
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue,  9 Nov 2021 17:02:45 -0600

start on expression parsing

Diffstat:
Mmain.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 71 insertions(+), 23 deletions(-)

diff --git a/main.c b/main.c @@ -83,6 +83,8 @@ enum tokentype { TOK_LPAREN, TOK_RPAREN, + TOK_PLUS, + TOK_COMMA, TOK_NUM, @@ -100,6 +102,13 @@ struct token { struct token *next; }; +void +error(char *error) +{ + fprintf(stderr, "%s\n", error); + exit(1); +} + struct token * lex(struct slice start) { @@ -158,6 +167,13 @@ lex(struct slice start) start.ptr++; start.len--; continue; + } else if (*start.ptr == '+') { + cur->type = TOK_PLUS; + start.ptr++; + start.len--; + continue; + } else { + error("invalid token"); } cur->next = calloc(1, sizeof(struct token)); @@ -180,7 +196,7 @@ enum func { struct fparams { size_t cap; size_t len; - int *data; + struct expr *data; }; struct fcall { @@ -189,13 +205,6 @@ struct fcall { }; void -error(char *error) -{ - fprintf(stderr, "%s\n", error); - exit(1); -} - -void expect(struct token *tok, enum tokentype type) { if (!tok) @@ -226,11 +235,62 @@ struct calls { struct fcall *data; }; +enum primitive { + I32, + STR, +}; + +struct value { + enum primitive type; + uint64_t val; +}; + +struct expr { + enum { + EXPR_LIT, + EXPR_BINARY + } kind; + struct value val; + struct expr *left; + struct expr *right; +}; + +struct expr +parseexpr(struct token **tok) +{ + struct expr expr = { 0 }; + while (1) { + switch ((*tok)->type) { + case TOK_NUM: + expr.kind = EXPR_LIT; + expr.val.type = I32; + expr.val.val = strtol((*tok)->slice.ptr, NULL, 10); + *tok = (*tok)->next; + break; + case TOK_STRING: + // FIXME: error check + expr.kind = EXPR_LIT; + expr.val.type = STR; + expr.val.val = data_push((*tok)->slice.ptr, (*tok)->slice.len); + *tok = (*tok)->next; + break; + default: + error("invalid token for expression"); + } + + if ((*tok)->type == TOK_COMMA || (*tok)->type == TOK_RPAREN) + break; + } + + return expr; +} + struct calls parse(struct token *tok) { struct calls calls = { 0 }; struct fcall fcall; + struct expr expr; while (tok->type != TOK_NONE) { fcall = (struct fcall){ 0 }; @@ -241,20 +301,8 @@ parse(struct token *tok) int val; while (1) { - switch (tok->type) { - case TOK_NUM: - val = strtol(tok->slice.ptr, NULL, 10); - array_add((&fcall.params), val); - tok = tok->next; - break; - case TOK_STRING: - // FIXME: error check - val = data_push(tok->slice.ptr, tok->slice.len); - array_add((&fcall.params), val); - tok = tok->next; - break; - } - + expr = parseexpr(&tok); + array_add((&fcall.params), expr); if (tok->type == TOK_RPAREN) break; expect(tok, TOK_COMMA); @@ -326,7 +374,7 @@ gensyscall(char *buf, struct fparams *params) // encoding for argument registers in ABI order for (int i = 0; i < params->len; i++) { - len += mov_r_imm(ptr ? ptr + len : ptr, abi_arg[i], params->data[i]); + len += mov_r_imm(ptr ? ptr + len : ptr, abi_arg[i], params->data[i].val.val); } if (buf) {