feat: 复合赋值 += -= *= /= + CHANGELOG 更新
- lexer: 4 个复合赋值 Token (解析时优先于单字符) - parser: desugar x+=expr → x=x+expr(零 sema/codegen 改动) - 新增集成测试 09_compound_assign.l (15 12 24 6) - CHANGELOG 新增 v0.2.0 条目
This commit is contained in:
@@ -277,6 +277,37 @@ static AstNode* parse_statement(Parser* p, ErrorInfo* error) {
|
||||
value, name->line, name->col);
|
||||
}
|
||||
|
||||
// 复合赋值: ident += expr → ident = ident + expr
|
||||
if (t->kind == TOK_IDENT) {
|
||||
TokenKind next_kind = (t + 1)->kind;
|
||||
if (next_kind >= TOK_PLUS_EQ && next_kind <= TOK_SLASH_EQ) {
|
||||
const Token* name = advance(p); // 消费标识符
|
||||
TokenKind comp_op = advance(p)->kind;
|
||||
|
||||
BinaryOp binop;
|
||||
switch (comp_op) {
|
||||
case TOK_PLUS_EQ: binop = OP_ADD; break;
|
||||
case TOK_MINUS_EQ: binop = OP_SUB; break;
|
||||
case TOK_STAR_EQ: binop = OP_MUL; break;
|
||||
case TOK_SLASH_EQ: binop = OP_DIV; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
AstNode* rhs = parse_expr(p, error);
|
||||
if (!rhs) return NULL;
|
||||
if (!expect(p, TOK_SEMICOLON, error, "缺少 ';'")) return NULL;
|
||||
|
||||
AstNode* lhs_ident = ast_make_ident(p->arena,
|
||||
arena_strdup_impl(p->arena, name->start, name->length),
|
||||
name->line, name->col);
|
||||
AstNode* bin_expr = ast_make_binary(p->arena, binop, lhs_ident, rhs,
|
||||
name->line, name->col);
|
||||
return ast_make_assign(p->arena,
|
||||
arena_strdup_impl(p->arena, name->start, name->length),
|
||||
bin_expr, name->line, name->col);
|
||||
}
|
||||
}
|
||||
|
||||
// 表达式语句
|
||||
AstNode* expr = parse_expr(p, error);
|
||||
if (!expr) return NULL;
|
||||
|
||||
Reference in New Issue
Block a user