commit c7a4513af88ba92af8cbf96cf178b332e6b288ba
parent 88a09d7c961e5425165d4ef4b9bc6e648eaf4acc
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 18 Apr 2021 13:00:15 -0400
hare::parse: implement allocation expressions
Diffstat:
4 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -26,7 +26,7 @@ export type access_expr =
// alloc(foo)
export type alloc_expr = struct {
- expr: *expr,
+ init: *expr,
capacity: nullable *expr,
};
@@ -280,7 +280,7 @@ export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
},
},
a: alloc_expr => {
- expr_free(a.expr);
+ expr_free(a.init);
expr_free(a.capacity);
},
a: append_expr => {
diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha
@@ -31,6 +31,14 @@
");
};
+@test fn builtin() void = {
+ roundtrip("export fn main() void = {
+ alloc(1234);
+ alloc(4321, 1234);
+};
+");
+};
+
@test fn call() void = {
roundtrip("export fn main() void = test();\n"
"export fn main() void = test(void, void, void);\n"
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -77,6 +77,24 @@ export fn expression(lexer: *lex::lexer) (ast::expr | error) = {
};
};
+fn alloc_expr(lexer: *lex::lexer) (ast::expr | error) = {
+ 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) {
+ alloc(expression(lexer)?);
+ } else null;
+
+ want(lexer, ltok::RPAREN)?;
+
+ return ast::alloc_expr {
+ init = alloc(init),
+ capacity = cap,
+ };
+};
+
fn binarithm(
lexer: *lex::lexer,
lvalue: (ast::expr | void),
@@ -155,7 +173,7 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = {
void => return postfix(lexer, void),
};
return switch (tok.0) {
- ltok::ALLOC => abort(),
+ ltok::ALLOC => alloc_expr(lexer)?,
ltok::APPEND => abort(),
ltok::DELETE => abort(),
ltok::FREE => abort(),
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -33,7 +33,19 @@ export fn expr(
z + expr(out, indent, *tp.value)?;
},
},
- e: ast::alloc_expr => abort(),
+ e: ast::alloc_expr => {
+ let z = fmt::fprint(out, "alloc(")?;
+ z += expr(out, indent, *e.init)?;
+ match (e.capacity) {
+ null => void,
+ e: *ast::expr => {
+ z += fmt::fprint(out, ", ")?;
+ z += expr(out, indent, *e)?;
+ },
+ };
+ z += fmt::fprint(out, ")")?;
+ z;
+ },
e: ast::append_expr => abort(),
e: ast::assert_expr => abort(),
e: ast::assign_expr => {