hare

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

commit 1a7acbf2462917c018759634563432b927c1ea9a
parent 80d03addce474489fb3be95293d454a667f4951f
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 16 Apr 2021 09:28:48 -0400

hare::parse: implement tuple access

Diffstat:
Mhare/parse/+test/expr.ha | 4+++-
Mhare/parse/expr.ha | 20+++++++++++++++-----
Mhare/unparse/expr.ha | 6+++++-
3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -24,7 +24,9 @@ @test fn postfix() void = { roundtrip("export fn main() void = x.y;\n" "export fn main() void = x.y.z.q;\n" - "export fn main() void = x().y;\n"); + "export fn main() void = x().y;\n" + "export fn main() void = x.42;\n" + "export fn main() void = x().y.0.q;\n"); }; @test fn unarithm() void = { diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -224,14 +224,24 @@ fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = }; fn postfix_dot(lexer: *lex::lexer, lvalue: ast::expr) (ast::expr | error) = { - let tok = want(lexer, ltok::NAME, ltok::LIT_INT)?; - return switch (tok.0) { - ltok::NAME => ast::access_field { + return match (try(lexer, ltok::NAME)?) { + tok: lex::token => ast::access_field { object = alloc(lvalue), field = tok.1 as str, }, - ltok::LIT_INT => abort(), // TODO: Tuple access - * => abort(), + void => { + let con = constant(lexer)?; + let val = con as ast::constant_expr; + synassert(mkloc(lexer), val is lex::value, + "Expected integer constant")?; + let val = val as lex::value; + synassert(mkloc(lexer), val is i64, + "Expected integer constant")?; + ast::access_tuple { + object = alloc(lvalue), + value = alloc(con), + }; + }, }; }; diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -16,7 +16,11 @@ export fn expr( let z = expr(out, indent, *fi.object)?; z + fmt::fprintf(out, ".{}", fi.field)?; }, - tp: ast::access_tuple => abort(), + tp: ast::access_tuple => { + let z = expr(out, indent, *tp.object)?; + z += fmt::fprintf(out, ".")?; + z + expr(out, indent, *tp.value)?; + }, }, e: ast::alloc_expr => abort(), e: ast::append_expr => abort(),