diff --git a/libs/ast/include/ast_builtin.h b/libs/ast/include/ast_builtin.h index ec61424..544bd48 100644 --- a/libs/ast/include/ast_builtin.h +++ b/libs/ast/include/ast_builtin.h @@ -3,28 +3,29 @@ #include "ast_def.h" +extern scc_ast_type_t scc_ast_builtin_type_va_list; +extern scc_ast_type_t scc_ast_builtin_type_void; +extern scc_ast_type_t scc_ast_builtin_type_bool; +extern scc_ast_type_t scc_ast_builtin_type_char; +extern scc_ast_type_t scc_ast_builtin_type_short; +extern scc_ast_type_t scc_ast_builtin_type_long; +extern scc_ast_type_t scc_ast_builtin_type_long_long; extern scc_ast_type_t scc_ast_builtin_type_int; extern scc_ast_type_t scc_ast_builtin_type_float; extern scc_ast_type_t scc_ast_builtin_type_double; -extern scc_ast_type_t scc_ast_builtin_type_char; -extern scc_ast_type_t scc_ast_builtin_type_void; -extern scc_ast_type_t scc_ast_builtin_type_long; -extern scc_ast_type_t scc_ast_builtin_type_long_long; -extern scc_ast_type_t scc_ast_builtin_type_short; -extern scc_ast_type_t scc_ast_builtin_type_bool; extern scc_ast_type_t scc_ast_builtin_type_long_double; extern scc_ast_type_t scc_ast_builtin_type_complex_float; extern scc_ast_type_t scc_ast_builtin_type_complex_double; extern scc_ast_type_t scc_ast_builtin_type_complex_long_double; +extern scc_ast_type_t scc_ast_builtin_type_unsigned_char; +extern scc_ast_type_t scc_ast_builtin_type_unsigned_short; extern scc_ast_type_t scc_ast_builtin_type_unsigned_int; extern scc_ast_type_t scc_ast_builtin_type_unsigned_long; extern scc_ast_type_t scc_ast_builtin_type_unsigned_long_long; -extern scc_ast_type_t scc_ast_builtin_type_unsigned_short; -extern scc_ast_type_t scc_ast_builtin_type_unsigned_char; +extern scc_ast_type_t scc_ast_builtin_type_signed_char; +extern scc_ast_type_t scc_ast_builtin_type_signed_short; extern scc_ast_type_t scc_ast_builtin_type_signed_int; extern scc_ast_type_t scc_ast_builtin_type_signed_long; extern scc_ast_type_t scc_ast_builtin_type_signed_long_long; -extern scc_ast_type_t scc_ast_builtin_type_signed_short; -extern scc_ast_type_t scc_ast_builtin_type_signed_char; #endif diff --git a/libs/ast/include/ast_def.h b/libs/ast/include/ast_def.h index e673f3a..7dd8c39 100644 --- a/libs/ast/include/ast_def.h +++ b/libs/ast/include/ast_def.h @@ -95,20 +95,34 @@ typedef struct { * @brief 内置类型枚举 */ typedef enum { + SCC_AST_BUILTIN_TYPE_UNKNOWN, + SCC_AST_BUILTIN_TYPE_VA_LIST, SCC_AST_BUILTIN_TYPE_VOID, + SCC_AST_BUILTIN_TYPE_BOOL, SCC_AST_BUILTIN_TYPE_CHAR, SCC_AST_BUILTIN_TYPE_SHORT, SCC_AST_BUILTIN_TYPE_INT, SCC_AST_BUILTIN_TYPE_LONG, SCC_AST_BUILTIN_TYPE_LONG_LONG, + + SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR, + SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT, + SCC_AST_BUILTIN_TYPE_UNSIGNED_INT, + SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG, + SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG, + + SCC_AST_BUILTIN_TYPE_SIGNED_CHAR, + SCC_AST_BUILTIN_TYPE_SIGNED_SHORT, + SCC_AST_BUILTIN_TYPE_SIGNED_INT, + SCC_AST_BUILTIN_TYPE_SIGNED_LONG, + SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG, + SCC_AST_BUILTIN_TYPE_FLOAT, SCC_AST_BUILTIN_TYPE_DOUBLE, SCC_AST_BUILTIN_TYPE_LONG_DOUBLE, - SCC_AST_BUILTIN_TYPE_BOOL, SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT, SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE, SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE, - SCC_AST_BUILTIN_TYPE_VA_LIST, } scc_ast_builtin_type_t; /** @@ -284,7 +298,7 @@ struct scc_ast_expr { const char *name; usize _target_idx; } member; - // 类型转换 + // cast 类型转换 struct { scc_ast_type_t *type; scc_ast_expr_t *expr; diff --git a/libs/ast/include/scc_ast.h b/libs/ast/include/scc_ast.h index 4dda9a0..d5a271e 100644 --- a/libs/ast/include/scc_ast.h +++ b/libs/ast/include/scc_ast.h @@ -46,12 +46,11 @@ static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl, decl->func.body = body; } -// body can be null +// name can be null static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl, scc_ast_type_t *type, - const char *name, - scc_ast_stmt_t *body) { - Assert(decl != null && name != null && type != null); + const char *name) { + Assert(decl != null && type != null); decl->base.loc = scc_pos_create(); decl->base.type = SCC_AST_DECL_PARAM; decl->name = name; @@ -342,10 +341,26 @@ static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr, _scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member); } +// TODO // SCC_AST_EXPR_CAST, // 类型转换 // SCC_AST_EXPR_SIZE_OF, // sizeof // SCC_AST_EXPR_ALIGN_OF, // _Alignof -// SCC_AST_EXPR_COMPOUND_LITERAL, // 复合字面量 + +// init can be null +static inline void +scc_ast_expr_compound_literal_init(scc_ast_expr_t *expr, scc_ast_type_t *type, + scc_ast_expr_vec_t *init) { + Assert(expr != null && type != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_COMPOUND_LITERAL; + expr->compound_literal.type = type; + if (init == null) { + scc_vec_init(expr->compound_literal.init_list); + } else { + expr->compound_literal.init_list = *init; + scc_vec_init(*init); + } +} static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr, scc_ast_node_type_t type, @@ -388,9 +403,36 @@ static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr, expr->identifier._target = null; } -// SCC_AST_TYPE_BUILTIN, // 内置类型 -// SCC_AST_TYPE_POINTER, // 指针类型 -// SCC_AST_TYPE_ARRAY, // 数组类型 +// have defined builtin type +static inline void _scc_ast_type_builtin_init(scc_ast_type_t *type, + scc_ast_builtin_type_t builtin) { + Assert(type != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_BUILTIN; + type->builtin.type = builtin; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME +} + +static inline void scc_ast_type_pointer_init(scc_ast_type_t *type, + scc_ast_type_t *pointee) { + Assert(type != null && pointee != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_POINTER; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME + type->pointer.pointee = pointee; +} + +// size can be null +static inline void scc_ast_type_array_init(scc_ast_type_t *type, + scc_ast_type_t *element, + scc_ast_expr_t *size) { + Assert(type != null && element != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_ARRAY; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME + type->array.element = element; + type->array.size = size; +} // return_type and params can be null static inline void scc_ast_type_function_init(scc_ast_type_t *type, @@ -400,6 +442,7 @@ static inline void scc_ast_type_function_init(scc_ast_type_t *type, type->base.loc = scc_pos_create(); type->base.type = SCC_AST_TYPE_FUNCTION; type->function.return_type = return_type; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME if (params == null) { scc_vec_init(type->function.param_types); } else { @@ -408,9 +451,62 @@ static inline void scc_ast_type_function_init(scc_ast_type_t *type, } } -// SCC_AST_TYPE_STRUCT, // 结构体类型 -// SCC_AST_TYPE_UNION, // 联合类型 -// SCC_AST_TYPE_ENUM, // 枚举类型 -// SCC_AST_TYPE_TYPEDEF, // typedef 类型 +static inline void _scc_ast_type_record_init(scc_ast_type_t *type, + scc_ast_node_type_t type_kind, + const char *name, + scc_ast_decl_vec_t *members) { + Assert(type != null && name != null); + type->base.loc = scc_pos_create(); + type->base.type = type_kind; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME + if (members == null) { + scc_vec_init(type->record.fields); + } else { + type->record.fields = *members; + scc_vec_init(*members); + } +} + +// name and members can be null +static inline void scc_ast_type_struct_init(scc_ast_type_t *type, + const char *name, + scc_ast_decl_vec_t *members) { + _scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, members); +} + +// name and members can be null +static inline void scc_ast_type_union_init(scc_ast_type_t *type, + const char *name, + scc_ast_decl_vec_t *members) { + _scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, members); +} + +// name and members can be null +static inline void scc_ast_type_enum_init(scc_ast_type_t *type, + const char *name, + scc_ast_expr_vec_t *members) { + Assert(type != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_ENUM; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME + type->enumeration.name = name; + if (members == null) { + scc_vec_init(type->enumeration.enumerators); + } else { + type->enumeration.enumerators = *members; + scc_vec_init(*members); + } +} + +static inline void scc_ast_type_typedef_init(scc_ast_type_t *type, + const char *name, + scc_ast_type_t *target) { + Assert(type != null && target != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_TYPEDEF; + type->quals = (scc_ast_decl_specifier_t){0}; // FIXME + type->typedef_type.name = name; + type->typedef_type.underlying = target; +} #endif /* __SCC_AST_H__ */ diff --git a/libs/ast/src/ast_builtin.c b/libs/ast/src/ast_builtin.c index e57d343..9003a1b 100644 --- a/libs/ast/src/ast_builtin.c +++ b/libs/ast/src/ast_builtin.c @@ -4,6 +4,32 @@ .base.type = SCC_AST_TYPE_BUILTIN, .base.loc.col = 0, .base.loc.line = 0, \ .base.loc.name = "__scc_ast_builtin_type", .base.loc.offset = 0 +// va_list +scc_ast_type_t scc_ast_builtin_type_va_list = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_VA_LIST, +}; + +scc_ast_type_t scc_ast_builtin_type_void = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_VOID, +}; + +scc_ast_type_t scc_ast_builtin_type_bool = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_BOOL, +}; + +scc_ast_type_t scc_ast_builtin_type_char = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_CHAR, +}; + +scc_ast_type_t scc_ast_builtin_type_short = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SHORT, +}; + scc_ast_type_t scc_ast_builtin_type_int = { SCC_AST_BUILTIN_TYPE_HEADER, .builtin.type = SCC_AST_BUILTIN_TYPE_INT, @@ -19,24 +45,56 @@ scc_ast_type_t scc_ast_builtin_type_long_long = { .builtin.type = SCC_AST_BUILTIN_TYPE_LONG_LONG, }; -scc_ast_type_t scc_ast_builtin_type_short = { +// unsigned 类型 +scc_ast_type_t scc_ast_builtin_type_unsigned_char = { SCC_AST_BUILTIN_TYPE_HEADER, - .builtin.type = SCC_AST_BUILTIN_TYPE_SHORT, + .builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR, }; -scc_ast_type_t scc_ast_builtin_type_char = { +scc_ast_type_t scc_ast_builtin_type_unsigned_short = { SCC_AST_BUILTIN_TYPE_HEADER, - .builtin.type = SCC_AST_BUILTIN_TYPE_CHAR, + .builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT, }; -scc_ast_type_t scc_ast_builtin_type_void = { +scc_ast_type_t scc_ast_builtin_type_unsigned_int = { SCC_AST_BUILTIN_TYPE_HEADER, - .builtin.type = SCC_AST_BUILTIN_TYPE_VOID, + .builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT, }; -scc_ast_type_t scc_ast_builtin_type_bool = { +scc_ast_type_t scc_ast_builtin_type_unsigned_long = { SCC_AST_BUILTIN_TYPE_HEADER, - .builtin.type = SCC_AST_BUILTIN_TYPE_BOOL, + .builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG, +}; + +scc_ast_type_t scc_ast_builtin_type_unsigned_long_long = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG, +}; + +// signed 类型(实际上与默认相同,但为了完整性) +scc_ast_type_t scc_ast_builtin_type_signed_char = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR, +}; + +scc_ast_type_t scc_ast_builtin_type_signed_short = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT, +}; + +scc_ast_type_t scc_ast_builtin_type_signed_int = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_INT, +}; + +scc_ast_type_t scc_ast_builtin_type_signed_long = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG, +}; + +scc_ast_type_t scc_ast_builtin_type_signed_long_long = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG, }; scc_ast_type_t scc_ast_builtin_type_float = { diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index a5a22f4..d580608 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -14,148 +14,100 @@ #define PRINT_QUOTED_VALUE(ctx, str) \ SCC_TREE_DUMP_PRINT_AROUND(ctx, ctx->value_color, "'", "%s", str) -// 获取节点类型的字符串表示 +static const char *node_type_names[] = { + [SCC_AST_UNKNOWN] = "Unknown", + [scc_ast_decl_t_BEGIN] = "ERROR", + [SCC_AST_DECL_VAR] = "VarDecl", + [SCC_AST_DECL_FUNC] = "FuncDecl", + [SCC_AST_DECL_PARAM] = "ParamDecl", + [SCC_AST_DECL_STRUCT] = "StructDecl", + [SCC_AST_DECL_UNION] = "UnionDecl", + [SCC_AST_DECL_ENUM] = "EnumDecl", + [SCC_AST_DECL_TYPEDEF] = "TypedefDecl", + [scc_ast_decl_t_END] = "ERROR", + [scc_ast_stmt_t_BEGIN] = "ERROR", + [SCC_AST_STMT_COMPOUND] = "CompoundStmt", + [SCC_AST_STMT_EXPR] = "ExprStmt", + [SCC_AST_STMT_IF] = "IfStmt", + [SCC_AST_STMT_WHILE] = "WhileStmt", + [SCC_AST_STMT_DO_WHILE] = "DoWhileStmt", + [SCC_AST_STMT_FOR] = "ForStmt", + [SCC_AST_STMT_SWITCH] = "SwitchStmt", + [SCC_AST_STMT_CASE] = "CaseStmt", + [SCC_AST_STMT_DEFAULT] = "DefaultStmt", + [SCC_AST_STMT_BREAK] = "BreakStmt", + [SCC_AST_STMT_CONTINUE] = "ContinueStmt", + [SCC_AST_STMT_RETURN] = "ReturnStmt", + [SCC_AST_STMT_GOTO] = "GotoStmt", + [SCC_AST_STMT_LABEL] = "LabelStmt", + [scc_ast_stmt_t_END] = "ERROR", + [scc_ast_expr_t_BEGIN] = "ERROR", + [SCC_AST_EXPR_BINARY] = "BinaryExpr", + [SCC_AST_EXPR_UNARY] = "UnaryExpr", + [SCC_AST_EXPR_COND] = "ConditionalExpr", + [SCC_AST_EXPR_CALL] = "CallExpr", + [SCC_AST_EXPR_ARRAY_SUBSCRIPT] = "ArraySubscriptExpr", + [SCC_AST_EXPR_MEMBER] = "MemberExpr", + [SCC_AST_EXPR_PTR_MEMBER] = "PtrMemberExpr", + [SCC_AST_EXPR_CAST] = "CastExpr", + [SCC_AST_EXPR_SIZE_OF] = "SizeofExpr", + [SCC_AST_EXPR_ALIGN_OF] = "AlignofExpr", + [SCC_AST_EXPR_COMPOUND_LITERAL] = "CompoundLiteralExpr", + [SCC_AST_EXPR_INT_LITERAL] = "IntLiteralExpr", + [SCC_AST_EXPR_FLOAT_LITERAL] = "FloatLiteralExpr", + [SCC_AST_EXPR_CHAR_LITERAL] = "CharLiteralExpr", + [SCC_AST_EXPR_STRING_LITERAL] = "StringLiteralExpr", + [SCC_AST_EXPR_IDENTIFIER] = "IdentifierExpr", + [scc_ast_expr_t_END] = "ERROR", + [scc_ast_type_t_BEGIN] = "ERROR", + [SCC_AST_TYPE_BUILTIN] = "BuiltinType", + [SCC_AST_TYPE_POINTER] = "PointerType", + [SCC_AST_TYPE_ARRAY] = "ArrayType", + [SCC_AST_TYPE_FUNCTION] = "FunctionType", + [SCC_AST_TYPE_STRUCT] = "StructType", + [SCC_AST_TYPE_UNION] = "UnionType", + [SCC_AST_TYPE_ENUM] = "EnumType", + [SCC_AST_TYPE_TYPEDEF] = "TypedefType", + [scc_ast_type_t_END] = "ERROR", + [scc_ast_translation_unit_t_BEGIN] = "ERROR", + [SCC_AST_TRANSLATION_UNIT] = "TranslationUnit", + [scc_ast_translation_unit_t_END] = "ERROR", +}; + static const char *get_node_type_str(scc_ast_node_type_t type) { - switch (type) { - // 声明类型 - case SCC_AST_DECL_VAR: - return "VarDecl"; - case SCC_AST_DECL_FUNC: - return "FuncDecl"; - case SCC_AST_DECL_PARAM: - return "ParamDecl"; - case SCC_AST_DECL_STRUCT: - return "StructDecl"; - case SCC_AST_DECL_UNION: - return "UnionDecl"; - case SCC_AST_DECL_ENUM: - return "EnumDecl"; - case SCC_AST_DECL_TYPEDEF: - return "TypedefDecl"; - - // 语句类型 - case SCC_AST_STMT_COMPOUND: - return "CompoundStmt"; - case SCC_AST_STMT_EXPR: - return "ExprStmt"; - case SCC_AST_STMT_IF: - return "IfStmt"; - case SCC_AST_STMT_WHILE: - return "WhileStmt"; - case SCC_AST_STMT_DO_WHILE: - return "DoStmt"; - case SCC_AST_STMT_FOR: - return "ForStmt"; - case SCC_AST_STMT_SWITCH: - return "SwitchStmt"; - case SCC_AST_STMT_CASE: - return "CaseStmt"; - case SCC_AST_STMT_DEFAULT: - return "DefaultStmt"; - case SCC_AST_STMT_BREAK: - return "BreakStmt"; - case SCC_AST_STMT_CONTINUE: - return "ContinueStmt"; - case SCC_AST_STMT_RETURN: - return "ReturnStmt"; - case SCC_AST_STMT_GOTO: - return "GotoStmt"; - case SCC_AST_STMT_LABEL: - return "LabelStmt"; - - // 表达式类型 - case SCC_AST_EXPR_BINARY: - return "BinaryOperator"; - case SCC_AST_EXPR_UNARY: - return "UnaryOperator"; - case SCC_AST_EXPR_COND: - return "ConditionalOperator"; - case SCC_AST_EXPR_CALL: - return "CallExpr"; - case SCC_AST_EXPR_ARRAY_SUBSCRIPT: - return "ArraySubscriptExpr"; - case SCC_AST_EXPR_MEMBER: - return "MemberExpr"; - case SCC_AST_EXPR_PTR_MEMBER: - return "PtrMemberExpr"; - case SCC_AST_EXPR_CAST: - return "CastExpr"; - case SCC_AST_EXPR_SIZE_OF: - return "SizeOfExpr"; - case SCC_AST_EXPR_ALIGN_OF: - return "AlignOfExpr"; - case SCC_AST_EXPR_COMPOUND_LITERAL: - return "CompoundLiteralExpr"; - case SCC_AST_EXPR_INT_LITERAL: - return "IntegerLiteral"; - case SCC_AST_EXPR_FLOAT_LITERAL: - return "FloatingLiteral"; - case SCC_AST_EXPR_CHAR_LITERAL: - return "CharacterLiteral"; - case SCC_AST_EXPR_STRING_LITERAL: - return "StringLiteral"; - case SCC_AST_EXPR_IDENTIFIER: - return "DeclRefExpr"; - - // 类型类型 - case SCC_AST_TYPE_BUILTIN: - return "BuiltinType"; - case SCC_AST_TYPE_POINTER: - return "PointerType"; - case SCC_AST_TYPE_ARRAY: - return "ArrayType"; - case SCC_AST_TYPE_FUNCTION: - return "FunctionType"; - case SCC_AST_TYPE_STRUCT: - return "RecordType"; - case SCC_AST_TYPE_UNION: - return "RecordType"; - case SCC_AST_TYPE_ENUM: - return "EnumType"; - case SCC_AST_TYPE_TYPEDEF: - return "TypedefType"; - - // 根节点 - case SCC_AST_TRANSLATION_UNIT: - return "TranslationUnitDecl"; - - default: - return "UnknownNode"; - } + return node_type_names[type]; } -// 获取内置类型名称 +static const char *builtin_type_names[] = { + [SCC_AST_BUILTIN_TYPE_UNKNOWN] = "", + [SCC_AST_BUILTIN_TYPE_VA_LIST] = "...", + [SCC_AST_BUILTIN_TYPE_VOID] = "void", + [SCC_AST_BUILTIN_TYPE_BOOL] = "bool", + [SCC_AST_BUILTIN_TYPE_CHAR] = "char", + [SCC_AST_BUILTIN_TYPE_SHORT] = "short", + [SCC_AST_BUILTIN_TYPE_INT] = "int", + [SCC_AST_BUILTIN_TYPE_LONG] = "long", + [SCC_AST_BUILTIN_TYPE_LONG_LONG] = "long long", + [SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR] = "unsigned char", + [SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT] = "unsigned short", + [SCC_AST_BUILTIN_TYPE_UNSIGNED_INT] = "unsigned int", + [SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG] = "unsigned long", + [SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG] = "unsigned long long", + [SCC_AST_BUILTIN_TYPE_SIGNED_CHAR] = "signed char", + [SCC_AST_BUILTIN_TYPE_SIGNED_SHORT] = "signed short", + [SCC_AST_BUILTIN_TYPE_SIGNED_INT] = "signed int", + [SCC_AST_BUILTIN_TYPE_SIGNED_LONG] = "signed long", + [SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG] = "signed long long", + [SCC_AST_BUILTIN_TYPE_FLOAT] = "float", + [SCC_AST_BUILTIN_TYPE_DOUBLE] = "double", + [SCC_AST_BUILTIN_TYPE_LONG_DOUBLE] = "long double", + [SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT] = "complex float", + [SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE] = "complex double", + [SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE] = "complex long double", +}; + static const char *get_builtin_type_str(scc_ast_builtin_type_t type) { - switch (type) { - case SCC_AST_BUILTIN_TYPE_VOID: - return "void"; - case SCC_AST_BUILTIN_TYPE_CHAR: - return "char"; - case SCC_AST_BUILTIN_TYPE_SHORT: - return "short"; - case SCC_AST_BUILTIN_TYPE_INT: - return "int"; - case SCC_AST_BUILTIN_TYPE_LONG: - return "long"; - case SCC_AST_BUILTIN_TYPE_LONG_LONG: - return "long long"; - case SCC_AST_BUILTIN_TYPE_FLOAT: - return "float"; - case SCC_AST_BUILTIN_TYPE_DOUBLE: - return "double"; - case SCC_AST_BUILTIN_TYPE_LONG_DOUBLE: - return "long double"; - case SCC_AST_BUILTIN_TYPE_BOOL: - return "_Bool"; - case SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT: - return "float _Complex"; - case SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE: - return "double _Complex"; - case SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE: - return "long double _Complex"; - default: - return ""; - } + return builtin_type_names[type]; } // 获取操作符字符串 @@ -286,6 +238,28 @@ static inline void dump_child_node(scc_ast_node_t *child, } \ } while (0) +static inline void dump_quals(scc_ast_decl_specifier_t quals, + scc_tree_dump_ctx_t *ctx) { + if (quals.is_atomic) { + PRINT_QUOTED_VALUE(ctx, "atomic"); + } + if (quals.is_restrict) { + PRINT_QUOTED_VALUE(ctx, "restrict"); + } + if (quals.is_volatile) { + PRINT_QUOTED_VALUE(ctx, "volatile"); + } + if (quals.is_const) { + PRINT_QUOTED_VALUE(ctx, "const"); + } + if (quals.is_inline) { + PRINT_QUOTED_VALUE(ctx, "inline"); + } + if (quals.is_extern) { + PRINT_QUOTED_VALUE(ctx, "extern"); + } +} + // 递归转储类型 static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { if (!type) @@ -293,25 +267,15 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { start_node_dump(&type->base, ctx); + dump_quals(type->quals, ctx); + // 根据类型输出特定信息 switch (type->base.type) { case SCC_AST_TYPE_BUILTIN: PRINT_QUOTED_VALUE(ctx, get_builtin_type_str(type->builtin.type)); break; case SCC_AST_TYPE_POINTER: - if (type->pointer.pointee && - type->pointer.pointee->base.type == SCC_AST_TYPE_BUILTIN) { - const char *base_type = - get_builtin_type_str(type->pointer.pointee->builtin.type); - if (ctx->use_color) { - scc_tree_dump_printf(ctx, "%s'%s *'%s", ctx->value_color, - base_type, ctx->reset_color); - } else { - scc_tree_dump_printf(ctx, "'%s *'", base_type); - } - } else { - PRINT_QUOTED_VALUE(ctx, "pointer"); - } + PRINT_QUOTED_VALUE(ctx, "pointer"); break; case SCC_AST_TYPE_ARRAY: PRINT_QUOTED_VALUE(ctx, "array"); @@ -331,10 +295,6 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { } dump_type_impl(param->param.type, ctx); } - } else { - start_node_dump(&type->base, ctx); - PRINT_QUOTED_VALUE(ctx, "void"); - // TODO? } break; case SCC_AST_TYPE_STRUCT: @@ -620,7 +580,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { case SCC_AST_DECL_FUNC: if (decl->func.type) { dump_child_node((scc_ast_node_t *)decl->func.type, ctx, - decl->func.body == NULL); + decl->func.body == null); if (decl->func.body) { dump_child_node((scc_ast_node_t *)decl->func.body, ctx, true); } diff --git a/libs/parser/include/parser_utils.h b/libs/parser/include/parser_utils.h index 6ea8486..9ad92ee 100644 --- a/libs/parser/include/parser_utils.h +++ b/libs/parser/include/parser_utils.h @@ -48,6 +48,7 @@ static inline void scc_parser_restore(scc_parser_t *parser) { _scc_ring_probe(*parser->ring) = parser->checkpoint; } +// tok can null it will be safty free static inline cbool scc_parser_next_consume(scc_parser_t *parser, scc_lexer_tok_t *tok) { cbool ok = false; diff --git a/libs/parser/include/scc_parser.h b/libs/parser/include/scc_parser.h index 28b37e3..ef101f4 100644 --- a/libs/parser/include/scc_parser.h +++ b/libs/parser/include/scc_parser.h @@ -66,10 +66,8 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser); * @param parser 解析器实例 * @return 类型 AST 节点 */ -scc_ast_type_t *scc_parse_type(scc_parser_t *parser); +scc_ast_node_t *_scc_parse_type(scc_parser_t *parser); -static inline scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { - return null; // TODO -} +scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser); #endif /* __SCC_PARSER_H__ */ diff --git a/libs/parser/src/parse_decl.c b/libs/parser/src/parse_decl.c index e28b54c..dfeeaf3 100644 --- a/libs/parser/src/parse_decl.c +++ b/libs/parser/src/parse_decl.c @@ -57,7 +57,7 @@ A.2.2 Declarations declarator(opt) : constant-expression (6.7.2.2) enum-specifier: enum identifier(opt) { enumerator-list } - enum identifier(opt) { enumerator-list ,} + enum identifier(opt) { enumerator-list , } enum identifier (6.7.2.2) enumerator-list: enumerator @@ -82,7 +82,7 @@ A.2.2 Declarations assignment-expression ] direct-declarator [ type-qualifier-list static assignment-expression ] - direct-declarator [ type-qualifier-list(opt) *] + direct-declarator [ type-qualifier-list(opt) * ] direct-declarator ( parameter-type-list ) direct-declarator ( identifier-list(opt) ) (6.7.5) pointer: @@ -112,9 +112,9 @@ A.2.2 Declarations ( abstract-declarator ) direct-abstract-declarator(opt) [ type-qualifier-list (opt) assignment-expression(opt) ] - direct-abstract-declarator(opt) [static type-qualifier-list(opt) + direct-abstract-declarator(opt) [ static type-qualifier-list(opt) assignment-expression ] - direct-abstract-declaratoropt [ type-qualifier-list static + direct-abstract-declarator(opt) [ type-qualifier-list static assignment-expression ] direct-abstract-declarator(opt) [ * ] direct-abstract-declarator(opt) ( parameter-type-list(opt) ) @@ -177,81 +177,46 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { cbool ok; scc_lexer_tok_t tok; - scc_ast_type_t *type = scc_parse_type(parser); - if (type == null) { + scc_ast_node_t *type_or_decl = _scc_parse_type(parser); + scc_ast_decl_t *decl = null; + if (type_or_decl == null) { return null; } - ok = scc_parser_next_consume(parser, &tok); - if (ok == false) { + if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) { + LOG_WARN("declaration dose not declare anything"); return null; - } - - scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t)); - /* - (6.7.5) declarator: - pointeropt direct-declarator - (6.7.5) direct-declarator: - identifier - ( declarator ) - direct-declarator [ type-qualifier-listopt assignment-expressionopt ] - direct-declarator [static type-qualifier-listopt assignment-expression ] - direct-declarator [ type-qualifier-list static assignment-expression ] - direct-declarator [ type-qualifier-listopt *] - direct-declarator ( parameter-type-list ) - direct-declarator ( identifier-listopt ) - */ - if (!scc_parser_consume_if(parser, SCC_TOK_L_PAREN)) { - if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { - scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme), - null); - goto RETURN; - } else if (scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { - scc_ast_expr_t *init = scc_parse_expression(parser); - scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme), - init); - if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { - LOG_ERROR("expect semicolon"); - } - goto RETURN; - } - // TODO - return null; - } - - // function decl - decl->base.type = SCC_AST_DECL_FUNC; - decl->name = scc_cstring_as_cstr(&tok.lexeme); - decl->func.type = scc_malloc(sizeof(scc_ast_type_t)); - decl->func.type->base.type = SCC_AST_TYPE_FUNCTION; - scc_vec_init(decl->func.type->function.param_types); - decl->func.type->function.return_type = type; - - // TODO param type - scc_parser_consume_if(parser, SCC_TOK_VOID); - - if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { + } else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) { + decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl); + } else { + LOG_ERROR("invalid declaration"); return null; } const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); - if (tok_ptr == null) { - return null; - } - if (tok_ptr->type != SCC_TOK_L_BRACE) { - if (tok_ptr->type == SCC_TOK_SEMICOLON) { - decl->func.body = null; - } else { - return null; + if (tok_ptr->type == SCC_TOK_SEMICOLON) { + scc_parser_next_consume(parser, null); + goto RETURN; + } else if (tok_ptr->type == SCC_TOK_ASSIGN) { + scc_parser_next_consume(parser, null); + scc_ast_expr_t *init = scc_parse_expression(parser); + decl->var.init = init; + if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { + LOG_ERROR("expect semicolon"); } + goto RETURN; + } else if (tok_ptr->type == SCC_TOK_L_BRACE) { + scc_ast_stmt_t *body = scc_parse_statement(parser); + Assert(decl->base.type == SCC_AST_DECL_FUNC); + decl->func.body = body; + Assert(decl->func.type != null); + Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION); + Assert(decl->func.body != null); + Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); + } else { + UNREACHABLE(); } - decl->func.body = scc_parse_statement(parser); - Assert(decl->func.type != null); - Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION); - Assert(decl->func.body != null); - Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); - RETURN: if (decl) { parser->sema_callbacks.on_decl(parser->sema_callbacks.context, diff --git a/libs/parser/src/parse_expr.c b/libs/parser/src/parse_expr.c index 9e6f814..a709813 100644 --- a/libs/parser/src/parse_expr.c +++ b/libs/parser/src/parse_expr.c @@ -897,8 +897,6 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) { case SCC_TOK_L_PAREN: return parse_paren_expression(parser); default: - LOG_ERROR("Unexpected token in primary expression: %s", - scc_get_tok_name(tok->type)); parser_sync(parser); return null; } diff --git a/libs/parser/src/parse_type.c b/libs/parser/src/parse_type.c index fa60ee3..4d65a08 100644 --- a/libs/parser/src/parse_type.c +++ b/libs/parser/src/parse_type.c @@ -46,7 +46,7 @@ EXAMPLE The constructions typedef-name (6.7.2.1) struct-or-union-specifier: - struct-or-union identifieropt { struct-declaration-list } + struct-or-union identifier(opt) { struct-declaration-list } struct-or-union identifier (6.7.2.1) struct-or-union: @@ -73,8 +73,8 @@ EXAMPLE The constructions declarator(opt) : constant-expression (6.7.2.2) enum-specifier: - enum identifieropt { enumerator-list } - enum identifieropt { enumerator-list ,} + enum identifier(opt) { enumerator-list } + enum identifier(opt) { enumerator-list , } enum identifier (6.7.2.2) enumerator-list: @@ -89,35 +89,85 @@ EXAMPLE The constructions const restrict volatile -(6.7.5) - pointer: - * type-qualifier-list(opt) - * type-qualifier-list(opt) pointer -(6.7.5) - type-qualifier-list: - type-qualifier - type-qualifier-list type-qualifier -(6.7.5) - parameter-type-list: - parameter-list - parameter-list , ... -(6.7.5) - parameter-list: - parameter-declaration - parameter-list , parameter-declaration -(6.7.5) - parameter-declaration: - declaration-specifiers declarator - declaration-specifiers abstract-declaratoropt -(6.7.5) - identifier-list: - identifier - identifier-list , identifier + +(6.7.5) declarator: + pointer(opt) direct-declarator +(6.7.5) direct-declarator: + identifier + ( declarator ) + direct-declarator [ type-qualifier-list(opt) + assignment-expression(opt) ] + direct-declarator [ static type-qualifier-list(opt) + assignment-expression ] + direct-declarator [ type-qualifier-list static + assignment-expression ] + direct-declarator [ type-qualifier-list(opt) * ] + direct-declarator ( parameter-type-list ) + direct-declarator ( identifier-list(opt) ) +(6.7.5) pointer: + * type-qualifier-list(opt) + * type-qualifier-list(opt) pointer +(6.7.5) type-qualifier-list: + type-qualifier + type-qualifier-list type-qualifier +(6.7.5) parameter-type-list: + parameter-list + parameter-list , ... +(6.7.5) parameter-list: + parameter-declaration + parameter-list , parameter-declaration +(6.7.5) parameter-declaration: + declaration-specifiers declarator + declaration-specifiers abstract-declarator(opt) +(6.7.5) identifier-list: + identifier + identifier-list , identifier +(6.7.6) type-name: + specifier-qualifier-list abstract-declarator(opt) +(6.7.6) abstract-declarator: + pointer + pointer(opt) direct-abstract-declarator +(6.7.6) direct-abstract-declarator: + ( abstract-declarator ) + direct-abstract-declarator(opt) [ type-qualifier-list (opt) + assignment-expression(opt) ] + direct-abstract-declarator(opt) [ static type-qualifier-list(opt) + assignment-expression ] + direct-abstract-declarator(opt) [ type-qualifier-list static + assignment-expression ] + direct-abstract-declarator(opt) [ * ] + direct-abstract-declarator(opt) ( parameter-type-list(opt) ) +(6.7.7) typedef-name: + identifier +(6.7.8) initializer: + assignment-expression + { initializer-list } + { initializer-list , } +(6.7.8) initializer-list: + designation(opt) initializer + initializer-list , designation(opt) initializer +(6.7.8) designation: + designator-list = +(6.7.8) designator-list: + designator + designator-list designator +(6.7.8) designator: + [ constant-expression ] + . identifier */ #include #include +static inline scc_ast_type_t *ast_type_alloc() { + scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t)); + ast_type->base.type = SCC_AST_UNKNOWN; + if (ast_type == null) { + LOG_FATAL("Out of memory"); + } + return ast_type; +} + /** * @brief 判断 token 是否为声明说明符的开始 * @@ -128,9 +178,11 @@ EXAMPLE The constructions * - 函数说明符 (inline) */ cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) { - const scc_lexer_tok_t *tok = scc_parser_peek(parser); - - switch (tok->type) { + const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return false; + } + switch (tok_ptr->type) { // 存储类说明符 case SCC_TOK_TYPEDEF: case SCC_TOK_EXTERN: @@ -175,10 +227,11 @@ cbool scc_parse_is_decl_specifier_start(scc_parser_t *parser) { } cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) { - const scc_lexer_tok_t *tok = scc_parser_peek(parser); - - switch (tok->type) { - // 基本类型说明符 + const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return false; + } + switch (tok_ptr->type) { case SCC_TOK_VOID: case SCC_TOK_CHAR: case SCC_TOK_SHORT: @@ -190,26 +243,25 @@ cbool scc_parse_is_type_specifier_start(scc_parser_t *parser) { case SCC_TOK_UNSIGNED: case SCC_TOK_BOOL: case SCC_TOK_COMPLEX: - // 复合类型说明符 case SCC_TOK_STRUCT: case SCC_TOK_UNION: case SCC_TOK_ENUM: return true; - // typedef 名称 case SCC_TOK_IDENT: // 需要检查标识符是否在符号表中定义为 typedef return true; - default: return false; } } cbool scc_parse_is_type_qualifier_start(scc_parser_t *parser) { - const scc_lexer_tok_t *tok = scc_parser_peek(parser); - - switch (tok->type) { + const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return false; + } + switch (tok_ptr->type) { case SCC_TOK_CONST: case SCC_TOK_VOLATILE: case SCC_TOK_RESTRICT: @@ -221,9 +273,11 @@ cbool scc_parse_is_type_qualifier_start(scc_parser_t *parser) { } cbool scc_parse_is_storage_class_start(scc_parser_t *parser) { - const scc_lexer_tok_t *tok = scc_parser_peek(parser); - - switch (tok->type) { + const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return false; + } + switch (tok_ptr->type) { case SCC_TOK_TYPEDEF: case SCC_TOK_EXTERN: case SCC_TOK_STATIC: @@ -235,825 +289,632 @@ cbool scc_parse_is_storage_class_start(scc_parser_t *parser) { } } -scc_ast_type_t *scc_parse_type(scc_parser_t *parser) { - if (!scc_parse_is_decl_specifier_start(parser)) { +static scc_ast_decl_specifier_t +parse_type_qualifier_list(scc_parser_t *parser) { + /* + (6.7.3) + type-qualifier: + const + restrict + volatile + (6.7.5) + type-qualifier-list: + type-qualifier + type-qualifier-list type-qualifier + */ + scc_ast_decl_specifier_t quals = {0}; + const scc_lexer_tok_t *tok_ptr = null; +CONTINUE: + tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return quals; + } + switch (tok_ptr->type) { + case SCC_TOK_CONST: + scc_parser_next_consume(parser, null); + quals.is_const = true; + break; + case SCC_TOK_RESTRICT: + scc_parser_next_consume(parser, null); + quals.is_restrict = true; + break; + case SCC_TOK_VOLATILE: + scc_parser_next_consume(parser, null); + quals.is_volatile = true; + break; + default: + return quals; + } + goto CONTINUE; +} + +typedef struct { + cbool is_void; + cbool is_char; + cbool is_short; + cbool is_int; + cbool is_long; + cbool is_long_long; + cbool is_float; + cbool is_double; + cbool is_bool; + cbool is_complex; + cbool is_signed; // 显式 signed + cbool is_unsigned; // 显式 unsigned + + // 以下用于 struct/union/enum/typedef-name + scc_ast_type_t *user_type; // 如果是用户定义类型,直接存储解析结果 +} type_spec_info_t; + +static cbool check_type_combinations(type_spec_info_t *info) { + // 基本类型不能同时出现多个(void, char, int, float, double, bool 互斥) + int basic_count = info->is_void + info->is_char + info->is_short + + info->is_int + info->is_float + info->is_double + + info->is_bool; + if (basic_count > 1) { + LOG_ERROR("Multiple basic type specifiers"); + return false; + } + + // long 不能与 void/char/float/bool 组合(但可以和 double 组合为 long + // double) + if (info->is_long && info->is_float) { + LOG_ERROR("'long' and 'float' cannot be combined"); + return false; + } + if (info->is_long && info->is_char) { + LOG_ERROR("'long' and 'char' cannot be combined"); + return false; + } + if (info->is_long && info->is_bool) { + LOG_ERROR("'long' and 'bool' cannot be combined"); + return false; + } + // long 与 double 可以组合为 long double + if (info->is_long_long && info->is_double) { + LOG_ERROR("'long long' and 'double' cannot be combined"); + return false; + } + // short 只能与 int 组合(默认 int),不能与 double/float 等 + if (info->is_short && + (info->is_double || info->is_float || info->is_bool || info->is_void)) { + LOG_ERROR("'short' cannot be combined with this type"); + return false; + } + // _Complex 只能与 float/double/long double 组合(或单独出现?C99 中 + // _Complex 本身不是类型,必须跟浮点类型) + if (info->is_complex && !info->is_float && !info->is_double) { + LOG_ERROR("'complex' must be combined with a floating type"); + return false; + } + // 如果用户定义了类型(struct/typedef),不能与任何其他类型说明符混合 + if (info->user_type != null && basic_count > 0) { + LOG_ERROR( + "Cannot combine user-defined type with basic type specifiers"); + return false; + } + return true; +} +static scc_ast_type_t *build_type_from_info(type_spec_info_t *info) { + // 如果有用户定义类型,直接返回(注意可能需要复制或共享) + if (info->user_type) { + return info->user_type; // 假设 parse_struct_union_enum 已分配好节点 + } + + // 确定基础类型 + scc_ast_builtin_type_t builtin; + + if (info->is_void) { + builtin = SCC_AST_BUILTIN_TYPE_VOID; + } else if (info->is_bool) { + builtin = SCC_AST_BUILTIN_TYPE_BOOL; + } else if (info->is_float) { + builtin = SCC_AST_BUILTIN_TYPE_FLOAT; + if (info->is_complex) + builtin = SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT; + } else if (info->is_double) { + if (info->is_long) { + builtin = SCC_AST_BUILTIN_TYPE_LONG_DOUBLE; + } else { + builtin = SCC_AST_BUILTIN_TYPE_DOUBLE; + } + if (info->is_complex) { + // 需要根据实际情况映射到 COMPLEX_DOUBLE 或 COMPLEX_LONG_DOUBLE + builtin = info->is_long ? SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE + : SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE; + } + } else { + // 整数类型 + // 如果没有指定任何整数基本类型,默认为 int + if (!info->is_char && !info->is_short && !info->is_int && + !info->is_long && !info->is_long_long) { + info->is_int = true; + } + + if (info->is_char) { + if (info->is_unsigned) + builtin = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR; + else if (!info->is_signed) + builtin = SCC_AST_BUILTIN_TYPE_CHAR; // plain char (可能区别于 + // signed char) + else + builtin = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR; + } else if (info->is_short) { + builtin = info->is_unsigned ? SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT + : SCC_AST_BUILTIN_TYPE_SHORT; + } else if (info->is_long_long) { + builtin = info->is_unsigned + ? SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG + : SCC_AST_BUILTIN_TYPE_LONG_LONG; + } else if (info->is_long) { + builtin = info->is_unsigned ? SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG + : SCC_AST_BUILTIN_TYPE_LONG; + } else { // int + builtin = info->is_unsigned ? SCC_AST_BUILTIN_TYPE_UNSIGNED_INT + : SCC_AST_BUILTIN_TYPE_INT; + } + } + + scc_ast_type_t *type = ast_type_alloc(); + _scc_ast_type_builtin_init(type, builtin); + // 注意:限定符(const, volatile)不应在此处处理,应由上层函数负责 + return type; +} +static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser) { + type_spec_info_t info = {0}; + if (!scc_parse_is_type_specifier_start(parser)) + return null; + while (1) { + const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + break; + } + switch (tok_ptr->type) { + case SCC_TOK_VOID: + if (info.is_void) + goto duplicate_error; + info.is_void = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_CHAR: + if (info.is_char) + goto duplicate_error; + info.is_char = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_SHORT: + if (info.is_short) + goto duplicate_error; + info.is_short = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_INT: + if (info.is_int) + goto duplicate_error; + info.is_int = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_LONG: + // long 可以出现两次 + if (info.is_long_long) { + LOG_ERROR("Three 'long's in type specifier"); + return null; + } + if (info.is_long) { + info.is_long_long = true; + info.is_long = false; // 升级为 long long + } else { + info.is_long = true; + } + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_FLOAT: + if (info.is_float) + goto duplicate_error; + info.is_float = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_DOUBLE: + if (info.is_double) + goto duplicate_error; + info.is_double = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_BOOL: + if (info.is_bool) + goto duplicate_error; + info.is_bool = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_SIGNED: + if (info.is_unsigned || info.is_signed) { + LOG_ERROR("Both 'signed' and 'unsigned' in type specifier"); + return null; + } + info.is_signed = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_UNSIGNED: + if (info.is_unsigned || info.is_signed) { + LOG_ERROR("Both 'signed' and 'unsigned' in type specifier"); + return null; + } + info.is_unsigned = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_COMPLEX: + if (info.is_complex) + goto duplicate_error; + info.is_complex = true; + scc_parser_next_consume(parser, null); + break; + case SCC_TOK_STRUCT: + case SCC_TOK_UNION: + case SCC_TOK_ENUM: + // // 解析 struct/union/enum 说明符(需单独实现) + // info.user_type = parse_struct_union_enum(parser, tok->type); + // if (!info.user_type) + // return null; + // // 这些类型说明符后不能再跟其他类型说明符,因此直接跳出循环 + TODO(); + goto done; + case SCC_TOK_IDENT: + // // 处理 typedef 名称:查符号表获取类型节点 + // info.user_type = parse_typedef_name(parser); + // if (!info.user_type) + // return null; + goto done; + default: + goto done; + } + } +done: + if (!check_type_combinations(&info)) { return null; } + return build_type_from_info(&info); +duplicate_error: + LOG_ERROR("Duplicate type specifier"); + return null; +} + +static scc_ast_node_t *parse_declarator(scc_parser_t *parser, + scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr); +static scc_ast_node_t * +parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr); +static scc_ast_type_t * +parse_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr); +static scc_ast_type_t * +parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr); + +static scc_ast_type_t *parse_pointer(scc_parser_t *parser, + scc_ast_type_t *pointee, + scc_ast_type_t **delay_pointee_ptr) { + /* + pointer: + * type-qualifier-list(opt) + * type-qualifier-list(opt) pointer + */ const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); - scc_ast_type_t *ret = null; - if (tok_ptr->type == SCC_TOK_INT) { - scc_lexer_tok_t tok; - scc_parser_next_consume(parser, &tok); - ret = scc_malloc(sizeof(scc_ast_type_t)); - if (ret == null) { - LOG_FATAL("memory alloc failed"); - return ret; - } - ret->base.type = SCC_AST_TYPE_BUILTIN; - ret->base.loc = tok_ptr->loc; - ret->builtin.type = SCC_AST_BUILTIN_TYPE_INT; - scc_lexer_tok_drop(&tok); + if (tok_ptr == null || tok_ptr->type != SCC_TOK_MUL) { + return pointee; } + scc_parser_next_consume(parser, null); + + scc_ast_type_t *pointer = ast_type_alloc(); + if (pointee == null) { + Assert(delay_pointee_ptr != null); + *delay_pointee_ptr = pointer; + pointee = pointer; + } + scc_ast_type_pointer_init(pointer, pointee); + pointer->quals = parse_type_qualifier_list(parser); + + return parse_pointer(parser, pointer, delay_pointee_ptr); +} + +static void parse_parameter_type_list(scc_parser_t *parser, + scc_ast_decl_vec_t *params) { + /* + (6.7.5) parameter-type-list: + parameter-list + parameter-list , ... + (6.7.5) parameter-list: + parameter-declaration + parameter-list , parameter-declaration + (6.7.5) parameter-declaration: + declaration-specifiers declarator + declaration-specifiers abstract-declarator(opt) + */ + scc_ast_decl_t *param = null; + while (1) { + // FIXME + scc_ast_decl_specifier_t spec = parse_type_qualifier_list(parser); + scc_ast_type_t *type = parse_type_specifier(parser); + if (type == null) { + break; + } + type->quals = spec; + + scc_ast_node_t *node = parse_declarator(parser, type, null); + + if (SCC_AST_IS_A(scc_ast_decl_t, node)) { + param = SCC_AST_CAST_TO(scc_ast_decl_t, node); + // TODO Check validation + param->base.type = SCC_AST_DECL_PARAM; + } else if (SCC_AST_IS_A(scc_ast_type_t, node)) { + param = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(param != null); + scc_ast_decl_param_init( + param, SCC_AST_CAST_TO(scc_ast_type_t, node), null); + } + + scc_vec_push(*params, param); + if (!scc_parser_consume_if(parser, SCC_TOK_COMMA)) { + break; + } + if (scc_parser_consume_if(parser, SCC_TOK_ELLIPSIS)) { + param = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(param != null); + // FIXME + scc_ast_decl_param_init(param, &scc_ast_builtin_type_va_list, null); + scc_vec_push(*params, param); + break; + } + } +} + +static void parse_function_parameters(scc_parser_t *parser, + scc_ast_decl_vec_t *params) { + // FIXME ? + // if (!scc_parser_consume_if(parser, SCC_TOK_L_PAREN)) { + // LOG_ERROR("Expect '('"); + // } + scc_vec_init(*params); + parse_parameter_type_list(parser, params); + if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { + LOG_ERROR("expect ')'"); + } +} + +static scc_ast_expr_t *parse_array_size_type(scc_parser_t *parser) { + const scc_lexer_tok_t *tok_ptr = null; + if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACKET)) { + LOG_ERROR("Expect '['"); + parser->errcode = 1; + return null; + } + + scc_ast_expr_t *size = null; + if (scc_parse_is_type_qualifier_start(parser)) { + // static assignment-expression + // assignment-expression(opt) + if (scc_parser_consume_if(parser, SCC_TOK_STATIC)) { + // TODO + } + tok_ptr = scc_parser_peek(parser); + if (tok_ptr != null && tok_ptr->type != SCC_TOK_R_BRACKET) { + size = scc_parse_expression(parser); + } + } else if (scc_parser_consume_if(parser, SCC_TOK_MUL)) { + // [ * ] + } else if (scc_parser_consume_if(parser, SCC_TOK_STATIC)) { + // type-qualifier-list(opt) assignment-expression + parse_type_qualifier_list(parser); + size = scc_parse_expression(parser); + } else { + // assignment-expression(opt) + tok_ptr = scc_parser_peek(parser); + if (tok_ptr != null && tok_ptr->type != SCC_TOK_R_BRACKET) { + size = scc_parse_expression(parser); + } + } + if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) { + LOG_ERROR("expect ']'"); + parser->errcode = 1; + return null; + } + return size; +} + +static scc_ast_node_t *parse_declarator(scc_parser_t *parser, + scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr) { + /* + (6.7.5) declarator: + pointer(opt) direct-declarator + (6.7.5) direct-declarator: + identifier + ( declarator ) + direct-declarator [ type-qualifier-list(opt) + assignment-expression(opt) ] + direct-declarator [ static type-qualifier-list(opt) + assignment-expression ] + direct-declarator [ type-qualifier-list static + assignment-expression ] + direct-declarator [ type-qualifier-list(opt) * ] + direct-declarator ( parameter-type-list ) + direct-declarator ( identifier-list(opt) ) + */ + scc_ast_type_t *ret = parse_pointer(parser, base, delay_pointee_ptr); + return parse_direct_declarator(parser, ret, delay_pointee_ptr); +} + +static scc_ast_node_t * +parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr) { + const scc_lexer_tok_t *tok_ptr = null; + scc_ast_type_t *ret = null; + // direct-abstract-declarator + tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return (scc_ast_node_t *)base; + } + + if (tok_ptr->type == SCC_TOK_IDENT) { + scc_lexer_tok_t tok = {0}; + scc_parser_next_consume(parser, &tok); + + scc_ast_node_t *type = + parse_direct_declarator(parser, base, delay_pointee_ptr); + Assert(SCC_AST_IS_A(scc_ast_type_t, type)); + scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(decl != null); + + if (type->type == SCC_AST_TYPE_FUNCTION) { + scc_ast_decl_func_init(decl, SCC_AST_CAST_TO(scc_ast_type_t, type), + scc_cstring_as_cstr(&tok.lexeme), null); + } else { + scc_ast_decl_val_init(decl, SCC_AST_CAST_TO(scc_ast_type_t, type), + scc_cstring_as_cstr(&tok.lexeme), null); + } + return (scc_ast_node_t *)decl; + } else if (tok_ptr->type == SCC_TOK_L_PAREN) { + // () SCC_TOK_L_PAREN + scc_parser_next_consume(parser, null); + scc_ast_type_t *delay_pointee = null; + ret = parse_abstract_declarator(parser, null, &delay_pointee); + if (ret == null) { + scc_ast_decl_vec_t params; + parse_function_parameters(parser, ¶ms); + ret = ast_type_alloc(); + scc_ast_type_function_init(ret, base, ¶ms); + return (scc_ast_node_t *)parse_direct_declarator(parser, ret, + delay_pointee_ptr); + } else { + if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { + LOG_ERROR("expect ')'"); + } + base = (scc_ast_type_t *)parse_direct_declarator(parser, base, + delay_pointee_ptr); + Assert(SCC_AST_IS_A(scc_ast_type_t, base)); + Assert(delay_pointee != null); + delay_pointee->pointer.pointee = base; + } + return (scc_ast_node_t *)ret; + } else if (tok_ptr->type == SCC_TOK_L_BRACKET) { + // [] SCC_TOK_L_BRACKET + scc_ast_expr_t *size = parse_array_size_type(parser); + scc_ast_type_t *ret = ast_type_alloc(); + base = (scc_ast_type_t *)parse_direct_declarator(parser, base, + delay_pointee_ptr); + Assert(SCC_AST_IS_A(scc_ast_type_t, base)); + scc_ast_type_array_init(ret, base, size); + return (scc_ast_node_t *)ret; + } else { + return (scc_ast_node_t *)base; + } +} + +static scc_ast_type_t * +parse_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr) { + /* + (6.7.6) abstract-declarator: + pointer + pointer(opt) direct-abstract-declarator + (6.7.6) direct-abstract-declarator: + ( abstract-declarator ) + direct-abstract-declarator(opt) [ type-qualifier-list (opt) + assignment-expression(opt) ] + direct-abstract-declarator(opt) [ static type-qualifier-list(opt) + assignment-expression ] + direct-abstract-declarator(opt) [ type-qualifier-list static + assignment-expression ] + direct-abstract-declarator(opt) [ * ] + direct-abstract-declarator(opt) ( parameter-type-list(opt) ) + */ + scc_ast_type_t *ret = parse_pointer(parser, base, delay_pointee_ptr); + ret = parse_direct_abstract_declarator(parser, ret, delay_pointee_ptr); return ret; } -// // 前向声明辅助函数 -// static scc_ast_type_t *parse_specifier_qualifier_list(scc_parser_t *parser, -// usize *offset); -// static scc_ast_type_t *parse_abstract_declarator(scc_parser_t *parser, -// usize *offset, -// scc_ast_type_t *base_type); -// static scc_ast_type_t * -// parse_direct_abstract_declarator(scc_parser_t *parser, usize *offset, -// scc_ast_type_t *base_type); -// static scc_ast_type_t *parse_pointer(scc_parser_t *parser, usize *offset); -// static scc_ast_decl_specifier_t parse_type_qualifier_list(scc_parser_t -// *parser, -// usize *offset); -// static scc_ast_type_t *parse_struct_or_union_specifier(scc_parser_t *parser, -// usize *offset); -// static scc_ast_type_t *parse_enum_specifier(scc_parser_t *parser, -// usize *offset); - -// // 创建内置类型节点的辅助函数 -// static scc_ast_type_t *create_builtin_type(scc_ast_builtin_type_t builtin, -// scc_ast_decl_specifier_t quals) { -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_BUILTIN; -// type->builtin.type = builtin; -// type->builtin.quals = quals; -// return type; -// } - -// // 创建指针类型节点的辅助函数 -// static scc_ast_type_t *create_pointer_type(scc_ast_type_t *pointee, -// scc_ast_decl_specifier_t quals) { -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_POINTER; -// type->pointer.pointee = pointee; -// type->pointer.quals = quals; -// return type; -// } - -// // 创建数组类型节点的辅助函数 -// static scc_ast_type_t *create_array_type(scc_ast_type_t *element, -// scc_ast_expr_t *size) { -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_ARRAY; -// type->array.element = element; -// type->array.size = size; -// return type; -// } - -// // 创建函数类型节点的辅助函数 -// static scc_ast_type_t *create_function_type(scc_ast_type_t *return_type, -// scc_ast_type_vec_t param_types, -// cbool is_variadic) { -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_FUNCTION; -// type->function.return_type = return_type; -// type->function.param_types = param_types; -// type->function.is_variadic = is_variadic; -// return type; -// } - -// /** -// * @brief 解析类型名 -// */ -// scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser, usize *offset) { -// usize start_offset = *offset; - -// // 解析 specifier-qualifier-list -// scc_ast_type_t *type = parse_specifier_qualifier_list(parser, offset); -// if (type == null) { -// // TODO -// // LOG_ERROR("Failed to parse specifier-qualifier-list at offset -// %zu", -// // start_offset); -// return null; -// } - -// // 解析可选的 abstract-declarator -// scc_ast_type_t *full_type = parse_abstract_declarator(parser, offset, -// type); if (full_type == null) { -// return type; -// } - -// return full_type; -// } - -// scc_ast_type_t *scc_parse_type(scc_parser_t *parser) { -// usize offset = 0; -// scc_ast_type_t *ret = scc_parse_type_name(parser, &offset); -// if (ret == null) { -// return null; -// } -// scc_lexer_stream_advance(parser->lex_stream, offset); -// return ret; -// } - -// /** -// * @brief 检查是否为类型限定符 token -// */ -// static cbool is_type_qualifier_token(const scc_lexer_tok_t *tok) { -// return tok->type == SCC_TOK_CONST || tok->type == SCC_TOK_RESTRICT || -// tok->type == SCC_TOK_VOLATILE || tok->type == SCC_TOK_ATOMIC; -// } - -// /** -// * @brief 解析类型限定符 -// */ -// static scc_ast_decl_specifier_t parse_type_qualifier(scc_parser_t *parser, -// usize *offset) { -// scc_ast_decl_specifier_t quals = {0}; -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// switch (tok->type) { -// case SCC_TOK_CONST: -// quals.is_const = true; -// (*offset)++; -// break; -// case SCC_TOK_RESTRICT: -// quals.is_restrict = true; -// (*offset)++; -// break; -// case SCC_TOK_VOLATILE: -// quals.is_volatile = true; -// (*offset)++; -// break; -// case SCC_TOK_ATOMIC: -// quals.is_atomic = true; -// (*offset)++; -// break; -// default: -// // 不是限定符 -// break; -// } - -// return quals; -// } - -// /** -// * @brief 解析类型限定符列表 -// */ -// static scc_ast_decl_specifier_t parse_type_qualifier_list(scc_parser_t -// *parser, -// usize *offset) { -// scc_ast_decl_specifier_t quals = {0}; - -// while (true) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// if (!is_type_qualifier_token(tok)) { -// break; -// } - -// scc_ast_decl_specifier_t new_qual = -// parse_type_qualifier(parser, offset); - -// // 合并限定符 -// quals.is_const = quals.is_const || new_qual.is_const; -// quals.is_restrict = quals.is_restrict || new_qual.is_restrict; -// quals.is_volatile = quals.is_volatile || new_qual.is_volatile; -// quals.is_atomic = quals.is_atomic || new_qual.is_atomic; -// } - -// return quals; -// } - -// /** -// * @brief 检查是否为类型说明符 token -// */ -// static cbool is_type_specifier_token(const scc_lexer_tok_t *tok) { -// switch (tok->type) { -// case SCC_TOK_VOID: -// case SCC_TOK_CHAR: -// case SCC_TOK_SHORT: -// case SCC_TOK_INT: -// case SCC_TOK_LONG: -// case SCC_TOK_FLOAT: -// case SCC_TOK_DOUBLE: -// case SCC_TOK_SIGNED: -// case SCC_TOK_UNSIGNED: -// case SCC_TOK_BOOL: -// case SCC_TOK_COMPLEX: -// case SCC_TOK_STRUCT: -// case SCC_TOK_UNION: -// case SCC_TOK_ENUM: -// return true; -// default: -// // 可能是 typedef 名称 -// return tok->type == SCC_TOK_IDENT; -// } -// } - -// /** -// * @brief 解析类型说明符 -// */ -// static scc_ast_type_t *parse_type_specifier(scc_parser_t *parser, -// usize *offset) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// // 处理简单内置类型 -// if (tok->type == SCC_TOK_VOID) { -// (*offset)++; -// return create_builtin_type(TYPE_VOID, (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_CHAR) { -// (*offset)++; -// return create_builtin_type(TYPE_CHAR, (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_SHORT) { -// (*offset)++; -// return create_builtin_type(TYPE_SHORT, -// (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_INT) { -// (*offset)++; -// return create_builtin_type(TYPE_INT, (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_LONG) { -// // 检查是否为 long long -// const scc_lexer_tok_t *next_tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset + 1); -// if (next_tok->type == SCC_TOK_LONG) { -// (*offset) += 2; // 跳过两个 long -// return create_builtin_type(TYPE_LONG_LONG, -// (scc_ast_decl_specifier_t){0}); -// } else { -// (*offset)++; -// return create_builtin_type(TYPE_LONG, -// (scc_ast_decl_specifier_t){0}); -// } -// } else if (tok->type == SCC_TOK_FLOAT) { -// (*offset)++; -// return create_builtin_type(TYPE_FLOAT, -// (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_DOUBLE) { -// // 检查是否为 long double -// const scc_lexer_tok_t *next_tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset + 1); -// if (next_tok->type == SCC_TOK_LONG) { -// (*offset) += 2; // 跳过 double long -// return create_builtin_type(TYPE_LONG_DOUBLE, -// (scc_ast_decl_specifier_t){0}); -// } else { -// (*offset)++; -// return create_builtin_type(TYPE_DOUBLE, -// (scc_ast_decl_specifier_t){0}); -// } -// } else if (tok->type == SCC_TOK_BOOL) { -// (*offset)++; -// return create_builtin_type(TYPE_BOOL, (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_SIGNED || tok->type == SCC_TOK_UNSIGNED) -// { -// // signed/unsigned 需要与后续类型组合 -// // 这里简化处理,默认为 int -// (*offset)++; -// return create_builtin_type(TYPE_INT, (scc_ast_decl_specifier_t){0}); -// } else if (tok->type == SCC_TOK_COMPLEX) { -// // _Complex 需要与浮点类型组合 -// // 这里简化处理 -// (*offset)++; -// return create_builtin_type(TYPE_COMPLEX_FLOAT, -// (scc_ast_decl_specifier_t){0}); -// } - -// // 处理结构体/联合体 -// if (tok->type == SCC_TOK_STRUCT || tok->type == SCC_TOK_UNION) { -// return parse_struct_or_union_specifier(parser, offset); -// } - -// // 处理枚举 -// if (tok->type == SCC_TOK_ENUM) { -// return parse_enum_specifier(parser, offset); -// } - -// // 处理 typedef 名称 -// if (tok->type == SCC_TOK_IDENT) { -// // TODO -// return null; -// scc_ast_type_t *type = -// (scc_ast_type_t *)scc_malloc(sizeof(scc_ast_type_t)); -// if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_TYPEDEF; -// type->typedef_type.name = tok->value.cstr.data; -// type->typedef_type.underlying = null; // 需要从符号表解析 - -// (*offset)++; -// return type; -// } - -// return null; -// } - -// /** -// * @brief 解析结构体或联合体说明符 -// */ -// static scc_ast_type_t *parse_struct_or_union_specifier(scc_parser_t *parser, -// usize *offset) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); -// cbool is_struct = (tok->type == SCC_TOK_STRUCT); - -// (*offset)++; // 跳过 struct 或 union - -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = is_struct ? SCC_AST_TYPE_STRUCT : SCC_AST_TYPE_UNION; -// type->record.name = null; -// scc_vec_init(type->record.fields); - -// // 检查是否有标识符 -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_IDENT) { -// type->record.name = tok->value.cstr.data; -// (*offset)++; -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// } - -// // 如果有 '{',解析结构体定义 -// if (tok->type == SCC_TOK_L_BRACE) { -// (*offset)++; // 跳过 '{' - -// // TODO: 解析 struct-declaration-list -// // 这是一个复杂的子解析器,需要单独实现 - -// // 临时:跳过所有声明直到遇到 '}' -// while (true) { -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_BRACE) -// break; -// if (tok->type == SCC_TOK_EOF) { -// LOG_ERROR("Unclosed struct/union definition"); -// scc_free(type); -// return null; -// } -// (*offset)++; -// } - -// (*offset)++; // 跳过 '}' -// } - -// return type; -// } - -// /** -// * @brief 解析枚举说明符 -// */ -// static scc_ast_type_t *parse_enum_specifier(scc_parser_t *parser, -// usize *offset) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type != SCC_TOK_ENUM) -// return null; - -// (*offset)++; // 跳过 enum - -// scc_ast_type_t *type = (scc_ast_type_t -// *)scc_malloc(sizeof(scc_ast_type_t)); if (!type) -// return null; - -// type->base.type = SCC_AST_TYPE_ENUM; -// type->enumeration.name = null; -// scc_vec_init(type->enumeration.enumerators); - -// // 检查是否有标识符 -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_IDENT) { -// type->enumeration.name = tok->value.cstr.data; -// (*offset)++; -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// } - -// // 如果有 '{',解析枚举定义 -// if (tok->type == SCC_TOK_L_BRACE) { -// (*offset)++; // 跳过 '{' - -// // TODO: 解析 enumerator-list -// // 这是一个复杂的子解析器,需要单独实现 - -// // 临时:跳过所有枚举项直到遇到 '}' -// while (true) { -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_BRACE) -// break; -// if (tok->type == SCC_TOK_EOF) { -// LOG_ERROR("Unclosed enum definition"); -// scc_free(type); -// return null; -// } -// (*offset)++; -// } - -// (*offset)++; // 跳过 '}' -// } - -// return type; -// } - -// /** -// * @brief 解析指定符-限定符列表 -// */ -// static scc_ast_type_t *parse_specifier_qualifier_list(scc_parser_t *parser, -// usize *offset) { -// scc_ast_decl_specifier_t quals = {0}; - -// // 收集类型限定符(可能出现在前面) -// while (true) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// if (!is_type_qualifier_token(tok)) { -// break; -// } - -// scc_ast_decl_specifier_t new_quals = -// parse_type_qualifier(parser, offset); -// quals.is_const |= new_quals.is_const; -// quals.is_restrict |= new_quals.is_restrict; -// quals.is_volatile |= new_quals.is_volatile; -// quals.is_atomic |= new_quals.is_atomic; -// } - -// // 解析类型说明符 -// scc_ast_type_t *type_specifier = parse_type_specifier(parser, offset); -// if (!type_specifier) { -// // TODO -// // LOG_ERROR("Expected type specifier"); -// return null; -// } - -// // 收集可能出现在类型说明符后面的限定符 -// while (true) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// if (!is_type_qualifier_token(tok)) { -// break; -// } - -// scc_ast_decl_specifier_t new_quals = -// parse_type_qualifier(parser, offset); -// quals.is_const |= new_quals.is_const; -// quals.is_restrict |= new_quals.is_restrict; -// quals.is_volatile |= new_quals.is_volatile; -// quals.is_atomic |= new_quals.is_atomic; -// } - -// // 将限定符应用到类型上 -// if (type_specifier->base.type == SCC_AST_TYPE_BUILTIN) { -// type_specifier->builtin.quals = quals; -// } else if (type_specifier->base.type == SCC_AST_TYPE_POINTER) { -// // 对于指针类型,这里的限定符应该应用到指针本身 -// type_specifier->pointer.quals = quals; -// } else if (type_specifier->base.type == SCC_AST_TYPE_TYPEDEF) { -// // typedef 类型可能也有限定符,但需要保存在其他地方 -// // 这里简化处理 -// } - -// return type_specifier; -// } - -// /** -// * @brief 解析指针 -// */ -// static scc_ast_type_t *parse_pointer(scc_parser_t *parser, usize *offset) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// if (tok->type != SCC_TOK_MUL) { -// return null; // 不是指针 -// } - -// (*offset)++; // 跳过 '*' - -// // 解析可选的类型限定符列表 -// scc_ast_decl_specifier_t ptr_quals = -// parse_type_qualifier_list(parser, offset); - -// // 递归解析更多指针(多重指针) -// scc_ast_type_t *inner_pointer = parse_pointer(parser, offset); - -// // 创建指针类型 -// scc_ast_type_t *ptr_type = create_pointer_type(null, ptr_quals); -// if (!ptr_type) -// return null; - -// if (inner_pointer) { -// // 有更多指针,将它们链接起来 -// scc_ast_type_t *current = ptr_type; -// while (current->base.type == SCC_AST_TYPE_POINTER && -// current->pointer.pointee && -// current->pointer.pointee->base.type == SCC_AST_TYPE_POINTER) { -// current = current->pointer.pointee; -// } -// current->pointer.pointee = inner_pointer; -// } - -// return ptr_type; -// } - -// /** -// * @brief 解析抽象声明符 -// */ -// static scc_ast_type_t *parse_abstract_declarator(scc_parser_t *parser, -// usize *offset, -// scc_ast_type_t *base_type) { -// // 解析可选的指针 -// scc_ast_type_t *ptr_type = parse_pointer(parser, offset); - -// if (ptr_type) { -// // 将指针的 pointee 指向解析出的直接抽象声明符 -// scc_ast_type_t *direct_type = -// parse_direct_abstract_declarator(parser, offset, base_type); - -// // 找到最内层的指针 -// scc_ast_type_t *current = ptr_type; -// while (current->base.type == SCC_AST_TYPE_POINTER && -// current->pointer.pointee && -// current->pointer.pointee->base.type == SCC_AST_TYPE_POINTER) { -// current = current->pointer.pointee; -// } - -// if (current->base.type == SCC_AST_TYPE_POINTER) { -// current->pointer.pointee = direct_type; -// } - -// return ptr_type; -// } else { -// // 没有指针,直接解析直接抽象声明符 -// return parse_direct_abstract_declarator(parser, offset, base_type); -// } -// } - -// /** -// * @brief 解析直接抽象声明符 -// */ -// static scc_ast_type_t * -// parse_direct_abstract_declarator(scc_parser_t *parser, usize *offset, -// scc_ast_type_t *base_type) { -// scc_ast_type_t *current_type = base_type; - -// while (true) { -// const scc_lexer_tok_t *tok = -// scc_lexer_stream_peek(parser->lex_stream, *offset); - -// // 情况1: ( abstract-declarator ) -// if (tok->type == SCC_TOK_L_PAREN) { -// (*offset)++; // 跳过 '(' - -// // 解析括号内的抽象声明符 -// scc_ast_type_t *inner_type = -// parse_abstract_declarator(parser, offset, current_type); - -// // 期望右括号 -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type != SCC_TOK_R_PAREN) { -// LOG_ERROR("Expected ')' after abstract-declarator"); -// return current_type; -// } -// (*offset)++; // 跳过 ')' - -// current_type = inner_type; -// continue; -// } - -// // 情况2: 数组声明符 [ ... ] -// if (tok->type == SCC_TOK_L_BRACKET) { -// (*offset)++; // 跳过 '[' - -// // 检查是否是 [ * ] (可变长度数组) -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_MUL) { -// // 可变长度数组 -// scc_ast_type_t *array_type = -// create_array_type(current_type, null); -// if (!array_type) -// return current_type; - -// (*offset)++; // 跳过 '*' -// } else { -// // 解析可选的 static 关键字 -// cbool has_static = false; -// if (tok->type == SCC_TOK_STATIC) { -// has_static = true; -// (*offset)++; -// } - -// // 解析可选的类型限定符列表 -// parse_type_qualifier_list(parser, offset); -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); - -// // 如果之前没有 static,但有限定符,再检查一次 static -// if (!has_static && tok->type == SCC_TOK_STATIC) { -// has_static = true; -// (*offset)++; -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// } - -// // 解析可选的赋值表达式(数组大小) -// scc_ast_expr_t *size_expr = null; -// if (tok->type != SCC_TOK_R_BRACKET) { -// // TODO: 解析 assignment-expression -// // 简化:设置 size 为 null -// size_expr = null; - -// // 跳过表达式 -// while (tok->type != SCC_TOK_R_BRACKET && -// tok->type != SCC_TOK_EOF) { -// (*offset)++; -// tok = -// scc_lexer_stream_peek(parser->lex_stream, -// *offset); -// } -// } - -// scc_ast_type_t *array_type = -// create_array_type(current_type, size_expr); -// if (!array_type) -// return current_type; - -// current_type = array_type; -// } - -// // 期望右括号 -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type != SCC_TOK_R_BRACKET) { -// LOG_ERROR("Expected ']' after array declarator"); -// return current_type; -// } -// (*offset)++; // 跳过 ']' -// continue; -// } - -// // 情况3: 函数声明符 ( parameter-type-list(opt) ) -// if (tok->type == SCC_TOK_L_PAREN) { -// (*offset)++; // 跳过 '(' - -// // 检查是否为空参数列表 () -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_PAREN) { -// // 空参数列表 -// (*offset)++; // 跳过 ')' -// scc_ast_type_t *func_type = create_function_type( -// current_type, (scc_ast_type_vec_t){0}, false); -// if (!func_type) -// return current_type; -// current_type = func_type; -// continue; -// } else if (tok->type == SCC_TOK_VOID) { -// // void 参数列表 -// (*offset)++; // 跳过 void -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_PAREN) { -// (*offset)++; // 跳过 ')' -// scc_ast_type_vec_t param_types; -// scc_vec_init(param_types); -// scc_ast_type_t *func_type = -// create_function_type(current_type, param_types, -// false); -// if (!func_type) -// return current_type; -// current_type = func_type; -// continue; -// } else { -// LOG_ERROR("Expected ')' after void parameter list"); -// return current_type; -// } -// } else { -// // TODO: 解析 parameter-type-list -// // 这是一个复杂的子解析器,需要单独实现 - -// scc_ast_type_vec_t param_types; -// scc_vec_init(param_types); -// cbool is_variadic = false; - -// // 临时:跳过所有参数直到遇到 ')' 或 '...' -// while (true) { -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_PAREN) -// break; -// if (tok->type == SCC_TOK_ELLIPSIS) { -// is_variadic = true; -// (*offset)++; -// break; -// } -// if (tok->type == SCC_TOK_EOF) { -// LOG_ERROR("Unclosed function parameter list"); -// return current_type; -// } -// (*offset)++; -// } - -// tok = scc_lexer_stream_peek(parser->lex_stream, *offset); -// if (tok->type == SCC_TOK_R_PAREN) { -// (*offset)++; // 跳过 ')' -// } - -// scc_ast_type_t *func_type = create_function_type( -// current_type, param_types, is_variadic); -// if (!func_type) -// return current_type; -// current_type = func_type; -// continue; -// } -// } - -// // 没有更多的直接抽象声明符 -// break; -// } - -// return current_type; -// } - -// // 提供类型检查接口 -// cbool scc_ast_type_is_builtin(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_BUILTIN; -// } - -// cbool scc_ast_type_is_pointer(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_POINTER; -// } - -// cbool scc_ast_type_is_array(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_ARRAY; -// } - -// cbool scc_ast_type_is_function(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_FUNCTION; -// } - -// cbool scc_ast_type_is_struct(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_STRUCT; -// } - -// cbool scc_ast_type_is_union(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_UNION; -// } - -// cbool scc_ast_type_is_enum(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_ENUM; -// } - -// cbool scc_ast_type_is_typedef(const scc_ast_type_t *type) { -// return type && type->base.type == SCC_AST_TYPE_TYPEDEF; -// } - -// // 获取内置类型 -// scc_ast_builtin_type_t scc_ast_type_get_builtin(const scc_ast_type_t *type) { -// if (!scc_ast_type_is_builtin(type)) -// return TYPE_VOID; -// return type->builtin.type; -// } - -// // 获取指针指向的类型 -// scc_ast_type_t *scc_ast_type_get_pointee(const scc_ast_type_t *type) { -// if (!scc_ast_type_is_pointer(type)) -// return null; -// return type->pointer.pointee; -// } - -// // 获取数组元素类型 -// scc_ast_type_t *scc_ast_type_get_element(const scc_ast_type_t *type) { -// if (!scc_ast_type_is_array(type)) -// return null; -// return type->array.element; -// } - -// // 获取函数返回类型 -// scc_ast_type_t *scc_ast_type_get_return(const scc_ast_type_t *type) { -// if (!scc_ast_type_is_function(type)) -// return null; -// return type->function.return_type; -// } - -// // 获取类型限定符 -// scc_ast_decl_specifier_t scc_ast_type_get_quals(const scc_ast_type_t *type) { -// if (!type) -// return (scc_ast_decl_specifier_t){0}; - -// switch (type->base.type) { -// case SCC_AST_TYPE_BUILTIN: -// return type->builtin.quals; -// case SCC_AST_TYPE_POINTER: -// return type->pointer.quals; -// default: -// return (scc_ast_decl_specifier_t){0}; -// } -// } +static scc_ast_type_t * +parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, + scc_ast_type_t **delay_pointee_ptr) { + const scc_lexer_tok_t *tok_ptr = null; + scc_ast_type_t *ret = null; + // direct-abstract-declarator + tok_ptr = scc_parser_peek(parser); + if (tok_ptr == null) { + return base; + } + + if (tok_ptr->type == SCC_TOK_L_PAREN) { + // () SCC_TOK_L_PAREN + scc_parser_next_consume(parser, null); + scc_ast_type_t *delay_pointee = null; + ret = parse_abstract_declarator(parser, null, &delay_pointee); + if (ret == null) { + scc_ast_decl_vec_t params; + parse_function_parameters(parser, ¶ms); + ret = ast_type_alloc(); + scc_ast_type_function_init(ret, base, ¶ms); + return parse_direct_abstract_declarator(parser, ret, + delay_pointee_ptr); + } else { + if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { + LOG_ERROR("expect ')'"); + } + base = parse_direct_abstract_declarator(parser, base, + delay_pointee_ptr); + Assert(delay_pointee != null); + delay_pointee->pointer.pointee = base; + } + return ret; + } else if (tok_ptr->type == SCC_TOK_L_BRACKET) { + // [] SCC_TOK_L_BRACKET + scc_ast_expr_t *size = parse_array_size_type(parser); + scc_ast_type_t *ret = ast_type_alloc(); + base = + parse_direct_abstract_declarator(parser, base, delay_pointee_ptr); + scc_ast_type_array_init(ret, base, size); + return ret; + } else { + return base; + } +} + +scc_ast_node_t *_scc_parse_type(scc_parser_t *parser) { + if (!scc_parse_is_decl_specifier_start(parser)) { + return null; + } + + cbool is_typedef_decl = false; + if (scc_parser_consume_if(parser, SCC_TOK_TYPEDEF)) { + is_typedef_decl = true; + } + + scc_ast_type_t *ret = null; + scc_ast_decl_specifier_t spec = parse_type_qualifier_list(parser); + ret = parse_type_specifier(parser); + if (ret != null) { + ret->quals = spec; + } + scc_ast_node_t *node = parse_declarator(parser, ret, null); + if (is_typedef_decl) { + Assert(node->type == SCC_AST_DECL_VAR); + node->type = SCC_AST_DECL_TYPEDEF; + } + return node; +} + +scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { + if (!(scc_parse_is_type_specifier_start(parser) || + scc_parse_is_type_qualifier_start(parser))) { + return null; + } + + scc_ast_type_t *ret = null; + scc_ast_decl_specifier_t spec = parse_type_qualifier_list(parser); + ret = parse_type_specifier(parser); + if (ret != null) { + ret->quals = spec; + } + ret = parse_abstract_declarator(parser, ret, null); + return ret; +} diff --git a/libs/parser/tests/test_parser_unit.c b/libs/parser/tests/test_parser_unit.c index 75ac743..1837ad2 100644 --- a/libs/parser/tests/test_parser_unit.c +++ b/libs/parser/tests/test_parser_unit.c @@ -26,7 +26,10 @@ static scc_ast_node_t *process_input(const char *input, cbool not_eof = false; scc_ring_not_eof(*parser.ring, not_eof); - Assert(!not_eof == true); + if (not_eof == true) { + // FIXME MAYBE free + return null; + } scc_lexer_drop_ring(parser.ring); scc_parser_drop(&parser); @@ -81,9 +84,13 @@ static void test_parser_unit(void) { { // 构造函数类型:返回 int,参数为空 scc_ast_type_t func_type; + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, - null); // 无参数,非可变参数 - + &func_params); // 构造复合语句块(空) scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, null); @@ -99,7 +106,13 @@ static void test_parser_unit(void) { // 3. 翻译单元包含一个函数定义 { scc_ast_type_t func_type; - scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null); + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); + scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, + &func_params); scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, null); @@ -138,7 +151,13 @@ static void test_parser_unit(void) { // 函数类型 scc_ast_type_t func_type; - scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null); + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); + scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, + &func_params); scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); @@ -318,6 +337,37 @@ static void test_parser_unit(void) { // 比较解析结果与期望 AST SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit); } + + { + scc_ast_decl_vec_t params; + scc_ast_decl_t param0; + scc_ast_decl_param_init( + ¶m0, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a"); + scc_ast_decl_t param1; + scc_ast_decl_param_init( + ¶m1, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b"); + scc_ast_decl_t param2; + scc_ast_decl_param_init( + ¶m2, (scc_ast_type_t *)&scc_ast_builtin_type_va_list, null); + scc_ast_decl_t *params_array[] = {¶m0, ¶m1, ¶m2}; + scc_vec_unsafe_from_array(params, params_array); + scc_ast_type_t decl_func_type; + scc_ast_type_function_init(&decl_func_type, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + ¶ms); + scc_ast_decl_t decl_func; + scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", null); + SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);", + scc_parse_declaration); + } + + { + scc_ast_decl_t typedef_decl; + scc_ast_decl_typedef_init(&typedef_decl, "int32_t", + &scc_ast_builtin_type_int); + SCC_CHECK_AST(&typedef_decl.base, "typedef int int32_t;", + scc_parse_declaration); + } } static void test_parser_expression(void) { @@ -596,8 +646,591 @@ static void test_parser_expression(void) { } } +static void test_parser_type(void) { + { + // 1. int + { + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int", + _scc_parse_type); + } + + // 2. int * + { + scc_ast_type_t ptr_to_int; + scc_ast_type_pointer_init( + &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); + SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type); + } + + // 3. int *[3] + { + scc_ast_type_t ptr_to_int; + scc_ast_type_pointer_init( + &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); + + scc_ast_expr_t size_3; + scc_ast_expr_literal_int_init(&size_3, "3", false); + + scc_ast_type_t array_of_ptr; + scc_ast_type_array_init(&array_of_ptr, &ptr_to_int, &size_3); + SCC_CHECK_AST(&array_of_ptr.base, "int *[3]", _scc_parse_type); + } + + // 4. int (*)[3] + { + scc_ast_expr_t size_3; + scc_ast_expr_literal_int_init(&size_3, "3", false); + + scc_ast_type_t array_of_int; + scc_ast_type_array_init(&array_of_int, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &size_3); + + scc_ast_type_t ptr_to_array; + scc_ast_type_pointer_init(&ptr_to_array, &array_of_int); + SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]", _scc_parse_type); + } + + // 5. int (*)[*] + { + scc_ast_type_t array_of_int_var; + scc_ast_type_array_init(&array_of_int_var, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + NULL); // NULL 表示不定长数组 + + scc_ast_type_t ptr_to_array_var; + scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var); + SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]", + _scc_parse_type); + } + + // 6. int *() + { + // 返回类型 int* + scc_ast_type_t ptr_to_int; + scc_ast_type_pointer_init( + &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); + + // 函数类型,返回 int*,无参数 + scc_ast_type_t func_type; + scc_ast_type_function_init(&func_type, &ptr_to_int, NULL); + SCC_CHECK_AST(&func_type.base, "int *()", _scc_parse_type); + } + + // 7. int (*)(void) + { + // 函数类型,返回 int,无参数 + scc_ast_type_t func_void; + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, + null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); + scc_ast_type_function_init( + &func_void, (scc_ast_type_t *)&scc_ast_builtin_type_int, + &func_params); + + scc_ast_type_t ptr_to_func; + scc_ast_type_pointer_init(&ptr_to_func, &func_void); + SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)", _scc_parse_type); + } + + // 8. int (*const [])(unsigned int, ...) + { + // --- 构造参数列表 --- + // 第一个参数:unsigned int + scc_ast_decl_t param_uint; + scc_ast_decl_param_init( + ¶m_uint, + (scc_ast_type_t *)&scc_ast_builtin_type_unsigned_int, "u"); + + // 第二个参数:... 用内置 va_list 类型近似表示 + scc_ast_type_t va_list_type; + _scc_ast_type_builtin_init(&va_list_type, + SCC_AST_BUILTIN_TYPE_VA_LIST); + scc_ast_decl_t param_var; + scc_ast_decl_param_init(¶m_var, &va_list_type, "..."); + + scc_ast_decl_vec_t params; + scc_vec_init(params); + scc_vec_push(params, ¶m_uint); + scc_vec_push(params, ¶m_var); + + // --- 函数类型,返回 int --- + scc_ast_type_t func_type; + scc_ast_type_function_init( + &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, + ¶ms); // params 被移动 + + // --- 指向函数的指针,带 const 限定 --- + scc_ast_type_t ptr_to_func; + scc_ast_type_pointer_init(&ptr_to_func, &func_type); + ptr_to_func.quals.is_const = true; // 设置 const + + // --- 数组,元素为上述 const 指针,大小未指定 --- + scc_ast_type_t array_of_ptr; + scc_ast_type_array_init(&array_of_ptr, &ptr_to_func, NULL); + + SCC_CHECK_AST(&array_of_ptr.base, + "int (*const [])(unsigned int, ...)", + _scc_parse_type); + } + } + + // 1. 基本内置类型及组合 + { + // int + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int", + _scc_parse_type); + + // char + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_char, "char", + _scc_parse_type); + + // long long + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_long, + "long long", _scc_parse_type); + + // unsigned int + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_unsigned_int, + "unsigned int", _scc_parse_type); + + // float + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_float, "float", + _scc_parse_type); + + // double + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_double, "double", + _scc_parse_type); + + // void + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void", + _scc_parse_type); + + // bool + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool", + _scc_parse_type); + + // long double + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double, + "long double", _scc_parse_type); + + // _Complex double + SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double, + "complex double", _scc_parse_type); + } + + // 2. 带类型限定符的基本类型 (const, volatile) + { + // const int + scc_ast_type_t const_int = scc_ast_builtin_type_int; + const_int.quals.is_const = true; + SCC_CHECK_AST(&const_int.base, "const int", _scc_parse_type); + + // volatile unsigned long + scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long; + volatile_ulong.quals.is_volatile = true; + SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long", + _scc_parse_type); + + // const volatile char + scc_ast_type_t const_volatile_char = scc_ast_builtin_type_char; + const_volatile_char.quals.is_const = true; + const_volatile_char.quals.is_volatile = true; + SCC_CHECK_AST(&const_volatile_char.base, "const volatile char", + _scc_parse_type); + } + + // 3. 指针类型 + { + // int * + scc_ast_type_t ptr_to_int; + scc_ast_type_pointer_init(&ptr_to_int, + (scc_ast_type_t *)&scc_ast_builtin_type_int); + SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type); + + // int ** + scc_ast_type_t ptr_to_ptr_to_int; + scc_ast_type_pointer_init(&ptr_to_ptr_to_int, &ptr_to_int); + SCC_CHECK_AST(&ptr_to_ptr_to_int.base, "int **", _scc_parse_type); + + // int * const (const pointer to int) + scc_ast_type_t const_ptr_to_int; + scc_ast_type_pointer_init(&const_ptr_to_int, + (scc_ast_type_t *)&scc_ast_builtin_type_int); + const_ptr_to_int.quals.is_const = true; + SCC_CHECK_AST(&const_ptr_to_int.base, "int * const", _scc_parse_type); + + // const int * (pointer to const int) + scc_ast_type_t const_int_type = scc_ast_builtin_type_int; + const_int_type.quals.is_const = true; + scc_ast_type_t ptr_to_const_int; + scc_ast_type_pointer_init(&ptr_to_const_int, &const_int_type); + SCC_CHECK_AST(&ptr_to_const_int.base, "const int *", _scc_parse_type); + + // const int * const (const pointer to const int) + scc_ast_type_t const_ptr_to_const_int; + scc_ast_type_pointer_init(&const_ptr_to_const_int, &const_int_type); + const_ptr_to_const_int.quals.is_const = true; + SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const", + _scc_parse_type); + + // volatile int * restrict + scc_ast_type_t volatile_int = scc_ast_builtin_type_int; + volatile_int.quals.is_volatile = true; + scc_ast_type_t restrict_ptr_to_volatile_int; + scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int); + restrict_ptr_to_volatile_int.quals.is_restrict = true; + SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base, + "volatile int * restrict", _scc_parse_type); + } + + // 4. 数组类型 + { + // int [5] + scc_ast_expr_t size_5; + scc_ast_expr_literal_int_init(&size_5, "5", false); + scc_ast_type_t array_of_5_int; + scc_ast_type_array_init(&array_of_5_int, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &size_5); + SCC_CHECK_AST(&array_of_5_int.base, "int [5]", _scc_parse_type); + + // int [] (不完整类型) + scc_ast_type_t array_of_int_unknown; + scc_ast_type_array_init(&array_of_int_unknown, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + NULL); + SCC_CHECK_AST(&array_of_int_unknown.base, "int []", _scc_parse_type); + + // // int [*] (变长数组原型中的不定长数组) + // FIXME + // scc_ast_type_t array_of_int_var; + // scc_ast_type_array_init(&array_of_int_var, + // (scc_ast_type_t *)&scc_ast_builtin_type_int, + // NULL); + // // 注意:[*] 与 [] 在AST中目前无法区分,都使用 size=NULL + // // 表示。如果解析器需要区分,可能需要特殊处理。 这里暂时假设解析器对 + // [*] + // // 也生成 size=NULL 的数组节点。 + // SCC_CHECK_AST(&array_of_int_var.base, "int [*]", scc_parse_type); + + // int [5][3] (二维数组) + scc_ast_expr_t size_3; + scc_ast_expr_literal_int_init(&size_3, "3", false); + scc_ast_type_t inner_array; + scc_ast_type_array_init( + &inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3); + scc_ast_type_t outer_array; + scc_ast_type_array_init(&outer_array, &inner_array, &size_5); + SCC_CHECK_AST(&outer_array.base, "int [5][3]", _scc_parse_type); + + // int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性 + scc_ast_type_t array_of_5_int2; + scc_ast_type_array_init(&array_of_5_int2, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &size_5); + scc_ast_type_t ptr_to_array; + scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2); + SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", _scc_parse_type); + + // int *[5] (指针数组) + scc_ast_type_t ptr_to_int2; + scc_ast_type_pointer_init(&ptr_to_int2, + (scc_ast_type_t *)&scc_ast_builtin_type_int); + scc_ast_type_t array_of_5_ptr; + scc_ast_type_array_init(&array_of_5_ptr, &ptr_to_int2, &size_5); + SCC_CHECK_AST(&array_of_5_ptr.base, "int *[5]", _scc_parse_type); + + // const int [5] (数组元素为const int) + scc_ast_type_t const_int2 = scc_ast_builtin_type_int; + const_int2.quals.is_const = true; + scc_ast_type_t const_array; + scc_ast_type_array_init(&const_array, &const_int2, &size_5); + SCC_CHECK_AST(&const_array.base, "const int [5]", _scc_parse_type); + } + + // 5. 函数类型 + { + // int (void) + scc_ast_type_t func_void; + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); + scc_ast_type_function_init(&func_void, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &func_params); + SCC_CHECK_AST(&func_void.base, "int (void)", _scc_parse_type); + + // // int () (无参数声明,非原型) + // // + // 在C中,空括号表示未指定参数,但AST中可能仍然用空参数列表表示。这里假设与 + // // (void) 相同。 + // SCC_CHECK_AST(&func_void.base, "int ()", scc_parse_type); + + // int (int, float) + scc_ast_decl_t param1, param2; + scc_ast_decl_param_init( + ¶m1, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); + scc_ast_decl_param_init( + ¶m2, (scc_ast_type_t *)&scc_ast_builtin_type_float, null); + scc_ast_decl_vec_t params; + scc_vec_init(params); + scc_vec_push(params, ¶m1); + scc_vec_push(params, ¶m2); + + scc_ast_type_t func_with_params; + scc_ast_type_function_init(&func_with_params, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + ¶ms); + SCC_CHECK_AST(&func_with_params.base, "int (int, float)", + _scc_parse_type); + + // int (int, ...) (可变参数) + scc_ast_decl_t param_int, param_var; + scc_ast_decl_param_init( + ¶m_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); + scc_ast_type_t va_list_type; + _scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST); + scc_ast_decl_param_init(¶m_var, &va_list_type, null); + scc_ast_decl_vec_t params_var; + scc_vec_init(params_var); + scc_vec_push(params_var, ¶m_int); + scc_vec_push(params_var, ¶m_var); + + scc_ast_type_t func_varargs; + scc_ast_type_function_init(&func_varargs, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + ¶ms_var); + SCC_CHECK_AST(&func_varargs.base, "int (int, ...)", _scc_parse_type); + + // int (*)(int) (函数指针) + scc_ast_decl_t param; + scc_ast_decl_param_init( + ¶m, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); + scc_ast_decl_vec_t params2; + scc_vec_init(params2); + scc_vec_push(params2, ¶m); + + scc_ast_type_t func_type; + scc_ast_type_function_init( + &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms2); + scc_ast_type_t ptr_to_func; + scc_ast_type_pointer_init(&ptr_to_func, &func_type); + SCC_CHECK_AST(&ptr_to_func.base, "int (*)(int)", _scc_parse_type); + } + + // 6. 函数指针和复杂声明符 + { + // int (*foo)(void) + // 这里应解析为类型名,但包含标识符?我们的解析函数是scc_parse_type,它应该解析类型名,不应包含标识符。 + // 所以跳过带标识符的,只测试抽象声明符。 + + // int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针) + // 步骤: + // 1) 数组类型:int [5] + scc_ast_expr_t size_5; + scc_ast_expr_literal_int_init(&size_5, "5", false); + scc_ast_type_t array_of_5_int; + scc_ast_type_array_init(&array_of_5_int, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &size_5); + + // 2) 函数类型:返回指向数组的指针,无参数 + scc_ast_type_t ptr_to_array; + scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int); + scc_ast_type_t func_type; + scc_ast_decl_vec_t func_params; + scc_ast_decl_t void_decl; + scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null); + scc_ast_decl_t *array[] = {&void_decl}; + scc_vec_unsafe_from_array(func_params, array); + scc_ast_type_function_init(&func_type, &ptr_to_array, + &func_params); // 无参数 + + // 3) 指向该函数的指针 + scc_ast_type_t ptr_to_func; + scc_ast_type_pointer_init(&ptr_to_func, &func_type); + + SCC_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]", + _scc_parse_type); + + // int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针) + // 1) 函数类型:返回 int,无参数 + scc_ast_type_t func_type2; + scc_ast_decl_vec_t func_params2; + scc_vec_unsafe_from_array(func_params2, array); + scc_ast_type_function_init(&func_type2, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + &func_params2); + + // 2) 指针指向该函数 + scc_ast_type_t ptr_to_func2; + scc_ast_type_pointer_init(&ptr_to_func2, &func_type2); + + // 3) 数组,元素为上述指针 + scc_ast_type_t array_of_ptr_to_func; + scc_ast_type_array_init(&array_of_ptr_to_func, &ptr_to_func2, &size_5); + + // 4) 指针指向该数组 + scc_ast_type_t ptr_to_array_of_ptr; + scc_ast_type_pointer_init(&ptr_to_array_of_ptr, &array_of_ptr_to_func); + SCC_CHECK_AST(&ptr_to_array_of_ptr.base, "int (*(*)[5])(void)", + _scc_parse_type); + } + + // 7. 结构体/联合/枚举类型(标记和定义) + { + // struct S (不完整类型) + scc_ast_type_t struct_tag; + scc_ast_type_struct_init(&struct_tag, "S", + NULL); // name="S", members=NULL + SCC_CHECK_AST(&struct_tag.base, "struct S", _scc_parse_type); + + // struct { int x; } (匿名结构体定义) + scc_ast_decl_t field; + scc_ast_decl_val_init( + &field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", NULL); + scc_ast_decl_vec_t fields; + scc_vec_init(fields); + scc_vec_push(fields, &field); + + scc_ast_type_t struct_def; + scc_ast_type_struct_init(&struct_def, NULL, + &fields); // name=NULL, members=fields + SCC_CHECK_AST(&struct_def.base, "struct { int x; }", _scc_parse_type); + + // union U (不完整类型) + scc_ast_type_t union_tag; + scc_ast_type_union_init(&union_tag, "U", NULL); + SCC_CHECK_AST(&union_tag.base, "union U", _scc_parse_type); + + // union { int a; float b; } (匿名联合定义) + scc_ast_decl_t field_a, field_b; + scc_ast_decl_val_init( + &field_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", NULL); + scc_ast_decl_val_init( + &field_b, (scc_ast_type_t *)&scc_ast_builtin_type_float, "b", NULL); + scc_ast_decl_vec_t fields_union; + scc_vec_init(fields_union); + scc_vec_push(fields_union, &field_a); + scc_vec_push(fields_union, &field_b); + + scc_ast_type_t union_def; + scc_ast_type_union_init(&union_def, NULL, &fields_union); + SCC_CHECK_AST(&union_def.base, "union { int a; float b; }", + _scc_parse_type); + + // enum E (不完整类型) + scc_ast_type_t enum_tag; + scc_ast_type_enum_init(&enum_tag, "E", NULL); + SCC_CHECK_AST(&enum_tag.base, "enum E", _scc_parse_type); + + // enum { RED, GREEN, BLUE } (匿名枚举定义) + scc_ast_expr_t red, green, blue; + scc_ast_expr_identifier_init(&red, "RED"); + scc_ast_expr_identifier_init(&green, "GREEN"); + scc_ast_expr_identifier_init(&blue, "BLUE"); + scc_ast_expr_vec_t enumerators; + scc_vec_init(enumerators); + scc_vec_push(enumerators, &red); + scc_vec_push(enumerators, &green); + scc_vec_push(enumerators, &blue); + + scc_ast_type_t enum_def; + scc_ast_type_enum_init(&enum_def, NULL, &enumerators); + SCC_CHECK_AST(&enum_def.base, "enum { RED, GREEN, BLUE }", + _scc_parse_type); + } + + // 8. typedef 类型 + { + // 假设存在 typedef int myint; 但类型解析时,遇到 myint + // 应得到对应的类型节点。 为了测试,我们直接构造一个 typedef 类型节点。 + // scc_ast_type_t myint_type; + // scc_ast_type_typedef_init(&myint_type, "myint", + // (scc_ast_type_t + // *)&scc_ast_builtin_type_int); + // SCC_CHECK_AST(&myint_type.base, "myint", scc_parse_type); + + // // myint * (指针指向 typedef 类型) + // scc_ast_type_t ptr_to_myint; + // scc_ast_type_pointer_init(&ptr_to_myint, &myint_type); + // SCC_CHECK_AST(&ptr_to_myint.base, "myint *", scc_parse_type); + } + + // 9. 混合复杂类型 + { + // const int * volatile (*)[10] + // 步骤: + // 1) const int + scc_ast_type_t const_int = scc_ast_builtin_type_int; + const_int.quals.is_const = true; + + // 2) 指针指向 const int (普通指针) + scc_ast_type_t ptr_to_const_int; + scc_ast_type_pointer_init(&ptr_to_const_int, &const_int); + // 该指针本身是 volatile 限定?语法上 "const int * volatile" 表示指针是 + // volatile 的,指向 const int。 + ptr_to_const_int.quals.is_volatile = true; + + // 3) 数组,元素为上述指针,大小为10 + scc_ast_expr_t size_10; + scc_ast_expr_literal_int_init(&size_10, "10", false); + scc_ast_type_t array_of_ptr; + scc_ast_type_array_init(&array_of_ptr, &ptr_to_const_int, &size_10); + + // 4) 指针指向该数组 + scc_ast_type_t ptr_to_array; + scc_ast_type_pointer_init(&ptr_to_array, &array_of_ptr); + SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]", + _scc_parse_type); + + // int (*(*)(int, ...))(float) + // 1) float 类型作为内部函数返回类型 + // 2) 构建返回 float 的函数类型,无参数(或者参数为空) + scc_ast_type_t func_ret_float; + scc_ast_type_function_init( + &func_ret_float, (scc_ast_type_t *)&scc_ast_builtin_type_float, + NULL); + + // 3) 指针指向该函数 + scc_ast_type_t ptr_to_func_ret_float; + scc_ast_type_pointer_init(&ptr_to_func_ret_float, &func_ret_float); + + // 4) 外层函数类型,返回上述指针,参数为 (int, ...) + scc_ast_decl_t param_int, param_var; + scc_ast_decl_param_init( + ¶m_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); + scc_ast_type_t va_list_type; + _scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST); + scc_ast_decl_param_init(¶m_var, &va_list_type, null); + scc_ast_decl_vec_t params_outer; + scc_vec_init(params_outer); + scc_vec_push(params_outer, ¶m_int); + scc_vec_push(params_outer, ¶m_var); + + scc_ast_type_t outer_func; + scc_ast_type_function_init(&outer_func, &ptr_to_func_ret_float, + ¶ms_outer); + + // 5) 指针指向外层函数 + scc_ast_type_t ptr_to_outer_func; + scc_ast_type_pointer_init(&ptr_to_outer_func, &outer_func); + SCC_CHECK_AST(&ptr_to_outer_func.base, "int (*(*)(int, ...))(float)", + _scc_parse_type); + } +} + TEST_LIST = { {"parser_unit", test_parser_unit}, {"parser_expression", test_parser_expression}, + {"parser_type", test_parser_type}, + // {"parser_statement", test_parser_statement}, + // {"parser_declaration", test_parser_declaration}, + // {"parser_translation_unit", test_parser_translation_unit}, {null, null}, }; \ No newline at end of file diff --git a/runtime/scc_core/include/scc_core_vec.h b/runtime/scc_core/include/scc_core_vec.h index 7600542..a50ba89 100644 --- a/runtime/scc_core/include/scc_core_vec.h +++ b/runtime/scc_core/include/scc_core_vec.h @@ -150,7 +150,7 @@ typedef size_t usize; (vec).size = (vec).cap = 0; \ } while (0) -#define scc_vec_unsafe_from_static_array(vec, array) \ +#define scc_vec_unsafe_from_array(vec, array) \ do { \ (vec).size = sizeof(array) / sizeof((array)[0]); \ (vec).cap = (vec).size; \ diff --git a/tests/simple/06_fcall.c b/tests/simple/06_fcall.c index 18f817c..546d677 100644 --- a/tests/simple/06_fcall.c +++ b/tests/simple/06_fcall.c @@ -1,9 +1,5 @@ -int add(int, int); +int add(int a, int b); -int main(void) { - return add(1, 2); -} +int main(void) { return add(1, 2); } -int add(int a, int b) { - return a + b; -} +int add(int a, int b) { return a + b; } diff --git a/tests/simple/11_recursive.c b/tests/simple/11_recursive.c index e526db0..604278c 100644 --- a/tests/simple/11_recursive.c +++ b/tests/simple/11_recursive.c @@ -1,6 +1,6 @@ // #include -int factorial(int num); +int factorial(int); int main() { int num = 5; @@ -13,6 +13,6 @@ int factorial(int num) { if (num == 0) { return 1; } else { - return num * factorial(num - 1); + return num * factorial(num + -1); } }