Exemplo n.º 1
0
        public Varible invoke(GcMachine m, int numParams)
        {
            if (numParams < 2 || m.GetLocalByID(1).type != VarType.TYPE_TABLE ||
                m.GetLocalByID(2).type != VarType.TYPE_TABLE)
            {
                throw new RuntimeException("Invaild argument");
            }
            Varible newTable = new Varible(new Dictionary <Varible, Varible>());
            var     table    = newTable.table;
            var     table2   = m.GetLocalByID(2).table;

            foreach (var kvp in m.GetLocalByID(1).table)
            {
                if (table2.ContainsKey(kvp.Key) && VarCompare.GetInstance().Equals(kvp.Value, table2[kvp.Key]))
                {
                    table.Add(kvp.Key, kvp.Value);
                }
            }
            return(newTable);
        }
Exemplo n.º 2
0
        static public void OpenLibrary(GcMachine m)
        {
            Varible v = new Varible(new Dictionary <Varible, Varible>(VarCompare.GetInstance()));

            v.table[new Varible("concat")]  = new Varible(new string_concat());
            v.table[new Varible("compare")] = new Varible(new string_compare());
            v.table[new Varible("contain")] = new Varible(new string_contain());
            v.table[new Varible("match")]   = new Varible(new string_match());
            v.table[new Varible("sub")]     = new Varible(new string_sub());
            //String library
            m.SetGlobal("String", v);

            v = new Varible(new Dictionary <Varible, Varible>(VarCompare.GetInstance()));
            //Math library
            v.table[new Varible("sin")]     = new Varible(new math_sin());
            v.table[new Varible("cos")]     = new Varible(new math_cos());
            v.table[new Varible("abs")]     = new Varible(new math_abs());
            v.table[new Varible("ceiling")] = new Varible(new math_ceiling());
            v.table[new Varible("floor")]   = new Varible(new math_floor());
            v.table[new Varible("exp")]     = new Varible(new math_exp());
            v.table[new Varible("pow")]     = new Varible(new math_pow());
            v.table[new Varible("log")]     = new Varible(new math_log());
            v.table[new Varible("random")]  = new Varible(new math_random());
            m.SetGlobal("Math", v);

            v = new Varible(new Dictionary <Varible, Varible>(VarCompare.GetInstance()));
            //Table library
            v.table[new Varible("copy")]          = new Varible(new table_copy());
            v.table[new Varible("contain_key")]   = new Varible(new table_contain_key());
            v.table[new Varible("contain_value")] = new Varible(new table_contain_value());
            v.table[new Varible("intersect")]     = new Varible(new table_intersect());
            v.table[new Varible("union")]         = new Varible(new table_union());
            v.table[new Varible("insert")]        = new Varible(new table_insert());
            v.table[new Varible("remove")]        = new Varible(new table_remove());

            m.SetGlobal("Table", v);
        }
Exemplo n.º 3
0
        private void executeInner()
        {
            Varible t;
            Varible __parent = new Varible("__parent");
            int     n;
            double  num;

            inSystemFunction = null;
            int   lastLine = symbol_getLineByCode(pc);
            int   currFunc = CurrentFunction;
            short opCode   = Convert.ToInt16(code[pc].opCode & 0x7F);

            while (pc < codeLength)
            {
                switch (opCode)
                {
                case OpCode.PUSHNUM:
                    userStack[userStackTop].num  = code[pc].num;
                    userStack[userStackTop].type = VarType.TYPE_NUMBER;
                    userStackTop++;
                    break;

                case OpCode.POP:
                    userStackTop -= code[pc].pointer;
                    break;

                case OpCode.GETLOCAL:
                    userStack[userStackTop] = userStack[userStackBase + code[pc].pointer - 1];
                    userStackTop++;
                    break;

                case OpCode.SETLOCAL:
                    userStack[userStackBase + code[pc].pointer - 1] = userStack[userStackTop - 1];
                    //userStackTop --;
                    break;

                case OpCode.GETGLOBAL:
                    userStack[userStackTop] = GetGlobal(stringMap[code[pc].pointer]);
                    userStackTop++;
                    break;

                case OpCode.SETGLOBAL:
                    SetGlobal(stringMap[code[pc].pointer], userStack[userStackTop - 1]);
                    //userStackTop --;
                    break;

                case OpCode.CALL:
                    systemStack[systemStackTop] = pc;
                    systemStackTop++;
                    systemStack[systemStackTop] = userStackBase;
                    systemStackTop++;
                    systemStack[systemStackTop] = code[pc].pointer;
                    systemStackTop++;
                    t             = userStack[--userStackTop];     // new_address
                    userStackBase = userStackTop - code[pc].pointer;
                    if (t.type == VarType.TYPE_FUNCTION)
                    {
                        pc = t.pointer - 1;
                        //opCode = code[pc].opCode;
                        break;
                    }
                    else if (t.type == VarType.TYPE_C_FUNCTION)
                    {
                        //C function
                        inSystemFunction        = t.func;
                        userStack[userStackTop] = t.func.invoke(this, code[pc].pointer);
                        userStackTop++;
                        inSystemFunction = null;
                        goto retInstruction;
                        // Fall through to RET
                    }
                    else
                    {
                        userStackBase   = systemStack[systemStackTop - 2];
                        systemStackTop -= 3;
                        throw new RuntimeException("Unable to call " + t.num.ToString());
                    }

                case OpCode.RET:
retInstruction:
                    if (systemStackTop == 0)
                    {
                        return;
                    }
                    t            = userStack[userStackTop - 1]; //retval
                    userStackTop = userStackBase;
                    systemStackTop--;                           //pop num param
                    userStackBase = systemStack[--systemStackTop];
                    pc            = systemStack[--systemStackTop];
                    opCode        = code[pc].opCode;

                    userStack[userStackTop++] = t;
                    if (systemStackTop < stepOutStackFrame &&
                        (flags == MachineFlags.MACHINE_FLAGS_STEP_OUT ||
                         flags == MachineFlags.MACHINE_FLAGS_STEP_OVER ||
                         flags == MachineFlags.MACHINE_FLAGS_STEP_IN)
                        )
                    {
                        ++pc;
                        throw new BreakpointException();
                    }
                    break;

                case OpCode.CMP:
                    if (userStack[userStackTop - 1].type != VarType.TYPE_NUMBER || userStack[userStackTop - 2].type != VarType.TYPE_NUMBER)
                    {
                        throw new RuntimeException("Unable to comapre " + VarType.getTypeString(userStack[userStackTop - 1].type) + " and "
                                                   + VarType.getTypeString(userStack[userStackTop - 2].type));
                    }
                    num = userStack[userStackTop - 2].num - userStack[userStackTop - 1].num;
                    if (Math.Abs(num) < 1e-10)
                    {
                        cmpState = (code[pc].pointer & CompareMode.COMPARE_EQUAL) != 0;
                    }
                    else
                    {
                        if (num < 0)
                        {
                            cmpState = (code[pc].pointer & CompareMode.COMPARE_LESS) != 0;
                        }
                        else
                        {
                            cmpState = (code[pc].pointer & CompareMode.COMPARE_GREATER) != 0;
                        }
                    }
                    --userStackTop;
                    if (cmpState)
                    {
                        userStack[userStackTop - 1].num = 1.0;
                    }
                    else
                    {
                        userStack[userStackTop - 1].num = 0.0;
                    }
                    break;

                case OpCode.JUMP:
                    cmpState = !(Math.Abs(userStack[--userStackTop].num) < 1e-10);
                    if (!cmpState)
                    {
                        break;
                    }
                    else
                    {
                        pc += (code[pc].pointer - 1);
                        //opCode = code[pc].opCode;
                        break;
                    }

                case OpCode.JUMPA:
                    pc += (code[pc].pointer - 1);
                    //opCode = code[pc].opCode;
                    break;

                case OpCode.ADJLOCAL:
                    n = userStackTop - userStackBase;
                    while (n > code[pc].pointer)
                    {
                        --userStackTop;
                        --n;
                    }
                    while (n < code[pc].pointer)
                    {
                        userStack[userStackTop] = new Varible(0.0);
                        ++userStackTop;
                        ++n;
                    }
                    break;

                case OpCode.NOT:
                    if (Math.Abs(userStack[userStackTop - 1].num) < 1e-10)
                    {
                        userStack[userStackTop - 1].num = 1;
                    }
                    else
                    {
                        userStack[userStackTop - 1].num = 0;
                    }
                    break;

                case OpCode.ARITH:
                    if (code[pc].pointer == OpCode.ARITH_ADD && userStack[userStackTop - 1].type == VarType.TYPE_STRING &&
                        userStack[userStackTop - 2].type == VarType.TYPE_STRING)
                    {
                        userStack[userStackTop - 2].str = userStack[userStackTop - 2].str + userStack[userStackTop - 1].str;
                        userStackTop--;
                        break;
                    }
                    if (userStack[userStackTop - 1].type != VarType.TYPE_NUMBER || userStack[userStackTop - 2].type != VarType.TYPE_NUMBER)
                    {
                        throw new RuntimeException("Unable to perform arithmatic on " + VarType.getTypeString(userStack[userStackTop - 1].type) + " and "
                                                   + VarType.getTypeString(userStack[userStackTop - 2].type));
                    }
                    switch (code[pc].pointer)
                    {
                    case OpCode.ARITH_ADD:
                        num = userStack[userStackTop - 2].num + userStack[userStackTop - 1].num;
                        break;

                    case OpCode.ARITH_SUB:
                        num = userStack[userStackTop - 2].num - userStack[userStackTop - 1].num;
                        break;

                    case OpCode.ARITH_MUL:
                        num = userStack[userStackTop - 2].num * userStack[userStackTop - 1].num;
                        break;

                    case OpCode.ARITH_DIV:
                        num = userStack[userStackTop - 2].num / userStack[userStackTop - 1].num;
                        break;

                    default:
                        throw new RuntimeException("Unknown arith type " + code[pc].pointer.ToString());
                    }
                    userStackTop--;
                    userStack[userStackTop - 1].num = num;
                    break;

                case OpCode.PUSHSTRING:
                    userStack[userStackTop].str  = GetString(code[pc].pointer);
                    userStack[userStackTop].type = VarType.TYPE_STRING;
                    userStackTop++;
                    break;

                case OpCode.TABLEOP:
                    switch (code[pc].pointer)
                    {
                    case OpCode.TABLE_NEW:
                        userStack[userStackTop].table = new Dictionary <Varible, Varible>(VarCompare.GetInstance());
                        userStack[userStackTop].type  = VarType.TYPE_TABLE;
                        userStackTop++;
                        break;

                    case OpCode.TABLE_GETITEM:
                        Dictionary <Varible, Varible> table;
                        int i = 0;
                        if (userStack[userStackTop - 2].type != VarType.TYPE_TABLE)
                        {
                            if (userStack[userStackTop - 2].type == VarType.TYPE_STRING)
                            {
                                if (IsGlobalExists("String") && GetGlobal("String").type == VarType.TYPE_TABLE)
                                {
                                    table = GetGlobal("String").table;
                                }
                                else
                                {
                                    throw new RuntimeException("Not a table");
                                }
                            }
                            else
                            {
                                throw new RuntimeException("Not a table");
                            }
                        }
                        else
                        {
                            table = userStack[userStackTop - 2].table;
                        }
                        while (!table.ContainsKey(userStack[userStackTop - 1]) && table.ContainsKey(__parent) &&
                               table[__parent].type == VarType.TYPE_TABLE)
                        {
                            table = table[__parent].table;
                            ++i;
                            if (i > 256)
                            {
                                throw new RuntimeException("Max levels of __parent exceeded");
                            }
                        }
                        if (!table.ContainsKey(userStack[userStackTop - 1]) && IsGlobalExists("Table") &&
                            GetGlobal("Table").type == VarType.TYPE_TABLE)
                        {
                            table = GetGlobal("Table").table;
                        }
                        if (!table.ContainsKey(userStack[userStackTop - 1]))
                        {
                            throw new RuntimeException("Key do not exist");
                        }
                        userStack[userStackTop - 2] = table[userStack[userStackTop - 1]];
                        userStackTop--;
                        break;

                    case OpCode.TABLE_SETITEM:
                        if (userStack[userStackTop - 2].type != VarType.TYPE_TABLE)
                        {
                            throw new RuntimeException("Not a table");
                        }
                        userStack[userStackTop - 2].table[userStack[userStackTop - 1]] = userStack[userStackTop - 3];
                        userStackTop -= 2;         //3
                        break;

                    case OpCode.TABLE_SETITEM_INIT:
                        if (userStack[userStackTop - 3].type != VarType.TYPE_TABLE)
                        {
                            throw new RuntimeException("Not a table");
                        }
                        userStack[userStackTop - 3].table[userStack[userStackTop - 1]] = userStack[userStackTop - 2];
                        userStackTop -= 1;         //
                        break;

                    default:
                        throw new RuntimeException("Unknown table op");
                    }
                    break;

                case OpCode.PSEUDO_BREAK:
                case OpCode.PSEUDO_CONTINUE:
                    throw new RuntimeException("Unexpected break or continue outside while loop");

                default:
                    if ((code[pc].opCode & 0x80) != 0)
                    {
                        throw new BreakpointException();
                    }
                    else
                    {
                        throw new RuntimeException("Unknown instruction");
                    }
                }
                ++pc;
                opCode = code[pc].opCode;
                if (wantPause)
                {
                    throw new BreakpointException();
                }
                if (flags == MachineFlags.MACHINE_FLAGS_STEP_IN)
                {
                    if (lastLine != symbol_getLineByCode(pc))
                    {
                        throw new BreakpointException();
                    }
                }
                if (flags == MachineFlags.MACHINE_FLAGS_STEP_OVER)
                {
                    if (systemStackTop == stepOutStackFrame && CurrentFunction == currFunc &&
                        lastLine != symbol_getLineByCode(pc))
                    {
                        throw new BreakpointException();
                    }
                }
            }
            return;
        }