hare

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

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:
Mhare/ast/expr.ha | 4++--
Mhare/parse/+test/expr.ha | 8++++++++
Mhare/parse/expr.ha | 20+++++++++++++++++++-
Mhare/unparse/expr.ha | 14+++++++++++++-
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 => {