1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-07-04 01:29:34 +00:00

Correctly handle delimiters in character operands

We weren't checking to see if character operands matched their
delimiters, so bad code like "LDA #'''" was being generated.

There wasn't a test for this in 2006-operand-formats, so the test
has been updated with single and double quotes in low and high ASCII.
This commit is contained in:
Andy McFadden 2019-08-14 17:25:40 -07:00
parent beb1024550
commit 8fd469b81f
9 changed files with 73 additions and 61 deletions

View File

@ -119,10 +119,9 @@ namespace Asm65 {
public char OpenDelim { get; private set; } public char OpenDelim { get; private set; }
public char CloseDelim { get; private set; } public char CloseDelim { get; private set; }
public string Suffix { get; private set; } public string Suffix { get; private set; }
public string FormatStr { get; private set; }
public DelimiterDef(char delim) { public DelimiterDef(char delim) : this(string.Empty, delim, delim, string.Empty) {
OpenDelim = CloseDelim = delim;
Prefix = Suffix = string.Empty;
} }
public DelimiterDef(string prefix, char openDelim, char closeDelim, string suffix) { public DelimiterDef(string prefix, char openDelim, char closeDelim, string suffix) {
Debug.Assert(prefix != null); Debug.Assert(prefix != null);
@ -131,6 +130,15 @@ namespace Asm65 {
OpenDelim = openDelim; OpenDelim = openDelim;
CloseDelim = closeDelim; CloseDelim = closeDelim;
Suffix = suffix; Suffix = suffix;
// Generate format string.
StringBuilder sb = new StringBuilder();
sb.Append(Prefix);
sb.Append(OpenDelim);
sb.Append("{0}");
sb.Append(CloseDelim);
sb.Append(Suffix);
FormatStr = sb.ToString();
} }
public override string ToString() { public override string ToString() {
return Prefix + OpenDelim + '#' + CloseDelim + Suffix; return Prefix + OpenDelim + '#' + CloseDelim + Suffix;
@ -291,13 +299,6 @@ namespace Asm65 {
private string mAddrFormatNoBank; private string mAddrFormatNoBank;
private string mAddrFormatWithBank; private string mAddrFormatWithBank;
// Character data delimiter format strings, processed from the delimiter patterns.
private string mCharDelimAsciiFmt;
private string mCharDelimHighAsciiFmt;
private string mCharDelimC64PetsciiFmt;
private string mCharDelimC64ScreenCodeFmt;
// Generated opcode strings. The index is the bitwise OR of the opcode value and // Generated opcode strings. The index is the bitwise OR of the opcode value and
// the disambiguation value. In most cases this just helps us avoid calling // the disambiguation value. In most cases this just helps us avoid calling
// ToUpper incessantly. // ToUpper incessantly.
@ -431,24 +432,6 @@ namespace Asm65 {
Debug.WriteLine("NOTE: char delimiters not set"); Debug.WriteLine("NOTE: char delimiters not set");
chrDelim = DelimiterSet.GetDefaultCharDelimiters(); chrDelim = DelimiterSet.GetDefaultCharDelimiters();
} }
mCharDelimAsciiFmt =
DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.Ascii));
mCharDelimHighAsciiFmt =
DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.HighAscii));
mCharDelimC64PetsciiFmt =
DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.C64Petscii));
mCharDelimC64ScreenCodeFmt =
DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.C64ScreenCode));
}
private string DelimiterDefToFormat(DelimiterDef def) {
StringBuilder sb = new StringBuilder();
sb.Append(def.Prefix);
sb.Append(def.OpenDelim);
sb.Append("{0}");
sb.Append(def.CloseDelim);
sb.Append(def.Suffix);
return sb.ToString();
} }
/// <summary> /// <summary>
@ -544,37 +527,36 @@ namespace Asm65 {
return FormatHexValue(value, 2); return FormatHexValue(value, 2);
} }
string fmt; DelimiterDef delimDef = mFormatConfig.mCharDelimiters.Get(enc);
string fmt = delimDef.FormatStr;
Debug.Assert(fmt != null);
CharEncoding.Convert conv; CharEncoding.Convert conv;
switch (enc) { switch (enc) {
case CharEncoding.Encoding.Ascii: case CharEncoding.Encoding.Ascii:
fmt = mCharDelimAsciiFmt;
conv = CharEncoding.ConvertAscii; conv = CharEncoding.ConvertAscii;
break; break;
case CharEncoding.Encoding.HighAscii: case CharEncoding.Encoding.HighAscii:
fmt = mCharDelimHighAsciiFmt;
conv = CharEncoding.ConvertHighAscii; conv = CharEncoding.ConvertHighAscii;
break; break;
case CharEncoding.Encoding.C64Petscii: case CharEncoding.Encoding.C64Petscii:
fmt = mCharDelimC64PetsciiFmt;
conv = CharEncoding.ConvertC64Petscii; conv = CharEncoding.ConvertC64Petscii;
break; break;
case CharEncoding.Encoding.C64ScreenCode: case CharEncoding.Encoding.C64ScreenCode:
fmt = mCharDelimC64ScreenCodeFmt;
conv = CharEncoding.ConvertC64ScreenCode; conv = CharEncoding.ConvertC64ScreenCode;
break; break;
default: default:
return FormatHexValue(value, 2); return FormatHexValue(value, 2);
} }
if (string.IsNullOrEmpty(fmt)) {
return FormatHexValue(value, 2);
}
char ch = conv((byte)value); char ch = conv((byte)value);
if (ch == CharEncoding.UNPRINTABLE_CHAR) { if (ch == CharEncoding.UNPRINTABLE_CHAR || ch == delimDef.OpenDelim ||
ch == delimDef.CloseDelim) {
// We might be able to do better with delimiter clashes, e.g. '\'', but
// that's assembler-specific.
return FormatHexValue(value, 2); return FormatHexValue(value, 2);
} else { } else {
// possible optimization: replace fmt with a prefix/suffix pair, and just concat // Possible optimization: replace fmt with a prefix/suffix pair, and just concat
return string.Format(fmt, ch); return string.Format(fmt, ch);
} }
} }

View File

@ -1,6 +1,6 @@
### 6502bench SourceGen dis65 v1.0 ### ### 6502bench SourceGen dis65 v1.0 ###
{ {
"_ContentVersion":1,"FileDataLength":125,"FileDataCrc32":611887040,"ProjectProps":{ "_ContentVersion":1,"FileDataLength":133,"FileDataCrc32":-811370049,"ProjectProps":{
"CpuName":"65816","IncludeUndocumentedInstr":false,"EntryFlags":33489103,"AnalysisParams":{ "CpuName":"65816","IncludeUndocumentedInstr":false,"EntryFlags":33489103,"AnalysisParams":{
"AnalyzeUncategorizedData":true,"MinCharsForString":4,"SeekNearbyTargets":true}, "AnalyzeUncategorizedData":true,"MinCharsForString":4,"SeekNearbyTargets":true},
"PlatformSymbolFileIdentifiers":[],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{ "PlatformSymbolFileIdentifiers":[],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{
@ -19,8 +19,8 @@
"UserLabels":{ "UserLabels":{
"63":{ "63":{
"Label":"skipdata","Value":4159,"Source":"User","Type":"LocalOrGlobalAddr"}, "Label":"skipdata","Value":4159,"Source":"User","Type":"LocalOrGlobalAddr"},
"104":{ "112":{
"Label":"more_ascii","Value":4200,"Source":"User","Type":"LocalOrGlobalAddr"}}, "Label":"more_ascii","Value":4208,"Source":"User","Type":"LocalOrGlobalAddr"}},
"OperandFormats":{ "OperandFormats":{
"4":{ "4":{
"Length":2,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null}, "Length":2,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null},
@ -93,33 +93,43 @@
"92":{ "92":{
"Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null}, "Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"94":{ "94":{
"Length":3,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"97":{
"Length":3,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"104":{
"Length":1,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"105":{
"Length":1,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"106":{
"Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null}, "Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"109":{ "96":{
"Length":2,"Format":"NumericLE","SubFormat":"Address","SymbolRef":null}, "Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"111":{ "98":{
"Length":3,"Format":"NumericLE","SubFormat":"Address","SymbolRef":null}, "Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"100":{
"Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"102":{
"Length":3,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"105":{
"Length":3,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"108":{
"Length":3,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"112":{
"Length":1,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"113":{
"Length":1,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"114":{ "114":{
"Length":2,"Format":"NumericLE","SubFormat":"Ascii","SymbolRef":null},
"117":{
"Length":2,"Format":"NumericLE","SubFormat":"Address","SymbolRef":null},
"119":{
"Length":3,"Format":"NumericLE","SubFormat":"Address","SymbolRef":null},
"122":{
"Length":2,"Format":"NumericBE","SubFormat":"Address","SymbolRef":null}, "Length":2,"Format":"NumericBE","SubFormat":"Address","SymbolRef":null},
"116":{ "124":{
"Length":1,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{ "Length":1,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{
"Label":"more_ascii","Part":"Low"}}, "Label":"more_ascii","Part":"Low"}},
"117":{ "125":{
"Length":1,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{ "Length":1,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{
"Label":"more_ascii","Part":"High"}}, "Label":"more_ascii","Part":"High"}},
"118":{ "126":{
"Length":2,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{ "Length":2,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{
"Label":"more_ascii","Part":"Low"}}, "Label":"more_ascii","Part":"Low"}},
"120":{ "128":{
"Length":3,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{ "Length":3,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{
"Label":"more_ascii","Part":"Low"}}, "Label":"more_ascii","Part":"Low"}},
"123":{ "131":{
"Length":2,"Format":"NumericBE","SubFormat":"Symbol","SymbolRef":{ "Length":2,"Format":"NumericBE","SubFormat":"Symbol","SymbolRef":{
"Label":"more_ascii","Part":"Low"}}}} "Label":"more_ascii","Part":"Low"}}}}

View File

@ -36,11 +36,15 @@ skipdata lda #'h'
lda @l'h' lda @l'h'
lda #$1f lda #$1f
lda #' ' lda #' '
lda #'"'
lda #$27
lda #'~' lda #'~'
lda #$7f lda #$7f
lda #$80 lda #$80
lda #$9f lda #$9f
lda #' ' | $80 lda #' ' | $80
lda #'"' | $80
lda #$a7
lda #'~' | $80 lda #'~' | $80
lda #$ff lda #$ff
rep #'0' rep #'0'
@ -62,4 +66,4 @@ more_ascii .byte 'h'
.byte >more_ascii .byte >more_ascii
.word more_ascii .word more_ascii
.long more_ascii .long more_ascii
.byte $10,$68 .byte $10,$70

View File

@ -33,11 +33,15 @@ skipdata lda #'h'
ldal 'h' ldal 'h'
lda #$1f lda #$1f
lda #' ' lda #' '
lda #'"'
lda #$27
lda #'~' lda #'~'
lda #$7f lda #$7f
lda #$80 lda #$80
lda #$9f lda #$9f
lda #" " lda #" "
lda #$a2
lda #"'"
lda #"~" lda #"~"
lda #$ff lda #$ff
rep #'0' rep #'0'

View File

@ -36,11 +36,15 @@ skipdata lda #'h'
lda+3 'h' lda+3 'h'
lda #$1f lda #$1f
lda #' ' lda #' '
lda #'"'
lda #$27
lda #'~' lda #'~'
lda #$7f lda #$7f
lda #$80 lda #$80
lda #$9f lda #$9f
lda #' ' | $80 lda #' ' | $80
lda #'"' | $80
lda #$a7
lda #'~' | $80 lda #'~' | $80
lda #$ff lda #$ff
rep #'0' rep #'0'
@ -62,4 +66,4 @@ more_ascii !byte 'h'
!byte >more_ascii !byte >more_ascii
!word more_ascii !word more_ascii
!24 more_ascii !24 more_ascii
!byte $10,$68 !byte $10,$70

View File

@ -37,11 +37,15 @@ skipdata: lda #'h'
lda f:'h' lda f:'h'
lda #$1f lda #$1f
lda #' ' lda #' '
lda #'"'
lda #$27
lda #'~' lda #'~'
lda #$7f lda #$7f
lda #$80 lda #$80
lda #$9f lda #$9f
lda #' ' | $80 lda #' ' | $80
lda #'"' | $80
lda #$a7
lda #'~' | $80 lda #'~' | $80
lda #$ff lda #$ff
rep #'0' rep #'0'

View File

@ -1,7 +1,7 @@
# 6502bench SourceGen generated linker script for 2006-operand-formats # 6502bench SourceGen generated linker script for 2006-operand-formats
MEMORY { MEMORY {
MAIN: file=%O, start=%S, size=65536; MAIN: file=%O, start=%S, size=65536;
# MEM000: file=%O, start=$1000, size=125; # MEM000: file=%O, start=$1000, size=133;
} }
SEGMENTS { SEGMENTS {
CODE: load=MAIN, type=rw; CODE: load=MAIN, type=rw;

View File

@ -43,11 +43,15 @@
lda #$1f lda #$1f
lda #$20 lda #$20
lda #$22
lda #$27
lda #$7e lda #$7e
lda #$7f lda #$7f
lda #$80 lda #$80
lda #$9f lda #$9f
lda #$a0 lda #$a0
lda #$a2
lda #$a7
lda #$fe lda #$fe
lda #$ff lda #$ff