예제 #1
0
        public override Value Evaluate()
        {
            ValueStack stack     = Runtime.State.Stack;
            Value      reference = stack.Pop(true, LOCATION);
            Value      target    = stack.Pop(true, LOCATION);
            var        obj       = reference as Object;
            Array      metadata;

            if (target.Meta == null)
            {
                metadata    = new Array();
                target.Meta = metadata;
            }
            else
            {
                metadata = target.Meta;
            }
            if (obj != null)
            {
                string key = Runtime.State.IsBound(reference) ? Runtime.State.Unbind(reference) : reference.Type.ToString();
                metadata[key] = reference;
                return(target);
            }
            return(metadata[reference.Text]);
        }
예제 #2
0
        public static void PopTest()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(3)
                        );

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(2)
                        );

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(1)
                        );

            Assert.That(() => valueStack.Pop(),
                        Throws.InvalidOperationException
                        );

            valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            _ = valueStack.Pop();
            valueStack.Push(4);

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(4)
                        );

            _ = valueStack.Pop();
            valueStack.Push(5);
            valueStack.Push(6);

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(6)
                        );

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(5)
                        );

            Assert.That(() => valueStack.Pop(),
                        Is.EqualTo(1)
                        );

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(3)
                        .And.Count.EqualTo(0)
                        );

            valueStack = new ValueStack <int>();

            Assert.That(() => valueStack.Pop(),
                        Throws.InvalidOperationException
                        );
        }
예제 #3
0
        public static void PeekInt32Test()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            Assert.That(() => valueStack.Peek(0),
                        Is.EqualTo(3)
                        );

            valueStack.Push(4);

            Assert.That(() => valueStack.Peek(0),
                        Is.EqualTo(4)
                        );

            Assert.That(() => valueStack.Peek(3),
                        Is.EqualTo(1)
                        );

            _ = valueStack.Pop();
            valueStack.Push(5);

            Assert.That(() => valueStack.Peek(0),
                        Is.EqualTo(5)
                        );

            Assert.That(() => valueStack.Peek(1),
                        Is.EqualTo(3)
                        );

            _ = valueStack.Pop();
            valueStack.Push(6);
            valueStack.Push(7);

            Assert.That(() => valueStack.Peek(0),
                        Is.EqualTo(7)
                        );

            Assert.That(() => valueStack.Peek(2),
                        Is.EqualTo(3)
                        );

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(6)
                        .And.Count.EqualTo(5)
                        );

            valueStack = new ValueStack <int>();

            Assert.That(() => valueStack.Peek(0),
                        Throws.InstanceOf <ArgumentOutOfRangeException>()
                        .And.Property("ActualValue").EqualTo(0)
                        .And.Property("ParamName").EqualTo("index")
                        );
        }
예제 #4
0
        /// <summary>
        /// 2値取得
        /// </summary>
        /// <param name="pValueStack">ValueStack</param>
        /// <param name="pValue1">値1</param>
        /// <param name="pValue2">値2</param>
        /// <returns>値1のコピー(pValueStackの先頭にpush済み)</returns>
        protected virtual CalculatorValue Get2Value(ValueStack pValueStack, out CalculatorValue pValue1, out CalculatorValue pValue2)
        {
            pValue2 = pValueStack.Pop();
            pValue1 = pValueStack.Pop();

            // pValue1破壊防止のため、身代わりのコピーを作ってスタックに積む
            CalculatorValue newValue = new CalculatorValue(pValue1);

            pValueStack.Push(newValue);
            return(newValue);
        }
예제 #5
0
        public override Value Evaluate()
        {
            ValueStack stack    = Runtime.State.Stack;
            Value      index    = stack.Pop(false, LOCATION);
            Value      value    = stack.Pop(true, LOCATION);
            var        variable = index as Variable;
            string     name     = variable != null ? variable.Value.Text : value.Text;
            Block      block    = Block.GuaranteeBlock(name);

            return(value.IsArray ? new KeyIndexer((Array)value.SourceArray, block) : value);
        }
예제 #6
0
        public static void CopyToTest()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            var destination = new int[3];

            valueStack.CopyTo(destination);

            Assert.That(() => destination,
                        Is.EquivalentTo(new int[] { 1, 2, 3 })
                        );

            _ = valueStack.Pop();
            valueStack.Push(4);

            valueStack.CopyTo(destination);

            Assert.That(() => destination,
                        Is.EquivalentTo(new int[] { 1, 2, 4 })
                        );

            destination = new int[6];
            valueStack.CopyTo(destination);

            Assert.That(() => destination,
                        Is.EquivalentTo(new int[] { 1, 2, 4, 0, 0, 0 })
                        );

            _ = valueStack.Pop();
            valueStack.Push(5);
            valueStack.Push(6);

            valueStack.CopyTo(destination);

            Assert.That(() => destination,
                        Is.EquivalentTo(new int[] { 1, 2, 5, 6, 0, 0 })
                        );

            Assert.That(() => valueStack.CopyTo(Array.Empty <int>()),
                        Throws.ArgumentException
                        .And.Property("ParamName").EqualTo("destination")
                        );

            valueStack = new ValueStack <int>();

            Assert.That(() => valueStack.CopyTo(Array.Empty <int>()),
                        Throws.Nothing
                        );
        }
예제 #7
0
        private bool FindErrorRecoveryState()
        {
            while (true)    // pop states until one found that accepts error token
            {
                if (FsaState.ParserTable != null &&
                    FsaState.ParserTable.ContainsKey(errorToken) &&
                    FsaState.ParserTable[errorToken] > 0) // shift
                {
                    return(true);
                }

#if TRACE_ACTIONS
                Console.Error.WriteLine("Error: popping state {0}", StateStack.TopElement().number);
#endif
                StateStack.Pop();
                ValueStack.Pop();
                LocationStack.Pop();

#if TRACE_ACTIONS
                DisplayStack();
#endif
                if (StateStack.IsEmpty())
                {
#if TRACE_ACTIONS
                    Console.Error.WriteLine("Aborting: didn't find a state that accepts error token");
#endif
                    return(false);
                }
                else
                {
                    FsaState = StateStack.TopElement();
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Find error recovery state.
        /// </summary>
        /// <returns>result.</returns>
        private bool FindErrorRecoveryState()
        {
            while (true)    // pop states until one found that accepts error token
            {
                if (FsaState.ParserTable != null &&
                    FsaState.ParserTable.ContainsKey(errorToken) &&
                    FsaState.ParserTable[errorToken] > 0) // shift
                {
                    return(true);
                }

                StateStack.Pop();
                ValueStack.Pop();
                LocationStack.Pop();

                if (StateStack.IsEmpty())
                {
                    return(false);
                }
                else
                {
                    FsaState = StateStack.TopElement();
                }
            }
        }
예제 #9
0
        private void Reduce(int ruleNumber)
        {
#if TRACE_ACTIONS
            DisplayRule(ruleNumber);
#endif
            Rule rule  = rules[ruleNumber];
            int  rhLen = rule.RightHandSide.Length;
            //
            //  Default actions for unit productions.
            //
            if (rhLen == 1)
            {
                CurrentSemanticValue = ValueStack.TopElement();    // Default action: $$ = $1;
                CurrentLocationSpan  = LocationStack.TopElement(); // Default action "@$ = @1;
            }
            else if (rhLen == 0)
            {
                // Create a new blank value.
                // Explicit semantic action may mutate this value
                CurrentSemanticValue = default(TValue);
                // The location span for an empty production will start with the
                // beginning of the next lexeme, and end with the finish of the
                // previous lexeme.  This gives the correct behaviour when this
                // nonsense value is used in later Merge operations.
                CurrentLocationSpan = (Scanner.yylloc != null && LastSpan != null ?
                                       Scanner.yylloc.Merge(LastSpan) :
                                       default(TSpan));
            }
            else
            {
                // Default action: $$ = $1;
                CurrentSemanticValue = ValueStack[LocationStack.Depth - rhLen];
                //  Default action "@$ = @1.Merge(@N)" for location info.
                TSpan at1 = LocationStack[LocationStack.Depth - rhLen];
                TSpan atN = LocationStack[LocationStack.Depth - 1];
                CurrentLocationSpan =
                    ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
            }

            DoAction(ruleNumber);

            for (int i = 0; i < rule.RightHandSide.Length; i++)
            {
                StateStack.Pop();
                ValueStack.Pop();
                LocationStack.Pop();
            }
            FsaState = StateStack.TopElement();

            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
            {
                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
            }

            StateStack.Push(FsaState);
            ValueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);
        }
예제 #10
0
        public static void ContainsTest()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            Assert.That(() => valueStack.Contains(1),
                        Is.True
                        );

            Assert.That(() => valueStack.Contains(4),
                        Is.False
                        );

            _ = valueStack.Pop();
            valueStack.Push(4);

            Assert.That(() => valueStack.Contains(3),
                        Is.False
                        );

            Assert.That(() => valueStack.Contains(4),
                        Is.True
                        );

            _ = valueStack.Pop();
            valueStack.Push(5);
            valueStack.Push(6);

            Assert.That(() => valueStack.Contains(4),
                        Is.False
                        );

            Assert.That(() => valueStack.Contains(5),
                        Is.True
                        );

            Assert.That(() => valueStack.Contains(6),
                        Is.True
                        );

            valueStack = new ValueStack <int>();

            Assert.That(() => valueStack.Contains(0),
                        Is.False
                        );
        }
예제 #11
0
        public static void TrimExcessTest()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            valueStack.TrimExcess();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(3)
                        .And.Count.EqualTo(3)
                        );

            valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            _ = valueStack.Pop();

            valueStack.Push(4);
            valueStack.TrimExcess();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(3)
                        .And.Count.EqualTo(3)
                        );

            valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            valueStack.Push(4);
            valueStack.Push(5);

            valueStack.TrimExcess();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(5)
                        .And.Count.EqualTo(5)
                        );

            valueStack.EnsureCapacity(15);
            valueStack.TrimExcess(0.3f);

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(15)
                        .And.Count.EqualTo(5)
                        );

            valueStack = new ValueStack <int>();
            valueStack.TrimExcess();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(0)
                        .And.Count.EqualTo(0)
                        );
        }
예제 #12
0
 public int DeleteHead()
 {
     if (AssistStack.Count == 0)
     {
         while (ValueStack.Count != 0)
         {
             AssistStack.Push(ValueStack.Pop());
         }
         if (AssistStack.Count == 0)
         {
             return(-1);
         }
     }
     return(AssistStack.Pop());
 }
예제 #13
0
        public static void ClearTest()
        {
            var valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            valueStack.Clear();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(3)
                        .And.Count.EqualTo(0)
                        );

            valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            _ = valueStack.Pop();

            valueStack.Push(4);
            valueStack.Clear();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(3)
                        .And.Count.EqualTo(0)
                        );

            valueStack = new ValueStack <int>(new int[] { 1, 2, 3 });

            _ = valueStack.Pop();

            valueStack.Push(4);
            valueStack.Push(5);

            valueStack.Clear();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(6)
                        .And.Count.EqualTo(0)
                        );

            valueStack = new ValueStack <int>();
            valueStack.Clear();

            Assert.That(() => valueStack,
                        Has.Property("Capacity").EqualTo(0)
                        .And.Count.EqualTo(0)
                        );
        }
예제 #14
0
        public bool StepThrough()
        {
            if (processStack.Count == 0)
            {
                return(false);
            }

            while (Step())
            {
            }

            while (ValueStack.Count > 0)
            {
                Results.Enqueue(ValueStack.Pop());
            }

            //Results = ValueStack.ToList();

            return(!HasFailed);
        }
예제 #15
0
        private void ExecuteVerify()
        {
            Contract.Ensures(Contract.OldValue(ToBool(ValueStack.Peek())) &&
                             ValueStack.Count == Contract.OldValue(ValueStack.Count) - 1 &&
                             Contract.OldValue(HardFailure) == HardFailure ||
                             !Contract.OldValue(ToBool(ValueStack.Peek())) &&
                             ValueStack.Count == Contract.OldValue(ValueStack.Count) &&
                             HardFailure == true &&
                             ByteArrayComparer.Instance.Compare(ValueStack.Peek(), Contract.OldValue(ValueStack.Peek())) == 0);
            var valid = ToBool(ValueStack.Peek());

            if (valid)
            {
                ValueStack.Pop();
            }
            else
            {
                HardFailure = true;
            }
        }
예제 #16
0
        public override Value Evaluate()
        {
            ValueStack stack   = Runtime.State.Stack;
            bool       resolve = Runtime.State.Resolve;

            if (stack.IsEmpty)
            {
                return(new Array());
            }
            Value right = stack.Pop(resolve, STR_LOCATION);

            if (stack.IsEmpty)
            {
                if (right.IsArray)
                {
                    right = right.SourceArray;
                }
                if (right.Type == Value.ValueType.Array)
                {
                    return(right.Clone());
                }
                if (right is InterpolatedString)
                {
                    right = right.Text;
                }
                return(new Array
                {
                    right
                });
            }
            Value left = stack.Pop(resolve, STR_LOCATION);
            Array array;

            if (left.IsArray)
            {
                left = left.SourceArray;
            }
            if (left is InterpolatedString)
            {
                left = left.Text;
            }
            if (left.Type == Value.ValueType.Array)
            {
                var leftArray = (Array)left.Clone();
                if (leftArray.Packed)
                {
                    array = new Array
                    {
                        leftArray
                    }
                }
                ;
                else
                {
                    array = leftArray;
                }
            }
            else
            {
                array = new Array
                {
                    left
                }
            };
            if (right.IsArray)
            {
                right = right.SourceArray;
            }
            if (right is InterpolatedString)
            {
                right = right.Text;
            }
            if (right.Type == Value.ValueType.Array)
            {
                var rightArray = (Array)right.Clone();
                if (rightArray.Packed)
                {
                    array.Add(rightArray);
                }
                else
                {
                    foreach (Array.IterItem item in rightArray)
                    {
                        array.Add(item.Value);
                    }
                }
            }
            else
            {
                array.Add(right);
            }
            return(array);
        }
예제 #17
0
        /// <summary>
        /// Reduce.
        /// </summary>
        /// <param name="ruleNumber">The rule to reduce by.</param>
        private void Reduce(int ruleNumber)
        {
            Rule rule = rules[ruleNumber];

            //
            //  Default actions for unit productions.
            //
            if (rule.RightHandSide.Length == 1)
            {
                CurrentSemanticValue = ValueStack.TopElement();    // Default action: $$ = $1;
                CurrentLocationSpan  = LocationStack.TopElement(); // Default action "@$ = @1;
            }
            else
            {
                if (rule.RightHandSide.Length == 0)
                {
                    // Create a new blank value.
                    // Explicit semantic action may mutate this value
                    CurrentSemanticValue = default(TValue);
                    // The location span for an empty production will start with the
                    // beginning of the next lexeme, and end with the finish of the
                    // previous lexeme.  This gives the correct behaviour when this
                    // nonsense value is used in later Merge operations.
                    CurrentLocationSpan = (Scanner.yylloc != null && LastSpan != null ?
                                           Scanner.yylloc.Merge(LastSpan) :
                                           default(TSpan));
                }
                else
                {
                    // Default action: $$ = $1;
                    CurrentSemanticValue = ValueStack.TopElement();
                    //  Default action "@$ = @1.Merge(@N)" for location info.
                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
                    TSpan atN = LocationStack[LocationStack.Depth - 1];
                    CurrentLocationSpan =
                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
                }
            }

            DoAction(ruleNumber);

            for (int i = rule.RightHandSide.Length - 1; i >= 0; i--)
            {
                _valueParameterList[i] = ValueStack.Pop(); // capture the values - added by Nate Wallace
                StateStack.Pop();
                LocationStack.Pop();
            }

            if (!_errorOccured)
            {
                ProcessReduce(rule.LeftHandSide, _valueParameterList, rule.RightHandSide.Length); // process the reduce action - added by Nate Wallace
            }
            else
            {
                _errorOccured = false;
            }

            FsaState = StateStack.TopElement();

            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
            {
                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
            }

            StateStack.Push(FsaState);
            ValueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);
        }
예제 #18
0
파일: NSBy.cs 프로젝트: toddcoder/Orange2
 protected virtual Value increment(ValueStack stack) => stack.Pop(true, LOCATION);
예제 #19
0
            private bool Execute(ResolvedInstruction inst)
            {
                switch (inst.Operation)
                {
                case Operation.NOP:
                    break;

                case Operation.BRK:
                    return(false);

                case Operation.HLT:
                    Halted = true;
                    return(false);

                case Operation.ADD:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) + ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.INC:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) + 1));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.SUB:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) - ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.DEC:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) - 1));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.MLT:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) * ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.DIV:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) / ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.MOD:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) % ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.CMP:
                    if (inst.Exists(Operand.A) && inst.Exists(Operand.B))
                    {
                        Flags = (ResolveValue(inst[Operand.A]) - ResolveValue(inst[Operand.B]));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.AND:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) & ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.OR:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) | ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.XOR:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) ^ ResolveValue(inst[Operand.C])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.NAND:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (~(ResolveValue(inst[Operand.B]) & ResolveValue(inst[Operand.C]))));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.NOR:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (~(ResolveValue(inst[Operand.B]) | ResolveValue(inst[Operand.C]))));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.XNOR:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (~(ResolveValue(inst[Operand.B]) ^ ResolveValue(inst[Operand.C]))));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.NOT:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Flags = (~ResolveValue(inst[Operand.B])));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.LSH:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) << 1));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BSL:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) << (int)(ResolveValue(inst[Operand.C]) & 0x7F)));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.RSH:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) >> 1));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BSR:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B) && inst.Exists(Operand.C))
                    {
                        SetRegister(inst[Operand.A], Flags = (ResolveValue(inst[Operand.B]) >> (int)(ResolveValue(inst[Operand.C]) & 0x7F)));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.MOV:
                case Operation.IMM:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], ResolveValue(inst[Operand.B]));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.LOAD:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        var address = ResolveValue(inst[Operand.B]);

                        if (address > (ulong)Host.RAM.LongLength)
                        {
                            throw new InvalidOperationException(this, InvalidOperationException.NotEnoughMemory);
                        }

                        SetRegister(inst[Operand.A], ResolveValue(Host.RAM[address]));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.STORE:
                    if (inst.Exists(Operand.A) && inst.Exists(Operand.B))
                    {
                        var address = ResolveValue(inst[Operand.A]);
                        var value   = ResolveValue(inst[Operand.B]);

                        if (address > (ulong)Host.RAM.LongLength)
                        {
                            throw new InvalidOperationException(this, InvalidOperationException.NotEnoughMemory);
                        }

                        Host.RAM[address] = value;
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.IN:
                    if (inst.IsRegister(Operand.A) && inst.Exists(Operand.B))
                    {
                        SetRegister(inst[Operand.A], Host.IoBus[ResolveValue(inst[Operand.B])]);
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.OUT:
                    if (inst.Exists(Operand.A) && inst.Exists(Operand.B))
                    {
                        Host.IoBus[ResolveValue(inst[Operand.A])] = ResolveValue(inst[Operand.B]);
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.PSH:
                    if (inst.Exists(Operand.A))
                    {
                        ValueStack.Push(ResolveValue(inst[Operand.A]));
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.POP:
                    if (inst.IsRegister(Operand.A))
                    {
                        SetRegister(inst[Operand.A], ValueStack.Pop());
                    }
                    else if (!inst.Exists(Operand.A))
                    {
                        ValueStack.Pop();
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BRA:
                    if (inst.Exists(Operand.A))
                    {
                        InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BRZ:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags == 0)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BNZ:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags != 0)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BRC:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags > Host.BitMask)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BNC:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags <= Host.BitMask)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BRP:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags <= long.MaxValue)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BRN:
                    if (inst.Exists(Operand.A))
                    {
                        if (Flags > long.MaxValue)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BEV:
                    if (inst.Exists(Operand.A) && inst.Exists(Operand.B))
                    {
                        if (ResolveValue(inst[Operand.B]) % 2 == 0)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.BOD:
                    if (inst.Exists(Operand.A) && inst.Exists(Operand.B))
                    {
                        if (ResolveValue(inst[Operand.B]) % 2 == 1)
                        {
                            InstructionPointer = ResolveValue(inst[Operand.A]) - 1;
                        }
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.CAL:
                    if (inst.Exists(Operand.A))
                    {
                        CallStack.Push(InstructionPointer);
                        InstructionPointer = ResolveValue(inst[Operand.A]);
                    }
                    else
                    {
                        Invalid();
                    }
                    break;

                case Operation.RET:
                    if (CallStack.Count == 0)
                    {
                        Halted = true;
                        return(false);
                    }
                    else
                    {
                        InstructionPointer = CallStack.Pop();
                    }
                    break;

                case Operation.MINRAM:
                case Operation.BENCHMARK:
                case Operation.COMPILER_CREATELABEL:
                case Operation.COMPILER_MARKLABEL:
                case Operation.COMPILER_MAXREG:
                    break;

                default:
                    Invalid();
                    break;
                }

                InstructionPointer++;
                return(true);
            }