Exemplo n.º 1
0
        public ByteCodeExecutor(ByteCodePoint[] program, ILiteral[] literals, int maxVariableIndex)
        {
            if (program == null) throw new ArgumentNullException(nameof(program));

            _program        = program;
            _literals       = literals;
            _programCounter = 0;
            _environment    = new ByteCodeEnvironment(0, 0, null);
            _registers      = new SimpleReference[maxVariableIndex];

            for (var registerIndex = 0; registerIndex<_registers.Length; ++registerIndex)
            {
                _registers[registerIndex] = new SimpleReference();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sets a label referencing the next instruction to be written
        /// </summary>
        public int Label(object label)
        {
            // Write the label
            var labelIp = _program.Count;

            _ipsWithLabel[label] = labelIp;

            // Update any instructions that reference the label
            List <int> existingReferences;

            if (_ipsReferencingLabel.TryGetValue(label, out existingReferences))
            {
                foreach (var refIp in existingReferences)
                {
                    var old = _program[refIp];
                    _program[refIp] = new ByteCodePoint(old.Op, labelIp - refIp, old.Arg2);
                }

                existingReferences.Clear();
            }

            return(labelIp);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Takes any call operations found in this program and replaces them with CallAddress operations
        /// </summary>
        /// <param name="predicateToLabel">Given the predicate for a Call instruction, returns null or the object representing the label for the address to call</param>
        public void BindCalls(Func <ILiteral, object> predicateToLabel)
        {
            if (predicateToLabel == null)
            {
                throw new ArgumentNullException(nameof(predicateToLabel));
            }

            for (int address = 0; address < _program.Count; ++address)
            {
                if (_program[address].Op == Operation.Call)
                {
                    // Ask for the value of this label
                    var label         = predicateToLabel(_literals[_program[address].Literal]);
                    var argumentCount = _program[address].Arg2;
                    int labelAddress;

                    // Try to map it to an existing address
                    if (label != null && _ipsWithLabel.TryGetValue(label, out labelAddress))
                    {
                        _program[address] = new ByteCodePoint(Operation.CallAddress, labelAddress, argumentCount);
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Dispatches a particular code point
        /// </summary>
        public void Dispatch(ByteCodePoint codePoint)
        {
            // Action depends on the opcode
            switch (codePoint.Op)
            {
                case Operation.Nothing:
                    break;

                case Operation.GetStructure:
                    GetStructure(codePoint.Literal, codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.GetVariable:
                    GetVariable(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.GetValue:
                    GetValue(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.PutStructure:
                    PutStructure(codePoint.Literal, codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.PutVariable:
                    PutVariable(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.PutValue:
                    PutValue(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.SetVariable:
                    SetVariable(codePoint.Arg1);
                    break;

                case Operation.SetValue:
                    SetValue(codePoint.Arg1);
                    break;

                case Operation.UnifyVariable:
                    UnifyVariable(codePoint.Arg1);
                    break;

                case Operation.UnifyValue:
                    UnifyValue(codePoint.Arg1);
                    break;

                case Operation.Allocate:
                    Allocate(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.Deallocate:
                    Deallocate();
                    break;

                case Operation.Proceed:
                    Proceed();
                    break;

                case Operation.CallAddress:
                    CallAddress(codePoint.Arg1, codePoint.Arg2);
                    break;

                case Operation.TryMeElse:
                    TryMeElse(codePoint.Arg1);
                    break;

                case Operation.RetryMeElse:
                    RetryMeElse(codePoint.Arg1);
                    break;

                case Operation.TrustMe:
                    TrustMe();
                    break;

                case Operation.Call:
                    throw new NotImplementedException("External calls not yet supported");

                default:
                    throw new NotImplementedException("Unknown opcode");
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Dispatches a particular code point
        /// </summary>
        public void Dispatch(ByteCodePoint codePoint)
        {
            // Action depends on the opcode
            switch (codePoint.Op)
            {
            case Operation.Nothing:
                break;

            case Operation.GetStructure:
                GetStructure(codePoint.Literal, codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.GetVariable:
                GetVariable(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.GetValue:
                GetValue(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.PutStructure:
                PutStructure(codePoint.Literal, codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.PutVariable:
                PutVariable(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.PutValue:
                PutValue(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.SetVariable:
                SetVariable(codePoint.Arg1);
                break;

            case Operation.SetValue:
                SetValue(codePoint.Arg1);
                break;

            case Operation.UnifyVariable:
                UnifyVariable(codePoint.Arg1);
                break;

            case Operation.UnifyValue:
                UnifyValue(codePoint.Arg1);
                break;

            case Operation.Allocate:
                Allocate(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.Deallocate:
                Deallocate();
                break;

            case Operation.Proceed:
                Proceed();
                break;

            case Operation.CallAddress:
                CallAddress(codePoint.Arg1, codePoint.Arg2);
                break;

            case Operation.TryMeElse:
                TryMeElse(codePoint.Arg1);
                break;

            case Operation.RetryMeElse:
                RetryMeElse(codePoint.Arg1);
                break;

            case Operation.TrustMe:
                TrustMe();
                break;

            case Operation.Call:
                throw new NotImplementedException("External calls not yet supported");

            default:
                throw new NotImplementedException("Unknown opcode");
            }
        }