hare

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

commit 05991cae3e628268fb2436feebd81254fe4353c3
parent 6590d9eaa1b54044a307b37e41ba499abb4ac278
Author: Sebastian <sebastian@sebsite.pw>
Date:   Tue, 17 Oct 2023 22:30:26 -0400

hare::unparse: pass around pointers

Closes: https://todo.sr.ht/~sircmpwn/hare/378
Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mcmd/hare/build/util.ha | 4++--
Mcmd/haredoc/doc/html.ha | 14+++++++-------
Mcmd/haredoc/doc/resolve.ha | 12++++++------
Mcmd/haredoc/doc/sort.ha | 6+++---
Mcmd/haredoc/doc/tty.ha | 12++++++------
Mcmd/haretype/main.ha | 2+-
Mhare/unparse/decl.ha | 32++++++++++++++++----------------
Mhare/unparse/expr.ha | 173++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mhare/unparse/import.ha | 6+++---
Mhare/unparse/syn.ha | 2+-
Mhare/unparse/type.ha | 68++++++++++++++++++++++++++++++++++----------------------------------
Mhare/unparse/unit.ha | 4++--
12 files changed, 173 insertions(+), 162 deletions(-)

diff --git a/cmd/hare/build/util.ha b/cmd/hare/build/util.ha @@ -152,11 +152,11 @@ fn get_flags(ctx: *context, t: *task) ([]str | error) = { case null => void; case let t: *ast::_type => memio::concat(&buf, ":")!; - unparse::_type(&buf, &unparse::syn_nowrap, *t)!; + unparse::_type(&buf, &unparse::syn_nowrap, t)!; }; memio::concat(&buf, "=")!; unparse::expr(&buf, &unparse::syn_nowrap, - *ctx.defines[i].init)!; + ctx.defines[i].init)!; append(flags, memio::string(&buf)!); }; diff --git a/cmd/haredoc/doc/html.ha b/cmd/haredoc/doc/html.ha @@ -134,35 +134,35 @@ export fn emit_html(ctx: *context) (void | error) = { if (len(decls.types) != 0) { fmt::fprintln(ctx.out, "<h3>Types</h3>")?; for (let i = 0z; i < len(decls.types); i += 1) { - details(ctx, decls.types[i])?; + details(ctx, &decls.types[i])?; }; }; if (len(decls.errors) != 0) { fmt::fprintln(ctx.out, "<h3>Errors</h3>")?; for (let i = 0z; i < len(decls.errors); i += 1) { - details(ctx, decls.errors[i])?; + details(ctx, &decls.errors[i])?; }; }; if (len(decls.constants) != 0) { fmt::fprintln(ctx.out, "<h3>Constants</h3>")?; for (let i = 0z; i < len(decls.constants); i += 1) { - details(ctx, decls.constants[i])?; + details(ctx, &decls.constants[i])?; }; }; if (len(decls.globals) != 0) { fmt::fprintln(ctx.out, "<h3>Globals</h3>")?; for (let i = 0z; i < len(decls.globals); i += 1) { - details(ctx, decls.globals[i])?; + details(ctx, &decls.globals[i])?; }; }; if (len(decls.funcs) != 0) { fmt::fprintln(ctx.out, "<h3>Functions</h3>")?; for (let i = 0z; i < len(decls.funcs); i += 1) { - details(ctx, decls.funcs[i])?; + details(ctx, &decls.funcs[i])?; }; }; }; @@ -188,14 +188,14 @@ fn tocentries( lname)?; undoc = true; }; - unparse::decl(out, &syn_centry, decls[i])?; + unparse::decl(out, &syn_centry, &decls[i])?; fmt::fprintln(out)?; }; fmt::fprint(out, "</pre>")?; return; }; -fn details(ctx: *context, decl: ast::decl) (void | error) = { +fn details(ctx: *context, decl: *ast::decl) (void | error) = { fmt::fprintln(ctx.out, "<section class='member'>")?; fmt::fprint(ctx.out, "<h4 id='")?; unparse::ident(ctx.out, decl_ident(decl))?; diff --git a/cmd/haredoc/doc/resolve.ha b/cmd/haredoc/doc/resolve.ha @@ -72,31 +72,31 @@ fn is_local(ctx: *context, what: ast::ident) bool = { const summary = ctx.summary; for (let i = 0z; i < len(summary.constants); i += 1) { - const name = decl_ident(summary.constants[i])[0]; + const name = decl_ident(&summary.constants[i])[0]; if (name == what[0]) { return true; }; }; for (let i = 0z; i < len(summary.errors); i += 1) { - const name = decl_ident(summary.errors[i])[0]; + const name = decl_ident(&summary.errors[i])[0]; if (name == what[0]) { return true; }; }; for (let i = 0z; i < len(summary.types); i += 1) { - const name = decl_ident(summary.types[i])[0]; + const name = decl_ident(&summary.types[i])[0]; if (name == what[0]) { return true; }; }; for (let i = 0z; i < len(summary.globals); i += 1) { - const name = decl_ident(summary.globals[i])[0]; + const name = decl_ident(&summary.globals[i])[0]; if (name == what[0]) { return true; }; }; for (let i = 0z; i < len(summary.funcs); i += 1) { - const name = decl_ident(summary.funcs[i])[0]; + const name = decl_ident(&summary.funcs[i])[0]; if (name == what[0]) { return true; }; @@ -107,7 +107,7 @@ fn is_local(ctx: *context, what: ast::ident) bool = { fn lookup_local_enum(ctx: *context, what: ast::ident) (ast::ident | void) = { for (let i = 0z; i < len(ctx.summary.types); i += 1) { - const decl = ctx.summary.types[i]; + const decl = &ctx.summary.types[i]; const name = decl_ident(decl)[0]; if (name == what[0]) { const t = (decl.decl as []ast::decl_type)[0]; diff --git a/cmd/haredoc/doc/sort.ha b/cmd/haredoc/doc/sort.ha @@ -92,8 +92,8 @@ export fn sort_decls(decls: []ast::decl) summary = { }; fn decl_cmp(a: const *opaque, b: const *opaque) int = { - const a = *(a: const *ast::decl); - const b = *(b: const *ast::decl); + const a = a: const *ast::decl; + const b = b: const *ast::decl; if (a.docs == "" && b.docs != "") { return 1; } else if (a.docs != "" && b.docs == "") { @@ -103,7 +103,7 @@ fn decl_cmp(a: const *opaque, b: const *opaque) int = { return strings::compare(id_a[len(id_a) - 1], id_b[len(id_b) - 1]); }; -fn decl_ident(decl: ast::decl) ast::ident = { +fn decl_ident(decl: *ast::decl) ast::ident = { match (decl.decl) { case let f: ast::decl_func => return f.ident; diff --git a/cmd/haredoc/doc/tty.ha b/cmd/haredoc/doc/tty.ha @@ -64,27 +64,27 @@ export fn emit_tty(ctx: *context) (void | error) = { // XXX: Should we emit the dependencies, too? let printed = false; for (let i = 0z; i < len(summary.types); i += 1) { - if (details_tty(ctx, summary.types[i])?) { + if (details_tty(ctx, &summary.types[i])?) { printed = true; }; }; for (let i = 0z; i < len(summary.constants); i += 1) { - if (details_tty(ctx, summary.constants[i])?) { + if (details_tty(ctx, &summary.constants[i])?) { printed = true; }; }; for (let i = 0z; i < len(summary.errors); i += 1) { - if (details_tty(ctx, summary.errors[i])?) { + if (details_tty(ctx, &summary.errors[i])?) { printed = true; }; }; for (let i = 0z; i < len(summary.globals); i += 1) { - if (details_tty(ctx, summary.globals[i])?) { + if (details_tty(ctx, &summary.globals[i])?) { printed = true; }; }; for (let i = 0z; i < len(summary.funcs); i += 1) { - if (details_tty(ctx, summary.funcs[i])?) { + if (details_tty(ctx, &summary.funcs[i])?) { printed = true; }; }; @@ -126,7 +126,7 @@ fn emit_submodules_tty(ctx: *context) (void | error) = { }; }; -fn details_tty(ctx: *context, decl: ast::decl) (bool | error) = { +fn details_tty(ctx: *context, decl: *ast::decl) (bool | error) = { if (len(decl.docs) == 0 && !ctx.show_undocumented) { return false; }; diff --git a/cmd/haretype/main.ha b/cmd/haretype/main.ha @@ -32,7 +32,7 @@ fn typeinfo( const atype = parse::_type(&lexer)?; defer ast::type_finish(&atype); const typ = types::lookup(store, &atype)?; - unparse::_type(os::stdout, &unparse::syn_nowrap, atype)?; + unparse::_type(os::stdout, &unparse::syn_nowrap, &atype)?; fmt::println()?; yield typ; }; diff --git a/hare/unparse/decl.ha b/hare/unparse/decl.ha @@ -12,13 +12,13 @@ use strings; export fn decl( out: io::handle, syn: *synfunc, - d: ast::decl, + d: *ast::decl, ) (size | io::error) = { let n = 0z; let ctx = context { out = out, stack = &stack { - cur = &d, + cur = d, ... }, ... @@ -42,12 +42,12 @@ export fn decl( case let ty: *ast::_type => n += syn(&ctx, ":", synkind::PUNCTUATION)?; n += space(&ctx)?; - n += __type(&ctx, syn, *ty)?; + n += __type(&ctx, syn, ty)?; }; n += space(&ctx)?; n += syn(&ctx, "=", synkind::OPERATOR)?; n += space(&ctx)?; - n += _expr(&ctx, syn, *c[i].init)?; + n += _expr(&ctx, syn, c[i].init)?; if (i + 1 < len(c)) { n += syn(&ctx, ",", synkind::PUNCTUATION)?; n += space(&ctx)?; @@ -76,7 +76,7 @@ export fn decl( case let ty: *ast::_type => n += syn(&ctx, ":", synkind::PUNCTUATION)?; n += space(&ctx)?; - n += __type(&ctx, syn, *ty)?; + n += __type(&ctx, syn, ty)?; }; match (g[i].init) { case null => void; @@ -84,7 +84,7 @@ export fn decl( n += space(&ctx)?; n += syn(&ctx, "=", synkind::OPERATOR)?; n += space(&ctx)?; - n += _expr(&ctx, syn, *ex)?; + n += _expr(&ctx, syn, ex)?; }; if (i + 1 < len(g)) { n += syn(&ctx, ",", synkind::OPERATOR)?; @@ -99,7 +99,7 @@ export fn decl( n += space(&ctx)?; n += syn(&ctx, "=", synkind::OPERATOR)?; n += space(&ctx)?; - n += __type(&ctx, syn, t[i]._type)?; + n += __type(&ctx, syn, &t[i]._type)?; if (i + 1 < len(t)) { n += syn(&ctx, ",", synkind::PUNCTUATION)?; n += space(&ctx)?; @@ -144,17 +144,17 @@ export fn decl( n += space(&ctx)?; n += _ident(&ctx, syn, f.ident, synkind::FUNCTION)?; const fntype = f.prototype.repr as ast::func_type; - n += prototype(&ctx, syn, fntype)?; + n += prototype(&ctx, syn, &fntype)?; match (f.body) { case void => void; case let e: ast::expr => n += space(&ctx)?; n += syn(&ctx, "=", synkind::OPERATOR)?; n += space(&ctx)?; - n += _expr(&ctx, syn, e)?; + n += _expr(&ctx, syn, &e)?; }; case let e: ast::assert_expr => - n += assert_expr(&ctx, syn, e)?; + n += assert_expr(&ctx, syn, &e)?; }; n += syn(&ctx, ";", synkind::PUNCTUATION)?; return n; @@ -180,7 +180,7 @@ fn comment(ctx: *context, syn: *synfunc, s: str) (size | io::error) = { return n; }; -fn decl_test(d: ast::decl, expected: str) bool = { +fn decl_test(d: *ast::decl, expected: str) bool = { let buf = memio::dynamic(); decl(&buf, &syn_nowrap, d)!; let s = memio::string(&buf)!; @@ -259,7 +259,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { ], ... }; - assert(decl_test(d, "let foo::bar: int = void, @threadlocal boo: int = void, @symbol(\"foobar\") baz: int = void;")); + assert(decl_test(&d, "let foo::bar: int = void, @threadlocal boo: int = void, @symbol(\"foobar\") baz: int = void;")); d.exported = true; d.decl = [ @@ -269,7 +269,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { init = alloc(expr_void), }, ]; - assert(decl_test(d, "export def foo: int = void;")); + assert(decl_test(&d, "export def foo: int = void;")); d.exported = false; d.decl = [ @@ -282,7 +282,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { _type = type_int, }, ]; - assert(decl_test(d, "type foo = int, bar = int;")); + assert(decl_test(&d, "type foo = int, bar = int;")); d.decl = ast::decl_func { symbol = "foo", @@ -291,7 +291,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { body = void, attrs = ast::fndecl_attrs::FINI, }; - assert(decl_test(d, "@fini @symbol(\"foo\") fn foo(foo: int, bar: int...) int;")); + assert(decl_test(&d, "@fini @symbol(\"foo\") fn foo(foo: int, bar: int...) int;")); type_fn.repr = ast::func_type { result = &type_int, @@ -311,5 +311,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) int = void;")); }; diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -13,7 +13,7 @@ use strings; export fn expr( out: io::handle, syn: *synfunc, - e: ast::expr, + e: *ast::expr, ) (size | io::error) = { let ctx = context { out = out, @@ -22,9 +22,9 @@ export fn expr( return _expr(&ctx, syn, e); }; -fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { +fn _expr(ctx: *context, syn: *synfunc, e: *ast::expr) (size | io::error) = { ctx.stack = &stack { - cur = &e, + cur = e, up = ctx.stack, ... }; @@ -49,12 +49,12 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *ix.object)?; + z += _expr(ctx, syn, ix.object)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; z += syn(ctx, "[", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *ix.index)?; + z += _expr(ctx, syn, ix.index)?; z += syn(ctx, "]", synkind::PUNCTUATION)?; return z; case let fi: ast::access_field => @@ -63,7 +63,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *fi.object)?; + z += _expr(ctx, syn, fi.object)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; @@ -76,24 +76,24 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *tp.object)?; + z += _expr(ctx, syn, tp.object)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; z += syn(ctx, ".", synkind::OPERATOR)?; - z += _expr(ctx, syn, *tp.value)?; + z += _expr(ctx, syn, tp.value)?; return z; }; case let e: ast::align_expr => let z = syn(ctx, "align", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += __type(ctx, syn, *e)?; + z += __type(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::alloc_expr => let z = syn(ctx, "alloc", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.init)?; + z += _expr(ctx, syn, e.init)?; match (e.capacity) { case null => if (e.form == ast::alloc_form::COPY) { @@ -102,17 +102,17 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { case let e: *ast::expr => z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; - case let e: ast::append_expr => - return append_insert_expr(ctx, syn, e, false); + case ast::append_expr => + return append_insert_expr(ctx, syn, e); case let e: ast::assert_expr => - return assert_expr(ctx, syn, e); + return assert_expr(ctx, syn, &e); case let e: ast::assign_expr => let z = 0z; - z += _expr(ctx, syn, *e.object)?; + z += _expr(ctx, syn, e.object)?; const op = match (e.op) { case void => yield "="; @@ -153,11 +153,11 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { z += space(ctx)?; z += syn(ctx, op, synkind::OPERATOR)?; z += space(ctx)?; - z += _expr(ctx, syn, *e.value)?; + z += _expr(ctx, syn, e.value)?; return z; case let e: ast::binarithm_expr => const prec = binprecedence(e.op); - let z = binexprval(ctx, syn, *e.lvalue, prec)?; + let z = binexprval(ctx, syn, e.lvalue, prec)?; z += space(ctx)?; z += syn(ctx, switch (e.op) { case binarithm_op::BAND => @@ -200,7 +200,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { yield "^"; }, synkind::OPERATOR)?; z += space(ctx)?; - z += binexprval(ctx, syn, *e.rvalue, prec)?; + z += binexprval(ctx, syn, e.rvalue, prec)?; return z; case let e: ast::binding_expr => let z = 0z; @@ -245,13 +245,13 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { case let t: *ast::_type => z += syn(ctx, ":", synkind::PUNCTUATION)?; z += space(ctx)?; - z += __type(ctx, syn, *t)?; + z += __type(ctx, syn, t)?; case null => void; }; z += space(ctx)?; z += syn(ctx, "=", synkind::OPERATOR)?; z += space(ctx)?; - z += _expr(ctx, syn, *binding.init)?; + z += _expr(ctx, syn, binding.init)?; if (i + 1 < len(e.bindings)) { z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; @@ -272,13 +272,13 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e.lvalue)?; + z += _expr(ctx, syn, e.lvalue)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; z += syn(ctx, "(", synkind::PUNCTUATION)?; for (let i = 0z; i < len(e.args); i += 1) { - z += _expr(ctx, syn, *e.args[i])?; + z += _expr(ctx, syn, e.args[i])?; if (i + 1 < len(e.args)) { z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; @@ -295,7 +295,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e.value)?; + z += _expr(ctx, syn, e.value)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; @@ -312,7 +312,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { z += syn(ctx, "is", synkind::OPERATOR)?; z += space(ctx)?; }; - z += __type(ctx, syn, *e._type)?; + z += __type(ctx, syn, e._type)?; return z; case let e: ast::constant_expr => return constant(ctx, syn, e)?; @@ -327,7 +327,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { case let e: ast::defer_expr => let z = syn(ctx, "defer", synkind::KEYWORD)?; z += space(ctx)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; return z; case let e: ast::delete_expr => let z = 0z; @@ -337,7 +337,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { }; z += syn(ctx, "delete", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.object)?; + z += _expr(ctx, syn, e.object)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::error_assert_expr => @@ -346,39 +346,39 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; z += syn(ctx, "!", synkind::OPERATOR)?; return z; case let e: ast::for_expr => - return for_expr(ctx, syn, e)?; + return for_expr(ctx, syn, &e)?; case let e: ast::free_expr => let z = syn(ctx, "free", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::if_expr => let z = syn(ctx, "if", synkind::KEYWORD)?; z += space(ctx)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.cond)?; + z += _expr(ctx, syn, e.cond)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *e.tbranch)?; + z += _expr(ctx, syn, e.tbranch)?; match (e.fbranch) { case null => void; case let e: *ast::expr => z += space(ctx)?; z += syn(ctx, "else", synkind::KEYWORD)?; z += space(ctx)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; return z; - case let e: ast::insert_expr => - return append_insert_expr(ctx, syn, e, true); + case ast::insert_expr => + return append_insert_expr(ctx, syn, e); case let e: ast::compound_expr => let z = 0z; if (e.label != "") { @@ -390,30 +390,30 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { ctx.indent += 1; for (let i = 0z; i < len(e.exprs); i += 1) { z += newline(ctx)?; - z += stmt(ctx, syn, *e.exprs[i])?; + z += stmt(ctx, syn, e.exprs[i])?; }; ctx.indent -= 1; z += newline(ctx)?; z += syn(ctx, "}", synkind::PUNCTUATION)?; return z; case let e: ast::match_expr => - return match_expr(ctx, syn, e)?; + return match_expr(ctx, syn, &e)?; case let e: ast::len_expr => let z = syn(ctx, "len", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::size_expr => let z = syn(ctx, "size", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += __type(ctx, syn, *e)?; + z += __type(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::offset_expr => let z = syn(ctx, "offset", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::propagate_expr => @@ -422,7 +422,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; @@ -434,7 +434,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { case null => void; case let e: *ast::expr => z += space(ctx)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; return z; case let e: ast::slice_expr => @@ -443,7 +443,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e.object)?; + z += _expr(ctx, syn, e.object)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; @@ -451,18 +451,18 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { match (e.start) { case null => void; case let e: *ast::expr => - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; z += syn(ctx, "..", synkind::OPERATOR)?; match (e.end) { case null => void; case let e: *ast::expr => - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; z += syn(ctx, "]", synkind::PUNCTUATION)?; return z; case let e: ast::switch_expr => - return switch_expr(ctx, syn, e)?; + return switch_expr(ctx, syn, &e)?; case let e: ast::unarithm_expr => let z = syn(ctx, switch (e.op) { case ast::unarithm_op::ADDR => @@ -486,7 +486,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; - z += _expr(ctx, syn, *e.operand)?; + z += _expr(ctx, syn, e.operand)?; if (needs_parens) { z += syn(ctx, ")", synkind::PUNCTUATION)?; }; @@ -501,13 +501,13 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { case let e: ast::vaarg_expr => let z = syn(ctx, "vaarg", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; case let e: ast::vaend_expr => let z = syn(ctx, "vaend", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; }; @@ -525,7 +525,7 @@ fn _expr(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { z += syn(ctx, ",", synkind::PUNCTUATION)?; }; z += space(ctx)?; - z += _expr(ctx, syn, *v)?; + z += _expr(ctx, syn, v)?; }; return z; }; @@ -562,7 +562,7 @@ fn binprecedence(op: binarithm_op) uint = { fn binexprval( ctx: *context, syn: *synfunc, - e: ast::expr, + e: *ast::expr, prec: uint, ) (size | io::error) = { let z = 0z; @@ -576,7 +576,7 @@ fn binexprval( }; case => void; }; - const needs_parens = !is_cast(&e) && !(e.expr is ast::binarithm_expr); + const needs_parens = !is_cast(e) && !(e.expr is ast::binarithm_expr); if (needs_parens) { z += syn(ctx, "(", synkind::PUNCTUATION)?; }; @@ -587,7 +587,7 @@ fn binexprval( return z; }; -fn stmt(ctx: *context, syn: *synfunc, e: ast::expr) (size | io::error) = { +fn stmt(ctx: *context, syn: *synfunc, e: *ast::expr) (size | io::error) = { let n = _expr(ctx, syn, e)?; n += syn(ctx, ";", synkind::PUNCTUATION)?; return n; @@ -630,7 +630,7 @@ fn constant( case let ac: ast::array_constant => let z = syn(ctx, "[", synkind::PUNCTUATION)?; for (let i = 0z; i < len(ac.values); i += 1) { - z += _expr(ctx, syn, *ac.values[i])?; + z += _expr(ctx, syn, ac.values[i])?; if (i + 1 < len(ac.values)) { z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; @@ -680,7 +680,7 @@ fn constant( case let tu: ast::tuple_constant => let z = syn(ctx, "(", synkind::PUNCTUATION)?; for (let i = 0z; i < len(tu); i += 1) { - z += _expr(ctx, syn, *tu[i])?; + z += _expr(ctx, syn, tu[i])?; if (i + 1 < len(tu)) { z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; @@ -715,12 +715,12 @@ fn struct_constant( case let t: *ast::_type => z += syn(ctx, ":", synkind::PUNCTUATION)?; z += space(ctx)?; - z += __type(ctx, syn, *t)?; + z += __type(ctx, syn, t)?; }; z += space(ctx)?; z += syn(ctx, "=", synkind::OPERATOR)?; z += space(ctx)?; - z += _expr(ctx, syn, *sv.init)?; + z += _expr(ctx, syn, sv.init)?; case let sc: *ast::struct_constant => z += constant(ctx, syn, *sc)?; }; @@ -739,7 +739,7 @@ fn struct_constant( fn for_expr( ctx: *context, syn: *synfunc, - e: ast::for_expr, + e: *ast::for_expr, ) (size | io::error) = { let z = syn(ctx, "for", synkind::KEYWORD)?; z += space(ctx)?; @@ -747,36 +747,36 @@ fn for_expr( match (e.bindings) { case null => void; case let e: *ast::expr => - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; z += syn(ctx, ";", synkind::PUNCTUATION)?; z += space(ctx)?; }; - z += _expr(ctx, syn, *e.cond)?; + z += _expr(ctx, syn, e.cond)?; match (e.afterthought) { case null => void; case let e: *ast::expr => z += syn(ctx, ";", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; }; z += syn(ctx, ")", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *e.body)?; + z += _expr(ctx, syn, e.body)?; return z; }; fn switch_expr( ctx: *context, syn: *synfunc, - e: ast::switch_expr, + e: *ast::switch_expr, ) (size | io::error) = { let z = syn(ctx, "switch", synkind::KEYWORD)?; z += space(ctx)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.value)?; + z += _expr(ctx, syn, e.value)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; z += space(ctx)?; z += syn(ctx, "{", synkind::PUNCTUATION)?; @@ -791,7 +791,7 @@ fn switch_expr( } else { for (let j = 0z; j < len(item.options); j += 1) { const opt = item.options[j]; - z += _expr(ctx, syn, *opt)?; + z += _expr(ctx, syn, opt)?; if (j + 1 < len(item.options)) { z += syn(ctx, ",", synkind::PUNCTUATION)?; @@ -812,12 +812,12 @@ fn switch_expr( fn match_expr( ctx: *context, syn: *synfunc, - e: ast::match_expr, + e: *ast::match_expr, ) (size | io::error) = { let z = syn(ctx, "match", synkind::KEYWORD)?; z += space(ctx)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.value)?; + z += _expr(ctx, syn, e.value)?; z += syn(ctx, ")", synkind::PUNCTUATION)?; z += space(ctx)?; z += syn(ctx, "{", synkind::PUNCTUATION)?; @@ -838,7 +838,7 @@ fn match_expr( z += syn(ctx, ":", synkind::PUNCTUATION)?; }; z += space(ctx)?; - z += __type(ctx, syn, *typ)?; + z += __type(ctx, syn, typ)?; case null => void; }; z += space(ctx)?; @@ -863,7 +863,7 @@ fn case_exprs( if (e.cond == null) { // abort() expression z += space(ctx)?; - z += assert_expr(ctx, syn, e)?; + z += assert_expr(ctx, syn, &e)?; z += syn(ctx, ";", synkind::PUNCTUATION)?; return z; }; @@ -887,7 +887,7 @@ fn case_exprs( ctx.indent += 1; for (let j = 0z; j < len(exprs); j += 1) { z += newline(ctx)?; - z += stmt(ctx, syn, *exprs[j])?; + z += stmt(ctx, syn, exprs[j])?; }; ctx.indent -= 1; @@ -983,7 +983,7 @@ fn is_cast(e: *ast::expr) bool = { fn assert_expr( ctx: *context, syn: *synfunc, - e: ast::assert_expr, + e: *ast::assert_expr, ) (size | io::error) = { let z = 0z; if (e.is_static) { @@ -995,7 +995,7 @@ fn assert_expr( case let e: *ast::expr => z += syn(ctx, "assert", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e)?; + z += _expr(ctx, syn, e)?; case null => z += syn(ctx, "abort", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; @@ -1008,7 +1008,7 @@ fn assert_expr( z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; }; - z += _expr(ctx, syn, *m)?; + z += _expr(ctx, syn, m)?; case null => void; }; z += syn(ctx, ")", synkind::PUNCTUATION)?; @@ -1018,20 +1018,31 @@ fn assert_expr( fn append_insert_expr( ctx: *context, syn: *synfunc, - e: ast::append_expr, - is_insert: bool, + e: *ast::expr, ) (size | io::error) = { let z = 0z; - if (e.is_static) { - z += syn(ctx, "static", synkind::KEYWORD)?; - z += space(ctx)?; + const e: *ast::append_expr = match (e.expr) { + case let e: ast::append_expr => + if (e.is_static) { + z += syn(ctx, "static", synkind::KEYWORD)?; + z += space(ctx)?; + }; + z += syn(ctx, "append", synkind::KEYWORD)?; + yield &e; + case let e: ast::insert_expr => + if (e.is_static) { + z += syn(ctx, "static", synkind::KEYWORD)?; + z += space(ctx)?; + }; + z += syn(ctx, "insert", synkind::KEYWORD)?; + yield &e; + case => abort(); // unreachable }; - z += syn(ctx, if (is_insert) "insert" else "append", synkind::KEYWORD)?; z += syn(ctx, "(", synkind::PUNCTUATION)?; - z += _expr(ctx, syn, *e.object)?; + z += _expr(ctx, syn, e.object)?; z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *e.value)?; + z += _expr(ctx, syn, e.value)?; if (e.variadic) { z += syn(ctx, "...", synkind::OPERATOR)?; }; @@ -1040,7 +1051,7 @@ fn append_insert_expr( case let l: *ast::expr => z += syn(ctx, ",", synkind::PUNCTUATION)?; z += space(ctx)?; - z += _expr(ctx, syn, *l)?; + z += _expr(ctx, syn, l)?; }; z += syn(ctx, ")", synkind::PUNCTUATION)?; return z; diff --git a/hare/unparse/import.ha b/hare/unparse/import.ha @@ -10,13 +10,13 @@ use memio; export fn import( out: io::handle, syn: *synfunc, - import: ast::import, + import: *ast::import, ) (size | io::error) = { let n = 0z; let ctx = context { out = out, stack = &stack { - cur = &import, + cur = import, ... }, ... @@ -104,7 +104,7 @@ export fn import( ]; for (let i = 0z; i < len(tests); i += 1) { let buf = memio::dynamic(); - import(&buf, &syn_nowrap, tests[i].0)!; + import(&buf, &syn_nowrap, &tests[i].0)!; let s = memio::string(&buf)!; assert(s == tests[i].1); free(s); diff --git a/hare/unparse/syn.ha b/hare/unparse/syn.ha @@ -111,7 +111,7 @@ export fn syn_wrap(ctx: *context, s: str, kind: synkind) (size | io::error) = { yield :extra, &syn_wrap_extra::NONE; }; - let z = _type(io::empty, &syn_nowrap, *t)!; + let z = _type(io::empty, &syn_nowrap, t)!; if (ctx.linelen + z < 80) yield; st.extra = alloc(syn_wrap_extra::MULTILINE_FN_PARAM); z = fmt::fprintln(ctx.out, s)?; diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha @@ -63,19 +63,19 @@ case ast::builtin_type::VOID => fn prototype( ctx: *context, syn: *synfunc, - t: ast::func_type, + t: *ast::func_type, ) (size | io::error) = { let n = 0z; n += syn(ctx, "(", synkind::PUNCTUATION)?; for (let i = 0z; i < len(t.params); i += 1) { - const param = t.params[i]; + const param = &t.params[i]; if (param.name != "") { n += syn(ctx, param.name, synkind::SECONDARY)?; n += syn(ctx, ":", synkind::PUNCTUATION)?; n += space(ctx)?; }; - n += __type(ctx, syn, *param._type)?; + n += __type(ctx, syn, param._type)?; if (i + 1 < len(t.params) || t.variadism == variadism::C) { n += syn(ctx, ",", synkind::PUNCTUATION)?; n += space(ctx)?; @@ -87,14 +87,14 @@ fn prototype( n += syn(ctx, ")", synkind::PUNCTUATION)?; n += space(ctx)?; - n += __type(ctx, syn, *t.result)?; + n += __type(ctx, syn, t.result)?; return n; }; fn struct_union_type( ctx: *context, syn: *synfunc, - t: ast::_type, + t: *ast::_type, ) (size | io::error) = { let z = 0z; let membs = match (t.repr) { @@ -131,21 +131,21 @@ fn struct_union_type( case null => void; case let ex: *ast::expr => z += syn(ctx, "@offset(", synkind::ATTRIBUTE)?; - z += _expr(ctx, syn, *ex)?; + z += _expr(ctx, syn, ex)?; z += syn(ctx, ")", synkind::ATTRIBUTE)?; z += space(ctx)?; }; match (membs[i].member) { case let se: ast::struct_embedded => - z += __type(ctx, syn, *se)?; + z += __type(ctx, syn, se)?; case let sa: ast::struct_alias => z += _ident(ctx, syn, sa, synkind::IDENT)?; case let sf: ast::struct_field => z += syn(ctx, sf.name, synkind::SECONDARY)?; z += syn(ctx, ":", synkind::PUNCTUATION)?; z += space(ctx)?; - z += __type(ctx, syn, *sf._type)?; + z += __type(ctx, syn, sf._type)?; }; z += syn(ctx, ",", synkind::PUNCTUATION)?; @@ -164,7 +164,7 @@ fn multiline_comment(s: str) bool = export fn _type( out: io::handle, syn: *synfunc, - t: ast::_type, + t: *ast::_type, ) (size | io::error) = { let ctx = context { out = out, @@ -173,9 +173,9 @@ export fn _type( return __type(&ctx, syn, t); }; -fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { +fn __type(ctx: *context, syn: *synfunc, t: *ast::_type) (size | io::error) = { ctx.stack = &stack { - cur = &t, + cur = t, up = ctx.stack, ... }; @@ -238,7 +238,7 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { n += space(ctx)?; n += syn(ctx, "=", synkind::OPERATOR)?; n += space(ctx)?; - n += _expr(ctx, syn, *e)?; + n += _expr(ctx, syn, e)?; }; n += syn(ctx, ",", synkind::PUNCTUATION)?; if (value.docs != "" && !wrotedocs) { @@ -260,7 +260,7 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { n += syn(ctx, "}", synkind::PUNCTUATION)?; case let f: ast::func_type => n += syn(ctx, "fn", synkind::TYPE)?; - n += prototype(ctx, syn, f)?; + n += prototype(ctx, syn, &f)?; case let l: ast::list_type => n += syn(ctx, "[", synkind::TYPE)?; match (l.length) { @@ -270,17 +270,17 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { case ast::len_contextual => n += syn(ctx, "_", synkind::TYPE)?; case let e: *ast::expr => - n += _expr(ctx, syn, *e)?; + n += _expr(ctx, syn, e)?; }; n += syn(ctx, "]", synkind::TYPE)?; - n += __type(ctx, syn, *l.members)?; + n += __type(ctx, syn, l.members)?; case let p: ast::pointer_type => if (p.flags & ast::pointer_flag::NULLABLE != 0) { n += syn(ctx, "nullable", synkind::TYPE)?; n += space(ctx)?; }; n += syn(ctx, "*", synkind::TYPE)?; - n += __type(ctx, syn, *p.referent)?; + n += __type(ctx, syn, p.referent)?; case ast::struct_type => n += struct_union_type(ctx, syn, t)?; case ast::union_type => @@ -288,7 +288,7 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { case let t: ast::tagged_type => n += syn(ctx, "(", synkind::TYPE)?; for (let i = 0z; i < len(t); i += 1) { - n += __type(ctx, syn, *t[i])?; + n += __type(ctx, syn, t[i])?; if (i + 1 == len(t)) break; n += space(ctx)?; n += syn(ctx, "|", synkind::TYPE)?; @@ -298,7 +298,7 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { case let t: ast::tuple_type => n += syn(ctx, "(", synkind::TYPE)?; for (let i = 0z; i < len(t); i += 1) { - n += __type(ctx, syn, *t[i])?; + n += __type(ctx, syn, t[i])?; if (i + 1 == len(t)) break; n += syn(ctx, ",", synkind::TYPE)?; n += space(ctx)?; @@ -308,7 +308,7 @@ fn __type(ctx: *context, syn: *synfunc, t: ast::_type) (size | io::error) = { return n; }; -fn type_test(t: ast::_type, expected: str) void = { +fn type_test(t: *ast::_type, expected: str) void = { let buf = memio::dynamic(); _type(&buf, &syn_nowrap, t)!; let s = memio::string(&buf)!; @@ -347,17 +347,17 @@ fn type_test(t: ast::_type, expected: str) void = { expr = void, }; - type_test(t, "const foo::bar"); + type_test(&t, "const foo::bar"); t.flags = 0; t.repr = ast::alias_type { unwrap = true, ident = ["baz"], }; - type_test(t, "...baz"); + type_test(&t, "...baz"); t.flags = ast::type_flag::ERROR; t.repr = ast::builtin_type::INT; - type_test(t, "!int"); + type_test(&t, "!int"); t.flags = ast::type_flag::CONST | ast::type_flag::ERROR; t.repr = ast::enum_type { @@ -377,7 +377,7 @@ fn type_test(t: ast::_type, expected: str) void = { }, ], }; - type_test(t, "const !enum u32 {\n\tFOO,\n\tBAR = void,\n}"); + type_test(&t, "const !enum u32 {\n\tFOO,\n\tBAR = void,\n}"); t.flags = 0; @@ -386,7 +386,7 @@ fn type_test(t: ast::_type, expected: str) void = { variadism = variadism::NONE, params = [], }; - type_test(t, "fn() int"); + type_test(&t, "fn() int"); t.repr = ast::func_type { result = &type_int, variadism = variadism::C, @@ -398,7 +398,7 @@ fn type_test(t: ast::_type, expected: str) void = { }, ], }; - type_test(t, "fn(int, ...) int"); + type_test(&t, "fn(int, ...) int"); t.repr = ast::func_type { result = &type_int, variadism = variadism::HARE, @@ -415,43 +415,43 @@ fn type_test(t: ast::_type, expected: str) void = { }, ], }; - type_test(t, "fn(foo: int, bar: int...) int"); + type_test(&t, "fn(foo: int, bar: int...) int"); t.repr = ast::list_type { length = ast::len_slice, members = &type_int, }; - type_test(t, "[]int"); + type_test(&t, "[]int"); t.repr = ast::list_type { length = ast::len_unbounded, members = &type_int, }; - type_test(t, "[*]int"); + type_test(&t, "[*]int"); t.repr = ast::list_type { length = ast::len_contextual, members = &type_int, }; - type_test(t, "[_]int"); + type_test(&t, "[_]int"); t.repr = ast::list_type { length = &expr_void, members = &type_int, }; - type_test(t, "[void]int"); + type_test(&t, "[void]int"); t.repr = ast::pointer_type { referent = &type_int, flags = 0, }; - type_test(t, "*int"); + type_test(&t, "*int"); t.repr = ast::pointer_type { referent = &type_int, flags = ast::pointer_flag::NULLABLE, }; - type_test(t, "nullable *int"); + type_test(&t, "nullable *int"); t.repr = [&type_int, &type_int]: ast::tagged_type; - type_test(t, "(int | int)"); + type_test(&t, "(int | int)"); t.repr = [&type_int, &type_int]: ast::tuple_type; - type_test(t, "(int, int)"); + type_test(&t, "(int, int)"); }; diff --git a/hare/unparse/unit.ha b/hare/unparse/unit.ha @@ -13,14 +13,14 @@ export fn subunit( ) (size | io::error) = { let n = 0z; for (let i = 0z; i < len(s.imports); i += 1) { - n += import(out, syn, s.imports[i])?; + n += import(out, syn, &s.imports[i])?; n += fmt::fprintln(out)?; }; if (len(s.imports) > 0) { n += fmt::fprintln(out)?; }; for (let i = 0z; i < len(s.decls); i += 1) { - n += decl(out, syn, s.decls[i])?; + n += decl(out, syn, &s.decls[i])?; if (i < len(s.decls) - 1) n += fmt::fprintln(out)?; n += fmt::fprintln(out)?; };