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:
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)
+}