Beispiel #1
0
        private TypeSymbol ExecuteListOfInstructions(BaseInstruction linst)
        {
            while (linst != null)
            {
                if (linst.Ins is CallInstruction)
                {
                    CallInstruction callaux = linst.Ins as CallInstruction;
                    UL = ExecuteCall(callaux);

                    if (UL == TypeSymbol.U_Return)
                    {
                        // warning but I condiered it as error;
                        GetRuntimeError(RuntimeMessagesError.ReturnInProcedure);
                    }

                    if (UL == TypeSymbol.U_Halt)
                    {
                        return(UL);
                    }
                }
                else if (linst.Ins is IfInstruction)
                {
                    IfInstruction ifaux = linst.Ins as IfInstruction;
                    UL = ExecuteListOfInstructions((EvaluateCondition(ifaux.Cond)) ? ifaux.Ins : ifaux.InsElse);

                    if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Break ||
                        UL == TypeSymbol.U_Return || UL == TypeSymbol.U_Exit)
                    {
                        return(UL);
                    }
                }
                else if (linst.Ins is WhileInstruction)
                {
                    WhileInstruction whileaux = linst.Ins as WhileInstruction;
                    while (EvaluateCondition(whileaux.Cond))
                    {
                        UL = ExecuteListOfInstructions(whileaux.Ins);

                        if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Return ||
                            UL == TypeSymbol.U_Exit)
                        {
                            return(UL);
                        }

                        if (UL == TypeSymbol.U_Break)
                        {
                            break;
                        }
                    }
                }
                else if (linst.Ins is ForInstruction)
                {
                    ForInstruction foraux = linst.Ins as ForInstruction;
                    TExpression    expB   = EvaluateInteger(foraux.ExpBegin);
                    TExpression    expE   = EvaluateInteger(foraux.ExpEnd);
                    TExpression    step   = EvaluateInteger(foraux.ExpStep);

                    if (!foraux.IsDown)
                    {
                        Assign(foraux.V, 0, expB);
                        while (expB.ValNB <= expE.ValNB)
                        {
                            UL = ExecuteListOfInstructions(foraux.Ins);

                            if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Return ||
                                UL == TypeSymbol.U_Exit)
                            {
                                return(UL);
                            }

                            if (UL == TypeSymbol.U_Break)
                            {
                                break;
                            }

                            // expB.ValNB = expB.ValNB + 1;
                            expB.ValNB = expB.ValNB + step.ValNB;
                            Assign(foraux.V, 0, expB);
                        }
                    }
                    else
                    {
                        Assign(foraux.V, 0, expB);
                        while (expB.ValNB >= expE.ValNB)
                        {
                            UL = ExecuteListOfInstructions(foraux.Ins);

                            if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Return ||
                                UL == TypeSymbol.U_Exit)
                            {
                                return(UL);
                            }

                            if (UL == TypeSymbol.U_Break)
                            {
                                break;
                            }

                            // expB.ValNB = expB.ValNB + 1;
                            expB.ValNB = expB.ValNB - step.ValNB;
                            Assign(foraux.V, 0, expB);
                        }
                    }

                    Free(ref expB);
                    Free(ref expE);
                    Free(ref step);
                }
                else if (linst.Ins is DoWhileInstruction)
                {
#if doc
                    DoWhileInstruction doaux = linst.Ins as DoWhileInstruction;
                    do
                    {
                        UL = ExecuteListOfInstructions(doaux.Ins);

                        if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Return ||
                            UL == TypeSymbol.U_Exit)
                        {
                            return(UL);
                        }

                        if (UL == TypeSymbol.U_Break)
                        {
                            break;
                        }
                    } while (EvaluateCondition(doaux.Cond));
#else
                    //ExecuteOneTimeLoopAtLeast(linst.Ins as TConditionBase, true);
#endif
                }
                else if (linst.Ins is RepeatUntilInstruction)
                {
#if doc
                    RepeatUntilInstruction repeataux = linst.Ins as RepeatUntilInstruction;
                    do
                    {
                        UL = ExecuteListOfInstructions(repeataux.Ins);

                        if (UL == TypeSymbol.U_Halt || UL == TypeSymbol.U_Return ||
                            UL == TypeSymbol.U_Exit)
                        {
                            return(UL);
                        }

                        if (UL == TypeSymbol.U_Break)
                        {
                            break;
                        }
                    } while (!EvaluateCondition(repeataux.Cond));
#else
                    ExecuteOneTimeLoopAtLeast(linst.Ins as TConditionBase, false)
#endif
                }
                else if (linst.Ins is BreakInstruction)
                {
                    return((linst.Ins as BreakInstruction).UL);
                }
                else if (linst.Ins is ReturnInstruction)
                {
                    ReturnInstruction returnaux = linst.Ins as ReturnInstruction;
                    GReturn = returnaux;
                    return(TypeSymbol.U_Return);
                }
                else if (linst.Ins is AssignInstruction)
                {
                    AssignInstruction assignaux = linst.Ins as AssignInstruction;

                    Func <TExpression, TExpression, TExpression> a = (expValue, op) =>
                    {
                        expValue.Next = op;
                        op.Prev       = expValue;

                        TExpression varExpression = new TExpression {
                            UL = TypeSymbol.U_Var
                        };
                        varExpression.ValVar = assignaux.Var;
                        varExpression.Index  = TExpression.CopyExpression(assignaux.index);

                        varExpression.Next = expValue;
                        expValue.Prev      = varExpression;

                        return(EvaluateExpression(varExpression));
                    };

                    TExpression exp0;
                    TExpression expOperator;

                    if (assignaux.Exp != null) // = , += , -= , *= , /=, ^= , %=
                    {
                        exp0 = EvaluateExpression(assignaux.Exp);
                        if (assignaux.UL != TypeSymbol.U_Assignment) //  += , -= , *= , /=, ^= , %=
                        {
                            TypeSymbol ulAux;
                            if (assignaux.UL == TypeSymbol.U_PluseAssigment)
                            {
                                ulAux = TypeSymbol.U_Pluse;
                            }
                            else if (assignaux.UL == TypeSymbol.U_MinusAssigment)
                            {
                                ulAux = TypeSymbol.U_Minus;
                            }
                            else if (assignaux.UL == TypeSymbol.U_MultiplyAssigment)
                            {
                                ulAux = TypeSymbol.U_Multiply;
                            }
                            else if (assignaux.UL == TypeSymbol.U_DivisionAssigment)
                            {
                                ulAux = TypeSymbol.U_Division;
                            }
                            else if (assignaux.UL == TypeSymbol.U_PowAssigment)
                            {
                                ulAux = TypeSymbol.U_Pow;
                            }
                            else //if (assignaux.UL == TypeSymbol.U_ModAssigment)
                            {
                                ulAux = TypeSymbol.U_Mod;
                            }

                            expOperator = new TExpression {
                                UL = ulAux
                            };
                            exp0 = EvaluateExpression(assignaux.Exp);
                            if ((exp0.Next != null) || (exp0.Prev != null))
                            {
                                throw new ArgumentException("This is notification for me hakam");
                            }

                            expOperator = new TExpression {
                                UL = ulAux
                            };
                            exp0 = EvaluateExpression(assignaux.Exp);
                            if ((exp0.Next != null) || (exp0.Prev != null))
                            {
                                throw new ArgumentException("This is notification for me hakam");
                            }

                            exp0 = a(exp0, expOperator);
                        }
                    }
                    else // ++ , --
                    {
                        exp0 = new TExpression {
                            UL = TypeSymbol.U_Cst_Int, ValNB = 1
                        };
                        if (assignaux.UL == TypeSymbol.U_PlusePluse)
                        {
                            expOperator = new TExpression {
                                UL = TypeSymbol.U_Pluse
                            };
                        }
                        else
                        {
                            expOperator = new TExpression {
                                UL = TypeSymbol.U_Minus
                            };
                        }

                        exp0 = a(exp0, expOperator);
                    }

                    if (assignaux.index == null)
                    {
                        Assign(assignaux.Var, 0, exp0);
                    }
                    else
                    {
                        TExpression iexp = EvaluateInteger(assignaux.index);
                        Assign(assignaux.Var, GiveIntWithRuntimeError(Math.Truncate(iexp.ValNB)), exp0);
                        Free(ref iexp);
                    }

                    Free(ref exp0);
                }

                else if (linst.Ins is TWrite)
                {
                    TWrite      writeAux = linst.Ins as TWrite;
                    TExpression exp      = EvaluateExpression(writeAux.exp);

                    string output = "";
                    while (exp != null)
                    {
                        if (exp.UL == TypeSymbol.U_True)
                        {
                            output += true.ToString();
                        }
                        else if (exp.UL == TypeSymbol.U_False)
                        {
                            output += false.ToString();
                        }
                        else if (exp.UL == TypeSymbol.U_Cst_Str)
                        {
                            output += exp.ValStr;
                        }
                        else if (exp.UL == TypeSymbol.U_Cst_Real || exp.UL == TypeSymbol.U_Cst_Int)
                        {
                            output += exp.ValNB.ToString();
                        }

                        exp = exp.Next;
                    }

                    WriteEvent?.Invoke(this, new WriteEventArgs(writeAux.isLn, output, false));

                    Free(ref exp);
                }
                else if (linst.Ins is ReadInstruction)
                {
                    ReadInstruction readAux = linst.Ins as ReadInstruction;

                    InputForm inputRead = new InputForm();
                    inputRead.ShowDialog();
                    string      result = inputRead.Input;
                    TExpression expAux = new TExpression {
                        UL = TypeSymbol.U_Cst_Str, ValStr = result
                    };

                    try
                    {
                        expAux.ValNB = Convert.ToDouble(result);

                        expAux.UL     = IsIntMethod(expAux.ValNB);
                        expAux.ValStr = "";
                    }
                    catch (FormatException)
                    {
                    }

                    try
                    {
                        expAux.UL     = (Convert.ToBoolean(result) ? TypeSymbol.U_True : TypeSymbol.U_False);
                        expAux.ValStr = "";
                    }
                    catch (FormatException)
                    {
                    }

                    int index = 0;
                    if (readAux.index != null)
                    {
                        TExpression temp = EvaluateInteger(readAux.index);
                        index = GiveIntWithRuntimeError(Math.Truncate(temp.ValNB));
                        Free(ref temp);
                    }

                    Assign(readAux.V, index, expAux);
                }
                else
                {
                    GetRuntimeError(RuntimeMessagesError.UnknownInstruction);
                }

                linst = linst.Next;
            }

            return(TypeSymbol.U_EOF);
        }