hare

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

commit 73647c00b26774d960e65fee9b502440904d4aed
parent abf25291435bcf240a753be2ee0ed987c4877329
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 28 Apr 2021 15:25:26 -0400

hare::parse: update for reverted match syntax

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Mhare/parse/+test/expr.ha | 7+++++--
Mhare/parse/expr.ha | 24++++++++++--------------
Mhare/parse/parse.ha | 41+++++++++++++++++++++++++++++++++++++++++
Mhare/unparse/expr.ha | 6------
4 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -216,14 +216,17 @@ roundtrip("export fn main() void = { match (x) { i: size => y, - _: str => { + str => { z; }, + foo => bar, + foo: int => bar, + foo::bar => baz, null => void, }; match (x) { s: matchdata => y, - _: str => { + str => { z; }, * => q, diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -821,22 +821,18 @@ fn switch_expr(lexer: *lex::lexer) (ast::expr | error) = { }; fn match_case(lexer: *lex::lexer) (ast::match_case | error) = { - let tok = want(lexer, ltok::NAME, ltok::UNDERSCORE, ltok::NULL)?; + let tok = peek(lexer)? as lex::token; + let loc = tok.2; let nt = switch (tok.0) { - ltok::NAME => { - let name = tok.1 as str; - want(lexer, ltok::COLON)?; - (name, _type(lexer)?); - }, - ltok::UNDERSCORE => { - want(lexer, ltok::COLON)?; - ("", _type(lexer)?); + ltok::NULL => { + want(lexer, ltok::NULL)?; + ("", ast::_type { + loc = loc, + flags = 0, + _type = ast::builtin_type::NULL, + }); }, - ltok::NULL => ("", ast::_type { - loc = tok.2, - flags = 0, - _type = ast::builtin_type::NULL, - }), + * => nametype(lexer)?, }; want(lexer, ltok::CASE)?; let expr = expression(lexer)?; diff --git a/hare/parse/parse.ha b/hare/parse/parse.ha @@ -1,5 +1,6 @@ use fmt; use hare::ast; +use hare::lex::{ltok}; use hare::lex; use io; use strio; @@ -92,3 +93,43 @@ fn synassert(loc: lex::location, cond: bool, msg: str) (void | error) = { return syntaxerr(loc, msg); }; }; + +fn nametype(lexer: *lex::lexer) ((str, ast::_type) | error) = { + let tok = peek(lexer)? as lex::token; + let loc = tok.2; + return switch (tok.0) { + ltok::NAME => { + let name = tok.1 as str; + want(lexer, ltok::NAME)?; + tok = peek(lexer)? as lex::token; + switch (tok.0) { + ltok::COLON => { + want(lexer, ltok::COLON)?; + (name, _type(lexer)?); + }, + ltok::DOUBLE_COLON => { + want(lexer, ltok::DOUBLE_COLON)?; + let id = ident(lexer)?; + insert(id[0], name); + ("", ast::_type { + loc = loc, + flags = 0, + _type = ast::alias_type { + unwrap = false, + ident = id, + }, + }); + }, + * => ("", ast::_type { + loc = loc, + flags = 0, + _type = ast::alias_type { + unwrap = false, + ident = alloc([name]), + }, + }), + }; + }, + * => ("", _type(lexer)?), + }; +}; diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -458,14 +458,8 @@ fn match_expr( for (let i = 0z; i < len(e.cases); i += 1) { z += newline(out, indent)?; const case = e.cases[i]; - const is_null = match (case._type._type) { - b: ast::builtin_type => b == ast::builtin_type::NULL, - * => false, - }; if (len(case.name) > 0) { z += fmt::fprintf(out, "{}: ", case.name)?; - } else if (!is_null) { - z += fmt::fprintf(out, "_: ")?; }; z += _type(out, indent, *case._type)?; z += fmt::fprint(out, " => ")?;