hare

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

commit 377af32d04fbeea786491a32d0aafce6ecd317e1
parent 559b994e6474c8b6a3f688ed8edcf587dac625f8
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 17 Apr 2021 08:48:46 -0400

hare::parse: implement array literals

Diffstat:
Mhare/parse/+test/expr.ha | 5++++-
Mhare/parse/expr.ha | 38+++++++++++++++++++++++++++++++++++++-
Mhare/unparse/expr.ha | 12+++++++++++-
3 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -18,7 +18,10 @@ }; @test fn constant() void = { - roundtrip("export fn main() void = 2 + -4 + void + true + \"hello\" + '?';\n"); + roundtrip("export fn main() void = 2 + -4 + void + true + \"hello\" + '?'; +export fn main() void = [1, 2, 3, 4]; +export fn main() void = [1, 2, 3, 4...]; +"); }; @test fn control() void = { diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -255,7 +255,7 @@ fn plain_expression(lexer: *lex::lexer) (ast::expr | error) = { return switch (tok.0) { ltok::TRUE, ltok::FALSE, ltok::NULL, ltok::VOID => constant(lexer), - ltok::LBRACKET => abort(), // TODO: Array literal + ltok::LBRACKET => plain_array(lexer)?, ltok::STRUCT => abort(), // TODO: Struct literal ltok::LPAREN => { let ex = expression(lexer); @@ -278,6 +278,42 @@ fn plain_expression(lexer: *lex::lexer) (ast::expr | error) = { }; }; +fn plain_array(lexer: *lex::lexer) (ast::expr | error) = { + want(lexer, ltok::LBRACKET)?; + + let values: []*ast::expr = []; + let expand = false; + for (true) { + match (try(lexer, ltok::RBRACKET)?) { + lex::token => break, + void => void, + }; + + append(values, alloc(expression(lexer)?)); + + match (try(lexer, ltok::COMMA, ltok::ELLIPSIS)?) { + void => { + want(lexer, ltok::RBRACKET)?; + break; + }, + tok: lex::token => switch (tok.0) { + ltok::COMMA => void, + ltok::ELLIPSIS => { + expand = true; + try(lexer, ltok::COMMA)?; + want(lexer, ltok::RBRACKET)?; + break; + }, + * => abort(), + }, + }; + }; + return ast::array_constant { + expand = expand, + values = values, + }; +}; + fn postfix(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = { let lvalue = match (lvalue) { void => plain_expression(lexer)?, diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -199,7 +199,17 @@ fn constant( s: str => return fmt::fprintf(out, "\"{}\"", s), r: rune => return fmt::fprintf(out, "'{}'", r), }), - ast::array_constant => abort(), // TODO + ac: ast::array_constant => { + let z = fmt::fprint(out, "[")?; + for (let i = 0z; i < len(ac.values); i += 1) { + z += expr(out, indent, *ac.values[i])?; + if (i + 1 < len(ac.values)) { + z += fmt::fprint(out, ", ")?; + }; + }; + z + fmt::fprintf(out, "{}]", + if (ac.expand) "..." else "")?; + }, ast::struct_constant => abort(), // TODO ast::tuple_constant => abort(), // TODO };