Пример #1
0
 /// <summary>
 /// Creates a new <see cref="InterpreterSession"/> with the specified parameters
 /// </summary>
 /// <param name="opcodes">The sequence of parsed opcodes to execute</param>
 /// <param name="breakpoints">The table of breakpoints for the current executable</param>
 /// <param name="jumpTable">The jump table for loops and function declarations</param>
 /// <param name="functions">The mapping of functions for the current execution</param>
 /// <param name="definitions">The lookup table to check which functions are defined</param>
 /// <param name="stackFrames">The sequence of stack frames for the current execution</param>
 /// <param name="stdin">The input <see cref="ReadOnlyMemory{T}"/> to read characters from</param>
 /// <param name="machineState">The target machine state to use to run the script</param>
 /// <param name="executionToken">A <see cref="CancellationToken"/> that can be used to halt the execution</param>
 /// <param name="debugToken">A <see cref="CancellationToken"/> that is used to ignore/respect existing breakpoints</param>
 internal InterpreterSession(
     MemoryOwner <Brainf_ckOperator> opcodes,
     MemoryOwner <bool> breakpoints,
     MemoryOwner <int> jumpTable,
     MemoryOwner <Range> functions,
     MemoryOwner <ushort> definitions,
     MemoryOwner <StackFrame> stackFrames,
     ReadOnlyMemory <char> stdin,
     TuringMachineState machineState,
     CancellationToken executionToken,
     CancellationToken debugToken)
 {
     Opcodes        = opcodes;
     Breakpoints    = breakpoints;
     JumpTable      = jumpTable;
     Functions      = functions;
     Definitions    = definitions;
     StackFrames    = stackFrames;
     MachineState   = machineState;
     StdinBuffer    = new StdinBuffer(stdin);
     StdoutBuffer   = StdoutBuffer.Allocate();
     ExecutionToken = executionToken;
     DebugToken     = debugToken;
     Stopwatch      = new Stopwatch();
     SourceCode     = Brainf_ckParser.ExtractSource(opcodes.Span);
 }
Пример #2
0
        public Option <InterpreterResult> TryRun()
        {
            Guard.IsNotNull(Source, nameof(Source));

            using MemoryOwner <Brainf_ckOperation>?operations = Brainf_ckParser.TryParse <Brainf_ckOperation>(Source.Value.Span, out SyntaxValidationResult validationResult);

            if (!validationResult.IsSuccess)
            {
                return(Option <InterpreterResult> .From(validationResult));
            }

            if (InitialState is TuringMachineState initialState)
            {
                Guard.IsNull(MemorySize, nameof(MemorySize));
                Guard.IsNull(OverflowMode, nameof(OverflowMode));

                initialState = (TuringMachineState)initialState.Clone();
            }
            else
            {
                int size = MemorySize ?? Specs.DefaultMemorySize;

                Guard.IsBetweenOrEqualTo(size, Specs.MinimumMemorySize, Specs.MaximumMemorySize, nameof(MemorySize));

                initialState = new TuringMachineState(size, OverflowMode ?? Specs.DefaultOverflowMode);
            }

            InterpreterResult result = Brainf_ckInterpreter.Release.Run(
                operations !.Span,
                Stdin.GetValueOrDefault().Span,
                initialState,
                ExecutionToken);

            return(Option <InterpreterResult> .From(validationResult, result));
        }
Пример #3
0
        public Option <InterpreterSession> TryRun()
        {
            Guard.IsNotNull(Source, nameof(Source));

            if (InitialState is TuringMachineState initialState)
            {
                Guard.IsNull(MemorySize, nameof(MemorySize));
                Guard.IsNull(OverflowMode, nameof(OverflowMode));

                initialState = (TuringMachineState)initialState.Clone();
            }
            else
            {
                int size = MemorySize ?? Specs.DefaultMemorySize;

                Guard.IsBetweenOrEqualTo(size, Specs.MinimumMemorySize, Specs.MaximumMemorySize, nameof(MemorySize));

                initialState = new TuringMachineState(size, OverflowMode ?? Specs.DefaultOverflowMode);
            }

            return(Brainf_ckInterpreter.Debug.TryCreateSession(
                       Source.Value.Span,
                       Breakpoints.Span,
                       Stdin.GetValueOrDefault(),
                       initialState,
                       ExecutionToken,
                       DebugToken));
        }
            /// <summary>
            /// Runs a given Brainf*ck/PBrain executable with the given parameters
            /// </summary>
            /// <param name="opcodes">The executable to run</param>
            /// <param name="stdin">The input buffer to read data from</param>
            /// <param name="machineState">The target machine state to use to run the script</param>
            /// <param name="executionToken">A <see cref="CancellationToken"/> that can be used to halt the execution</param>
            /// <returns>An <see cref="InterpreterResult"/> instance with the results of the execution</returns>
            public static InterpreterResult Run(
                Span <Brainf_ckOperation> opcodes,
                ReadOnlySpan <char> stdin,
                TuringMachineState machineState,
                CancellationToken executionToken)
            {
                Assert(opcodes.Length >= 0);
                Assert(machineState.Size >= 0);

                return(machineState.Mode switch
                {
                    OverflowMode.ByteWithOverflow => Run <TuringMachineState.ByteWithOverflowExecutionContext>(opcodes, stdin, machineState, executionToken),
                    OverflowMode.ByteWithNoOverflow => Run <TuringMachineState.ByteWithNoOverflowExecutionContext>(opcodes, stdin, machineState, executionToken),
                    OverflowMode.UshortWithOverflow => Run <TuringMachineState.UshortWithOverflowExecutionContext>(opcodes, stdin, machineState, executionToken),
                    OverflowMode.UshortWithNoOverflow => Run <TuringMachineState.UshortWithNoOverflowExecutionContext>(opcodes, stdin, machineState, executionToken),
                    _ => ThrowHelper.ThrowArgumentOutOfRangeException <InterpreterResult>(nameof(TuringMachineState.Mode), "Invalid execution mode")
                });
Пример #5
0
            /// <summary>
            /// Creates a new Brainf*ck/PBrain session with the given parameters
            /// </summary>
            /// <param name="source">The source code to parse and execute</param>
            /// <param name="breakpoints">The sequence of indices for the breakpoints to apply to the script</param>
            /// <param name="stdin">The input buffer to read data from</param>
            /// <param name="machineState">The target machine state to use to run the script</param>
            /// <param name="executionToken">A <see cref="CancellationToken"/> that can be used to halt the execution</param>
            /// <param name="debugToken">A <see cref="CancellationToken"/> that is used to ignore/respect existing breakpoints</param>
            /// <returns>An <see cref="Option{T}"/> of <see cref="InterpreterSession"/> instance with the results of the execution</returns>
            public static Option <InterpreterSession> TryCreateSession(
                ReadOnlySpan <char> source,
                ReadOnlySpan <int> breakpoints,
                ReadOnlyMemory <char> stdin,
                TuringMachineState machineState,
                CancellationToken executionToken,
                CancellationToken debugToken)
            {
                MemoryOwner <Brainf_ckOperator> opcodes = Brainf_ckParser.TryParse <Brainf_ckOperator>(source, out SyntaxValidationResult validationResult) !;

                if (!validationResult.IsSuccess)
                {
                    return(Option <InterpreterSession> .From(validationResult));
                }

                // Initialize the temporary buffers
                MemoryOwner <bool>  breakpointsTable = LoadBreakpointsTable(source, validationResult.OperatorsCount, breakpoints);
                MemoryOwner <int>   jumpTable        = LoadJumpTable(opcodes.Span, out int functionsCount);
                MemoryOwner <Range> functions        = MemoryOwner <Range> .Allocate(ushort.MaxValue, AllocationMode.Clear);

                MemoryOwner <ushort>     definitions = LoadDefinitionsTable(functionsCount);
                MemoryOwner <StackFrame> stackFrames = MemoryOwner <StackFrame> .Allocate(Specs.MaximumStackSize);

                // Initialize the root stack frame
                stackFrames.DangerousGetReference() = new StackFrame(new Range(0, opcodes.Length), 0);

                // Create the interpreter session
                InterpreterSession session = new InterpreterSession(
                    opcodes,
                    breakpointsTable,
                    jumpTable,
                    functions,
                    definitions,
                    stackFrames,
                    stdin,
                    machineState,
                    executionToken,
                    debugToken);

                return(Option <InterpreterSession> .From(validationResult, session));
            }
Пример #6
0
 internal IReadOnlyMachineStateEnumerator(TuringMachineState machineState)
 {
     MachineState = machineState;
     Size         = machineState.Size;
     _Index       = -1;
 }