2023-04-04 11:32:39 +02:00
|
|
|
package asm
|
2023-04-03 09:22:01 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-04-04 11:32:39 +02:00
|
|
|
|
2023-04-14 10:59:37 +02:00
|
|
|
"git.defalsify.org/vise/vm"
|
2023-04-03 09:22:01 +02:00
|
|
|
)
|
|
|
|
|
2023-04-12 19:04:36 +02:00
|
|
|
// BatchCode defines quasi-opcodes that expand to mulitple individual vm instructions.
|
2023-04-03 09:22:01 +02:00
|
|
|
type BatchCode uint16
|
|
|
|
|
|
|
|
const (
|
2023-04-03 10:14:45 +02:00
|
|
|
_MENU_OFFSET = 256
|
|
|
|
MENU_DOWN = _MENU_OFFSET
|
|
|
|
MENU_UP = _MENU_OFFSET + 1
|
|
|
|
MENU_NEXT = _MENU_OFFSET + 2
|
|
|
|
MENU_PREVIOUS = _MENU_OFFSET + 3
|
2023-04-03 09:22:01 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-04-12 19:04:36 +02:00
|
|
|
// MenuProcessor handles code lines with BatchCode quasi-opcodes that control menu generation.
|
|
|
|
//
|
|
|
|
// It creates vm instructions for display of menu and handling of input on either size of a vm.HALT instruction.
|
2023-04-03 09:22:01 +02:00
|
|
|
type MenuProcessor struct {
|
|
|
|
items []menuItem
|
|
|
|
size uint32
|
|
|
|
}
|
|
|
|
|
2023-04-12 19:04:36 +02:00
|
|
|
// NewMenuProcessor creates a new MenuProcessor object.
|
2023-04-03 09:22:01 +02:00
|
|
|
func NewMenuProcessor() MenuProcessor {
|
|
|
|
return MenuProcessor{}
|
|
|
|
}
|
|
|
|
|
2023-04-12 19:04:36 +02:00
|
|
|
// Add a menu batch instruction to be processed.
|
|
|
|
//
|
|
|
|
// Instructions will be rendered in the order in which they have been added.
|
2023-04-03 09:22:01 +02:00
|
|
|
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)
|
|
|
|
}
|
2023-04-06 09:49:16 +02:00
|
|
|
if len(target) > 0 && bopCode != MENU_DOWN {
|
|
|
|
return fmt.Errorf("target is only valid for DOWN")
|
|
|
|
}
|
2023-04-03 09:22:01 +02:00
|
|
|
m := menuItem{
|
|
|
|
code: bopCode,
|
|
|
|
choice: choice,
|
|
|
|
display: display,
|
|
|
|
target: target,
|
|
|
|
}
|
|
|
|
mp.items = append(mp.items, m)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-04-12 19:04:36 +02:00
|
|
|
// ToLines returns the generated bytecode from the added menu batch instructions.
|
2023-04-03 09:22:01 +02:00
|
|
|
func (mp *MenuProcessor) ToLines() []byte {
|
|
|
|
preLines := []byte{}
|
|
|
|
postLines := []byte{}
|
|
|
|
|
|
|
|
for _, v := range mp.items {
|
|
|
|
switch v.code {
|
|
|
|
case MENU_UP:
|
2023-04-08 10:31:32 +02:00
|
|
|
preLines = vm.NewLine(preLines, vm.MOUT, []string{v.choice, v.display}, nil, nil)
|
2023-04-04 11:32:39 +02:00
|
|
|
postLines = vm.NewLine(postLines, vm.INCMP, []string{v.choice, "_"}, nil, nil)
|
2023-04-03 09:22:01 +02:00
|
|
|
case MENU_NEXT:
|
2023-04-08 11:01:28 +02:00
|
|
|
preLines = vm.NewLine(preLines, vm.MNEXT, []string{v.choice, v.display}, nil, nil)
|
2023-04-08 09:14:14 +02:00
|
|
|
postLines = vm.NewLine(postLines, vm.INCMP, []string{v.choice, ">"}, nil, nil)
|
2023-04-03 09:22:01 +02:00
|
|
|
case MENU_PREVIOUS:
|
2023-04-08 11:01:28 +02:00
|
|
|
preLines = vm.NewLine(preLines, vm.MPREV, []string{v.choice, v.display}, nil, nil)
|
2023-04-08 09:14:14 +02:00
|
|
|
postLines = vm.NewLine(postLines, vm.INCMP, []string{v.choice, "<"}, nil, nil)
|
2023-04-03 09:22:01 +02:00
|
|
|
default:
|
2023-04-08 10:31:32 +02:00
|
|
|
preLines = vm.NewLine(preLines, vm.MOUT, []string{v.choice, v.display}, nil, nil)
|
2023-04-04 11:32:39 +02:00
|
|
|
postLines = vm.NewLine(postLines, vm.INCMP, []string{v.choice, v.target}, nil, nil)
|
2023-04-03 09:22:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 11:32:39 +02:00
|
|
|
preLines = vm.NewLine(preLines, vm.HALT, nil, nil, nil)
|
2023-04-03 09:22:01 +02:00
|
|
|
return append(preLines, postLines...)
|
|
|
|
}
|