diff options
| author | hachem <im@hachem.wtf> | 2026-08-31 16:56:40 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-31 16:56:40 +0200 |
| commit | 53aed3fadf1f7ad66dea9a8a0b46bf42eda921be (patch) | |
| tree | ea14a08b29a18072d1e420353a39c1397f85bee2 /src/parser | |
| parent | f8a2d02c75df62f74e5907696d5a99a024d59018 (diff) | |
feat: add memory loads via ^reg
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/ast.c | 3 | ||||
| -rw-r--r-- | src/parser/ast.h | 26 | ||||
| -rw-r--r-- | src/parser/parser.c | 41 |
3 files changed, 48 insertions, 22 deletions
diff --git a/src/parser/ast.c b/src/parser/ast.c index 96ee479..f9f857d 100644 --- a/src/parser/ast.c +++ b/src/parser/ast.c @@ -18,6 +18,9 @@ void free_expr(struct Expr* expr) case EXPR_MEMBER: free_expr(expr->member.object); break; + case EXPR_DEREF: + free_expr(expr->deref.address); + break; } free(expr); diff --git a/src/parser/ast.h b/src/parser/ast.h index a98f43b..fc7af2b 100644 --- a/src/parser/ast.h +++ b/src/parser/ast.h @@ -24,11 +24,21 @@ struct Param struct Token reg; }; +enum StoreSize +{ + STORE_SIZE_NONE, + STORE_SIZE_BYTE, + STORE_SIZE_WORD, + STORE_SIZE_DWORD, + STORE_SIZE_QWORD, +}; + enum ExprKind { EXPR_PRIMARY, EXPR_BINARY, EXPR_MEMBER, + EXPR_DEREF, }; struct PrimaryExpr @@ -49,6 +59,12 @@ struct MemberExpr struct Token member; }; +struct DerefExpr +{ + enum StoreSize size; + struct Expr* address; +}; + struct Expr { enum ExprKind kind; @@ -57,18 +73,10 @@ struct Expr struct PrimaryExpr primary; struct BinaryExpr binary; struct MemberExpr member; + struct DerefExpr deref; }; }; -enum StoreSize -{ - STORE_SIZE_NONE, - STORE_SIZE_BYTE, - STORE_SIZE_WORD, - STORE_SIZE_DWORD, - STORE_SIZE_QWORD, -}; - enum StatementKind { STATEMENT_ASSIGN, diff --git a/src/parser/parser.c b/src/parser/parser.c index beb6b04..969ed86 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -133,8 +133,35 @@ static struct Expr* alloc_expr(enum ExprKind kind) return expr; } +static enum StoreSize parse_store_size(struct Parser* parser) +{ + if (match_token(parser, TOKEN_BYTE)) + return STORE_SIZE_BYTE; + if (match_token(parser, TOKEN_WORD)) + return STORE_SIZE_WORD; + if (match_token(parser, TOKEN_DWORD)) + return STORE_SIZE_DWORD; + if (match_token(parser, TOKEN_QWORD)) + return STORE_SIZE_QWORD; + return STORE_SIZE_NONE; +} + static struct Expr* parse_primary(struct Parser* parser) { + if (match_token(parser, TOKEN_CARET)) + { + enum StoreSize size = parse_store_size(parser); + + struct Expr* address = parse_primary(parser); + if (address == NULL) + return NULL; + + struct Expr* deref = alloc_expr(EXPR_DEREF); + deref->deref.size = size; + deref->deref.address = address; + return deref; + } + if (check(parser, TOKEN_IDENTIFIER) || check(parser, TOKEN_INTEGER) || check(parser, TOKEN_CHAR)) { advance_parser(parser); @@ -350,19 +377,7 @@ static bool parse_statement(struct Parser* parser, struct Statement* out) } bool deref = match_token(parser, TOKEN_CARET); - - enum StoreSize store_size = STORE_SIZE_NONE; - if (deref) - { - if (match_token(parser, TOKEN_BYTE)) - store_size = STORE_SIZE_BYTE; - else if (match_token(parser, TOKEN_WORD)) - store_size = STORE_SIZE_WORD; - else if (match_token(parser, TOKEN_DWORD)) - store_size = STORE_SIZE_DWORD; - else if (match_token(parser, TOKEN_QWORD)) - store_size = STORE_SIZE_QWORD; - } + enum StoreSize store_size = deref ? parse_store_size(parser) : STORE_SIZE_NONE; if (!consume(parser, TOKEN_IDENTIFIER, "expected a statement")) return false; |
