feat(ast): 更新AST字面量表示方式
更新AST定义以使用词素字符串代替常量值, 并修改AST转储功能以正确显示字面量内容。 BREAKING CHANGE: AST表达式结构体中literal成员从value改为lexme字段。 refactor(pproc): 重构宏展开和文件包含逻辑 将宏展开函数重构为独立接口,实现文件包含处理逻辑, 改进预处理器的状态管理机制。 fix(sstream): 修复文件流初始化错误码返回 修正文件打开失败时的错误码返回值,确保调用方能正确处理异常情况。
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#define __SCC_AST_DEF_H__
|
#define __SCC_AST_DEF_H__
|
||||||
|
|
||||||
#include <scc_core.h>
|
#include <scc_core.h>
|
||||||
|
#include <scc_pos.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief AST 节点类型枚举
|
* @brief AST 节点类型枚举
|
||||||
@@ -310,7 +311,7 @@ struct scc_ast_expr {
|
|||||||
} compound_literal;
|
} compound_literal;
|
||||||
// 字面量
|
// 字面量
|
||||||
struct {
|
struct {
|
||||||
scc_cvalue_t value;
|
scc_cstring_t lexme;
|
||||||
} literal;
|
} literal;
|
||||||
// 标识符
|
// 标识符
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -392,16 +392,10 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) {
|
|||||||
PRINT_QUOTED_VALUE(ctx, get_op_str(expr->unary.op));
|
PRINT_QUOTED_VALUE(ctx, get_op_str(expr->unary.op));
|
||||||
break;
|
break;
|
||||||
case SCC_AST_EXPR_INT_LITERAL:
|
case SCC_AST_EXPR_INT_LITERAL:
|
||||||
PRINT_VALUE(ctx, " %lld", expr->literal.value.i);
|
|
||||||
break;
|
|
||||||
case SCC_AST_EXPR_FLOAT_LITERAL:
|
case SCC_AST_EXPR_FLOAT_LITERAL:
|
||||||
PRINT_VALUE(ctx, " %f", expr->literal.value.f);
|
|
||||||
break;
|
|
||||||
case SCC_AST_EXPR_CHAR_LITERAL:
|
case SCC_AST_EXPR_CHAR_LITERAL:
|
||||||
PRINT_VALUE(ctx, " '%c'", (char)expr->literal.value.ch);
|
|
||||||
break;
|
|
||||||
case SCC_AST_EXPR_STRING_LITERAL:
|
case SCC_AST_EXPR_STRING_LITERAL:
|
||||||
PRINT_VALUE(ctx, " \"%s\"", expr->literal.value.cstr.data);
|
PRINT_VALUE(ctx, " %s", expr->literal.lexme);
|
||||||
break;
|
break;
|
||||||
case SCC_AST_EXPR_IDENTIFIER:
|
case SCC_AST_EXPR_IDENTIFIER:
|
||||||
if (expr->identifier.name) {
|
if (expr->identifier.name) {
|
||||||
|
|||||||
@@ -22,5 +22,12 @@ scc_lexer_array_to_ring(scc_lexer_tok_vec_t *array) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx);
|
void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx);
|
||||||
|
void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
|
||||||
|
scc_lexer_tok_ring_t *input,
|
||||||
|
scc_lexer_tok_ring_t *output,
|
||||||
|
const scc_pproc_macro_t *macro);
|
||||||
|
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
|
||||||
|
scc_lexer_tok_vec_t *input,
|
||||||
|
scc_lexer_tok_ring_t *output);
|
||||||
|
|
||||||
#endif /* __SCC_PPROC_EXPAND_H__ */
|
#endif /* __SCC_PPROC_EXPAND_H__ */
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ typedef struct {
|
|||||||
} scc_pproc_if_state_t;
|
} scc_pproc_if_state_t;
|
||||||
typedef SCC_VEC(scc_pproc_if_state_t) scc_pproc_if_stack_t;
|
typedef SCC_VEC(scc_pproc_if_state_t) scc_pproc_if_stack_t;
|
||||||
|
|
||||||
// 文件包含栈
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
scc_lexer_t *lexer; // 当前文件的 lexer
|
scc_sstream_t sstream;
|
||||||
scc_lexer_tok_ring_t *tok_ring; // 当前文件的 token 环(由 lexer 提供)
|
scc_lexer_t lexer;
|
||||||
// 可能还需要保存当前位置等
|
scc_lexer_tok_ring_t *ring;
|
||||||
} scc_pproc_file_state_t;
|
} scc_pproc_file_state_t;
|
||||||
typedef SCC_VEC(scc_pproc_file_state_t) scc_pproc_file_stack_t;
|
typedef SCC_VEC(scc_pproc_file_state_t *) scc_pproc_file_stack_t;
|
||||||
typedef SCC_VEC(scc_lexer_tok_ring_t *) scc_pproc_ring_vec_t;
|
typedef SCC_VEC(scc_lexer_tok_ring_t *) scc_pproc_ring_vec_t;
|
||||||
|
|
||||||
typedef struct scc_pproc {
|
typedef struct scc_pproc {
|
||||||
|
scc_lexer_tok_ring_t *org_ring;
|
||||||
scc_lexer_tok_ring_t *cur_ring;
|
scc_lexer_tok_ring_t *cur_ring;
|
||||||
scc_lexer_tok_ring_t expanded_ring;
|
scc_lexer_tok_ring_t expanded_ring;
|
||||||
scc_strpool_t strpool;
|
scc_strpool_t strpool;
|
||||||
@@ -49,7 +49,7 @@ scc_lexer_tok_ring_t *scc_pproc_to_ring(scc_pproc_t *pp, int ring_size);
|
|||||||
void scc_pproc_drop(scc_pproc_t *pp);
|
void scc_pproc_drop(scc_pproc_t *pp);
|
||||||
|
|
||||||
void scc_pproc_handle_directive(scc_pproc_t *pp);
|
void scc_pproc_handle_directive(scc_pproc_t *pp);
|
||||||
void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro);
|
void scc_pproc_parse_include(scc_pproc_t *pp);
|
||||||
void scc_pproc_parse_macro_arguments(scc_lexer_tok_ring_t *ring,
|
void scc_pproc_parse_macro_arguments(scc_lexer_tok_ring_t *ring,
|
||||||
scc_lexer_tok_vec_t *args, int need_full);
|
scc_lexer_tok_vec_t *args, int need_full);
|
||||||
void scc_pproc_parse_function_macro(scc_pproc_t *pp,
|
void scc_pproc_parse_function_macro(scc_pproc_t *pp,
|
||||||
|
|||||||
@@ -271,6 +271,9 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SCC_PP_TOK_INCLUDE:
|
case SCC_PP_TOK_INCLUDE:
|
||||||
|
scc_lexer_tok_drop(&tok);
|
||||||
|
scc_pproc_parse_include(pp);
|
||||||
|
return;
|
||||||
case SCC_PP_TOK_IF:
|
case SCC_PP_TOK_IF:
|
||||||
case SCC_PP_TOK_IFDEF:
|
case SCC_PP_TOK_IFDEF:
|
||||||
case SCC_PP_TOK_IFNDEF:
|
case SCC_PP_TOK_IFNDEF:
|
||||||
@@ -279,6 +282,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
|
|||||||
case SCC_PP_TOK_ELIFDEF:
|
case SCC_PP_TOK_ELIFDEF:
|
||||||
case SCC_PP_TOK_ELIFNDEF:
|
case SCC_PP_TOK_ELIFNDEF:
|
||||||
case SCC_PP_TOK_ENDIF:
|
case SCC_PP_TOK_ENDIF:
|
||||||
|
goto ERROR;
|
||||||
case SCC_PP_TOK_LINE:
|
case SCC_PP_TOK_LINE:
|
||||||
case SCC_PP_TOK_EMBED:
|
case SCC_PP_TOK_EMBED:
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
|
|||||||
@@ -81,26 +81,35 @@ static inline void scc_copy_expand(scc_pproc_expand_t *expand_ctx,
|
|||||||
scc_vec_init(copyed_ctx->output);
|
scc_vec_init(copyed_ctx->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro) {
|
void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
|
||||||
scc_pproc_expand_t ctx;
|
scc_lexer_tok_ring_t *input,
|
||||||
|
scc_lexer_tok_ring_t *output,
|
||||||
|
const scc_pproc_macro_t *macro) {
|
||||||
scc_lexer_tok_vec_t expaned_buffer;
|
scc_lexer_tok_vec_t expaned_buffer;
|
||||||
scc_vec_init(expaned_buffer);
|
scc_vec_init(expaned_buffer);
|
||||||
|
|
||||||
int ok;
|
int ok;
|
||||||
scc_lexer_tok_t tok;
|
scc_lexer_tok_t tok;
|
||||||
scc_ring_next_consume(*pp->cur_ring, tok, ok);
|
scc_ring_next_consume(*input, tok, ok);
|
||||||
if (macro->type == SCC_PP_MACRO_NONE || ok == false) {
|
if (macro->type == SCC_PP_MACRO_NONE || ok == false) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
} else if (macro->type == SCC_PP_MACRO_OBJECT) {
|
} else if (macro->type == SCC_PP_MACRO_OBJECT) {
|
||||||
scc_vec_push(expaned_buffer, tok);
|
scc_vec_push(expaned_buffer, tok);
|
||||||
} else if (macro->type == SCC_PP_MACRO_FUNCTION) {
|
} else if (macro->type == SCC_PP_MACRO_FUNCTION) {
|
||||||
scc_vec_push(expaned_buffer, tok);
|
scc_vec_push(expaned_buffer, tok);
|
||||||
scc_pproc_parse_macro_arguments(pp->cur_ring, &expaned_buffer, true);
|
scc_pproc_parse_macro_arguments(input, &expaned_buffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(&expaned_buffer);
|
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
|
||||||
|
scc_lexer_tok_vec_t *input,
|
||||||
|
scc_lexer_tok_ring_t *output) {
|
||||||
|
scc_pproc_expand_t ctx;
|
||||||
|
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(input);
|
||||||
ctx.input = ˚
|
ctx.input = ˚
|
||||||
ctx.macro_table = &pp->macro_table;
|
ctx.macro_table = macro_table;
|
||||||
ctx.need_rescan = false;
|
ctx.need_rescan = false;
|
||||||
scc_vec_init(ctx.output);
|
scc_vec_init(ctx.output);
|
||||||
scc_pproc_macro_table_t expanded_set;
|
scc_pproc_macro_table_t expanded_set;
|
||||||
@@ -108,7 +117,7 @@ void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro) {
|
|||||||
|
|
||||||
scc_pproc_marco_table_init(ctx.expanded_set);
|
scc_pproc_marco_table_init(ctx.expanded_set);
|
||||||
scc_pproc_expand_macro(&ctx);
|
scc_pproc_expand_macro(&ctx);
|
||||||
pp->expanded_ring = scc_lexer_array_to_ring(&ctx.output);
|
*output = scc_lexer_array_to_ring(&ctx.output);
|
||||||
scc_pproc_macro_table_drop(ctx.expanded_set);
|
scc_pproc_macro_table_drop(ctx.expanded_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
#include <pproc_expand.h>
|
||||||
#include <scc_pproc.h>
|
#include <scc_pproc.h>
|
||||||
|
|
||||||
static int pproc_next(scc_pproc_t *pp, scc_lexer_tok_t *out) {
|
static int pproc_next_one_file(scc_pproc_t *pp, scc_lexer_tok_t *out) {
|
||||||
|
CONTINUE:
|
||||||
scc_lexer_tok_ring_t *stream = pp->cur_ring;
|
scc_lexer_tok_ring_t *stream = pp->cur_ring;
|
||||||
scc_lexer_tok_t tok = {0};
|
scc_lexer_tok_t tok = {0};
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
CONTINUE:
|
|
||||||
if (pp->expanded_ring.cap) {
|
if (pp->expanded_ring.cap) {
|
||||||
scc_ring_next_consume(pp->expanded_ring, *out, ok);
|
scc_ring_next_consume(pp->expanded_ring, *out, ok);
|
||||||
if (ok == false) {
|
if (ok == false) {
|
||||||
@@ -39,7 +40,8 @@ CONTINUE:
|
|||||||
scc_ring_next_consume(*stream, *out, ok);
|
scc_ring_next_consume(*stream, *out, ok);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
scc_pproc_expand_by_src(pp, macro);
|
scc_pproc_expand_by_src(&pp->macro_table, pp->cur_ring,
|
||||||
|
&pp->expanded_ring, macro);
|
||||||
goto CONTINUE;
|
goto CONTINUE;
|
||||||
} else {
|
} else {
|
||||||
// continue
|
// continue
|
||||||
@@ -49,9 +51,37 @@ CONTINUE:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pproc_next(scc_pproc_t *pp, scc_lexer_tok_t *tok) {
|
||||||
|
CONTINUE:
|
||||||
|
int ret = pproc_next_one_file(pp, tok);
|
||||||
|
if (ret != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scc_vec_size(pp->file_stack) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
scc_pproc_file_state_t *file = scc_vec_pop(pp->file_stack);
|
||||||
|
Assert(file->ring == pp->cur_ring);
|
||||||
|
scc_lexer_drop_ring(file->ring);
|
||||||
|
scc_lexer_drop(&(file->lexer));
|
||||||
|
scc_sstream_drop(&(file->sstream));
|
||||||
|
scc_free(file);
|
||||||
|
|
||||||
|
if (scc_vec_size(pp->file_stack) == 0) {
|
||||||
|
pp->cur_ring = pp->org_ring;
|
||||||
|
} else {
|
||||||
|
pp->cur_ring =
|
||||||
|
scc_vec_at(pp->file_stack, scc_vec_size(pp->file_stack) - 1)->ring;
|
||||||
|
}
|
||||||
|
goto CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
void scc_pproc_init(scc_pproc_t *pp, scc_lexer_tok_ring_t *input) {
|
void scc_pproc_init(scc_pproc_t *pp, scc_lexer_tok_ring_t *input) {
|
||||||
Assert(pp != null && input != null);
|
Assert(pp != null && input != null);
|
||||||
pp->cur_ring = input;
|
pp->org_ring = input;
|
||||||
|
pp->cur_ring = pp->org_ring;
|
||||||
scc_ring_init(pp->expanded_ring, 0, 0, 0);
|
scc_ring_init(pp->expanded_ring, 0, 0, 0);
|
||||||
scc_pproc_marco_table_init(&pp->macro_table);
|
scc_pproc_marco_table_init(&pp->macro_table);
|
||||||
scc_vec_init(pp->if_stack);
|
scc_vec_init(pp->if_stack);
|
||||||
|
|||||||
@@ -84,13 +84,13 @@ int scc_sstream_init(scc_sstream_t *stream, const char *fname, int ring_size) {
|
|||||||
scc_file_t file = scc_fopen(fname, SCC_FILE_READ);
|
scc_file_t file = scc_fopen(fname, SCC_FILE_READ);
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
LOG_ERROR("Failed to open file: %s", fname);
|
LOG_ERROR("Failed to open file: %s", fname);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
usize fsize = scc_fsize(file);
|
usize fsize = scc_fsize(file);
|
||||||
if (fsize == 0) {
|
if (fsize == 0) {
|
||||||
LOG_WARN("file size is 0");
|
LOG_WARN("file size is 0");
|
||||||
scc_fclose(file);
|
scc_fclose(file);
|
||||||
return 0;
|
return 2;
|
||||||
}
|
}
|
||||||
char *buffer = (char *)scc_malloc(fsize);
|
char *buffer = (char *)scc_malloc(fsize);
|
||||||
scc_memset(buffer, 0, fsize);
|
scc_memset(buffer, 0, fsize);
|
||||||
|
|||||||
Reference in New Issue
Block a user