hare

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

commit 851cc1e1b24f6ff7666bf298ecfb0948d6383cad
parent 721d50d0e16b9b46cb6dc1780208b38825edbb28
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri, 28 May 2021 11:45:10 -0400

parse::expression: fix bugs in loc tracking

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Mhare/parse/expr.ha | 94++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
1 file changed, 52 insertions(+), 42 deletions(-)

diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -29,7 +29,7 @@ export fn expression(lexer: *lex::lexer) (ast::expr | error) = { expr; } else return binarithm(lexer, ast::expr { start = loc, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::unarithm_expr { op = ast::unarithm_op::DEREF, operand = alloc(expr), @@ -86,7 +86,7 @@ export fn expression(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = loc, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr, }; }; @@ -130,7 +130,7 @@ fn assert_expr(lexer: *lex::lexer, is_static: bool) (ast::expr | error) = { return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr, }; }; @@ -149,7 +149,7 @@ fn alloc_expr(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::alloc_expr { init = alloc(init), capacity = cap, @@ -193,7 +193,7 @@ fn append_expr(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::append_expr { object = alloc(object), variadic = variadic, @@ -224,7 +224,7 @@ fn measurement(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr, }; }; @@ -256,7 +256,7 @@ fn binarithm( const expr = ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::binarithm_expr { op = op, lvalue = alloc(lvalue), @@ -299,7 +299,7 @@ fn binding(lexer: *lex::lexer, is_static: bool) (ast::expr | error) = { return ast::expr { start = loc, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::binding_expr { is_static = is_static, is_const = is_const, @@ -340,10 +340,11 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = { ltok::SIZE, ltok::LEN, ltok::OFFSET => measurement(lexer), ltok::DEFER => { want(lexer, ltok::DEFER)?; + let expr = alloc(expression(lexer)?); ast::expr { start = tok.2, - end = lex::mkloc(lexer), - expr = alloc(expression(lexer)?): ast::defer_expr, + end = lex::prevloc(lexer), + expr = expr: ast::defer_expr, }; }, * => abort(), // Invariant @@ -380,7 +381,7 @@ fn call(lexer: *lex::lexer, lvalue: ast::expr) (ast::expr | error) = { return ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::call_expr { lvalue = alloc(lvalue), variadic = variadic, @@ -405,15 +406,16 @@ fn cast(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = { ltok::IS => ast::cast_kind::TEST, * => abort(), }; + let typ = alloc(_type(lexer)?); return cast(lexer, ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::cast_expr { kind = kind, value = alloc(lvalue), - _type = alloc(_type(lexer)?), + _type = typ, }, - }); + })?; }; fn constant(lexer: *lex::lexer) (ast::expr | error) = { @@ -432,7 +434,7 @@ fn constant(lexer: *lex::lexer) (ast::expr | error) = { }; return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr, }; }; @@ -455,7 +457,7 @@ fn control(lexer: *lex::lexer) (ast::expr | error) = { }; return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr, }; }; @@ -468,7 +470,7 @@ fn delete_expr(lexer: *lex::lexer) (ast::expr | error) = { want(lexer, ltok::RPAREN)?; return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr: ast::delete_expr, }; }; @@ -489,7 +491,7 @@ fn expression_list(lexer: *lex::lexer) (ast::expr | error) = { want(lexer, ltok::RBRACE)?; return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = items, }; }; @@ -529,15 +531,17 @@ fn for_expr(lexer: *lex::lexer) (ast::expr | error) = { want(lexer, ltok::RPAREN)?; + const body = alloc(expression(lexer)?); + return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::for_expr { label = label, bindings = bindings, cond = cond, afterthought = afterthought, - body = alloc(expression(lexer)?), + body = body, }, }; }; @@ -549,7 +553,7 @@ fn free_expr(lexer: *lex::lexer) (ast::expr | error) = { want(lexer, ltok::RPAREN)?; return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = expr: ast::free_expr, }; }; @@ -566,7 +570,7 @@ fn if_expr(lexer: *lex::lexer) (ast::expr | error) = { }; return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::if_expr { cond = cond, tbranch = tbranch, @@ -595,7 +599,7 @@ fn indexing(lexer: *lex::lexer, lvalue: ast::expr) (ast::expr | error) = { want(lexer, ltok::RBRACKET)?; return ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = if (is_slice) ast::slice_expr { object = alloc(lvalue), start = start, @@ -626,17 +630,20 @@ fn plain_expression(lexer: *lex::lexer) (ast::expr | error) = { ltok::TRUE, ltok::FALSE, ltok::NULL, ltok::VOID => constant(lexer), ltok::LBRACKET => plain_array(lexer)?, - ltok::STRUCT => ast::expr { - start = tok.2, - end = lex::mkloc(lexer), - expr = plain_struct(lexer, [])?, + ltok::STRUCT => { + let s = plain_struct(lexer, [])?; + return ast::expr { + start = tok.2, + end = lex::prevloc(lexer), + expr = s, + }; }, ltok::LPAREN => { want(lexer, ltok::LPAREN)?; let ex = expression(lexer)?; return switch (want(lexer, ltok::RPAREN, ltok::COMMA)?.0) { ltok::RPAREN => ex, - ltok::COMMA => plain_tuple(lexer, ex)?, + ltok::COMMA => plain_tuple(lexer, ex, tok.2)?, * => abort(), }; }, @@ -645,14 +652,14 @@ fn plain_expression(lexer: *lex::lexer) (ast::expr | error) = { return match (peek(lexer, ltok::LBRACE)?) { void => ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = id: ast::access_identifier, }, lex::token => { let s = plain_struct(lexer, id)?; ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = s, }; }, @@ -696,7 +703,7 @@ fn plain_array(lexer: *lex::lexer) (ast::expr | error) = { }; return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::array_constant { expand = expand, values = values, @@ -798,8 +805,11 @@ fn struct_field( }; }; -fn plain_tuple(lexer: *lex::lexer, ex: ast::expr) (ast::expr | error) = { - const loc = lex::mkloc(lexer); +fn plain_tuple( + lexer: *lex::lexer, + ex: ast::expr, + start: lex::location +) (ast::expr | error) = { let values: []*ast::expr = []; append(values, alloc(ex)); @@ -822,8 +832,8 @@ fn plain_tuple(lexer: *lex::lexer, ex: ast::expr) (ast::expr | error) = { // XXX: Why do we have to cast this twice? harec bug? return ast::expr { - start = loc, - end = lex::mkloc(lexer), + start = start, + end = lex::prevloc(lexer), expr = values: ast::tuple_constant: ast::constant_expr, }; }; @@ -842,7 +852,7 @@ fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = ltok::LBRACKET => indexing(lexer, lvalue)?, ltok::QUESTION => ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::propagate_expr { is_abort = false, expr = alloc(lvalue), @@ -850,7 +860,7 @@ fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = }, ltok::LNOT => ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::propagate_expr { is_abort = true, expr = alloc(lvalue), @@ -868,7 +878,7 @@ fn postfix_dot( ) (ast::expr | error) = match (try(lexer, ltok::NAME)?) { tok: lex::token => ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::access_field { object = alloc(lvalue), field = tok.1 as str, @@ -884,7 +894,7 @@ fn postfix_dot( "Expected integer constant")?; ast::expr { start = lvalue.start, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::access_tuple { object = alloc(lvalue), value = alloc(con), @@ -939,7 +949,7 @@ fn switch_expr(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::switch_expr { value = alloc(value), cases = cases, @@ -1018,7 +1028,7 @@ fn match_expr(lexer: *lex::lexer) (ast::expr | error) = { return ast::expr { start = start.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::match_expr { value = alloc(value), cases = cases, @@ -1048,7 +1058,7 @@ fn unarithm(lexer: *lex::lexer) (ast::expr | error) = { else unarithm(lexer)?; return ast::expr { start = tok.2, - end = lex::mkloc(lexer), + end = lex::prevloc(lexer), expr = ast::unarithm_expr { op = op, operand = alloc(operand),