예제 #1
0
 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);
     }
 }
예제 #2
0
 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);
     }
 }
예제 #3
0
 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]);
 }
예제 #4
0
 /// <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);
 }
예제 #5
0
 /// <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);
 }
예제 #6
0
        /// <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);
        }
예제 #7
0
 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;
 }
예제 #8
0
 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;
 }
예제 #9
0
        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;
            }
        }
예제 #10
0
        /// <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;
            }
        }
예제 #11
0
 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;
 }
예제 #12
0
 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;
 }
예제 #13
0
 /// <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;
 }
예제 #14
0
        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);
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
 /// <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;
     }
 }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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;
        }
예제 #19
0
        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);
        }
예제 #20
0
        /// <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;
        }
예제 #21
0
 /// <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;
 }
예제 #22
0
        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);
            }
        }
예제 #23
0
 /// <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);
 }
예제 #24
0
        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;
            }
        }
예제 #25
0
        /// <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;
        }
예제 #26
0
        /// <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);
        }
예제 #27
0
        /// <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;
        }
예제 #28
0
        /// <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;
        }
예제 #29
0
        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;
            }
        }
예제 #30
0
 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);
 }