go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit 856bbdeb6317e8c28b46b828f2357c50f5d0f785
parent 5a63b24ec1c59d83779daa3adf870de620e63f63
Author: lash <dev@holbrook.no>
Date:   Mon,  3 Apr 2023 08:22:01 +0100

Add menu interpreter

Diffstat:
Ago/vm/interpreter.go | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ago/vm/interpreter_test.go | 46++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/go/vm/interpreter.go b/go/vm/interpreter.go @@ -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...) +} diff --git a/go/vm/interpreter_test.go b/go/vm/interpreter_test.go @@ -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) + } +}