Пример #1
0
 internal IToken Store(IToken t, int token_pos)
 {
     m_eLastTokCode = t.GetCode();
     t.SetExprPos(token_pos);
     m_vTokens.Add(t);
     return(t);
 }
Пример #2
0
        public static string Dump(this IToken o, params object[] strz)
        {
            Global.MUP_VERIFY(strz.Length % 2 == 0);
            const char DELIM = ';';
            var        ss    = new StringBuilder();

            ss.Append($"{Global.g_sCmdCode[(int)o.GetCode()], -9}");
            ss.Append($" [ addr = 0x{o.MemoryAddress()}");
            for (int i = 0; i < strz.Length; i += 2)
            {
                ss.Append($"{DELIM} {strz[i]} = {strz[i + 1]}");
            }
            ss.Append("]");

            return(ss.ToString());
        }
Пример #3
0
        //---------------------------------------------------------------------------

        /*  Simulates the effect of the execution of an if-then-else block.
         */
        private void ApplyIfElse(Stack <IToken> a_stOpt)
        {
            while (a_stOpt.Any() && a_stOpt.Peek().GetCode() == ECmdCode.cmELSE)
            {
                Global.MUP_VERIFY(a_stOpt.Any());
                Global.MUP_VERIFY(m_nPos >= 3);
                Global.MUP_VERIFY(a_stOpt.Peek().GetCode() == ECmdCode.cmELSE);

                IToken opElse = a_stOpt.Pop();
                IToken opIf   = a_stOpt.Pop();
                Global.MUP_VERIFY(opElse.GetCode() == ECmdCode.cmELSE);

                Global.MUP_VERIFY(opIf.GetCode() == ECmdCode.cmIF);

                // If then else hat 3 argumente und erzeugt einen rückgabewert (3-1=2)
                m_nPos -= 2;
                m_rpn.Add(new TokenIfThenElse(ECmdCode.cmENDIF));
            }
        }
Пример #4
0
        //---------------------------------------------------------------------------
        private void ApplyRemainingOprt(Stack <IToken> stOpt)
        {
            while (stOpt.Any() &&
                   stOpt.Peek().GetCode() != ECmdCode.cmBO &&
                   stOpt.Peek().GetCode() != ECmdCode.cmIO &&
                   stOpt.Peek().GetCode() != ECmdCode.cmCBO &&
                   stOpt.Peek().GetCode() != ECmdCode.cmIF)
            {
                IToken op = stOpt.Peek();
                switch (op.GetCode())
                {
                case ECmdCode.cmOPRT_INFIX:
                case ECmdCode.cmOPRT_BIN: ApplyFunc(stOpt, 2); break;

                case ECmdCode.cmELSE: ApplyIfElse(stOpt); break;

                default: Error(EErrorCodes.ecINTERNAL_ERROR); break;
                } // switch operator token type
            }     // While operator stack not empty
        }
Пример #5
0
        //---------------------------------------------------------------------------
        private IValue ParseFromRPN()
        {
            IValue[] pStack = m_vStackBuffer;
            if (m_rpn.GetSize() == 0)
            {
                // Passiert bei leeren strings oder solchen, die nur Leerzeichen enthalten
                ErrorContext err = new ErrorContext();
                err.Expr = m_pTokenReader.GetExpr();
                err.Errc = EErrorCodes.ecUNEXPECTED_EOF;
                err.Pos  = 0;
                throw new ParserError(err);
            }

            IList <IToken> pRPN = m_rpn.GetData();

            int j      = 0;
            int sidx   = -1;
            int lenRPN = m_rpn.GetSize();

            for (int i = 0; i < lenRPN; ++i)
            {
                IToken   pTok  = pRPN[i];
                ECmdCode eCode = pTok.GetCode();

                switch (eCode)
                {
                case ECmdCode.cmSCRIPT_NEWLINE:
                    sidx = -1;
                    continue;

                case ECmdCode.cmVAL:
                {
                    IValue pVal = (IValue)pTok;
                    sidx++;
                    Global.MUP_VERIFY(sidx < pStack.Length);
                    pStack[sidx] = pVal;
                    //  m_vStackBuffer[sidx] = rVal;
                    //if (pVal.IsVariable())
                    //{
                    //    // m_vStackBuffer[sidx].Release();
                    //    pStack[sidx] = pVal;
                    //}
                    //else
                    //{
                    //    ref IValue val = ref pStack[sidx];
                    //    if (val.IsVariable())
                    //        m_cache.CreateFromCache(out val);

                    //    val = pVal;
                    //}
                }
                    continue;

                case ECmdCode.cmIC:
                {
                    j = 0;
                    ICallback pIdxOprt = (ICallback)pTok;
                    int       nArgs    = pIdxOprt.GetArgsPresent();
                    sidx -= nArgs - 1;
                    Global.MUP_VERIFY(sidx >= 0);
                    var        arr = new IValue[nArgs + 1];
                    ref IValue val = ref pStack[--sidx];
                    Array.Copy(pStack, sidx, arr, 0, nArgs + 1);
                    //int t = sidx + nArgs +1;
                    //arr = new IValue[nArgs+1];
                    //if (t == 1)
                    //    arr[0] = m_vStackBuffer[sidx];
                    //else if (t != 0)
                    //for (int k = sidx; k < t; k++)
                    //    arr[j++] = m_vStackBuffer[k];
                    pIdxOprt.Eval(ref val, arr);
                }
                    continue;
Пример #6
0
        //---------------------------------------------------------------------------
        private void CreateRPN()
        {
            if (string.IsNullOrEmpty(m_pTokenReader.GetExpr()))
            {
                Error(EErrorCodes.ecUNEXPECTED_EOF, 0);
            }

            // The Stacks take the ownership over the tokens
            Stack <IToken> stOpt = new Stack <IToken>();
            Stack <int>    stArgCount = new Stack <int>();
            Stack <int>    stIdxCount = new Stack <int>();
            IToken         pTok = null, pTokPrev;
            Value          val;

            ReInit();

            for (; ;)
            {
                pTokPrev = pTok;
                pTok     = m_pTokenReader.ReadNextToken();

                ECmdCode eCmd = pTok.GetCode();
                switch (eCmd)
                {
                case ECmdCode.cmVAL:
                    m_nPos++;
                    m_rpn.Add(pTok);
                    break;

                case ECmdCode.cmCBC:
                case ECmdCode.cmIC:
                {
                    ECmdCode eStarter = eCmd - 1;
                    Global.MUP_VERIFY(eStarter == ECmdCode.cmCBO || eStarter == ECmdCode.cmIO);

                    // The argument count for parameterless functions is zero
                    // by default an opening bracket sets parameter count to 1
                    // in preparation of arguments to come. If the last token
                    // was an opening bracket we know better...
                    if (pTokPrev != null && pTokPrev.GetCode() == eStarter)
                    {
                        stArgCount.Push(stArgCount.Pop() - 1);
                    }

                    ApplyRemainingOprt(stOpt);

                    // if opt is "]" and opta is "[" the bracket content has been evaluated.
                    // Now check whether there is an index operator on the stack.
                    if (stOpt.Any() && stOpt.Peek().GetCode() == eStarter)
                    {
                        //
                        // Find out how many dimensions were used in the index operator.
                        //
                        int iArgc = stArgCount.Pop();
                        stOpt.Pop();         // Take opening bracket from stack

                        ICallback PoprtIndex = pTok.AsICallback();
                        Global.MUP_VERIFY(PoprtIndex != null);

                        pTok = PoprtIndex.SetNumArgsPresent(iArgc);
                        m_rpn.Add(pTok);

                        // If this is an index operator there must be something else in the register (the variable to index)
                        Global.MUP_VERIFY(eCmd != ECmdCode.cmIC || m_nPos >= iArgc + 1);

                        // Reduce the index into the value registers accordingly
                        m_nPos -= iArgc;

                        if (eCmd == ECmdCode.cmCBC)
                        {
                            ++m_nPos;
                        }
                    }         // if opening index bracket is on Peek of operator stack
                }
                break;

                case ECmdCode.cmBC:
                {
                    // The argument count for parameterless functions is zero
                    // by default an opening bracket sets parameter count to 1
                    // in preparation of arguments to come. If the last token
                    // was an opening bracket we know better...
                    if (pTokPrev != null && pTokPrev.GetCode() == ECmdCode.cmBO)
                    {
                        stArgCount.Push(stArgCount.Pop() - 1);
                    }

                    ApplyRemainingOprt(stOpt);

                    // if opt is ")" and opta is "(" the bracket content has been evaluated.
                    // Now its time to check if there is either a function or a sign pending.
                    // - Neither the opening nor the closing bracket will be pushed back to
                    //   the operator stack
                    // - Check if a function is standing in front of the opening bracket,
                    //   if so evaluate it afterwards to apply an infix operator.
                    if (stOpt.Any() && stOpt.Peek().GetCode() == ECmdCode.cmBO)
                    {
                        //
                        // Here is the stuff to evaluate a function token
                        //
                        int iArgc = stArgCount.Pop();

                        stOpt.Pop();         // Take opening bracket from stack
                        if (!stOpt.Any())
                        {
                            break;
                        }

                        if ((stOpt.Peek().GetCode() != ECmdCode.cmFUNC) && (stOpt.Peek().GetCode() != ECmdCode.cmOPRT_INFIX))
                        {
                            break;
                        }

                        ICallback pFun = stOpt.Peek().AsICallback();

                        if (pFun.GetArgc() != -1 && iArgc > pFun.GetArgc())
                        {
                            Error(EErrorCodes.ecTOO_MANY_PARAMS, pTok.GetExprPos(), pFun);
                        }

                        if (iArgc < pFun.GetArgc())
                        {
                            Error(EErrorCodes.ecTOO_FEW_PARAMS, pTok.GetExprPos(), pFun);
                        }

                        // Apply function, if present
                        if (stOpt.Any() &&
                            stOpt.Peek().GetCode() != ECmdCode.cmOPRT_INFIX &&
                            stOpt.Peek().GetCode() != ECmdCode.cmOPRT_BIN)
                        {
                            ApplyFunc(stOpt, iArgc);
                        }
                    }
                }
                break;

                case ECmdCode.cmELSE:
                    ApplyRemainingOprt(stOpt);
                    m_rpn.Add(pTok);
                    stOpt.Push(pTok);
                    break;

                case ECmdCode.cmSCRIPT_NEWLINE:
                    ApplyRemainingOprt(stOpt);
                    m_rpn.AddNewline(pTok, m_nPos);
                    stOpt.Clear();
                    m_nPos = 0;
                    break;

                case ECmdCode.cmARG_SEP:
                    if (!stArgCount.Any())
                    {
                        Error(EErrorCodes.ecUNEXPECTED_COMMA, m_pTokenReader.GetPos() - 1);
                    }

                    stArgCount.Push(stArgCount.Pop() + 1);

                    ApplyRemainingOprt(stOpt);
                    break;

                case ECmdCode.cmEOE:
                    ApplyRemainingOprt(stOpt);
                    m_rpn.Finalise();
                    break;

                case ECmdCode.cmIF:
                case ECmdCode.cmOPRT_BIN:
                {
                    while (stOpt.Any() &&
                           stOpt.Peek().GetCode() != ECmdCode.cmBO &&
                           stOpt.Peek().GetCode() != ECmdCode.cmIO &&
                           stOpt.Peek().GetCode() != ECmdCode.cmCBO &&
                           stOpt.Peek().GetCode() != ECmdCode.cmELSE &&
                           stOpt.Peek().GetCode() != ECmdCode.cmIF)
                    {
                        IToken Poprt1 = stOpt.Peek();
                        IToken Poprt2 = pTok;
                        Global.MUP_VERIFY(Poprt1 != null && Poprt2 != null);
                        Global.MUP_VERIFY(Poprt1.AsIPrecedence() != null && Poprt2.AsIPrecedence() != null);

                        int nPrec1 = Poprt1.AsIPrecedence().GetPri(),
                            nPrec2 = Poprt2.AsIPrecedence().GetPri();

                        if (Poprt1.GetCode() == Poprt2.GetCode())
                        {
                            // Deal with operator associativity
                            EOprtAsct eOprtAsct = Poprt1.AsIPrecedence().GetAssociativity();
                            if ((eOprtAsct == EOprtAsct.oaRIGHT && (nPrec1 <= nPrec2)) ||
                                (eOprtAsct == EOprtAsct.oaLEFT && (nPrec1 < nPrec2)))
                            {
                                break;
                            }
                        }
                        else if (nPrec1 < nPrec2)
                        {
                            break;
                        }

                        // apply the operator now
                        // (binary operators are identic to functions with two arguments)
                        ApplyFunc(stOpt, 2);
                    }         // while ( ... )

                    if (pTok.GetCode() == ECmdCode.cmIF)
                    {
                        m_rpn.Add(pTok);
                    }

                    stOpt.Push(pTok);
                }
                break;

                //
                //  Postfix Operators
                //
                case ECmdCode.cmOPRT_POSTFIX:
                    Global.MUP_VERIFY(m_nPos != 0);
                    m_rpn.Add(pTok);
                    break;

                case ECmdCode.cmCBO:
                case ECmdCode.cmIO:
                case ECmdCode.cmBO:
                    stOpt.Push(pTok);
                    stArgCount.Push(1);
                    break;

                //
                // Functions
                //
                case ECmdCode.cmOPRT_INFIX:
                case ECmdCode.cmFUNC:
                {
                    ICallback pFunc = pTok.AsICallback();
                    Global.MUP_VERIFY(pFunc != null);
                    stOpt.Push(pTok);
                }
                break;

                default:
                    Error(EErrorCodes.ecINTERNAL_ERROR);
                    break;
                } // switch Code

                if (s_bDumpStack)
                {
                    StackDump(stOpt);
                }

                if (pTok.GetCode() == ECmdCode.cmEOE)
                {
                    break;
                }
            } // for (all tokens)

            if (s_bDumpRPN)
            {
                m_rpn.AsciiDump();
            }

            if (m_nPos > 1)
            {
                Error(EErrorCodes.ecUNEXPECTED_COMMA, -1);
            }
        }