- 在ABI类型计算中添加FLOAT和DOUBLE类型的映射 - 修复AST操作符注释中的歧义描述 - 为ast2ir上下文添加类型缓存以解决递归结构体定义问题 - 实现复合初始化表达式的支持,包括数组和结构体初始化 - 添加前置和后置自增/自减操作符的IR转换 - 实现三元条件表达式的IR生成 - 添加类型转换(cast)和sizeof操作符的支持 - 重构数组长度推断逻辑并添加类型大小计算函数 - 实现结构体和联合体的递归类型解析 - 添加函数指针调用相关的IR节点类型定义 fix(ast): 修正间接操作符的注释说明 refactor(ast2ir): 优化代码结构并添加必要的断言验证
114 lines
3.5 KiB
C
114 lines
3.5 KiB
C
#include <pproc_expand.h>
|
|
#include <scc_core_ring.h>
|
|
#include <scc_pproc.h>
|
|
|
|
static int switch_file_stack(scc_pproc_t *pp, scc_str_t *fname, scc_pos_t *pos,
|
|
int is_system) {
|
|
scc_str_t fpath = scc_str_empty();
|
|
int ret = 0;
|
|
|
|
const char *org_fname = pos->name;
|
|
|
|
if (!is_system) {
|
|
const char parent[] = "/../";
|
|
// FIXME maybe it can eazy
|
|
scc_str_append_cstr(&fpath, org_fname, scc_strlen(org_fname));
|
|
scc_str_append_cstr(&fpath, parent, scc_strlen(parent));
|
|
scc_str_append(&fpath, fname);
|
|
ret = scc_fexists(scc_str_as_cstr(&fpath));
|
|
if (ret == true) {
|
|
goto FOPEN;
|
|
}
|
|
}
|
|
|
|
/* system default path and -I includes path */
|
|
scc_vec_foreach(pp->include_paths, i) {
|
|
scc_str_drop(&fpath);
|
|
scc_str_t *syspath = &scc_vec_at(pp->include_paths, i);
|
|
scc_str_append(&fpath, syspath);
|
|
scc_str_append_ch(&fpath, '/');
|
|
scc_str_append(&fpath, fname);
|
|
ret = scc_fexists(scc_str_as_cstr(&fpath));
|
|
if (ret == true) {
|
|
SCC_DEBUG(*pos, "include file '%s' found", scc_str_as_cstr(&fpath));
|
|
goto FOPEN;
|
|
}
|
|
}
|
|
SCC_ERROR(*pos, "include file '%s' not found", scc_str_as_cstr(fname));
|
|
return -1;
|
|
FOPEN:
|
|
if ((int)scc_vec_size(pp->file_stack) >= pp->config.max_include_depth) {
|
|
SCC_FATAL(*pos, "include depth exceeds maximum (%d)",
|
|
pp->config.max_include_depth);
|
|
LOG_FATAL("Include depth is too deep...");
|
|
}
|
|
|
|
scc_pproc_file_t *file = scc_malloc(sizeof(scc_pproc_file_t));
|
|
Assert(file != nullptr);
|
|
if (scc_sstream_init(&(file->sstream), scc_str_as_cstr(&fpath), 1024)) {
|
|
return -1;
|
|
}
|
|
scc_lexer_init(&(file->lexer), scc_sstream_to_ring(&(file->sstream)));
|
|
file->ring = scc_lexer_to_ring(&(file->lexer), 8, true);
|
|
pp->cur_ring = file->ring;
|
|
|
|
scc_vec_push(pp->file_stack, file);
|
|
return 0;
|
|
}
|
|
|
|
void scc_pproc_parse_include(scc_pproc_t *pp, scc_lexer_tok_t *include_tok,
|
|
scc_lexer_tok_ring_t *tok_ring) {
|
|
int ok;
|
|
scc_lexer_tok_t tok;
|
|
scc_pos_t pos = include_tok->loc;
|
|
scc_lexer_tok_drop(include_tok);
|
|
|
|
scc_str_t line = scc_str_empty();
|
|
while (1) {
|
|
scc_ring_next_consume(*tok_ring, tok, ok);
|
|
if (!ok)
|
|
break;
|
|
if (scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_EMPTYSPACE &&
|
|
scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_COMMENT) {
|
|
scc_str_append(&line, &tok.lexeme);
|
|
}
|
|
scc_lexer_tok_drop(&tok);
|
|
}
|
|
scc_ring_free(*tok_ring);
|
|
|
|
const char *includename = scc_str_as_cstr(&line);
|
|
int len = scc_str_len(&line);
|
|
if (len < 2) {
|
|
goto ERROR;
|
|
} else if (len == 2) {
|
|
goto ERROR;
|
|
} else {
|
|
if (includename[0] == '\"') {
|
|
if (includename[len - 1] != '\"') {
|
|
goto ERROR;
|
|
}
|
|
} else if (includename[0] == '<') {
|
|
if (includename[len - 1] != '>') {
|
|
goto ERROR;
|
|
}
|
|
} else {
|
|
goto ERROR;
|
|
}
|
|
}
|
|
scc_str_t fname = scc_str_empty();
|
|
for (int i = 1; i < len - 1; i++) {
|
|
scc_str_append_ch(&fname, includename[i]);
|
|
}
|
|
int is_system = includename[0] == '<';
|
|
if (switch_file_stack(pp, &fname, &pos, is_system)) {
|
|
// LOG_ERROR()
|
|
}
|
|
scc_str_drop(&line);
|
|
scc_str_drop(&fname);
|
|
return;
|
|
ERROR:
|
|
SCC_ERROR(pos,
|
|
"invalid include filename, expected \"FILENAME\" or <FILENAME>");
|
|
scc_str_drop(&line);
|
|
}
|