hare

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

commit cce8406cf5b73b6098f81a8d55cb9ab3437e71ab
parent da23ff58f3971c73c29d3f719c59631f89890221
Author: Sebastian <sebastian@sebsite.pw>
Date:   Thu, 24 Feb 2022 20:52:17 -0500

ast: add copy allocation form

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

Diffstat:
Mhare/ast/expr.ha | 12++++++++++++
Mhare/parse/+test/expr.ha | 1+
Mhare/parse/expr.ha | 37++++++++++++++++++++++++++-----------
Mhare/unparse/expr.ha | 5++++-
4 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha @@ -37,11 +37,23 @@ export type access_tuple = struct { export type access_expr = (access_identifier | access_index | access_field | access_tuple); +// The form of an allocation expression. +// +// alloc(foo) // OBJECT +// alloc(foo...) // COPY +export type alloc_form = enum { + OBJECT, + COPY, +}; + // An allocation expression. // // alloc(foo) +// alloc(foo...) +// alloc(foo, bar) export type alloc_expr = struct { init: *expr, + form: alloc_form, capacity: nullable *expr, }; diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -45,6 +45,7 @@ @test fn builtin() void = { roundtrip(`export fn main() void = { alloc(1234); + alloc(1234...); alloc(4321, 1234); append(x, 10); append(x, 10...); diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -171,21 +171,36 @@ fn alloc_expr(lexer: *lex::lexer) (ast::expr | error) = { const start = want(lexer, ltok::ALLOC)?; want(lexer, ltok::LPAREN)?; - const init = expression(lexer)?; - const cap: nullable *ast::expr = - if (try(lexer, ltok::COMMA)? is lex::token) { - yield alloc(expression(lexer)?); - } else null; - - want(lexer, ltok::RPAREN)?; + const init = alloc(expression(lexer)?); + const expr = + switch (want(lexer, ltok::COMMA, ltok::ELLIPSIS, ltok::RPAREN)?.0) { + case ltok::COMMA => + const cap = alloc(expression(lexer)?); + want(lexer, ltok::RPAREN)?; + yield ast::alloc_expr { + init = init, + form = ast::alloc_form::COPY, + capacity = cap, + }; + case ltok::ELLIPSIS => + want(lexer, ltok::RPAREN)?; + yield ast::alloc_expr { + init = init, + form = ast::alloc_form::COPY, + capacity = null, + }; + case ltok::RPAREN => + yield ast::alloc_expr { + init = init, + form = ast::alloc_form::OBJECT, + capacity = null, + }; + }; return ast::expr { start = start.2, end = lex::prevloc(lexer), - expr = ast::alloc_expr { - init = alloc(init), - capacity = cap, - }, + expr = expr, }; }; diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -41,7 +41,10 @@ export fn expr( let z = fmt::fprint(out, "alloc(")?; z += expr(out, indent, *e.init)?; match (e.capacity) { - case null => void; + case null => + if (e.form == ast::alloc_form::COPY) { + z += fmt::fprint(out, "...")?; + }; case let e: *ast::expr => z += fmt::fprint(out, ", ")?; z += expr(out, indent, *e)?;