commit 725ee335ec2d0247bf1959bb9e38ca94d572a672
parent c3d634c1d3abedf671c6dceddc55feab8e0638d6
Author: lash <dev@holbrook.no>
Date: Fri, 31 Mar 2023 20:05:57 +0100
Add back handler
Diffstat:
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/go/vm/vm.go b/go/vm/vm.go
@@ -38,6 +38,8 @@ func Apply(input []byte, instruction []byte, st state.State, rs resource.Fetcher
}
if sym == "" {
instruction = NewLine([]byte{}, MOVE, []string{"_catch"}, nil, nil)
+ } else if sym == "_" {
+ instruction = NewLine([]byte{}, BACK, nil, nil, nil)
} else {
new_instruction := NewLine([]byte{}, MOVE, []string{sym}, nil, nil)
instruction = append(new_instruction, instruction...)
@@ -80,6 +82,9 @@ func Run(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Co
case MOVE:
st, instruction, err = RunMove(instruction[2:], st, rs, ctx)
break
+ case BACK:
+ st, instruction, err = RunBack(instruction[2:], st, rs, ctx)
+ break
default:
err = fmt.Errorf("Unhandled state: %v", op)
}
@@ -169,6 +174,11 @@ func RunMove(instruction []byte, st state.State, rs resource.Fetcher, ctx contex
return st, tail, nil
}
+func RunBack(instruction []byte, st state.State, rs resource.Fetcher, ctx context.Context) (state.State, []byte, error) {
+ st.Up()
+ return st, instruction, nil
+}
+
func refresh(key string, sym []byte, rs resource.Fetcher, ctx context.Context) (string, error) {
fn, err := rs.FuncFor(key)
if err != nil {
diff --git a/go/vm/vm_test.go b/go/vm/vm_test.go
@@ -250,9 +250,10 @@ func TestRunArgInvalid(t *testing.T) {
func TestRunArgInstructions(t *testing.T) {
st := state.NewState(5)
+ rs := TestResource{}
+
rt := router.NewRouter()
rt.Add("foo", "bar")
- rs := TestResource{}
b := []byte{0x03}
b = append(b, []byte("foo")...)
b = append(b, rt.ToBytes()...)
@@ -284,3 +285,57 @@ func TestRunArgInstructions(t *testing.T) {
}
_ = r
}
+
+func TestRunMoveAndBack(t *testing.T) {
+ st := state.NewState(5)
+ rs := TestResource{}
+ rt := router.NewRouter()
+ rt.Add("foo", "bar")
+ b := []byte{0x03}
+ b = append(b, []byte("foo")...)
+ b = append(b, rt.ToBytes()...)
+ bi := NewLine([]byte{}, LOAD, []string{"one"}, nil, []uint8{0})
+
+ var err error
+ st, b, err = Apply(b, bi, st, &rs, context.TODO())
+ if err != nil {
+ t.Error(err)
+ }
+ l := len(b)
+ if l != 0 {
+ t.Errorf("expected empty remainder, got length %v: %v", l, b)
+ }
+
+ rt = router.NewRouter()
+ rt.Add("foo", "baz")
+ b = []byte{0x03}
+ b = append(b, []byte("foo")...)
+ b = append(b, rt.ToBytes()...)
+ bi = NewLine([]byte{}, LOAD, []string{"two"}, nil, []uint8{0})
+ st, b, err = Apply(b, bi, st, &rs, context.TODO())
+ if err != nil {
+ t.Error(err)
+ }
+ l = len(b)
+ if l != 0 {
+ t.Errorf("expected empty remainder, got length %v: %v", l, b)
+ }
+
+ rt = router.NewRouter()
+ rt.Add("foo", "_")
+ b = []byte{0x03}
+ b = append(b, []byte("foo")...)
+ b = append(b, rt.ToBytes()...)
+ st, b, err = Apply(b, []byte{}, st, &rs, context.TODO())
+ if err != nil {
+ t.Error(err)
+ }
+ l = len(b)
+ if l != 0 {
+ t.Errorf("expected empty remainder, got length %v: %v", l, b)
+ }
+ loc := st.Where()
+ if loc != "bar" {
+ t.Errorf("expected where-string 'bar', got %v", loc)
+ }
+}