From 9d7452da4034e369e3a4d6d296d9127c4e7634a7 Mon Sep 17 00:00:00 2001 From: GeorgRottensteiner Date: Mon, 27 May 2019 19:37:46 +0200 Subject: [PATCH] Fix: BASIC renumber now also renumbers line numbers directly after THEN --- C64Models/Parser/BasicFileParser.cs | 65 +++++++++++-- C64Studio/Compiling.cs | 2 +- .../CustomRenderer/BASICSyntaxHighlighter.cs | 2 +- C64Studio/Dialogs/Settings.cs | 2 +- C64Studio/Documents/SourceBasicEx.cs | 6 +- C64Studio/TODO.txt | 3 + Sample Projects/MacroTest/MacroTest.c64 | Bin 14278 -> 14213 bytes Sample Projects/MacroTest/test.bas | 2 +- Sample Projects/MacroTest/test.prg | Bin 516 -> 45 bytes TestProject/UnitTestBASICParser.cs | 90 +++++++++++++++++- 10 files changed, 155 insertions(+), 17 deletions(-) diff --git a/C64Models/Parser/BasicFileParser.cs b/C64Models/Parser/BasicFileParser.cs index 0b9c4c89..111e298e 100644 --- a/C64Models/Parser/BasicFileParser.cs +++ b/C64Models/Parser/BasicFileParser.cs @@ -354,15 +354,17 @@ static BasicFileParser() - public BasicFileParser() + public BasicFileParser( ParserSettings Settings ) { LabelMode = false; + this.Settings = Settings; } - public BasicFileParser( string Filename ) + public BasicFileParser( ParserSettings Settings, string Filename ) { + this.Settings = Settings; LabelMode = false; m_Filename = Filename; } @@ -1881,6 +1883,8 @@ public string EncodeToLabels() sb.AppendLine(); sb.Append( lineNumberReference[lineInfo.Value.LineNumber] + "\r\n" ); } + bool hadREM = false; + for ( int i = 0; i < lineInfo.Value.Tokens.Count; ++i ) { Token token = lineInfo.Value.Tokens[i]; @@ -1900,6 +1904,11 @@ public string EncodeToLabels() if ( token.TokenType == Token.Type.BASIC_TOKEN ) { + if ( token.ByteValue == m_Opcodes["REM"].ByteValue ) + { + hadREM = true; + } + if ( ( token.ByteValue == m_Opcodes["RUN"].ByteValue ) || ( token.ByteValue == m_Opcodes["THEN"].ByteValue ) ) { @@ -1927,7 +1936,8 @@ public string EncodeToLabels() { // ON x GOTO/GOSUB can have more than one line number // insert label instead of line number - sb.Append( token.Content + " " ); + //sb.Append( token.Content + " " ); + sb.Append( token.Content ); int nextIndex = i + 1; bool mustBeComma = false; @@ -1947,6 +1957,16 @@ public string EncodeToLabels() } sb.Append( lineNumberReference[refNo].ToString() ); } + else if ( ( nextToken.TokenType == Token.Type.DIRECT_TOKEN ) + && ( nextToken.Content == " " ) ) + { + if ( !Settings.StripSpaces ) + { + sb.Append( nextToken.Content ); + } + ++nextIndex; + continue; + } else { // error or end @@ -1978,7 +1998,8 @@ public string EncodeToLabels() || ( token.TokenType == Token.Type.NUMERIC_LITERAL ) || ( token.TokenType == Token.Type.EX_BASIC_TOKEN ) ) { - if ( token.ByteValue != m_Opcodes["REM"].ByteValue ) + if ( ( token.ByteValue != m_Opcodes["REM"].ByteValue ) + && ( hadREM ) ) { sb.Append( " " ); } @@ -1991,6 +2012,7 @@ public string EncodeToLabels() + // finds next non-space token or returns -1 private int FindNextToken( List Tokens, int StartIndex ) { int curIndex = StartIndex + 1; @@ -2030,7 +2052,7 @@ public string DecodeFromLabels() string labelToReplace = "LABEL" + lineInfo.Value.Tokens[1].Content; labelToNumber[labelToReplace] = lineNumber; - Debug.Log( "Replace label " + labelToReplace + " with line " + lineNumber ); + //Debug.Log( "Replace label " + labelToReplace + " with line " + lineNumber ); } else { @@ -2043,6 +2065,8 @@ public string DecodeFromLabels() lineNumber = 10; foreach ( KeyValuePair lineInfo in m_LineInfos ) { + bool hadREM = false; + // is this a label definition? int nextTokenIndex = FindNextToken( lineInfo.Value.Tokens, -1 ); int nextTokenIndex2 = FindNextToken( lineInfo.Value.Tokens, nextTokenIndex ); @@ -2067,11 +2091,21 @@ public string DecodeFromLabels() Token token = lineInfo.Value.Tokens[tokenIndex]; if ( ( token.TokenType == Token.Type.DIRECT_TOKEN ) + && ( Settings.StripSpaces ) + && ( !hadREM ) && ( token.Content.Trim().Length == 0 ) ) { continue; } bool tokenIsInserted = false; + + if ( ( token.TokenType == Token.Type.BASIC_TOKEN ) + && ( token.ByteValue == m_Opcodes["REM"].ByteValue ) ) + { + hadREM = true; + } + + if ( ( token.TokenType == Token.Type.BASIC_TOKEN ) && ( ( token.ByteValue == m_Opcodes["GOTO"].ByteValue ) || ( token.ByteValue == m_Opcodes["GOSUB"].ByteValue ) @@ -2081,6 +2115,7 @@ public string DecodeFromLabels() bool isGotoOrGosub = ( token.ByteValue == m_Opcodes["GOTO"].ByteValue ) | ( token.ByteValue == m_Opcodes["GOSUB"].ByteValue ); nextTokenIndex = FindNextToken( lineInfo.Value.Tokens, tokenIndex ); nextTokenIndex2 = FindNextToken( lineInfo.Value.Tokens, nextTokenIndex ); + while ( ( nextTokenIndex != -1 ) && ( nextTokenIndex2 != -1 ) ) { @@ -2100,6 +2135,13 @@ public string DecodeFromLabels() { tokenIsInserted = true; sb.Append( token.Content ); + + while ( nextTokenIndex - 1 > tokenIndex ) + { + // there were blanks in between + sb.Append( lineInfo.Value.Tokens[tokenIndex + 1].Content ); + ++tokenIndex; + } } sb.Append( labelToNumber[label].ToString() ); } @@ -2397,9 +2439,18 @@ public string Renumber( int LineStart, int LineStep ) if ( i + 1 < lineInfo.Tokens.Count ) { int refNo = -1; - if ( int.TryParse( lineInfo.Tokens[i + 1].Content, out refNo ) ) + int nextTokenIndex = FindNextToken( lineInfo.Tokens, i ); + if ( ( nextTokenIndex != -1 ) + && ( int.TryParse( lineInfo.Tokens[nextTokenIndex].Content, out refNo ) ) ) { - sb.Append( token.Content + lineNumberReference[refNo].ToString() ); + sb.Append( token.Content ); + + while ( i + 1 < nextTokenIndex ) + { + sb.Append( lineInfo.Tokens[i + 1].Content ); + ++i; + } + sb.Append( lineNumberReference[refNo] ); ++i; continue; } diff --git a/C64Studio/Compiling.cs b/C64Studio/Compiling.cs index 9b58f4e2..90553430 100644 --- a/C64Studio/Compiling.cs +++ b/C64Studio/Compiling.cs @@ -21,7 +21,7 @@ public class Compiling public Parser.ASMFileParser ParserASM = new C64Studio.Parser.ASMFileParser(); - public Parser.BasicFileParser ParserBasic = new C64Studio.Parser.BasicFileParser(); + public Parser.BasicFileParser ParserBasic = new C64Studio.Parser.BasicFileParser( new Parser.BasicFileParser.ParserSettings() ); diff --git a/C64Studio/CustomRenderer/BASICSyntaxHighlighter.cs b/C64Studio/CustomRenderer/BASICSyntaxHighlighter.cs index 1d1fa412..b5654aef 100644 --- a/C64Studio/CustomRenderer/BASICSyntaxHighlighter.cs +++ b/C64Studio/CustomRenderer/BASICSyntaxHighlighter.cs @@ -8,7 +8,7 @@ namespace C64Studio.CustomRenderer { class BASICSyntaxHighlighter : FastColoredTextBoxNS.SyntaxHighlighter { - static Parser.BasicFileParser _Parser = new Parser.BasicFileParser(); + static Parser.BasicFileParser _Parser = new Parser.BasicFileParser( new Parser.BasicFileParser.ParserSettings() ); diff --git a/C64Studio/Dialogs/Settings.cs b/C64Studio/Dialogs/Settings.cs index d2838d99..0c08c08f 100644 --- a/C64Studio/Dialogs/Settings.cs +++ b/C64Studio/Dialogs/Settings.cs @@ -1213,7 +1213,7 @@ private void editKeyMapBinding_PreviewKeyDown( object sender, PreviewKeyDownEven private void checkBASICStripSpaces_CheckedChanged( object sender, EventArgs e ) { - Core.Settings.BASICStripSpaces = checkBASICStripSpaces.Checked; + Core.Settings.BASICStripSpaces = checkBASICStripSpaces.Checked; Core.Compiling.ParserBasic.Settings.StripSpaces = Core.Settings.BASICStripSpaces; } diff --git a/C64Studio/Documents/SourceBasicEx.cs b/C64Studio/Documents/SourceBasicEx.cs index d661c4f7..08396012 100644 --- a/C64Studio/Documents/SourceBasicEx.cs +++ b/C64Studio/Documents/SourceBasicEx.cs @@ -1353,7 +1353,11 @@ private bool ToggleLabelMode() bool labelMode = !m_LabelMode; Core.MainForm.m_CompileResult.ClearMessages(); - Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser( DocumentInfo.FullPath ); + + var settings = new Parser.BasicFileParser.ParserSettings(); + settings.StripSpaces = Core.Settings.BASICStripSpaces; + + Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser( settings, DocumentInfo.FullPath ); parser.LabelMode = m_LabelMode; var compilerConfig = new C64Studio.Parser.CompileConfig() { Assembler = C64Studio.Types.AssemblerType.AUTO }; diff --git a/C64Studio/TODO.txt b/C64Studio/TODO.txt index 718b8c70..bccdf201 100644 --- a/C64Studio/TODO.txt +++ b/C64Studio/TODO.txt @@ -1,5 +1,8 @@ C64Studio o Output bei Custom Build kann Info von anderer Datei anzeigen? +o BASIC: Schalte ich Labelmode um und wieder zurück werden auch alle Spaces entfernt (sogar in REM Kommentaren?!). +o BASIC: Undo bei Label-Mode-Wechsel sollte Label-Mode mit wechseln! + o Die Sortierreihenfolge vom "autocomplete" führt bei mir häufig zu Eingabefehlern, weil die Vorschläge alphabetisch sortiert und nicht nach Relevanz dargestellt werden (siehe Bild). Ausserdem wäre es gut, wenn ein vollständig ausgeschriebener Begriff in der Liste (ganz oben) erthalten bleiben würde (siehe Bild), so könnte man wie gewohnt mit ENTER in die näschte Zeile wechseln. o Could a future version get some keybindings for the editors, for example the sprite editor would benefit from bindings for: diff --git a/Sample Projects/MacroTest/MacroTest.c64 b/Sample Projects/MacroTest/MacroTest.c64 index 3919b1ff8a87da211f41d9ae8adf00a2f7dd4d20..ae2ea41988b505c5ce990610ca97497d8c2fc381 100644 GIT binary patch delta 151 zcmX?>- z3`{I1Co(%up1{sB+0tBK5+jQ+vw#Fp23Z%!m{EB0J~J^M4h9B>oZ{Rxy@I0ji3g-63!9rw{=mdCd7HR^ISWt@S)Ld+vw%Fv PTuzW$CXoKgapvj(9}+F= diff --git a/Sample Projects/MacroTest/test.bas b/Sample Projects/MacroTest/test.bas index 941bfad0..3968f536 100644 --- a/Sample Projects/MacroTest/test.bas +++ b/Sample Projects/MacroTest/test.bas @@ -1 +1 @@ -YYyyyyYYYyyYYYYYYYZZZYYYYZZ \ No newline at end of file +10 GOTO 10:REM Y Y YYYYYYYYYYYYYYYYZZZYYYYZZ diff --git a/Sample Projects/MacroTest/test.prg b/Sample Projects/MacroTest/test.prg index f53543c694e582cc5dcdf4158831b8587f442b05..44345f223ee9d634f516baf00b36f31ba7f2cd31 100644 GIT binary patch literal 45 icmZSN(Bj}?=u|K?u%iHc%iU;qI6dJEwI literal 516 zcmdT-xebFr5L__eb0?JLQZ_lV+afN(LlxGPLlqvOOF@n-d6U`sH1;;bS}m{33s$|D zN9PzS%fJ{Zjl~!p0j02P=#}a{ZjMRb#JCelUt&DIO=%CFwJ4-;ZhX#=zKI{W?-x#L T-J~qlX{gS*^OK#Y{nvc}dCav$ diff --git a/TestProject/UnitTestBASICParser.cs b/TestProject/UnitTestBASICParser.cs index e50c00c4..e5f37cb3 100644 --- a/TestProject/UnitTestBASICParser.cs +++ b/TestProject/UnitTestBASICParser.cs @@ -6,9 +6,16 @@ namespace TestProject [TestClass] public class UnitTestBASICParser { + private C64Studio.Parser.BasicFileParser CreateParser() + { + return new C64Studio.Parser.BasicFileParser( new C64Studio.Parser.BasicFileParser.ParserSettings() ); + } + + + private GR.Memory.ByteBuffer TestCompile( string Source ) { - C64Studio.Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser(); + var parser = CreateParser(); C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); config.OutputFile = "test.prg"; @@ -28,7 +35,7 @@ public void TestRenumberWithSpaces() { string source = @"20 ifa=1then 20"; - C64Studio.Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser(); + var parser = CreateParser(); C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); config.OutputFile = "test.prg"; @@ -43,13 +50,34 @@ public void TestRenumberWithSpaces() + [TestMethod] + public void TestRenumberWithSpacesNoStripSpaces() + { + string source = @"20 ifa=1then 20"; + + var parser = CreateParser(); + parser.Settings.StripSpaces = false; + + C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); + config.OutputFile = "test.prg"; + config.TargetType = C64Studio.Types.CompileTargetType.PRG; + config.Assembler = C64Studio.Types.AssemblerType.C64_STUDIO; + Assert.IsTrue( parser.Parse( source, null, config ) ); + + string result = parser.Renumber( 10, 3 ); + + Assert.AreEqual( "10IFA=1THEN 10", result ); + } + + + [TestMethod] public void TestRenumberOverLines() { string source = @"10 goto 300 300 goto 10"; - C64Studio.Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser(); + var parser = CreateParser(); C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); config.OutputFile = "test.prg"; @@ -73,7 +101,7 @@ public void TestRenumberOnGosub() 400 printb 700 printc"; - C64Studio.Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser(); + var parser = CreateParser(); C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); config.OutputFile = "test.prg"; @@ -100,7 +128,7 @@ 400 printb 700 printc 2000 printd"; - C64Studio.Parser.BasicFileParser parser = new C64Studio.Parser.BasicFileParser(); + var parser = CreateParser(); C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); config.OutputFile = "test.prg"; @@ -117,5 +145,57 @@ 700 printc 22PRINTD", result ); } + + + [TestMethod] + public void TestEncodeToLabels() + { + string source = @"10 print ""Hallo"" + 20 goto 10"; + + var parser = CreateParser(); + + C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); + config.OutputFile = "test.prg"; + config.TargetType = C64Studio.Types.CompileTargetType.PRG; + config.Assembler = C64Studio.Types.AssemblerType.C64_STUDIO; + + Assert.IsTrue( parser.Parse( source, null, config ) ); + + string encoded = parser.EncodeToLabels(); + Assert.AreEqual( @" +LABEL10 +PRINT""HALLO"" +GOTOLABEL10 +", encoded ); + } + + + + [TestMethod] + public void TestEncodeToLabelsNoStripSpaces() + { + string source = @"10 print ""Hallo"" + 20 goto 10"; + + var parser = CreateParser(); + + parser.Settings.StripSpaces = false; + + C64Studio.Parser.CompileConfig config = new C64Studio.Parser.CompileConfig(); + config.OutputFile = "test.prg"; + config.TargetType = C64Studio.Types.CompileTargetType.PRG; + config.Assembler = C64Studio.Types.AssemblerType.C64_STUDIO; + + Assert.IsTrue( parser.Parse( source, null, config ) ); + + string encoded = parser.EncodeToLabels(); + Assert.AreEqual( @" +LABEL10 +PRINT ""HALLO"" +GOTO LABEL10 +", encoded ); + } + } }