#include #include cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, const scc_lexer_tok_t *tok) { int defined = 0; if (tok) { defined = (scc_pproc_macro_table_get(&pp->macro_table, &(tok->lexeme)) != null); } switch (type) { case SCC_PP_TOK_IFDEF: case SCC_PP_TOK_IFNDEF: { cbool condition = (type == SCC_PP_TOK_IFDEF) ? defined : !defined; scc_pproc_if_t new_if; new_if.found_true = condition; new_if.seen_else = 0; new_if.active = pp->enable ? condition : 0; scc_vec_push(pp->if_stack, new_if); pp->enable = new_if.active; break; } case SCC_PP_TOK_ELIFDEF: case SCC_PP_TOK_ELIFNDEF: { if (scc_vec_size(pp->if_stack) == 0) { LOG_ERROR("#elif without #if"); return false; } scc_pproc_if_t *top = &scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1); if (top->seen_else) { LOG_ERROR("#elif after #else"); return false; } int condition = (type == SCC_PP_TOK_ELIFDEF) ? defined : !defined; if (top->found_true) { // 前面已有真分支,本 elif 不激活 top->active = 0; } else { if (condition) { top->active = 1; top->found_true = 1; } else { top->active = 0; } } // seen_else 仍为 0 pp->enable = top->active; break; } case SCC_PP_TOK_ELSE: { if (scc_vec_size(pp->if_stack) == 0) { LOG_ERROR("#else without #if"); return false; } scc_pproc_if_t *top = &scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1); if (top->seen_else) { LOG_ERROR("multiple #else"); return false; } if (top->found_true) { top->active = 0; } else { top->active = 1; top->found_true = 1; } top->seen_else = 1; pp->enable = top->active; break; } case SCC_PP_TOK_ENDIF: { if (scc_vec_size(pp->if_stack) == 0) { LOG_ERROR("#endif without #if"); } else { scc_vec_pop(pp->if_stack); } if (scc_vec_size(pp->if_stack) == 0) { pp->enable = 1; } else { pp->enable = scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1).active; } break; } default: { LOG_FATAL("unexpected directive"); } } return true; } static cbool parse_constant_condition() { return false; } cbool scc_pproc_parse_if_condition(scc_pproc_t *pp, scc_tok_type_t type, scc_lexer_tok_ring_t *tok_ring) { // TODO int ok; scc_lexer_tok_t tok = {0}; ok = scc_lexer_next_non_blank(tok_ring, &tok); if (ok == false) { LOG_FATAL("unexpected EOF"); } int condition = 0; if (tok.type == SCC_TOK_INT_LITERAL) { condition = scc_cstring_as_cstr(&tok.lexeme)[0] == '0' ? 0 : 1; } else { LOG_ERROR("expected integer constant but got %s", scc_cstring_as_cstr(&tok.lexeme)); } scc_lexer_tok_drop(&tok); ok = scc_lexer_next_non_blank(tok_ring, &tok); if (ok == false) { LOG_FATAL("unexpected EOF"); } if (tok.type != SCC_TOK_ENDLINE) { LOG_ERROR("expected endline"); scc_lexer_skip_until_newline(tok_ring); } else { scc_lexer_tok_drop(&tok); } scc_ring_free(*tok_ring); // 根据指令类型更新条件编译栈 switch (type) { case SCC_PP_TOK_IF: { scc_pproc_if_t new_if; new_if.found_true = condition; new_if.seen_else = 0; new_if.active = pp->enable ? condition : 0; scc_vec_push(pp->if_stack, new_if); pp->enable = new_if.active; break; } case SCC_PP_TOK_ELIF: { if (scc_vec_size(pp->if_stack) == 0) { LOG_ERROR("#elif without #if"); return false; } scc_pproc_if_t *top = &scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1); if (top->seen_else) { LOG_ERROR("#elif after #else"); return false; } if (top->found_true) { top->active = 0; } else { if (condition) { top->active = 1; top->found_true = 1; } else { top->active = 0; } } pp->enable = top->active; break; } default: LOG_FATAL("unexpected directive in parse_if_condition"); } return true; return true; }