예제 #1
0
        /// <summary>
        /// Translates the second argument to the machine code.
        /// The resulting value contains the argument encoding in the right
        /// position within the word, and zeroes in locations intended for the
        /// OPCode (mnemonic) and the other argument.
        /// </summary>
        /// <remarks>
        /// Because there is no third argument for I/O instructions, the second
        /// argument uses additional four bits.
        ///
        /// If the argument is a constant, it is stored in the lowest 7 bits,
        /// while the 8th has the value 0 to indicate a constant.
        ///
        /// If 3-bit addressing is used, the 5th to 8th bits have value 1000b,
        /// while the address is stored in the 3 lowest bits. The 4th lowest
        /// bit indicates if direct (0) or indirect (1) addressing is used.
        /// </remarks>
        /// <returns>A value containing the translation of the argument</returns>
        protected ushort TranslateArgument2()
        {
            if (Argument2.Type == ArgumentType.None)
            {
                return(1);                                                 // This argument is optional.
            }
            int value;

            Argument2.LookUpValue(Assembler, out value);

            if (Argument2.Type == ArgumentType.Constant || Argument2.Type == ArgumentType.SymbolConstant)
            {
                ushort constant = (ushort)value;
                // No shifting is required, and the constant range [0..127] garanties that
                // only the first 7 low bits can be set.
                return(constant);
            }
            else
            {
                // Write address to the lowest 3 bits
                ushort result = (ushort)value;
                if (Argument2.Type == ArgumentType.Indirect)
                {
                    // Indirect addressing is indicated by setting the 4th lowest bit.
                    result |= 0x8;
                }
                // The 3-bit address and the (in)direct addresing indicator are already in place.
                // It is only necessary to write the 1000b marker to the second argument position.
                result |= 0x8 << 4;
                return(result);
            }
        }
예제 #2
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, it's value can be between [-32768..32767]
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                if (value < 0 || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, 0, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < short.MinValue || value > short.MaxValue)
                {
                    Error             = new Error();
                    Error.ID          = 2;
                    Error.Description = string.Format(Messages.E0002, Argument2.Text);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }
예제 #3
0
            public int CompareTo(object obj)
            {
                if (obj == null)
                {
                    return(1);
                }
                var second = obj as AvailableExpression;

                if (second != null)
                {
                    var arg1Res = Argument1.CompareTo(second.Argument1);
                    if (arg1Res == 0)
                    {
                        var arg2Res = Argument2.CompareTo(second.Argument2);
                        if (arg2Res == 0)
                        {
                            return(Operation.CompareTo(second.Operation));
                        }
                        else
                        {
                            return(arg2Res);
                        }
                    }
                    else
                    {
                        return(arg1Res);
                    }
                }
                else
                {
                    return(1);
                }
            }
예제 #4
0
        /// <summary>
        /// Translates the second argument to the machine code.
        /// The resulting value contains the argument encoding in the right
        /// position within the word, and zeroes in locations intended for the
        /// OPCode (mnemonic) or other arguments.
        /// </summary>
        /// <param name="constantSet">used to indicate that the argument is a consant, otherwise unchanged</param>
        /// <param name="constant">used to store the constant, if any, otherwise unchanged</param>
        /// <returns>A value containing the translation of the argument</returns>
        protected ushort TranslateArgument2(ref bool constantSet, ref ushort constant)
        {
            int value;

            Argument2.LookUpValue(Assembler, out value);

            if (Argument2.Type == ArgumentType.Constant || Argument2.Type == ArgumentType.SymbolConstant)
            {
                constant    = (ushort)value;
                constantSet = true;
                // The argument field content is not defined if it is a constant.
                return(0);
            }
            else
            {
                // Write address to the lowest 3 bits
                ushort result = (ushort)value;
                if (Argument2.Type == ArgumentType.Indirect)
                {
                    // Indirect addressing is indicated by setting the 4th lowest bit.
                    result |= 0x8;
                }
                // Move the argument to the right position : 00000000aaaa0000
                result <<= 4;
                return(result);
            }
        }
        public void PopulateFilterIndex(Type type, IDictionary <string, IList <QueryFilterCondition> > index)
        {
            if (Operator != and)
            {
                return;
            }

            if (Argument1 != null)
            {
                Argument1.PopulateFilterIndex(type, index);
            }
            else if (Child1 != null)
            {
                Child1.PopulateFilterIndex(type, index);
            }

            if (Argument2 != null)
            {
                Argument2.PopulateFilterIndex(type, index);
            }
            else if (Child2 != null)
            {
                Child2.PopulateFilterIndex(type, index);
            }
        }
예제 #6
0
        public override int GetHashCode()
        {
            int hash = 0;

            hash += Operation.GetHashCode();
            hash += Argument1.GetHashCode();
            hash += Argument2.GetHashCode();
            hash += Result.GetHashCode();
            hash += Label.GetHashCode();
            return(hash);
        }
예제 #7
0
            public override bool Equals(object obj)
            {
                if (obj == null)
                {
                    return(false);
                }
                var second = obj as AvailableExpression;

                if (second == null)
                {
                    return(false);
                }
                return(Argument1.Equals(second.Argument1) &&
                       Argument2.Equals(second.Argument2) &&
                       Operation.Equals(second.Operation));
            }
예제 #8
0
        public void WriteXML(XElement ele, ElderScrollsPlugin master)
        {
            XElement subEle;

            ele.TryPathTo("Type", true, out subEle);
            subEle.Value = Type.ToString();

            ele.TryPathTo(Arg1Label, true, out subEle);
            if (Arg1Type == null)
            {
                subEle.Value = ((byte[])Argument1).ToHex();
            }
            else if (Arg1Type == typeof(FormID))
            {
                Argument1.WriteXML(subEle, master);
            }
            else if (Arg1Type.IsEnum)
            {
                subEle.Value = Argument1.ToString();
            }
            else
            {
                throw new ArgumentException(Arg1Type.ToString() + " is not handled.");
            }

            ele.TryPathTo(Arg2Label, true, out subEle);
            if (Arg2Type == null)
            {
                subEle.Value = ((byte[])Argument2).ToHex();
            }
            else if (Arg2Type == typeof(FormID))
            {
                Argument2.WriteXML(subEle, master);
            }
            else if (Arg2Type.IsEnum)
            {
                subEle.Value = Argument2.ToString();
            }
            else if (Arg2Type == typeof(uint))
            {
                subEle.Value = Argument2.ToString();
            }
            else
            {
                throw new ArgumentException(Arg2Type.ToString() + " is not handled.");
            }
        }
예제 #9
0
        public override void Execute
        (
            PftContext context
        )
        {
            Argument1.Execute(context);

            int minLength = 1;

            if (Argument2 == null)
            {
                if (Argument3 == null)
                {
                    minLength = 16;
                }
            }
            else
            {
                Argument2.Execute(context);
                minLength = (int)Argument2.Value;
            }

            bool useE          = true;
            int  decimalPoints = 0;

            if (Argument3 != null)
            {
                useE = false;
                Argument3.Execute(context);
                decimalPoints = (int)Argument3.Value;
            }

            string format = useE
                ? string.Format("E{0}", minLength)
                : string.Format("F{0}", decimalPoints);

            context.Write
            (
                Argument1.Value.ToString
                (
                    format,
                    CultureInfo.InvariantCulture
                )
            );
        }
예제 #10
0
        /// <summary>
        /// Formats the instruction as string.
        /// <example>
        /// ADD (x), x, 2
        /// </example>
        /// </summary>
        /// <returns>A string representing the instruction</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(Mnemonic);
            sb.Append(' ');
            sb.Append(Argument1.ToString());
            if (Argument2.Type != ArgumentType.None)
            {
                sb.Append(", ");
                sb.Append(Argument2.ToString());
            }
            if (Argument3.Type != ArgumentType.None)
            {
                sb.Append(", ");
                sb.Append(Argument3.ToString());
            }
            return(sb.ToString());
        }
예제 #11
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, its value must be between [0..127] because there are
        /// 7 bits reserved for storing the constant.
        /// These instructions have a maximum of two arguments, so the second argument is stored in eight
        /// instead of the usual four bits.
        ///
        /// If the argument is a 3-bit address, the value must be between [0..7]
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            // If there is no second argumnt, then there is no argument here. See what I did there? :P
            if (Argument2.Type == ArgumentType.None)
            {
                return(true);
            }

            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                if (value < 0 || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, 0, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < 0 || value > 127)
                {
                    Error             = new Error();
                    Error.ID          = 5;
                    Error.Description = Messages.E0005;
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }
예제 #12
0
        /// <summary>
        /// Checks if the second argument is valid.
        /// </summary>
        /// <remarks>
        /// The second argument can be either a constant, or a direct or indirect 3-bit addressing.
        ///
        /// If the argument is a constant, it's value can be between [-32768..32767]
        ///
        /// If the argument is a 3-bit address, the value can be between [0..7] only if
        /// the third argument is NOT a constant. Otherwise, it is between [1..7].
        /// This is due to fact that the constant argument is encoded as 0 and it
        /// would be imposible to differentiate it from the 0 address.
        /// (The constant is stored in the second word of the instruction and only one
        /// argument can be a constant.)
        /// </remarks>
        /// <returns>A value indicating if Argument2 is valid</returns>
        protected bool CheckArgument2()
        {
            int value;

            if (!Argument2.LookUpValue(Assembler, out value))
            {
                return(false);
            }

            if (Argument2.Type == ArgumentType.Direct || Argument2.Type == ArgumentType.Indirect)
            {
                // Techically, an indirect addressing of the zero address would not be a problem, because the encoded
                // argument would be 1000b, not 0000b like a constant, but pCAS (the original assembler) does not allow this.
                // For compatibility, neither does Messy Lab.
                int min = Argument3.Type == ArgumentType.Constant || Argument3.Type == ArgumentType.SymbolConstant ? 1 : 0;
                if (value < min || value > 7)
                {
                    Error             = new Error();
                    Error.ID          = 3;
                    Error.Description = string.Format(Messages.E0003, Argument2.Text, min, 7);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            else
            {
                if (value < short.MinValue || value > short.MaxValue)
                {
                    Error             = new Error();
                    Error.ID          = 2;
                    Error.Description = string.Format(Messages.E0002, Argument2.Text);
                    Error.Line        = Line;
                    Error.Column      = Argument2.Column;
                    return(false);
                }
            }
            return(true);
        }
 public override double Compute(IReadOnlyDictionary <string, double> variableValues)
 => Argument1.Compute(variableValues) / Argument2.Compute(variableValues);
예제 #14
0
 public bool UseVariable(string variable)
 {
     return(Argument1.Equals(variable) || Argument2.Equals(variable));
 }