~sircmpwn/harec unlisted

8afb6a1223ec2057765ba8d1228d131bff0c88fb — Eyal Sawady a month ago 183a71a
Revert match syntax changes

This reverts commits 4fd4b372f4424b14a37f227adf2d6c9888fa8440 and
0e12d1e84cf7f0be0a9b94ee97352ca4d72d9219.

Signed-off-by: Eyal Sawady <ecs@d2evs.net>
3 files changed, 77 insertions(+), 45 deletions(-)

M src/parse.c
M tests/18-match.ha
M tests/26-gen.ha
M src/parse.c => src/parse.c +48 -16
@@ 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);


M tests/18-match.ha => tests/18-match.ha +26 -26
@@ 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);
};

M tests/26-gen.ha => tests/26-gen.ha +3 -3
@@ 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;