feat: guard 语句 guard x >= 0 else { return -1; }

This commit is contained in:
2026-06-05 20:49:03 +08:00
parent 18172ca724
commit c6e492662e
5 changed files with 27 additions and 3 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ static TokenKind check_keyword(const Token* tok) {
#define KW(s, k) if (tok->length == sizeof(s)-1 && memcmp(tok->start, s, sizeof(s)-1) == 0) return k
KW("fn", TOK_FN); KW("let", TOK_LET);
KW("var", TOK_VAR);
KW("if", TOK_IF); KW("else", TOK_ELSE);
KW("if", TOK_IF); KW("else", TOK_ELSE); KW("guard", TOK_GUARD);
KW("while", TOK_WHILE); KW("for", TOK_FOR); KW("in", TOK_IN);
KW("to", TOK_TO);
KW("return", TOK_RETURN);
+1 -1
View File
@@ -5,7 +5,7 @@
#include <inttypes.h>
static const char* NAMES[] = {
[TOK_FN] = "fn", [TOK_LET] = "let", [TOK_VAR] = "var", [TOK_IF] = "if",
[TOK_FN] = "fn", [TOK_LET] = "let", [TOK_VAR] = "var", [TOK_IF] = "if", [TOK_GUARD] = "guard",
[TOK_ELSE] = "else", [TOK_WHILE] = "while", [TOK_FOR] = "for", [TOK_IN] = "in", [TOK_RETURN] = "return",
[TOK_STRUCT] = "struct", [TOK_TYPE] = "type", [TOK_ENUM] = "enum", [TOK_EXTEND] = "extend",
[TOK_MATCH] = "match",
+1 -1
View File
@@ -6,7 +6,7 @@
// === Token 类型枚举 ===
typedef enum {
// 关键字
TOK_FN, TOK_LET, TOK_VAR, TOK_IF, TOK_ELSE, TOK_WHILE, TOK_FOR, TOK_IN, TOK_RETURN,
TOK_FN, TOK_LET, TOK_VAR, TOK_IF, TOK_ELSE, TOK_WHILE, TOK_FOR, TOK_IN, TOK_RETURN, TOK_GUARD,
TOK_STRUCT, TOK_TYPE, TOK_ENUM, TOK_EXTEND, TOK_MATCH,
// 类型关键字
TOK_I32, TOK_I64, TOK_U64, TOK_F64, TOK_BOOL, TOK_CHAR, TOK_STR, TOK_VOID,
+13
View File
@@ -621,6 +621,19 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
return parse_match_stmt(p, error);
}
if (t->kind == TOK_GUARD) {
// guard expr else { ... } → if !(expr) { ... }
const Token* guard_tok = advance(p);
AstNode* cond = parse_expr(p, error);
if (!cond) return NULL;
if (!expect(p, TOK_ELSE, error, "guard 缺少 'else'")) return NULL;
AstNode* body = parse_block(p, error);
if (!body) return NULL;
// 去糖: if !cond { body }
AstNode* not_cond = ast_make_unary(p->arena, OP_NOT, cond, tok_loc(guard_tok));
return ast_make_if(p->arena, not_cond, body, NULL, tok_loc(guard_tok));
}
if (t->kind == TOK_RETURN) {
advance(p);
if (match(p, TOK_SEMICOLON)) {