예제 #1
0
        /// <summary>
        /// Visit an invoke node
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="invokeNode">Invoke syntax node</param>
        /// <returns>Invoke plan</returns>
        private InvokePlanBase VisitInvoke(TestFilePlan plan, TestSetPlan testSetPlan, InvokeCodeNode invokeNode)
        {
            // --- Get start address
            var start = Eval(plan, testSetPlan, invokeNode.StartExpr);

            if (start == null)
            {
                return(null);
            }

            if (invokeNode.IsCall)
            {
                return(new CallPlan(start.AsWord()));
            }

            if (invokeNode.IsHalt)
            {
                return(new StartPlan(start.AsWord(), null));
            }

            // --- Get Stop address
            var stop = Eval(plan, testSetPlan, invokeNode.StopExpr);

            return(stop == null
                ? null
                : new StartPlan(start.AsWord(), stop.AsWord()));
        }
예제 #2
0
        /// <summary>
        /// Visits a test block
        /// </summary>
        /// <param name="plan"></param>
        /// <param name="testSetPlan"></param>
        /// <param name="block"></param>
        /// <returns>Test block plan</returns>
        private TestBlockPlan VisitTestBlock(TestFilePlan plan, TestSetPlan testSetPlan, TestBlockNode block)
        {
            var testBlock = new TestBlockPlan(testSetPlan, block.TestId, block.Category, block.Span);

            if (block.TestOptions != null)
            {
                VisitTestOptions(plan, testSetPlan, block.TestOptions, out var nonmi, out var timeout);
                testBlock.DisableInterrupt = nonmi;
                testBlock.TimeoutValue     = timeout;
            }
            VisitTestParameters(plan, testBlock, block.Params);
            VisitTestCases(plan, testBlock, block.Cases);
            var invoke = VisitInvoke(plan, testSetPlan, block.Act);

            if (invoke != null)
            {
                testBlock.Act = invoke;
            }
            VisitArrange(plan, testBlock, block.Arrange);
            if (block.Breakpoints != null)
            {
                VisitBreakPoints(plan, testBlock, block.Breakpoints);
            }
            testBlock.SignMachineAvalilable();
            VisitAssert(plan, testBlock, block.Assert);
            return(testBlock);
        }
예제 #3
0
        /// <summary>
        /// Visits an assignment of a TestBlock
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testBlockPlan">TestSetPlan to visit</param>
        /// <param name="asgn">Assignment syntax node</param>
        /// <returns>Assignment plan</returns>
        private RunTimeAssignmentPlanBase VisitAssignment(TestFilePlan plan, TestBlockPlan testBlockPlan, AssignmentNode asgn)
        {
            if (asgn is RegisterAssignmentNode regAsgn)
            {
                var value = Eval(plan, testBlockPlan, regAsgn.Expr, true);
                return(value != null
                    ? new RunTimeRegisterAssignmentPlan(regAsgn.RegisterName, regAsgn.Expr)
                    : null);
            }

            if (asgn is FlagAssignmentNode flagAsgn)
            {
                return(new RunTimeFlagAssignmentPlan(flagAsgn.FlagName));
            }

            if (asgn is MemoryAssignmentNode memAsgn)
            {
                var address = Eval(plan, testBlockPlan, memAsgn.Address, true);
                var value   = Eval(plan, testBlockPlan, memAsgn.Value, true);
                if (address == null || value == null)
                {
                    return(null);
                }
                if (memAsgn.Length != null)
                {
                    if (Eval(plan, testBlockPlan, memAsgn.Length, true) == null)
                    {
                        return(null);
                    }
                }
                return(new RunTimeMemoryAssignmentPlan(memAsgn.Address, memAsgn.Value, memAsgn.Length));
            }

            return(null);
        }
예제 #4
0
 /// <summary>
 /// Emits the test plan from the passed syntax nodes
 /// </summary>
 /// <param name="plan">Test plan</param>
 /// <param name="testSetNodes">TesSet syntax nodes</param>
 private void EmitPlan(TestFilePlan plan, IEnumerable <TestSetNode> testSetNodes)
 {
     foreach (var testSetNode in testSetNodes)
     {
         plan.TestSetPlans.Add(VisitTestSet(plan, testSetNode));
     }
 }
예제 #5
0
        /// <summary>
        /// Visits the machine context of a test set
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="machineContext">machine context</param>
        private void VisitMachineContext(TestFilePlan plan, TestSetPlan testSetPlan, MachineContextNode machineContext)
        {
            if (machineContext == null)
            {
                return;
            }
            switch (machineContext.Id.ToUpper())
            {
            case "SPECTRUM48":
                testSetPlan.MachineType = MachineType.Spectrum48;
                return;

            case "SPECTRUM128":
                testSetPlan.MachineType = MachineType.Spectrum128;
                return;

            case "SPECTRUMP3":
                testSetPlan.MachineType = MachineType.SpectrumP3;
                return;

            case "NEXT":
                testSetPlan.MachineType = MachineType.Next;
                return;
            }
            ReportError(Errors.T0002, plan, machineContext.IdSpan);
        }
예제 #6
0
        /// <summary>
        /// Compiles the test specified test file
        /// </summary>
        /// <returns></returns>
        public TestFilePlan Compile(string sourceText)
        {
            var testFilePlan = new TestFilePlan(NOFILE_ITEM);

            DoCompile(testFilePlan, sourceText);
            return(testFilePlan);
        }
예제 #7
0
 /// <summary>
 /// Visits test set options
 /// </summary>
 /// <param name="plan">Test file plan</param>
 /// <param name="testSetPlan">TestSetPlan to visit</param>
 /// <param name="testOptions">TestOptions syntax node</param>
 private void VisitTestOptions(TestFilePlan plan, TestSetPlan testSetPlan, TestOptionsNode testOptions)
 {
     if (testOptions == null)
     {
         return;
     }
     VisitTestOptions(plan, testSetPlan, testOptions, out var nonmi, out var timeout);
     testSetPlan.DisableInterrupt = nonmi ?? false;
     testSetPlan.TimeoutValue     = timeout ?? DEFAULT_TIMEOUT;
 }
예제 #8
0
        /// <summary>
        /// Compiles the test specified test file
        /// </summary>
        /// <param name="filename">Test file name</param>
        /// <returns></returns>
        public TestFilePlan CompileFile(string filename)
        {
            var fi           = new FileInfo(filename);
            var fullName     = fi.FullName;
            var sourceText   = File.ReadAllText(fullName);
            var testFilePlan = new TestFilePlan(fullName);

            DoCompile(testFilePlan, sourceText);
            return(testFilePlan);
        }
예제 #9
0
        /// <summary>
        /// Carries out the compilation of the specified source text into the given plan
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="sourceText">Test language source text</param>
        private void DoCompile(TestFilePlan plan, string sourceText)
        {
            // --- Init the compilation process
            if (sourceText == null)
            {
                throw new ArgumentNullException(nameof(sourceText));
            }

            if (ExecuteParse(plan, sourceText, out var testSetNodes))
            {
                EmitPlan(plan, testSetNodes);
            }
        }
예제 #10
0
        /// <summary>
        /// Visits a callstub node
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">Test set plan to visit</param>
        /// <param name="nodeCallStub">Call stub ode to visit</param>
        private void VisitCallStubContext(TestFilePlan plan, TestSetPlan testSetPlan, CallStubNode nodeCallStub)
        {
            if (nodeCallStub == null)
            {
                return;
            }
            var value = Eval(plan, testSetPlan, nodeCallStub.Value);

            if (value != null)
            {
                testSetPlan.CallStubAddress = value.AsWord();
            }
        }
예제 #11
0
 /// <summary>
 /// Visit the arrange section of the block
 /// </summary>
 /// <param name="plan">Test file plan</param>
 /// <param name="testBlock">TestBlockPlan to visit</param>
 /// <param name="arrange">Arrange syntax node</param>
 private void VisitArrange(TestFilePlan plan, TestBlockPlan testBlock, AssignmentsNode arrange)
 {
     if (arrange == null)
     {
         return;
     }
     foreach (var asgn in arrange.Assignments)
     {
         var asgnPlan = VisitAssignment(plan, testBlock, asgn);
         if (asgnPlan != null)
         {
             testBlock.ArrangeAssignments.Add(asgnPlan);
         }
     }
 }
예제 #12
0
 /// <summary>
 /// Visit the assert section of the block
 /// </summary>
 /// <param name="plan">Test file plan</param>
 /// <param name="testBlock">TestBlockPlan to visit</param>
 /// <param name="assert">Asser syntax node</param>
 private void VisitAssert(TestFilePlan plan, TestBlockPlan testBlock, AssertNode assert)
 {
     if (assert == null)
     {
         return;
     }
     foreach (var expr in assert.Expressions)
     {
         var value = Eval(plan, testBlock, expr, true);
         if (value == null)
         {
             continue;
         }
         testBlock.Assertions.Add(expr);
     }
 }
예제 #13
0
        /// <summary>
        /// Visits breakpoint of the test block
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testBlock">TestBlockPlan to visit</param>
        /// <param name="breakpoints">Breakpoints syntax node</param>
        private void VisitBreakPoints(TestFilePlan plan, TestBlockPlan testBlock, BreakpointsNode breakpoints)
        {
            if (breakpoints == null)
            {
                return;
            }
            foreach (var expr in breakpoints.Expressions)
            {
                var value = Eval(plan, testBlock, expr, true);
                if (value == null)
                {
                    continue;
                }

                testBlock.Breakpoints.Add(expr);
            }
        }
예제 #14
0
        /// <summary>
        /// Visits the parameters of a test block
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testBlock">TestBlockPlan to visit</param>
        /// <param name="paramsNode">Parameters syntax node</param>
        private void VisitTestParameters(TestFilePlan plan, TestBlockPlan testBlock, ParamsNode paramsNode)
        {
            if (paramsNode == null)
            {
                return;
            }
            foreach (var param in paramsNode.Ids)
            {
                if (testBlock.ContainsParameter(param.Id))
                {
                    ReportError(Errors.T0008, plan, param.Span, param.Id);
                    continue;
                }

                testBlock.AddParameter(param.Id);
            }
        }
예제 #15
0
        /// <summary>
        /// Visits the test cases of the block
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testBlock">TestBlockPlan to visit</param>
        /// <param name="cases">Test cases syntax node</param>
        private void VisitTestCases(TestFilePlan plan, TestBlockPlan testBlock, List <TestCaseNode> cases)
        {
            if (cases == null)
            {
                return;
            }
            var testIndex = 0;

            foreach (var blockCase in cases)
            {
                testIndex++;
                var exprs = new List <ExpressionNode>();
                foreach (var expr in blockCase.Expressions)
                {
                    // --- We intentionally use the evaluation context of the test set, because
                    // --- test case expressions must not contain parameter identifiers
                    var value = Eval(plan, testBlock.TestSet, expr, true);
                    if (value == null)
                    {
                        continue;
                    }
                    exprs.Add(expr);
                }
                if (blockCase.Expressions.Count != testBlock.ParameterNames.Count)
                {
                    ReportError(Errors.T0009, plan, blockCase.CaseKeywordSpan, testIndex,
                                blockCase.Expressions.Count, testBlock.ParameterNames.Count);
                }

                var portMocks = new List <PortMockPlan>();

                foreach (var portMockId in blockCase.PortMocks)
                {
                    var portMockPlan = testBlock.TestSet.GetPortMock(portMockId.Id);
                    if (portMockPlan == null)
                    {
                        ReportError(Errors.T0010, plan, portMockId.Span, portMockId.Id);
                        continue;
                    }
                    portMocks.Add(portMockPlan);
                }

                testBlock.TestCases.Add(new TestCasePlan(testBlock, exprs, portMocks, blockCase.TestCaseText, blockCase.Span));
            }
        }
예제 #16
0
        /// <summary>
        /// Visits a single test plan
        /// </summary>
        /// <param name="plan">Test plan to emit</param>
        /// <param name="node">TestSetNode to use</param>
        private TestSetPlan VisitTestSet(TestFilePlan plan, TestSetNode node)
        {
            var testSetPlan = new TestSetPlan(node.TestSetId, node.Span);

            VisitMachineContext(plan, testSetPlan, node.MachineContext);
            VisitSourceContext(plan, testSetPlan, node.SourceContext);
            VisitTestOptions(plan, testSetPlan, node.TestOptions);
            VisitDataBlock(plan, testSetPlan, node.DataBlock);
            if (node.Init != null)
            {
                foreach (var asgn in node.Init.Assignments)
                {
                    var asgnPlan = VisitAssignment(plan, testSetPlan, asgn);
                    if (asgnPlan != null)
                    {
                        testSetPlan.InitAssignments.Add(asgnPlan);
                    }
                }
            }
            if (node.Setup != null)
            {
                testSetPlan.Setup = VisitInvoke(plan, testSetPlan, node.Setup);
            }
            if (node.Cleanup != null)
            {
                testSetPlan.Cleanup = VisitInvoke(plan, testSetPlan, node.Cleanup);
            }

            foreach (var block in node.TestBlocks)
            {
                var blockPlan = VisitTestBlock(plan, testSetPlan, block);
                if (blockPlan != null)
                {
                    if (testSetPlan.TestBlocks.Any(tb =>
                                                   string.Compare(tb.Id, blockPlan.Id, StringComparison.InvariantCultureIgnoreCase) == 0))
                    {
                        ReportError(Errors.T0007, plan, block.TestIdSpan, block.TestId);
                        continue;
                    }
                    testSetPlan.TestBlocks.Add(blockPlan);
                }
            }
            return(testSetPlan);
        }
예제 #17
0
        /// <summary>
        /// Visits a value data member
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="valueMember">Value member syntax node</param>
        private void VisitValueMember(TestFilePlan plan, TestSetPlan testSetPlan, ValueMemberNode valueMember)
        {
            // --- Check ID duplication
            var id = valueMember.Id;

            if (testSetPlan.ContainsSymbol(id))
            {
                ReportError(Errors.T0006, plan, valueMember.IdSpan, id);
                return;
            }

            // --- Evaluate the expression
            var value = Eval(plan, testSetPlan, valueMember.Expr);

            if (value != null)
            {
                testSetPlan.SetDataMember(id, value);
            }
        }
예제 #18
0
        /// <summary>
        /// Vistis test set and test node options
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="testOptions">TestOptions syntax node</param>
        /// <param name="disableInterrupt">Disable interrupt flag</param>
        /// <param name="timeout">TIMEOUT value</param>
        private void VisitTestOptions(TestFilePlan plan, TestSetPlan testSetPlan, TestOptionsNode testOptions, out bool disableInterrupt, out int timeout)
        {
            // --- Set default values
            disableInterrupt = false;
            timeout          = 0;
            if (testOptions?.Options == null)
            {
                return;
            }

            // --- Process options
            var interruptModeFound = false;
            var timeoutFound       = false;

            foreach (var option in testOptions.Options)
            {
                if (option is InterruptOptionNodeBase intNode)
                {
                    if (interruptModeFound)
                    {
                        ReportError(Errors.T0005, plan, intNode.Span, "DI or EI");
                        return;
                    }
                    interruptModeFound = true;
                    disableInterrupt   = intNode is DiTestOptionNode;
                }
                else if (option is TimeoutTestOptionNode timeoutNode)
                {
                    if (timeoutFound)
                    {
                        ReportError(Errors.T0005, plan, timeoutNode.Span, "TIMEOUT");
                        return;
                    }
                    timeoutFound = true;
                    var value = Eval(plan, testSetPlan, timeoutNode.Expr);
                    if (value != null)
                    {
                        timeout = (int)value.AsNumber();
                    }
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Vistis test set and test node options
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="testOptions">TestOptions syntax node</param>
        /// <param name="nonmi">NONMI value</param>
        /// <param name="timeout">TIMEOUT value</param>
        private void VisitTestOptions(TestFilePlan plan, TestSetPlan testSetPlan, TestOptionsNode testOptions, out bool?nonmi, out int?timeout)
        {
            // --- Set default values
            nonmi   = null;
            timeout = null;
            if (testOptions?.Options == null)
            {
                return;
            }

            // --- Process options
            var nonmiFound   = false;
            var timeoutFound = false;

            foreach (var option in testOptions.Options)
            {
                if (option is NoNmiTestOptionNode nonmiNode)
                {
                    if (nonmiFound)
                    {
                        ReportError(Errors.T0005, plan, nonmiNode.Span, "NONMI");
                        return;
                    }
                    nonmiFound = true;
                    nonmi      = true;
                }
                else if (option is TimeoutTestOptionNode timeoutNode)
                {
                    if (timeoutFound)
                    {
                        ReportError(Errors.T0005, plan, timeoutNode.Span, "TIMEOUT");
                        return;
                    }
                    timeoutFound = true;
                    var value = Eval(plan, testSetPlan, timeoutNode.Expr);
                    if (value != null)
                    {
                        timeout = (int)value.AsNumber();
                    }
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Visits the source context of a test set
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="sourceContext">Machine context</param>
        private void VisitSourceContext(TestFilePlan plan, TestSetPlan testSetPlan, SourceContextNode sourceContext)
        {
            if (sourceContext == null)
            {
                return;
            }

            // --- Prepare predefined symbols for Z80 compilation
            var options = new AssemblerOptions();

            foreach (var symbol in sourceContext.Symbols)
            {
                options.PredefinedSymbols.Add(symbol.Id);
            }
            var assembler = new Z80Assembler();

            // --- Check filename existence
            var filename = sourceContext.SourceFile;

            if (!Path.IsPathRooted(filename))
            {
                filename = Path.Combine(DefaultSourceFolder ?? "", filename);
            }
            if (!File.Exists(filename))
            {
                ReportError(Errors.T0003, plan, sourceContext.SourceFileSpan, filename);
                return;
            }

            // --- Compile the Z80 source file
            var output = assembler.CompileFile(filename, options);

            if (output.ErrorCount == 0)
            {
                testSetPlan.CodeOutput = output;
                return;
            }

            // --- Issue cZ80 ompilation error
            ReportError(Errors.T0004, plan, sourceContext.SourceFileSpan, filename, output.ErrorCount);
        }
예제 #21
0
        /// <summary>
        /// Evaluates the specified expression.
        /// </summary>
        /// <param name="sourceItem">Source item of the expression</param>
        /// <param name="evalContext">TestSetPlan that holds the expression</param>
        /// <param name="expr">Expression to evaluate</param>
        /// <param name="checkOnly">Check only if the expression could be evaluated</param>
        /// <returns>
        /// Null, if the expression cannot be evaluated, or evaluation
        /// results an error (e.g. divide by zero)
        /// </returns>
        public ExpressionValue Eval(TestFilePlan sourceItem, IExpressionEvaluationContext evalContext, ExpressionNode expr, bool checkOnly = false)
        {
            if (expr == null)
            {
                throw new ArgumentNullException(nameof(expr));
            }
            if (!expr.ReadyToEvaluate(evalContext))
            {
                ReportError(Errors.T0201, sourceItem, expr.Span);
                return(null);
            }
            var result = expr.Evaluate(evalContext, checkOnly);

            if (expr.EvaluationError == null)
            {
                return(result);
            }

            ReportError(Errors.T0200, sourceItem, expr.Span, expr.EvaluationError);
            return(null);
        }
예제 #22
0
        /// <summary>
        /// Executes the parse phase of the compilation
        /// </summary>
        /// <param name="plan">Test plan</param>
        /// <param name="sourcetext">Source text</param>
        /// <param name="testSetNodes">TestSetNode as the result of compilation</param>
        /// <returns>True, if compilation successful; otherwise, false</returns>
        private bool ExecuteParse(TestFilePlan plan, string sourcetext, out List <TestSetNode> testSetNodes)
        {
            // --- Parse the source text
            var inputStream = new AntlrInputStream(sourcetext);
            var lexer       = new Z80TestLexer(inputStream);
            var tokenStream = new CommonTokenStream(lexer);
            var parser      = new Z80TestParser(tokenStream);
            var context     = parser.compileUnit();
            var visitor     = new Z80TestVisitor();

            visitor.Visit(context);
            testSetNodes = visitor.Compilation.TestSets;

            // --- Collect syntax errors
            foreach (var error in parser.SyntaxErrors)
            {
                ReportError(plan, error);
            }

            return(parser.SyntaxErrors.Count == 0);
        }
예제 #23
0
        /// <summary>
        /// Visits an assignment of a TestSet
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="asgn">Assignment syntax node</param>
        /// <returns>Assignment plan</returns>
        private AssignmentPlanBase VisitAssignment(TestFilePlan plan, TestSetPlan testSetPlan, AssignmentNode asgn)
        {
            if (asgn is RegisterAssignmentNode regAsgn)
            {
                var value = Eval(plan, testSetPlan, regAsgn.Expr);
                return(value != null
                    ? new RegisterAssignmentPlan(regAsgn.RegisterName, value.AsWord())
                    : null);
            }

            if (asgn is FlagAssignmentNode flagAsgn)
            {
                return(new FlagAssignmentPlan(flagAsgn.FlagName));
            }

            if (asgn is MemoryAssignmentNode memAsgn)
            {
                var address = Eval(plan, testSetPlan, memAsgn.Address);
                var value   = Eval(plan, testSetPlan, memAsgn.Value);
                if (address == null || value == null)
                {
                    return(null);
                }
                ExpressionValue length = null;
                if (memAsgn.Length != null)
                {
                    length = Eval(plan, testSetPlan, memAsgn.Length);
                    if (length == null)
                    {
                        return(null);
                    }
                }

                return(length == null
                    ? new MemoryAssignmentPlan(address.AsWord(), value.AsByteArray())
                    : new MemoryAssignmentPlan(address.AsWord(), value.AsByteArray().Take(length.AsWord()).ToArray()));
            }

            return(null);
        }
예제 #24
0
 /// <summary>
 /// Visit a data block
 /// </summary>
 /// <param name="plan">Test file plan</param>
 /// <param name="testSetPlan">TestSetPlan to visit</param>
 /// <param name="dataBlock">DataBlock syntax node</param>
 private void VisitDataBlock(TestFilePlan plan, TestSetPlan testSetPlan, DataBlockNode dataBlock)
 {
     if (dataBlock == null)
     {
         return;
     }
     foreach (var dataMember in dataBlock.DataMembers)
     {
         if (dataMember is ValueMemberNode valueMember)
         {
             VisitValueMember(plan, testSetPlan, valueMember);
         }
         else if (dataMember is MemoryPatternMemberNode mempatMember)
         {
             VisitMemoryPatternMember(plan, testSetPlan, mempatMember);
         }
         else if (dataMember is PortMockMemberNode portMockMember)
         {
             VisitPortMockMember(plan, testSetPlan, portMockMember);
         }
     }
 }
예제 #25
0
        /// <summary>
        /// Visits a test block
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">Test set plan to visit</param>
        /// <param name="block">Block to visit</param>
        /// <returns>Test block plan</returns>
        private TestBlockPlan VisitTestBlock(TestFilePlan plan, TestSetPlan testSetPlan, TestBlockNode block)
        {
            var testBlock = new TestBlockPlan(testSetPlan, block.TestId, block.Category, block.Span);

            if (block.TestOptions != null)
            {
                VisitTestOptions(plan, testSetPlan, block.TestOptions, out var disableInterrupt, out var timeout);
                testBlock.DisableInterrupt = disableInterrupt;
                testBlock.TimeoutValue     = timeout;
            }
            if (block.Setup != null)
            {
                testBlock.Setup = VisitInvoke(plan, testSetPlan, block.Setup);
            }
            VisitTestParameters(plan, testBlock, block.Params);
            VisitTestCases(plan, testBlock, block.Cases);
            var invoke = VisitInvoke(plan, testSetPlan, block.Act);

            if (invoke != null)
            {
                testBlock.Act = invoke;
            }
            VisitArrange(plan, testBlock, block.Arrange);
            if (block.Breakpoints != null)
            {
                VisitBreakPoints(plan, testBlock, block.Breakpoints);
            }
            testBlock.MachineContext = new CompileTimeMachineContext();
            VisitAssert(plan, testBlock, block.Assert);
            if (block.Cleanup != null)
            {
                testBlock.Cleanup = VisitInvoke(plan, testSetPlan, block.Cleanup);
            }

            return(testBlock);
        }
예제 #26
0
 /// <summary>
 /// Reports the specified error
 /// </summary>
 /// <param name="errorCode">Code of error</param>
 /// <param name="sourceItem"></param>
 /// <param name="span">Span associated with the error</param>
 /// <param name="parameters">Optiona error message parameters</param>
 private static void ReportError(string errorCode, TestFilePlan sourceItem, TextSpan span, params object[] parameters)
 {
     sourceItem.Errors.Add(new TestCompilerErrorInfo(sourceItem.Filename, errorCode,
                                                     span.StartLine, span.StartColumn, parameters));
 }
예제 #27
0
 /// <summary>
 /// Translates a Z80AsmParserErrorInfo instance into an error
 /// </summary>
 /// <param name="sourceItem">
 /// Source file information, to allow the error to track the filename the error ocurred in
 /// </param>
 /// <param name="error">Error information</param>
 private static void ReportError(TestFilePlan sourceItem, Z80TestParserErrorInfo error)
 {
     sourceItem.Errors.Add(new TestCompilerErrorInfo(sourceItem.Filename, error));
 }
예제 #28
0
        /// <summary>
        /// Visit a port mock member
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="portMockMember">Port mock syntax node</param>
        private void VisitPortMockMember(TestFilePlan plan, TestSetPlan testSetPlan, PortMockMemberNode portMockMember)
        {
            // --- Check ID duplication
            var id = portMockMember.Id;

            if (testSetPlan.ContainsSymbol(id))
            {
                ReportError(Errors.T0006, plan, portMockMember.IdSpan, id);
                return;
            }

            // --- Get port address
            var portAddress = Eval(plan, testSetPlan, portMockMember.Expr);
            var portMock    = portAddress != null ? new PortMockPlan(portAddress.AsWord()) : null;

            // --- Get pulses
            var pulsesOk       = true;
            var nextPulseStart = 0L;

            foreach (var pulse in portMockMember.Pulses)
            {
                // --- Get pulse expression values
                var value  = Eval(plan, testSetPlan, pulse.ValueExpr);
                var pulse1 = Eval(plan, testSetPlan, pulse.Pulse1Expr);
                if (value == null || pulse1 == null)
                {
                    pulsesOk = false;
                    continue;
                }

                ExpressionValue pulse2 = null;
                if (pulse.Pulse2Expr != null)
                {
                    pulse2 = Eval(plan, testSetPlan, pulse.Pulse2Expr);
                    if (pulse2 == null)
                    {
                        pulsesOk = false;
                        continue;
                    }
                }

                // --- Create a new pulse
                PortPulsePlan pulsePlan;
                if (pulse2 == null)
                {
                    // --- We have only value and length
                    pulsePlan = new PortPulsePlan(value.AsByte(), nextPulseStart,
                                                  nextPulseStart + pulse1.AsNumber() - 1);
                }
                else
                {
                    // --- We have pulse value, start, and end
                    pulsePlan = new PortPulsePlan(value.AsByte(), pulse1.AsNumber(),
                                                  pulse.IsInterval ? pulse2.AsNumber() : pulse1.AsNumber() + pulse2.AsNumber() - 1);
                }
                nextPulseStart = pulsePlan.EndTact + 1;
                portMock?.AddPulse(pulsePlan);
            }

            // --- Create the entire port mock
            if (portMock != null && pulsesOk)
            {
                testSetPlan.SetPortMock(id, portMock);
            }
        }
예제 #29
0
        /// <summary>
        /// Visits a memory pattern member
        /// </summary>
        /// <param name="plan">Test file plan</param>
        /// <param name="testSetPlan">TestSetPlan to visit</param>
        /// <param name="mempatMember">Memory pattern member syntax node</param>
        private void VisitMemoryPatternMember(TestFilePlan plan, TestSetPlan testSetPlan, MemoryPatternMemberNode mempatMember)
        {
            // --- Check ID duplication
            var id = mempatMember.Id;

            if (testSetPlan.ContainsSymbol(id))
            {
                ReportError(Errors.T0006, plan, mempatMember.IdSpan, id);
                return;
            }

            // --- Evaluate byte array
            var bytes      = new List <byte>();
            var errorFound = false;

            foreach (var mempat in mempatMember.Patterns)
            {
                if (mempat is BytePatternNode bytePattern)
                {
                    foreach (var byteExpr in bytePattern.Bytes)
                    {
                        var value = Eval(plan, testSetPlan, byteExpr);
                        if (value != null)
                        {
                            bytes.Add((byte)value.AsNumber());
                        }
                        else
                        {
                            errorFound = true;
                        }
                    }
                }
                else if (mempat is WordPatternNode wordPattern)
                {
                    foreach (var byteExpr in wordPattern.Words)
                    {
                        var value = Eval(plan, testSetPlan, byteExpr);
                        if (value != null)
                        {
                            var word = value.AsWord();
                            bytes.Add((byte)word);
                            bytes.Add((byte)(word >> 8));
                        }
                        else
                        {
                            errorFound = true;
                        }
                    }
                }
                else if (mempat is TextPatternNode textPattern)
                {
                    foreach (var val in SyntaxHelper.SpectrumStringToBytes(textPattern.String))
                    {
                        bytes.Add(val);
                    }
                }
            }

            if (errorFound)
            {
                return;
            }
            testSetPlan.SetDataMember(id, new ExpressionValue(bytes.ToArray()));
        }