public MultiValue ReadValueMultiValue(object state)
        {
            object arg;

            var name = this._Input.ReadString(4, true, Encoding.ASCII);
            MultiValueOpcode op;

            if (MultiValue.TryParseOpcode(name, out op) == false)
            {
                throw new FormatException("invalid or unknown multivalue opcode");
            }

            // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
            switch (op & MultiValueOpcode.TypeMask) // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
            {
            case MultiValueOpcode.NON:
            {
                arg = null;
                break;
            }

            case MultiValueOpcode.StaticVariable:
            {
                StaticVariableType sv;
                if (MultiValue.TryParseStaticVariable(this._Input.ReadValueU32(), out sv) == false)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected static variable index",
                                  op));
                }
                arg = sv;
                break;
            }

            case MultiValueOpcode.INT:
            {
                arg = this._Input.ReadValueS64();
                break;
            }

            case MultiValueOpcode.FLT:
            {
                arg = this._Input.ReadValueF64();
                break;
            }

            case MultiValueOpcode.STR:
            {
                arg = this._Input.ReadStringPascalUncapped();
                break;
            }

            default:
                throw new InvalidOperationException(
                          string.Format(
                              "multival {0} had an unsupported argument data type",
                              op));
            }

            return(new MultiValue()
            {
                Op = op,
                Arg = arg,
            });
        }
Beispiel #2
0
        public static List <MultiValue> FromStringValue(CDataWrapper value)
        {
            var parser = new Irony.Parsing.Parser(new Grammars.PCodeGrammar());
            var tree   = parser.Parse(value);

            if (tree.Status != Irony.Parsing.ParseTreeStatus.Parsed)
            {
                throw new FormatException("failed to parse pcode");
            }

            var list   = new List <MultiValue>();
            var labels = new Dictionary <string, int>();

            foreach (var line in tree.Root.ChildNodes)
            {
                var label = line.ChildNodes.SingleOrDefault(c => c.Term.Name == "LABEL");
                if (label != null)
                {
                    labels.Add(label.ChildNodes[0].Token.ValueString, list.Count);
                }

                var statement = line.ChildNodes.SingleOrDefault(c => c.Term.Name == "STATEMENT");
                if (statement != null)
                {
                    var code = statement.ChildNodes[0];

                    MultiValueOpcode op;
                    object           arg = null;

                    if (_SimpleOps.ContainsKey(code.Term.Name) == true)
                    {
                        op = _SimpleOps[code.Term.Name];
                    }
                    else
                    {
                        switch (code.Term.Name)
                        {
                        case "OP_J__":
                        {
                            op  = MultiValueOpcode.J__;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        case "OP_JZ_":
                        {
                            op  = MultiValueOpcode.JZ_;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        case "OP_S_V":
                        {
                            op = MultiValueOpcode.S_V;
                            StaticVariableType sv;
                            if (MultiValue.TryParseStaticVariable(code.ChildNodes[1].Token.Text, out sv) == false)
                            {
                                throw new FormatException("invalid static variable type");
                            }
                            arg = sv;
                            break;
                        }

                        case "OP_STR":
                        {
                            op  = MultiValueOpcode.STR;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        case "OP_INT":
                        {
                            op  = MultiValueOpcode.INT;
                            arg = code.ChildNodes[1].Token.Value;
                            break;
                        }

                        case "OP_FLT":
                        {
                            op  = MultiValueOpcode.FLT;
                            arg = code.ChildNodes[1].Token.Value;
                            break;
                        }

                        case "OP_OBJ":
                        {
                            op  = MultiValueOpcode.OBJ;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        case "OP_RP_":
                        {
                            op  = MultiValueOpcode.RP_;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }


                        case "OP_IDS":
                        {
                            op  = MultiValueOpcode.IDS;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        case "OP_FUN":
                        {
                            op  = MultiValueOpcode.FUN;
                            arg = code.ChildNodes[1].Token.ValueString;
                            break;
                        }

                        default:
                        {
                            throw new NotImplementedException();
                        }
                        }
                    }

                    list.Add(new MultiValue()
                    {
                        Op  = op,
                        Arg = arg,
                    });
                }
            }

            foreach (var mv in list.Where(
                         item =>
                         item.Op == MultiValueOpcode.J__ ||
                         item.Op == MultiValueOpcode.JZ_))
            {
                var label = (string)mv.Arg;
                if (labels.ContainsKey(label) == false)
                {
                    throw new InvalidOperationException();
                }
                mv.Arg = (long)labels[label];
            }

            return(list);
        }
        public void WriteValueMultiValue(MultiValue value, object state)
        {
            this._Output.WriteString(value.OpName, 4, Encoding.ASCII);

            // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
            switch (value.Op & MultiValueOpcode.TypeMask) // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
            {
            case MultiValueOpcode.NON:
            {
                if (value.Arg != null)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had a non-null argument",
                                  value.Op));
                }

                break;
            }

            case MultiValueOpcode.StaticVariable:
            {
                if (value.Arg is uint)
                {
                    this._Output.WriteValueU32((uint)value.Arg);
                }
                else if (value.Arg.GetType() == typeof(StaticVariableType))
                {
                    this._Output.WriteValueU32((uint)((StaticVariableType)value.Arg));
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected data type (got {1}, should be uint or StaticVariable)",
                                  value.Op,
                                  value.Arg.GetType().Name));
                }

                break;
            }

            case MultiValueOpcode.INT:
            {
                if (value.Arg.GetType() != typeof(long))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected data type (got {1}, should be long)",
                                  value.Op,
                                  value.Arg.GetType().Name));
                }

                this._Output.WriteValueS64((long)value.Arg);
                break;
            }

            case MultiValueOpcode.FLT:
            {
                if (value.Arg.GetType() != typeof(double))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected data type (got {1}, should be double)",
                                  value.Op,
                                  value.Arg.GetType().Name));
                }

                this._Output.WriteValueF64((double)value.Arg);
                break;
            }

            case MultiValueOpcode.STR:
            {
                if (value.Arg.GetType() != typeof(string))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected data type (got {1}, should be string)",
                                  value.Op,
                                  value.Arg.GetType()));
                }

                this._Output.WriteStringPascalUncapped((string)value.Arg);
                break;
            }

            default:
                throw new InvalidOperationException(
                          string.Format(
                              "multival {0} had an unsupported argument data type",
                              value.Op));
            }
        }
Beispiel #4
0
        public MultiValue ReadValueMultiValue(object state)
        {
            MultiValueOpcode op;
            var _ = this._Input.ReadValueU32();

            if (MultiValue.TryParseOpcode(_, out op) == false)
            {
                throw new FormatException();
            }

            object arg;

            // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
            switch (op & MultiValueOpcode.TypeMask) // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
            {
            case MultiValueOpcode.NON:
            {
                arg = null;
                break;
            }

            case MultiValueOpcode.StaticVariable:
            {
                StaticVariableType sv;
                if (MultiValue.TryParseStaticVariable(this.ReadNativeUInt32Packed(), out sv) == false)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "multival {0} had an unexpected static variable index",
                                  op));
                }
                arg = sv;
                break;
            }

            case MultiValueOpcode.INT:
            {
                var lo = this.ReadNativeUInt32Packed();
                var hi = this.ReadNativeUInt32Packed();
                arg = (long)(((ulong)hi << 32) | lo);
                break;
            }

            case MultiValueOpcode.FLT:
            {
                var lo = this.ReadNativeUInt32Packed();
                var hi = this.ReadNativeUInt32Packed();
                arg = BitConverter.Int64BitsToDouble(((long)hi << 32) | lo);
                break;
            }

            case MultiValueOpcode.STR:
            {
                arg = this._Input.ReadStringZ(Encoding.UTF8);
                break;
            }

            default:
            {
                throw new NotSupportedException("unhandled opcode in multival");
            }
            }

            return(new MultiValue()
            {
                Op = op,
                Arg = arg,
            });
        }