Add menu interpreter
This commit is contained in:
parent
5a63b24ec1
commit
856bbdeb63
76
go/vm/interpreter.go
Normal file
76
go/vm/interpreter.go
Normal file
@ -0,0 +1,76 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type BatchCode uint16
|
||||
|
||||
const (
|
||||
MENU_DOWN = 256
|
||||
MENU_UP = 257
|
||||
MENU_NEXT = 258
|
||||
MENU_PREVIOUS = 259
|
||||
)
|
||||
|
||||
var (
|
||||
batchCode = map[string]BatchCode{
|
||||
"DOWN": MENU_DOWN,
|
||||
"UP": MENU_UP,
|
||||
"NEXT": MENU_NEXT,
|
||||
"PREVIOUS": MENU_PREVIOUS,
|
||||
}
|
||||
)
|
||||
|
||||
type menuItem struct {
|
||||
code BatchCode
|
||||
choice string
|
||||
display string
|
||||
target string
|
||||
}
|
||||
|
||||
type MenuProcessor struct {
|
||||
items []menuItem
|
||||
size uint32
|
||||
}
|
||||
|
||||
func NewMenuProcessor() MenuProcessor {
|
||||
return MenuProcessor{}
|
||||
}
|
||||
|
||||
func(mp *MenuProcessor) Add(bop string, choice string, display string, target string) error {
|
||||
bopCode := batchCode[bop]
|
||||
if bopCode == 0 {
|
||||
return fmt.Errorf("unknown menu instruction: %v", bop)
|
||||
}
|
||||
m := menuItem{
|
||||
code: bopCode,
|
||||
choice: choice,
|
||||
display: display,
|
||||
target: target,
|
||||
}
|
||||
mp.items = append(mp.items, m)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MenuProcessor) ToLines() []byte {
|
||||
preLines := []byte{}
|
||||
postLines := []byte{}
|
||||
|
||||
for _, v := range mp.items {
|
||||
preLines = NewLine(preLines, MOUT, []string{v.choice, v.display}, nil, nil)
|
||||
switch v.code {
|
||||
case MENU_UP:
|
||||
postLines = NewLine(postLines, INCMP, []string{v.choice, "_"}, nil, nil)
|
||||
case MENU_NEXT:
|
||||
_ = postLines
|
||||
case MENU_PREVIOUS:
|
||||
_ = postLines
|
||||
default:
|
||||
postLines = NewLine(postLines, INCMP, []string{v.choice, v.target}, nil, nil)
|
||||
}
|
||||
}
|
||||
|
||||
preLines = NewLine(preLines, HALT, nil, nil, nil)
|
||||
return append(preLines, postLines...)
|
||||
}
|
46
go/vm/interpreter_test.go
Normal file
46
go/vm/interpreter_test.go
Normal file
@ -0,0 +1,46 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
||||
func TestMenuInterpreter(t *testing.T) {
|
||||
m := NewMenuProcessor()
|
||||
err := m.Add("DOWN", "0", "inky", "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = m.Add("NEXT", "1", "pinky", "bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = m.Add("PREVIOUS", "2", "blinky clyde", "baz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = m.Add("UP", "99", "tinky-winky", "xyzzy")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = m.Add("BOGUS", "42", "lala poo", "plugh")
|
||||
if err == nil {
|
||||
t.Errorf("expected error on invalid menu item 'BOGUS'")
|
||||
}
|
||||
b := m.ToLines()
|
||||
r, err := ToString(b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expect := `MOUT 0 "inky"
|
||||
MOUT 1 "pinky"
|
||||
MOUT 2 "blinky clyde"
|
||||
MOUT 99 "tinky-winky"
|
||||
HALT
|
||||
INCMP 0 foo
|
||||
INCMP 99 _
|
||||
`
|
||||
if r != expect {
|
||||
t.Errorf("expected:\n\t%v\ngot:\n\t%v\n", expect, r)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user