mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
o debugger
- commands - removed RECORD command. the functionality is now part of the SCRIPT command o commandline - bugfixes
This commit is contained in:
parent
47b59fedad
commit
102f9813d7
7 changed files with 97 additions and 54 deletions
|
@ -151,6 +151,7 @@ func TestParser(t *testing.T) {
|
|||
|
||||
template = []string{
|
||||
"DISPLAY (OFF|DEBUG|SCALE [%V]|DEBUGCOLORS)",
|
||||
"SCRIPT [%F|RECORD [%F]|END]",
|
||||
"DROP [BREAK|TRAP|WATCH] [%S]",
|
||||
"GREP %V",
|
||||
"TEST [FOO [%S]|BAR] (EGG [%S]|FOG|NOG NUG) (TUG)",
|
||||
|
@ -159,6 +160,6 @@ func TestParser(t *testing.T) {
|
|||
cmds, err = commandline.ParseCommandTemplate(template)
|
||||
if expectSuccess(t, err) {
|
||||
expectEquality(t, template, cmds)
|
||||
//memvizOutput(t, "1", cmds)
|
||||
// memvizOutput(t, "1", cmds)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,8 +59,6 @@ func (tc *TabCompletion) Complete(input string) string {
|
|||
}
|
||||
|
||||
// new tabcompletion session
|
||||
|
||||
// reinitialise matches array
|
||||
tc.Reset()
|
||||
|
||||
// no need to to anything if input ends with a space
|
||||
|
@ -134,11 +132,18 @@ func (tc *TabCompletion) buildMatches(n *node, tokens *Tokens) {
|
|||
match = err == nil
|
||||
|
||||
case "%S":
|
||||
// accept anything
|
||||
// against expectations, string placeholders do not cause a match. if
|
||||
// they did then they would be acting in the same way as the %*
|
||||
// placeholder and any subsequent branches will not be considered at
|
||||
// all.
|
||||
match = false
|
||||
|
||||
case "%F":
|
||||
// TODO: filename completion
|
||||
|
||||
// see commentary for %S above
|
||||
match = false
|
||||
|
||||
case "%*":
|
||||
// this placeholder indicates that the rest of the tokens can be
|
||||
// ignored.
|
||||
|
|
|
@ -190,3 +190,26 @@ func TestTabCompletion_complex(t *testing.T) {
|
|||
t.Errorf("expecting '%s' got '%s'", expected, completion)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTabCompletion_filenameFirstOption(t *testing.T) {
|
||||
var cmds *commandline.Commands
|
||||
var tc *commandline.TabCompletion
|
||||
var completion, expected string
|
||||
var err error
|
||||
|
||||
cmds, err = commandline.ParseCommandTemplate([]string{
|
||||
"TEST [%F|foo|bar]",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
tc = commandline.NewTabCompletion(cmds)
|
||||
|
||||
completion = "TEST f"
|
||||
expected = "TEST FOO "
|
||||
completion = tc.Complete(completion)
|
||||
if completion != expected {
|
||||
t.Errorf("expecting '%s' got '%s'", expected, completion)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func placeHolderText(text string) string {
|
|||
// branches creates a readable string, listing all the branches of the node
|
||||
func branches(n *node) string {
|
||||
s := strings.Builder{}
|
||||
s.WriteString(n.tag)
|
||||
s.WriteString(placeHolderText(n.tag))
|
||||
for bi := range n.branch {
|
||||
s.WriteString(" or ")
|
||||
s.WriteString(placeHolderText(n.branch[bi].tag))
|
||||
|
@ -112,11 +112,18 @@ func (n *node) validate(tokens *Tokens) error {
|
|||
}
|
||||
|
||||
case "%S":
|
||||
// accept anything
|
||||
// string placeholders do not cause a match if the node has branches.
|
||||
// if they did then they would be acting in the same way as the %*
|
||||
// placeholder and any subsequent branches will not be considered at
|
||||
// all.
|
||||
|
||||
match = n.branch == nil
|
||||
|
||||
case "%F":
|
||||
// accept anything (note: filename is distinct from %S when we use it
|
||||
// for tab-completion)
|
||||
// TODO: check for file existance
|
||||
|
||||
// see commentary for %S above
|
||||
match = n.branch == nil
|
||||
|
||||
case "%*":
|
||||
// this placeholder indicates that the rest of the tokens can be
|
||||
|
|
|
@ -228,3 +228,18 @@ func TestValidation_doubleArgs(t *testing.T) {
|
|||
t.Errorf("doesn't match but should: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidation_filenameFirstArg(t *testing.T) {
|
||||
var cmds *commandline.Commands
|
||||
var err error
|
||||
|
||||
cmds, err = commandline.ParseCommandTemplate([]string{"TEST [%F|foo [wibble]|bar]"})
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
err = cmds.Validate("TEST foo wibble")
|
||||
if err != nil {
|
||||
t.Errorf("doesn't match but should: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ const (
|
|||
cmdPoke = "POKE"
|
||||
cmdQuit = "QUIT"
|
||||
cmdRAM = "RAM"
|
||||
cmdRecord = "RECORD"
|
||||
cmdRIOT = "RIOT"
|
||||
cmdReset = "RESET"
|
||||
cmdRun = "RUN"
|
||||
|
@ -90,11 +89,10 @@ var expCommandTemplate = []string{
|
|||
cmdPoke + " %V %*",
|
||||
cmdQuit,
|
||||
cmdRAM,
|
||||
cmdRecord + " [END|%F]",
|
||||
cmdRIOT,
|
||||
cmdReset,
|
||||
cmdRun,
|
||||
cmdScript + " %F",
|
||||
cmdScript + " [RECORD [%S]|END|%F]",
|
||||
cmdStep + " (CPU|VIDEO|SCANLINE)", // see notes
|
||||
cmdStepMode + " (CPU|VIDEO)",
|
||||
cmdStick + "[0|1] [LEFT|RIGHT|UP|DOWN|FIRE|CENTRE|NOFIRE]",
|
||||
|
@ -162,13 +160,14 @@ func (dbg *Debugger) parseCommand(userInput *string) (parseCommandResult, error)
|
|||
// much about the success of tokens.Get() in the command implementations
|
||||
// below:
|
||||
//
|
||||
// tok, _ := tokens.Get()
|
||||
// arg, _ := tokens.Get()
|
||||
//
|
||||
// is an acceptable pattern. default values can be handled thus:
|
||||
// is an acceptable pattern when an argument is required. default values
|
||||
// can be handled thus:
|
||||
//
|
||||
// tok, ok := tokens.Get()
|
||||
// arg, ok := tokens.Get()
|
||||
// if ok {
|
||||
// switch tok {
|
||||
// switch arg {
|
||||
// ...
|
||||
// }
|
||||
// } else {
|
||||
|
@ -222,17 +221,31 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens) (parseCommandResul
|
|||
dbg.print(console.Feedback, "machine reset with new cartridge (%s)", cart)
|
||||
|
||||
case cmdScript:
|
||||
script, _ := tokens.Get()
|
||||
|
||||
spt, err := dbg.loadScript(script)
|
||||
if err != nil {
|
||||
dbg.print(console.Error, "error running debugger initialisation script: %s\n", err)
|
||||
return doNothing, err
|
||||
}
|
||||
|
||||
err = dbg.inputLoop(spt, false)
|
||||
if err != nil {
|
||||
return doNothing, err
|
||||
option, _ := tokens.Get()
|
||||
switch strings.ToUpper(option) {
|
||||
case "RECORD":
|
||||
var err error
|
||||
script, _ := tokens.Get()
|
||||
dbg.scriptRec, err = dbg.startScriptRecording(script)
|
||||
return scriptRecordStarted, err
|
||||
case "END":
|
||||
if dbg.scriptRec == nil {
|
||||
return doNothing, fmt.Errorf("no script recording currently taking place")
|
||||
}
|
||||
err := dbg.scriptRec.end()
|
||||
dbg.scriptRec = nil
|
||||
dbg.print(console.Feedback, "script recording completed\n")
|
||||
return scriptRecordEnded, err
|
||||
default:
|
||||
// run a script
|
||||
spt, err := dbg.loadScript(option)
|
||||
if err != nil {
|
||||
return doNothing, err
|
||||
}
|
||||
err = dbg.inputLoop(spt, false)
|
||||
if err != nil {
|
||||
return doNothing, err
|
||||
}
|
||||
}
|
||||
|
||||
case cmdDisassembly:
|
||||
|
@ -542,9 +555,9 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens) (parseCommandResul
|
|||
}
|
||||
|
||||
case cmdCartridge:
|
||||
tok, ok := tokens.Get()
|
||||
arg, ok := tokens.Get()
|
||||
if ok {
|
||||
switch tok {
|
||||
switch arg {
|
||||
case "ANALYSIS":
|
||||
dbg.print(console.Feedback, dbg.disasm.String())
|
||||
}
|
||||
|
@ -707,8 +720,8 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens) (parseCommandResul
|
|||
case cmdPlayer:
|
||||
plyr := -1
|
||||
|
||||
tok, _ := tokens.Get()
|
||||
switch tok {
|
||||
arg, _ := tokens.Get()
|
||||
switch arg {
|
||||
case "0":
|
||||
plyr = 0
|
||||
case "1":
|
||||
|
@ -766,8 +779,8 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens) (parseCommandResul
|
|||
case cmdMissile:
|
||||
mssl := -1
|
||||
|
||||
tok, _ := tokens.Get()
|
||||
switch tok {
|
||||
arg, _ := tokens.Get()
|
||||
switch arg {
|
||||
case "0":
|
||||
mssl = 0
|
||||
case "1":
|
||||
|
@ -913,26 +926,6 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens) (parseCommandResul
|
|||
if err != nil {
|
||||
return doNothing, err
|
||||
}
|
||||
|
||||
case cmdRecord:
|
||||
// record can refer to recording of a script or recording of user
|
||||
// input. in this context, it currently only refers to script recording
|
||||
|
||||
tok, _ := tokens.Get()
|
||||
|
||||
if strings.ToUpper(tok) == "END" {
|
||||
if dbg.scriptRec == nil {
|
||||
return doNothing, fmt.Errorf("no script recording currently taking place")
|
||||
}
|
||||
err := dbg.scriptRec.end()
|
||||
dbg.scriptRec = nil
|
||||
return scriptRecordEnded, err
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
dbg.scriptRec, err = dbg.startScriptRecording(tok)
|
||||
return scriptRecordStarted, err
|
||||
}
|
||||
|
||||
return doNothing, nil
|
||||
|
|
|
@ -27,11 +27,10 @@ var Help = map[string]string{
|
|||
cmdPoke: "Modify an individual memory address",
|
||||
cmdQuit: "Exits the emulator",
|
||||
cmdRAM: "Display the current contents of PIA RAM",
|
||||
cmdRecord: "Start recording entered commands to an external script",
|
||||
cmdRIOT: "Display the current state of the RIOT",
|
||||
cmdReset: "Reset the emulation to its initial state",
|
||||
cmdRun: "Run emulator until next halt state",
|
||||
cmdScript: "Run commands from specified file",
|
||||
cmdScript: "Run commands from specified file or record commands to a file",
|
||||
cmdStep: "Step forward emulator one step (see STEPMODE command)",
|
||||
cmdStepMode: "Change method of stepping: CPU or VIDEO",
|
||||
cmdStick: "Emulate a joystick input for Player 0 or Player 1",
|
||||
|
|
Loading…
Add table
Reference in a new issue