Swap input output files, allow multiple input, fix string parsing
- Swapped the input filename and output filename on the command line so multiple input files could be passed. - Implemented appending configs when reading multiple input files. Only lables, ranges, and segments are updated. All other config settings are taken from the first input file. - Fixed string parsing to allow escaping quotes inside a string.
This commit is contained in:
parent
2310b042b0
commit
3406122170
35
cmd/main.go
35
cmd/main.go
|
|
@ -10,11 +10,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Arguments struct {
|
type Arguments struct {
|
||||||
Input string `arg:"positional,required"`
|
Output string `arg:"positional,required"`
|
||||||
Output string `arg:"positional"`
|
Input []string `arg:"positional,required"`
|
||||||
|
|
||||||
RamStart int `arg:"--ram-start" default:"0x5000"`
|
RamStart int `arg:"--ram-start" default:"0x6000"`
|
||||||
RomStart int `arg:"--rom-start" default:"0xE000"`
|
RomStart int `arg:"--rom-start" default:"0x8000"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
@ -29,20 +29,41 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(args *Arguments) error {
|
func run(args *Arguments) error {
|
||||||
input, err := os.ReadFile(args.Input)
|
var config *dasmlbl.Config
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for _, infile := range args.Input {
|
||||||
|
input, err := os.ReadFile(infile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
l, ch := dasmlbl.NewLexer(string(input))
|
l, ch := dasmlbl.NewLexer(string(input))
|
||||||
go l.Run()
|
go l.Run()
|
||||||
|
|
||||||
parser := dasmlbl.NewParser(ch)
|
parser := dasmlbl.NewParser(ch)
|
||||||
config, err := parser.Run()
|
cfg, err := parser.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Printf("[%s] %s\n", infile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config == nil {
|
||||||
|
config = cfg
|
||||||
|
} else {
|
||||||
|
config.Append(cfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config == nil {
|
||||||
|
return fmt.Errorf("no configs parsed")
|
||||||
|
}
|
||||||
|
|
||||||
|
//input, err := os.ReadFile(args.Input)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
var output *os.File
|
var output *os.File
|
||||||
if args.Output == "" {
|
if args.Output == "" {
|
||||||
output = os.Stdout
|
output = os.Stdout
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,12 @@ type Config struct {
|
||||||
Segments []Segment
|
Segments []Segment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) Append(other *Config) {
|
||||||
|
c.Labels = append(c.Labels, other.Labels...)
|
||||||
|
c.Ranges = append(c.Ranges, other.Ranges...)
|
||||||
|
c.Segments = append(c.Segments, other.Segments...)
|
||||||
|
}
|
||||||
|
|
||||||
type Label struct {
|
type Label struct {
|
||||||
Name string
|
Name string
|
||||||
Address int
|
Address int
|
||||||
|
|
|
||||||
20
lex.go
20
lex.go
|
|
@ -61,6 +61,19 @@ func (l *Lexer) next() rune {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Lexer) peek() rune {
|
||||||
|
if l.pos >= len(l.input) {
|
||||||
|
l.width = 0
|
||||||
|
return unicode_EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
r, size := utf8.DecodeRuneInString(l.input[l.pos:])
|
||||||
|
if size == 0 {
|
||||||
|
panic(fmt.Sprintf("zero width at %d", l.pos))
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Lexer) backup() {
|
func (l *Lexer) backup() {
|
||||||
l.pos -= l.width
|
l.pos -= l.width
|
||||||
}
|
}
|
||||||
|
|
@ -177,6 +190,13 @@ func lexString(l *Lexer) stateFn {
|
||||||
l.items <- LexItem{lex_Error, "EOF before string end"}
|
l.items <- LexItem{lex_Error, "EOF before string end"}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r == '\\' && l.peek() == '"' {
|
||||||
|
r = l.next()
|
||||||
|
//fmt.Printf("consuming %c\n", r) // consume
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if r == '"' {
|
if r == '"' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
parse.go
4
parse.go
|
|
@ -139,7 +139,7 @@ func (p *Parser) parseRange() error {
|
||||||
|
|
||||||
itm = p.next()
|
itm = p.next()
|
||||||
if itm.typ != lex_Semicolon {
|
if itm.typ != lex_Semicolon {
|
||||||
return fmt.Errorf("missing semicolon")
|
return fmt.Errorf("[parseRange] missing semicolon")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +213,7 @@ func (p *Parser) parseLabel() error {
|
||||||
|
|
||||||
itm = p.next()
|
itm = p.next()
|
||||||
if itm.typ != lex_Semicolon {
|
if itm.typ != lex_Semicolon {
|
||||||
return fmt.Errorf("missing semicolon")
|
return fmt.Errorf("[parseLabel] missing semicolon; %#v", lbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue