commit 5edc06a049a5ba9530315b0de02f3aa3d41e0dad
parent 87dbd8f0783ff9fa723668540f552e0d25090bff
Author: Eyal Sawady <ecs@d2evs.net>
Date: Sat, 23 Oct 2021 15:21:14 +0000
hare::{ast,parse,unparse}: implement offset()
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -291,7 +291,7 @@ export type match_expr = struct {
// An offset expression.
//
// offset(foo.bar)
-export type offset_expr = void; // TODO
+export type offset_expr = *expr;
// An error propagation expression.
//
@@ -514,8 +514,8 @@ case e: expr =>
expr_free(m.default[i]);
};
free(m.default);
- case offset_expr =>
- abort(); // TODO
+ case o: offset_expr =>
+ expr_free(o: *expr);
case p: propagate_expr =>
expr_free(p.expr);
case r: return_expr =>
diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha
@@ -63,6 +63,7 @@
insert(x[0], foo, bar...);
static insert(x[0], foo);
len([1, 2, 3, 4]);
+ offset(foo.bar);
size(u32);
type(u32);
};
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -240,20 +240,16 @@ fn append_insert_expr(
fn measurement(lexer: *lex::lexer) (ast::expr | error) = {
const tok = want(lexer, ltok::LEN, ltok::SIZE, ltok::OFFSET)?;
+ want(lexer, ltok::LPAREN)?;
const expr = switch (tok.0) {
case ltok::LEN =>
- want(lexer, ltok::LPAREN)?;
- let e = expression(lexer)?;
- want(lexer, ltok::RPAREN)?;
- yield alloc(e): ast::len_expr;
+ yield alloc(expression(lexer)?): ast::len_expr;
case ltok::SIZE =>
- want(lexer, ltok::LPAREN)?;
- let ty = _type(lexer)?;
- want(lexer, ltok::RPAREN)?;
- yield alloc(ty): ast::size_expr;
+ yield alloc(_type(lexer)?): ast::size_expr;
case ltok::OFFSET =>
- abort(); // TODO
+ yield alloc(expression(lexer)?): ast::offset_expr;
};
+ want(lexer, ltok::RPAREN)?;
return ast::expr {
start = tok.2,
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -319,7 +319,11 @@ export fn expr(
z += _type(out, indent, *e)?;
z += fmt::fprint(out, ")")?;
return z;
- case ast::offset_expr => abort(); // TODO
+ case e: ast::offset_expr =>
+ let z = fmt::fprint(out, "offset(")?;
+ z += expr(out, indent, *e)?;
+ z += fmt::fprint(out, ")")?;
+ return z;
case e: ast::propagate_expr =>
let z = expr(out, indent, *e.expr)?;
z += fmt::fprintf(out, if (e.is_abort) "!" else "?")?;