go-vise

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

commit 845380fd7ab5d9a44df023ae158a2d7d3dd549a6
parent d370bc33fa26d4807fdf46b184fa828d19d32c8d
Author: lash <dev@holbrook.no>
Date:   Tue, 18 Apr 2023 14:41:28 +0100

Remove menu residue when move without render, trigger on halt

Diffstat:
Masm/asm.go | 13++++++++-----
Masm/asm_test.go | 16++++++++++++++++
Mrender/menu.go | 5++++-
Mrender/page.go | 3+++
Mvm/runner.go | 2++
Mvm/runner_test.go | 43+++++++++++++++++++++++++++++++++++++++++++
6 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/asm/asm.go b/asm/asm.go @@ -23,11 +23,11 @@ type Asm struct { // Arg holds all parsed argument elements of a single line of assembly code. type Arg struct { - Sym *string `(@Sym Whitespace?)?` + Sym *string `((@SpecialSym | @Sym) Whitespace?)?` Size *uint32 `(@Size Whitespace?)?` Flag *uint8 `(@Size Whitespace?)?` - Selector *string `(@Sym Whitespace?)?` - Desc *string `(Quote ((@Sym | @Size) @Whitespace?)+ Quote Whitespace?)?` + Selector *string `((@SpecialSym | @SpecialSelector | @Sym) Whitespace?)?` + Desc *string `(Quote (@Sym @Whitespace?)+ Quote Whitespace?)?` } func flush(b *bytes.Buffer, w io.Writer) (int, error) { @@ -246,7 +246,7 @@ func (a Arg) String() string { type Instruction struct { OpCode string `@Ident` OpArg Arg `(Whitespace @@)?` - Comment string `Comment? EOL` + Comment string `Whitespace? Comment? EOL` } // String implement the String interface. @@ -259,7 +259,10 @@ var ( {"Comment", `(?:#)[^\n]*`}, {"Ident", `^[A-Z]+`}, {"Size", `[0-9]+`}, - {"Sym", `[a-zA-Z_\*\.][a-zA-Z0-9_]*`}, + {"Cap", `[A-Z]`}, + {"Sym", `[a-zA-Z0-9_]+`}, + {"SpecialSym", `_`}, + {"SpecialSelector", `[\*\.]`}, {"Whitespace", `[ \t]+`}, {"EOL", `[\n\r]+`}, {"Quote", `["']`}, diff --git a/asm/asm_test.go b/asm/asm_test.go @@ -247,3 +247,19 @@ func TestParserWriteMultiple(t *testing.T) { t.Fatal(err) } } + +func TestParserCapQuote(t *testing.T) { + t.Skip("please fix mysterious ignore of initial cap in display sym match") + b := vm.NewLine(nil, vm.MOUT, []string{"a", "foo"}, nil, nil) + b = vm.NewLine(b, vm.MOUT, []string{"b", "Bar"}, nil, nil) + b = vm.NewLine(b, vm.MOUT, []string{"c", "baz"}, nil, nil) + s, err := vm.ToString(b) + log.Printf("parsing:\n%s", s) + + r := bytes.NewBuffer(nil) + n, err := Parse(s, r) + if err != nil { + t.Fatal(err) + } + _ = n +} diff --git a/render/menu.go b/render/menu.go @@ -178,4 +178,7 @@ func(m *Menu) reset() { } } - +func(m *Menu) Reset() { + m.menu = [][2]string{} + m.reset() +} diff --git a/render/page.go b/render/page.go @@ -176,6 +176,9 @@ func(pg *Page) Render(sym string, idx uint16) (string, error) { func(pg *Page) Reset() { pg.sink = nil pg.cacheMap = make(map[string]string) + if pg.menu != nil { + pg.menu.Reset() + } } // render menu and all syms except sink, split sink into display chunks diff --git a/vm/runner.go b/vm/runner.go @@ -76,6 +76,8 @@ func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { if err != nil { panic(err) } + vm.pg.Reset() + vm.mn.Reset() } _, err = vm.st.SetFlag(state.FLAG_DIRTY) diff --git a/vm/runner_test.go b/vm/runner_test.go @@ -80,6 +80,8 @@ func (r TestResource) GetTemplate(sym string) (string, error) { return "root", nil case "_catch": return "aiee", nil + case "ouf": + return "ouch", nil case "flagCatch": return "flagiee", nil } @@ -124,6 +126,9 @@ func(r TestResource) GetCode(sym string) ([]byte, error) { b = NewLine(b, MOVE, []string{"_"}, nil, nil) case "root": b = r.RootCode + case "ouf": + b = NewLine(b, MOUT, []string{"1", "oo"}, nil, nil) + b = NewLine(b, HALT, nil, nil, nil) } return b, nil @@ -185,6 +190,7 @@ func TestRunLoadRender(t *testing.T) { t.Fatal(err) } b = NewLine(nil, MAP, []string{"one"}, nil, nil) + b = NewLine(b, MAP, []string{"two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) _, err = vm.Run(b, ctx) if err != nil { @@ -583,3 +589,40 @@ func TestInputIgnoreWildcard(t *testing.T) { t.Fatalf("expected 'one', got %s", location) } } + +func TestCatchCleanMenu(t *testing.T) { + st := state.NewState(5) + rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil) + + var err error + + st.Down("root") + + b := NewLine(nil, MOUT, []string{"1", "one"}, nil, nil) + b = NewLine(b, MOUT, []string{"2", "two"}, nil, nil) + b = NewLine(b, HALT, nil, nil, nil) + b = NewLine(b, INCMP, []string{"1", "foo"}, nil, nil) + b = NewLine(b, CATCH, []string{"ouf"}, []byte{0x08}, []uint8{0x01}) + + ctx := context.TODO() + + st.SetInput([]byte("foo")) + b, err = vm.Run(b, ctx) + if err != nil { + t.Fatal(err) + } + + st.SetInput([]byte("foo")) + b, err = vm.Run(b, ctx) + if err != nil { + t.Fatal(err) + } + + r, err := vm.Render(ctx) + if err != nil { + t.Fatal(err) + } + fmt.Printf("Result:\n%s", r) +}