Files
scc/libs/ast/include/scc_ast.h
zzy 2e5e98868d feat(ast): 添加汇编器模块并改进AST定义和IR转换
- 在README.md中添加asm汇编器模块说明
- 更新ast_def.h中的枚举注释,添加sema相关信息以明确语义分析作用域
- 重命名函数参数param_types为params,使命名更清晰
- 移除call表达式中的_target字段,简化结构
- 为member、identifier等字段添加///< fill by sema注释说明填充时机
- 为jump语句添加_target字段用于语义分析
- 更新所有AST初始化函数,接受位置信息参数以改进错误定位
- 修复alignof表达式的类型应为ALIGN_OF而非SIZE_OF的问题
- 重构ast2ir.h,引入scc_ast2ir_ctx_t上下文结构体统一管理转换状态
- 添加符号表、节点到IR映射等必要的转换上下文信息
2026-03-17 20:29:40 +08:00

616 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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, scc_pos_t loc) {
Assert(translation_unit != null);
translation_unit->base.type = SCC_AST_TRANSLATION_UNIT;
translation_unit->base.loc = loc;
if (decls == null) {
scc_vec_init(translation_unit->declarations);
} else {
translation_unit->declarations = *decls;
scc_vec_init(*decls);
}
}
static inline void scc_ast_decl_list_init(scc_ast_decl_t *decl,
scc_ast_decl_vec_t *list_move,
scc_pos_t loc) {
Assert(decl != null && list_move != null);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_LIST;
decl->name = null;
decl->list.vars = *list_move;
scc_vec_init(*list_move);
}
// 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,
scc_pos_t loc) {
Assert(decl != null && type != null);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_VAR;
decl->name = name;
decl->var.type = type;
decl->var.init = var_init;
}
// 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,
scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
decl->base.loc = loc;
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, scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
decl->base.loc = loc;
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;
}
// name can be null
static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
scc_ast_type_t *type,
const char *name, scc_pos_t loc) {
Assert(decl != null && type != null);
decl->base.loc = loc;
decl->base.type = SCC_AST_DECL_PARAM;
decl->name = name;
decl->param.type = type;
}
// name and 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,
scc_pos_t loc) {
Assert(decl != null);
decl->base.loc = loc;
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);
}
}
// name and 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,
scc_pos_t loc) {
Assert(decl != null);
decl->base.loc = loc;
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);
}
}
// name and 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,
scc_pos_t loc) {
Assert(decl != null);
decl->base.loc = loc;
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,
scc_pos_t loc) {
Assert(decl != null && name != null && type != null);
decl->base.loc = loc;
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, scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
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, scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null && cond != null && then != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null);
stmt->base.loc = loc;
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, scc_pos_t loc) {
Assert(stmt != null && body != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null);
stmt->base.loc = loc;
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, scc_pos_t loc) {
Assert(stmt != null && cond != null && body != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null && body != null);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_DEFAULT;
stmt->default_stmt.stmt = body;
}
static inline void scc_ast_stmt_break_init(scc_ast_stmt_t *stmt,
scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_BREAK;
stmt->jump._target = null;
}
static inline void scc_ast_stmt_continue_init(scc_ast_stmt_t *stmt,
scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
stmt->base.type = SCC_AST_STMT_CONTINUE;
stmt->jump._target = null;
}
// expr can be null
static inline void scc_ast_stmt_return_init(scc_ast_stmt_t *stmt,
scc_ast_expr_t *expr,
scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
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, scc_pos_t loc) {
Assert(stmt != null && label != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(stmt != null);
stmt->base.loc = loc;
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,
scc_pos_t loc) {
Assert(expr != null && lhs != null && rhs != null);
expr->base.loc = loc;
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,
scc_pos_t loc) {
Assert(expr != null && operand != null);
expr->base.loc = loc;
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,
scc_pos_t loc) {
Assert(expr != null && cond != null && then_expr != null &&
else_expr != null);
expr->base.loc = loc;
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,
scc_ast_expr_t *callee,
scc_ast_expr_vec_t *args,
scc_pos_t loc) {
Assert(expr != null && callee != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CALL;
expr->call.callee = callee;
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,
scc_pos_t loc) {
Assert(expr != null && array != null && index != null);
expr->base.loc = loc;
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,
scc_pos_t loc) {
Assert(expr != null && object != null && member != null);
expr->base.loc = loc;
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_pos_t loc) {
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_MEMBER, object, member, loc);
}
static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr,
scc_ast_expr_t *object,
const char *member,
scc_pos_t loc) {
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member,
loc);
}
static inline void scc_ast_expr_cast_init(scc_ast_expr_t *expr,
scc_ast_type_t *type,
scc_ast_expr_t *operand,
scc_pos_t loc) {
Assert(expr != null && type != null && operand != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_CAST;
expr->cast.type = type;
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,
scc_ast_type_t *type,
scc_ast_expr_t *target_expr,
scc_pos_t loc) {
Assert(expr != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_SIZE_OF;
expr->attr_of.type = type;
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,
scc_ast_type_t *type,
scc_ast_expr_t *target_expr,
scc_pos_t loc) {
Assert(expr != null);
expr->base.loc = loc;
expr->base.type =
SCC_AST_EXPR_SIZE_OF; // 注意:这里使用了 SIZE_OF可能需要改为 ALIGN_OF
expr->attr_of.type = type;
expr->attr_of.expr = target_expr;
}
// lhs_exprs and rhs_exprs can be null
static inline void scc_ast_expr_compound_init(scc_ast_expr_t *expr,
scc_ast_expr_t *base,
scc_ast_expr_vec_t *lhs_exprs,
scc_ast_expr_vec_t *rhs_exprs,
scc_pos_t loc) {
Assert(expr != null && base != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_COMPOUND;
expr->compound.base = base;
if (lhs_exprs == null) {
scc_vec_init(expr->compound.lhs_exprs);
} else {
expr->compound.lhs_exprs = *lhs_exprs;
scc_vec_init(*lhs_exprs);
}
if (rhs_exprs == null) {
scc_vec_init(expr->compound.rhs_exprs);
} else {
expr->compound.rhs_exprs = *rhs_exprs;
scc_vec_init(*rhs_exprs);
}
}
static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
scc_ast_node_type_t type,
const char *value, cbool owned,
scc_pos_t loc) {
Assert(expr != null && value != null);
expr->base.loc = loc;
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_pos_t loc) {
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_INT_LITERAL, value, owned,
loc);
}
static inline void scc_ast_expr_literal_float_init(scc_ast_expr_t *expr,
const char *value,
cbool owned, scc_pos_t loc) {
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_FLOAT_LITERAL, value, owned,
loc);
}
static inline void scc_ast_expr_literal_char_init(scc_ast_expr_t *expr,
const char *value,
cbool owned, scc_pos_t loc) {
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_CHAR_LITERAL, value, owned,
loc);
}
static inline void scc_ast_expr_literal_string_init(scc_ast_expr_t *expr,
const char *value,
cbool owned,
scc_pos_t loc) {
scc_ast_expr_literal_init(expr, SCC_AST_EXPR_STRING_LITERAL, value, owned,
loc);
}
static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr,
const char *name,
scc_pos_t loc) {
Assert(expr != null && name != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_IDENTIFIER;
expr->identifier.name = name;
expr->identifier._target = null;
}
static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
scc_ast_type_t *type,
scc_pos_t loc) {
Assert(expr != null && type != null);
expr->base.loc = loc;
expr->base.type = SCC_AST_EXPR_LVALUE;
expr->lvalue.type = type;
}
// have defined builtin type
static inline void _scc_ast_type_builtin_init(scc_ast_type_t *type,
scc_ast_builtin_type_t builtin,
scc_pos_t loc) {
Assert(type != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_BUILTIN;
type->builtin.type = builtin;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
}
static inline void scc_ast_type_pointer_init(scc_ast_type_t *type,
scc_ast_type_t *pointee,
scc_pos_t loc) {
Assert(type != null && pointee != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_POINTER;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->pointer.pointee = pointee;
}
// size can be null
static inline void scc_ast_type_array_init(scc_ast_type_t *type,
scc_ast_type_t *element,
scc_ast_expr_t *size,
scc_pos_t loc) {
Assert(type != null && element != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_ARRAY;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->array.element = element;
type->array.size = size;
}
// return_type and params can be null
static inline void scc_ast_type_function_init(scc_ast_type_t *type,
scc_ast_type_t *return_type,
scc_ast_decl_vec_t *params,
scc_pos_t loc) {
Assert(type != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_FUNCTION;
type->function.return_type = return_type;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
if (params == null) {
scc_vec_init(type->function.params);
} else {
type->function.params = *params;
scc_vec_init(*params);
}
}
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
scc_ast_node_type_t type_kind,
const char *name,
scc_ast_decl_t *decl,
scc_pos_t loc) {
Assert(type != null);
type->base.loc = loc;
type->base.type = type_kind;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->record.name = name;
type->record.decl = decl;
}
// name and decl can be null
static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_t *decl,
scc_pos_t loc) {
_scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, decl, loc);
}
// name and decl can be null
static inline void scc_ast_type_union_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_t *decl,
scc_pos_t loc) {
_scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, decl, loc);
}
// name and decl can be null
static inline void scc_ast_type_enum_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_t *decl, scc_pos_t loc) {
Assert(type != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_ENUM;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->enumeration.name = name;
type->enumeration.decl = decl;
}
static inline void scc_ast_type_typedef_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_t *target,
scc_pos_t loc) {
Assert(type != null && target != null);
type->base.loc = loc;
type->base.type = SCC_AST_TYPE_TYPEDEF;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->typedef_type.name = name;
type->typedef_type.decl = target;
}
#endif /* __SCC_AST_H__ */