Skip to content

Commit

Permalink
Do case-insensitive lookup of symbols
Browse files Browse the repository at this point in the history
Add a bunch of tests as well.
  • Loading branch information
smoynes committed Oct 16, 2023
1 parent 7b3ce36 commit 2c7924f
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 47 deletions.
4 changes: 3 additions & 1 deletion internal/asm/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ func (s SymbolTable) Add(sym string, loc uint16) {

// Offset computes a n-bit PC-relative offset.
func (s SymbolTable) Offset(sym string, pc uint16, n int) (uint16, error) {
sym = strings.ToUpper(sym)

loc, ok := s[sym]
if !ok {
return 0xffff, &SymbolError{Symbol: sym, Loc: pc}
Expand Down Expand Up @@ -122,7 +124,7 @@ func (pe *SyntaxError) Error() string {
} else if pe.Err == nil && pe.Line != "" {
return fmt.Sprintf("syntax error: line: %q", pe.Line)
} else {
return fmt.Sprintf("syntax error: %s: line: %0#4X %q", pe.Err, pe.Pos, pe.Line)
return fmt.Sprintf("syntax error: %s: line: %0#4x %q", pe.Err, pe.Pos, pe.Line)
}
}

Expand Down
24 changes: 24 additions & 0 deletions internal/asm/gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,3 +539,27 @@ func TestSTRINGZ_Generate(tt *testing.T) {
}
}
}

func Test_CaseInsensitiveLabels(tt *testing.T) {
pc := uint16(0x3000)
symbols := SymbolTable{
"LABEL": 0x2fff, // -1
"THERE": 0x31ff, // 64
"BACK": 0x2800, // -64
"WAYBACK": 0x27ff,
"OVERTHERE": 0x3800,
}

t := generatorHarness{tt}
tcs := []generateCase{
{oper: &JSR{OFFSET: 0x00ff}, want: 0x48ff},
{oper: &JSR{OFFSET: 0xffff}, want: 0x4bff},
{oper: &JSR{SYMBOL: "label"}, want: 0x4fff},
{oper: &JSR{SYMBOL: "there"}, want: 0x49ff},
{oper: &JSR{SYMBOL: "back"}, want: 0x4800},
{oper: &JSR{SYMBOL: "wayback"}, wantErr: &OffsetError{0xf7ff}},
{oper: &JSR{SYMBOL: "overthere"}, wantErr: &OffsetError{0x0800}},
}

t.Run(pc, symbols, tcs)
}
6 changes: 6 additions & 0 deletions internal/asm/ops_parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,12 @@ func TestLEA_Parse(t *testing.T) {
want: &LEA{DR: "DR", OFFSET: 0, SYMBOL: "LABEL"},
wantErr: nil,
},
{
name: "LEA label mixed case",
opcode: "LEA", operands: []string{"DR", "LaBel"},
want: &LEA{DR: "DR", OFFSET: 0, SYMBOL: "LABEL"},
wantErr: nil,
},
{
name: "LEA literal",
opcode: "LEA", operands: []string{"DR", "#-1"},
Expand Down
45 changes: 24 additions & 21 deletions internal/asm/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,33 +381,36 @@ func parseRegister(oper string) string {
// parseImmediate returns a constant literal value or a symbolic reference from an operand. The
// value is taken as n bits long. Literals can take the forms:
//
// #123
// #-1
// #x123
// #o123
// #b0101
// - #123
// - #-1
// - #x123
// - #o123
// - #b0101
//
// References may be in the forms:
// Symbolic references may be in the forms:
//
// LABEL
// [LABEL]
func parseImmediate(oper string, n uint8) (uint16, string, error) {
if len(oper) > 1 && oper[0] == '#' { // Immediate-mode prefix.
val, err := parseLiteral(oper[1:], n)
return val, "", err
} else if len(oper) > 2 && oper[0] == '[' && oper[len(oper)-1] == ']' { // [LABEL]
return 0, oper[1 : len(oper)-2], nil
} else if len(oper) > 1 {
val, err := parseLiteral(oper, n)
// - LABEL
// - [LABEL]
func parseImmediate(oper string, n uint8) (lit uint16, sym string, err error) {
switch {
case len(oper) > 1 && oper[0] == '#': // #IMMn
lit, err = parseLiteral(oper[1:], n)
case len(oper) > 2 && oper[0] == '[' && oper[len(oper)-1] == ']': // [LABEL]
sym = oper[1 : len(oper)-2]
case len(oper) > 1:
lit, err = parseLiteral(oper, n)
if err != nil {
return 0, oper, nil //nolint:nilerr
lit = 0
sym = oper
err = nil
}

return val, oper, nil

} else { // oh no
default: // oh no
return 0xffff, "", errors.New("operand error")
}

sym = strings.ToUpper(sym)

return
}

// parseLiteral converts an operand as literal text to an n-bit integer value. If the literal cannot
Expand Down
1 change: 1 addition & 0 deletions internal/asm/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func TestParser_Fixtures(tt *testing.T) {
"parser5.asm",
"parser6.asm",
"parser7.asm",
"parser8.asm",
}

for _, fn := range tests {
Expand Down
4 changes: 2 additions & 2 deletions internal/asm/testdata/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Assembler Test Fixtures
-----------------------

The asm files in this directory are test files and should parse and generate
code cleanly. They are not examples of good code and some of the files are not
even meaningful programs.
code cleanly. They are not examples of good code. Some are not even meaningful
programs.
23 changes: 0 additions & 23 deletions internal/asm/testdata/parser1.asm

This file was deleted.

5 changes: 5 additions & 0 deletions internal/asm/testdata/parser8.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
;;; Parser regression test for label case-sensitivity.
.ORIG x3100
LEA R0,MixedCase

MIXEDCASE .FILL x2364

0 comments on commit 2c7924f

Please sign in to comment.