go-vise

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

commit 22d37de779a79b0e26e9dc7b8c4b22abee19f5bf
parent 324fd98cc3e32dae86fe6f1efb32d54478e411a4
Author: lash <dev@holbrook.no>
Date:   Sat,  1 Apr 2023 09:03:03 +0100

Add catch implementation

Diffstat:
Mgo/state/state.go | 5+++++
Mgo/vm/vm.go | 23++++++++++++++++-------
Mgo/vm/vm_test.go | 34+++++++++++++++++++++++++++++++++-
3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/go/state/state.go b/go/state/state.go @@ -126,6 +126,11 @@ func(st *State) FlagBitSize() uint32 { return st.bitSize } +// FlagBitSize reports the amount of bits available in the bit field index. +func(st *State) FlagByteSize() uint8 { + return uint8(len(st.Flags)) +} + // GetIndex scans a byte slice in same order as in storage, and returns the index of the first set bit. // // If the given byte slice is too small for the bit field bitsize, the check will terminate at end-of-data without error. diff --git a/go/vm/vm.go b/go/vm/vm.go @@ -120,13 +120,22 @@ func RunCatch(instruction []byte, st state.State, rs resource.Resource, ctx cont if err != nil { return st, instruction, err } - r, err := rs.Get(head) - if err != nil { - return st, instruction, err - } - _ = tail - st.Add(head, r, 0) - return st, []byte{}, nil + // TODO: perhaps check against the registered byte size + //l := st.FlagByteSize() + bitFieldSize := tail[0] + bitField := tail[1:1+bitFieldSize] + tail = tail[1+bitFieldSize:] + if st.GetIndex(bitField) { + log.Printf("catch at flag %v, moving to %v", bitField, head) +// r, err := rs.Get(head) +// if err != nil { +// return st, instruction, err +// } + //st.Add(head, r, 0) + st.Down(head) + tail = []byte{} + } + return st, tail, nil } // RunMap executes the CROAK opcode diff --git a/go/vm/vm_test.go b/go/vm/vm_test.go @@ -51,6 +51,7 @@ func (r *TestResource) Get(sym string) (string, error) { case "three": return "{{.one}} inky pinky {{.three}} blinky clyde {{.two}}", nil } + panic(fmt.Sprintf("unknown symbol %s", sym)) return "", fmt.Errorf("unknown symbol %s", sym) } @@ -89,7 +90,7 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) { func TestRun(t *testing.T) { st := state.NewState(5) rs := TestResource{} - b := []byte{0x00, 0x01, 0x03} + b := []byte{0x00, MOVE, 0x03} b = append(b, []byte("foo")...) r, _, err := Run(b, st, &rs, context.TODO()) if err != nil { @@ -339,3 +340,34 @@ func TestRunMoveAndBack(t *testing.T) { t.Errorf("expected where-string 'bar', got %v", loc) } } + +func TestCatchAndBack(t *testing.T) { + st := state.NewState(5) + rs := TestResource{} + rt := router.NewRouter() + rt.Add("foo", "bar") + b := NewLine([]byte{}, LOAD, []string{"one"}, nil, []uint8{0}) + b = NewLine(b, CATCH, []string{"bar"}, []byte{0x04}, nil) + b = NewLine(b, MOVE, []string{"foo"}, nil, nil) + st, _, err := Run(b, st, &rs, context.TODO()) + if err != nil { + t.Error(err) + } + r := st.Where() + if r != "foo" { + t.Errorf("expected where-symbol 'foo', got %v", r) + } + + st.SetFlag(2) + b = NewLine([]byte{}, LOAD, []string{"two"}, nil, []uint8{0}) + b = NewLine(b, CATCH, []string{"bar"}, []byte{0x04}, nil) + b = NewLine(b, MOVE, []string{"foo"}, nil, nil) + st, _, err = Run(b, st, &rs, context.TODO()) + if err != nil { + t.Error(err) + } + r = st.Where() + if r != "bar" { + t.Errorf("expected where-symbol 'bar', got %v", r) + } +}