bool?If_SymbolExists(ConditionalDirective directive) { if (directive.condition.IsNullOrEmpty) { return(null); } return(Values.NameExists(directive.condition.ToString())); }
bool?If_EvalCondition(ConditionalDirective directive, out Error error) { error = Error.None; if (directive.condition.IsNullOrEmpty) { return(null); } var condition = directive.condition; var result = Assembler.Evaluator.EvaluateExpression(ref condition, directive.SourceLine, out error); if (error.IsError) { error = new Error(error, directive.SourceLine); } return((int)result.Value != 0); }
internal void ProcessIfBlockDirective(ConditionalDirective directive, out Error error) { error = Error.None; bool?ifCondition; switch (directive.part) { case ConditionalDirective.ConditionalPart.IF: // We must note IFs in excluded code to respect nesting (avoid misinterpreting inner ENDIF) if (InExcludedCode) { If_EnterExcludedIf(); } else { ifCondition = If_EvalCondition(directive, out error); if (error.IsError) { return; } if (ifCondition == null) { error = new Error(ErrorCode.If_Missing_Condition, Error.Msg_MissingCondition, directive.SourceLine); return; } If_EnterIf((bool)ifCondition); } break; case ConditionalDirective.ConditionalPart.ELSEIF: // We can treat else/else if like it is not in excluded code (if it IS in excluded code, it will look as if // we already had a block executed, so the else/elseif won't be processed.) if (!inIfStack) { error = new Error(ErrorCode.Missing_Preceeding_If, Error.Msg_NoPreceedingIf, directive.SourceLine); return; } bool considerElseIf = !ifStack.Peek().foundCase; // Has a previous block been executed? (We only process an else if it hasn't) if (considerElseIf) { ifCondition = If_EvalCondition(directive, out error); if (error.IsError) { return; } if (ifCondition == null) { error = new Error(ErrorCode.If_Missing_Condition, Error.Msg_MissingCondition, directive.SourceLine); return; } If_EnterElse((bool)ifCondition); } break; case ConditionalDirective.ConditionalPart.ELSE: // We can treat else/else if like it is not in excluded code (if it IS in excluded code, it will look as if // we already had a block executed, so the else/elseif won't be processed.) if (!inIfStack) { error = new Error(ErrorCode.Missing_Preceeding_If, Error.Msg_NoPreceedingIf, directive.SourceLine); return; } bool runElse = !ifStack.Peek().foundCase; // Has a previous block been executed? (We only process an else if it hasn't) if (!directive.condition.IsNullOrEmpty) { error = new Error(ErrorCode.Unexpected_Text, Error.Msg_NoTextExpected, directive.SourceLine); return; } If_EnterElse(runElse); break; case ConditionalDirective.ConditionalPart.IFDEF: // We must note IFs in excluded code to respect nesting (avoid misinterpreting inner ENDIF) if (InExcludedCode) { If_EnterExcludedIf(); } else { ifCondition = If_SymbolExists(directive); if (ifCondition == null) { error = new Error(ErrorCode.If_Missing_Condition, Error.Msg_MissingCondition, directive.SourceLine); return; } If_EnterIf((bool)ifCondition); } break; case ConditionalDirective.ConditionalPart.IFNDEF: // We must note IFs in excluded code to respect nesting (avoid misinterpreting inner ENDIF) if (InExcludedCode) { If_EnterExcludedIf(); } else { ifCondition = If_SymbolExists(directive); if (ifCondition == null) { error = new Error(ErrorCode.If_Missing_Condition, Error.Msg_MissingCondition, directive.SourceLine); return; } If_EnterIf(!(bool)ifCondition); } break; case ConditionalDirective.ConditionalPart.ENDIF: If_CloseIf(); break; default: error = new Error(ErrorCode.Engine_Error, "Unexpected IF block tiye in Pass.ProcessIfBlockDirective"); break; } }