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:
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)?;