feat: match 表达式 (P1 #8 收官)

- lexer: TOK_MATCH, TOK_MATCH_ARROW, TOK_UNDERSCORE
- parser: parse_match_stmt() desugar → let+if-else链
- 零 sema/codegen 改动
- 4个集成测试: enum/int literal/wildcard match

P1 全部完成: type alias + enum + array + impl + match
This commit is contained in:
2026-06-05 14:41:52 +08:00
parent 9f6e695ba8
commit a15cd9d56e
8 changed files with 143 additions and 6 deletions
+3 -1
View File
@@ -63,7 +63,8 @@ static TokenKind check_keyword(const Token* tok) {
KW("bool", TOK_BOOL); KW("str", TOK_STR);
KW("void", TOK_VOID);
KW("struct", TOK_STRUCT); KW("type", TOK_TYPE);
KW("enum", TOK_ENUM); KW("impl", TOK_IMPL);
KW("enum", TOK_ENUM); KW("impl", TOK_IMPL); KW("match", TOK_MATCH);
KW("_", TOK_UNDERSCORE);
KW("true", TOK_TRUE); KW("false", TOK_FALSE);
#undef KW
return TOK_IDENT;
@@ -126,6 +127,7 @@ Token* lex(Arena* a, const char* source, const char* filename,
else if (c == '/') { tokens[idx++] = make_token(&l, TOK_SLASH, l.pos, 1); advance(&l); }
else if (c == '%') { tokens[idx++] = make_token(&l, TOK_PERCENT, l.pos, 1); advance(&l); }
else if (c == '=' && peek_next(&l) == '=') { tokens[idx++] = make_token(&l, TOK_EQ_EQ, l.pos, 2); advance(&l); advance(&l); }
else if (c == '=' && peek_next(&l) == '>') { tokens[idx++] = make_token(&l, TOK_MATCH_ARROW, l.pos, 2); advance(&l); advance(&l); }
else if (c == '=') { tokens[idx++] = make_token(&l, TOK_ASSIGN, l.pos, 1); advance(&l); }
else if (c == '!' && peek_next(&l) == '=') { tokens[idx++] = make_token(&l, TOK_BANG_EQ, l.pos, 2); advance(&l); advance(&l); }
else if (c == '!') { tokens[idx++] = make_token(&l, TOK_BANG, l.pos, 1); advance(&l); }