public void CloseFile(VirtualMachine vm, Instruction i, List<Value> args) { try { FileStream fs = files[args[0].Int32_Value]; fs.Close(); } catch (Exception e) { vm.RaiseError(e.Message); } }
public void OpenFileWrite(VirtualMachine vm, Instruction i, List<Value> args) { try { FileStream fs = File.Open(args[0].String_Value, FileMode.OpenOrCreate); files.Add(fs); vm.Stack.Push(Value.New(ValueTypes.INT_32, (Int32)(files.Count() - 1))); } catch (Exception e) { vm.RaiseError(e.Message); } }
public void WriteToFile(VirtualMachine vm, Instruction i, List<Value> args) { byte[] toWrite = GetBytes(args[0].String_Value); try { FileStream fs = files[args[1].Int32_Value]; fs.Write(toWrite, 0, toWrite.Count()); } catch (Exception e) { vm.RaiseError(e.Message); } vm.Stack.Push(args[1]); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void Get(VirtualMachine vm, Instruction i) { Value name = vm.Stack.Shift(); if (name.Type != ValueTypes.STRING || name.String_Value == null || name.String_Value == "") { vm.RaiseError("Tried to access a bound value with a non-string name"); return; } Environment cEnv = vm.CurrentEnvironment; while (cEnv != null) { if (cEnv.Exists(name.String_Value)) { vm.Stack.Push(cEnv.Get(name.String_Value)); return; } cEnv = cEnv.Parent; } vm.RaiseError("Could not find variable " + name.String_Value + " in any environment"); return; }
internal static void FalseJumpLabel(VirtualMachine vm, Instruction i) { Value a = vm.Stack.Shift(); if (a.Type != ValueTypes.BOOLEAN) { vm.RaiseError("Attempted a test jump condition on a non-boolean value"); return; } if (a.Boolean_Value == false) { OpCodes.JumpLabel(vm, i); return; } vm.ByteCode.ProgramCounter++; return; }
/// <summary> /// /// (array) (index) (end) | (value) (end) /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void ArrayGet(VirtualMachine vm, Instruction i) { Value vIndex = vm.Stack.Shift(); Value vArray = vm.Stack.Shift(); if (vArray.Type != ValueTypes.ARRAY && vArray.Type != ValueTypes.STRING) { vm.RaiseError("Tried to index get a non-array and non-string type " + vArray.Type); return; } if(vIndex.IsNumeric() == false || vIndex.Type == ValueTypes.FLOAT || vIndex.Type == ValueTypes.DOUBLE || vIndex.Type == ValueTypes.DECIMAL){ vm.RaiseError("Tried to index get an array with a non-integer type " + vIndex.Type); return; } Int32 index = Convert.ToInt32(vIndex.Get()); Value v = new Value(); if (vArray.Type == ValueTypes.ARRAY) { if (index >= vArray.Array_Value.Count()) { vm.RaiseError("Tried to get index " + index + " on an array of max index " + (vArray.Array_Value.Count() - 1)); } v = vArray.Array_Value[index]; } else if (vArray.Type == ValueTypes.STRING) { if (index >= vArray.String_Value.Count()) { vm.RaiseError("Tried to get index " + index + " on a string of max index " + (vArray.Array_Value.Count() - 1)); } v = Value.New(ValueTypes.STRING, vArray.String_Value[index]); } vm.Stack.Push(v); return; }
static void Main(string[] args) { if (args.Count() < 1 || System.IO.File.Exists(args[0]) == false) { Console.Write("Filename>"); args = new String[1]; args[0] = Console.ReadLine(); } Assembler asm = new Assembler(); Console.WriteLine("Compiling..."); String code = System.IO.File.ReadAllText(args[0]); List<Instruction> bc = asm.Compile(code, false); Console.WriteLine("Executing."); VirtualMachine vm = new VirtualMachine(bc); Primitives prims = new Primitives(); vm.AddPrimitive("<IO.PrintLine>", prims.ConsoleWriteLine, new List<Value>() { Value.New(ValueTypes.ANY_TYPE) }); vm.AddPrimitive("<IO.Print>", prims.ConsoleWrite, new List<Value>() { Value.New(ValueTypes.ANY_TYPE) }); vm.AddPrimitive("<IO.ReadLine>", prims.ConsoleReadLine, new List<Value>()); vm.AddPrimitive("<IO.File.OpenForWriting>", prims.OpenFileWrite, new List<Value>() { Value.New(ValueTypes.STRING) }); vm.AddPrimitive("<IO.File.Write>", prims.WriteToFile, new List<Value>() { Value.New(ValueTypes.STRING), Value.New(ValueTypes.INT_32) }); vm.AddPrimitive("<IO.File.Close>", prims.CloseFile, new List<Value>() { Value.New(ValueTypes.INT_32) }); vm.AddPrimitive("<Random.GetInt>", prims.GetRandom, new List<Value>() { Value.New(ValueTypes.INT_32), Value.New(ValueTypes.INT_32) }); vm.Start(); // We've actually run a full cycle here, but this // indicates while (vm.CanBeRestarted || vm.IsAborted) { if (vm.IsDebugging || vm.IsAborted) { if (vm.IsAborted) { Console.Write("Panic at PC " + vm.ProgramCounter + ": "); vm.DumpErrors(Console.Out); } else { Console.WriteLine("Debug mode at PC " + vm.ProgramCounter + " (" + vm.DebugText + ")"); } bool debugMode = true; while (debugMode) { Console.Write(">"); String cmd = Console.ReadLine().ToUpperInvariant(); switch (cmd) { case "HELP": case "?": Console.WriteLine(@" COMMANDS: CLO/SURES: Dump closure stack. C/ONT/INUE: Leave debug mode and continue execution. G/LO/BALS: Dump global variables. EN/V/IRONMENT: Dump the current environment. E/RR/ORS: Dump errors, if any. P/RIM/ITIVES: Dump primitives. Q/UIT: Quit. S/TACK: Dump the stack. STAT/US: Dump status. "); break; case "Q": case "QUIT": System.Environment.Exit(111); break; case "STAT": case "STATUS": vm.DumpOperation(Console.Out); break; case "CLO": case "CLOSURES": vm.DumpClosures(Console.Out); break; case "ERRORS": case "ERR": case "E": vm.DumpErrors(Console.Out); break; case "GLOBALS": case "GLO": case "G": vm.DumpGlobals(Console.Out); break; case "V": case "ENVIRONMENT": case "ENV": vm.DumpCurrentEnvironment(Console.Out); break; case "P": case "PRIM": case "PRIMITIVES": vm.DumpPrimitives(Console.Out); break; case "STACK": case "S": vm.DumpStack(Console.Out); break; case "CONTINUE": case "CONT": case "C": debugMode = false; break; default: break; } } } vm.Run(); } if (vm.IsAborted) { vm.DumpOperation(Console.Out); vm.DumpErrors(Console.Out); vm.DumpCurrentEnvironment(Console.Out); vm.DumpStack(Console.Out); } }
internal static void TestGreaterThanEquals(VirtualMachine vm, Instruction i) { Value b = vm.Stack.Shift(); Value a = vm.Stack.Shift(); if (a.IsNumeric() == false || b.IsNumeric() == false) { vm.RaiseError("Attempted to compare non-comparable type " + a.Type); return; } Value v = new Value(); switch (a.Type) { case ValueTypes.INT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int16_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int16_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int16_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int16_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int16_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Int16_Value >= (long)b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Int16_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int16_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int16_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int32_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int32_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int32_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int32_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int32_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Int32_Value >= (long)b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Int32_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int32_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int32_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_64: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int64_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int64_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int64_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int64_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int64_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: if (b.UInt64_Value <= Int64.MaxValue) { var val6 = a.Int64_Value >= Convert.ToInt64(b.UInt64_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); } else { vm.RaiseError("Overflow error"); } return; case ValueTypes.DECIMAL: var val7 = a.Int64_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int64_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int64_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt16_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt16_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt16_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt16_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt16_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt16_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.UInt16_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.UInt16_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.UInt16_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt32_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt32_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt32_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt32_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt32_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt32_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.UInt32_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.UInt32_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.UInt32_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_64: switch (b.Type) { case ValueTypes.INT_16: vm.RaiseError("Incommensurate value error: Int16 to UInt64"); return; case ValueTypes.INT_32: vm.RaiseError("Incommensurate value error: Int32 to UInt64"); return; case ValueTypes.INT_64: vm.RaiseError("Incommensurate value error: Int64 to UInt64"); return; case ValueTypes.UINT_16: var val1 = a.UInt64_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val2 = a.UInt64_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val3 = a.UInt64_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val4 = a.UInt64_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val5 = a.UInt64_Value >= Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val6 = a.UInt64_Value >= Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DECIMAL: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Decimal_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Decimal_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Decimal_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Decimal_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Decimal_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Decimal_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Decimal_Value >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Decimal_Value >= Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Decimal_Value >= Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.FLOAT: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Float_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Float_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Float_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Float_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Float_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Float_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Float_Value) >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = Convert.ToDouble(a.Float_Value) >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Float_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DOUBLE: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Double_Value >= b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Double_Value >= b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Double_Value >= b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Double_Value >= b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Double_Value >= b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Double_Value >= b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Double_Value) >= b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Double_Value >= b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Double_Value >= b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; } }
/// <summary> /// /// /// The difference /// between RETURN_BLOCK and RETURN_CLOSURE *is* meaningful, as the former will attempt to return context /// to parent scope and the latter will attempt to return context to saved scope. Mixing up the two will /// cause memory corruption and probable execution failure. /// /// Note that we push arguments for a call from 0...n (end), and recovered the same way, as we shift them and /// move them to the new stack, where they will be removed in LIFO order. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void CallFunction(VirtualMachine vm, Instruction i) { Value callable = vm.Stack.Shift(); if (callable.Type != ValueTypes.CODE_BLOCK) { vm.RaiseError("Tried to call a non-callable value as a function"); return; } if (i.Type == OpCodeTypes.CALL_CLOSURE && callable.CodeBlock_Value.Closure == null) { vm.RaiseError("Tried to call a non-closure block with lexical scope."); return; } if ( (i.Type == OpCodeTypes.CALL_BLOCK || i.Type == OpCodeTypes.CALL_FUNCTION) && callable.CodeBlock_Value.Closure != null) { vm.RaiseError("Tried to call a closure with dynamic scope."); return; } // Create a new environment and shift arguments onto the stack Environment env = null; if (i.Type == OpCodeTypes.CALL_BLOCK) { // dynamically-scoped env = vm.PushCurrentEnvironment(); } else if (i.Type == OpCodeTypes.CALL_FUNCTION) { // non-closure lexical scope (function) env = vm.PushClosure(); } else if (i.Type == OpCodeTypes.CALL_CLOSURE) { // lexically-scoped (closure) env = callable.CodeBlock_Value.Closure; } else { vm.RaiseError("Attempt to call block or closure with unknown opcode " + i.Type); return; } for (int aInc = callable.CodeBlock_Value.ArgumentsArity.Count() - 1; aInc >= 0; aInc--) { Value v = callable.CodeBlock_Value.ArgumentsArity[aInc]; Value arg = vm.Stack.Shift(); if (v.Type != ValueTypes.ANY_TYPE && arg.Type != v.Type) { vm.RaiseError("Argument arity error: expected type " + arg.Type + ", saw " + v.Type); return; } env.Stack.Push(arg); } // If we're operating in lexical scope, save the current environment so we can return // back to it. if (i.Type == OpCodeTypes.CALL_CLOSURE || i.Type == OpCodeTypes.CALL_FUNCTION) { vm.ClosureStack.Add(vm.CurrentEnvironment); } // Finally, add the code block to the VM's function call list. We only use this to // enable tail calls so we don't lose tex start locations and function arity vm.FunctionCallList.Add(callable.CodeBlock_Value); vm.CurrentEnvironment = env; vm.ByteCode.ProgramCounter = callable.CodeBlock_Value.StartProgramCounter; }
/// <summary> /// /// </summary> /// <param name="vm"></param> internal static void Clone(VirtualMachine vm, Instruction i) { Value prot = vm.Stack.Shift(); if (prot.Type != ValueTypes.OBJECT) { vm.RaiseError("Tried to clone a non-object reference"); return; } Prototype p = new Prototype(); p.Parent = prot.ObjectReference_Value.Home; p.ParentIndex = prot.ObjectReference_Value.Index; Value v = vm.CurrentEnvironment.AddObject(p); vm.Stack.Push(v); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void Copy(VirtualMachine vm, Instruction i) { Value prot = vm.Stack.Shift(); if (prot.Type != ValueTypes.OBJECT) { vm.RaiseError("Tried to copy a non-object reference"); return; } Prototype p = prot.ObjectReference_Value.GetObject(); Value v = vm.CurrentEnvironment.AddObject(p); vm.Stack.Push(v); }
internal static void CheckTypeNumeracy(VirtualMachine vm, Instruction i) { Value a = vm.Stack.Shift(); Value b = vm.Stack.Shift(); vm.Stack.Push(Value.New(ValueTypes.BOOLEAN, (a.IsNumeric() && b.IsNumeric()))); }
/// <summary> /// Pushes the current UTC time in ticks onto the stack. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void ClockUtcTicks(VirtualMachine vm, Instruction i) { Value v = Value.New(ValueTypes.UINT_64, DateTime.UtcNow.Ticks); vm.Stack.Push(v); }
/// <summary> /// Will return true if the types are the same, or if either type is ANY_TYPE. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void CheckTypeEquality(VirtualMachine vm, Instruction i) { Value a = vm.Stack.Shift(); Value b = vm.Stack.Shift(); vm.Stack.Push(Value.New(ValueTypes.BOOLEAN, (a.Type == b.Type || a.Type == ValueTypes.ANY_TYPE || b.Type == ValueTypes.ANY_TYPE))); }
/// <summary> /// When TAIL_CALL is invoked, the VM inspects the top CodeBlock in the FunctionCallList, /// pops the argument off the local stack, clears the local stack, clears local arguments, /// pushes the arguments back onto the stack, and then moves the VM PC to the top of the /// current CodeBlock. This allows for stack-free(ish) recursion. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void CallTailCall(VirtualMachine vm, Instruction i) { if (vm.FunctionCallList.Count() < 1) { vm.RaiseError("Attempt to invoke tail call outside of a code block."); return; } CodeBlock cb = vm.FunctionCallList.Last(); List<Value> argStack = new List<Value>(); for (int aInc = cb.ArgumentsArity.Count() - 1; aInc >= 0; aInc--) { Value v = cb.ArgumentsArity[aInc]; Value arg = vm.Stack.Shift(); if (v.Type != ValueTypes.ANY_TYPE && arg.Type != v.Type) { vm.RaiseError("Argument arity error: expected type " + arg.Type + ", saw " + v.Type); return; } argStack.Add(arg); } // Clear out the current environment so we can reuse it. vm.CurrentEnvironment.Stack.Clear(); vm.CurrentEnvironment.Variables.Clear(); vm.CurrentEnvironment.Memory = 0; vm.CurrentEnvironment.Prototypes.Clear(); vm.CurrentEnvironment.Objects.Clear(); foreach (Value v in argStack) { vm.Stack.Push(v); } vm.ByteCode.ProgramCounter = cb.StartProgramCounter; }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void CallPrimitive(VirtualMachine vm, Instruction i) { Value pName = vm.Stack.Shift(); if (pName.Type != ValueTypes.STRING) { vm.RaiseError("Tried to call a primitive with a non-string name"); return; } Action<VirtualMachine, Instruction, List<Value>> prim = null; if (vm.Primitives.ContainsKey(pName.String_Value) == false) { vm.RaiseError("Tried to call empty primitive " + pName.String_Value); return; } prim = vm.Primitives[pName.String_Value]; Value[] arity = new Value[vm.PrimitivesArity[pName.String_Value].Count()]; vm.PrimitivesArity[pName.String_Value].CopyTo(arity); // We are going to get arguments in reverse order for (int x = arity.Count() - 1; x >= 0; x--) { Value v = vm.Stack.Shift(); if (arity[x].Type != ValueTypes.ANY_TYPE && (arity[x].Type != v.Type)) { vm.RaiseError("Argument arity error for primitive " + pName.String_Value + ": expected type " + arity[x].Type + ", saw " + v.Type); return; } arity[x] = v; } prim(vm, i, new List<Value>(arity)); return; }
internal static void GetGlobal(VirtualMachine vm, Instruction i) { Value name = vm.Stack.Shift(); if (name.Type != ValueTypes.STRING || name.String_Value == null || name.String_Value == "") { vm.RaiseError("Tried to access a global bound value with a non-string name"); return; } if (vm.GlobalsExists(name.String_Value) == false) { vm.RaiseError("Tried to access non-existent global bound value name " + name.String_Value); return; } vm.Stack.Push(vm.GetGlobal(name.String_Value)); return; }
public void ConsoleReadLine(VirtualMachine vm, Instruction i, List<Value> args) { String s = Console.ReadLine(); Value v = Value.New(ValueTypes.STRING, s); vm.Stack.Push(v); }
/// <summary> /// Looks for a variable bound to name 'name' in the current environment and returns it. /// name (end) | value (end) /// </summary> /// <param name="vm"></param> /// <returns></returns> internal static void GetLocal(VirtualMachine vm, Instruction i) { Value name = vm.Stack.Shift(); if (name.Type != ValueTypes.STRING || name.String_Value == null || name.String_Value == "") { vm.RaiseError("Tried to access a bound value with a non-string name"); return; } if (vm.CurrentEnvironment.Exists(name.String_Value) == false) { vm.RaiseError("Tried to access non-existent value name " + name.String_Value); return; } Value val = vm.CurrentEnvironment.Get(name.String_Value); vm.Stack.Push(val); }
public void GetRandom(VirtualMachine vm, Instruction i, List<Value> args) { Value v = Value.New(ValueTypes.INT_32); v.Int32_Value = rand.Next(args[0].Int32_Value, args[1].Int32_Value); vm.Stack.Push(v); }
/// <summary> /// Create an object and return a reference. /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void CreatePrototype(VirtualMachine vm, Instruction i) { Prototype p = new Prototype(); p.Parent = null; p.ParentIndex = -1; Value v = vm.CurrentEnvironment.AddObject(p); vm.Stack.Push(v); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void ArraySet(VirtualMachine vm, Instruction i) { Value vIndex = vm.Stack.Shift(); Value vArray = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); if (vArray.Type != ValueTypes.ARRAY && vArray.Type != ValueTypes.STRING) { vm.RaiseError("Tried to index set a non-array and non-string type " + vArray.Type); return; } if (vIndex.IsNumeric() == false || vIndex.Type == ValueTypes.FLOAT || vIndex.Type == ValueTypes.DOUBLE || vIndex.Type == ValueTypes.DECIMAL) { vm.RaiseError("Tried to index gsetet an array or string with a non-integer type " + vIndex.Type); return; } Int32 index = Convert.ToInt32(vIndex.Get()); if (vArray.Type == ValueTypes.ARRAY) { if (index >= vArray.Array_Value.Count()) { vm.RaiseError("Tried to set index " + index + " on an array of max index " + (vArray.Array_Value.Count() - 1)); return; } vArray.Array_Value[index] = vValue; } else if (vArray.Type == ValueTypes.STRING) { if (index > vArray.String_Value.Count()) { vm.RaiseError("Tried to set index " + index + " on a string of max index " + (vArray.Array_Value.Count() - 1)); return; } String tmpStr = vArray.String_Value.Substring(0, index); tmpStr = tmpStr + vValue.String_Value[0]; tmpStr = tmpStr + vArray.String_Value.Substring(index + 1); vArray.String_Value = tmpStr; } vm.Stack.Push(vArray); return; }
public void ConsoleWriteLine(VirtualMachine vm, Instruction i, List<Value> args) { Console.WriteLine(args[0].Get().ToString()); }
internal static void Debug(VirtualMachine vm, Instruction i) { String reason = ""; if (i.Args.Count() > 0) { object o = i.Args[0].Get(); reason = o.ToString(); } vm.RaiseDebug(reason); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void DeletePrototypeProperty(VirtualMachine vm, Instruction i) { Value propName = vm.Stack.Shift(); Value refc = vm.Stack.Shift(); if (propName.Type != ValueTypes.STRING || propName.String_Value == null || propName.String_Value == "") { vm.RaiseError("Tried to delete a property without a string value"); } if (refc.Type != ValueTypes.OBJECT) { vm.RaiseError("Tried to delete a property on something other than an object reference."); } ObjectReference reference = refc.ObjectReference_Value; Prototype p = reference.Home.Prototypes[reference.Home.Objects[reference.Index]]; while (p != null) { if (p.ContainsKey(propName.String_Value)) { p.Remove(propName.String_Value); } else { if (p.Parent == null) { p = null; } else { p = p.Parent.Prototypes[p.Parent.Objects[p.ParentIndex]]; } } } if (p == null) { vm.RaiseError("Tried to remove nonexistent property " + propName.String_Value); return; } vm.Stack.Push(refc); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void Dupe(VirtualMachine vm, Instruction i) { Value v = vm.Stack.Peek(); vm.Stack.Push(v.Dupe()); }
internal static void Add(VirtualMachine vm, Instruction i) { Value b = vm.Stack.Shift(); Value a = vm.Stack.Shift(); if (a.IsNumeric() == false || b.IsNumeric() == false) { vm.RaiseError("Tried to add one or more non-numeric values"); return; } Value v = new Value(); switch (a.Type) { case ValueTypes.INT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int16_Value + b.Int16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int16_Value + b.Int32_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = (Int32)val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int16_Value + b.Int64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int16_Value + b.UInt16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int16_Value + b.UInt32_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: if (b.UInt64_Value <= Int64.MaxValue) { var val6 = a.Int16_Value + (long)b.UInt64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val6; vm.Stack.Push(v); } else { vm.RaiseError("Overflow error"); } return; case ValueTypes.DECIMAL: decimal val7 = a.Int16_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: double val8 = a.Int16_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: float val9 = a.Int16_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int32_Value + b.Int16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = (Int32)val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int32_Value + b.Int32_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = (Int32)val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int32_Value + b.Int64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int32_Value + b.UInt16_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int32_Value + b.UInt16_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: if (b.UInt64_Value <= Int64.MaxValue) { var val6 = a.Int32_Value + (long)b.UInt64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val6; vm.Stack.Push(v); } else { vm.RaiseError("Overflow error"); } return; case ValueTypes.DECIMAL: decimal val7 = a.Int32_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: double val8 = a.Int32_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: float val9 = a.Int32_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_64: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int64_Value + b.Int16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = (Int32)val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int64_Value + b.Int32_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = (Int32)val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int64_Value + b.Int64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int64_Value + b.UInt16_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int64_Value + b.UInt32_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: if (b.UInt64_Value <= Int64.MaxValue) { var val6 = a.Int64_Value + (long)b.UInt64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val6; vm.Stack.Push(v); } else { vm.RaiseError("Overflow error"); } return; case ValueTypes.DECIMAL: decimal val7 = a.Int64_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: double val8 = a.Int64_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: float val9 = a.Int64_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt16_Value + b.Int16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt16_Value + b.Int32_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt16_Value + b.Int64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt16_Value + b.UInt16_Value; v.Type = ValueTypes.INT_32; v.Int32_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt16_Value + b.UInt32_Value; v.Type = ValueTypes.UINT_32; v.UInt32_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt16_Value + b.UInt64_Value; v.Type = ValueTypes.UINT_64; v.UInt64_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: decimal val7 = a.UInt16_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: double val8 = a.UInt16_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: float val9 = a.UInt16_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt32_Value + b.Int16_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt32_Value + b.Int32_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt32_Value + b.Int64_Value; v.Type = ValueTypes.INT_64; v.Int64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt32_Value + b.UInt16_Value; v.Type = ValueTypes.UINT_32; v.UInt32_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt32_Value + b.UInt32_Value; v.Type = ValueTypes.UINT_32; v.UInt32_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt32_Value + b.UInt64_Value; v.Type = ValueTypes.UINT_64; v.UInt64_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: decimal val7 = a.UInt32_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: double val8 = a.UInt32_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: float val9 = a.UInt32_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_64: switch (b.Type) { case ValueTypes.INT_16: vm.RaiseError("Incommensurate value error: Int16 to UInt64"); return; case ValueTypes.INT_32: vm.RaiseError("Incommensurate value error: Int32 to UInt64"); return; case ValueTypes.INT_64: vm.RaiseError("Incommensurate value error: Int64 to UInt64"); return; case ValueTypes.UINT_16: var val1 = a.UInt64_Value + b.UInt16_Value; v.Type = ValueTypes.UINT_64; v.UInt64_Value = val1; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val2 = a.UInt64_Value + b.UInt32_Value; v.Type = ValueTypes.UINT_64; v.UInt64_Value = val2; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val3 = a.UInt64_Value + b.UInt64_Value; v.Type = ValueTypes.UINT_64; v.UInt64_Value = val3; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: decimal val4 = a.UInt64_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val4; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: decimal val5 = a.UInt64_Value + Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val5; vm.Stack.Push(v); return; case ValueTypes.FLOAT: decimal val6 = a.UInt64_Value + Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val6; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DECIMAL: switch (b.Type) { case ValueTypes.INT_16: decimal val1 = a.Decimal_Value + b.Int16_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: decimal val2 = a.Decimal_Value + b.Int32_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: decimal val3 = a.Decimal_Value + b.Int64_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: decimal val4 = a.Decimal_Value + b.UInt16_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: decimal val5 = a.Decimal_Value + b.UInt32_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: decimal val6 = a.Decimal_Value + b.UInt64_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: decimal val7 = a.Decimal_Value + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: decimal val8 = a.Decimal_Value + Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: decimal val9 = a.Decimal_Value + Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.FLOAT: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Float_Value + b.Int16_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Float_Value + b.Int32_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Float_Value + b.Int64_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Float_Value + b.UInt16_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Float_Value + b.UInt32_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Float_Value + b.UInt64_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Float_Value) + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = Convert.ToDouble(a.Float_Value) + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Float_Value + b.Float_Value; v.Type = ValueTypes.FLOAT; v.Float_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DOUBLE: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Double_Value + b.Int16_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Double_Value + b.Int32_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Double_Value + b.Int64_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Double_Value + b.UInt16_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Double_Value + b.UInt32_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Double_Value + b.UInt64_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Double_Value) + b.Decimal_Value; v.Type = ValueTypes.DECIMAL; v.Decimal_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Double_Value + b.Double_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Double_Value + b.Float_Value; v.Type = ValueTypes.DOUBLE; v.Double_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; } }
internal static void EndBlock(VirtualMachine vm, Instruction i) { CodeBlock call = vm.CodeBlockBeingDefined; if (i.Type == OpCodeTypes.END_CLOSURE && call.Closure == null) { vm.RaiseError("Tried to end a closure with a null environment."); return; } else if ( (i.Type == OpCodeTypes.END_BLOCK || i.Type == OpCodeTypes.END_FUNCTION) && call.Closure != null) { vm.RaiseError("Tried to end a code block or function with a closure."); return; } call.EndProgramCounter = vm.ByteCode.ProgramCounter-1; Value block = Value.New(ValueTypes.CODE_BLOCK, call); vm.CodeBlockBeingDefined = null; vm.Stack.Push(block); }
internal static void TestNotEquals(VirtualMachine vm, Instruction i) { Value b = vm.Stack.Shift(); Value a = vm.Stack.Shift(); if (a.IsNumeric() == false || b.IsNumeric() == false) { if (a.Type != b.Type) { vm.RaiseError("Tried to compare incommensurate values"); return; } Value testValue = new Value(); testValue.Type = ValueTypes.BOOLEAN; if (a.Type == ValueTypes.BOOLEAN) { testValue.Boolean_Value = Convert.ToBoolean(a.Get()) != Convert.ToBoolean(b.Get()); } else if (a.Type == ValueTypes.BYTE) { testValue.Boolean_Value = Convert.ToByte(a.Get()) != Convert.ToByte(b.Get()); } else if (a.Type == ValueTypes.DATETIME) { throw new NotImplementedException(); } else if (a.Type == ValueTypes.GUID) { throw new NotImplementedException(); } else if (a.Type == ValueTypes.STRING) { testValue.Boolean_Value = Convert.ToString(a.Get()) != Convert.ToString(b.Get()); } else if (a.Type == ValueTypes.OBJECT) { ObjectReference av = a.ObjectReference_Value; ObjectReference bv = b.ObjectReference_Value; testValue.Boolean_Value = (av.Home != bv.Home || av.Index != bv.Index); } else { vm.RaiseError("Attempted to compare non-comparable type " + a.Type); } vm.Stack.Push(testValue); return; } Value v = new Value(); switch (a.Type) { case ValueTypes.INT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int16_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int16_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int16_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int16_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int16_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Int16_Value != (long)b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Int16_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int16_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int16_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int32_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int32_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int32_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int32_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int32_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Int32_Value != (long)b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Int32_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int32_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int32_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.INT_64: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Int64_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Int64_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Int64_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Int64_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Int64_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: if (b.UInt64_Value <= Int64.MaxValue) { var val6 = a.Int64_Value != Convert.ToInt64(b.UInt64_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); } else { vm.RaiseError("Overflow error"); } return; case ValueTypes.DECIMAL: var val7 = a.Int64_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Int64_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Int64_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_16: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt16_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt16_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt16_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt16_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt16_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt16_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.UInt16_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.UInt16_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.UInt16_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_32: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.UInt32_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.UInt32_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.UInt32_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.UInt32_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.UInt32_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.UInt32_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.UInt32_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.UInt32_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.UInt32_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.UINT_64: switch (b.Type) { case ValueTypes.INT_16: vm.RaiseError("Incommensurate value error: Int16 to UInt64"); return; case ValueTypes.INT_32: vm.RaiseError("Incommensurate value error: Int32 to UInt64"); return; case ValueTypes.INT_64: vm.RaiseError("Incommensurate value error: Int64 to UInt64"); return; case ValueTypes.UINT_16: var val1 = a.UInt64_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val2 = a.UInt64_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val3 = a.UInt64_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val4 = a.UInt64_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val5 = a.UInt64_Value != Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val6 = a.UInt64_Value != Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DECIMAL: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Decimal_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Decimal_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Decimal_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Decimal_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Decimal_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Decimal_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = a.Decimal_Value != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Decimal_Value != Convert.ToDecimal(b.Double_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Decimal_Value != Convert.ToDecimal(b.Float_Value); v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.FLOAT: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Float_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Float_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Float_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Float_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Float_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Float_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Float_Value) != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = Convert.ToDouble(a.Float_Value) != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Float_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; case ValueTypes.DOUBLE: switch (b.Type) { case ValueTypes.INT_16: var val1 = a.Double_Value != b.Int16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val1; vm.Stack.Push(v); return; case ValueTypes.INT_32: var val2 = a.Double_Value != b.Int32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val2; vm.Stack.Push(v); return; case ValueTypes.INT_64: var val3 = a.Double_Value != b.Int64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val3; vm.Stack.Push(v); return; case ValueTypes.UINT_16: var val4 = a.Double_Value != b.UInt16_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val4; vm.Stack.Push(v); return; case ValueTypes.UINT_32: var val5 = a.Double_Value != b.UInt32_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val5; vm.Stack.Push(v); return; case ValueTypes.UINT_64: var val6 = a.Double_Value != b.UInt64_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val6; vm.Stack.Push(v); return; case ValueTypes.DECIMAL: var val7 = Convert.ToDecimal(a.Double_Value) != b.Decimal_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val7; vm.Stack.Push(v); return; case ValueTypes.DOUBLE: var val8 = a.Double_Value != b.Double_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val8; vm.Stack.Push(v); return; case ValueTypes.FLOAT: var val9 = a.Double_Value != b.Float_Value; v.Type = ValueTypes.BOOLEAN; v.Boolean_Value = val9; vm.Stack.Push(v); return; } vm.RaiseError("Incommensurate value error"); break; } }
internal static void AppendString(VirtualMachine vm, Instruction i) { Value vSecond = vm.Stack.Shift(); Value vFirst = vm.Stack.Shift(); Value ret = Value.New(ValueTypes.STRING); ret.String_Value = vFirst.Get().ToString() + vSecond.Get().ToString(); vm.Stack.Push(ret); }