feat(ast): 添加内置表达式支持并完善解析器功能

- 添加SCC_AST_EXPR_BUILTIN枚举值用于表示内置表达式
- 定义scc_ast_builtin_expr_type_t枚举包含va_start、va_end、va_copy、va_arg等内置函数类型
- 在AST表达式结构中添加builtin字段以支持内置表达式存储
- 实现scc_ast_decl_unsafe_val_init内联函数用于不安全的声明初始化
- 修改sizeof和alignof表达式初始化函数以支持类型或表达式参数
- 修复默认语句的字段引用错误(default_stmt而非case_stmt)
- 改进词法分析器对整数字面量后缀(U、L、LL等)的处理逻辑
- 重构解析器中的声明解析逻辑,统一使用scc_parse_declarator函数
- 完善结构体、联合体和枚举类型的声明解析,支持仅有名称的前向声明
- 优化初始化列表解析,支持复合字面量的成员访问语法
- 更新参数类型列表解析以正确处理参数声明
- 修复括号表达式的解析逻辑,区分类型转换和普通括号表达式
This commit is contained in:
zzy
2026-03-13 17:39:14 +08:00
parent c99f64708e
commit 8fcfeda14e
12 changed files with 431 additions and 225 deletions

View File

@@ -52,6 +52,7 @@ typedef enum {
SCC_AST_EXPR_ALIGN_OF, // _Alignof SCC_AST_EXPR_ALIGN_OF, // _Alignof
SCC_AST_EXPR_COMPOUND, // 复合字面量 SCC_AST_EXPR_COMPOUND, // 复合字面量
SCC_AST_EXPR_LVALUE, // 右值 SCC_AST_EXPR_LVALUE, // 右值
SCC_AST_EXPR_BUILTIN, // 内置表达式
// 字面量 // 字面量
SCC_AST_EXPR_INT_LITERAL, // 整数字面量 SCC_AST_EXPR_INT_LITERAL, // 整数字面量
SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量 SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量
@@ -258,6 +259,13 @@ typedef enum scc_ast_expr_op {
SCC_AST_OP_PTR_MEMBER_ACCESS, // -> SCC_AST_OP_PTR_MEMBER_ACCESS, // ->
} scc_ast_expr_op_t; } scc_ast_expr_op_t;
typedef enum {
SCC_AST_EXPR_BUILTIN_VA_START,
SCC_AST_EXPR_BUILTIN_VA_END,
SCC_AST_EXPR_BUILTIN_VA_COPY,
SCC_AST_EXPR_BUILTIN_VA_ARG,
} scc_ast_builtin_expr_type_t;
/** /**
* @brief 表达式节点 * @brief 表达式节点
*/ */
@@ -328,6 +336,11 @@ struct scc_ast_expr {
struct { struct {
scc_ast_type_t *type; scc_ast_type_t *type;
} lvalue; } lvalue;
// 内置表达式
struct {
scc_ast_builtin_expr_type_t type;
scc_ast_expr_vec_t args;
} builtin;
}; };
}; };

View File

@@ -20,6 +20,19 @@ scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit,
} }
} }
// name and var_init can be null
static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl,
scc_ast_type_t *type,
const char *name,
scc_ast_expr_t *var_init) {
Assert(decl != 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;
}
// var_init can be null // var_init can be null
static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl, static inline void scc_ast_decl_val_init(scc_ast_decl_t *decl,
scc_ast_type_t *type, const char *name, scc_ast_type_t *type, const char *name,
@@ -212,7 +225,7 @@ static inline void scc_ast_stmt_default_init(scc_ast_stmt_t *stmt,
Assert(stmt != null && body != null); Assert(stmt != null && body != null);
stmt->base.loc = scc_pos_create(); stmt->base.loc = scc_pos_create();
stmt->base.type = SCC_AST_STMT_DEFAULT; stmt->base.type = SCC_AST_STMT_DEFAULT;
stmt->case_stmt.stmt = body; stmt->default_stmt.stmt = body;
} }
static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt) { static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt) {
@@ -351,22 +364,26 @@ static inline void scc_ast_expr_cast_init(scc_ast_expr_t *expr,
expr->cast.expr = operand; expr->cast.expr = operand;
} }
// type and target_expr can be null but it only one of them can be null
static inline void scc_ast_expr_sizeof_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_sizeof_init(scc_ast_expr_t *expr,
scc_ast_type_t *type) { scc_ast_type_t *type,
Assert(expr != null && type != null); scc_ast_expr_t *target_expr) {
Assert(expr != null);
expr->base.loc = scc_pos_create(); expr->base.loc = scc_pos_create();
expr->base.type = SCC_AST_EXPR_SIZE_OF; expr->base.type = SCC_AST_EXPR_SIZE_OF;
expr->attr_of.type = type; expr->attr_of.type = type;
expr->attr_of.expr = null; expr->attr_of.expr = target_expr;
} }
// type and target_expr can be null but it only one of them can be null
static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr, static inline void scc_ast_expr_alignof_init(scc_ast_expr_t *expr,
scc_ast_type_t *type) { scc_ast_type_t *type,
Assert(expr != null && type != null); scc_ast_expr_t *target_expr) {
Assert(expr != null);
expr->base.loc = scc_pos_create(); expr->base.loc = scc_pos_create();
expr->base.type = SCC_AST_EXPR_SIZE_OF; expr->base.type = SCC_AST_EXPR_SIZE_OF;
expr->attr_of.type = type; expr->attr_of.type = type;
expr->attr_of.expr = null; expr->attr_of.expr = target_expr;
} }
// lhs_exprs and rhs_exprs can be null // lhs_exprs and rhs_exprs can be null

View File

@@ -484,6 +484,10 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) {
} }
break; break;
case SCC_AST_EXPR_BUILTIN:
// PRINT_QUOTED_VALUE(ctx, scc_ast_builtin_type_name(expr->builtin));
break;
default: default:
break; break;
} }

View File

@@ -160,10 +160,10 @@ typedef enum scc_tok_type {
SCC_CKEYWORD_TABLE SCC_CKEYWORD_TABLE
#undef X #undef X
// FIXME hack one bit for disabled // FIXME hack one bit for disabled or other method
#define X(str, subtype, tok) tok, #define X(str, subtype, tok) tok,
X(sum , SCC_TOK_SUBTYPE_INVALID, SCC_TOK_SUM ) X(sum , SCC_TOK_SUBTYPE_INVALID, SCC_TOK_SUM )
X(disabled , SCC_TOK_SUBTYPE_INVALID, SCC_TOK_DISABLED = 1<<7 ) X(disabled , SCC_TOK_SUBTYPE_INVALID, SCC_TOK_DISABLED )
#undef X #undef X
} scc_tok_type_t; } scc_tok_type_t;
/* clang-format on */ /* clang-format on */

View File

@@ -195,8 +195,24 @@ void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) {
} }
break; break;
} }
if (maybe_float) if (maybe_float) {
token->type = SCC_TOK_FLOAT_LITERAL; token->type = SCC_TOK_FLOAT_LITERAL;
} else {
// FIXME 0U 0UL 0ULL 0L 0LL
while (1) {
if (!peek_char(lexer, &cur)) {
break;
}
ch = cur.character;
if (ch == 'U' || ch == 'u' || ch == 'L' || ch == 'l') {
next_char(lexer, &lex, &cur);
// 带后缀的整数字面量
continue;
} else {
break;
}
}
}
} else if (ch == '\'') { } else if (ch == '\'') {
// 字符字面量 // 字符字面量
token->type = SCC_TOK_CHAR_LITERAL; token->type = SCC_TOK_CHAR_LITERAL;

View File

@@ -75,8 +75,7 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser);
* @param parser 解析器实例 * @param parser 解析器实例
* @return 类型 AST 节点 * @return 类型 AST 节点
*/ */
scc_ast_node_t *_scc_parse_type(scc_parser_t *parser); scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser);
scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser); scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser);
static inline void scc_parse_decl_sema(scc_parser_t *parser, static inline void scc_parse_decl_sema(scc_parser_t *parser,

View File

@@ -174,6 +174,7 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
. identifier . identifier
*/ */
const scc_lexer_tok_t *tok_ptr = null; const scc_lexer_tok_t *tok_ptr = null;
scc_lexer_tok_t tok = {0};
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
scc_ast_expr_t *init = null; scc_ast_expr_t *init = null;
if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE)) { if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE)) {
@@ -191,21 +192,21 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
scc_vec_init(rhs_exprs); scc_vec_init(rhs_exprs);
scc_ast_expr_t *lhs = null; scc_ast_expr_t *lhs = null;
scc_ast_expr_t *rhs = null; scc_ast_expr_t *rhs = null;
scc_ast_expr_t *ptr = base;
while (1) { while (1) {
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_DOT) { if (tok_ptr->type == SCC_TOK_DOT) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, null);
tok_ptr = scc_parser_peek(parser); tok_ptr = scc_parser_peek(parser);
if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) { if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) {
scc_parser_next(parser); scc_parser_next_consume(parser, &tok);
lhs = scc_malloc(sizeof(scc_ast_expr_t)); lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null); Assert(lhs != null);
scc_ast_expr_member_init(lhs, base, scc_ast_expr_member_init(lhs, ptr,
scc_cstring_as_cstr(&tok_ptr->lexeme)); scc_cstring_as_cstr(&tok.lexeme));
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), ptr = lhs;
"Expected '='"); continue;
} }
rhs = scc_parse_initializer(parser, lhs); rhs = scc_parse_initializer(parser, lhs);
if (rhs == null) { if (rhs == null) {
@@ -215,6 +216,7 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
} }
scc_vec_push(lhs_exprs, lhs); scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs); scc_vec_push(rhs_exprs, rhs);
ptr = base;
} else { } else {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected 'identifier' after '.'"); "Expected 'identifier' after '.'");
@@ -228,14 +230,16 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
} }
lhs = scc_malloc(sizeof(scc_ast_expr_t)); lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null); Assert(lhs != null);
scc_ast_expr_array_subscript_init(lhs, base, idx); scc_ast_expr_array_subscript_init(lhs, ptr, idx);
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) { if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected '='"); ptr = lhs;
continue;
} }
rhs = scc_parse_initializer(parser, lhs); rhs = scc_parse_initializer(parser, lhs);
Assert(rhs != null); Assert(rhs != null);
scc_vec_push(lhs_exprs, lhs); scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs); scc_vec_push(rhs_exprs, rhs);
ptr = base;
} else if (tok_ptr->type == SCC_TOK_R_BRACE) { } else if (tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null); scc_parser_next_consume(parser, null);
break; break;
@@ -254,31 +258,8 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
} }
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
scc_ast_node_t *type_or_decl = _scc_parse_type(parser); scc_ast_decl_t *decl = scc_parse_declarator(parser);
scc_ast_decl_t *decl = null; if (decl == null) {
if (type_or_decl == null) {
return null;
}
if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) {
scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl);
if (type->base.type == SCC_AST_TYPE_STRUCT ||
type->base.type == SCC_AST_TYPE_UNION) {
Assert(type->record.decl != null);
decl = type->record.decl;
scc_free(type_or_decl); // FIXME
} else if (type->base.type == SCC_AST_TYPE_ENUM) {
Assert(type->enumeration.decl != null);
decl = type->enumeration.decl;
scc_free(type_or_decl); // FIXME
} else {
LOG_WARN("declaration dose not declare anything");
return null;
}
} 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 {
SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration");
return null; return null;
} }
@@ -305,6 +286,8 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
Assert(decl->func.body != null); Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
} else { } else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ';' or '=' or '{'");
UNREACHABLE(); UNREACHABLE();
} }

View File

@@ -507,10 +507,25 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
// 一元表达式 // 一元表达式
static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
/*
(6.5.3)
unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
(6.5.3)
unary-operator: one of
& * + - ~ !
*/
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr) if (!tok_ptr)
return null; return null;
scc_lexer_tok_t tok = {0};
// 处理一元运算符 // 处理一元运算符
switch (tok_ptr->type) { switch (tok_ptr->type) {
case SCC_TOK_ADD_ADD: // ++x case SCC_TOK_ADD_ADD: // ++x
@@ -529,7 +544,14 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
scc_lexer_tok_drop(&op_tok); scc_lexer_tok_drop(&op_tok);
// 一元运算符右结合,递归调用 parse_unary_expression // 一元运算符右结合,递归调用 parse_unary_expression
scc_ast_expr_t *operand = parse_unary_expression(parser);
scc_ast_expr_t *operand = null;
if (tok_ptr->type == SCC_TOK_ADD_ADD ||
tok_ptr->type == SCC_TOK_SUB_SUB) {
operand = parse_unary_expression(parser);
} else {
operand = parse_cast_expression(parser);
}
if (!operand) { if (!operand) {
parser_sync(parser); parser_sync(parser);
return null; return null;
@@ -563,35 +585,35 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
return null; return null;
} }
scc_ast_expr_t *expr = null; scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
// 尝试解析 sizeof(type-name)
if (next->type == SCC_TOK_L_PAREN) { if (next->type == SCC_TOK_L_PAREN) {
scc_parser_store(parser); scc_parser_store(parser);
scc_ast_type_t *type = scc_parse_type_name(parser); scc_parser_next(parser);
if (type) { scc_ast_type_t *type_name = scc_parse_type_name(parser);
// 消耗 ')' if (type_name == null) {
scc_parser_restore(parser);
goto next;
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// 消耗 ')'
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"expected ')' after type-name in sizeof expression"); "expected ')' after type-name in sizeof expression");
} }
scc_ast_expr_sizeof_init(null, type);
Assert(type_name != null);
scc_ast_expr_sizeof_init(expr, type_name, null);
return expr; return expr;
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected type-name after sizeof");
TODO();
} }
} next:
// 否则作为 sizeof unary-expression // 尝试解析 sizeof unary-expression
scc_ast_expr_t *operand = parse_unary_expression(parser); scc_ast_expr_t *operand = parse_unary_expression(parser);
if (!operand) { if (operand != null) {
scc_free(expr); scc_ast_expr_sizeof_init(expr, null, operand);
parser_sync(parser); return expr;
return null;
} else {
scc_ast_expr_sizeof_init(operand, null);
} }
// 否则作为 sizeof(type-name)
return expr; return expr;
} }
@@ -737,6 +759,14 @@ done:
// 基本表达式 // 基本表达式
static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
/*
(6.5.1)
primary-expression:
identifier
constant
string-literal
( expression )
*/
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr) if (!tok_ptr)
return null; return null;
@@ -803,64 +833,16 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return expr; return expr;
} }
case SCC_TOK_L_PAREN: case SCC_TOK_L_PAREN:
return parse_paren_expression(parser); scc_parser_next_consume(parser, null);
default: expr = scc_parse_expression(parser);
return null;
}
}
// 处理括号表达式、类型转换、复合字面量
static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
// 保存位置以便回退
scc_parser_store(parser);
// 尝试解析类型名
scc_ast_type_t *type = scc_parse_type_name(parser);
if (type) {
// 如果成功,下一个应该是 ')'
if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// 是类型转换,解析后面的 cast-expression
scc_ast_expr_t *operand = parse_cast_expression(parser);
if (!operand) {
// FIXME postfix-expression
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
scc_ast_expr_lvalue_init(expr, type);
operand = scc_parse_initializer(parser, expr);
return operand;
}
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_cast_init(expr, type, operand);
return expr;
} else {
// 不是类型转换,回退并释放 type
scc_parser_restore(parser);
// TODO: scc_ast_type_drop(type);
}
} else {
scc_parser_restore(parser);
}
// 否则作为括号表达式
scc_lexer_tok_t lp;
if (!scc_parser_next_consume(parser, &lp) || lp.type != SCC_TOK_L_PAREN) {
return null;
}
scc_lexer_tok_drop(&lp);
scc_ast_expr_t *inner = scc_parse_expression(parser);
if (!inner) {
parser_sync(parser);
return null;
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ')' after expression"); "Expected ')' after expression");
parser_sync(parser); }
return expr;
default:
return null; return null;
} }
return inner;
} }
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) { scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {

View File

@@ -159,6 +159,21 @@ EXAMPLE The constructions
#include <parser_utils.h> #include <parser_utils.h>
#include <scc_parser.h> #include <scc_parser.h>
static scc_ast_type_t *parse_declarator(scc_parser_t *parser,
scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident);
static scc_ast_type_t *
parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident);
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 inline scc_ast_type_t *ast_type_alloc() { static inline scc_ast_type_t *ast_type_alloc() {
scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t)); scc_ast_type_t *ast_type = scc_malloc(sizeof(scc_ast_type_t));
ast_type->base.type = SCC_AST_UNKNOWN; ast_type->base.type = SCC_AST_UNKNOWN;
@@ -398,9 +413,8 @@ typedef struct {
static cbool check_type_combinations(scc_parser_t *parser, static cbool check_type_combinations(scc_parser_t *parser,
type_spec_info_t *info) { type_spec_info_t *info) {
// 基本类型不能同时出现多个void, char, int, float, double, bool 互斥) // 基本类型不能同时出现多个void, char, int, float, double, bool 互斥)
int basic_count = info->is_void + info->is_char + info->is_short + int basic_count = info->is_void + info->is_char + info->is_int +
info->is_int + info->is_float + info->is_double + info->is_float + info->is_double + info->is_bool;
info->is_bool;
if (basic_count > 1) { if (basic_count > 1) {
SCC_ERROR(scc_parser_got_current_pos(parser), SCC_ERROR(scc_parser_got_current_pos(parser),
"Multiple basic type specifiers"); "Multiple basic type specifiers");
@@ -574,11 +588,7 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
break; break;
} }
scc_ast_node_t *node = _scc_parse_type(parser); decl = scc_parse_declarator(parser);
scc_ast_decl_t *decl = null;
if (node != null) {
decl = SCC_AST_CAST_TO(scc_ast_decl_t, node);
}
if (decl != null) { if (decl != null) {
scc_vec_push(member, decl); scc_vec_push(member, decl);
continue; continue;
@@ -606,6 +616,21 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
scc_ast_decl_union_init(decl, name, &member); scc_ast_decl_union_init(decl, name, &member);
} }
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
} else {
if (name == null) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in struct/union specifier");
// FIXME memory leak
return null;
}
decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null);
if (type_kind == SCC_AST_TYPE_STRUCT) {
scc_ast_decl_struct_init(decl, name, null);
} else {
scc_ast_decl_union_init(decl, name, null);
}
} }
scc_ast_type_t *type = ast_type_alloc(); scc_ast_type_t *type = ast_type_alloc();
@@ -678,6 +703,16 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) {
Assert(decl != null); Assert(decl != null);
scc_ast_decl_enum_init(decl, name, &member); scc_ast_decl_enum_init(decl, name, &member);
scc_parse_decl_sema(parser, decl); scc_parse_decl_sema(parser, decl);
} else {
if (name == null) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected name in enum specifier");
// FIXME memory leak
return null;
}
decl = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl != null);
scc_ast_decl_enum_init(decl, name, null);
} }
scc_ast_type_t *type = ast_type_alloc(); scc_ast_type_t *type = ast_type_alloc();
@@ -818,21 +853,6 @@ duplicate_error:
return null; return null;
} }
static scc_ast_type_t *parse_declarator(scc_parser_t *parser,
scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident);
static scc_ast_type_t *
parse_direct_declarator(scc_parser_t *parser, scc_ast_type_t *base,
scc_ast_type_t **delay_pointee_ptr,
scc_lexer_tok_t *tok_ident);
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, static scc_ast_type_t *parse_pointer(scc_parser_t *parser,
scc_ast_type_t *pointee, scc_ast_type_t *pointee,
scc_ast_type_t **delay_pointee_ptr) { scc_ast_type_t **delay_pointee_ptr) {
@@ -875,22 +895,15 @@ static void parse_parameter_type_list(scc_parser_t *parser,
scc_ast_decl_t *param = null; scc_ast_decl_t *param = null;
while (1) { while (1) {
// FIXME // FIXME
scc_ast_node_t *node = _scc_parse_type(parser); scc_ast_decl_t *decl = scc_parse_declarator(parser);
if (node == null) { if (decl == null) {
return; return;
} }
if (SCC_AST_IS_A(scc_ast_decl_t, node)) {
param = SCC_AST_CAST_TO(scc_ast_decl_t, node);
// TODO Check validation // TODO Check validation
param = SCC_AST_CAST_TO(scc_ast_decl_t, decl);
Assert(param->base.type = SCC_AST_DECL_VAR); Assert(param->base.type = SCC_AST_DECL_VAR);
param->base.type = SCC_AST_DECL_PARAM; 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); scc_vec_push(*params, param);
if (!scc_parser_consume_if(parser, SCC_TOK_COMMA)) { if (!scc_parser_consume_if(parser, SCC_TOK_COMMA)) {
@@ -1129,7 +1142,7 @@ parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base,
} }
} }
scc_ast_node_t *_scc_parse_type(scc_parser_t *parser) { scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser) {
if (!scc_parse_is_decl_specifier_start(parser)) { if (!scc_parse_is_decl_specifier_start(parser)) {
return null; return null;
} }
@@ -1177,7 +1190,37 @@ scc_ast_node_t *_scc_parse_type(scc_parser_t *parser) {
} }
} }
return decl != null ? &decl->base : &type->base; scc_ast_node_t *type_or_decl = decl != null ? &decl->base : &type->base;
if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) {
scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl);
if (type->base.type == SCC_AST_TYPE_STRUCT ||
type->base.type == SCC_AST_TYPE_UNION) {
if (type->record.decl == null) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"record don't have a decl");
Panic();
}
decl = type->record.decl;
scc_free(type_or_decl); // FIXME
} else if (type->base.type == SCC_AST_TYPE_ENUM) {
if (type->enumeration.decl == null) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"enum don't have a decl");
Panic();
}
decl = type->enumeration.decl;
scc_free(type_or_decl); // FIXME
} else {
decl = scc_malloc(sizeof(scc_ast_decl_t));
scc_ast_decl_unsafe_val_init(decl, type, null, null);
}
} 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 {
SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration");
return null;
}
return decl;
} }
scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) {

View File

@@ -597,6 +597,53 @@ static void test_parser_unit(void) {
SCC_CHECK_AST(&stmt.base, SCC_CHECK_AST(&stmt.base,
"return (void){.data = (void *)0, .size = 0, .cap = 0};", "return (void){.data = (void *)0, .size = 0, .cap = 0};",
scc_parse_statement); scc_parse_statement);
scc_ast_expr_t lhs4;
scc_ast_expr_t lhs5;
scc_ast_expr_member_init(&lhs4, &lvalue, "a");
scc_ast_expr_member_init(&lhs5, &lhs4, "b");
scc_ast_expr_t lhs6;
scc_ast_expr_t lhs7;
scc_ast_expr_member_init(&lhs6, &lvalue, "c");
scc_ast_expr_array_subscript_init(&lhs7, &lhs6, &rl0);
scc_ast_expr_t *lhs_array_hard[] = {&lhs5, &lhs7};
scc_vec_unsafe_from_array(lhs_exprs, lhs_array_hard);
scc_ast_expr_t *rhs_array_hard[] = {&rhs2, &rhs3};
scc_vec_unsafe_from_array(rhs_exprs, rhs_array_hard);
scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs);
SCC_CHECK_AST(&expr.base, "(void){.a.b = 0, .c[0] = 0}",
scc_parse_expression);
}
{
// 测试 struct S; 仅标记声明
{
scc_ast_decl_t struct_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_struct_init(&struct_decl, "S", &empty_members);
SCC_CHECK_AST(&struct_decl.base, "struct S;",
scc_parse_declaration);
}
// 测试 union U; 仅标记声明
{
scc_ast_decl_t union_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_union_init(&union_decl, "U", &empty_members);
SCC_CHECK_AST(&union_decl.base, "union U;", scc_parse_declaration);
}
// 测试 enum E; 仅标记声明
{
scc_ast_decl_t enum_decl;
scc_ast_expr_vec_t empty_enumerators;
scc_vec_init(empty_enumerators);
scc_ast_decl_enum_init(&enum_decl, "E", &empty_enumerators);
SCC_CHECK_AST(&enum_decl.base, "enum E;", scc_parse_declaration);
}
} }
{ {
@@ -611,6 +658,88 @@ static void test_parser_unit(void) {
SCC_CHECK_AST(&str.base, "\"a\" \"b\"", scc_parse_expression); SCC_CHECK_AST(&str.base, "\"a\" \"b\"", scc_parse_expression);
} }
{
// 测试 int a = *(int*)b;
{
// 构造类型 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);
// 标识符 b
scc_ast_expr_t b_expr;
scc_ast_expr_identifier_init(&b_expr, "b");
// 类型转换 (int*)b
scc_ast_expr_t cast_expr;
scc_ast_expr_cast_init(&cast_expr, &ptr_to_int, &b_expr);
// 解引用 *(int*)b
scc_ast_expr_t deref_expr;
scc_ast_expr_unary_init(&deref_expr, SCC_AST_OP_INDIRECTION,
&cast_expr);
// 声明 int a = *(int*)b;
scc_ast_decl_t decl;
scc_ast_decl_val_init(&decl,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"a", &deref_expr);
SCC_CHECK_AST(&decl.base, "int a = *(int*)b;",
scc_parse_declaration);
}
// // 测试 int a, b;
// {
// scc_ast_decl_t decl_a, decl_b;
// scc_ast_decl_val_init(&decl_a,
// (scc_ast_type_t
// *)&scc_ast_builtin_type_int, "a", null);
// scc_ast_decl_val_init(&decl_b,
// (scc_ast_type_t
// *)&scc_ast_builtin_type_int, "b", null);
// scc_ast_decl_vec_t decl_vec;
// scc_vec_init(decl_vec);
// scc_vec_push(decl_vec, &decl_a);
// scc_vec_push(decl_vec, &decl_b);
// scc_ast_decl_t decl_list;
// scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数
// SCC_CHECK_AST(&decl_list.base, "int a, b;",
// scc_parse_declaration);
// }
// // 测试 int a = 1, b = 2;
// {
// scc_ast_expr_t lit1, lit2;
// scc_ast_expr_literal_int_init(&lit1, "1", false);
// scc_ast_expr_literal_int_init(&lit2, "2", false);
// scc_ast_decl_t decl_a, decl_b;
// scc_ast_decl_val_init(&decl_a,
// (scc_ast_type_t
// *)&scc_ast_builtin_type_int, "a", &lit1);
// scc_ast_decl_val_init(&decl_b,
// (scc_ast_type_t
// *)&scc_ast_builtin_type_int, "b", &lit2);
// scc_ast_decl_vec_t decl_vec;
// scc_vec_init(decl_vec);
// scc_vec_push(decl_vec, &decl_a);
// scc_vec_push(decl_vec, &decl_b);
// scc_ast_decl_t decl_list;
// scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数
// SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;",
// scc_parse_declaration);
// }
"__scc_builtin_va_arg(ag, int)";
"__scc_builtin_va_arg(ag, long long)";
}
{ {
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针) // int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤: // 步骤:
@@ -795,10 +924,16 @@ static void test_parser_expression(void) {
SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression); SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression);
// sizeof 表达式 // sizeof 表达式
// TODO scc_ast_expr_t sizeof_x_expr;
// scc_ast_expr_t sizeof_expr; scc_ast_expr_sizeof_init(&sizeof_x_expr, null, &x);
// scc_ast_expr_sizeof_expr_init(&sizeof_expr, &x); SCC_CHECK_AST(&sizeof_x_expr.base, "sizeof(x)", scc_parse_expression);
// SCC_CHECK_AST(&sizeof_expr.base, "sizeof x", scc_parse_expression);
scc_ast_expr_t sizeof_int_expr;
scc_ast_expr_sizeof_init(&sizeof_int_expr,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null);
SCC_CHECK_AST(&sizeof_int_expr.base, "sizeof(int)",
scc_parse_expression);
} }
// 4. 类型转换(示例: (int)x // 4. 类型转换(示例: (int)x
@@ -955,7 +1090,7 @@ static void test_parser_type(void) {
// 1. int // 1. int
{ {
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int", SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int",
_scc_parse_type); scc_parse_type_name);
} }
// 2. int * // 2. int *
@@ -963,7 +1098,7 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_int; scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init( scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type); SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name);
} }
// 3. int *[3] // 3. int *[3]
@@ -977,7 +1112,7 @@ static void test_parser_type(void) {
scc_ast_type_t array_of_ptr; scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_int, &size_3); 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); SCC_CHECK_AST(&array_of_ptr.base, "int *[3]", scc_parse_type_name);
} }
// 4. int (*)[3] // 4. int (*)[3]
@@ -992,7 +1127,8 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_array; scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_int); scc_ast_type_pointer_init(&ptr_to_array, &array_of_int);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]", _scc_parse_type); SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]",
scc_parse_type_name);
} }
// 5. int (*)[*] // 5. int (*)[*]
@@ -1005,7 +1141,7 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_array_var; scc_ast_type_t ptr_to_array_var;
scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var); scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var);
SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]", SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]",
_scc_parse_type); scc_parse_type_name);
} }
// 6. int *() // 6. int *()
@@ -1018,7 +1154,7 @@ static void test_parser_type(void) {
// 函数类型,返回 int*,无参数 // 函数类型,返回 int*,无参数
scc_ast_type_t func_type; scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_int, null); scc_ast_type_function_init(&func_type, &ptr_to_int, null);
SCC_CHECK_AST(&func_type.base, "int *()", _scc_parse_type); SCC_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name);
} }
// 7. int (*)(void) // 7. int (*)(void)
@@ -1037,7 +1173,8 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_func; scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_void); scc_ast_type_pointer_init(&ptr_to_func, &func_void);
SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)", _scc_parse_type); SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)",
scc_parse_type_name);
} }
// 8. int (*const [])(unsigned int, ...) // 8. int (*const [])(unsigned int, ...)
@@ -1078,51 +1215,59 @@ static void test_parser_type(void) {
SCC_CHECK_AST(&array_of_ptr.base, SCC_CHECK_AST(&array_of_ptr.base,
"int (*const [])(unsigned int, ...)", "int (*const [])(unsigned int, ...)",
_scc_parse_type); scc_parse_type_name);
} }
} }
// 1. 基本内置类型及组合 // 1. 基本内置类型及组合
{ {
// int // int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int", SCC_CHECK_AST(&scc_ast_builtin_type_int.base, "int",
_scc_parse_type); scc_parse_type_name);
// char // char
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_char, "char", SCC_CHECK_AST(&scc_ast_builtin_type_char.base, "char",
_scc_parse_type); scc_parse_type_name);
// long long // long long
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_long, SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long",
"long long", _scc_parse_type); scc_parse_type_name);
// long long
SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long int",
scc_parse_type_name);
// short
SCC_CHECK_AST(&scc_ast_builtin_type_short.base, "short int",
scc_parse_type_name);
// unsigned int // unsigned int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_unsigned_int, SCC_CHECK_AST(&scc_ast_builtin_type_unsigned_int.base, "unsigned int",
"unsigned int", _scc_parse_type); scc_parse_type_name);
// float // float
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_float, "float", SCC_CHECK_AST(&scc_ast_builtin_type_float.base, "float",
_scc_parse_type); scc_parse_type_name);
// double // double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_double, "double", SCC_CHECK_AST(&scc_ast_builtin_type_double.base, "double",
_scc_parse_type); scc_parse_type_name);
// void // void
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void", SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void",
_scc_parse_type); scc_parse_type_name);
// bool // bool
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool", SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool",
_scc_parse_type); scc_parse_type_name);
// long double // long double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double, SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double,
"long double", _scc_parse_type); "long double", scc_parse_type_name);
// _Complex double // _Complex double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double, SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double,
"double complex", _scc_parse_type); "double complex", scc_parse_type_name);
} }
// 2. 带类型限定符的基本类型 (const, volatile) // 2. 带类型限定符的基本类型 (const, volatile)
@@ -1130,20 +1275,20 @@ static void test_parser_type(void) {
// const int // const int
scc_ast_type_t const_int = scc_ast_builtin_type_int; scc_ast_type_t const_int = scc_ast_builtin_type_int;
const_int.quals.is_const = true; const_int.quals.is_const = true;
SCC_CHECK_AST(&const_int.base, "const int", _scc_parse_type); SCC_CHECK_AST(&const_int.base, "const int", scc_parse_type_name);
// volatile unsigned long // volatile unsigned long
scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long; scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long;
volatile_ulong.quals.is_volatile = true; volatile_ulong.quals.is_volatile = true;
SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long", SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long",
_scc_parse_type); scc_parse_type_name);
// const volatile char // const volatile char
scc_ast_type_t const_volatile_char = scc_ast_builtin_type_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_const = true;
const_volatile_char.quals.is_volatile = true; const_volatile_char.quals.is_volatile = true;
SCC_CHECK_AST(&const_volatile_char.base, "const volatile char", SCC_CHECK_AST(&const_volatile_char.base, "const volatile char",
_scc_parse_type); scc_parse_type_name);
} }
// 3. 指针类型 // 3. 指针类型
@@ -1152,33 +1297,35 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_int; scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_int, scc_ast_type_pointer_init(&ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int); (scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type); SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name);
// int ** // int **
scc_ast_type_t ptr_to_ptr_to_int; scc_ast_type_t ptr_to_ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_ptr_to_int, &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); SCC_CHECK_AST(&ptr_to_ptr_to_int.base, "int **", scc_parse_type_name);
// int * const (const pointer to int) // int * const (const pointer to int)
scc_ast_type_t const_ptr_to_int; scc_ast_type_t const_ptr_to_int;
scc_ast_type_pointer_init(&const_ptr_to_int, scc_ast_type_pointer_init(&const_ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int); (scc_ast_type_t *)&scc_ast_builtin_type_int);
const_ptr_to_int.quals.is_const = true; const_ptr_to_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_int.base, "int * const", _scc_parse_type); SCC_CHECK_AST(&const_ptr_to_int.base, "int * const",
scc_parse_type_name);
// const int * (pointer to const int) // const int * (pointer to const int)
scc_ast_type_t const_int_type = scc_ast_builtin_type_int; scc_ast_type_t const_int_type = scc_ast_builtin_type_int;
const_int_type.quals.is_const = true; const_int_type.quals.is_const = true;
scc_ast_type_t ptr_to_const_int; scc_ast_type_t ptr_to_const_int;
scc_ast_type_pointer_init(&ptr_to_const_int, &const_int_type); 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); SCC_CHECK_AST(&ptr_to_const_int.base, "const int *",
scc_parse_type_name);
// const int * const (const pointer to const int) // const int * const (const pointer to const int)
scc_ast_type_t const_ptr_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); scc_ast_type_pointer_init(&const_ptr_to_const_int, &const_int_type);
const_ptr_to_const_int.quals.is_const = true; const_ptr_to_const_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const", SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const",
_scc_parse_type); scc_parse_type_name);
// volatile int * restrict // volatile int * restrict
scc_ast_type_t volatile_int = scc_ast_builtin_type_int; scc_ast_type_t volatile_int = scc_ast_builtin_type_int;
@@ -1187,7 +1334,7 @@ static void test_parser_type(void) {
scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int); scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int);
restrict_ptr_to_volatile_int.quals.is_restrict = true; restrict_ptr_to_volatile_int.quals.is_restrict = true;
SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base, SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base,
"volatile int * restrict", _scc_parse_type); "volatile int * restrict", scc_parse_type_name);
} }
// 4. 数组类型 // 4. 数组类型
@@ -1199,14 +1346,15 @@ static void test_parser_type(void) {
scc_ast_type_array_init(&array_of_5_int, scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5); &size_5);
SCC_CHECK_AST(&array_of_5_int.base, "int [5]", _scc_parse_type); SCC_CHECK_AST(&array_of_5_int.base, "int [5]", scc_parse_type_name);
// int [] (不完整类型) // int [] (不完整类型)
scc_ast_type_t array_of_int_unknown; scc_ast_type_t array_of_int_unknown;
scc_ast_type_array_init(&array_of_int_unknown, scc_ast_type_array_init(&array_of_int_unknown,
(scc_ast_type_t *)&scc_ast_builtin_type_int, (scc_ast_type_t *)&scc_ast_builtin_type_int,
null); null);
SCC_CHECK_AST(&array_of_int_unknown.base, "int []", _scc_parse_type); SCC_CHECK_AST(&array_of_int_unknown.base, "int []",
scc_parse_type_name);
// // int [*] (变长数组原型中的不定长数组) // // int [*] (变长数组原型中的不定长数组)
// FIXME // FIXME
@@ -1228,7 +1376,7 @@ static void test_parser_type(void) {
&inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3); &inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3);
scc_ast_type_t outer_array; scc_ast_type_t outer_array;
scc_ast_type_array_init(&outer_array, &inner_array, &size_5); scc_ast_type_array_init(&outer_array, &inner_array, &size_5);
SCC_CHECK_AST(&outer_array.base, "int [5][3]", _scc_parse_type); SCC_CHECK_AST(&outer_array.base, "int [5][3]", scc_parse_type_name);
// int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性 // int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性
scc_ast_type_t array_of_5_int2; scc_ast_type_t array_of_5_int2;
@@ -1237,7 +1385,7 @@ static void test_parser_type(void) {
&size_5); &size_5);
scc_ast_type_t ptr_to_array; scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2); scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", _scc_parse_type); SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", scc_parse_type_name);
// int *[5] (指针数组) // int *[5] (指针数组)
scc_ast_type_t ptr_to_int2; scc_ast_type_t ptr_to_int2;
@@ -1245,14 +1393,14 @@ static void test_parser_type(void) {
(scc_ast_type_t *)&scc_ast_builtin_type_int); (scc_ast_type_t *)&scc_ast_builtin_type_int);
scc_ast_type_t array_of_5_ptr; scc_ast_type_t array_of_5_ptr;
scc_ast_type_array_init(&array_of_5_ptr, &ptr_to_int2, &size_5); 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); SCC_CHECK_AST(&array_of_5_ptr.base, "int *[5]", scc_parse_type_name);
// const int [5] (数组元素为const int) // const int [5] (数组元素为const int)
scc_ast_type_t const_int2 = scc_ast_builtin_type_int; scc_ast_type_t const_int2 = scc_ast_builtin_type_int;
const_int2.quals.is_const = true; const_int2.quals.is_const = true;
scc_ast_type_t const_array; scc_ast_type_t const_array;
scc_ast_type_array_init(&const_array, &const_int2, &size_5); scc_ast_type_array_init(&const_array, &const_int2, &size_5);
SCC_CHECK_AST(&const_array.base, "const int [5]", _scc_parse_type); SCC_CHECK_AST(&const_array.base, "const int [5]", scc_parse_type_name);
} }
// 5. 函数类型 // 5. 函数类型
@@ -1267,7 +1415,7 @@ static void test_parser_type(void) {
scc_ast_type_function_init(&func_void, scc_ast_type_function_init(&func_void,
(scc_ast_type_t *)&scc_ast_builtin_type_int, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params); &func_params);
SCC_CHECK_AST(&func_void.base, "int (void)", _scc_parse_type); SCC_CHECK_AST(&func_void.base, "int (void)", scc_parse_type_name);
// // int () (无参数声明,非原型) // // int () (无参数声明,非原型)
// // // //
@@ -1291,7 +1439,7 @@ static void test_parser_type(void) {
(scc_ast_type_t *)&scc_ast_builtin_type_int, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&params); &params);
SCC_CHECK_AST(&func_with_params.base, "int (int, float)", SCC_CHECK_AST(&func_with_params.base, "int (int, float)",
_scc_parse_type); scc_parse_type_name);
// int (int, ...) (可变参数) // int (int, ...) (可变参数)
scc_ast_decl_t param_int, param_var; scc_ast_decl_t param_int, param_var;
@@ -1309,7 +1457,8 @@ static void test_parser_type(void) {
scc_ast_type_function_init(&func_varargs, scc_ast_type_function_init(&func_varargs,
(scc_ast_type_t *)&scc_ast_builtin_type_int, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&params_var); &params_var);
SCC_CHECK_AST(&func_varargs.base, "int (int, ...)", _scc_parse_type); SCC_CHECK_AST(&func_varargs.base, "int (int, ...)",
scc_parse_type_name);
// int (*)(int) (函数指针) // int (*)(int) (函数指针)
scc_ast_decl_t param; scc_ast_decl_t param;
@@ -1324,7 +1473,7 @@ static void test_parser_type(void) {
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, &params2); &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, &params2);
scc_ast_type_t ptr_to_func; scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type); scc_ast_type_pointer_init(&ptr_to_func, &func_type);
SCC_CHECK_AST(&ptr_to_func.base, "int (*)(int)", _scc_parse_type); SCC_CHECK_AST(&ptr_to_func.base, "int (*)(int)", scc_parse_type_name);
} }
// 6. 函数指针和复杂声明符 // 6. 函数指针和复杂声明符
@@ -1360,7 +1509,7 @@ static void test_parser_type(void) {
scc_ast_type_pointer_init(&ptr_to_func, &func_type); scc_ast_type_pointer_init(&ptr_to_func, &func_type);
SCC_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]", SCC_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]",
_scc_parse_type); scc_parse_type_name);
// int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针) // int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针)
// 1) 函数类型:返回 int无参数 // 1) 函数类型:返回 int无参数
@@ -1383,7 +1532,7 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_array_of_ptr; 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_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_CHECK_AST(&ptr_to_array_of_ptr.base, "int (*(*)[5])(void)",
_scc_parse_type); scc_parse_type_name);
} }
// 7. 结构体/联合/枚举类型(标记和定义) // 7. 结构体/联合/枚举类型(标记和定义)
@@ -1392,7 +1541,7 @@ static void test_parser_type(void) {
scc_ast_type_t struct_tag; scc_ast_type_t struct_tag;
scc_ast_type_struct_init(&struct_tag, "S", scc_ast_type_struct_init(&struct_tag, "S",
null); // name="S", members=null null); // name="S", members=null
SCC_CHECK_AST(&struct_tag.base, "struct S", _scc_parse_type); SCC_CHECK_AST(&struct_tag.base, "struct S", scc_parse_type_name);
// struct { int x; } (匿名结构体定义) // struct { int x; } (匿名结构体定义)
scc_ast_decl_t field; scc_ast_decl_t field;
@@ -1406,18 +1555,19 @@ static void test_parser_type(void) {
scc_ast_decl_struct_init(&struct_def, null, &fields); scc_ast_decl_struct_init(&struct_def, null, &fields);
scc_ast_type_t struct_type; scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_def); scc_ast_type_struct_init(&struct_type, null, &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct { int x; }", _scc_parse_type); SCC_CHECK_AST(&struct_type.base, "struct { int x; }",
scc_parse_type_name);
scc_vec_init(fields); scc_vec_init(fields);
scc_vec_push(fields, &field); scc_vec_push(fields, &field);
scc_ast_decl_struct_init(&struct_def, "A", &fields); scc_ast_decl_struct_init(&struct_def, "A", &fields);
scc_ast_type_struct_init(&struct_type, "A", &struct_def); scc_ast_type_struct_init(&struct_type, "A", &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct A { int x; }", SCC_CHECK_AST(&struct_type.base, "struct A { int x; }",
_scc_parse_type); scc_parse_type_name);
// union U (不完整类型) // union U (不完整类型)
scc_ast_type_t union_tag; scc_ast_type_t union_tag;
scc_ast_type_union_init(&union_tag, "U", null); scc_ast_type_union_init(&union_tag, "U", null);
SCC_CHECK_AST(&union_tag.base, "union U", _scc_parse_type); SCC_CHECK_AST(&union_tag.base, "union U", scc_parse_type_name);
// union { int a; float b; } (匿名联合定义) // union { int a; float b; } (匿名联合定义)
scc_ast_decl_t field_a, field_b; scc_ast_decl_t field_a, field_b;
@@ -1435,16 +1585,16 @@ static void test_parser_type(void) {
scc_ast_type_t union_type; scc_ast_type_t union_type;
scc_ast_type_union_init(&union_type, null, &union_def); scc_ast_type_union_init(&union_type, null, &union_def);
SCC_CHECK_AST(&union_type.base, "union { int a; float b; }", SCC_CHECK_AST(&union_type.base, "union { int a; float b; }",
_scc_parse_type); scc_parse_type_name);
scc_ast_decl_union_init(&union_def, "Union", &fields_union); scc_ast_decl_union_init(&union_def, "Union", &fields_union);
scc_ast_type_union_init(&union_type, "Union", &union_def); scc_ast_type_union_init(&union_type, "Union", &union_def);
SCC_CHECK_AST(&union_type.base, "union Union { int a; float b; }", SCC_CHECK_AST(&union_type.base, "union Union { int a; float b; }",
_scc_parse_type); scc_parse_type_name);
// enum E (不完整类型) // enum E (不完整类型)
scc_ast_type_t enum_tag; scc_ast_type_t enum_tag;
scc_ast_type_enum_init(&enum_tag, "E", null); scc_ast_type_enum_init(&enum_tag, "E", null);
SCC_CHECK_AST(&enum_tag.base, "enum E", _scc_parse_type); SCC_CHECK_AST(&enum_tag.base, "enum E", scc_parse_type_name);
// enum { RED, GREEN, BLUE } (匿名枚举定义) // enum { RED, GREEN, BLUE } (匿名枚举定义)
scc_ast_expr_t red, green, blue; scc_ast_expr_t red, green, blue;
@@ -1460,13 +1610,13 @@ static void test_parser_type(void) {
scc_ast_type_t enum_type; scc_ast_type_t enum_type;
scc_ast_type_enum_init(&enum_type, null, &enum_def); scc_ast_type_enum_init(&enum_type, null, &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }", SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }",
_scc_parse_type); scc_parse_type_name);
scc_vec_unsafe_from_array(enumerators, array); scc_vec_unsafe_from_array(enumerators, array);
scc_ast_decl_enum_init(&enum_def, "E", &enumerators); scc_ast_decl_enum_init(&enum_def, "E", &enumerators);
scc_ast_type_enum_init(&enum_type, "E", &enum_def); scc_ast_type_enum_init(&enum_type, "E", &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum E { RED, GREEN, BLUE, }", SCC_CHECK_AST(&enum_type.base, "enum E { RED, GREEN, BLUE, }",
_scc_parse_type); scc_parse_type_name);
} }
// 8. typedef 类型 // 8. typedef 类型
@@ -1510,7 +1660,7 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_array; scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_ptr); scc_ast_type_pointer_init(&ptr_to_array, &array_of_ptr);
SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]", SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]",
_scc_parse_type); scc_parse_type_name);
// float (*(*)(int, ...))() // float (*(*)(int, ...))()
// 1) float 类型作为内部函数返回类型 // 1) float 类型作为内部函数返回类型
@@ -1544,7 +1694,7 @@ static void test_parser_type(void) {
scc_ast_type_t ptr_to_outer_func; scc_ast_type_t ptr_to_outer_func;
scc_ast_type_pointer_init(&ptr_to_outer_func, &outer_func); scc_ast_type_pointer_init(&ptr_to_outer_func, &outer_func);
SCC_CHECK_AST(&ptr_to_outer_func.base, "float (*(*)(int, ...))()", SCC_CHECK_AST(&ptr_to_outer_func.base, "float (*(*)(int, ...))()",
_scc_parse_type); scc_parse_type_name);
} }
} }

View File

@@ -1,7 +1,7 @@
#ifndef __SMCC_UTILS_H__ #ifndef __SMCC_UTILS_H__
#define __SMCC_UTILS_H__ #define __SMCC_UTILS_H__
#include "kllist.h" // #include "kllist.h"
#include "scc_hashtable.h" #include "scc_hashtable.h"
#include "scc_strpool.h" #include "scc_strpool.h"
#include <scc_core.h> #include <scc_core.h>

View File

@@ -694,12 +694,11 @@ class SccCompiler(Compiler):
# cmd = ["clang"] + flags + ["-c", str(source), "-o", str(output)] # cmd = ["clang"] + flags + ["-c", str(source), "-o", str(output)]
cmd = [ cmd = [
"scc", "scc",
"--emit-pp", # "--emit-pp",
"-T",
"-o", "-o",
str(output), str(output),
str(source), str(source),
"-I",
"scc_include",
] ]
for inc in includes: for inc in includes:
cmd += ["-I", f"{inc}"] cmd += ["-I", f"{inc}"]