feat(ast): 更新AST字面量表示方式
更新AST定义以使用词素字符串代替常量值, 并修改AST转储功能以正确显示字面量内容。 BREAKING CHANGE: AST表达式结构体中literal成员从value改为lexme字段。 refactor(pproc): 重构宏展开和文件包含逻辑 将宏展开函数重构为独立接口,实现文件包含处理逻辑, 改进预处理器的状态管理机制。 fix(sstream): 修复文件流初始化错误码返回 修正文件打开失败时的错误码返回值,确保调用方能正确处理异常情况。
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#include <pproc_expand.h>
|
||||
#include <scc_pproc.h>
|
||||
|
||||
static int switch_file_stack(scc_pproc_t *pp, scc_cstring_t fname,
|
||||
int is_system) {
|
||||
scc_pproc_file_state_t *file = scc_malloc(sizeof(scc_pproc_file_state_t));
|
||||
Assert(file != null);
|
||||
if (scc_sstream_init(&(file->sstream), fname.data, 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) {
|
||||
int ok;
|
||||
scc_lexer_tok_t tok;
|
||||
|
||||
scc_lexer_tok_ring_t *stream = pp->cur_ring;
|
||||
scc_lexer_tok_vec_t org_toks;
|
||||
scc_vec_init(org_toks);
|
||||
while (1) {
|
||||
scc_ring_peek(*stream, tok, ok);
|
||||
if (ok == false)
|
||||
break;
|
||||
scc_ring_next_consume(*stream, tok, ok);
|
||||
scc_vec_push(org_toks, tok);
|
||||
// FIXME endline needed?
|
||||
if (tok.type == SCC_TOK_ENDLINE)
|
||||
break;
|
||||
}
|
||||
|
||||
scc_lexer_tok_ring_t out_ring;
|
||||
scc_pproc_expand_by_vec(&pp->macro_table, &org_toks, &out_ring);
|
||||
scc_cstring_t line = scc_cstring_create();
|
||||
while (1) {
|
||||
scc_ring_next_consume(out_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_cstring_append(&line, &tok.lexeme);
|
||||
}
|
||||
scc_lexer_tok_drop(&tok);
|
||||
}
|
||||
scc_ring_free(out_ring);
|
||||
|
||||
const char *includename = scc_cstring_as_cstr(&line);
|
||||
int len = scc_cstring_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_cstring_t fname = scc_cstring_create();
|
||||
for (int i = 1; i < len - 1; i++) {
|
||||
scc_cstring_append_ch(&fname, includename[i]);
|
||||
}
|
||||
scc_cstring_free(&line);
|
||||
int is_system = includename[0] == '<';
|
||||
if (switch_file_stack(pp, fname, is_system)) {
|
||||
goto ERROR;
|
||||
}
|
||||
return;
|
||||
ERROR:
|
||||
LOG_ERROR("Invalid include filename need \"FILENAME\" or <FILENAME>");
|
||||
scc_cstring_free(&line);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user