commit b542c7b40aa4798d1a18f8551a814f1602a61063
parent d2b7a4b57a9ae953a046f05eb2f1c54bf026c065
Author: Eyal Sawady <ecs@d2evs.net>
Date: Thu, 2 Sep 2021 06:46:52 +0000
parse, gen: implement &unary-expression
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -2504,8 +2504,17 @@ gen_expr_unarithm(struct gen_context *ctx,
const struct expression *operand = expr->unarithm.operand;
switch (expr->unarithm.op) {
case UN_ADDRESS:
- assert(operand->type == EXPR_ACCESS);
- val = gen_expr_access_addr(ctx, operand);
+ if (operand->type == EXPR_ACCESS) {
+ val = gen_expr_access_addr(ctx, operand);
+ val.type = expr->result;
+ return val;
+ }
+ struct gen_value val = mktemp(ctx, operand->result, ".%d");
+ struct qbe_value qv = mklval(ctx, &val);
+ struct qbe_value sz = constl(val.type->size);
+ enum qbe_instr alloc = alloc_for_align(val.type->align);
+ pushprei(ctx->current, &qv, alloc, &sz, NULL);
+ gen_expr_at(ctx, operand, val);
val.type = expr->result;
return val;
case UN_DEREF:
diff --git a/src/parse.c b/src/parse.c
@@ -1486,11 +1486,7 @@ parse_unary_expression(struct lexer *lexer)
exp = mkexpr(&lexer->loc);
exp->type = EXPR_UNARITHM;
exp->unarithm.op = unop_for_token(tok.token);
- if (tok.token == T_BAND) {
- exp->unarithm.operand = parse_object_selector(lexer);
- } else {
- exp->unarithm.operand = parse_unary_expression(lexer);
- }
+ exp->unarithm.operand = parse_unary_expression(lexer);
return exp;
default:
unlex(lexer, &tok);
diff --git a/tests/29-unarithm.ha b/tests/29-unarithm.ha
@@ -4,6 +4,17 @@ fn lnot() void = {
assert(!(false: abool));
};
+fn addr() void = {
+ let x = 42;
+ let xptr = &x;
+ assert(*xptr == 42);
+ let y = &69;
+ assert(*y == 69);
+ let z = &struct { a: int = 42 };
+ assert(z.a == 42);
+};
+
export fn main() void = {
lnot();
+ addr();
};