diff options
| author | hachem <im@hachem.wtf> | 2026-09-08 11:26:42 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-08 11:26:42 +0200 |
| commit | 21be45a904a0afc767214298721bd2bbce19a054 (patch) | |
| tree | 4e97ae690457f82cbedd30bb8f7cf67898e578a5 /src/sema | |
| parent | 8d73e3f2cdba9ce3591bab5c02e5d90ce62a8de3 (diff) | |
feat: add signed memory loads
Diffstat (limited to 'src/sema')
| -rw-r--r-- | src/sema/sema.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/sema/sema.c b/src/sema/sema.c index 6505077..748ccbe 100644 --- a/src/sema/sema.c +++ b/src/sema/sema.c @@ -103,10 +103,11 @@ static bool is_program_const(const struct Program* program, struct Token name) return false; } -static struct Token first_token(struct Expr* expr) +static struct Token first_token(const struct Expr* expr) { switch (expr->kind) { + case EXPR_UNARY: return expr->unary.op; case EXPR_BINARY: return first_token(expr->binary.left); case EXPR_MEMBER: return first_token(expr->member.object); case EXPR_DEREF: return first_token(expr->deref.address); @@ -116,6 +117,9 @@ static struct Token first_token(struct Expr* expr) static bool check_const_value(struct Source source, struct Program* program, struct Expr* expr) { + if (expr->kind == EXPR_UNARY) + return check_const_value(source, program, expr->unary.operand); + if (expr->kind == EXPR_BINARY) { bool left = check_const_value(source, program, expr->binary.left); @@ -319,9 +323,18 @@ static void check_expr(struct RefCheck* check, const struct Expr* expr) check_expr(check, expr->binary.left); check_expr(check, expr->binary.right); break; + case EXPR_UNARY: + check_expr(check, expr->unary.operand); + break; case EXPR_DEREF: { const struct Expr* address = expr->deref.address; + if (expr->deref.is_signed + && expr->deref.size != STORE_SIZE_BYTE + && expr->deref.size != STORE_SIZE_WORD + && expr->deref.size != STORE_SIZE_DWORD) + ref_error(check, first_token(expr), "signed load requires a byte, word, or dword size"); + if (address->kind == EXPR_PRIMARY && (is_register(check, address->primary.token) || is_param(check, address->primary.token))) break; @@ -406,6 +419,9 @@ static void check_stack_size(struct RefCheck* check, struct Expr* expr) check_stack_size(check, expr->binary.left); check_stack_size(check, expr->binary.right); break; + case EXPR_UNARY: + check_stack_size(check, expr->unary.operand); + break; case EXPR_MEMBER: { const struct Expr* object = expr->member.object; |
