hare

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

commit 7f3283f2e743611463be7f1fe7b1bf0d92a78f24
parent 07c4c8efb39a29d5accfdd79a0581930e697104e
Author: Joe Finney <me@spxtr.net>
Date:   Sun, 10 Mar 2024 14:23:13 +0000

Update hare::parse for optional function params.

Signed-off-by: Joe Finney <me@spxtr.net>

Diffstat:
Mhare/ast/type.ha | 1+
Mhare/parse/+test/types.ha | 2+-
Mhare/parse/type.ha | 8++++++++
Mhare/unparse/decl.ha | 13++++++++++++-
Mhare/unparse/type.ha | 12++++++++++++
5 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/hare/ast/type.ha b/hare/ast/type.ha @@ -42,6 +42,7 @@ export type func_param = struct { loc: lex::location, name: str, _type: *_type, + default_value: (void | expr), }; // fn(foo: int, baz: int...) int diff --git a/hare/parse/+test/types.ha b/hare/parse/+test/types.ha @@ -129,7 +129,7 @@ export type foo = fn( long_type_name, blablablabla, multiple_lines, - and_stuff, + and_stuff = 4, ) void; export type foo = fn( diff --git a/hare/parse/type.ha b/hare/parse/type.ha @@ -28,6 +28,7 @@ fn prototype(lexer: *lex::lexer) (ast::func_type | error) = { loc = loc, name = "", _type = alloc(name_or_type), + default_value = void, }); case lex::token => // Bit of a hack because we can't unlex twice. @@ -39,8 +40,15 @@ fn prototype(lexer: *lex::lexer) (ast::func_type | error) = { loc = loc, name = ns[0], _type = alloc(_type(lexer)?), + default_value = void, }); }; + match (try(lexer, ltok::EQUAL)?) { + case void => + yield void; + case lex::token => + params[len(params) - 1].default_value = expr(lexer)?; + }; match (try(lexer, ltok::ELLIPSIS)?) { case lex::token => variadism = ast::variadism::HARE; diff --git a/hare/unparse/decl.ha b/hare/unparse/decl.ha @@ -181,6 +181,7 @@ fn decl_test(d: *ast::decl, expected: str) bool = { decl(&buf, &syn_nowrap, d)!; let s = memio::string(&buf)!; defer free(s); + fmt::println(s)!; return s == expected; }; @@ -208,11 +209,13 @@ fn decl_test(d: *ast::decl, expected: str) bool = { loc = loc, name = "foo", _type = &type_int, + default_value = void, }, ast::func_param { loc = loc, name = "bar", _type = &type_int, + default_value = void, }, ], }, @@ -297,6 +300,14 @@ fn decl_test(d: *ast::decl, expected: str) bool = { loc = loc, name = "", _type = &type_int, + default_value = ast::expr { + expr = ast::number_literal { + value = 4u64, + sign = false, + suff = lex::ltok::LIT_ICONST, + }, + ... + }, }, ], }; @@ -307,5 +318,5 @@ fn decl_test(d: *ast::decl, expected: str) bool = { body = &expr_void, attrs = 0, }; - assert(decl_test(&d, "fn foo(int) int = void;")); + assert(decl_test(&d, "fn foo(int = 4) int = void;")); }; diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha @@ -78,6 +78,15 @@ fn prototype( n += space(ctx)?; }; n += __type(ctx, syn, param._type)?; + match (param.default_value) { + case void => + yield; + case let e: ast::expr => + n += space(ctx)?; + n += syn(ctx, "=", synkind::PUNCTUATION)?; + n += space(ctx)?; + n += _expr(ctx, syn, &e)?; + }; if (i + 1 < len(t.params) || t.variadism == variadism::C) { n += syn(ctx, ",", synkind::PUNCTUATION)?; n += space(ctx)?; @@ -396,6 +405,7 @@ fn type_test(t: *ast::_type, expected: str) void = { loc = loc, name = "", _type = &type_int, + default_value = void, }, ], }; @@ -408,11 +418,13 @@ fn type_test(t: *ast::_type, expected: str) void = { loc = loc, name = "foo", _type = &type_int, + default_value = void, }, ast::func_param { loc = loc, name = "bar", _type = &type_int, + default_value = void, }, ], };