WIP correct entry point in persisted runner
This commit is contained in:
parent
28cbe308d4
commit
59dcb7875d
@ -43,7 +43,8 @@ func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memor
|
|||||||
ca: ca,
|
ca: ca,
|
||||||
vm: vm.NewVm(st, rs, ca, szr),
|
vm: vm.NewVm(st, rs, ca, szr),
|
||||||
}
|
}
|
||||||
if cfg.Root != "" {
|
//if cfg.Root != "" {
|
||||||
|
if st.Moves == 0 {
|
||||||
engine.Init(cfg.Root, ctx)
|
engine.Init(cfg.Root, ctx)
|
||||||
}
|
}
|
||||||
return engine
|
return engine
|
||||||
@ -65,10 +66,12 @@ func(en *Engine) Init(sym string, ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil)
|
b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil)
|
||||||
|
log.Printf("start new init VM run with code %x", b)
|
||||||
b, err = en.vm.Run(b, ctx)
|
b, err = en.vm.Run(b, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log.Printf("ended init VM run with code %x", b)
|
||||||
en.st.SetCode(b)
|
en.st.SetCode(b)
|
||||||
en.initd = true
|
en.initd = true
|
||||||
return nil
|
return nil
|
||||||
@ -102,10 +105,12 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
|||||||
if len(code) == 0 {
|
if len(code) == 0 {
|
||||||
return false, fmt.Errorf("no code to execute")
|
return false, fmt.Errorf("no code to execute")
|
||||||
}
|
}
|
||||||
|
log.Printf("start new VM run with code %x", code)
|
||||||
code, err = en.vm.Run(code, ctx)
|
code, err = en.vm.Run(code, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
log.Printf("ended VM run with code %x", code)
|
||||||
|
|
||||||
v, err := en.st.MatchFlag(state.FLAG_TERMINATE, false)
|
v, err := en.st.MatchFlag(state.FLAG_TERMINATE, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -133,11 +138,10 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
|||||||
// - required data inputs to the template are not available.
|
// - required data inputs to the template are not available.
|
||||||
// - the template for the given node point is note available for retrieval using the resource.Resource implementer.
|
// - the template for the given node point is note available for retrieval using the resource.Resource implementer.
|
||||||
// - the supplied writer fails to process the writes.
|
// - the supplied writer fails to process the writes.
|
||||||
func(en *Engine) WriteResult(w io.Writer, ctx context.Context) error {
|
func(en *Engine) WriteResult(w io.Writer, ctx context.Context) (int, error) {
|
||||||
r, err := en.vm.Render(ctx)
|
r, err := en.vm.Render(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
_, err = io.WriteString(w, r)
|
return io.WriteString(w, r)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,14 @@ type FsWrapper struct {
|
|||||||
|
|
||||||
func NewFsWrapper(path string, st *state.State) FsWrapper {
|
func NewFsWrapper(path string, st *state.State) FsWrapper {
|
||||||
rs := resource.NewFsResource(path)
|
rs := resource.NewFsResource(path)
|
||||||
return FsWrapper {
|
wr := FsWrapper {
|
||||||
&rs,
|
&rs,
|
||||||
st,
|
st,
|
||||||
}
|
}
|
||||||
|
wr.AddLocalFunc("one", wr.one)
|
||||||
|
wr.AddLocalFunc("inky", wr.inky)
|
||||||
|
wr.AddLocalFunc("pinky", wr.pinky)
|
||||||
|
return wr
|
||||||
}
|
}
|
||||||
|
|
||||||
func(fs FsWrapper) one(sym string, input []byte, ctx context.Context) (resource.Result, error) {
|
func(fs FsWrapper) one(sym string, input []byte, ctx context.Context) (resource.Result, error) {
|
||||||
@ -51,18 +55,6 @@ func(fs FsWrapper) pinky(sym string, input []byte, ctx context.Context) (resourc
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func(fs FsWrapper) FuncFor(sym string) (resource.EntryFunc, error) {
|
|
||||||
switch sym {
|
|
||||||
case "one":
|
|
||||||
return fs.one, nil
|
|
||||||
case "inky":
|
|
||||||
return fs.inky, nil
|
|
||||||
case "pinky":
|
|
||||||
return fs.pinky, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("function for %v not found", sym)
|
|
||||||
}
|
|
||||||
|
|
||||||
func(fs FsWrapper) GetCode(sym string) ([]byte, error) {
|
func(fs FsWrapper) GetCode(sym string) ([]byte, error) {
|
||||||
sym += ".bin"
|
sym += ".bin"
|
||||||
fp := path.Join(fs.Path, sym)
|
fp := path.Join(fs.Path, sym)
|
||||||
@ -82,20 +74,19 @@ func generateTestData(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEngineInit(t *testing.T) {
|
func TestEngineInit(t *testing.T) {
|
||||||
|
var err error
|
||||||
generateTestData(t)
|
generateTestData(t)
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
st := state.NewState(17)
|
st := state.NewState(17)
|
||||||
rs := NewFsWrapper(dataDir, &st)
|
rs := NewFsWrapper(dataDir, &st)
|
||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
|
|
||||||
en := NewEngine(Config{}, &st, &rs, ca, ctx)
|
en := NewEngine(Config{
|
||||||
err := en.Init("root", ctx)
|
Root: "root",
|
||||||
if err != nil {
|
}, &st, &rs, ca, ctx)
|
||||||
t.Fatal(err)
|
//
|
||||||
}
|
|
||||||
|
|
||||||
w := bytes.NewBuffer(nil)
|
w := bytes.NewBuffer(nil)
|
||||||
err = en.WriteResult(w, ctx)
|
_, err = en.WriteResult(w, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -118,7 +109,7 @@ func TestEngineInit(t *testing.T) {
|
|||||||
t.Fatalf("expected where-string 'foo', got %s", r)
|
t.Fatalf("expected where-string 'foo', got %s", r)
|
||||||
}
|
}
|
||||||
w = bytes.NewBuffer(nil)
|
w = bytes.NewBuffer(nil)
|
||||||
err = en.WriteResult(w, ctx)
|
_, err = en.WriteResult(w, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ import (
|
|||||||
//
|
//
|
||||||
// Rendered output is written to the provided writer.
|
// Rendered output is written to the provided writer.
|
||||||
func Loop(en *Engine, reader io.Reader, writer io.Writer, ctx context.Context) error {
|
func Loop(en *Engine, reader io.Reader, writer io.Writer, ctx context.Context) error {
|
||||||
err := en.WriteResult(writer, ctx)
|
var err error
|
||||||
|
_, err = en.WriteResult(writer, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -41,7 +42,7 @@ func Loop(en *Engine, reader io.Reader, writer io.Writer, ctx context.Context) e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unexpected termination: %v\n", err)
|
return fmt.Errorf("unexpected termination: %v\n", err)
|
||||||
}
|
}
|
||||||
err = en.WriteResult(writer, ctx)
|
_, err = en.WriteResult(writer, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,43 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
st := pr.GetState()
|
st := pr.GetState()
|
||||||
log.Printf("st %v", st)
|
location, idx := st.Where()
|
||||||
|
if location != "" {
|
||||||
|
cfg.Root = location
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("run persisted with state %v %x input %s", st, st.Code, input)
|
||||||
en := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx)
|
en := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx)
|
||||||
|
|
||||||
if len(input) > 0 {
|
log.Printf("location %s", location)
|
||||||
|
|
||||||
|
// if len(input) == 0 {
|
||||||
|
// log.Printf("init")
|
||||||
|
// err = en.Init(location, ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
c, err := en.WriteResult(w, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = pr.Save(cfg.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("engine init write %v flags %v", c, st.Flags)
|
||||||
|
if c > 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = idx
|
||||||
|
|
||||||
_, err = en.Exec(input, ctx)
|
_, err = en.Exec(input, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = en.WriteResult(w, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return en.WriteResult(w, ctx)
|
return pr.Save(cfg.SessionId)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
// "bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
// "errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
@ -16,7 +16,7 @@ import (
|
|||||||
func TestPersist(t *testing.T) {
|
func TestPersist(t *testing.T) {
|
||||||
generateTestData(t)
|
generateTestData(t)
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
OutputSize: 128,
|
OutputSize: 83,
|
||||||
SessionId: "xyzzy",
|
SessionId: "xyzzy",
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}
|
}
|
||||||
@ -31,26 +31,18 @@ func TestPersist(t *testing.T) {
|
|||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
pr := persist.NewFsPersister(persistDir).WithContent(&st, ca)
|
pr := persist.NewFsPersister(persistDir).WithContent(&st, ca)
|
||||||
|
|
||||||
w := bytes.NewBuffer(nil)
|
//w := bytes.NewBuffer(nil)
|
||||||
|
w := os.Stdout
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
st = state.NewState(cfg.FlagCount)
|
||||||
err = RunPersisted(cfg, rs, pr, []byte{}, w, ctx)
|
ca = cache.NewCache()
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
st := state.NewState(cfg.FlagCount)
|
|
||||||
ca := cache.NewCache()
|
|
||||||
if cfg.CacheSize > 0 {
|
|
||||||
ca = ca.WithCacheSize(cfg.CacheSize)
|
ca = ca.WithCacheSize(cfg.CacheSize)
|
||||||
}
|
|
||||||
pr = persist.NewFsPersister(persistDir).WithContent(&st, ca)
|
pr = persist.NewFsPersister(persistDir).WithContent(&st, ca)
|
||||||
err = pr.Save(cfg.SessionId)
|
err = pr.Save(cfg.SessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pr = persist.NewFsPersister(persistDir)
|
pr = persist.NewFsPersister(persistDir)
|
||||||
inputs := []string{
|
inputs := []string{
|
||||||
@ -65,4 +57,20 @@ func TestPersist(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr = persist.NewFsPersister(persistDir)
|
||||||
|
err = pr.Load(cfg.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stAfter := pr.GetState()
|
||||||
|
location, idx := stAfter.Where()
|
||||||
|
if location != "long" {
|
||||||
|
t.Fatalf("expected 'long', got %s", location)
|
||||||
|
}
|
||||||
|
if idx != 1 {
|
||||||
|
t.Fatalf("expected '1', got %v", idx)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func(p *FsPersister) Save(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fp := path.Join(p.dir, key)
|
fp := path.Join(p.dir, key)
|
||||||
log.Printf("saved key %v", key)
|
log.Printf("saved key %v state %x", key, p.State.Code)
|
||||||
return ioutil.WriteFile(fp, b, 0600)
|
return ioutil.WriteFile(fp, b, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +80,6 @@ func(p *FsPersister) Load(key string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = p.Deserialize(b)
|
err = p.Deserialize(b)
|
||||||
log.Printf("loaded key %v", key)
|
log.Printf("loaded key %v state %x", key, p.State.Code)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,13 @@ func(fs FsResource) GetCode(sym string) ([]byte, error) {
|
|||||||
return ioutil.ReadFile(fp)
|
return ioutil.ReadFile(fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func(fs *FsResource) AddLocalFunc(sym string, fn EntryFunc) {
|
||||||
|
if fs.fns == nil {
|
||||||
|
fs.fns = make(map[string]EntryFunc)
|
||||||
|
}
|
||||||
|
fs.fns[sym] = fn
|
||||||
|
}
|
||||||
|
|
||||||
func(fs FsResource) FuncFor(sym string) (EntryFunc, error) {
|
func(fs FsResource) FuncFor(sym string) (EntryFunc, error) {
|
||||||
fn, ok := fs.fns[sym]
|
fn, ok := fs.fns[sym]
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -34,6 +34,7 @@ type State struct {
|
|||||||
BitSize uint32 // size of (32-bit capacity) bit flag byte array
|
BitSize uint32 // size of (32-bit capacity) bit flag byte array
|
||||||
SizeIdx uint16
|
SizeIdx uint16
|
||||||
Flags []byte // Error state
|
Flags []byte // Error state
|
||||||
|
Moves uint32 // Number of times navigation has been performed
|
||||||
input []byte // Last input
|
input []byte // Last input
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +209,7 @@ func(st *State) Next() (uint16, error) {
|
|||||||
st.SizeIdx += 1
|
st.SizeIdx += 1
|
||||||
s, idx := st.Where()
|
s, idx := st.Where()
|
||||||
log.Printf("next page for %s: %v", s, idx)
|
log.Printf("next page for %s: %v", s, idx)
|
||||||
|
st.Moves += 1
|
||||||
return st.SizeIdx, nil
|
return st.SizeIdx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +226,7 @@ func(st *State) Previous() (uint16, error) {
|
|||||||
st.SizeIdx -= 1
|
st.SizeIdx -= 1
|
||||||
s, idx := st.Where()
|
s, idx := st.Where()
|
||||||
log.Printf("previous page for %s: %v", s, idx)
|
log.Printf("previous page for %s: %v", s, idx)
|
||||||
|
st.Moves += 1
|
||||||
return st.SizeIdx, nil
|
return st.SizeIdx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +261,7 @@ func(st *State) Top() (bool, error) {
|
|||||||
func(st *State) Down(input string) error {
|
func(st *State) Down(input string) error {
|
||||||
st.ExecPath = append(st.ExecPath, input)
|
st.ExecPath = append(st.ExecPath, input)
|
||||||
st.SizeIdx = 0
|
st.SizeIdx = 0
|
||||||
|
st.Moves += 1
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +285,7 @@ func(st *State) Up() (string, error) {
|
|||||||
}
|
}
|
||||||
st.SizeIdx = 0
|
st.SizeIdx = 0
|
||||||
log.Printf("execpath after %v", st.ExecPath)
|
log.Printf("execpath after %v", st.ExecPath)
|
||||||
|
st.Moves += 1
|
||||||
return sym, nil
|
return sym, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,5 +337,5 @@ func(st *State) Reset() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func(st State) String() string {
|
func(st State) String() string {
|
||||||
return fmt.Sprintf("idx %v path: %s", st.SizeIdx, strings.Join(st.ExecPath, "/"))
|
return fmt.Sprintf("moves %v idx %v path: %s", st.Moves, st.SizeIdx, strings.Join(st.ExecPath, "/"))
|
||||||
}
|
}
|
||||||
|
@ -182,10 +182,10 @@ func(vm *Vm) RunCatch(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
b = append(bh, b...)
|
||||||
vm.st.Down(sym)
|
vm.st.Down(sym)
|
||||||
vm.ca.Push()
|
vm.ca.Push()
|
||||||
vm.Reset()
|
vm.Reset()
|
||||||
b = append(bh, b...)
|
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
@ -292,6 +292,7 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
log.Printf("ignoring input %s, already have match", sym)
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +408,7 @@ func(vm *Vm) Render(ctx context.Context) (string, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if !changed {
|
if !changed {
|
||||||
log.Printf("Render called when not dirty, please investigate.")
|
return "", nil
|
||||||
}
|
}
|
||||||
sym, idx := vm.st.Where()
|
sym, idx := vm.st.Where()
|
||||||
r, err := vm.pg.Render(sym, idx)
|
r, err := vm.pg.Render(sym, idx)
|
||||||
|
Loading…
Reference in New Issue
Block a user