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:
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, " => ")?;