[CodeGen::RCC::] Resolving Conditional Compilation. To generate the initial state of storage for variables. @h Pipeline stage. = void CodeGen::RCC::create_pipeline_stage(void) { CodeGen::Stage::new(I"resolve-conditional-compilation", CodeGen::RCC::run_pipeline_stage, NO_STAGE_ARG, FALSE); } int CodeGen::RCC::run_pipeline_stage(pipeline_step *step) { CodeGen::RCC::resolve(step->repository); return TRUE; } @h Resolution. @d MAX_CC_STACK_SIZE 32 = typedef struct rcc_state { struct dictionary *I6_level_symbols; int cc_stack[MAX_CC_STACK_SIZE]; int cc_sp; } rcc_state; void CodeGen::RCC::resolve(inter_tree *I) { rcc_state state; state.I6_level_symbols = Dictionaries::new(1024, TRUE); state.cc_sp = 0; InterTree::traverse(I, CodeGen::RCC::visitor, &state, NULL, 0); if (state.cc_sp != 0) TemplateReader::error("conditional compilation is wrongly structured in the template: not enough #endif", NULL); } void CodeGen::RCC::visitor(inter_tree *I, inter_tree_node *P, void *v_state) { rcc_state *state = (rcc_state *) v_state; int allow = TRUE; for (int i=0; icc_sp; i++) if (state->cc_stack[i] == FALSE) allow = FALSE; inter_package *outer = Inter::Packages::container(P); if ((outer == NULL) || (Inter::Packages::is_codelike(outer) == FALSE)) { if (P->W.data[ID_IFLD] == SPLAT_IST) { text_stream *S = Inode::ID_to_text(P, P->W.data[MATTER_SPLAT_IFLD]); switch (P->W.data[PLM_SPLAT_IFLD]) { case CONSTANT_PLM: case GLOBAL_PLM: case ARRAY_PLM: case ROUTINE_PLM: case DEFAULT_PLM: case STUB_PLM: if (allow) @; break; case IFDEF_PLM: @; break; case IFNDEF_PLM: @; break; case IFTRUE_PLM: @; break; case IFNOT_PLM: @; break; case ENDIF_PLM: @; break; } } } if (allow == FALSE) InterTree::remove_node(P); } @ = int tcount = 0; LOOP_THROUGH_TEXT(pos, S) { wchar_t c = Str::get(pos); if ((c == ' ') || (c == '\t') || (c == '\n')) { if (tcount == 1) tcount = 2; else if (tcount == 2) break; } else { if (tcount == 0) tcount = 1; if ((c == ';') || (c == '-')) break; if (tcount == 2) PUT_TO(ident, c); } } @ = int tcount = 0; LOOP_THROUGH_TEXT(pos, S) { wchar_t c = Str::get(pos); if ((c == ' ') || (c == '\t') || (c == '\n')) { if (tcount == 1) tcount = 2; } else { if (tcount == 0) tcount = 1; if ((c == ';') || (c == '-')) break; if (tcount == 2) PUT_TO(ident, c); } } @ = TEMPORARY_TEXT(ident) @; LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "I6 defines %S here\n", ident); Dictionaries::create(state->I6_level_symbols, ident); DISCARD_TEXT(ident) @ = TEMPORARY_TEXT(ident) @; int result = FALSE; text_stream *symbol_name = ident; @; @; allow = FALSE; DISCARD_TEXT(ident) @ = TEMPORARY_TEXT(ident) @; int result = FALSE; text_stream *symbol_name = ident; @; result = (result)?FALSE:TRUE; @; allow = FALSE; DISCARD_TEXT(ident) @ = inter_symbol *symbol = InterSymbolsTables::symbol_from_name_in_main_or_basics(I, symbol_name); if (symbol) { result = TRUE; if (Inter::Symbols::is_extern(symbol)) result = FALSE; } else if (Dictionaries::find(state->I6_level_symbols, symbol_name)) result = TRUE; LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "Must decide if %S defined: %s\n", symbol_name, (result)?"yes":"no"); if (Log::aspect_switched_on(RESOLVING_CONDITIONAL_COMPILATION_DA)) LOG_INDENT; @ = TEMPORARY_TEXT(ident) @; int result = NOT_APPLICABLE; text_stream *cond = ident; match_results mr2 = Regexp::create_mr(); if (Regexp::match(&mr2, cond, L" *(%C+?) *== *(%d+) *")) { text_stream *identifier = mr2.exp[0]; inter_symbol *symbol = InterSymbolsTables::symbol_from_name_in_main_or_basics(I, identifier); if (symbol) { inter_tree_node *P = Inter::Symbols::definition(symbol); if ((P) && (P->W.data[ID_IFLD] == CONSTANT_IST) && (P->W.data[FORMAT_CONST_IFLD] == CONSTANT_DIRECT) && (P->W.data[DATA_CONST_IFLD] == LITERAL_IVAL)) { int V = (int) P->W.data[DATA_CONST_IFLD + 1]; int W = Str::atoi(mr2.exp[1], 0); if (V == W) result = TRUE; else result = FALSE; } } } if (result == NOT_APPLICABLE) { TemplateReader::error("conditional compilation is too difficult in the template: #iftrue on %S", cond); result = FALSE; } LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "Must decide if %S: ", cond); LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "%s\n", (result)?"true":"false"); if (Log::aspect_switched_on(RESOLVING_CONDITIONAL_COMPILATION_DA)) LOG_INDENT; @; allow = FALSE; DISCARD_TEXT(ident) @ = if (state->cc_sp >= MAX_CC_STACK_SIZE) { state->cc_sp = MAX_CC_STACK_SIZE; TemplateReader::error("conditional compilation is wrongly structured in the template: too many nested #ifdef or #iftrue", NULL); } else { state->cc_stack[state->cc_sp++] = result; } @ = LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "ifnot\n"); if (state->cc_sp == 0) TemplateReader::error("conditional compilation is wrongly structured in the template: #ifnot at top level", NULL); else state->cc_stack[state->cc_sp-1] = (state->cc_stack[state->cc_sp-1])?FALSE:TRUE; allow = FALSE; @ = if (Log::aspect_switched_on(RESOLVING_CONDITIONAL_COMPILATION_DA)) LOG_OUTDENT; LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "endif\n"); state->cc_sp--; if (state->cc_sp < 0) { state->cc_sp = 0; TemplateReader::error("conditional compilation is wrongly structured in the template: too many #endif", NULL); } allow = FALSE;