feat: struct方法 impl (P1 #9)
- lexer: TOK_IMPL 关键字
- ast: AST_IMPL_BLOCK, AST_METHOD_CALL + AST_PROGRAM impls数组
- parser: impl StructName { fn ... } + p.method() 方法调用
- sema: 方法名mangle(StructName$method), self参数, 类型检查
- codegen: METHOD_CALL→mangled函数调用(recv为第一参数)
- 新增集成测试: 19_struct_method.l
P1 4项全部完成: type alias + enum + array + impl
测试: 145 通过 (41+15+65+24)
This commit is contained in:
@@ -329,6 +329,42 @@ void test_array_assign_ok() {
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
/* === 方法调用语义分析测试 === */
|
||||
|
||||
void test_method_call_ok() {
|
||||
Arena a = arena_create(1);
|
||||
size_t tc; ErrorInfo lex_err = {0};
|
||||
Token* toks = lex(&a,
|
||||
"struct Point { x: i64, y: i64 } impl Point { fn get_x(self: Point) -> i64 { return self.x; } } fn main() -> i64 { let p: Point = Point { x: 42, y: 0 }; return p.get_x(); }",
|
||||
"test", &tc, &lex_err);
|
||||
ASSERT(toks != NULL);
|
||||
ErrorInfo parse_err = {0};
|
||||
AstNode* ast = parse(&a, toks, tc, "test", &parse_err);
|
||||
ASSERT(ast != NULL);
|
||||
|
||||
ErrorList errors; error_init(&errors);
|
||||
sema_analyze(ast, &errors, &a);
|
||||
ASSERT(errors.count == 0);
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
void test_method_undefined() {
|
||||
Arena a = arena_create(1);
|
||||
size_t tc; ErrorInfo lex_err = {0};
|
||||
Token* toks = lex(&a,
|
||||
"struct Point { x: i64, y: i64 } fn main() -> i64 { let p: Point = Point { x: 42, y: 0 }; return p.nope(); }",
|
||||
"test", &tc, &lex_err);
|
||||
ASSERT(toks != NULL);
|
||||
ErrorInfo parse_err = {0};
|
||||
AstNode* ast = parse(&a, toks, tc, "test", &parse_err);
|
||||
ASSERT(ast != NULL);
|
||||
|
||||
ErrorList errors; error_init(&errors);
|
||||
sema_analyze(ast, &errors, &a);
|
||||
ASSERT(errors.count > 0); // nope 不是 Point 的方法
|
||||
arena_destroy(&a);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
TEST_RUN(test_type_error);
|
||||
TEST_RUN(test_undefined_var);
|
||||
@@ -349,5 +385,7 @@ int main(void) {
|
||||
TEST_RUN(test_array_index_type_error);
|
||||
TEST_RUN(test_array_not_indexable);
|
||||
TEST_RUN(test_array_assign_ok);
|
||||
TEST_RUN(test_method_call_ok);
|
||||
TEST_RUN(test_method_undefined);
|
||||
return test_summary();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user