feat: guard 语句 guard x >= 0 else { return -1; }
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fn abs(x: i64) -> i64 {
|
||||
guard x >= 0 else { return -x; }
|
||||
return x;
|
||||
}
|
||||
|
||||
fn main() -> i64 {
|
||||
print_i64(abs(10)); // 10
|
||||
print_i64(abs(-5)); // 5
|
||||
print_i64(abs(0)); // 0
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user