Пример #1
0
        bool?If_SymbolExists(ConditionalDirective directive)
        {
            if (directive.condition.IsNullOrEmpty)
            {
                return(null);
            }

            return(Values.NameExists(directive.condition.ToString()));
        }
Пример #2
0
        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);
        }
Пример #3
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;
            }
        }