commit 8afb6a1223ec2057765ba8d1228d131bff0c88fb
parent 183a71a35b32e617a8dc018897895a32fc3d32df
Author: Eyal Sawady <ecs@d2evs.net>
Date: Wed, 28 Apr 2021 12:57:14 -0400
Revert match syntax changes
This reverts commits 4fd4b372f4424b14a37f227adf2d6c9888fa8440 and
0e12d1e84cf7f0be0a9b94ee97352ca4d72d9219.
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
3 files changed, 77 insertions(+), 45 deletions(-)
diff --git a/src/parse.c b/src/parse.c
@@ -1840,30 +1840,62 @@ parse_match_expression(struct lexer *lexer)
struct ast_match_case *_case =
*next_case = xcalloc(1, sizeof(struct ast_match_case));
- struct ast_type *null = NULL;
+ struct token tok2 = {0};
+ struct identifier ident = {0};
+ struct ast_type *type = NULL;
switch (lex(lexer, &tok)) {
- case T_NULL:
- null = xcalloc(1, sizeof(struct ast_type));
- null->loc = tok.loc;
- null->storage = STORAGE_NULL;
- _case->type = null;
- break;
- case T_UNDERSCORE:
- want(lexer, T_COLON, NULL);
- _case->type = parse_type(lexer);
- break;
case T_NAME:
- _case->name = tok.name;
- want(lexer, T_COLON, NULL);
- _case->type = parse_type(lexer);
+ switch (lex(lexer, &tok2)) {
+ case T_COLON:
+ _case->name = tok.name; // Assumes ownership
+ _case->type = parse_type(lexer);
+ break;
+ case T_DOUBLE_COLON:
+ ident.ns = xcalloc(1, sizeof(struct identifier));
+ ident.ns->name = tok.name; // Assumes ownership
+ parse_identifier(lexer, &ident, false);
+ _case->type = mktype(&tok.loc);
+ _case->type->storage = STORAGE_ALIAS;
+ _case->type->alias = ident;
+ break;
+ case T_CASE:
+ unlex(lexer, &tok2);
+ _case->type = mktype(&tok.loc);
+ _case->type->storage = STORAGE_ALIAS;
+ _case->type->alias.name = tok.name;
+ break;
+ default:
+ synassert(false, &tok, T_COLON,
+ T_DOUBLE_COLON, T_CASE, T_EOF);
+ break;
+ }
break;
case T_TIMES:
+ switch (lex(lexer, &tok2)) {
+ case T_CASE: // Default case
+ unlex(lexer, &tok2);
+ break;
+ default:
+ unlex(lexer, &tok2);
+ _case->type = parse_type(lexer);
+ struct ast_type *ptr = mktype(&tok.loc);
+ ptr->storage = STORAGE_POINTER;
+ ptr->pointer.referent = _case->type;
+ _case->type = ptr;
+ break;
+ }
+ break;
+ case T_NULL:
+ type = mktype(&tok.loc);
+ type->storage = STORAGE_NULL;
+ _case->type = type;
break;
default:
- synassert(false, &tok, T_NAME, T_NULL, T_UNDERSCORE,
- T_TIMES, T_EOF);
+ unlex(lexer, &tok);
+ _case->type = parse_type(lexer);
break;
}
+
want(lexer, T_CASE, &tok);
_case->value = parse_expression(lexer);
diff --git a/tests/18-match.ha b/tests/18-match.ha
@@ -3,9 +3,9 @@ fn tagged() void = {
let expected: [_]size = [1, 2, 5];
for (let i = 0z; i < len(cases); i += 1) {
let y: size = match (cases[i]) {
- _: int => 1,
- _: uint => 2,
- s: str => len(s),
+ int => 1,
+ uint => 2,
+ s: str => len(s),
};
assert(y == expected[i]);
};
@@ -15,9 +15,9 @@ fn termination() void = {
let x: (int | uint | str) = 1337i;
for (true) {
let y: int = match (x) {
- _: int => 42,
- _: uint => abort(),
- _: str => break,
+ int => 42,
+ uint => abort(),
+ str => break,
};
assert(y == 42);
x = "hi";
@@ -27,8 +27,8 @@ fn termination() void = {
fn default() void = {
let x: (int | uint | str) = 1337u;
let y: int = match (x) {
- _: int => 42,
- * => 24,
+ int => 42,
+ * => 24,
};
assert(y == 24);
};
@@ -44,7 +44,7 @@ fn pointer() void = {
y = null;
z = match(y) {
- _: *int => abort(),
+ *int => abort(),
null => 1337,
};
assert(z == 1337);
@@ -59,8 +59,8 @@ fn alias() void = {
let expected = [42, 24];
for (let i = 0z; i < len(cases); i += 1) {
let y: int = match (cases[i]) {
- _: foo => 42,
- _: bar => 24,
+ foo => 42,
+ bar => 24,
};
assert(y == expected[i]);
};
@@ -102,24 +102,24 @@ fn transitivity() void = {
let x: (foobar | int) = 10;
match (x) {
i: int => assert(i == 10),
- _: foo => abort(),
- _: bar => abort(),
+ foo => abort(),
+ bar => abort(),
};
x = foo;
let visit = false;
match (x) {
- _: int => abort(),
- _: foo => visit = true,
- _: bar => abort(),
+ int => abort(),
+ foo => visit = true,
+ bar => abort(),
};
assert(visit);
x = bar;
visit = false;
match (x) {
- _: int => abort(),
- _: foo => abort(),
- _: foobar => visit = true,
+ int => abort(),
+ foo => abort(),
+ foobar => visit = true,
};
assert(visit);
@@ -129,25 +129,25 @@ fn transitivity() void = {
visit = true;
assert(z is bar);
},
- _: int => abort(),
+ int => abort(),
};
assert(visit);
let y: foobarbaz = 10;
visit = false;
match (y) {
- _: baz => visit = true,
- _: foo => abort(),
- _: bar => abort(),
+ baz => visit = true,
+ foo => abort(),
+ bar => abort(),
};
assert(visit);
y = foo;
visit = false;
match (y) {
- _: baz => abort(),
- _: foo => visit = true,
- _: bar => abort(),
+ baz => abort(),
+ foo => visit = true,
+ bar => abort(),
};
assert(visit);
};
diff --git a/tests/26-gen.ha b/tests/26-gen.ha
@@ -24,13 +24,13 @@ export fn main() void = {
let x: (void | int) = 10;
match (x) {
i: int => assert(i == 10),
- _: void => abort(),
+ void => abort(),
};
let p = 0;
let p = &p: uintptr: u64: (u64 | void);
let p = match (p) {
- _: void => abort(),
+ void => abort(),
p: u64 => p: uintptr: *int,
};
assert(*p == 0);
@@ -38,7 +38,7 @@ export fn main() void = {
let thing: int = 0;
let thing = &thing: (*int | int);
let p = match (thing) {
- _: int => abort(),
+ int => abort(),
p: *int => p,
};
*p = 0;