Example #1
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));
        }
Example #2
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);
 }
Example #3
0
        // Tests a valid script
        private static void AssertIsValid(string script)
        {
            SyntaxValidationResult result = Brainf_ckParser.ValidateSyntax(script);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(result.ErrorOffset, -1);
            Assert.AreEqual(result.ErrorType, SyntaxError.None);
        }
Example #4
0
        // Tests an invalid script
        private static void AssertIsInvalid(string script, int position, SyntaxError error)
        {
            SyntaxValidationResult result = Brainf_ckParser.ValidateSyntax(script);

            Assert.IsFalse(result.IsSuccess);
            Assert.AreEqual(result.ErrorOffset, position);
            Assert.AreEqual(result.ErrorType, error);
        }
Example #5
0
        // Tests a sequence of characters
        private static void AssertIsOperator(string characters, bool result)
        {
            foreach (char c in characters)
            {
                bool isOperator = Brainf_ckParser.IsOperator(c);

                Assert.AreEqual(isOperator, result);
            }
        }
Example #6
0
        public void EmptyStackTrace()
        {
            using MemoryOwner <Brainf_ckOperator>?operators = Brainf_ckParser.TryParse <Brainf_ckOperator>("++[>++>-]>+", out _);

            Assert.IsNotNull(operators);

            using MemoryOwner <StackFrame> stackFrames = MemoryOwner <StackFrame> .Allocate(512);

            stackFrames.DangerousGetReference() = new StackFrame(new Range(0, operators !.Length), 10);

            HaltedExecutionInfo?exceptionInfo = Brainf_ckInterpreter.LoadDebugInfo(operators.Span, stackFrames.Span, -1);

            Assert.IsNull(exceptionInfo);
        }
Example #7
0
        public void ValidateReleaseCompression()
        {
            Span <Brainf_ckOperation> operations = stackalloc[]
            {
                new Brainf_ckOperation(Operators.Plus, 5),
                new Brainf_ckOperation(Operators.Minus, 4),
                new Brainf_ckOperation(Operators.ForwardPtr, 7),
                new Brainf_ckOperation(Operators.BackwardPtr, 3),
                new Brainf_ckOperation(Operators.ForwardPtr, 1),
                new Brainf_ckOperation(Operators.BackwardPtr, 1),
                new Brainf_ckOperation(Operators.ForwardPtr, 2),
                new Brainf_ckOperation(Operators.FunctionStart, 1),
                new Brainf_ckOperation(Operators.Plus, 5),
                new Brainf_ckOperation(Operators.FunctionEnd, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.LoopStart, 1),
                new Brainf_ckOperation(Operators.LoopStart, 1),
                new Brainf_ckOperation(Operators.Plus, 5),
                new Brainf_ckOperation(Operators.LoopEnd, 1),
                new Brainf_ckOperation(Operators.LoopEnd, 1),
                new Brainf_ckOperation(Operators.FunctionCall, 1),
                new Brainf_ckOperation(Operators.Plus, 15),
                new Brainf_ckOperation(Operators.Minus, 15),
                new Brainf_ckOperation(Operators.PrintChar, 1),
                new Brainf_ckOperation(Operators.PrintChar, 1),
                new Brainf_ckOperation(Operators.ReadChar, 1),
                new Brainf_ckOperation(Operators.ReadChar, 1),
            };

            string script = Brainf_ckParser.ExtractSource(operations);

            using MemoryOwner <Brainf_ckOperation>?buffer = Brainf_ckParser.TryParse <Brainf_ckOperation>(script, out SyntaxValidationResult result);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(result.ErrorType, SyntaxError.None);
            Assert.AreEqual(result.ErrorOffset, -1);
            Assert.AreEqual(result.OperatorsCount, script.Length);

            CollectionAssert.AreEqual(operations.ToArray(), buffer !.Span.ToArray());
        }
Example #8
0
        public void RootBreakpoint()
        {
            using MemoryOwner <Brainf_ckOperator>?operators = Brainf_ckParser.TryParse <Brainf_ckOperator>("++[>++>-]>+", out _);

            Assert.IsNotNull(operators);

            using MemoryOwner <StackFrame> stackFrames = MemoryOwner <StackFrame> .Allocate(512);

            stackFrames.DangerousGetReference() = new StackFrame(new Range(0, operators !.Length), 7);

            HaltedExecutionInfo?exceptionInfo = Brainf_ckInterpreter.LoadDebugInfo(operators.Span, stackFrames.Span, 0);

            Assert.IsNotNull(exceptionInfo);
            Assert.AreEqual(exceptionInfo !.StackTrace.Count, 1);
            Assert.AreEqual(exceptionInfo.StackTrace[0], "++[>++>-");
            Assert.AreEqual(exceptionInfo.HaltingOperator, '-');
            Assert.AreEqual(exceptionInfo.HaltingOffset, 7);
        }
Example #9
0
        public void TryParseInReleaseMode()
        {
            const string script = "[\n\tTest script\n]\n+++++[\n\t>++ 5 x 2 = 10\n\t<- Loop decrement\n]\n> Move to cell 1";

            using MemoryOwner <Brainf_ckOperation>?operations = Brainf_ckParser.TryParse <Brainf_ckOperation>(script, out SyntaxValidationResult result);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(result.ErrorType, SyntaxError.None);
            Assert.AreEqual(result.ErrorOffset, -1);
            Assert.AreEqual(result.OperatorsCount, 15);

            Assert.IsNotNull(operations);
            Assert.AreEqual(operations !.Length, 10);

            string source = Brainf_ckParser.ExtractSource(operations.Span);

            Assert.IsNotNull(source);
            Assert.AreEqual(source, "[]+++++[>++<-]>");
        }
        public static bool HaveSameColor(char first, char second)
        {
            if (first == second)
            {
                return(true);
            }

            // Always have the lowest character in first position
            if (second > first)
            {
                (first, second) = (second, first);
            }

            return
                (!Brainf_ckParser.IsOperator(first) && !Brainf_ckParser.IsOperator(second) ||
                 first == Characters.BackwardPtr && second == Characters.ForwardPtr ||
                 first == Characters.Plus && second == Characters.Minus ||
                 first == Characters.LoopStart && second == Characters.LoopEnd ||
                 first == Characters.FunctionStart && second == Characters.FunctionEnd);
        }
Example #11
0
        public void FunctionCallBreakpoint()
        {
            using MemoryOwner <Brainf_ckOperator>?operators = Brainf_ckParser.TryParse <Brainf_ckOperator>("(+>):+", out _);

            Assert.IsNotNull(operators);

            using MemoryOwner <StackFrame> stackFrames = MemoryOwner <StackFrame> .Allocate(512);

            stackFrames.Span[0] = new StackFrame(new Range(0, operators !.Length), 5);
            stackFrames.Span[1] = new StackFrame(new Range(1, 3), 2);

            HaltedExecutionInfo?exceptionInfo = Brainf_ckInterpreter.LoadDebugInfo(operators.Span, stackFrames.Span, 1);

            Assert.IsNotNull(exceptionInfo);
            Assert.AreEqual(exceptionInfo !.StackTrace.Count, 2);
            Assert.AreEqual(exceptionInfo.StackTrace[0], "+>");
            Assert.AreEqual(exceptionInfo.StackTrace[1], "(+>):");
            Assert.AreEqual(exceptionInfo.HaltingOperator, '>');
            Assert.AreEqual(exceptionInfo.HaltingOffset, 2);
        }
Example #12
0
        public void ExtractSource()
        {
            Span <Brainf_ckOperator> operators = stackalloc Brainf_ckOperator[]
            {
                Operators.Plus,
                Operators.Minus,
                Operators.ForwardPtr,
                Operators.BackwardPtr,
                Operators.PrintChar,
                Operators.ReadChar,
                Operators.LoopStart,
                Operators.LoopEnd,
                Operators.FunctionStart,
                Operators.FunctionEnd,
                Operators.FunctionCall
            };

            string source = Brainf_ckParser.ExtractSource(operators);

            Assert.IsNotNull(source);
            Assert.AreEqual(source, "+-><.,[]():");
        }
Example #13
0
 protected override void OnTextChanged(ReadOnlyMemory <char> text)
 {
     ValidationResult = Brainf_ckParser.ValidateSyntax(text.Span);
     Column           = text.Length + 1;
 }