Ejemplo n.º 1
0
        public void DefwPragmaWorksWithImmediateEvaluation()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var expected = new byte[] { 0x01, 0xA0, 0x45, 0x23, 0x12, 0xAE, 122, 0 };

            // --- Act
            var output = compiler.Compile(@"
                .defw #A001, #2345, #AE12, 122");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments.Count.ShouldBe(1);
            var segment = output.Segments[0];

            segment.EmittedCode.Count.ShouldBe(expected.Length);
            for (var i = 0; i < expected.Length; i++)
            {
                segment.EmittedCode[i].ShouldBe(expected[i]);
            }
        }
Ejemplo n.º 2
0
        public void DefwPragmaWorksWithFunctions()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var expected = new byte[] { 0xE5, 0x03 };

            // --- Act
            var output = compiler.Compile(@"
                .defw 1000*sin(1.5)");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments.Count.ShouldBe(1);
            var segment = output.Segments[0];

            segment.EmittedCode.Count.ShouldBe(expected.Length);
            for (var i = 0; i < expected.Length; i++)
            {
                segment.EmittedCode[i].ShouldBe(expected[i]);
            }
        }
Ejemplo n.º 3
0
        public void SkipPragmaWorksWithFillValue()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var expected = new byte[] { 0x3A, 0x3A, 0x3A, 0x3A, 0x3A };

            // --- Act
            var output = compiler.Compile(@"
                .skip $+#05, #3A");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments.Count.ShouldBe(1);
            var segment = output.Segments[0];

            segment.EmittedCode.Count.ShouldBe(expected.Length);
            for (var i = 0; i < expected.Length; i++)
            {
                segment.EmittedCode[i].ShouldBe(expected[i]);
            }
        }
Ejemplo n.º 4
0
        public void IfndefTrueWorksWithoutElseBranch()
        {
            // --- Arrange
            var          compiler = new Z80Assembler();
            var          options  = new AssemblerOptions();
            const string SOURCE   = @"
                  nop ; 1
                  #ifndef MySymbol
                  nop ; 2
                  nop ; 3
                  nop ; 4
                  #endif
                  nop ; 5";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            compiler.PreprocessedLines.Count.ShouldBe(5);
        }
Ejemplo n.º 5
0
        public void IfFalseWorksWithoutElseBranch()
        {
            // --- Arrange
            var          compiler = new Z80Assembler();
            var          options  = new AssemblerOptions();
            const string SOURCE   = @"
                  nop ; 1
                  #if 2 == 3
                  nop
                  nop
                  nop
                  #endif
                  nop ; 2";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            compiler.PreprocessedLines.Count.ShouldBe(2);
        }
Ejemplo n.º 6
0
        public void StructDefinitionWithDuplicatedFieldFails2()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                MyStruct: 
                    .struct
                        field1 .defb 0x12, 0x13
                        field2 ; This is a comment
                        field2 .defgx ""----OOOO OOOO----""
                        field1 .fillw 2, #12A3
                        .defw #FEDC
                    .ends
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(2);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0438);
            output.Errors[1].ErrorCode.ShouldBe(Errors.Z0438);
        }
Ejemplo n.º 7
0
        public void IntegrationTest1()
        {
            List <string> programrows = new List <string>
            {
                "ORG $3000",
                "RST $30",
                "DB  $05",
                "LD  BC,$010C",
                "RST $30",
                "DB  $03",
                "LD  DE,SZOVEG",
                "LD  BC,21",
                "RST $30",
                "DB  $02",
                "RET",
                "SZOVEG  DB 'ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP'"
            };

            string fileName = @"IntegrationTest1.cas";

            var assembler = new Z80Assembler(programrows);
            var assembled = assembler.BuildProgram();

            Assert.AreEqual(assembled, true);

            var  loader          = new TvcBasicLoader(assembler.AssembledProgram, 1, 1, 0x3000);
            bool loaderGenerated = loader.GenerateBasicLoader();

            Assert.AreEqual(loaderGenerated, true);

            CasFileWriter writer = new CasFileWriter(fileName);

            writer.Write(loader.BasicLoaderProgramBytes.ToArray());

            var bytesOfCreatedFile = File.ReadAllBytes(fileName);
            var bytesOfBaseFile    = File.ReadAllBytes(IntegrationTest1TestFileName);

            Assert.AreEqual(bytesOfCreatedFile.SequenceEqual(bytesOfBaseFile), true);
        }
Ejemplo n.º 8
0
        public void TooManyErrorsStopProcessing()
        {
            // --- Arrange
            var options = new AssemblerOptions
            {
                MaxLoopErrorsToReport = 3
            };
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    counter = 0;
                    .repeat
                        Value: .var 100 + Other;
                        counter = counter + 1;
                    .until counter >= 100
                ", options);

            // --- Assert
            output.ErrorCount.ShouldBe(4);
            output.Errors[3].ErrorCode.ShouldBe(Errors.Z0408);
        }
Ejemplo n.º 9
0
        public void StructLabelShowsStructLength()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                MyStruct: 
                    .struct
                        .defb 0x12, 0x13
                        ; This is a comment
                        .defgx ""----OOOO OOOO----""
                        .fillw 2, #12A3
                        .defw #FEDC
                    .ends
                .defs MyStruct*10
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments[0].EmittedCode.Count.ShouldBe(100);
        }
Ejemplo n.º 10
0
        public void ModuleWithDuplicatedNameFails1()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                .org #6000
                MyModule .module
                    ld a,b
                .endmodule
                ld b,c
                MyModule .module
                    ld a,b
                .endmodule
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(2);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0040);
            output.Errors[1].ErrorCode.ShouldBe(Errors.Z0429);
        }
Ejemplo n.º 11
0
        public void InternalModuleLabelDoesNotWorkWithoutScope()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    .org #6000
                Start:
                    .module MyModule
                    ld a,b
                    ld bc,t1
                t1:
                    ld a,b
                    .endmodule
                    ld hl,t1
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(1);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0201);
        }
Ejemplo n.º 12
0
        public void OrgPragmaWorksWithNewSegment()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                ld a,c
                .org #6400
                ld a,b
                ld a,c");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments.Count.ShouldBe(2);
            output.Segments[0].StartAddress.ShouldBe((ushort)0x8000);
            output.Segments[0].Displacement.ShouldBeNull();
            output.Segments[0].EmittedCode.Count.ShouldBe(1);
            output.Segments[1].StartAddress.ShouldBe((ushort)0x6400);
            output.Segments[1].Displacement.ShouldBeNull();
            output.Segments[1].EmittedCode.Count.ShouldBe(2);
        }
Ejemplo n.º 13
0
        public void UnknownModuleNameIsCaught2()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    .org #6000
                Start:
                    .module MyModule
                    ld a,b
                    ld bc,t1
                t1:
                    ld a,b
                    .endmodule
                    ld hl,::OtherModule.t1
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(1);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0201);
        }
Ejemplo n.º 14
0
        protected void EvalExpression(string expr, string expected, bool hasEvaluationError = false,
                                      Dictionary <string, ushort> symbols = null)
        {
            var assembler = new Z80Assembler();

            assembler.Compile("");
            if (symbols != null)
            {
                foreach (var pair in symbols)
                {
                    assembler.SetSymbolValue(pair.Key, new ExpressionValue(pair.Value));
                }
            }
            var exprNode = ParseExpr(expr);
            var result   = assembler.Eval(null, exprNode);

            result.AsString().ShouldBe(expected);
            if (hasEvaluationError)
            {
                exprNode.EvaluationError.ShouldNotBeNull();
            }
        }
Ejemplo n.º 15
0
        public void StructWithHangingLabelWorks()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                MyStruct: 
                    .struct
                    .ends
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Structs.ContainsKey("MyStruct").ShouldBeTrue();
            var def = output.Structs["MyStruct"];

            def.ShouldNotBeNull();
            def.Section.FirstLine.ShouldBe(1);
            def.Section.LastLine.ShouldBe(2);
            def.StructName.ShouldBe("MYSTRUCT");
        }
Ejemplo n.º 16
0
        public void DefsPragmaWorksWithIndirectEvaluation1()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var expected = new byte[] { 0x00, 0x00, 0x00 };

            // --- Act
            var output = compiler.Compile(@"
                Count: .equ 3
                .defs Count");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Segments.Count.ShouldBe(1);
            var segment = output.Segments[0];

            segment.EmittedCode.Count.ShouldBe(expected.Length);
            for (var i = 0; i < expected.Length; i++)
            {
                segment.EmittedCode[i].ShouldBe(expected[i]);
            }
        }
Ejemplo n.º 17
0
        public void MultipleLabelIssuesDetected()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    .if true 
                Label1: 
                    .elif true
                Label2: .elif true
                Label3:
                    .else
                    .endif
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(3);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0411);
            output.Errors[1].ErrorCode.ShouldBe(Errors.Z0411);
            output.Errors[2].ErrorCode.ShouldBe(Errors.Z0411);
        }
Ejemplo n.º 18
0
        public void NestedIfdefTrueTrueElseElseWorks()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var options  = new AssemblerOptions();

            options.PredefinedSymbols.Add("MYSYMBOL");
            options.PredefinedSymbols.Add("MYSYMBOL2");
            const string SOURCE = @"
                  #ifdef MySymbol
                  nop ; 1
                  #ifdef MySymbol2
                  nop ; 2
                  nop ; 3
                  #else
                  nop
                  nop
                  nop
                  #endif
                  nop ; 4
                  nop ; 5
                  nop ; 6
                  nop ; 7
                  #else
                  nop
                  nop
                  nop
                  nop
                  nop
                  #endif";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            compiler.PreprocessedLines.Count.ShouldBe(7);
        }
Ejemplo n.º 19
0
        public void UnexpectedEndifRaisesError()
        {
            // --- Arrange
            var          compiler = new Z80Assembler();
            var          options  = new AssemblerOptions();
            const string SOURCE   = @"nop
                  #endif ; 1
                  nop
                  nop
                  nop
                  #endif ; 2
                  nop
                  nop";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(2);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0061);
            output.Errors[1].ErrorCode.ShouldBe(Errors.Z0061);
            compiler.PreprocessedLines.Count.ShouldBe(6);
        }
Ejemplo n.º 20
0
        public void IfnmodWithInvalidModelTypeRaisesError()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var options  = new AssemblerOptions {
                CurrentModel = SpectrumModelType.Spectrum48
            };
            const string SOURCE = @"
                  nop ; 1
                  #ifnmod Unknown
                  nop ; 2
                  nop ; 3
                  nop ; 4
                  #endif
                  nop ; 5";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(1);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0090);
        }
Ejemplo n.º 21
0
        public void StructDefinitionFixupWithDefbWorks()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                MyStruct: 
                    .struct
                        .defb 0x13, Symb1, 0x15, Sym1*Symb2
                    .ends
                Symb1: .equ 1
                Symb2: .equ 2
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            output.Structs.ContainsKey("MyStruct").ShouldBeTrue();
            var def = output.Structs["MyStruct"];

            def.ShouldNotBeNull();
            def.Size.ShouldBe(4);
        }
Ejemplo n.º 22
0
        public void IfnmodFalseWorksWithoutElseBranch()
        {
            // --- Arrange
            var compiler = new Z80Assembler();
            var options  = new AssemblerOptions {
                CurrentModel = SpectrumModelType.Spectrum128
            };
            const string SOURCE = @"
                  nop ; 1
                  #ifnmod Spectrum48
                  nop
                  nop
                  nop
                  #endif
                  nop ; 2";

            // --- Act
            var output = compiler.Compile(SOURCE, options);

            // --- Assert
            output.ErrorCount.ShouldBe(0);
            compiler.PreprocessedLines.Count.ShouldBe(5);
        }
Ejemplo n.º 23
0
        public void StructDefinitionWithDuplicatedFieldFailsCs3()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                MyStruct: 
                    .struct
                        field1: .defb 0x12, 0x13
                        field2: ; This is a comment
                                .defgx ""----OOOO OOOO----""
                        Field1: .fillw 2, #12A3
                        .defw #FEDC
                    .ends
                ",
                                          new AssemblerOptions {
                UseCaseSensitiveSymbols = true
            });

            // --- Assert
            output.ErrorCount.ShouldBe(0);
        }
Ejemplo n.º 24
0
        public override void AnalyzeCode()
        {
            ClearResults();

            var programLines = Document.Lines.Select(dl => Document.GetText(dl.Offset, dl.TotalLength)
                                                     .TrimStart(' ', '\t').Replace(Environment.NewLine, "").ToUpper()).ToList();

            var fileName         = Path.GetFileName(m_ProgramFullPath);
            var programDirectory = Path.GetDirectoryName(m_ProgramFullPath);

            m_Assembler = new Z80Assembler(programLines, new List <string> {
                programDirectory
            }, fileName);

            if (!m_Assembler.BuildProgram())
            {
                MarkLineAsWrong(Document.GetLineByNumber(m_Assembler.WrongLineNumber), m_Assembler.StatusMessage);
                WrongLine.Add(new Tuple <string, int>(m_Assembler.StatusMessage, m_Assembler.WrongLineNumber));
                AnalizingFinished?.Invoke(this, new EventArgs());
                return;
            }

            InterpretedSymbols.AddRange(m_Assembler.AssembledProgram.SymbolTable.Where(sd => sd.Key != @".LC").Select(kvp => new SymbolData
            {
                SymbolName = kvp.Key,
                SymbolText = kvp.Value.ToString(),
                LineNumber = kvp.Value.LineNumber,
                SymbolType = kvp.Value.Type == SymbolType.Address ? @"Cím" : "Konstans"
            }));

            if (Settings.AssemblyEditorSettings.MarkInactiveCode)
            {
                MarkSkippedLines(m_Assembler.SkippedLineNumbers);
            }

            AnalizingFinished?.Invoke(this, new EventArgs());
        }
Ejemplo n.º 25
0
        public void MultipleElifAndElseAfterElseFails()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    .if true 
                    .elif true
                    .else
                    .elif false
                    .elif false
                    .else
                    .else
                    .endif
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(4);
            output.Errors[0].ErrorCode.ShouldBe(Errors.Z0410);
            output.Errors[1].ErrorCode.ShouldBe(Errors.Z0410);
            output.Errors[2].ErrorCode.ShouldBe(Errors.Z0410);
            output.Errors[3].ErrorCode.ShouldBe(Errors.Z0410);
        }
Ejemplo n.º 26
0
        public void NonLocalModuleNameIsVisible()
        {
            // --- Arrange
            var compiler = new Z80Assembler();

            // --- Act
            var output = compiler.Compile(@"
                    .org #6000
                Start:
                    .module MyModule
                    ld a,b
                    .module Nested
                    Inner: nop
                    .endmodule
                    ld bc,t1
                t1:
                    ld a,b
                    .endmodule
                    ld hl,MyModule.Nested.Inner
                ");

            // --- Assert
            output.ErrorCount.ShouldBe(0);
        }
Ejemplo n.º 27
0
        public override void Build()
        {
            if (!OpenInputFile())
            {
                return;
            }

            OnBuildMessageSent(@"Assembly program fordítása...");

            var          fileName         = Path.GetFileName(BuildSettings.ProgramPath);
            var          programDirectory = Path.GetDirectoryName(BuildSettings.ProgramPath);
            Z80Assembler assembler        = new Z80Assembler(ProgramLines, new List <string> {
                programDirectory
            }, fileName);

            if (!assembler.BuildProgram())
            {
                OnBuildMessageSent(assembler.StatusMessage);
                return;
            }

            float programSizeInKb = (float)assembler.AssembledProgramBytes.Length / 1024;

            OnBuildMessageSent($"Lefordított assembly program mérete: {programSizeInKb:F3} KB ({assembler.AssembledProgramBytes.Length} byte)");

            if (BuildSettings.GenerateNativeFile)
            {
                OnBuildMessageSent($"Nativ tárgykód létrehozása({BuildSettings.NativePath})...");
                if (!CreateNativeFile(assembler))
                {
                    return;
                }
            }

            if (BuildSettings.GenerateListFile)
            {
                OnBuildMessageSent($"Lista file létrehozása({BuildSettings.LstFilePath})...");
                if (!CreateListFile(assembler))
                {
                    return;
                }
            }

            if (!BuildSettings.GenerateLoader)
            {
                if (BuildSettings.GenerateCasFile)
                {
                    OnBuildMessageSent($"CAS file létrehozása ({BuildSettings.CasFilePath})...");
                    if (!CreateCasFile(assembler.AssembledProgramBytes, CasFileContent.NativProgramCode))
                    {
                        OnBuildMessageSent(@"CAS file létrehozása sikertelen!");
                    }
                }

                if (BuildSettings.GenerateWavFile)
                {
                    OnBuildMessageSent($"WAV file létrehozása ({BuildSettings.WavFilePath})...");
                    CreateWavFile(assembler.AssembledProgramBytes);
                }

                return;
            }

            ushort startAddress = assembler.AssembledProgram.ProgramSections[0].ProgramStartAddress;

            if (BuildSettings.StartAddress.HasValue)
            {
                var selectedprogramSection = assembler.AssembledProgram.ProgramSections
                                             .Where(ps => ps.ProgramStartAddress == BuildSettings.StartAddress.Value)
                                             .Select(ps => ps).FirstOrDefault();

                if (selectedprogramSection == null)
                {
                    OnBuildMessageSent($"A megadott indítási cím:{BuildSettings.StartAddress.Value:D} (${BuildSettings.StartAddress.Value:X4}) érvénytelen!");
                    var addressList = assembler.AssembledProgram.ProgramSections
                                      .Select(ps => $"{ps.ProgramStartAddress}(${ps.ProgramStartAddress:x4})").ToList();

                    OnBuildMessageSent($"A lehetséges indítási címek:{string.Join(",", addressList)}");
                    return;
                }

                startAddress = selectedprogramSection.ProgramStartAddress;
            }

            var loader = new TvcBasicLoader(assembler.AssembledProgram, 1, 1, startAddress);

            OnBuildMessageSent(@"Basic loader generálása...");
            OnBuildMessageSent($"Program indítási cím:{startAddress:D} (${startAddress:X4})");

            if (!loader.GenerateBasicLoader())
            {
                OnBuildMessageSent(loader.StatusMessage);
                return;
            }

            if (!CreateLoaderFile(loader))
            {
                return;
            }

            if (BuildSettings.GenerateCasFile)
            {
                OnBuildMessageSent($"CAS file létrehozása basic betöltővel ({BuildSettings.CasFilePath})...");
                if (!CreateCasFile(loader.BasicLoaderProgramBytes.ToArray(), CasFileContent.BasicProgram))
                {
                    OnBuildMessageSent(@"CAS file létrehozása sikertelen!");
                    return;
                }
            }

            if (BuildSettings.GenerateWavFile)
            {
                OnBuildMessageSent($"WAV file létrehozása basic betöltővel ({BuildSettings.WavFilePath})...");
                CreateWavFile(loader.BasicLoaderProgramBytes.ToArray());
            }
        }
Ejemplo n.º 28
0
        public override object VisitLiteral(Z80AsmParser.LiteralContext context)
        {
            if (context == null)
            {
                return(null);
            }

            switch (context)
            {
            case Z80AsmParser.CurAddrLiteralContext ctx:
                AddSemiVar(ctx);
                return(new CurrentAddressNode(ctx));

            case Z80AsmParser.CurCounterLiteralContext ctx:
                AddSemiVar(ctx);
                return(new CurrentLoopCounterNode(ctx));

            case Z80AsmParser.BoolLiteralContext ctx:
                AddNumber(ctx);
                var boolValue = new ExpressionValue(ctx.BOOLLIT().GetText().ToLower().Contains("t"));
                return(new LiteralNode(ctx, boolValue));

            case Z80AsmParser.RealLiteralContext ctx:
                AddNumber(ctx);
                return(double.TryParse(ctx.REALNUM().GetText(), out var realValue)
                        ? new LiteralNode(ctx, realValue)
                        : new LiteralNode(ctx, ExpressionValue.Error));

            case Z80AsmParser.StringLiteralContext ctx:
                AddString(ctx);
                var stringValue = ctx.STRING().NormalizeString();
                return(new LiteralNode(ctx, stringValue));
            }

            var    token = context.NormalizeToken();
            ushort value;

            // --- Hexadecimal literals
            if (token.StartsWith("#") && token.Length > 1)
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(1), NumberStyles.HexNumber);
            }
            else if (token.StartsWith("0X") && token.Length > 2)
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(2), NumberStyles.HexNumber);
            }
            else if (token.StartsWith("$") && token.Length > 1)
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(1), NumberStyles.HexNumber);
            }
            else if (token.EndsWith("H", StringComparison.OrdinalIgnoreCase) && token.Length > 1)
            {
                AddNumber(context);
                value = (ushort)int.Parse(token.Substring(0, token.Length - 1),
                                          NumberStyles.HexNumber);
            }

            // --- Binary literals
            else if (token.StartsWith("%") && token.Length > 1)
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(1).Replace("_", ""), 2);
            }
            else if (token.StartsWith("0B") && token.Length > 2)
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(2).Replace("_", ""), 2);
            }
            else if ((token.EndsWith("b") || token.EndsWith("B")) && token.Length > 1)
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(0, token.Length - 1).Replace("_", ""), 2);
            }

            // --- Octal literals
            else if ((token.EndsWith("q") || token.EndsWith("Q") || token.EndsWith("o") || token.EndsWith("O")) &&
                     token.Length > 1)
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(0, token.Length - 1), 8);
            }

            // --- Character literals
            else if ((token.StartsWith("\"") || token.StartsWith("'")) && token.Length > 2)
            {
                AddString(context);
                var charExpr = context.GetText();
                var bytes    = Z80Assembler.SpectrumStringToBytes(charExpr.Substring(1, charExpr.Length - 2));
                value = bytes.Count == 0 ? (ushort)0x00 : bytes[0];
            }

            // --- Decimal literals
            else
            {
                AddNumber(context);
                value = (ushort)int.Parse(context.NormalizeToken());
            }

            return(new LiteralNode(context, value));
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Visit a parse tree produced by <see cref="Generated.Z80AsmParser.literalExpr"/>.
        /// </summary>
        /// <param name="context">The parse tree.</param>
        /// <return>The visitor result.</return>
        public override object VisitLiteralExpr(Z80AsmParser.LiteralExprContext context)
        {
            var token = context.NormalizeToken();

            if (context.CURADDR() != null || context.MULOP() != null || context.DOT() != null)
            {
                AddSemiVar(context);
                return(new CurrentAddressNode());
            }

            if (context.CURCNT() != null)
            {
                AddSemiVar(context);
                return(new CurrentLoopCounterNode());
            }

            // --- Check for Boolean values
            if (context.BOOLLIT() != null)
            {
                AddNumber(context);
                var boolValue = new ExpressionValue(context.BOOLLIT().GetText().ToLower().Contains("t"));
                return(new LiteralNode(boolValue));
            }

            // --- Check for real values
            if (context.REALNUM() != null)
            {
                AddNumber(context);
                return(double.TryParse(context.REALNUM().GetText(), out var realValue)
                    ? new LiteralNode(realValue)
                    : new LiteralNode(ExpressionValue.Error));
            }

            // --- Check for string values
            if (context.STRING() != null)
            {
                AddString(context);
                var stringValue = context.STRING().NormalizeString();
                return(new LiteralNode(stringValue));
            }

            ushort value;

            // --- Hexadecimal literals
            if (token.StartsWith("#"))
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(1), NumberStyles.HexNumber);
            }
            else if (token.StartsWith("0X"))
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(2), NumberStyles.HexNumber);
            }
            else if (token.StartsWith("$"))
            {
                AddNumber(context);
                value = ushort.Parse(token.Substring(1), NumberStyles.HexNumber);
            }
            else if (token.EndsWith("H", StringComparison.OrdinalIgnoreCase))
            {
                AddNumber(context);
                value = (ushort)int.Parse(token.Substring(0, token.Length - 1),
                                          NumberStyles.HexNumber);
            }
            // --- Binary literals
            else if (token.StartsWith("%"))
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(1).Replace("_", ""), 2);
            }
            else if (token.StartsWith("0B"))
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(2).Replace("_", ""), 2);
            }
            else if (token.EndsWith("b") || token.EndsWith("B"))
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(0, token.Length - 1).Replace("_", ""), 2);
            }
            // --- Octal literals
            else if (token.EndsWith("q") || token.EndsWith("Q") || token.EndsWith("o") || token.EndsWith("O"))
            {
                AddNumber(context);
                value = (ushort)Convert.ToInt32(token.Substring(0, token.Length - 1), 8);
            }
            // --- Character literals
            else if (token.StartsWith("\"") || token.StartsWith("'"))
            {
                AddString(context);
                var charExpr = context.GetText();
                var bytes    = Z80Assembler.SpectrumStringToBytes(charExpr.Substring(1, charExpr.Length - 2));
                value = bytes.Count == 0 ? (ushort)0x00 : bytes[0];
            }
            // --- Decimal literals
            else
            {
                AddNumber(context);
                value = (ushort)int.Parse(context.NormalizeToken());
            }

            return(new LiteralNode(value));
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Visit a parse tree produced by <see cref="Generated.Z80AsmParser.literalExpr"/>.
        /// </summary>
        /// <param name="context">The parse tree.</param>
        /// <return>The visitor result.</return>
        public override object VisitLiteralExpr(Z80AsmParser.LiteralExprContext context)
        {
            if (IsInvalidContext(context))
            {
                return(null);
            }

            var token = context.NormalizeToken();

            if (token == "$")
            {
                return(new CurrentAddressNode());
            }

            ushort value;

            // --- Hexadecimal literals
            if (token.StartsWith("#"))
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = ushort.Parse(token.Substring(1), NumberStyles.HexNumber);
            }
            else if (token.StartsWith("0X"))
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = ushort.Parse(token.Substring(2), NumberStyles.HexNumber);
            }
            else if (token.EndsWith("H", StringComparison.OrdinalIgnoreCase))
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = (ushort)int.Parse(token.Substring(0, token.Length - 1),
                                          NumberStyles.HexNumber);
            }
            // --- Binary literals
            else if (token.StartsWith("%"))
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = (ushort)Convert.ToInt32(token.Substring(1).Replace("_", ""), 2);
            }
            else if (token.StartsWith("0B"))
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = (ushort)Convert.ToInt32(token.Substring(2).Replace("_", ""), 2);
            }
            // --- Character literals
            else if (token.StartsWith("\""))
            {
                var charExpr = context.GetText();
                var bytes    = Z80Assembler.SpectrumStringToBytes(charExpr.Substring(1, charExpr.Length - 2));
                value = bytes.Count == 0 ? (ushort)0x00 : bytes[0];
            }
            // --- Decimal literals
            else
            {
                _numbers.Add(new TextSpan(context.Start.StartIndex, context.Start.StopIndex + 1));
                value = (ushort)int.Parse(context.NormalizeToken());
            }
            return(new LiteralNode
            {
                LiteralValue = value
            });
        }