feat(ast): 重构AST节点类型定义并实现数组下标访问
- 将scc_ast_node_type_t重命名为scc_ast_node_kind_t以提高语义清晰度 - 为scc_ast_node结构体添加名称定义 - 更新所有相关头文件中的类型引用 - 实现数组下标表达式的IR转换逻辑 - 添加对sizeof和alignof表达式的基本支持 fix(ast2ir): 修复表达式求值和类型处理问题 - 修复数组类型退化为指针的逻辑 - 修复变量声明初始化值检查条件 - 添加结构体和枚举类型的IR生成支持 - 移除未使用的代码段 refactor(ir): 完善IR上下文错误处理 - 为未处理的类型标签添加恐慌处理 - 修复联合类型的哈希计算 chore(build): 更新依赖项配置 - 修正lexer模块中的依赖项名称 style(parser): 清理解析器代码 - 移除未使用的类型哈希表 - 更新语义分析回调函数签名 - 添加属性语法的占位符实现 - 完善内存清理逻辑 test: 添加数组下标和枚举测试用例 - 新增15_array_subscript.c测试数组下标访问 - 新增16_enum.c测试枚举类型功能 - 更新期望结果配置文件
This commit is contained in:
@@ -79,10 +79,10 @@ typedef enum {
|
|||||||
scc_ast_translation_unit_t_BEGIN,
|
scc_ast_translation_unit_t_BEGIN,
|
||||||
SCC_AST_TRANSLATION_UNIT, // 翻译单元(根节点)
|
SCC_AST_TRANSLATION_UNIT, // 翻译单元(根节点)
|
||||||
scc_ast_translation_unit_t_END,
|
scc_ast_translation_unit_t_END,
|
||||||
} scc_ast_node_type_t;
|
} scc_ast_node_kind_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct scc_ast_node {
|
||||||
scc_ast_node_type_t type;
|
scc_ast_node_kind_t type;
|
||||||
scc_pos_t loc;
|
scc_pos_t loc;
|
||||||
} scc_ast_node_t;
|
} scc_ast_node_t;
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
|
static inline void _scc_ast_decl_record_init(scc_ast_decl_t *decl,
|
||||||
scc_ast_node_type_t type,
|
scc_ast_node_kind_t type,
|
||||||
const char *name,
|
const char *name,
|
||||||
scc_ast_decl_vec_t *fields_move,
|
scc_ast_decl_vec_t *fields_move,
|
||||||
scc_pos_t loc) {
|
scc_pos_t loc) {
|
||||||
@@ -352,7 +352,7 @@ static inline void scc_ast_expr_array_subscript_init(scc_ast_expr_t *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void _scc_ast_expr_member_init(scc_ast_expr_t *expr,
|
static inline void _scc_ast_expr_member_init(scc_ast_expr_t *expr,
|
||||||
scc_ast_node_type_t type,
|
scc_ast_node_kind_t type,
|
||||||
scc_ast_expr_t *object,
|
scc_ast_expr_t *object,
|
||||||
const char *member,
|
const char *member,
|
||||||
scc_pos_t loc) {
|
scc_pos_t loc) {
|
||||||
@@ -441,7 +441,7 @@ static inline void scc_ast_expr_compound_init(scc_ast_expr_t *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
|
static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
|
||||||
scc_ast_node_type_t type,
|
scc_ast_node_kind_t type,
|
||||||
const char *value, cbool owned,
|
const char *value, cbool owned,
|
||||||
scc_pos_t loc) {
|
scc_pos_t loc) {
|
||||||
Assert(expr != nullptr && value != nullptr);
|
Assert(expr != nullptr && value != nullptr);
|
||||||
@@ -550,7 +550,7 @@ static inline void scc_ast_type_function_init(scc_ast_type_t *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
|
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
|
||||||
scc_ast_node_type_t type_kind,
|
scc_ast_node_kind_t type_kind,
|
||||||
const char *name,
|
const char *name,
|
||||||
scc_ast_decl_t *decl,
|
scc_ast_decl_t *decl,
|
||||||
scc_pos_t loc) {
|
scc_pos_t loc) {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ static const char *node_type_names[] = {
|
|||||||
[scc_ast_translation_unit_t_END] = "ERROR",
|
[scc_ast_translation_unit_t_END] = "ERROR",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *get_node_type_str(scc_ast_node_type_t type) {
|
static const char *get_node_type_str(scc_ast_node_kind_t type) {
|
||||||
return node_type_names[type];
|
return node_type_names[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ scc_ir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx,
|
|||||||
scc_ast_expr_t *expr,
|
scc_ast_expr_t *expr,
|
||||||
scc_ir_value_ref_t lhs,
|
scc_ir_value_ref_t lhs,
|
||||||
scc_ir_value_ref_t rhs) {
|
scc_ir_value_ref_t rhs) {
|
||||||
scc_ir_bblock_ref_t start_block =
|
// scc_ir_bblock_ref_t start_block =
|
||||||
scc_ir_builder_current_bblock(&ctx->builder);
|
// scc_ir_builder_current_bblock(&ctx->builder);
|
||||||
|
|
||||||
scc_ir_bblock_ref_t right_block =
|
scc_ir_bblock_ref_t right_block =
|
||||||
scc_ir_builder_bblock(&ctx->builder, "logic_right");
|
scc_ir_builder_bblock(&ctx->builder, "logic_right");
|
||||||
@@ -421,12 +421,39 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
|||||||
scc_vec_free(args);
|
scc_vec_free(args);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
|
case SCC_AST_EXPR_ARRAY_SUBSCRIPT: {
|
||||||
|
// 1. 计算数组/指针基址(右值,得到地址)
|
||||||
|
scc_ir_value_ref_t base_ptr =
|
||||||
|
scc_ast2ir_expr(ctx, expr->subscript.array, true);
|
||||||
|
// 2. 计算下标值
|
||||||
|
scc_ir_value_ref_t index =
|
||||||
|
scc_ast2ir_expr(ctx, expr->subscript.index, false);
|
||||||
|
// 3. 生成 getptr(GEP)
|
||||||
|
scc_ir_value_ref_t elem_ptr =
|
||||||
|
scc_ir_builder_get_ptr(&ctx->builder, base_ptr, index);
|
||||||
|
// 4. 根据左值/右值返回
|
||||||
|
if (is_lvalue) {
|
||||||
|
return elem_ptr; // 作为左值:返回地址
|
||||||
|
} else {
|
||||||
|
return scc_ir_builder_load(&ctx->builder,
|
||||||
|
elem_ptr); // 作为右值:加载值
|
||||||
|
}
|
||||||
|
}
|
||||||
// SCC_AST_EXPR_MEMBER, // 成员访问 .
|
// SCC_AST_EXPR_MEMBER, // 成员访问 .
|
||||||
// SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
|
// SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
|
||||||
// SCC_AST_EXPR_CAST, // 类型转换
|
// SCC_AST_EXPR_CAST, // 类型转换
|
||||||
// SCC_AST_EXPR_SIZE_OF, // sizeof
|
case SCC_AST_EXPR_SIZE_OF: {
|
||||||
// SCC_AST_EXPR_ALIGN_OF, // _Alignof
|
scc_ir_const_int_t val;
|
||||||
|
val.int64 = 1;
|
||||||
|
return scc_ir_builder_const_int(
|
||||||
|
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
|
||||||
|
}
|
||||||
|
case SCC_AST_EXPR_ALIGN_OF: {
|
||||||
|
scc_ir_const_int_t val;
|
||||||
|
val.int64 = 1;
|
||||||
|
return scc_ir_builder_const_int(
|
||||||
|
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
|
||||||
|
}
|
||||||
// SCC_AST_EXPR_COMPOUND, // 复合字面量
|
// SCC_AST_EXPR_COMPOUND, // 复合字面量
|
||||||
// SCC_AST_EXPR_LVALUE, // 右值
|
// SCC_AST_EXPR_LVALUE, // 右值
|
||||||
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
|
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
|
||||||
@@ -491,7 +518,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
|||||||
// 右值:如果是数组类型,退化为指针(返回地址)
|
// 右值:如果是数组类型,退化为指针(返回地址)
|
||||||
scc_ir_type_t *ir_type =
|
scc_ir_type_t *ir_type =
|
||||||
scc_ir_module_get_type_by_value(ctx->builder.ctx.module, in);
|
scc_ir_module_get_type_by_value(ctx->builder.ctx.module, in);
|
||||||
Assert(ir_type->tag == SCC_IR_TYPE_PTR);
|
if (ir_type->tag == SCC_IR_TYPE_PTR) {
|
||||||
scc_ir_type_t *target_type = scc_ir_module_get_type(
|
scc_ir_type_t *target_type = scc_ir_module_get_type(
|
||||||
ctx->builder.ctx.module, ir_type->data.pointer.base);
|
ctx->builder.ctx.module, ir_type->data.pointer.base);
|
||||||
if (target_type->tag == SCC_IR_TYPE_ARRAY) {
|
if (target_type->tag == SCC_IR_TYPE_ARRAY) {
|
||||||
@@ -502,6 +529,9 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
|||||||
// 标量类型:加载值
|
// 标量类型:加载值
|
||||||
return scc_ir_builder_load(&ctx->builder, in);
|
return scc_ir_builder_load(&ctx->builder, in);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +749,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
|
|||||||
}
|
}
|
||||||
scc_ir_value_ref_t init_val_node =
|
scc_ir_value_ref_t init_val_node =
|
||||||
scc_ast2ir_expr(ctx, decl->var.init, false);
|
scc_ast2ir_expr(ctx, decl->var.init, false);
|
||||||
Assert(init_val_node != nullptr);
|
Assert(init_val_node != SCC_IR_REF_nullptr);
|
||||||
|
|
||||||
// FIXME array auto calucate size
|
// FIXME array auto calucate size
|
||||||
scc_ir_type_t *ir_type =
|
scc_ir_type_t *ir_type =
|
||||||
@@ -802,10 +832,29 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCC_AST_DECL_STRUCT:
|
case SCC_AST_DECL_STRUCT:
|
||||||
break;
|
|
||||||
case SCC_AST_DECL_UNION:
|
case SCC_AST_DECL_UNION:
|
||||||
|
scc_vec_foreach(decl->record.fields, i) {
|
||||||
|
scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i);
|
||||||
|
scc_ast2ir_decl(ctx, item);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCC_AST_DECL_ENUM:
|
case SCC_AST_DECL_ENUM:
|
||||||
|
scc_ir_const_int_t val;
|
||||||
|
val.int32 = 0;
|
||||||
|
scc_vec_foreach(decl->record.fields, i) {
|
||||||
|
scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i);
|
||||||
|
Assert(item->base.type == SCC_AST_DECL_VAR);
|
||||||
|
if (item->var.init) {
|
||||||
|
Assert(item->var.init->base.type == SCC_AST_EXPR_INT_LITERAL);
|
||||||
|
parse_lexme2const_int(item->var.init->literal.lexme, &val);
|
||||||
|
}
|
||||||
|
scc_ir_value_ref_t item_val_ref = scc_ir_builder_const_int(
|
||||||
|
&ctx->builder, scc_ir_builder_type_i32(&ctx->builder), val);
|
||||||
|
scc_hashtable_set(&ctx->decl2ir_ref, item,
|
||||||
|
(void *)(usize)item_val_ref);
|
||||||
|
val.int32 += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCC_AST_DECL_TYPEDEF:
|
case SCC_AST_DECL_TYPEDEF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -54,14 +54,17 @@ static u32 hash_type(const void *_key) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SCC_IR_TYPE_STRUCT:
|
case SCC_IR_TYPE_STRUCT:
|
||||||
|
case SCC_IR_TYPE_UNION:
|
||||||
|
return 0;
|
||||||
case SCC_IR_TYPE_VECTOR:
|
case SCC_IR_TYPE_VECTOR:
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
Panic("Invalid type tag %d", key->tag);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_type(const void *_key1, const void *_key2) {
|
static int cmp_type(const void *_key1, const void *_key2) {
|
||||||
const scc_ir_type_t *key1 = _key1, *key2 = _key2;
|
const scc_ir_type_t *key1 = _key1, *key2 = _key2;
|
||||||
Assert(key1 != nullptr && key2 != nullptr);
|
Assert(key1 != nullptr && key2 != nullptr);
|
||||||
|
|||||||
@@ -77,11 +77,10 @@ static void win64_finalize(scc_frame_alloc_ops_t *ops) {
|
|||||||
current_offset -= (align - rem);
|
current_offset -= (align - rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_offset -= slot->size;
|
||||||
slot->offset = current_offset;
|
slot->offset = current_offset;
|
||||||
scc_hashtable_set(&self->offset_cache, (void *)(intptr_t)slot->slot_id,
|
scc_hashtable_set(&self->offset_cache, (void *)(intptr_t)slot->slot_id,
|
||||||
(void *)(intptr_t)slot->offset);
|
(void *)(intptr_t)slot->offset);
|
||||||
|
|
||||||
current_offset -= slot->size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int total_size = -current_offset + 32; // 加上影子空间
|
int total_size = -current_offset + 32; // 加上影子空间
|
||||||
|
|||||||
@@ -294,11 +294,11 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
|||||||
scc_ir_value_t *src_addr = scc_ir_module_get_value(
|
scc_ir_value_t *src_addr = scc_ir_module_get_value(
|
||||||
GET_MODULE(ctx), value->data.get_ptr.src_addr);
|
GET_MODULE(ctx), value->data.get_ptr.src_addr);
|
||||||
Assert(src_addr != nullptr);
|
Assert(src_addr != nullptr);
|
||||||
|
if (value->data.get_ptr.index == 0) {
|
||||||
if (src_addr->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
|
if (src_addr->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
|
||||||
// 全局变量:RIP相对寻址
|
// 全局变量:RIP相对寻址
|
||||||
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX,
|
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode,
|
||||||
0);
|
SCC_AMD64_RAX, 0);
|
||||||
usize sym_idx =
|
usize sym_idx =
|
||||||
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
|
sccf_builder_get_symbol_idx(ctx->builder, src_addr->name);
|
||||||
Assert(sym_idx != 0);
|
Assert(sym_idx != 0);
|
||||||
@@ -318,14 +318,22 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
|||||||
src_loc.kind = SCC_REG_KIND_STACK_ADDR;
|
src_loc.kind = SCC_REG_KIND_STACK_ADDR;
|
||||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
||||||
} else {
|
} else {
|
||||||
// 其他情况(如链式 getptr):源地址值已经存储在某个位置,直接加载到
|
// 其他情况(如链式
|
||||||
// RAX
|
// getptr):源地址值已经存储在某个位置,直接加载到 RAX
|
||||||
scc_reg_loc_t src_loc;
|
scc_reg_loc_t src_loc;
|
||||||
parse_location(ctx, &src_loc, value->data.get_ptr.src_addr);
|
parse_location(ctx, &src_loc, value->data.get_ptr.src_addr);
|
||||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
store_value_from_reg(ctx, &loc_res, SCC_AMD64_RAX);
|
store_value_from_reg(ctx, &loc_res, SCC_AMD64_RAX);
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
scc_ir_value_t *index = scc_ir_module_get_value(
|
||||||
|
GET_MODULE(ctx), value->data.get_ptr.index);
|
||||||
|
Assert(index != nullptr &&
|
||||||
|
index->tag == SCC_IR_VALUE_TAG_CONST_INT);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
|
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ void scc_ir2mcode_init(scc_ir2mcode_ctx_t *ctx, scc_ir_cprog_t *cprog,
|
|||||||
sccf_builder_init(ctx->builder);
|
sccf_builder_init(ctx->builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx) {}
|
void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx) {
|
||||||
|
// TODO drop all objs
|
||||||
|
scc_ir_cprog_drop(ctx->cprog);
|
||||||
|
}
|
||||||
|
|
||||||
void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx);
|
void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ version = "0.1.0"
|
|||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "scc_core", path = "../../runtime/scc_core" },
|
{ name = "scc_core", path = "../../runtime/scc_core" },
|
||||||
{ name = "lex_parser", path = "../sstream" },
|
{ name = "scc_sstream", path = "../sstream" },
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ typedef struct scc_parser {
|
|||||||
scc_lexer_tok_ring_t *ring;
|
scc_lexer_tok_ring_t *ring;
|
||||||
usize checkpoint;
|
usize checkpoint;
|
||||||
|
|
||||||
scc_hashtable_t type_ht;
|
|
||||||
|
|
||||||
scc_sema_callbacks_t sema_callbacks;
|
scc_sema_callbacks_t sema_callbacks;
|
||||||
scc_ast_translation_unit_t *translation_unit;
|
scc_ast_translation_unit_t *translation_unit;
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @brief 语义分析回调函数类型
|
* @brief 语义分析回调函数类型
|
||||||
*/
|
*/
|
||||||
typedef void (*scc_sema_callback_t)(void *context,
|
typedef void (*scc_sema_callback_t)(void *context,
|
||||||
scc_ast_node_type_t node_type, void *node);
|
scc_ast_node_kind_t node_type, void *node);
|
||||||
|
|
||||||
typedef scc_ast_type_t *(*scc_sema_got_type_t)(void *context, const char *name);
|
typedef scc_ast_type_t *(*scc_sema_got_type_t)(void *context, const char *name);
|
||||||
|
|
||||||
|
|||||||
32
libs/parser/src/parse_attr.c
Normal file
32
libs/parser/src/parse_attr.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
ISO/IEC 9899:2024 (en) — N3220 working draft
|
||||||
|
|
||||||
|
(6.7.13.2) attribute-specifier-sequence:
|
||||||
|
attribute-specifier-sequence(opt) attribute-specifier
|
||||||
|
(6.7.13.2) attribute-specifier:
|
||||||
|
[ [ attribute-list ] ]
|
||||||
|
(6.7.13.2) attribute-list:
|
||||||
|
attribute(opt)
|
||||||
|
attribute-list , attribute(opt)
|
||||||
|
(6.7.13.2) attribute:
|
||||||
|
attribute-token attribute-argument-clause(opt)
|
||||||
|
(6.7.13.2) attribute-token:
|
||||||
|
standard-attribute
|
||||||
|
attribute-prefixed-token
|
||||||
|
(6.7.13.2) standard-attribute:
|
||||||
|
identifier
|
||||||
|
(6.7.13.2) attribute-prefixed-token:
|
||||||
|
attribute-prefix :: identifier
|
||||||
|
(6.7.13.2) attribute-prefix:
|
||||||
|
identifier
|
||||||
|
(6.7.13.2) attribute-argument-clause:
|
||||||
|
( balanced-token-sequence(opt) )
|
||||||
|
(6.7.13.2) balanced-token-sequence:
|
||||||
|
balanced-token
|
||||||
|
balanced-token-sequence balanced-token
|
||||||
|
(6.7.13.2) balanced-token:
|
||||||
|
( balanced-token-sequence(opt) )
|
||||||
|
[ balanced-token-sequence(opt) ]
|
||||||
|
{ balanced-token-sequence(opt) }
|
||||||
|
any token other than a parenthesis, a bracket, or a brace
|
||||||
|
*/
|
||||||
@@ -537,7 +537,7 @@ static scc_ast_type_t *build_type_from_info(type_spec_info_t *info,
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
|
static scc_ast_type_t *parse_record_type(scc_parser_t *parser,
|
||||||
scc_ast_node_type_t type_kind) {
|
scc_ast_node_kind_t type_kind) {
|
||||||
/*
|
/*
|
||||||
(6.7.2.1)
|
(6.7.2.1)
|
||||||
struct-or-union-specifier:
|
struct-or-union-specifier:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <parser_utils.h>
|
#include <parser_utils.h>
|
||||||
#include <scc_parser.h>
|
#include <scc_parser.h>
|
||||||
|
|
||||||
static void dummy_sema_callback(void *context, scc_ast_node_type_t node_type,
|
static void dummy_sema_callback(void *context, scc_ast_node_kind_t node_type,
|
||||||
void *node) {
|
void *node) {
|
||||||
(void)context;
|
(void)context;
|
||||||
(void)node_type;
|
(void)node_type;
|
||||||
@@ -49,6 +49,8 @@ void scc_parser_init(scc_parser_t *parser, scc_lexer_tok_ring_t *tok_ring,
|
|||||||
|
|
||||||
void scc_parser_drop(scc_parser_t *parser) {
|
void scc_parser_drop(scc_parser_t *parser) {
|
||||||
// TODO: 释放 AST 内存
|
// TODO: 释放 AST 内存
|
||||||
|
scc_ring_free(*parser->ring);
|
||||||
|
scc_sema_drop(&parser->sema_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
|
scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <scc_sema.h>
|
#include <scc_sema.h>
|
||||||
#include <sema_symtab.h>
|
#include <sema_symtab.h>
|
||||||
|
|
||||||
static void type_callback(void *context, scc_ast_node_type_t node_type,
|
static void type_callback(void *context, scc_ast_node_kind_t node_type,
|
||||||
void *node) {
|
void *node) {
|
||||||
scc_sema_symtab_t *sema_symtab = context;
|
scc_sema_symtab_t *sema_symtab = context;
|
||||||
(void)context;
|
(void)context;
|
||||||
@@ -11,7 +11,7 @@ static void type_callback(void *context, scc_ast_node_type_t node_type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expr_callback(void *context, scc_ast_node_type_t node_type,
|
static void expr_callback(void *context, scc_ast_node_kind_t node_type,
|
||||||
void *node) {
|
void *node) {
|
||||||
scc_sema_symtab_t *sema_symtab = context;
|
scc_sema_symtab_t *sema_symtab = context;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ static void expr_callback(void *context, scc_ast_node_type_t node_type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stmt_callback(void *context, scc_ast_node_type_t node_type,
|
static void stmt_callback(void *context, scc_ast_node_kind_t node_type,
|
||||||
void *node) {
|
void *node) {
|
||||||
scc_sema_symtab_t *sema_symtab = context;
|
scc_sema_symtab_t *sema_symtab = context;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ static void stmt_callback(void *context, scc_ast_node_type_t node_type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decl_callback(void *context, scc_ast_node_type_t node_type,
|
static void decl_callback(void *context, scc_ast_node_kind_t node_type,
|
||||||
void *node) {
|
void *node) {
|
||||||
scc_sema_symtab_t *sema_symtab = context;
|
scc_sema_symtab_t *sema_symtab = context;
|
||||||
|
|
||||||
@@ -196,4 +196,7 @@ void scc_sema_init(scc_sema_callbacks_t *callbacks) {
|
|||||||
&builin_func->base);
|
&builin_func->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_sema_drop(scc_sema_callbacks_t *callbacks) {}
|
void scc_sema_drop(scc_sema_callbacks_t *callbacks) {
|
||||||
|
// FIXME drop obj
|
||||||
|
scc_sema_symtab_drop(callbacks->context);
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ static int switch_file_stack(scc_pproc_t *pp, scc_str_t *fname, scc_pos_t *pos,
|
|||||||
scc_str_append(&fpath, fname);
|
scc_str_append(&fpath, fname);
|
||||||
ret = scc_fexists(scc_str_as_cstr(&fpath));
|
ret = scc_fexists(scc_str_as_cstr(&fpath));
|
||||||
if (ret == true) {
|
if (ret == true) {
|
||||||
|
SCC_DEBUG(*pos, "include file '%s' found", scc_str_as_cstr(&fpath));
|
||||||
goto FOPEN;
|
goto FOPEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ typedef struct scc_pos {
|
|||||||
usize offset;
|
usize offset;
|
||||||
} scc_pos_t;
|
} scc_pos_t;
|
||||||
|
|
||||||
|
#define scc_pos_pnt_fmt "%s:%zu:%zu"
|
||||||
|
#define scc_pos_pnt_val(val) (val).name, (val).line, (val).col
|
||||||
|
|
||||||
static inline scc_pos_t scc_pos_create() { return (scc_pos_t){0, 1, 1, 0}; }
|
static inline scc_pos_t scc_pos_create() { return (scc_pos_t){0, 1, 1, 0}; }
|
||||||
|
|
||||||
static inline void scc_pos_next(scc_pos_t *pos) {
|
static inline void scc_pos_next(scc_pos_t *pos) {
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ extern logger_t __scc_usr_log;
|
|||||||
#define SCC_POS_LOG(level, pos, fmt, ...) \
|
#define SCC_POS_LOG(level, pos, fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
char _full_msg[LOGGER_MAX_BUF_SIZE]; \
|
char _full_msg[LOGGER_MAX_BUF_SIZE]; \
|
||||||
int _n = \
|
int _n = scc_snprintf(_full_msg, sizeof(_full_msg), \
|
||||||
scc_snprintf(_full_msg, sizeof(_full_msg), \
|
scc_pos_pnt_fmt ": ", scc_pos_pnt_val(pos)); \
|
||||||
"%s:%zu:%zu: ", (pos).name, (pos).line, (pos).col); \
|
|
||||||
scc_snprintf(_full_msg + _n, sizeof(_full_msg) - _n, fmt, \
|
scc_snprintf(_full_msg + _n, sizeof(_full_msg) - _n, fmt, \
|
||||||
##__VA_ARGS__); \
|
##__VA_ARGS__); \
|
||||||
__scc_usr_log.handler(&__scc_usr_log, level, nullptr, 0, nullptr, \
|
__scc_usr_log.handler(&__scc_usr_log, level, nullptr, 0, nullptr, \
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ static void load_from_def(pe_idata_lib_ctx_t *ctx, const char *file_path,
|
|||||||
Assert(read_size == fsize);
|
Assert(read_size == fsize);
|
||||||
scc_fclose(fp);
|
scc_fclose(fp);
|
||||||
|
|
||||||
scc_pe_name_vec_t symbol_names;
|
// scc_pe_name_vec_t symbol_names;
|
||||||
usize line = 0;
|
usize line = 0;
|
||||||
for (usize i = 0; i < fsize; i += 1) {
|
for (usize i = 0; i < fsize; i += 1) {
|
||||||
if (buffer[i] == '\n') {
|
if (buffer[i] == '\n') {
|
||||||
|
|||||||
8
tests/simple/15_array_subscript.c
Normal file
8
tests/simple/15_array_subscript.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
int main(void) {
|
||||||
|
char buff[] = "hello buffer";
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < sizeof(buff); i += 1) {
|
||||||
|
res += buff[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
9
tests/simple/16_enum.c
Normal file
9
tests/simple/16_enum.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
int main(void) {
|
||||||
|
enum {
|
||||||
|
ENUM_0,
|
||||||
|
ENUM_2 = 2,
|
||||||
|
ENUM_3,
|
||||||
|
};
|
||||||
|
return ENUM_0 + ENUM_2 + ENUM_3;
|
||||||
|
}
|
||||||
@@ -16,4 +16,6 @@
|
|||||||
"./12_logic.c" = 10
|
"./12_logic.c" = 10
|
||||||
"./13_array.c" = 1198
|
"./13_array.c" = 1198
|
||||||
"./14_pointer.c" = 2
|
"./14_pointer.c" = 2
|
||||||
|
"./15_array_subscript.c" = 1198
|
||||||
|
"./16_enum.c" = 5
|
||||||
[stdout_val_cases]
|
[stdout_val_cases]
|
||||||
|
|||||||
Reference in New Issue
Block a user