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> 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); }
/// <summary> /// Sets the value of the variable pointed to by a Reference. /// value, ref (end) | ref (end) /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void SetReference(VirtualMachine vm, Instruction i) { Value vRef = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); if (vRef.Type != ValueTypes.REFERENCE) { vm.RaiseError("Attempted to set the far value of non-reference type " + vRef.Type); return; } Reference refc = vRef.Reference_Value; if (refc.HomeEnvironment == null) { vm.RaiseError("Attempted to set the far value of an out-of-scope environment"); return; } if (refc.HomeEnvironment.Exists(refc.Name) == false) { vm.RaiseError("Tried to set via reference undefined value " + refc.Name); return; } if (i.Type == OpCodeTypes.TYPESET_REF) { Value vCurr = refc.HomeEnvironment.Get(refc.Name); if (vCurr.Type != vValue.Type) { vm.RaiseError("Tried to redefine via reference type for variable " + refc.Name + ": value is " + vCurr.Type + ", new value is " + vValue.Type); return; } } refc.HomeEnvironment.Set(refc.Name, vValue); vm.Stack.Push(vRef); }
internal static void SetLabelReturn(VirtualMachine vm, Instruction i) { if (i.Args.Count() < 1 || i.Args[0].Type != ValueTypes.STRING || i.Args[0].String_Value == null || i.Args[0].String_Value == "") { vm.RaiseError("Tried to set a return without an offset label"); return; } if (vm.ByteCode.Labels.ContainsKey(i.Args[0].String_Value) == false) { vm.RaiseError("Tried to set return value for nonexistent label " + i.Args[0].String_Value); } int shift = vm.ByteCode.Labels[i.Args[0].String_Value]; vm.ReturnAddresses.Add(shift); 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; }
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> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void Append(VirtualMachine vm, Instruction i) { Value vArray = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); switch(vArray.Type){ case ValueTypes.ARRAY: if (i.Type == OpCodeTypes.APPEND) { vArray.Array_Value.Add(vValue); vm.Stack.Push(vArray); } else if (i.Type == OpCodeTypes.APPEND_RANGE) { if (vValue.Type == ValueTypes.ARRAY) { vArray.Array_Value.AddRange(vValue.Array_Value); vm.Stack.Push(vArray); } else { vm.RaiseError("Tried to range append using a non-array value. Use APPEND instead."); } } else { vm.RaiseError("Tried append with unknown opcode " + i.Type); } return; case ValueTypes.STRING: if (i.Type == OpCodeTypes.APPEND) { vm.RaiseError("Tried to append to a string. Use APPEND_RANGE instead."); return; } vArray.String_Value = vArray.String_Value + vValue.Get().ToString(); vm.Stack.Push(vArray); return; default: if (i.Type == OpCodeTypes.APPEND) { vm.RaiseError("Tried to append to a string conversion. Use APPEND_RANGE instead."); return; } Value vNew = new Value(); vNew.String_Value = vArray.Get().ToString() + vValue.Get().ToString(); vNew.Type = ValueTypes.STRING; vm.Stack.Push(vNew); 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; }
internal static void VarExists(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 find 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(Value.New(ValueTypes.BOOLEAN, true)); return; } cEnv = cEnv.Parent; } vm.Stack.Push(Value.New(ValueTypes.BOOLEAN, false)); return; }
/// <summary> /// /// </summary> /// <param name="vm"></param> internal static void Abort(VirtualMachine vm, Instruction i) { String msg = ""; if (i.Args.Count() > 0) { msg = i.Args[0].Get().ToString(); } vm.RaiseError(msg); vm.ContinueExecution = false; }
internal static void SpliceString(VirtualMachine vm, Instruction i) { Value vIndex = vm.Stack.Shift(); Value vArray = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); if (vArray.Type != ValueTypes.STRING) { vm.RaiseError("Tried to splice a 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 splice a string with a non-integer type " + vIndex.Type); return; } Int32 index = Convert.ToInt32(vIndex.Get()); if (index > vArray.String_Value.Count()) { vm.RaiseError("Tried to splice index " + index + " on a string of max index " + (vArray.Array_Value.Count() - 1)); return; } String tmpStr = ""; if (index == 0) { tmpStr = vValue.Get().ToString() + vArray.String_Value; } else if (index == vArray.String_Value.Count()) { tmpStr = vArray.String_Value + vValue.Get().ToString(); } else { tmpStr = vArray.String_Value.Substring(0, index) + vValue.String_Value + vArray.String_Value.Substring(index); } vArray.String_Value = tmpStr; vm.Stack.Push(vArray); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void SetVar(VirtualMachine vm, Instruction i) { if (i.Args.Count() < 1) { vm.RaiseError("Tried to set a variable argument without an argument."); return; } Value vName = i.Args[0]; Value vValue = Value.New(ValueTypes.NULL); if(i.Args.Count() > 1){ vValue = i.Args[1]; } else { vValue = vm.Stack.Shift(); } if (vName.Type != ValueTypes.STRING || vName.String_Value == null || vName.String_Value == "") { vm.RaiseError("Tried to use a non-string value for a variable argument name"); return; } Environment e = vm.CurrentEnvironment; while (e != null) { if (e.Exists(vName.String_Value)) { break; } e = e.Parent; } if (e == null) { e = vm.CurrentEnvironment; } else { if (i.Type == OpCodeTypes.TYPESET) { Value typeValue = e.Get(vName.String_Value); if (typeValue.Type != ValueTypes.ARRAY && typeValue.Type != vValue.Type) { vm.RaiseError("Tried to redefine type for variable " + vName.String_Value + ": value is " + vm.Get(vName.String_Value).Type + ", new value is " + vValue.Type); return; } } } e.Set(vName.String_Value, vValue); vm.Stack.Push(vName); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void SetReturn(VirtualMachine vm, Instruction i) { if (i.Args.Count() < 1 || i.Args[0].Type != ValueTypes.INT_32) { vm.RaiseError("Tried to set a return without an offset"); return; } int shift = i.Args[0].Int32_Value; if (i.Type == OpCodeTypes.SET_RETURN_RELATIVE) { vm.ReturnAddresses.Add(vm.ByteCode.ProgramCounter + shift); return; } else if (i.Type == OpCodeTypes.SET_RETURN_ABSOLUTE) { vm.ReturnAddresses.Add(shift); return; } else { vm.RaiseError("Tried to set return with unknown opcode " + i.Type); return; } }
/// <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> /// /// (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; }
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); }
/// <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; }
/// <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 SetNear(VirtualMachine vm, Instruction i) { Value vName = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); if (vName.Type != ValueTypes.STRING || vName.String_Value == null || vName.String_Value == "") { vm.RaiseError("Tried to use a non-string value for a variable name"); return; } if (vm.Exists(vName.String_Value) == false) { if (vm.CurrentEnvironment.Parent == null || vm.CurrentEnvironment.Parent.Exists(vName.String_Value) == false) { vm.RaiseError("Tried to access non-existent value name " + vName.String_Value); return; } if (i.Type == OpCodeTypes.TYPESET) { if (vm.CurrentEnvironment.Parent.Get(vName.String_Value).Type != vValue.Type) { vm.RaiseError("Tried to redefine type for variable " + vName.String_Value + ": value is " + vm.Get(vName.String_Value).Type + ", new value is " + vValue.Type); return; } } vm.CurrentEnvironment.Parent.Set(vName.String_Value, vValue); vm.Stack.Push(vName); return; } else { if (i.Type == OpCodeTypes.TYPESET) { if (vm.Get(vName.String_Value).Type != vValue.Type) { vm.RaiseError("Tried to redefine type for variable " + vName.String_Value + ": value is " + vm.Get(vName.String_Value).Type + ", new value is " + vValue.Type); return; } } vm.Set(vName.String_Value, vValue); vm.Stack.Push(vName); } }
/// <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); }
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; } }
/// <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> /// value,ref,prop (end) | ref (end) /// </summary> /// <param name="vm"></param> /// <param name="i"></param> internal static void SetPrototypeProperty(VirtualMachine vm, Instruction i) { Value propName = vm.Stack.Shift(); Value refc = vm.Stack.Shift(); Value val = vm.Stack.Shift(); if (propName.Type != ValueTypes.STRING || propName.String_Value == null || propName.String_Value == "") { vm.RaiseError("Tried to set a property without a string value"); } if (refc.Type != ValueTypes.OBJECT) { vm.RaiseError("Tried to set a property on something other than an object reference."); } if (i.Type == OpCodeTypes.TYPESETPROP) { try { Value existVal = OpCodes.ReturnProperty(vm, refc, propName); if (existVal.Type != val.Type) { vm.RaiseError("Tried to redefine type for property " + propName + ": property is " + existVal.Type + ", new value is " + val.Type); } } catch (Exceptions.StrikePropertyNotFoundException) { // ignore } catch (Exception e) { vm.RaiseError(e.Message); return; } } ObjectReference reference = refc.ObjectReference_Value; reference.Home.SetObjectProperty(reference.Index, propName.String_Value, val); vm.Stack.Push(refc); }
/// <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; }
/// <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; }
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 SetGlobal(VirtualMachine vm, Instruction i) { Value vName = vm.Stack.Shift(); Value vValue = vm.Stack.Shift(); if (vName.Type != ValueTypes.STRING || vName.String_Value == null || vName.String_Value == "") { vm.RaiseError("Tried to use a non-string value for a variable name"); return; } if (vm.GlobalsExists(vName.String_Value) && i.Type == OpCodeTypes.TYPESET_TOP) { Value vTop = vm.GetGlobal(vName.String_Value); if (vTop.Type != vValue.Type) { vm.RaiseError("Tried to redefine type for value " + vName.String_Value + ": variable is " + vTop.Type + ", new value is " + vValue.Type); return; } } vm.SetGlobal(vName.String_Value, vValue); }