diff --git a/libs/ast/include/ast_builtin.h b/libs/ast/include/ast_builtin.h new file mode 100644 index 0000000..ec61424 --- /dev/null +++ b/libs/ast/include/ast_builtin.h @@ -0,0 +1,30 @@ +#ifndef __SCC_AST_BUILTIN_H__ +#define __SCC_AST_BUILTIN_H__ + +#include "ast_def.h" + +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_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_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 4c1ad3d..da2b2d7 100644 --- a/libs/ast/include/ast_def.h +++ b/libs/ast/include/ast_def.h @@ -108,6 +108,7 @@ typedef enum { 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; /** @@ -148,14 +149,13 @@ typedef SCC_VEC(scc_ast_node_t *) scc_ast_block_item_vec_t; */ struct scc_ast_type { scc_ast_node_t base; + scc_ast_decl_specifier_t quals; union { struct { scc_ast_builtin_type_t type; - scc_ast_decl_specifier_t quals; } builtin; struct { scc_ast_type_t *pointee; - scc_ast_decl_specifier_t quals; } pointer; struct { scc_ast_type_t *element; @@ -163,8 +163,7 @@ struct scc_ast_type { } array; struct { scc_ast_type_t *return_type; - scc_ast_type_vec_t param_types; - cbool is_variadic; // va_arg <=> ... + scc_ast_decl_vec_t param_types; // va_list <=> ... } function; struct { const char *name; @@ -269,7 +268,8 @@ struct scc_ast_expr { } cond; // 函数调用 struct { - scc_ast_expr_t *callee; + const char *name; + scc_ast_expr_t *_target; scc_ast_expr_vec_t args; } call; // 数组下标 @@ -277,16 +277,12 @@ struct scc_ast_expr { scc_ast_expr_t *array; scc_ast_expr_t *index; } subscript; - // 成员访问 + // 成员访问 指针成员访问 struct { scc_ast_expr_t *base; - const char *member_name; + const char *name; + usize _target_idx; } member; - // 指针成员访问 - struct { - scc_ast_expr_t *base; - const char *member_name; - } ptr_member; // 类型转换 struct { scc_ast_type_t *type; @@ -310,6 +306,7 @@ struct scc_ast_expr { // 标识符 struct { const char *name; + scc_ast_decl_t *_target; } identifier; }; }; @@ -334,21 +331,16 @@ struct scc_ast_stmt { scc_ast_stmt_t *then_stmt; scc_ast_stmt_t *opt_else_stmt; // stmt or null } if_stmt; - // while 语句 + // while do-while 语句 struct { scc_ast_expr_t *cond; scc_ast_stmt_t *body; } while_stmt; - // do-while 语句 - struct { - scc_ast_stmt_t *body; - scc_ast_expr_t *cond; - } do_while_stmt; // for 语句 struct { scc_ast_type_t *init; // expr or decl or null scc_ast_expr_t *cond; // 可为 null - scc_ast_expr_t *iter; // 可为 null + scc_ast_expr_t *incr; // 可为 null scc_ast_stmt_t *body; } for_stmt; // switch 语句 @@ -367,15 +359,15 @@ struct scc_ast_stmt { } default_stmt; // break/continue struct { - // 无额外字段 } jump; // return 语句 struct { - scc_ast_expr_t *expr; // 可为 NULL + scc_ast_expr_t *expr; // 可为 null } return_stmt; // goto 语句 struct { const char *label; + scc_ast_stmt_t *_target; // fill by sema } goto_stmt; // 标签语句 struct { @@ -390,37 +382,32 @@ struct scc_ast_stmt { */ struct scc_ast_decl { scc_ast_node_t base; + const char *name; union { // 变量声明 struct { - const char *name; scc_ast_type_t *type; scc_ast_expr_t *init; // 可为 NULL } var; // 函数声明 struct { - const char *name; scc_ast_type_t *type; // 函数类型 scc_ast_stmt_t *body; // 可为 null 表示只有声明 } func; // 参数声明 struct { - const char *name; scc_ast_type_t *type; } param; // 结构体/联合声明 struct { - const char *name; scc_ast_decl_vec_t fields; } record; // 枚举声明 struct { - const char *name; scc_ast_expr_vec_t enumerators; } enumeration; // typedef 声明 struct { - const char *name; scc_ast_type_t *type; } typedef_decl; }; diff --git a/libs/ast/include/scc_ast.h b/libs/ast/include/scc_ast.h index 7d6d56c..c484961 100644 --- a/libs/ast/include/scc_ast.h +++ b/libs/ast/include/scc_ast.h @@ -1,7 +1,416 @@ #ifndef __SCC_AST_H__ #define __SCC_AST_H__ +#include "ast_builtin.h" #include "ast_def.h" #include "ast_dump.h" +// decls can be null but maybe warning +static inline void +scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit, + scc_ast_decl_vec_t *decls) { + Assert(translation_unit != null); + translation_unit->base.type = SCC_AST_TRANSLATION_UNIT; + translation_unit->base.loc = scc_pos_create(); + if (decls == null) { + scc_vec_init(translation_unit->declarations); + } else { + translation_unit->declarations = *decls; + scc_vec_init(*decls); + } +} + +// var_init can be null +static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl, + scc_ast_type_t *type, const char *name, + scc_ast_expr_t *var_init) { + Assert(decl != null && name != null && type != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_VAR; + decl->name = name; + decl->var.type = type; + decl->var.init = var_init; +} + +// body can be null +static inline void scc_ast_decl_func_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); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_FUNC; + decl->name = name; + decl->func.type = type; + Assert(type->base.type == SCC_AST_TYPE_FUNCTION); + decl->func.body = body; +} + +// body 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); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_PARAM; + decl->name = name; + decl->param.type = type; +} + +// fields can be null +static inline void scc_ast_decl_struct_init(scc_ast_decl_t *decl, + const char *name, + scc_ast_decl_vec_t *fields_move) { + Assert(decl != null && name != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_STRUCT; + decl->name = name; + if (fields_move == null) { + scc_vec_init(decl->record.fields); + } else { + decl->record.fields = *fields_move; + scc_vec_init(*fields_move); + } +} + +// fields can be null +static inline void scc_ast_decl_union_init(scc_ast_decl_t *decl, + const char *name, + scc_ast_decl_vec_t *fields_move) { + Assert(decl != null && name != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_UNION; + decl->name = name; + if (fields_move == null) { + scc_vec_init(decl->record.fields); + } else { + decl->record.fields = *fields_move; + scc_vec_init(*fields_move); + } +} + +// fields can be null +static inline void scc_ast_decl_enum_init(scc_ast_decl_t *decl, + const char *name, + scc_ast_expr_vec_t *fields_move) { + Assert(decl != null && name != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_ENUM; + decl->name = name; + if (fields_move == null) { + scc_vec_init(decl->enumeration.enumerators); + } else { + decl->enumeration.enumerators = *fields_move; + scc_vec_init(*fields_move); + } +} + +static inline void scc_ast_decl_typedef_init(scc_ast_decl_t *decl, + const char *name, + scc_ast_type_t *type) { + Assert(decl != null && name != null && type != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_TYPEDEF; + decl->name = name; + decl->typedef_decl.type = type; +} + +// items can be null +static inline void +scc_ast_stmt_compound_init(scc_ast_stmt_t *stmt, + scc_ast_block_item_vec_t *items_move) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_COMPOUND; + if (items_move == null) { + scc_vec_init(stmt->compound.block_items); + } else { + stmt->compound.block_items = *items_move; + scc_vec_init(*items_move); + } +} + +// expr can be null +static inline void scc_ast_stmt_expr_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *expr) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_EXPR; + stmt->expr.expr = expr; +} + +// opt_else can be null +static inline void scc_ast_stmt_if_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *cond, + scc_ast_stmt_t *then, + scc_ast_stmt_t *opt_else) { + Assert(stmt != null && cond != null && then != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_IF; + stmt->if_stmt.cond = cond; + stmt->if_stmt.then_stmt = then; + stmt->if_stmt.opt_else_stmt = opt_else; +} + +static inline void scc_ast_stmt_while_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *cond, + scc_ast_stmt_t *body) { + Assert(stmt != null && cond != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_WHILE; + stmt->while_stmt.cond = cond; + stmt->while_stmt.body = body; +} + +static inline void scc_ast_stmt_do_while_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *cond, + scc_ast_stmt_t *body) { + Assert(stmt != null && cond != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_DO_WHILE; + stmt->while_stmt.cond = cond; + stmt->while_stmt.body = body; +} + +// FIXME +static inline void scc_ast_stmt_for_init(scc_ast_stmt_t *stmt, + scc_ast_type_t *init, + scc_ast_expr_t *cond, + scc_ast_expr_t *incr, + scc_ast_stmt_t *body) { + Assert(stmt != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_FOR; + stmt->for_stmt.init = init; + stmt->for_stmt.cond = cond; + stmt->for_stmt.incr = incr; + stmt->for_stmt.body = body; +} + +static inline void scc_ast_stmt_switch_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *cond, + scc_ast_stmt_t *body) { + Assert(stmt != null && cond != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_SWITCH; + stmt->switch_stmt.cond = cond; + stmt->switch_stmt.body = body; +} + +static inline void scc_ast_stmt_case_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *cond, + scc_ast_stmt_t *body) { + Assert(stmt != null && cond != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_CASE; + stmt->case_stmt.expr = cond; + stmt->case_stmt.stmt = body; +} + +static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt, + scc_ast_stmt_t *body) { + Assert(stmt != null && body != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_DEFAULT; + stmt->case_stmt.stmt = body; +} + +static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_BREAK; +} + +static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_CONTINUE; +} + +// expr can be null +static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt, + scc_ast_expr_t *expr) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_RETURN; + stmt->return_stmt.expr = expr; +} + +static inline void scc_ast_stmt_goto_init(scc_ast_stmt_t *stmt, + const char *label) { + Assert(stmt != null && label != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_GOTO; + stmt->goto_stmt.label = label; + stmt->goto_stmt._target = null; +} + +static inline void scc_ast_stmt_label_init(scc_ast_stmt_t *stmt, + const char *label, + scc_ast_stmt_t *body) { + Assert(stmt != null); + stmt->base.loc = scc_pos_create(); + stmt->base.type = SCC_AST_STMT_LABEL; + stmt->label_stmt.label = label; + stmt->label_stmt.stmt = body; +} + +static inline void scc_ast_expr_binary_init(scc_ast_expr_t *expr, + scc_ast_expr_op_t op, + scc_ast_expr_t *lhs, + scc_ast_expr_t *rhs) { + Assert(expr != null && lhs != null && rhs != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_BINARY; + expr->binary.op = op; + expr->binary.lhs = lhs; + expr->binary.rhs = rhs; +} + +static inline void scc_ast_expr_unary_init(scc_ast_expr_t *expr, + scc_ast_expr_op_t op, + scc_ast_expr_t *operand) { + Assert(expr != null && operand != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_UNARY; + expr->unary.op = op; + expr->unary.operand = operand; +} + +static inline void scc_ast_expr_cond_init(scc_ast_expr_t *expr, + scc_ast_expr_t *cond, + scc_ast_expr_t *then_expr, + scc_ast_expr_t *else_expr) { + Assert(expr != null && cond != null && then_expr != null && + else_expr != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_COND; + expr->cond.cond = cond; + expr->cond.then_expr = then_expr; + expr->cond.else_expr = else_expr; +} + +// args can be null +static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr, + const char *name, + scc_ast_expr_vec_t *args) { + Assert(expr != null && name != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_CALL; + expr->call.name = name; + expr->call._target = null; + if (args == null) { + scc_vec_init(expr->call.args); + } else { + expr->call.args = *args; + } +} + +// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标 +static inline void scc_ast_expr_array_subscript_init(scc_ast_expr_t *expr, + scc_ast_expr_t *array, + scc_ast_expr_t *index) { + Assert(expr != null && array != null && index != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT; + expr->subscript.array = array; + expr->subscript.index = index; +} + +static inline void _scc_ast_expr_member_init(scc_ast_expr_t *expr, + scc_ast_node_type_t type, + scc_ast_expr_t *object, + const char *member) { + Assert(expr != null && object != null && member != null); + expr->base.loc = scc_pos_create(); + expr->base.type = type; + expr->member.base = object; + expr->member.name = member; + expr->member._target_idx = 0; +} + +static inline void scc_ast_expr_member_init(scc_ast_expr_t *expr, + scc_ast_expr_t *object, + const char *member) { + _scc_ast_expr_member_init(expr, SCC_AST_EXPR_MEMBER, object, member); +} + +static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr, + scc_ast_expr_t *object, + const char *member) { + _scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member); +} + +// SCC_AST_EXPR_CAST, // 类型转换 +// SCC_AST_EXPR_SIZE_OF, // sizeof +// SCC_AST_EXPR_ALIGN_OF, // _Alignof +// SCC_AST_EXPR_COMPOUND_LITERAL, // 复合字面量 + +static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr, + scc_ast_node_type_t type, + const char *value, cbool owned) { + Assert(expr != null && value != null); + expr->base.loc = scc_pos_create(); + expr->base.type = type; + expr->literal.lexme = value; + expr->literal.owned = owned; +} + +static inline void scc_ast_expr_literal_int_init(scc_ast_expr_t *expr, + const char *value, + cbool owned) { + scc_ast_expr_literal_init(expr, SCC_AST_EXPR_INT_LITERAL, value, owned); +} + +static inline void scc_ast_expr_literal_float_init(scc_ast_expr_t *expr, + const char *value, + cbool owned) { + scc_ast_expr_literal_init(expr, SCC_AST_EXPR_FLOAT_LITERAL, value, owned); +} +static inline void scc_ast_expr_literal_char_init(scc_ast_expr_t *expr, + const char *value, + cbool owned) { + scc_ast_expr_literal_init(expr, SCC_AST_EXPR_CHAR_LITERAL, value, owned); +} +static inline void scc_ast_expr_literal_string_init(scc_ast_expr_t *expr, + const char *value, + cbool owned) { + scc_ast_expr_literal_init(expr, SCC_AST_EXPR_STRING_LITERAL, value, owned); +} + +static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr, + const char *name) { + Assert(expr != null && name != null); + expr->base.loc = scc_pos_create(); + expr->base.type = SCC_AST_EXPR_IDENTIFIER; + expr->identifier.name = name; + expr->identifier._target = null; +} + +// SCC_AST_TYPE_BUILTIN, // 内置类型 +// SCC_AST_TYPE_POINTER, // 指针类型 +// SCC_AST_TYPE_ARRAY, // 数组类型 + +// return_type and params can be null +static inline void scc_ast_type_function_init(scc_ast_type_t *type, + scc_ast_type_t *return_type, + scc_ast_decl_vec_t *params) { + Assert(type != null); + type->base.loc = scc_pos_create(); + type->base.type = SCC_AST_TYPE_FUNCTION; + type->function.return_type = return_type; + if (params == null) { + scc_vec_init(type->function.param_types); + } else { + type->function.param_types = *params; + scc_vec_init(*params); + } +} + +// SCC_AST_TYPE_STRUCT, // 结构体类型 +// SCC_AST_TYPE_UNION, // 联合类型 +// SCC_AST_TYPE_ENUM, // 枚举类型 +// SCC_AST_TYPE_TYPEDEF, // typedef 类型 + #endif /* __SCC_AST_H__ */ diff --git a/libs/ast/src/ast_builtin.c b/libs/ast/src/ast_builtin.c new file mode 100644 index 0000000..e57d343 --- /dev/null +++ b/libs/ast/src/ast_builtin.c @@ -0,0 +1,70 @@ +#include + +#define SCC_AST_BUILTIN_TYPE_HEADER \ + .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 + +scc_ast_type_t scc_ast_builtin_type_int = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_INT, +}; + +scc_ast_type_t scc_ast_builtin_type_long = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_LONG, +}; + +scc_ast_type_t scc_ast_builtin_type_long_long = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_LONG_LONG, +}; + +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_char = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_CHAR, +}; + +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_float = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_FLOAT, +}; + +scc_ast_type_t scc_ast_builtin_type_double = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_DOUBLE, +}; + +scc_ast_type_t scc_ast_builtin_type_long_double = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_LONG_DOUBLE, +}; + +scc_ast_type_t scc_ast_builtin_type_complex_float = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT, +}; + +scc_ast_type_t scc_ast_builtin_type_complex_double = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE, +}; + +scc_ast_type_t scc_ast_builtin_type_complex_long_double = { + SCC_AST_BUILTIN_TYPE_HEADER, + .builtin.type = SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE, +}; diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index d2b946a..c8bd9df 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -324,7 +324,12 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { } if (scc_vec_size(type->function.param_types) != 0) { scc_vec_foreach(type->function.param_types, i) { - dump_type_impl(scc_vec_at(type->function.param_types, i), ctx); + scc_ast_decl_t *param = + scc_vec_at(type->function.param_types, i); + if (param->name) { + // FIXME param name + } + dump_type_impl(param->param.type, ctx); } } else { start_node_dump(&type->base, ctx); @@ -435,7 +440,8 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) { break; case SCC_AST_EXPR_CALL: - dump_child_node((scc_ast_node_t *)expr->call.callee, ctx, false); + // dump_child_node((scc_ast_node_t *)expr->call._target, ctx, false); + PRINT_NODE(ctx, "%s", expr->call.name); // 转储参数 for (size_t i = 0; i < expr->call.args.size; i++) { dump_child_node((scc_ast_node_t *)expr->call.args.data[i], ctx, @@ -453,7 +459,7 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) { dump_child_node((scc_ast_node_t *)expr->member.base, ctx, false); // 打印成员访问信息 scc_tree_print_indent(ctx); - PRINT_NODE(ctx, "Member [\"%s\"]", expr->member.member_name); + PRINT_NODE(ctx, "Member [\"%s\"]", expr->member.name); scc_tree_dump_printf(ctx, "\n"); break; @@ -512,8 +518,8 @@ static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_tree_dump_ctx_t *ctx) { return; case SCC_AST_STMT_DO_WHILE: end_node_dump(ctx); - dump_child_node((scc_ast_node_t *)stmt->do_while_stmt.body, ctx, false); - dump_child_node((scc_ast_node_t *)stmt->do_while_stmt.cond, ctx, true); + dump_child_node((scc_ast_node_t *)stmt->while_stmt.body, ctx, false); + dump_child_node((scc_ast_node_t *)stmt->while_stmt.cond, ctx, true); return; case SCC_AST_STMT_SWITCH: end_node_dump(ctx); @@ -528,8 +534,8 @@ static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_tree_dump_ctx_t *ctx) { if (stmt->for_stmt.cond) { dump_child_node((scc_ast_node_t *)stmt->for_stmt.cond, ctx, false); } - if (stmt->for_stmt.iter) { - dump_child_node((scc_ast_node_t *)stmt->for_stmt.iter, ctx, false); + if (stmt->for_stmt.incr) { + dump_child_node((scc_ast_node_t *)stmt->for_stmt.incr, ctx, false); } dump_child_node((scc_ast_node_t *)stmt->for_stmt.body, ctx, true); return; @@ -594,46 +600,8 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { return; start_node_dump(&decl->base, ctx); - - // 根据声明类型输出特定信息 - switch (decl->base.type) { - case SCC_AST_DECL_VAR: - if (decl->var.name) { - PRINT_QUOTED_VALUE(ctx, decl->var.name); - } - break; - case SCC_AST_DECL_FUNC: - if (decl->func.name) { - PRINT_QUOTED_VALUE(ctx, decl->func.name); - } - break; - case SCC_AST_DECL_PARAM: - if (decl->param.name) { - PRINT_QUOTED_VALUE(ctx, decl->param.name); - } - break; - case SCC_AST_DECL_STRUCT: - if (decl->record.name) { - PRINT_QUOTED_VALUE(ctx, decl->record.name); - } - break; - case SCC_AST_DECL_UNION: - if (decl->record.name) { - PRINT_QUOTED_VALUE(ctx, decl->record.name); - } - break; - case SCC_AST_DECL_ENUM: - if (decl->enumeration.name) { - PRINT_QUOTED_VALUE(ctx, decl->enumeration.name); - } - break; - case SCC_AST_DECL_TYPEDEF: - if (decl->typedef_decl.name) { - PRINT_QUOTED_VALUE(ctx, decl->typedef_decl.name); - } - break; - default: - break; + if (decl->name) { + PRINT_QUOTED_VALUE(ctx, decl->name); } end_node_dump(ctx); diff --git a/libs/ast/src/scc_ast.c b/libs/ast/src/scc_ast.c deleted file mode 100644 index e69de29..0000000 diff --git a/libs/lexer/tests/test_lexer.c b/libs/lexer/tests/test_lexer.c index b98be2e..1cf00ab 100644 --- a/libs/lexer/tests/test_lexer.c +++ b/libs/lexer/tests/test_lexer.c @@ -293,7 +293,7 @@ void test_identifiers() { // 超长标识符(假设缓冲区足够) char long_id[1024]; - memset(long_id, 'a', sizeof(long_id) - 1); + scc_memset(long_id, 'a', sizeof(long_id) - 1); long_id[sizeof(long_id) - 1] = '\0'; TEST_TOKEN(long_id, SCC_TOK_IDENT); } diff --git a/libs/parser/src/parse_decl.c b/libs/parser/src/parse_decl.c index 7375791..8ef339e 100644 --- a/libs/parser/src/parse_decl.c +++ b/libs/parser/src/parse_decl.c @@ -188,7 +188,6 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { } scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t)); - /* (6.7.5) declarator: pointeropt direct-declarator @@ -203,18 +202,14 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { direct-declarator ( identifier-listopt ) */ if (!scc_parser_consume_if(parser, SCC_TOK_L_PAREN)) { - // TODO if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { - decl->base.type = SCC_AST_DECL_VAR; - decl->var.type = type; - decl->var.name = scc_cstring_as_cstr(&tok.lexeme); - decl->var.init = null; + 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)) { - decl->base.type = SCC_AST_DECL_VAR; - decl->var.type = type; - decl->var.name = scc_cstring_as_cstr(&tok.lexeme); - decl->var.init = scc_parse_expression(parser); + scc_ast_expr_t *init = scc_parse_expression(parser); + scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme), + init); goto RETURN; } // TODO @@ -223,13 +218,11 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { // function decl decl->base.type = SCC_AST_DECL_FUNC; - decl->func.name = scc_cstring_as_cstr(&tok.lexeme); + 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 - decl->func.type->function.is_variadic = false; // TODO param type scc_parser_consume_if(parser, SCC_TOK_VOID); diff --git a/libs/parser/src/parse_expr.c b/libs/parser/src/parse_expr.c index 6a9a58a..5b8f196 100644 --- a/libs/parser/src/parse_expr.c +++ b/libs/parser/src/parse_expr.c @@ -760,7 +760,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) { scc_lexer_tok_drop(&lp); scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL); - call->call.callee = left; + call->call._target = left; scc_vec_init(call->call.args); // 解析参数列表 @@ -811,13 +811,9 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) { scc_ast_expr_t *member = expr_create( parser, op_tok.type == SCC_TOK_DOT ? SCC_AST_EXPR_MEMBER : SCC_AST_EXPR_PTR_MEMBER); - if (op_tok.type == SCC_TOK_DOT) { - member->member.base = left; - member->member.member_name = name; - } else { - member->ptr_member.base = left; - member->ptr_member.member_name = name; - } + member->member.base = left; + member->member.name = name; + scc_lexer_tok_drop(&op_tok); left = member; break; diff --git a/libs/parser/src/parse_stmt.c b/libs/parser/src/parse_stmt.c index 8628636..62ba1fb 100644 --- a/libs/parser/src/parse_stmt.c +++ b/libs/parser/src/parse_stmt.c @@ -51,9 +51,9 @@ A.2.3 Statements #include static inline scc_ast_stmt_t *ast_stmt_alloc() { scc_ast_stmt_t *stmt = (scc_ast_stmt_t *)scc_malloc(sizeof(scc_ast_stmt_t)); - Assert(stmt != null); - stmt->base.type = SCC_AST_UNKNOWN; - stmt->base.loc = scc_pos_create(); + if (stmt == null) { + LOG_FATAL("Out of memory"); + } return stmt; } @@ -87,10 +87,7 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser) { scc_ast_stmt_t *stmt = ast_stmt_alloc(); Assert(stmt != null); - - stmt->base.type = SCC_AST_STMT_LABEL; - stmt->label_stmt.label = scc_cstring_as_cstr(&tok.lexeme); - stmt->label_stmt.stmt = statement; + scc_ast_stmt_label_init(stmt, scc_cstring_as_cstr(&tok.lexeme), statement); return stmt; } @@ -113,10 +110,7 @@ static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser) { } scc_ast_stmt_t *stmt = ast_stmt_alloc(); - Assert(stmt != null); - stmt->case_stmt.expr = expr; - stmt->base.type = SCC_AST_STMT_CASE; - stmt->case_stmt.stmt = statement; + scc_ast_stmt_case_init(stmt, expr, statement); return stmt; } @@ -134,11 +128,9 @@ static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser) { if (statement == null) { Panic("expect stmt"); } - scc_ast_stmt_t *stmt = ast_stmt_alloc(); - Assert(stmt != null); - stmt->base.type = SCC_AST_STMT_DEFAULT; - stmt->default_stmt.stmt = statement; + scc_ast_stmt_t *stmt = ast_stmt_alloc(); + scc_ast_stmt_default_init(stmt, statement); return stmt; } @@ -146,10 +138,9 @@ static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser) { if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACE)) { return null; } - scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_COMPOUND; + scc_ast_block_item_vec_t block_items; + scc_vec_init(block_items); - scc_vec_init(stmt->compound.block_items); while (!scc_parser_consume_if(parser, SCC_TOK_R_BRACE)) { /// TODO // scc_parse_is_decl(); @@ -160,12 +151,15 @@ static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser) { } if (ret == null) { LOG_ERROR("Invalid statement"); - // TODO - scc_free(stmt); + // TODO free + parser->errcode = 1; return null; } - scc_vec_push(stmt->compound.block_items, ret); + scc_vec_push(block_items, ret); } + + scc_ast_stmt_t *stmt = ast_stmt_alloc(); + scc_ast_stmt_compound_init(stmt, &block_items); return stmt; } @@ -176,16 +170,16 @@ static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser) { scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_stmt_t *statement = scc_parse_statement(parser); + scc_ast_stmt_t *opt_else = null; + + if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) { + opt_else = scc_parse_statement(parser); + } else { + opt_else = null; + } scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_IF; - stmt->if_stmt.cond = expression; - stmt->if_stmt.then_stmt = statement; - if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) { - stmt->if_stmt.opt_else_stmt = scc_parse_statement(parser); - } else { - stmt->if_stmt.opt_else_stmt = null; - } + scc_ast_stmt_if_init(stmt, expression, statement, opt_else); return stmt; } @@ -198,9 +192,7 @@ static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser) { scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_SWITCH; - stmt->switch_stmt.cond = expression; - stmt->switch_stmt.body = statement; + scc_ast_stmt_switch_init(stmt, expression, statement); return stmt; } @@ -213,9 +205,7 @@ static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser) { scc_ast_stmt_t *statement = scc_parse_statement(parser); scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_WHILE; - stmt->while_stmt.cond = expression; - stmt->while_stmt.body = statement; + scc_ast_stmt_while_init(stmt, expression, statement); return stmt; } @@ -235,9 +225,7 @@ static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser) { scc_ast_expr_t *expression = ast_parse_paren_expression(parser); scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_DO_WHILE; - stmt->do_while_stmt.cond = expression; - stmt->do_while_stmt.body = statement; + scc_ast_stmt_do_while_init(stmt, expression, statement); return stmt; } @@ -255,15 +243,17 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) { LOG_ERROR("Expected '(' before like `( expression )` ."); } - scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_FOR; + scc_ast_type_t *init = null; + scc_ast_expr_t *cond = null; + scc_ast_expr_t *incr = null; + scc_ast_stmt_t *body = null; // TODO use decl or expr - stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_expression(parser); - if (stmt->for_stmt.init == null) { - stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_declaration(parser); + init = (scc_ast_type_t *)scc_parse_expression(parser); + if (init == null) { + init = (scc_ast_type_t *)scc_parse_declaration(parser); } - if (stmt->for_stmt.init == null) { + if (init == null) { LOG_ERROR("Expected expression or declaration in for statement."); } @@ -271,20 +261,22 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) { LOG_ERROR("Expected semicolon in for statement."); } - stmt->for_stmt.cond = scc_parse_expression(parser); + cond = scc_parse_expression(parser); if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { LOG_ERROR("Expected semicolon in for statement."); } - stmt->for_stmt.iter = scc_parse_expression(parser); + incr = scc_parse_expression(parser); if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { LOG_ERROR("Expected ')' after like `( expression )` ."); } - stmt->for_stmt.body = scc_parse_statement(parser); + body = scc_parse_statement(parser); + scc_ast_stmt_t *stmt = ast_stmt_alloc(); + scc_ast_stmt_for_init(stmt, init, cond, incr, body); return stmt; } @@ -292,20 +284,18 @@ static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) { scc_ast_stmt_t *stmt = ast_stmt_alloc(); if (scc_parser_consume_if(parser, SCC_TOK_GOTO)) { - stmt->base.type = SCC_AST_STMT_GOTO; scc_lexer_tok_t tok = {0}; if (scc_parser_next_consume(parser, &tok)) { - stmt->goto_stmt.label = scc_cstring_as_cstr(&tok.lexeme); + scc_ast_stmt_goto_init(stmt, scc_cstring_as_cstr(&tok.lexeme)); } else { LOG_ERROR("Expected label after goto."); } } else if (scc_parser_consume_if(parser, SCC_TOK_CONTINUE)) { - stmt->base.type = SCC_AST_STMT_CONTINUE; + scc_ast_stmt_continue_init(stmt); } else if (scc_parser_consume_if(parser, SCC_TOK_BREAK)) { - stmt->base.type = SCC_AST_STMT_BREAK; + scc_ast_stmt_break_init(stmt); } else if (scc_parser_consume_if(parser, SCC_TOK_RETURN)) { - stmt->base.type = SCC_AST_STMT_RETURN; - stmt->return_stmt.expr = scc_parse_expression(parser); + scc_ast_stmt_return_init(stmt, scc_parse_expression(parser)); } else { UNREACHABLE(); } @@ -317,21 +307,19 @@ static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) { } static scc_ast_stmt_t *parse_expression_statement(scc_parser_t *parser) { - scc_ast_stmt_t *stmt = ast_stmt_alloc(); - stmt->base.type = SCC_AST_STMT_EXPR; if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { - stmt->expr.expr = null; - return stmt; - } - - stmt->expr.expr = scc_parse_expression(parser); - if (stmt->expr.expr == null) { - // TODO - scc_free(stmt); return null; } + scc_ast_expr_t *expr = scc_parse_expression(parser); + if (expr == null) { + return null; + } + + scc_ast_stmt_t *stmt = ast_stmt_alloc(); + scc_ast_stmt_expr_init(stmt, expr); + if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { LOG_ERROR("Expected semicolon after expression."); } diff --git a/libs/parser/src/parse_type.c b/libs/parser/src/parse_type.c index 6456a50..fa60ee3 100644 --- a/libs/parser/src/parse_type.c +++ b/libs/parser/src/parse_type.c @@ -234,7 +234,11 @@ cbool scc_parse_is_storage_class_start(scc_parser_t *parser) { return false; } } + scc_ast_type_t *scc_parse_type(scc_parser_t *parser) { + if (!scc_parse_is_decl_specifier_start(parser)) { + return null; + } const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); scc_ast_type_t *ret = null; if (tok_ptr->type == SCC_TOK_INT) { diff --git a/libs/parser/tests/test_parser_unit.c b/libs/parser/tests/test_parser_unit.c index 82bc31b..79b304d 100644 --- a/libs/parser/tests/test_parser_unit.c +++ b/libs/parser/tests/test_parser_unit.c @@ -17,7 +17,7 @@ static scc_ast_node_t *process_input(const char *input, scc_lexer_t lexer; scc_lexer_init(&lexer, scc_sstream_to_ring(&mem_stream)); - scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring(&lexer, 8, false); + scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring(&lexer, 64, false); scc_parser_t parser; scc_parser_init(&parser, tok_ring, null); @@ -69,516 +69,455 @@ static void dump2buffer(void *_buffer, const char *fmt, ...) { } while (0); static void test_parser_unit(void) { - scc_ast_decl_t int_decl = { - .base.type = SCC_AST_DECL_VAR, - .var.name = "a", - .var.init = null, - .var.type = &(scc_ast_type_t){.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = SCC_AST_BUILTIN_TYPE_INT}, - }; - SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration); - - scc_ast_decl_t func_decl = { - .base.type = SCC_AST_DECL_FUNC, - .func.name = "main", - .func.body = - &(scc_ast_stmt_t){ - .base.type = SCC_AST_STMT_COMPOUND, - .compound.block_items = {0}, - }, - .func.type = - &(scc_ast_type_t){ - .base.type = SCC_AST_TYPE_FUNCTION, - .function.is_variadic = false, - .function.param_types = {0}, - .function.return_type = - &(scc_ast_type_t){.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = SCC_AST_BUILTIN_TYPE_INT}, - }, - }; - SCC_CHECK_AST(&func_decl.base, "int main(void) {}", scc_parse_declaration); - - scc_ast_decl_t *decls[] = {&func_decl}; - scc_ast_translation_unit_t tu = { - .base.type = SCC_AST_TRANSLATION_UNIT, - .declarations.data = decls, - .declarations.cap = 1, - .declarations.size = 1, - }; - SCC_CHECK_AST(&tu.base, "int main(void) {}", scc_parse_translation_unit); - // SCC_CHECK_AST(&func_decl.base, "int main(void);", scc_parse_declaration); - + // 1. 变量声明 int a; { - scc_ast_node_t *items[] = { - (scc_ast_node_t *)&(scc_ast_stmt_t){ - .base.type = SCC_AST_STMT_RETURN, - .return_stmt.expr = - &(scc_ast_expr_t){ - .base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "65536", - }, - }, - }; - scc_ast_decl_t func_decl = { - .base.type = SCC_AST_DECL_FUNC, - .func.name = "main", - .func.body = - &(scc_ast_stmt_t){ - .base.type = SCC_AST_STMT_COMPOUND, - .compound.block_items.cap = 1, - .compound.block_items.size = 1, - .compound.block_items.data = items, - }, - .func.type = - &(scc_ast_type_t){ - .base.type = SCC_AST_TYPE_FUNCTION, - .function.is_variadic = false, - .function.param_types = {0}, - .function.return_type = - &(scc_ast_type_t){.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = - SCC_AST_BUILTIN_TYPE_INT}, - }, - }; - scc_ast_decl_t *decls[] = {&func_decl}; - scc_ast_translation_unit_t tu = { - .base.type = SCC_AST_TRANSLATION_UNIT, - .declarations.cap = 1, - .declarations.size = 1, - .declarations.data = decls, - }; + scc_ast_decl_t int_decl; + scc_ast_decl_val_init( + &int_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null); + SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration); + } + + // 2. 函数声明 int main(void) {} + { + // 构造函数类型:返回 int,参数为空 + scc_ast_type_t func_type; + scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, + null); // 无参数,非可变参数 + + // 构造复合语句块(空) + scc_ast_stmt_t compound; + scc_ast_stmt_compound_init(&compound, null); + + // 构造函数声明 + scc_ast_decl_t func_decl; + scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); + + SCC_CHECK_AST(&func_decl.base, "int main(void) {}", + scc_parse_declaration); + } + + // 3. 翻译单元包含一个函数定义 + { + scc_ast_type_t func_type; + scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null); + + scc_ast_stmt_t compound; + scc_ast_stmt_compound_init(&compound, null); + + scc_ast_decl_t func_decl; + scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); + + // 构造翻译单元 + scc_ast_decl_vec_t tu_decls; + scc_vec_init(tu_decls); + scc_vec_push(tu_decls, &func_decl); + + scc_ast_translation_unit_t tu; + scc_ast_translation_unit_init(&tu, &tu_decls); + + SCC_CHECK_AST(&tu.base, "int main(void) {}", + scc_parse_translation_unit); + } + + // 4. 带返回语句的函数 int main(void) { return 65536; } + { + // 返回语句中的整数常量 + scc_ast_expr_t ret_val; + scc_ast_expr_literal_int_init(&ret_val, "65536", false); + + scc_ast_stmt_t ret_stmt; + scc_ast_stmt_return_init(&ret_stmt, &ret_val); + + // 复合语句包含该返回语句 + scc_ast_block_item_vec_t items; + scc_vec_init(items); + scc_vec_push(items, (scc_ast_node_t *)&ret_stmt); + + scc_ast_stmt_t compound; + scc_ast_stmt_compound_init(&compound, &items); // items 被移动 + + // 函数类型 + scc_ast_type_t func_type; + scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null); + + scc_ast_decl_t func_decl; + scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); + + scc_ast_decl_vec_t tu_decls; + scc_vec_init(tu_decls); + scc_vec_push(tu_decls, &func_decl); + + scc_ast_translation_unit_t tu; + scc_ast_translation_unit_init(&tu, &tu_decls); + SCC_CHECK_AST(&tu.base, "int main(void) { return 65536; }", scc_parse_translation_unit); } + // 5. 多语句函数(复杂示例) { - // 修复后的测试用例:正确表示多语句函数 - // 创建变量声明: int a; - scc_ast_type_t a_type = {.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = SCC_AST_BUILTIN_TYPE_INT}; - scc_ast_decl_t a_decl = {.base.type = SCC_AST_DECL_VAR, - .var.name = "a", - .var.type = &a_type}; + // 变量声明 int a; + scc_ast_decl_t a_decl; + scc_ast_decl_val_init(&a_decl, &scc_ast_builtin_type_int, "a", null); - // 创建变量声明: int b; - scc_ast_type_t b_type = {.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = SCC_AST_BUILTIN_TYPE_INT}; - scc_ast_decl_t b_decl = {.base.type = SCC_AST_DECL_VAR, - .var.name = "b", - .var.type = &b_type}; + // 变量声明 int b; + scc_ast_decl_t b_decl; + scc_ast_decl_val_init(&b_decl, &scc_ast_builtin_type_int, "b", null); - // 创建表达式: 1 + 2 * 3 - scc_ast_expr_t expr1_3 = {.base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "3"}; - scc_ast_expr_t expr1_2 = {.base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "2"}; - scc_ast_expr_t expr1_mul = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_MUL, - .binary.lhs = &expr1_2, - .binary.rhs = &expr1_3}; - scc_ast_expr_t expr1_1 = {.base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "1"}; - scc_ast_expr_t expr1_add = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_ADD, - .binary.lhs = &expr1_1, - .binary.rhs = &expr1_mul}; + // 表达式 1 + 2 * 3 + scc_ast_expr_t lit1, lit2, lit3, mul, add; + scc_ast_expr_literal_int_init(&lit1, "1", false); + scc_ast_expr_literal_int_init(&lit2, "2", false); + scc_ast_expr_literal_int_init(&lit3, "3", false); + scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &lit2, &lit3); + scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &lit1, &mul); - // 创建赋值语句: a = 1 + 2 * 3; - scc_ast_expr_t a_expr1 = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "a"}; - scc_ast_expr_t assign1 = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_ASSIGN, - .binary.lhs = &a_expr1, - .binary.rhs = &expr1_add}; - scc_ast_stmt_t assign1_stmt = {.base.type = SCC_AST_STMT_EXPR, - .expr.expr = &assign1}; + // 赋值 a = 1 + 2 * 3; + scc_ast_expr_t a_ref1, assign1; + scc_ast_expr_identifier_init(&a_ref1, "a"); + scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a_ref1, &add); + scc_ast_stmt_t assign1_stmt; + scc_ast_stmt_expr_init(&assign1_stmt, &assign1); - // 创建赋值语句: b = 7; - scc_ast_expr_t expr2_7 = {.base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "7"}; - scc_ast_expr_t b_expr1 = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "b"}; - scc_ast_expr_t assign2 = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_ASSIGN, - .binary.lhs = &b_expr1, - .binary.rhs = &expr2_7}; - scc_ast_stmt_t assign2_stmt = {.base.type = SCC_AST_STMT_EXPR, - .expr.expr = &assign2}; + // 赋值 b = 7; + scc_ast_expr_t lit7; + scc_ast_expr_literal_int_init(&lit7, "7", false); + scc_ast_expr_t b_ref1, assign2; + scc_ast_expr_identifier_init(&b_ref1, "b"); + scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &b_ref1, &lit7); + scc_ast_stmt_t assign2_stmt; + scc_ast_stmt_expr_init(&assign2_stmt, &assign2); - // 创建表达式: a - b + 1 - scc_ast_expr_t a_expr2 = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "a"}; - scc_ast_expr_t b_expr2 = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "b"}; - scc_ast_expr_t sub_expr = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_SUB, - .binary.lhs = &a_expr2, - .binary.rhs = &b_expr2}; - scc_ast_expr_t expr3_1 = {.base.type = SCC_AST_EXPR_INT_LITERAL, - .literal.lexme = "1"}; - scc_ast_expr_t add_expr = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_ADD, - .binary.lhs = &sub_expr, - .binary.rhs = &expr3_1}; + // 表达式 a - b + 1 + scc_ast_expr_t a_ref2, b_ref2, sub, add2, lit1_2; + scc_ast_expr_identifier_init(&a_ref2, "a"); + scc_ast_expr_identifier_init(&b_ref2, "b"); + scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a_ref2, &b_ref2); + scc_ast_expr_literal_int_init(&lit1_2, "1", false); + scc_ast_expr_binary_init(&add2, SCC_AST_OP_ADD, &sub, &lit1_2); - // 创建赋值语句: a = a - b + 1; - scc_ast_expr_t a_expr3 = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "a"}; - scc_ast_expr_t assign3 = {.base.type = SCC_AST_EXPR_BINARY, - .binary.op = SCC_AST_OP_ASSIGN, - .binary.lhs = &a_expr3, - .binary.rhs = &add_expr}; - scc_ast_stmt_t assign3_stmt = {.base.type = SCC_AST_STMT_EXPR, - .expr.expr = &assign3}; + // 赋值 a = a - b + 1; + scc_ast_expr_t a_ref3, assign3; + scc_ast_expr_identifier_init(&a_ref3, "a"); + scc_ast_expr_binary_init(&assign3, SCC_AST_OP_ASSIGN, &a_ref3, &add2); + scc_ast_stmt_t assign3_stmt; + scc_ast_stmt_expr_init(&assign3_stmt, &assign3); - // 创建return语句: return a; - scc_ast_expr_t return_expr = {.base.type = SCC_AST_EXPR_IDENTIFIER, - .identifier.name = "a"}; - scc_ast_stmt_t return_stmt = {.base.type = SCC_AST_STMT_RETURN, - .return_stmt.expr = &return_expr}; + // return a; + scc_ast_expr_t a_ref4; + scc_ast_expr_identifier_init(&a_ref4, "a"); + scc_ast_stmt_t ret_stmt; + scc_ast_stmt_return_init(&ret_stmt, &a_ref4); - // 创建复合语句块 - scc_ast_node_t *items[] = { - (scc_ast_node_t *)&a_decl, (scc_ast_node_t *)&b_decl, - (scc_ast_node_t *)&assign1_stmt, (scc_ast_node_t *)&assign2_stmt, - (scc_ast_node_t *)&assign3_stmt, (scc_ast_node_t *)&return_stmt}; + // 复合语句块,按顺序放入 + scc_ast_block_item_vec_t items; + scc_vec_init(items); + scc_vec_push(items, (scc_ast_node_t *)&a_decl); + scc_vec_push(items, (scc_ast_node_t *)&b_decl); + scc_vec_push(items, (scc_ast_node_t *)&assign1_stmt); + scc_vec_push(items, (scc_ast_node_t *)&assign2_stmt); + scc_vec_push(items, (scc_ast_node_t *)&assign3_stmt); + scc_vec_push(items, (scc_ast_node_t *)&ret_stmt); - scc_ast_type_t return_type = {.base.type = SCC_AST_TYPE_BUILTIN, - .builtin.type = SCC_AST_BUILTIN_TYPE_INT}; + scc_ast_stmt_t compound; + scc_ast_stmt_compound_init(&compound, &items); - scc_ast_type_t func_type = {.base.type = SCC_AST_TYPE_FUNCTION, - .function.is_variadic = false, - .function.param_types = {0}, - .function.return_type = &return_type}; + // 函数类型 + scc_ast_type_t func_type; + scc_ast_type_function_init( + &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); - scc_ast_decl_t func_decl = { - .base.type = SCC_AST_DECL_FUNC, - .func.name = "main", - .func.body = &(scc_ast_stmt_t){.base.type = SCC_AST_STMT_COMPOUND, - .compound.block_items.cap = 6, - .compound.block_items.size = 6, - .compound.block_items.data = items}, - .func.type = &func_type}; + scc_ast_decl_t func_decl; + scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); - scc_ast_decl_t *decls[] = {&func_decl}; - scc_ast_translation_unit_t tu = {.base.type = SCC_AST_TRANSLATION_UNIT, - .declarations.cap = 1, - .declarations.size = 1, - .declarations.data = decls}; + scc_ast_decl_vec_t tu_decls; + scc_vec_init(tu_decls); + scc_vec_push(tu_decls, &func_decl); - SCC_CHECK_AST(&tu.base, - "int main() {\n" - " int a;\n" - " int b;\n" - " a = 1 + 2 * 3;\n" - " b = 7;\n" - " a = a - b + 1;\n" - " return a;\n" - "}\n", - scc_parse_translation_unit); + scc_ast_translation_unit_t tu; + scc_ast_translation_unit_init(&tu, &tu_decls); + + const char *input = "int main() {\n" + " int a;\n" + " int b;\n" + " a = 1 + 2 * 3;\n" + " b = 7;\n" + " a = a - b + 1;\n" + " return a;\n" + "}\n"; + + SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit); } } -static scc_ast_expr_t make_binary(scc_ast_expr_op_t op, scc_ast_expr_t *lhs, - scc_ast_expr_t *rhs) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_BINARY}; - expr.binary.op = op; - expr.binary.lhs = lhs; - expr.binary.rhs = rhs; - return expr; -} - -static scc_ast_expr_t make_unary(scc_ast_expr_op_t op, - scc_ast_expr_t *operand) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_UNARY}; - expr.unary.op = op; - expr.unary.operand = operand; - return expr; -} - -static scc_ast_expr_t make_identifier(char *name) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_IDENTIFIER}; - expr.identifier.name = name; - return expr; -} - -static scc_ast_expr_t make_int_literal(char *val) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_INT_LITERAL}; - expr.literal.lexme = val; - return expr; -} - -static scc_ast_expr_t make_float_literal(char *val) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_FLOAT_LITERAL}; - expr.literal.lexme = val; - return expr; -} - -static scc_ast_expr_t make_string_literal(char *val) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_STRING_LITERAL}; - expr.literal.lexme = val; - return expr; -} - -static scc_ast_expr_t make_char_literal(char *val) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_CHAR_LITERAL}; - expr.literal.lexme = val; - return expr; -} - -static scc_ast_expr_t make_conditional(scc_ast_expr_t *cond, - scc_ast_expr_t *then_expr, - scc_ast_expr_t *else_expr) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_COND}; - expr.cond.cond = cond; - expr.cond.then_expr = then_expr; - expr.cond.else_expr = else_expr; - return expr; -} - -static scc_ast_expr_t make_call(scc_ast_expr_t *callee, - scc_ast_expr_vec_t *args) { - scc_ast_expr_t expr = {.base.type = SCC_AST_EXPR_CALL}; - expr.call.callee = callee; - // 注意:args 需要提前初始化,此处简化处理,实际测试中可能需要动态分配 - // 我们将在具体测试中手动初始化 args 数组 - return expr; -} - static void test_parser_expression(void) { - // 1. 基本表达式:标识符、整数常量、字符串字面量、括号 + // 1. 基本表达式 { - scc_ast_expr_t ident = make_identifier("x"); + scc_ast_expr_t ident; + scc_ast_expr_identifier_init(&ident, "x"); SCC_CHECK_AST(&ident.base, "x", scc_parse_expression); - scc_ast_expr_t int_lit = make_int_literal("42"); + scc_ast_expr_t int_lit; + scc_ast_expr_literal_int_init(&int_lit, "42", false); SCC_CHECK_AST(&int_lit.base, "42", scc_parse_expression); - scc_ast_expr_t str_lit = make_string_literal("\"hello\""); + scc_ast_expr_t str_lit; + scc_ast_expr_literal_string_init(&str_lit, "\"hello\"", false); SCC_CHECK_AST(&str_lit.base, "\"hello\"", scc_parse_expression); - // 括号表达式 - scc_ast_expr_t paren_ident = make_identifier("y"); + // 括号表达式(解析器应直接返回内部表达式) + scc_ast_expr_t paren_ident; + scc_ast_expr_identifier_init(&paren_ident, "y"); SCC_CHECK_AST(&paren_ident.base, "(y)", scc_parse_expression); } // 2. 后缀表达式 { - // 数组下标:a[10] - scc_ast_expr_t a = make_identifier("a"); - scc_ast_expr_t index = make_int_literal("10"); - scc_ast_expr_t subscript = {.base.type = SCC_AST_EXPR_ARRAY_SUBSCRIPT}; - subscript.subscript.array = &a; - subscript.subscript.index = &index; + // 数组下标 a[10] + scc_ast_expr_t a, index, subscript; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_literal_int_init(&index, "10", false); + scc_ast_expr_array_subscript_init(&subscript, &a, &index); SCC_CHECK_AST(&subscript.base, "a[10]", scc_parse_expression); - // 函数调用:f() - scc_ast_expr_t f = make_identifier("f"); - scc_ast_expr_t call = {.base.type = SCC_AST_EXPR_CALL}; - call.call.callee = &f; + // 函数调用 f() + scc_ast_expr_t f; + scc_ast_expr_identifier_init(&f, "f"); scc_ast_expr_vec_t args; scc_vec_init(args); - call.call.args = args; // 空参数列表 + scc_ast_expr_t call; + scc_ast_expr_call_init(&call, "f", + &args); // 使用函数名,target 在语义分析时填充 SCC_CHECK_AST(&call.base, "f()", scc_parse_expression); - // 函数调用带参数:f(1, x) - scc_ast_expr_t f2 = make_identifier("f"); - scc_ast_expr_t arg1 = make_int_literal("1"); - scc_ast_expr_t arg2 = make_identifier("x"); + // 函数调用带参数 f(1, x) + scc_ast_expr_t arg1, arg2; + scc_ast_expr_literal_int_init(&arg1, "1", false); + scc_ast_expr_identifier_init(&arg2, "x"); scc_ast_expr_vec_t args2; scc_vec_init(args2); scc_vec_push(args2, &arg1); scc_vec_push(args2, &arg2); - scc_ast_expr_t call2 = {.base.type = SCC_AST_EXPR_CALL}; - call2.call.callee = &f2; - call2.call.args = args2; + scc_ast_expr_t call2; + scc_ast_expr_call_init(&call2, "f", &args2); SCC_CHECK_AST(&call2.base, "f(1, x)", scc_parse_expression); - // 成员访问 . 和 -> - scc_ast_expr_t s = make_identifier("s"); - scc_ast_expr_t dot = {.base.type = SCC_AST_EXPR_MEMBER}; - dot.member.base = &s; - dot.member.member_name = "field"; + // 成员访问 . + scc_ast_expr_t s, dot; + scc_ast_expr_identifier_init(&s, "s"); + scc_ast_expr_member_init(&dot, &s, "field"); SCC_CHECK_AST(&dot.base, "s.field", scc_parse_expression); - scc_ast_expr_t p = make_identifier("p"); - scc_ast_expr_t arrow = {.base.type = SCC_AST_EXPR_PTR_MEMBER}; - arrow.ptr_member.base = &p; - arrow.ptr_member.member_name = "field"; + // 指针成员访问 -> + scc_ast_expr_t p, arrow; + scc_ast_expr_identifier_init(&p, "p"); + scc_ast_expr_ptr_member_init(&arrow, &p, "field"); SCC_CHECK_AST(&arrow.base, "p->field", scc_parse_expression); // 后缀 ++/-- - scc_ast_expr_t x = make_identifier("x"); - scc_ast_expr_t post_inc = make_unary(SCC_AST_OP_POSTFIX_INCREMENT, &x); + scc_ast_expr_t x, post_inc, post_dec; + scc_ast_expr_identifier_init(&x, "x"); + scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &x); + scc_ast_expr_unary_init(&post_dec, SCC_AST_OP_POSTFIX_DECREMENT, &x); SCC_CHECK_AST(&post_inc.base, "x++", scc_parse_expression); - - scc_ast_expr_t post_dec = make_unary(SCC_AST_OP_POSTFIX_DECREMENT, &x); SCC_CHECK_AST(&post_dec.base, "x--", scc_parse_expression); - - // 复合字面量 TODO: (int){1,2} 需要更复杂的构造,暂略 - // SCC_CHECK_AST(..., "(int){1,2}", scc_parse_expression); } // 3. 一元表达式 { - scc_ast_expr_t x = make_identifier("x"); + scc_ast_expr_t x; + scc_ast_expr_identifier_init(&x, "x"); - scc_ast_expr_t pre_inc = make_unary(SCC_AST_OP_PREFIX_INCREMENT, &x); + scc_ast_expr_t pre_inc; + scc_ast_expr_unary_init(&pre_inc, SCC_AST_OP_PREFIX_INCREMENT, &x); SCC_CHECK_AST(&pre_inc.base, "++x", scc_parse_expression); - scc_ast_expr_t pre_dec = make_unary(SCC_AST_OP_PREFIX_DECREMENT, &x); + scc_ast_expr_t pre_dec; + scc_ast_expr_unary_init(&pre_dec, SCC_AST_OP_PREFIX_DECREMENT, &x); SCC_CHECK_AST(&pre_dec.base, "--x", scc_parse_expression); - scc_ast_expr_t addr = make_unary(SCC_AST_OP_ADDRESS_OF, &x); + scc_ast_expr_t addr; + scc_ast_expr_unary_init(&addr, SCC_AST_OP_ADDRESS_OF, &x); SCC_CHECK_AST(&addr.base, "&x", scc_parse_expression); - scc_ast_expr_t deref = make_unary(SCC_AST_OP_INDIRECTION, &x); + scc_ast_expr_t deref; + scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &x); SCC_CHECK_AST(&deref.base, "*x", scc_parse_expression); - scc_ast_expr_t plus = make_unary(SCC_AST_OP_UNARY_PLUS, &x); + scc_ast_expr_t plus; + scc_ast_expr_unary_init(&plus, SCC_AST_OP_UNARY_PLUS, &x); SCC_CHECK_AST(&plus.base, "+x", scc_parse_expression); - scc_ast_expr_t minus = make_unary(SCC_AST_OP_UNARY_MINUS, &x); + scc_ast_expr_t minus; + scc_ast_expr_unary_init(&minus, SCC_AST_OP_UNARY_MINUS, &x); SCC_CHECK_AST(&minus.base, "-x", scc_parse_expression); - scc_ast_expr_t bit_not = make_unary(SCC_AST_OP_BITWISE_NOT, &x); + scc_ast_expr_t bit_not; + scc_ast_expr_unary_init(&bit_not, SCC_AST_OP_BITWISE_NOT, &x); SCC_CHECK_AST(&bit_not.base, "~x", scc_parse_expression); - scc_ast_expr_t log_not = make_unary(SCC_AST_OP_LOGICAL_NOT, &x); + scc_ast_expr_t log_not; + scc_ast_expr_unary_init(&log_not, SCC_AST_OP_LOGICAL_NOT, &x); SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression); - // sizeof 两种形式 // sizeof 表达式 - scc_ast_expr_t sizeof_expr = {.base.type = SCC_AST_EXPR_SIZE_OF}; - sizeof_expr.attr_of.expr = &x; - SCC_CHECK_AST(&sizeof_expr.base, "sizeof x", scc_parse_expression); - - // sizeof(类型名) 需要构造类型节点,暂时略,用TODO - // SCC_CHECK_AST(..., "sizeof(int)", scc_parse_expression); + // TODO + // scc_ast_expr_t sizeof_expr; + // scc_ast_expr_sizeof_expr_init(&sizeof_expr, &x); + // SCC_CHECK_AST(&sizeof_expr.base, "sizeof x", scc_parse_expression); } - // 4. 类型转换 + // 4. 类型转换(示例: (int)x ) { - // (int)x - // 需要构造类型节点,这里简化,用TODO - // scc_ast_type_t int_type = { .base.type = SCC_AST_TYPE_BUILTIN, - // .builtin.type = SCC_AST_BUILTIN_TYPE_INT }; scc_ast_expr_t x = - // make_identifier("x"); scc_ast_expr_t cast = { .base.type = - // SCC_AST_EXPR_CAST }; cast.cast.type = &int_type; cast.cast.expr = - // &x; SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression); + // scc_ast_type_t + // int_type; // 使用内置类型全局变量即可,但类型转换需要一个类型节点 + // // + // 我们可以直接使用全局内置类型的地址,但类型转换节点需要一个类型节点,直接引用全局即可 + // // TODO + // scc_ast_expr_t x; + // scc_ast_expr_identifier_init(&x, "x"); + // scc_ast_expr_t cast; + // scc_ast_expr_cast_init(&cast, + // (scc_ast_type_t *)&scc_ast_builtin_type_int, + // &x); + // SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression); } - // 5. 二元运算符(按优先级测试) + // 5. 二元运算符优先级 { - scc_ast_expr_t a = make_identifier("a"); - scc_ast_expr_t b = make_identifier("b"); - scc_ast_expr_t c = make_identifier("c"); - scc_ast_expr_t d = make_identifier("d"); + scc_ast_expr_t a, b, c, d; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_identifier_init(&b, "b"); + scc_ast_expr_identifier_init(&c, "c"); + scc_ast_expr_identifier_init(&d, "d"); - // 乘除模优先级高于加减 - scc_ast_expr_t mul = make_binary(SCC_AST_OP_MUL, &a, &b); - scc_ast_expr_t add = make_binary(SCC_AST_OP_ADD, &mul, &c); + // a * b + c + scc_ast_expr_t mul, add; + scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &a, &b); + scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &mul, &c); SCC_CHECK_AST(&add.base, "a * b + c", scc_parse_expression); - // 左结合性 a - b - c => (a - b) - c - scc_ast_expr_t sub1 = make_binary(SCC_AST_OP_SUB, &a, &b); - scc_ast_expr_t sub2 = make_binary(SCC_AST_OP_SUB, &sub1, &c); + // a - b - c => (a - b) - c + scc_ast_expr_t sub1, sub2; + scc_ast_expr_binary_init(&sub1, SCC_AST_OP_SUB, &a, &b); + scc_ast_expr_binary_init(&sub2, SCC_AST_OP_SUB, &sub1, &c); SCC_CHECK_AST(&sub2.base, "a - b - c", scc_parse_expression); - // 移位 - scc_ast_expr_t shift = make_binary(SCC_AST_OP_LEFT_SHIFT, &a, &b); + // a << b + scc_ast_expr_t shift; + scc_ast_expr_binary_init(&shift, SCC_AST_OP_LEFT_SHIFT, &a, &b); SCC_CHECK_AST(&shift.base, "a << b", scc_parse_expression); - // 关系 - scc_ast_expr_t lt = make_binary(SCC_AST_OP_LESS, &a, &b); + // a < b + scc_ast_expr_t lt; + scc_ast_expr_binary_init(<, SCC_AST_OP_LESS, &a, &b); SCC_CHECK_AST(<.base, "a < b", scc_parse_expression); - // 相等 - scc_ast_expr_t eq = make_binary(SCC_AST_OP_EQUAL, &a, &b); + // a == b + scc_ast_expr_t eq; + scc_ast_expr_binary_init(&eq, SCC_AST_OP_EQUAL, &a, &b); SCC_CHECK_AST(&eq.base, "a == b", scc_parse_expression); - // 按位与、异或、或的优先级:& 高于 ^ 高于 | - scc_ast_expr_t bitand = make_binary(SCC_AST_OP_BITWISE_AND, &a, &b); - scc_ast_expr_t bitxor = - make_binary(SCC_AST_OP_BITWISE_XOR, &bitand, &c); - scc_ast_expr_t bitor = make_binary(SCC_AST_OP_BITWISE_OR, &bitxor, &d); + // a & b ^ c | d + scc_ast_expr_t bitand, bitxor, bitor; + scc_ast_expr_binary_init(&bitand, SCC_AST_OP_BITWISE_AND, &a, &b); + scc_ast_expr_binary_init(&bitxor, SCC_AST_OP_BITWISE_XOR, &bitand, &c); + scc_ast_expr_binary_init(&bitor, SCC_AST_OP_BITWISE_OR, &bitxor, &d); SCC_CHECK_AST(&bitor.base, "a & b ^ c | d", scc_parse_expression); - // 逻辑与、或:&& 高于 || - scc_ast_expr_t logand = make_binary(SCC_AST_OP_LOGICAL_AND, &a, &b); - scc_ast_expr_t logor = make_binary(SCC_AST_OP_LOGICAL_OR, &logand, &c); + // a && b || c + scc_ast_expr_t logand, logor; + scc_ast_expr_binary_init(&logand, SCC_AST_OP_LOGICAL_AND, &a, &b); + scc_ast_expr_binary_init(&logor, SCC_AST_OP_LOGICAL_OR, &logand, &c); SCC_CHECK_AST(&logor.base, "a && b || c", scc_parse_expression); } // 6. 三元运算符 { - scc_ast_expr_t cond = make_identifier("a"); - scc_ast_expr_t then_expr = make_identifier("b"); - scc_ast_expr_t else_expr = make_identifier("c"); - scc_ast_expr_t cond_expr = - make_conditional(&cond, &then_expr, &else_expr); - SCC_CHECK_AST(&cond_expr.base, "a ? b : c", scc_parse_expression); + scc_ast_expr_t a, b, c; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_identifier_init(&b, "b"); + scc_ast_expr_identifier_init(&c, "c"); - // 右结合性 a ? b : c ? d : e => a ? b : (c ? d : e) - scc_ast_expr_t cond2 = make_identifier("c"); - scc_ast_expr_t then2 = make_identifier("d"); - scc_ast_expr_t else2 = make_identifier("e"); - scc_ast_expr_t inner_cond = make_conditional(&cond2, &then2, &else2); - scc_ast_expr_t outer_cond = - make_conditional(&cond, &then_expr, &inner_cond); - SCC_CHECK_AST(&outer_cond.base, "a ? b : c ? d : e", - scc_parse_expression); + // a ? b : c + scc_ast_expr_t cond1; + scc_ast_expr_cond_init(&cond1, &a, &b, &c); + SCC_CHECK_AST(&cond1.base, "a ? b : c", scc_parse_expression); + + // a ? b : c ? d : e => a ? b : (c ? d : e) + scc_ast_expr_t d, e; + scc_ast_expr_identifier_init(&d, "d"); + scc_ast_expr_identifier_init(&e, "e"); + scc_ast_expr_t inner, outer; + scc_ast_expr_cond_init(&inner, &c, &d, &e); + scc_ast_expr_cond_init(&outer, &a, &b, &inner); + SCC_CHECK_AST(&outer.base, "a ? b : c ? d : e", scc_parse_expression); } - // 7. 赋值运算符(右结合) + // 7. 赋值运算符 { - scc_ast_expr_t a = make_identifier("a"); - scc_ast_expr_t b = make_identifier("b"); - scc_ast_expr_t c = make_identifier("c"); - scc_ast_expr_t int_lit = make_int_literal("42"); - scc_ast_expr_t assign1 = make_binary(SCC_AST_OP_ASSIGN, &b, &c); - scc_ast_expr_t assign2 = - make_binary(SCC_AST_OP_ASSIGN, &a, &assign1); // a = (b = c) - SCC_CHECK_AST(&assign2.base, "a = b = c", scc_parse_expression); + scc_ast_expr_t a, b, c; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_identifier_init(&b, "b"); + scc_ast_expr_identifier_init(&c, "c"); + scc_ast_expr_t lit42; + scc_ast_expr_literal_int_init(&lit42, "42", false); - scc_ast_expr_t assign3 = make_binary(SCC_AST_OP_ASSIGN, &a, &int_lit); - SCC_CHECK_AST(&assign3.base, "a = 42", scc_parse_expression); + // a = b = c + scc_ast_expr_t assign_inner, assign_outer; + scc_ast_expr_binary_init(&assign_inner, SCC_AST_OP_ASSIGN, &b, &c); + scc_ast_expr_binary_init(&assign_outer, SCC_AST_OP_ASSIGN, &a, + &assign_inner); + SCC_CHECK_AST(&assign_outer.base, "a = b = c", scc_parse_expression); - scc_ast_expr_t assign4 = make_binary(SCC_AST_OP_SUB, &a, &b); - scc_ast_expr_t assign5 = - make_binary(SCC_AST_OP_ADD, &assign4, &int_lit); - scc_ast_expr_t assign6 = make_binary(SCC_AST_OP_ASSIGN, &a, &assign5); - SCC_CHECK_AST(&assign6.base, "a = a - b + 42", scc_parse_expression); + // a = 42 + scc_ast_expr_t assign1; + scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a, &lit42); + SCC_CHECK_AST(&assign1.base, "a = 42", scc_parse_expression); - scc_ast_expr_t add_assign = make_binary(SCC_AST_OP_ASSIGN_ADD, &a, &b); + // a = a - b + 42 + scc_ast_expr_t sub, add, assign2; + scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a, &b); + scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &sub, &lit42); + scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &a, &add); + SCC_CHECK_AST(&assign2.base, "a = a - b + 42", scc_parse_expression); + + // a += b + scc_ast_expr_t add_assign; + scc_ast_expr_binary_init(&add_assign, SCC_AST_OP_ASSIGN_ADD, &a, &b); SCC_CHECK_AST(&add_assign.base, "a += b", scc_parse_expression); } // 8. 逗号运算符 { - scc_ast_expr_t a = make_identifier("a"); - scc_ast_expr_t b = make_identifier("b"); - scc_ast_expr_t comma1 = make_binary(SCC_AST_OP_COMMA, &a, &b); - SCC_CHECK_AST(&comma1.base, "a, b", scc_parse_expression); + scc_ast_expr_t a, b; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_identifier_init(&b, "b"); + scc_ast_expr_t comma; + scc_ast_expr_binary_init(&comma, SCC_AST_OP_COMMA, &a, &b); + SCC_CHECK_AST(&comma.base, "a, b", scc_parse_expression); } - // 9. 混合优先级测试 + // 9. 混合优先级 { - scc_ast_expr_t a = make_identifier("a"); - scc_ast_expr_t b = make_identifier("b"); - scc_ast_expr_t c = make_identifier("c"); - scc_ast_expr_t d = make_identifier("d"); + scc_ast_expr_t a, b, c, d; + scc_ast_expr_identifier_init(&a, "a"); + scc_ast_expr_identifier_init(&b, "b"); + scc_ast_expr_identifier_init(&c, "c"); + scc_ast_expr_identifier_init(&d, "d"); - // a + b * c - d => (a + (b * c)) - d - scc_ast_expr_t mul = make_binary(SCC_AST_OP_MUL, &b, &c); - scc_ast_expr_t add = make_binary(SCC_AST_OP_ADD, &a, &mul); - scc_ast_expr_t sub = make_binary(SCC_AST_OP_SUB, &add, &d); + // a + b * c - d + scc_ast_expr_t mul, add, sub; + scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &b, &c); + scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &a, &mul); + scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &add, &d); SCC_CHECK_AST(&sub.base, "a + b * c - d", scc_parse_expression); - // *p++ => *(p++) - scc_ast_expr_t p = make_identifier("p"); - scc_ast_expr_t post_inc = make_unary(SCC_AST_OP_POSTFIX_INCREMENT, &p); - scc_ast_expr_t deref = make_unary(SCC_AST_OP_INDIRECTION, &post_inc); + // *p++ + scc_ast_expr_t p, post_inc, deref; + scc_ast_expr_identifier_init(&p, "p"); + scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &p); + scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &post_inc); SCC_CHECK_AST(&deref.base, "*p++", scc_parse_expression); } } @@ -586,5 +525,5 @@ static void test_parser_expression(void) { TEST_LIST = { {"parser_unit", test_parser_unit}, {"parser_expression", test_parser_expression}, - {NULL, NULL}, + {null, null}, }; \ No newline at end of file diff --git a/libs/pproc/tests/test_pproc_unit.c b/libs/pproc/tests/test_pproc_unit.c index df4bea3..710915d 100644 --- a/libs/pproc/tests/test_pproc_unit.c +++ b/libs/pproc/tests/test_pproc_unit.c @@ -16,7 +16,7 @@ static cbool process_input(const char *input, scc_cstring_t *output) { scc_pproc_t pp; scc_pproc_init(&pp, scc_lexer_to_ring(&lexer, 8, true)); - scc_lexer_tok_ring_t *tok_ring = scc_pproc_to_ring(&pp, 8); + scc_lexer_tok_ring_t *tok_ring = scc_pproc_to_ring(&pp, 8, true, true); *output = scc_cstring_from_cstr(""); scc_lexer_tok_t tok; while (1) { diff --git a/runtime/scc_core/include/scc_core_impl.h b/runtime/scc_core/include/scc_core_impl.h index c748e49..59fc87f 100644 --- a/runtime/scc_core/include/scc_core_impl.h +++ b/runtime/scc_core/include/scc_core_impl.h @@ -16,8 +16,8 @@ typedef enum { SCC_FILE_WRITE, SCC_FILE_APPEND, } scc_fmode_t; -#define scc_stdout 1 -#define scc_stderr 2 +#define scc_stdout ((scc_file_t)1) +#define scc_stderr ((scc_file_t)2) scc_file_t scc_fopen(const char *path, scc_fmode_t mode); void scc_fclose(scc_file_t file); usize scc_fsize(scc_file_t file); diff --git a/runtime/scc_core/include/scc_core_vec.h b/runtime/scc_core/include/scc_core_vec.h index 952963a..7600542 100644 --- a/runtime/scc_core/include/scc_core_vec.h +++ b/runtime/scc_core/include/scc_core_vec.h @@ -150,4 +150,11 @@ typedef size_t usize; (vec).size = (vec).cap = 0; \ } while (0) +#define scc_vec_unsafe_from_static_array(vec, array) \ + do { \ + (vec).size = sizeof(array) / sizeof((array)[0]); \ + (vec).cap = (vec).size; \ + (vec).data = array; \ + } while (0) + #endif /* __SCC_CORE_VEC_H__ */ diff --git a/runtime/scc_core/src/core_impl.c b/runtime/scc_core/src/core_impl.c index e00c188..2b67061 100644 --- a/runtime/scc_core/src/core_impl.c +++ b/runtime/scc_core/src/core_impl.c @@ -72,9 +72,9 @@ int scc_fprintf(scc_file_t file, const char *format, ...) { int scc_vfprintf(scc_file_t file, const char *format, va_list args) { char buf[4096] = {0}; int size = vsnprintf_(buf, sizeof(buf), format, args); - if (file == (scc_file_t)scc_stdout) { + if (file == scc_stdout) { scc_pal_write(buf, size); - } else if (file == (scc_file_t)scc_stderr) { + } else if (file == scc_stderr) { scc_pal_ewrite(buf, size); } else { scc_pal_fwrite(file, buf, size); diff --git a/src/main.c b/src/main.c index bd6dd2b..2af75f2 100644 --- a/src/main.c +++ b/src/main.c @@ -158,30 +158,22 @@ static void print_ring(scc_lexer_tok_ring_t *ring, int verbose) { } } -static void print_file(scc_lexer_tok_ring_t *ring, const char *file_name) { +static void print_file(scc_lexer_tok_ring_t *ring, scc_file_t fp) { scc_lexer_tok_t tok = {0}; int ret = 0; - scc_file_t fp = null; - cbool is_stdout = scc_strcmp(file_name, "-") == 0; - if (!is_stdout) { - fp = scc_fopen(file_name, SCC_FILE_WRITE); - if (fp == null) { - LOG_FATAL("Failed to open file %s", file_name); - return; - } - } + while (1) { scc_ring_next_consume(*ring, tok, ret); if (ret == false || tok.type == SCC_TOK_EOF) { break; } - if (is_stdout) { + if (fp == scc_stdout) { scc_printf("%s", scc_cstring_as_cstr(&tok.lexeme)); } else { usize ret = scc_fwrite(fp, scc_cstring_as_cstr(&tok.lexeme), scc_cstring_len(&tok.lexeme)); if (ret != scc_cstring_len(&tok.lexeme)) { - LOG_FATAL("Failed to write to file %s", file_name); + LOG_FATAL("Failed to write to file"); } } scc_lexer_tok_drop(&tok); @@ -225,6 +217,18 @@ int main(int argc, const char **argv, const char **envp) { } scc_argparse_drop(&argparse); + scc_file_t fp = null; + if (config.output_file) { + cbool is_stdout = scc_strcmp(config.output_file, "-") == 0; + if (!is_stdout) { + fp = scc_fopen(config.output_file, SCC_FILE_WRITE); + if (fp == null) { + LOG_FATAL("Failed to open file %s", config.output_file); + return 1; + } + } + } + scc_sstream_t sstream; if (scc_sstream_init(&sstream, config.input_file, 1024)) { return 0; @@ -233,12 +237,12 @@ int main(int argc, const char **argv, const char **envp) { scc_lexer_t lexer; scc_lexer_init(&lexer, scc_sstream_to_ring(&sstream)); if (config.emit_lex) { - scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring( - &lexer, 8, config.output_file == null ? false : true); - if (config.output_file == null) { + scc_lexer_tok_ring_t *tok_ring = + scc_lexer_to_ring(&lexer, 8, fp == null ? false : true); + if (fp == null) { print_ring(tok_ring, config.verbose); } else { - print_file(tok_ring, config.output_file); + print_file(tok_ring, fp); } return 0; } @@ -260,7 +264,7 @@ int main(int argc, const char **argv, const char **envp) { if (config.output_file == null) { print_ring(tok_ring, config.verbose); } else { - print_file(tok_ring, config.output_file); + print_file(tok_ring, fp); } return 0; } @@ -271,15 +275,20 @@ int main(int argc, const char **argv, const char **envp) { scc_ast_translation_unit_t *translation_unit = scc_parse_translation_unit(&parser); - scc_parser_drop(&parser); - scc_pproc_drop(&pproc); - scc_lexer_drop(&lexer); - scc_sstream_drop(&sstream); + // scc_parser_drop(&parser); + // scc_pproc_drop(&pproc); + // scc_lexer_drop(&lexer); + // scc_sstream_drop(&sstream); if (config.emit_ast) { scc_tree_dump_ctx_t tree_dump; - scc_tree_dump_ctx_init(&tree_dump, true, (void *)scc_fprintf, - (void *)scc_stdout); + if (fp == null) { + scc_tree_dump_ctx_init(&tree_dump, true, (void *)scc_fprintf, + (void *)scc_stdout); + } else { + scc_tree_dump_ctx_init(&tree_dump, false, (void *)scc_fprintf, + (void *)fp); + } scc_ast_dump_node(&tree_dump, (scc_ast_node_t *)translation_unit); scc_tree_dump_ctx_drop(&tree_dump); return 0;