commit 4f473c12f05cef511d231183e80d1e3f3763b275
parent 39eafc8ff272cb0c0b59cf789ee21bba51df4b5a
Author: lash <dev@holbrook.no>
Date: Sat, 1 Apr 2023 14:47:03 +0100
WIP implement engine object
Diffstat:
6 files changed, 259 insertions(+), 172 deletions(-)
diff --git a/go/engine/engine.go b/go/engine/engine.go
@@ -2,6 +2,7 @@ package engine
import (
"context"
+ "fmt"
"io"
"log"
@@ -16,11 +17,11 @@ import (
//}
type Engine struct {
- st state.State
+ st *state.State
rs resource.Resource
}
-func NewEngine(st state.State, rs resource.Resource) Engine {
+func NewEngine(st *state.State, rs resource.Resource) Engine {
engine := Engine{st, rs}
return engine
}
@@ -28,7 +29,33 @@ func NewEngine(st state.State, rs resource.Resource) Engine {
func(en *Engine) Init(ctx context.Context) error {
b := vm.NewLine([]byte{}, vm.MOVE, []string{"root"}, nil, nil)
var err error
- en.st, _, err = vm.Run(b, en.st, en.rs, ctx)
+ _, err = vm.Run(b, en.st, en.rs, ctx)
+ if err != nil {
+ return err
+ }
+ location := en.st.Where()
+ code, err := en.rs.GetCode(location)
+ if err != nil {
+ return err
+ }
+ return en.st.AppendCode(code)
+}
+
+func (en *Engine) Exec(input []byte, ctx context.Context) error {
+ l := uint8(len(input))
+ if l > 255 {
+ return fmt.Errorf("input too long (%v)", l)
+ }
+ input = append([]byte{l}, input...)
+ code, err := en.st.GetCode()
+ if err != nil {
+ return err
+ }
+ if len(code) == 0 {
+ return fmt.Errorf("no code to execute")
+ }
+ code, err = vm.Apply(input, code, en.st, en.rs, ctx)
+ en.st.SetCode(code)
return err
}
diff --git a/go/engine/engine_test.go b/go/engine/engine_test.go
@@ -3,6 +3,8 @@ package engine
import (
"bytes"
"context"
+ "fmt"
+ "io/ioutil"
"log"
"path"
"text/template"
@@ -16,10 +18,10 @@ import (
type FsWrapper struct {
*resource.FsResource
- st state.State
+ st *state.State
}
-func NewFsWrapper(path string, st state.State, ctx context.Context) FsWrapper {
+func NewFsWrapper(path string, st *state.State, ctx context.Context) FsWrapper {
rs := resource.NewFsResource(path, ctx)
return FsWrapper {
&rs,
@@ -42,12 +44,27 @@ func (r FsWrapper) RenderTemplate(sym string, values map[string]string) (string,
if err != nil {
return "", err
}
- log.Printf("template is %v render is %v", v, b)
return b.String(), err
}
+func(fs FsWrapper) one(ctx context.Context) (string, error) {
+ return "one", nil
+}
+
func(fs FsWrapper) FuncFor(sym string) (resource.EntryFunc, error) {
- return nil, nil
+ switch sym {
+ case "one":
+ return fs.one, nil
+ }
+ return nil, fmt.Errorf("function for %v not found", sym)
+}
+
+func(fs FsWrapper) GetCode(sym string) ([]byte, error) {
+ sym += ".bin"
+ fp := path.Join(fs.Path, sym)
+ r, err := ioutil.ReadFile(fp)
+ log.Printf("getcode for %v %v", fp, r)
+ return r, err
}
func TestEngineInit(t *testing.T) {
@@ -62,8 +79,8 @@ func TestEngineInit(t *testing.T) {
// }
dir := path.Join(testdataloader.GetBasePath(), "testdata")
ctx := context.TODO()
- rs := NewFsWrapper(dir, st, ctx)
- en := NewEngine(st, rs)
+ rs := NewFsWrapper(dir, &st, ctx)
+ en := NewEngine(&st, &rs)
err := en.Init(ctx)
if err != nil {
t.Fatal(err)
@@ -78,4 +95,13 @@ func TestEngineInit(t *testing.T) {
if !bytes.Equal(b, []byte("hello world")) {
t.Fatalf("expected result 'hello world', got %v", b)
}
+ input := []byte("foo")
+ err = en.Exec(input, ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ r := st.Where()
+ if r != "bar" {
+ t.Fatalf("expected where-string 'bar', got %v", r)
+ }
}
diff --git a/go/resource/fs.go b/go/resource/fs.go
@@ -9,19 +9,19 @@ import (
)
type FsResource struct {
- path string
+ Path string
ctx context.Context
}
func NewFsResource(path string, ctx context.Context) (FsResource) {
return FsResource{
- path: path,
+ Path: path,
ctx: ctx,
}
}
func(fs FsResource) GetTemplate(sym string) (string, error) {
- fp := path.Join(fs.path, sym)
+ fp := path.Join(fs.Path, sym)
r, err := ioutil.ReadFile(fp)
s := string(r)
return strings.TrimSpace(s), err
diff --git a/go/state/state.go b/go/state/state.go
@@ -26,7 +26,7 @@ type State struct {
CacheUseSize uint32 // Currently used bytes by all values in cache
Cache []map[string]string // All loaded cache items
CacheMap map[string]string // Mapped
- Code []byte // Pending bytecode to execute
+ code []byte // Pending bytecode to execute
execPath []string // Command symbols stack
arg *string // Optional argument. Nil if not set.
sizes map[string]uint16 // Size limits for all loaded symbols.
@@ -366,7 +366,7 @@ func(st *State) Check(key string) bool {
return st.frameOf(key) == -1
}
-// Returns size used by values, and remaining size available
+// Size returns size used by values, and remaining size available
func(st *State) Size() (uint32, uint32) {
var l int
var c uint16
@@ -378,6 +378,25 @@ func(st *State) Size() (uint32, uint32) {
return r, uint32(c)-r
}
+// Appendcode adds the given bytecode to the end of the existing code.
+func(st *State) AppendCode(b []byte) error {
+ st.code = append(st.code, b...)
+ log.Printf("code changed to %v", b)
+ return nil
+}
+
+// SetCode replaces the current bytecode with the given bytecode.
+func(st *State) SetCode(b []byte) {
+ log.Printf("code set to %v", b)
+ st.code = b
+}
+
+func(st *State) GetCode() ([]byte, error) {
+ b := st.code
+ st.code = []byte{}
+ return b, nil
+}
+
// return 0-indexed frame number where key is defined. -1 if not defined
func(st *State) frameOf(key string) int {
for i, m := range st.Cache {
@@ -408,4 +427,3 @@ func(st *State) resetCurrent() {
st.sink = nil
st.CacheMap = make(map[string]string)
}
-
diff --git a/go/vm/vm.go b/go/vm/vm.go
@@ -29,34 +29,43 @@ func argFromBytes(input []byte) (string, []byte, error) {
// If the router indicates an argument input, the optional argument is set on the state.
//
// TODO: the bytecode load is a separate step so Run should be run separately.
-func Apply(input []byte, instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func Apply(input []byte, instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
var err error
+ log.Printf("running input %v against instruction %v", input, instruction)
arg, input, err := argFromBytes(input)
if err != nil {
- return st, input, err
+ return input, err
}
- rt := router.FromBytes(input)
+ rt := router.FromBytes(instruction)
sym := rt.Get(arg)
if sym == "" {
sym = rt.Default()
st.PutArg(arg)
- }
+ }
+
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...)
+ instruction, err = rs.GetCode(sym)
+ if err != nil {
+ return instruction, err
+ }
+
+ if sym == "_" {
+ instruction = NewLine([]byte{}, BACK, nil, nil, nil)
+ } else {
+ new_instruction := NewLine([]byte{}, MOVE, []string{sym}, nil, nil)
+ instruction = append(new_instruction, instruction...)
+ }
}
- st, instruction, err = Run(instruction, st, rs, ctx)
+ instruction, err = Run(instruction, st, rs, ctx)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
- return st, instruction, nil
+ return instruction, nil
}
// Run extracts individual op codes and arguments and executes them.
@@ -64,61 +73,54 @@ func Apply(input []byte, instruction []byte, st state.State, rs resource.Resourc
// Each step may update the state.
//
// On error, the remaining instructions will be returned. State will not be rolled back.
-func Run(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func Run(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
var err error
for len(instruction) > 0 {
log.Printf("instruction is now %v", instruction)
op := binary.BigEndian.Uint16(instruction[:2])
if op > _MAX {
- return st, instruction, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX)
+ return instruction, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX)
}
switch op {
case CATCH:
- st, instruction, err = RunCatch(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunCatch(instruction[2:], st, rs, ctx)
case CROAK:
- st, instruction, err = RunCroak(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunCroak(instruction[2:], st, rs, ctx)
case LOAD:
- st, instruction, err = RunLoad(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunLoad(instruction[2:], st, rs, ctx)
case RELOAD:
- st, instruction, err = RunReload(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunReload(instruction[2:], st, rs, ctx)
case MAP:
- st, instruction, err = RunMap(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunMap(instruction[2:], st, rs, ctx)
case MOVE:
- st, instruction, err = RunMove(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunMove(instruction[2:], st, rs, ctx)
case BACK:
- st, instruction, err = RunBack(instruction[2:], st, rs, ctx)
- break
+ instruction, err = RunBack(instruction[2:], st, rs, ctx)
default:
err = fmt.Errorf("Unhandled state: %v", op)
}
if err != nil {
- return st, instruction, err
+ return instruction, err
}
}
- return st, instruction, nil
+ return instruction, nil
}
// RunMap executes the MAP opcode
-func RunMap(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunMap(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
err = st.Map(head)
- return st, tail, err
+ return tail, err
}
// RunMap executes the CATCH opcode
-func RunCatch(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunCatch(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
bitFieldSize := tail[0]
bitField := tail[1:1+bitFieldSize]
@@ -128,69 +130,69 @@ func RunCatch(instruction []byte, st state.State, rs resource.Resource, ctx cont
st.Down(head)
tail = []byte{}
}
- return st, tail, nil
+ return tail, nil
}
// RunMap executes the CROAK opcode
-func RunCroak(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunCroak(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
_ = head
_ = tail
st.Reset()
- return st, []byte{}, nil
+ return []byte{}, nil
}
// RunLoad executes the LOAD opcode
-func RunLoad(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunLoad(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
if !st.Check(head) {
- return st, instruction, fmt.Errorf("key %v already loaded", head)
+ return instruction, fmt.Errorf("key %v already loaded", head)
}
sz := uint16(tail[0])
tail = tail[1:]
r, err := refresh(head, rs, ctx)
if err != nil {
- return st, tail, err
+ return tail, err
}
err = st.Add(head, r, sz)
- return st, tail, err
+ return tail, err
}
// RunLoad executes the RELOAD opcode
-func RunReload(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunReload(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
r, err := refresh(head, rs, ctx)
if err != nil {
- return st, tail, err
+ return tail, err
}
st.Update(head, r)
- return st, tail, nil
+ return tail, nil
}
// RunLoad executes the MOVE opcode
-func RunMove(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunMove(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
head, tail, err := instructionSplit(instruction)
if err != nil {
- return st, instruction, err
+ return instruction, err
}
st.Down(head)
- return st, tail, nil
+ return tail, nil
}
// RunLoad executes the BACK opcode
-func RunBack(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) {
+func RunBack(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
st.Up()
- return st, instruction, nil
+ return instruction, nil
}
// retrieve data for key
@@ -199,6 +201,9 @@ func refresh(key string, rs resource.Resource, ctx context.Context) (string, err
if err != nil {
return "", err
}
+ if fn == nil {
+ return "", fmt.Errorf("no retrieve function for external symbol %v", key)
+ }
return fn(ctx)
}
diff --git a/go/vm/vm_test.go b/go/vm/vm_test.go
@@ -96,17 +96,16 @@ func TestRun(t *testing.T) {
rs := TestResource{}
b := []byte{0x00, MOVE, 0x03}
b = append(b, []byte("foo")...)
- r, _, err := Run(b, st, &rs, context.TODO())
+ _, err := Run(b, &st, &rs, context.TODO())
if err != nil {
t.Errorf("error on valid opcode: %v", err)
}
b = []byte{0x01, 0x02}
- r, _, err = Run(b, st, &rs, context.TODO())
+ _, err = Run(b, &st, &rs, context.TODO())
if err == nil {
t.Errorf("no error on invalid opcode")
}
- _ = r
}
func TestRunLoadRender(t *testing.T) {
@@ -117,7 +116,7 @@ func TestRunLoadRender(t *testing.T) {
ins := append([]byte{uint8(len(sym))}, []byte(sym)...)
ins = append(ins, 0x0a)
var err error
- st, _, err = RunLoad(ins, st, &rs, context.TODO())
+ _, err = RunLoad(ins, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -142,7 +141,7 @@ func TestRunLoadRender(t *testing.T) {
sym = "two"
ins = append([]byte{uint8(len(sym))}, []byte(sym)...)
ins = append(ins, 0)
- st, _, err = RunLoad(ins, st, &rs, context.TODO())
+ _, err = RunLoad(ins, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -166,7 +165,7 @@ func TestRunMultiple(t *testing.T) {
b := []byte{}
b = NewLine(b, LOAD, []string{"one"}, nil, []uint8{0})
b = NewLine(b, LOAD, []string{"two"}, nil, []uint8{42})
- st, _, err := Run(b, st, &rs, context.TODO())
+ _, err := Run(b, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -178,7 +177,7 @@ func TestRunReload(t *testing.T) {
b := []byte{}
b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0})
b = NewLine(b, MAP, []string{"dyn"}, nil, nil)
- st, _, err := Run(b, st, &rs, context.TODO())
+ _, err := Run(b, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -192,7 +191,7 @@ func TestRunReload(t *testing.T) {
dynVal = "baz"
b = []byte{}
b = NewLine(b, RELOAD, []string{"dyn"}, nil, nil)
- st, _, err = Run(b, st, &rs, context.TODO())
+ _, err = Run(b, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -209,14 +208,15 @@ func TestRunReload(t *testing.T) {
func TestRunArg(t *testing.T) {
st := state.NewState(5)
+ rs := TestResource{}
rt := router.NewRouter()
rt.Add("foo", "bar")
rt.Add("baz", "xyzzy")
b := []byte{0x03}
b = append(b, []byte("baz")...)
- b = append(b, rt.ToBytes()...)
+ //b = append(b, rt.ToBytes()...)
var err error
- st, b, err = Apply(b, []byte{}, st, nil, context.TODO())
+ b, err = Apply(b, rt.ToBytes(), &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -237,9 +237,9 @@ func TestRunArgInvalid(t *testing.T) {
rt.Add("baz", "xyzzy")
b := []byte{0x03}
b = append(b, []byte("bar")...)
- b = append(b, rt.ToBytes()...)
+ //b = append(b, rt.ToBytes()...)
var err error
- st, b, err = Apply(b, []byte{}, st, nil, context.TODO())
+ b, err = Apply(b, rt.ToBytes(), &st, nil, context.TODO())
if err != nil {
t.Error(err)
}
@@ -253,97 +253,108 @@ func TestRunArgInvalid(t *testing.T) {
}
}
-func TestRunArgInstructions(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})
- bi = NewLine(bi, LOAD, []string{"two"}, nil, []uint8{3})
- bi = NewLine(bi, MAP, []string{"one"}, nil, nil)
- bi = NewLine(bi, MAP, []string{"two"}, nil, nil)
- 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)
- }
- loc := st.Where()
- if loc != "bar" {
- t.Errorf("expected where-state _catch, got %v", loc)
- }
- m, err := st.Get()
- if err != nil {
- t.Error(err)
- }
- r, err := rs.RenderTemplate(loc, m)
- if err != nil {
- t.Error(err)
- }
- _ = 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)
- }
-}
+//func TestRunArgInstructions(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})
+// bi = NewLine(bi, LOAD, []string{"two"}, nil, []uint8{3})
+// bi = NewLine(bi, MAP, []string{"one"}, nil, nil)
+// bi = NewLine(bi, MAP, []string{"two"}, nil, nil)
+// var err error
+// 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)
+// }
+// loc := st.Where()
+// if loc != "bar" {
+// t.Errorf("expected where-state bar, got %v", loc)
+// }
+// m, err := st.Get()
+// if err != nil {
+// t.Fatal(err)
+// }
+// _, err = rs.RenderTemplate(loc, m)
+// if err == nil {
+// t.Fatalf("expected error to generate template")
+// }
+// _, err = Run(bi, &st, &rs, context.TODO())
+// if err != nil {
+// t.Error(err)
+// }
+// m, err = st.Get()
+// if err != nil {
+// t.Fatal(err)
+// }
+// _, err = rs.RenderTemplate(loc, m)
+// if err != nil {
+// t.Fatal(err)
+// }
+//}
+//
+//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
+// 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})
+// 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()...)
+// b, err = Apply(b, rt.ToBytes(), &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)
+// }
+//}
func TestCatchAndBack(t *testing.T) {
st := state.NewState(5)
@@ -353,7 +364,7 @@ func TestCatchAndBack(t *testing.T) {
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())
+ _, err := Run(b, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}
@@ -366,7 +377,7 @@ func TestCatchAndBack(t *testing.T) {
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())
+ _, err = Run(b, &st, &rs, context.TODO())
if err != nil {
t.Error(err)
}