/// <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); }
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)); }
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") });
/// <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)); }
internal IReadOnlyMachineStateEnumerator(TuringMachineState machineState) { MachineState = machineState; Size = machineState.Size; _Index = -1; }