public static VarCompare GetInstance() { if (_inst == null) { _inst = new VarCompare(); } return(_inst); }
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); }
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); }
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; }