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:
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
};