Пример #1
0
        }                                                                         //#define ST2 m_precompiled[ptr-2].value()

        //#define OP(OP, ADJ, EXPR) \
        //    case OP: \
        //        if (ADJ == 2) {\
        //            if (m_precompiled[ptr-3].cmd() == PUSH_CONST && m_precompiled[ptr-2].cmd() == PUSH_CONST && m_precompiled[ptr-1].cmd() == PUSH_CONST) \
        //            {   ptr--; m_precompiled[ptr-2] = rpn_inst(EXPR); n -= 3; ptr++; std::copy(m_precompiled.begin()+(ptr+1), m_precompiled.end(), m_precompiled.begin()+(ptr-2)); ptr-=2;} \
        //            else { ptr++; } \
        //        } else if (ADJ == 1) {\
        //            if (m_precompiled[ptr-2].cmd() == PUSH_CONST && m_precompiled[ptr-1].cmd() == PUSH_CONST) \
        //            {   m_precompiled[ptr-2] = rpn_inst(EXPR); n -= 2; std::copy(m_precompiled.begin()+(ptr+1), m_precompiled.end(), m_precompiled.begin()+(ptr-1)); ptr--;} \
        //            else { ptr++; } \
        //        } else if (ADJ == 0) {\
        //            if (m_precompiled[ptr-1].cmd() == PUSH_CONST) \
        //            { ptr++; m_precompiled[ptr-2] = rpn_inst(EXPR); n -= 1; ptr--; std::copy(m_precompiled.begin()+(ptr+1), m_precompiled.end(), m_precompiled.begin()+(ptr)); } \
        //            else { ptr++; } \
        //        } else ptr++; \
        //        break;
        void compress_OP(ref unsigned ptr, ref size_t n, int ADJ, NT EXPR)
        {
            if (ADJ == 2)
            {
                if (m_precompiled[ptr - 3].cmd() == rpn_cmd.PUSH_CONST && m_precompiled[ptr - 2].cmd() == rpn_cmd.PUSH_CONST && m_precompiled[ptr - 1].cmd() == rpn_cmd.PUSH_CONST)
                {
                    ptr--;
                    m_precompiled[ptr - 2] = new rpn_inst(EXPR);
                    n -= 3;
                    ptr++;
                    m_precompiled.CopyTo((int)ptr + 1, m_precompiled, (int)ptr - 2, ((int)ptr + 1) - m_precompiled.Count);
                    ptr -= 2;
                }
                else
                {
                    ptr++;
                }
            }
            else if (ADJ == 1)
            {
                if (m_precompiled[ptr - 2].cmd() == rpn_cmd.PUSH_CONST && m_precompiled[ptr - 1].cmd() == rpn_cmd.PUSH_CONST)
                {
                    m_precompiled[ptr - 2] = new rpn_inst(EXPR);
                    n -= 2;
                    m_precompiled.CopyTo((int)ptr + 1, m_precompiled, (int)ptr - 1, ((int)ptr + 1) - m_precompiled.Count);
                    ptr--;
                }
                else
                {
                    ptr++;
                }
            }
            else if (ADJ == 0)
            {
                if (m_precompiled[ptr - 1].cmd() == rpn_cmd.PUSH_CONST)
                {
                    ptr++;
                    m_precompiled[ptr - 2] = new rpn_inst(EXPR);
                    n -= 1;
                    ptr--;
                    m_precompiled.CopyTo((int)ptr + 1, m_precompiled, (int)ptr, ((int)ptr + 1) - m_precompiled.Count);//std::copy(m_precompiled.begin() + (ptr + 1), m_precompiled.end(), m_precompiled.begin() + (ptr));
                }
                else
                {
                    ptr++;
                }
            }
            else
            {
                ptr++;
            }
        }
Пример #2
0
        //template <typename NT>
        void compile_postfix(std.vector <string> inputs, std.vector <string> cmds, string expr)  //void pfunction<NT>::compile_postfix(const inputs_container &inputs, const std::vector<pstring> &cmds, const pstring &expr) noexcept(false)
        {
            m_precompiled.clear();
            int stk = 0;

            foreach (string cmd in cmds)
            {
                rpn_inst rc = new rpn_inst();
                var      p  = pcmds().find(cmd);
                if (p != default)
                {
                    rc   = new rpn_inst(p.cmd);
                    stk -= p.adj;
                }
                else
                {
                    for (size_t i = 0; i < inputs.size(); i++)
                    {
                        if (inputs[i] == cmd)
                        {
                            rc   = new rpn_inst(rpn_cmd.PUSH_INPUT, i);
                            stk += 1;
                            break;
                        }
                    }

                    if (rc.cmd() != rpn_cmd.PUSH_INPUT)
                    {
                        bool err = false;
                        var  rs  = plib.pg.right(cmd, 1);
                        var  r   = units_si().find(rs);                             //auto r=units_si<NT>().find(rs);
                        if (ops.equals(r, ops.default_))                            //if (r == units_si<NT>().end())
                        {
                            rc = new rpn_inst(ops.pstonum_ne(false, cmd, out err)); //rc = rpn_inst(plib::pstonum_ne<NT>(cmd, err));
                        }
                        else
                        {
                            rc = new rpn_inst(ops.multiply(ops.pstonum_ne(false, plib.pg.left(cmd, cmd.length() - 1), out err), r));  //rc = rpn_inst(plib::pstonum_ne<NT>(plib::left(cmd, cmd.length()-1), err) * r->second);
                        }

                        if (err)
                        {
                            throw new pexception(new plib.pfmt("pfunction: unknown/misformatted token <{0}> in <{1}>").op(cmd, expr));
                        }

                        stk += 1;
                    }
                }

                if (stk < 1)
                {
                    throw new pexception(new plib.pfmt("pfunction: stack underflow on token <{0}> in <{1}>").op(cmd, expr));
                }

                if (stk >= (int)MAX_STACK)
                {
                    throw new pexception(new plib.pfmt("pfunction: stack overflow on token <{0}> in <{1}>").op(cmd, expr));
                }

                if (rc.cmd() == rpn_cmd.LP || rc.cmd() == rpn_cmd.RP)
                {
                    throw new pexception(new plib.pfmt("pfunction: parenthesis inequality on token <{1}> in <{2}>").op(cmd, expr));
                }

                m_precompiled.push_back(rc);
            }

            if (stk != 1)
            {
                throw new pexception(new plib.pfmt("pfunction: stack count {0} different to one on <{1}>").op(stk, expr));
            }

            compress();
        }