hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 11f85693f4a3175f999555f2750fc9781a515d54
parent 636319739fc4515766685389bc8570b5a22c0e4b
Author: Sebastian <sebastian@sebsite.pw>
Date:   Fri, 29 Sep 2023 22:19:53 -0400

hare::ast: remove indirect field from assign_expr

This served no purpose other than complicating the parser: the object
can just be parsed as a unary expression, and there's no need to special
case anything.

This also fixes another bug in hare::parse: the object in an indirect
assignment expression was parsed as a cast expression rather than a
unary expression, so the following code would successfully parse:

	fn f() void = { *a: b = c; };

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mhare/ast/expr.ha | 1-
Mhare/parse/expr.ha | 35++++++++++++-----------------------
Mhare/unparse/expr.ha | 3---
3 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha @@ -93,7 +93,6 @@ export type assign_expr = struct { op: (binarithm_op | void), object: *expr, value: *expr, - indirect: bool, }; // A binary arithmetic operator diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -11,7 +11,6 @@ use strings; // Parses an expression. export fn expr(lexer: *lex::lexer) (ast::expr | error) = { const loc = lex::mkloc(lexer); - const indirect = try(lexer, ltok::TIMES)? is lex::token; // All assignment-op tokens const atoks: []ltok = [ @@ -21,25 +20,9 @@ export fn expr(lexer: *lex::lexer) (ast::expr | error) = { ltok::RSHIFTEQ, ltok::TIMESEQ, ]; - const ex: ast::expr = if (indirect) { - const ex = cast(lexer, void)?; - // Disambiguate between - // * unary-expression assignment-op expression - // and - // binary-expression - yield if (peek(lexer, atoks...)? is lex::token) { - yield ex; - } else return binarithm(lexer, ast::expr { - start = loc, - end = lex::prevloc(lexer), - expr = ast::unarithm_expr { - op = ast::unarithm_op::DEREF, - operand = alloc(ex), - }, - }, 0); - } else match (peek(lexer, ltok::IF, ltok::FOR, - ltok::BREAK, ltok::CONTINUE, ltok::RETURN, ltok::LET, - ltok::CONST, ltok::YIELD)?) { + const ex = match (peek(lexer, ltok::IF, ltok::FOR, ltok::BREAK, + ltok::CONTINUE, ltok::RETURN, ltok::LET, ltok::CONST, + ltok::YIELD)?) { case void => yield binarithm(lexer, void, 0)?; case let tok: lex::token => @@ -65,8 +48,15 @@ export fn expr(lexer: *lex::lexer) (ast::expr | error) = { return ex; }; - synassert(lex::mkloc(lexer), - ex.expr is ast::access_expr || ex.expr is ast::slice_expr || indirect, + const is_obj_selector = match (ex.expr) { + case (ast::access_expr | ast::slice_expr) => + yield true; + case let ex: ast::unarithm_expr => + yield ex.op == ast::unarithm_op::DEREF; + case => + yield false; + }; + synassert(lex::mkloc(lexer), is_obj_selector, "Expected an object-selector or slice for assignment target")?; const ex = ast::assign_expr { op = switch (tok.0) { @@ -102,7 +92,6 @@ export fn expr(lexer: *lex::lexer) (ast::expr | error) = { }, object = alloc(ex), value = alloc(expr(lexer)?), - indirect = indirect, }; return ast::expr { diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -139,9 +139,6 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { return z; case let e: ast::assign_expr => let z = 0z; - if (e.indirect) { - z += syn(ctx, "*", synkind::OPERATOR)?; - }; z += _expr(ctx, syn, *e.object)?; const op = match (e.op) { case void =>