go-vise

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

commit 6b9a2c868952b4726f78546d9d9bab895b1cd695
parent 6f39c23163df336178c914d8b62e66452d345804
Author: lash <dev@holbrook.no>
Date:   Sun, 23 Apr 2023 11:35:14 +0100

Move context to first arg everywhere

Diffstat:
Mdev/interactive/main.go | 4++--
Mengine/default.go | 12++++++------
Mengine/engine.go | 18+++++++++---------
Mengine/engine_test.go | 60++++++++++++++++++++++++++++++++----------------------------
Mengine/loop.go | 8++++----
Mengine/loop_test.go | 12++++++------
Mengine/persist.go | 18++++++++++--------
Mengine/persist_test.go | 12++++++------
Mexamples/profile/main.go | 8++++----
Mexamples/session/main.go | 6+++---
Mexamples/validate/main.go | 8++++----
Mrender/page.go | 18+++++++++---------
Mrender/page_test.go | 2+-
Mrender/size_test.go | 163+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mresource/fs.go | 4++--
Mresource/fs_test.go | 6+++---
Mresource/mem.go | 2+-
Mresource/mem_test.go | 8++++----
Mresource/resource.go | 10+++++-----
Mresource/resource_test.go | 42++++++++++++++----------------------------
Mvm/runner.go | 62+++++++++++++++++++++++++++++++-------------------------------
Mvm/runner_test.go | 162+++++++++++++++++++++++++++++++++++++++++--------------------------------------
22 files changed, 342 insertions(+), 303 deletions(-)

diff --git a/dev/interactive/main.go b/dev/interactive/main.go @@ -35,7 +35,7 @@ func main() { os.Exit(1) } if !cont { - _, err = en.WriteResult(os.Stdout, ctx) + _, err = en.WriteResult(ctx, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "dead init write error: %v\n", err) os.Exit(1) @@ -43,7 +43,7 @@ func main() { os.Stdout.Write([]byte{0x0a}) os.Exit(0) } - err = engine.Loop(en, os.Stdin, os.Stdout, ctx) + err = engine.Loop(ctx, en, os.Stdin, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) os.Exit(1) diff --git a/engine/default.go b/engine/default.go @@ -35,7 +35,7 @@ func NewDefaultEngine(dir string, persisted bool, session *string) (EngineIsh, e return nil, err } pr := persist.NewFsPersister(dp) - en, err = NewPersistedEngine(cfg, pr, &rs, ctx) + en, err = NewPersistedEngine(ctx, cfg, pr, &rs) if err != nil { Logg.Infof("persisted engine create error. trying again with persisting empty state first...") pr = pr.WithContent(&st, ca) @@ -43,10 +43,10 @@ func NewDefaultEngine(dir string, persisted bool, session *string) (EngineIsh, e if err != nil { return nil, err } - en, err = NewPersistedEngine(cfg, pr, &rs, ctx) + en, err = NewPersistedEngine(ctx, cfg, pr, &rs) } } else { - enb := NewEngine(cfg, &st, &rs, ca, ctx) + enb := NewEngine(ctx, cfg, &st, &rs, ca) en = &enb } return en, err @@ -76,7 +76,7 @@ func NewSizedEngine(dir string, size uint32, persisted bool, session *string) (E return nil, err } pr := persist.NewFsPersister(dp) - en, err = NewPersistedEngine(cfg, pr, &rs, ctx) + en, err = NewPersistedEngine(ctx, cfg, pr, &rs) if err != nil { Logg.Infof("persisted engine create error. trying again with persisting empty state first...") pr = pr.WithContent(&st, ca) @@ -84,10 +84,10 @@ func NewSizedEngine(dir string, size uint32, persisted bool, session *string) (E if err != nil { return nil, err } - en, err = NewPersistedEngine(cfg, pr, &rs, ctx) + en, err = NewPersistedEngine(ctx, cfg, pr, &rs) } } else { - enb := NewEngine(cfg, &st, &rs, ca, ctx) + enb := NewEngine(ctx, cfg, &st, &rs, ca) en = &enb } return en, err diff --git a/engine/engine.go b/engine/engine.go @@ -15,8 +15,8 @@ import ( // EngineIsh defines the interface for execution engines that handle vm initialization and execution, and rendering outputs. type EngineIsh interface { Init(ctx context.Context) (bool, error) - Exec(input []byte, ctx context.Context) (bool, error) - WriteResult(w io.Writer, ctx context.Context) (int, error) + Exec(ctx context.Context, input []byte) (bool, error) + WriteResult(ctx context.Context, w io.Writer) (int, error) Finish() error } @@ -42,7 +42,7 @@ type Engine struct { } // NewEngine creates a new Engine -func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memory, ctx context.Context) Engine { +func NewEngine(ctx context.Context, cfg Config, st *state.State, rs resource.Resource, ca cache.Memory) Engine { var szr *render.Sizer if cfg.OutputSize > 0 { szr = render.NewSizer(cfg.OutputSize) @@ -113,7 +113,7 @@ func(en *Engine) Init(ctx context.Context) (bool, error) { } b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil) Logg.DebugCtxf(ctx, "start new init VM run", "code", b) - b, err = en.vm.Run(b, ctx) + b, err = en.vm.Run(ctx, b) if err != nil { return false, err } @@ -137,7 +137,7 @@ func(en *Engine) Init(ctx context.Context) (bool, error) { // - input is formally invalid (too long etc) // - no current bytecode is available // - input processing against bytcode failed -func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) { +func (en *Engine) Exec(ctx context.Context, input []byte) (bool, error) { var err error if en.st.Language != nil { ctx = context.WithValue(ctx, "Language", *en.st.Language) @@ -157,11 +157,11 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) { if err != nil { return false, err } - return en.exec(input, ctx) + return en.exec(ctx, input) } // backend for Exec, after the input validity check -func(en *Engine) exec(input []byte, ctx context.Context) (bool, error) { +func(en *Engine) exec(ctx context.Context, input []byte) (bool, error) { Logg.InfoCtxf(ctx, "new VM execution with input", "input", string(input)) code, err := en.st.GetCode() if err != nil { @@ -172,7 +172,7 @@ func(en *Engine) exec(input []byte, ctx context.Context) (bool, error) { } Logg.Debugf("start new VM run", "code", code) - code, err = en.vm.Run(code, ctx) + code, err = en.vm.Run(ctx, code) if err != nil { return false, err } @@ -204,7 +204,7 @@ func(en *Engine) exec(input []byte, ctx context.Context) (bool, error) { // - 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 supplied writer fails to process the writes. -func(en *Engine) WriteResult(w io.Writer, ctx context.Context) (int, error) { +func(en *Engine) WriteResult(ctx context.Context, w io.Writer) (int, error) { if en.st.Language != nil { ctx = context.WithValue(ctx, "Language", *en.st.Language) } diff --git a/engine/engine_test.go b/engine/engine_test.go @@ -40,26 +40,26 @@ func NewFsWrapper(path string, st *state.State) FsWrapper { return wr } -func(fs FsWrapper) one(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(fs FsWrapper) one(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: "one", }, nil } -func(fs FsWrapper) inky(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(fs FsWrapper) inky(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: "tinkywinky", }, nil } -func(fs FsWrapper) pinky(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(fs FsWrapper) pinky(ctx context.Context, sym string, input []byte) (resource.Result, error) { r := fmt.Sprintf("xyzzy: %x", input) return resource.Result{ Content: r, }, nil } -func(fs FsWrapper) translate(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(fs FsWrapper) translate(ctx context.Context, sym string, input []byte) (resource.Result, error) { r := "cool" v := ctx.Value("Language") code := "" @@ -75,7 +75,7 @@ func(fs FsWrapper) translate(sym string, input []byte, ctx context.Context) (res }, nil } -func(fs FsWrapper) set_lang(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(fs FsWrapper) set_lang(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: string(input), FlagSet: []uint32{state.FLAG_LANG}, @@ -107,17 +107,18 @@ func TestEngineInit(t *testing.T) { st := state.NewState(17) rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - - en := NewEngine(Config{ + + cfg := Config{ Root: "root", - }, &st, &rs, ca, ctx) + } + en := NewEngine(ctx, cfg, &st, &rs, ca) _, err = en.Init(ctx) if err != nil { t.Fatal(err) } w := bytes.NewBuffer(nil) - _, err = en.WriteResult(w, ctx) + _, err = en.WriteResult(ctx, w) if err != nil { t.Fatal(err) } @@ -132,7 +133,7 @@ func TestEngineInit(t *testing.T) { } input := []byte("1") - _, err = en.Exec(input, ctx) + _, err = en.Exec(ctx, input) if err != nil { t.Fatal(err) } @@ -141,7 +142,7 @@ func TestEngineInit(t *testing.T) { t.Fatalf("expected where-string 'foo', got %s", r) } w = bytes.NewBuffer(nil) - _, err = en.WriteResult(w, ctx) + _, err = en.WriteResult(ctx, w) if err != nil { t.Fatal(err) } @@ -165,16 +166,16 @@ func TestEngineExecInvalidInput(t *testing.T) { rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - - en := NewEngine(Config{ + cfg := Config{ Root: "root", - }, &st, &rs, ca, ctx) + } + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) if err != nil { t.Fatal(err) } - _, err = en.Exec([]byte("_foo"), ctx) + _, err = en.Exec(ctx, []byte("_foo")) if err == nil { t.Fatalf("expected fail on invalid input") } @@ -186,22 +187,23 @@ func TestEngineResumeTerminated(t *testing.T) { st := state.NewState(17) rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - - en := NewEngine(Config{ + + cfg := Config{ Root: "root", - }, &st, &rs, ca, ctx) + } + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) if err != nil { t.Fatal(err) } - _, err = en.Exec([]byte("1"), ctx) + _, err = en.Exec(ctx, []byte("1")) if err != nil { t.Fatal(err) } - _, err = en.Exec([]byte("1"), ctx) + _, err = en.Exec(ctx, []byte("1")) if err != nil { t.Fatal(err) } @@ -222,9 +224,10 @@ func TestLanguageSet(t *testing.T) { rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - en := NewEngine(Config{ + cfg := Config{ Root: "root", - }, &st, &rs, ca, ctx) + } + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) @@ -237,7 +240,7 @@ func TestLanguageSet(t *testing.T) { b = vm.NewLine(b, vm.MOVE, []string{"."}, nil, nil) st.SetCode(b) - _, err = en.Exec([]byte("no"), ctx) + _, err = en.Exec(ctx, []byte("no")) if err != nil { t.Fatal(err) } @@ -254,7 +257,7 @@ func TestLanguageSet(t *testing.T) { b = vm.NewLine(b, vm.MOVE, []string{"."}, nil, nil) st.SetCode(b) - _, err = en.Exec([]byte("no"), ctx) + _, err = en.Exec(ctx, []byte("no")) if err != nil { t.Fatal(err) } @@ -274,9 +277,10 @@ func TestLanguageRender(t *testing.T) { rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache() - en := NewEngine(Config{ + cfg := Config{ Root: "root", - }, &st, &rs, ca, ctx) + } + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) @@ -289,13 +293,13 @@ func TestLanguageRender(t *testing.T) { b = vm.NewLine(b, vm.MOVE, []string{"lang"}, nil, nil) st.SetCode(b) - _, err = en.Exec([]byte("nor"), ctx) + _, err = en.Exec(ctx, []byte("nor")) if err != nil { t.Fatal(err) } br := bytes.NewBuffer(nil) - _, err = en.WriteResult(br, ctx) + _, err = en.WriteResult(ctx, br) if err != nil { t.Fatal(err) } diff --git a/engine/loop.go b/engine/loop.go @@ -17,10 +17,10 @@ import ( // Any error not handled by the engine will terminate the oop and return an error. // // Rendered output is written to the provided writer. -func Loop(en EngineIsh, reader io.Reader, writer io.Writer, ctx context.Context) error { +func Loop(ctx context.Context, en EngineIsh, reader io.Reader, writer io.Writer) error { defer en.Finish() var err error - _, err = en.WriteResult(writer, ctx) + _, err = en.WriteResult(ctx, writer) if err != nil { return err } @@ -38,11 +38,11 @@ func Loop(en EngineIsh, reader io.Reader, writer io.Writer, ctx context.Context) return fmt.Errorf("cannot read input: %v\n", err) } in = strings.TrimSpace(in) - running, err = en.Exec([]byte(in), ctx) + running, err = en.Exec(ctx, []byte(in)) if err != nil { return fmt.Errorf("unexpected termination: %v\n", err) } - _, err = en.WriteResult(writer, ctx) + _, err = en.WriteResult(ctx, writer) if err != nil { return err } diff --git a/engine/loop_test.go b/engine/loop_test.go @@ -23,7 +23,7 @@ func TestLoopTop(t *testing.T) { cfg := Config{ Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) if err != nil { @@ -40,7 +40,7 @@ func TestLoopTop(t *testing.T) { outputBuf := bytes.NewBuffer(nil) log.Printf("running with input: %s", inputBuf.Bytes()) - err = Loop(&en, inputBuf, outputBuf, ctx) + err = Loop(ctx, &en, inputBuf, outputBuf) if err != nil { t.Fatal(err) } @@ -60,7 +60,7 @@ func TestLoopBackForth(t *testing.T) { cfg := Config{ Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) if err != nil { @@ -78,7 +78,7 @@ func TestLoopBackForth(t *testing.T) { outputBuf := bytes.NewBuffer(nil) log.Printf("running with input: %s", inputBuf.Bytes()) - err = Loop(&en, inputBuf, outputBuf, ctx) + err = Loop(ctx, &en, inputBuf, outputBuf) if err != nil { t.Fatal(err) } @@ -95,7 +95,7 @@ func TestLoopBrowse(t *testing.T) { OutputSize: 68, Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) + en := NewEngine(ctx, cfg, &st, &rs, ca) var err error _, err = en.Init(ctx) if err != nil { @@ -114,7 +114,7 @@ func TestLoopBrowse(t *testing.T) { outputBuf := bytes.NewBuffer(nil) log.Printf("running with input: %s", inputBuf.Bytes()) - err = Loop(&en, inputBuf, outputBuf, ctx) + err = Loop(ctx, &en, inputBuf, outputBuf) if err != nil { t.Fatal(err) } diff --git a/engine/persist.go b/engine/persist.go @@ -16,7 +16,7 @@ type PersistedEngine struct { // NewPersistedEngine creates a new PersistedEngine -func NewPersistedEngine(cfg Config, pr persist.Persister, rs resource.Resource, ctx context.Context) (PersistedEngine, error) { +func NewPersistedEngine(ctx context.Context, cfg Config, pr persist.Persister, rs resource.Resource) (PersistedEngine, error) { err := pr.Load(cfg.SessionId) if err != nil { return PersistedEngine{}, err @@ -24,7 +24,7 @@ func NewPersistedEngine(cfg Config, pr persist.Persister, rs resource.Resource, st := pr.GetState() ca := pr.GetMemory() - enb := NewEngine(cfg, st, rs, ca, ctx) + enb := NewEngine(ctx, cfg, st, rs, ca) en := PersistedEngine{ &enb, pr, @@ -33,8 +33,8 @@ func NewPersistedEngine(cfg Config, pr persist.Persister, rs resource.Resource, } // Exec executes the parent method Engine.Exec, and afterwards persists the new state. -func(pe PersistedEngine) Exec(input []byte, ctx context.Context) (bool, error) { - v, err := pe.Engine.Exec(input, ctx) +func(pe PersistedEngine) Exec(ctx context.Context, input []byte) (bool, error) { + v, err := pe.Engine.Exec(ctx, input) if err != nil { return v, err } @@ -64,9 +64,11 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input return err } - en := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx) + st := pr.GetState() + ca := pr.GetMemory() + en := NewEngine(ctx, cfg, st, rs, ca) - c, err := en.WriteResult(w, ctx) + c, err := en.WriteResult(ctx, w) if err != nil { return err } @@ -78,11 +80,11 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input return err } - _, err = en.Exec(input, ctx) + _, err = en.Exec(ctx, input) if err != nil { return err } - _, err = en.WriteResult(w, ctx) + _, err = en.WriteResult(ctx, w) if err != nil { return err } diff --git a/engine/persist_test.go b/engine/persist_test.go @@ -101,7 +101,7 @@ func TestEnginePersist(t *testing.T) { t.Fatal(err) } - en, err := NewPersistedEngine(cfg, pr, rs, ctx) + en, err := NewPersistedEngine(ctx, cfg, pr, rs) if err != nil { t.Fatal(err) } @@ -111,16 +111,16 @@ func TestEnginePersist(t *testing.T) { t.Fatal(err) } - _, err = en.Exec([]byte("1"), ctx) + _, err = en.Exec(ctx, []byte("1")) if err != nil { t.Fatal(err) } - _, err = en.Exec([]byte("2"), ctx) + _, err = en.Exec(ctx, []byte("2")) if err != nil { t.Fatal(err) } - _, err = en.Exec([]byte("00"), ctx) + _, err = en.Exec(ctx, []byte("00")) if err != nil { t.Fatal(err) } @@ -133,7 +133,7 @@ func TestEnginePersist(t *testing.T) { } pr = persist.NewFsPersister(persistDir) - en, err = NewPersistedEngine(cfg, pr, rs, ctx) + en, err = NewPersistedEngine(ctx, cfg, pr, rs) if err != nil { t.Fatal(err) } @@ -146,7 +146,7 @@ func TestEnginePersist(t *testing.T) { t.Fatalf("expected index '1', got %v", idx) } - _, err = en.Exec([]byte("11"), ctx) + _, err = en.Exec(ctx, []byte("11")) if err != nil { t.Fatal(err) } diff --git a/examples/profile/main.go b/examples/profile/main.go @@ -66,7 +66,7 @@ func(pr *profileResource) checkEntry() error { return nil } -func(pr profileResource) nameSave(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(pr profileResource) nameSave(ctx context.Context, sym string, input []byte) (resource.Result, error) { log.Printf("writing name to file") fp := path.Join(scriptDir, "myname.txt") err := ioutil.WriteFile(fp, input, 0600) @@ -83,7 +83,7 @@ func(pr profileResource) nameSave(sym string, input []byte, ctx context.Context) return emptyResult, err } -func(pr profileResource) emailSave(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(pr profileResource) emailSave(ctx context.Context, sym string, input []byte) (resource.Result, error) { log.Printf("writing email to file") fp := path.Join(scriptDir, "myemail.txt") err := ioutil.WriteFile(fp, input, 0600) @@ -126,7 +126,7 @@ func main() { OutputSize: uint32(size), } ctx := context.Background() - en := engine.NewEngine(cfg, &st, rs, ca, ctx) + en := engine.NewEngine(ctx, cfg, &st, rs, ca) var err error _, err = en.Init(ctx) if err != nil { @@ -134,7 +134,7 @@ func main() { os.Exit(1) } - err = engine.Loop(&en, os.Stdin, os.Stdout, ctx) + err = engine.Loop(ctx, &en, os.Stdin, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) os.Exit(1) diff --git a/examples/session/main.go b/examples/session/main.go @@ -23,7 +23,7 @@ var ( emptyResult = resource.Result{} ) -func save(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func save(ctx context.Context, sym string, input []byte) (resource.Result, error) { sessionId := ctx.Value("SessionId").(string) sessionDir := path.Join(scriptDir, sessionId) err := os.MkdirAll(sessionDir, 0700) @@ -71,14 +71,14 @@ func main() { } ctx := context.Background() ctx = context.WithValue(ctx, "SessionId", sessionId) - en := engine.NewEngine(cfg, &st, rs, ca, ctx) + en := engine.NewEngine(ctx, cfg, &st, rs, ca) var err error _, err = en.Init(ctx) if err != nil { fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err) os.Exit(1) } - err = engine.Loop(&en, os.Stdin, os.Stdout, ctx) + err = engine.Loop(ctx, &en, os.Stdin, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) os.Exit(1) diff --git a/examples/validate/main.go b/examples/validate/main.go @@ -30,7 +30,7 @@ type verifyResource struct { st *state.State } -func(vr *verifyResource) verify(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(vr *verifyResource) verify(ctx context.Context, sym string, input []byte) (resource.Result, error) { var err error if string(input) == "something" { _, err = vr.st.SetFlag(USERFLAG_HAVESOMETHING) @@ -40,7 +40,7 @@ func(vr *verifyResource) verify(sym string, input []byte, ctx context.Context) ( }, err } -func(vr *verifyResource) again(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(vr *verifyResource) again(ctx context.Context, sym string, input []byte) (resource.Result, error) { var err error _, err = vr.st.ResetFlag(USERFLAG_HAVESOMETHING) return resource.Result{}, err @@ -69,14 +69,14 @@ func main() { } ctx := context.Background() ctx = context.WithValue(ctx, "SessionId", sessionId) - en := engine.NewEngine(cfg, &st, rs, ca, ctx) + en := engine.NewEngine(ctx, cfg, &st, rs, ca) var err error _, err = en.Init(ctx) if err != nil { fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err) os.Exit(1) } - err = engine.Loop(&en, os.Stdin, os.Stdout, ctx) + err = engine.Loop(ctx, &en, os.Stdin, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) os.Exit(1) diff --git a/render/page.go b/render/page.go @@ -145,8 +145,8 @@ func(pg *Page) Sizes() (map[string]uint16, error) { } // RenderTemplate is an adapter to implement the builtin golang text template renderer as resource.RenderTemplate. -func(pg *Page) RenderTemplate(sym string, values map[string]string, idx uint16, ctx context.Context) (string, error) { - tpl, err := pg.resource.GetTemplate(sym, ctx) +func(pg *Page) RenderTemplate(ctx context.Context, sym string, values map[string]string, idx uint16) (string, error) { + tpl, err := pg.resource.GetTemplate(ctx, sym) if err != nil { return "", err } @@ -184,15 +184,15 @@ func(pg *Page) RenderTemplate(sym string, values map[string]string, idx uint16, } // Render renders the current mapped content and menu state against the template associated with the symbol. -func(pg *Page) Render(sym string, idx uint16, ctx context.Context) (string, error) { +func(pg *Page) Render(ctx context.Context, sym string, idx uint16) (string, error) { var err error - values, err := pg.prepare(sym, pg.cacheMap, idx, ctx) + values, err := pg.prepare(ctx, sym, pg.cacheMap, idx) if err != nil { return "", err } - return pg.render(sym, values, idx, ctx) + return pg.render(ctx, sym, values, idx) } // Reset prepared the Page object for re-use. @@ -209,7 +209,7 @@ func(pg *Page) Reset() { // render menu and all syms except sink, split sink into display chunks // TODO: Function too long, split up -func(pg *Page) prepare(sym string, values map[string]string, idx uint16, ctx context.Context) (map[string]string, error) { +func(pg *Page) prepare(ctx context.Context, sym string, values map[string]string, idx uint16) (map[string]string, error) { var sink string if pg.sizer == nil { @@ -238,7 +238,7 @@ func(pg *Page) prepare(sym string, values map[string]string, idx uint16, ctx con } pg.sizer.AddCursor(0) - s, err := pg.render(sym, noSinkValues, 0, ctx) + s, err := pg.render(ctx, sym, noSinkValues, 0) if err != nil { return nil, err } @@ -330,10 +330,10 @@ func(pg *Page) prepare(sym string, values map[string]string, idx uint16, ctx con } // render template, menu (if it exists), and audit size constraint (if it exists). -func(pg *Page) render(sym string, values map[string]string, idx uint16, ctx context.Context) (string, error) { +func(pg *Page) render(ctx context.Context, sym string, values map[string]string, idx uint16) (string, error) { var ok bool r := "" - s, err := pg.RenderTemplate(sym, values, idx, ctx) + s, err := pg.RenderTemplate(ctx, sym, values, idx) if err != nil { return "", err } diff --git a/render/page_test.go b/render/page_test.go @@ -133,7 +133,7 @@ func TestWithError(t *testing.T) { pg = pg.WithMenu(mn).WithError(err) ctx := context.TODO() - r, err := pg.Render("foo", 0, ctx) + r, err := pg.Render(ctx, "foo", 0) if err != nil { t.Fatal(err) } diff --git a/render/size_test.go b/render/size_test.go @@ -11,59 +11,101 @@ import ( ) type TestSizeResource struct { - *resource.MenuResource + *resource.MemResource } -func getTemplate(sym string, ctx context.Context) (string, error) { - var tpl string - switch sym { - case "small": - tpl = "one {{.foo}} two {{.bar}} three {{.baz}}" - case "toobig": - tpl = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in mattis lorem. Aliquam erat volutpat. Ut vitae metus." - case "pages": - tpl = "one {{.foo}} two {{.bar}} three {{.baz}}\n{{.xyzzy}}" - } - return tpl, nil +func NewTestSizeResource() TestSizeResource { + mem := resource.NewMemResource() + rs := TestSizeResource{&mem} + rs.AddTemplate("small", "one {{.foo}} two {{.bar}} three {{.baz}}") + rs.AddTemplate("toobug", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in mattis lorem. Aliquam erat volutpat. Ut vitae metus.") + rs.AddTemplate("pages", "one {{.foo}} two {{.bar}} three {{.baz}}\n{{.xyzzy}}") + rs.AddEntryFunc("foo", get) + rs.AddEntryFunc("bar", get) + rs.AddEntryFunc("baz", get) + rs.AddEntryFunc("xyzzy", getXyzzy) + return rs } -func funcFor(sym string) (resource.EntryFunc, error) { +func get(ctx context.Context, sym string, input []byte) (resource.Result, error) { switch sym { case "foo": - return getFoo, nil + return resource.Result{ + Content: "inky", + }, nil case "bar": - return getBar, nil + return resource.Result{ + Content: "pinky", + }, nil case "baz": - return getBaz, nil - case "xyzzy": - return getXyzzy, nil + return resource.Result{ + Content: "blinky", + }, nil } - return nil, fmt.Errorf("unknown func: %s", sym) -} - -func getFoo(sym string, input []byte, ctx context.Context) (resource.Result, error) { - return resource.Result{ - Content: "inky", - }, nil -} - -func getBar(sym string, input []byte, ctx context.Context) (resource.Result, error) { - return resource.Result{ - Content: "pinky", - }, nil -} - -func getBaz(sym string, input []byte, ctx context.Context) (resource.Result, error) { - return resource.Result{ - Content: "blinky", - }, nil + return resource.Result{}, fmt.Errorf("unknown sym: %s", sym) } -func getXyzzy(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func getXyzzy(ctx context.Context, sym string, input []byte) (resource.Result, error) { + r := "inky pinky\nblinky clyde sue\ntinkywinky dipsy\nlala poo\none two three four five six seven\neight nine ten\neleven twelve" return resource.Result{ - Content: "inky pinky\nblinky clyde sue\ntinkywinky dipsy\nlala poo\none two three four five six seven\neight nine ten\neleven twelve", + Content: r, }, nil } +// +//type TestSizeResource struct { +// *resource.MenuResource +//} +// +//func getTemplate(sym string, ctx context.Context) (string, error) { +// var tpl string +// switch sym { +// case "small": +// tpl = "one {{.foo}} two {{.bar}} three {{.baz}}" +// case "toobig": +// tpl = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in mattis lorem. Aliquam erat volutpat. Ut vitae metus." +// case "pages": +// tpl = "one {{.foo}} two {{.bar}} three {{.baz}}\n{{.xyzzy}}" +// } +// return tpl, nil +//} +// +//func funcFor(sym string) (resource.EntryFunc, error) { +// switch sym { +// case "foo": +// return getFoo, nil +// case "bar": +// return getBar, nil +// case "baz": +// return getBaz, nil +// case "xyzzy": +// return getXyzzy, nil +// } +// return nil, fmt.Errorf("unknown func: %s", sym) +//} +// +//func getFoo(sym string, input []byte, ctx context.Context) (resource.Result, error) { +// return resource.Result{ +// Content: "inky", +// }, nil +//} +// +//func getBar(sym string, input []byte, ctx context.Context) (resource.Result, error) { +// return resource.Result{ +// Content: "pinky", +// }, nil +//} +// +//func getBaz(sym string, input []byte, ctx context.Context) (resource.Result, error) { +// return resource.Result{ +// Content: "blinky", +// }, nil +//} +// +//func getXyzzy(sym string, input []byte, ctx context.Context) (resource.Result, error) { +// return resource.Result{ +// Content: "inky pinky\nblinky clyde sue\ntinkywinky dipsy\nlala poo\none two three four five six seven\neight nine ten\neleven twelve", +// }, nil +//} func TestSizeCheck(t *testing.T) { szr := NewSizer(16) @@ -88,10 +130,11 @@ func TestSizeLimit(t *testing.T) { st := state.NewState(0) ca := cache.NewCache() mn := NewMenu().WithOutputSize(32) - mrs := resource.NewMenuResource().WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) - rs := TestSizeResource{ - mrs, - } + //mrs := NewMenuResource() //.WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) + //rs := TestSizeResource{ + // mrs, + //} + rs := NewTestSizeResource() szr := NewSizer(128) pg := NewPage(ca, rs).WithMenu(mn).WithSizer(szr) ca.Push() @@ -125,12 +168,12 @@ func TestSizeLimit(t *testing.T) { mn.Put("2", "go to bar") ctx := context.TODO() - _, err = pg.Render("small", 0, ctx) + _, err = pg.Render(ctx, "small", 0) if err != nil { t.Fatal(err) } - _, err = pg.Render("toobig", 0, ctx) + _, err = pg.Render(ctx, "toobig", 0) if err == nil { t.Fatalf("expected size exceeded") } @@ -140,10 +183,11 @@ func TestSizePages(t *testing.T) { st := state.NewState(0) ca := cache.NewCache() mn := NewMenu().WithOutputSize(32) - mrs := resource.NewMenuResource().WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) - rs := TestSizeResource{ - mrs, - } + //mrs := NewMenuResource() //.WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) + //rs := TestSizeResource{ + // mrs, + //} + rs := NewTestSizeResource() szr := NewSizer(128) pg := NewPage(ca, rs).WithSizer(szr).WithMenu(mn) ca.Push() @@ -161,7 +205,7 @@ func TestSizePages(t *testing.T) { mn.Put("2", "go to bar") ctx := context.TODO() - r, err := pg.Render("pages", 0, ctx) + r, err := pg.Render(ctx, "pages", 0) if err != nil { t.Fatal(err) } @@ -178,7 +222,7 @@ lala poo if r != expect { t.Fatalf("expected:\n\t%x\ngot:\n\t%x\n", expect, r) } - r, err = pg.Render("pages", 1, ctx) + r, err = pg.Render(ctx, "pages", 1) if err != nil { t.Fatal(err) } @@ -200,10 +244,10 @@ func TestManySizes(t *testing.T) { st := state.NewState(0) ca := cache.NewCache() mn := NewMenu().WithOutputSize(32) - mrs := resource.NewMenuResource().WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) - rs := TestSizeResource{ - mrs, - } + rs := NewTestSizeResource() //.WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) + //rs := TestSizeResource{ + // mrs, + //} szr := NewSizer(uint32(i)) pg := NewPage(ca, rs).WithSizer(szr).WithMenu(mn) ca.Push() @@ -218,7 +262,7 @@ func TestManySizes(t *testing.T) { pg.Map("xyzzy") ctx := context.TODO() - _, err := pg.Render("pages", 0, ctx) + _, err := pg.Render(ctx, "pages", 0) if err != nil { t.Fatal(err) } @@ -230,10 +274,7 @@ func TestManySizesMenued(t *testing.T) { st := state.NewState(0) ca := cache.NewCache() mn := NewMenu().WithOutputSize(32) - mrs := resource.NewMenuResource().WithEntryFuncGetter(funcFor).WithTemplateGetter(getTemplate) - rs := TestSizeResource{ - mrs, - } + rs := NewTestSizeResource() szr := NewSizer(uint32(i)) pg := NewPage(ca, rs).WithSizer(szr).WithMenu(mn) ca.Push() @@ -250,7 +291,7 @@ func TestManySizesMenued(t *testing.T) { mn.Put("12", "nay") ctx := context.TODO() - _, err := pg.Render("pages", 0, ctx) + _, err := pg.Render(ctx, "pages", 0) if err != nil { t.Fatal(err) } diff --git a/resource/fs.go b/resource/fs.go @@ -29,7 +29,7 @@ func NewFsResource(path string) FsResource { } } -func(fsr FsResource) GetTemplate(sym string, ctx context.Context) (string, error) { +func(fsr FsResource) GetTemplate(ctx context.Context, sym string) (string, error) { fp := path.Join(fsr.Path, sym) fpl := fp v := ctx.Value("Language") @@ -83,7 +83,7 @@ func(fsr FsResource) String() string { return fmt.Sprintf("fs resource at path: %s", fsr.Path) } -func(fsr FsResource) getFunc(sym string, input []byte, ctx context.Context) (Result, error) { +func(fsr FsResource) getFunc(ctx context.Context, sym string, input []byte) (Result, error) { v := ctx.Value("Language") if v == nil { return fsr.getFuncNoCtx(sym, input, nil) diff --git a/resource/fs_test.go b/resource/fs_test.go @@ -34,7 +34,7 @@ func TestResourceLanguage(t *testing.T) { } rs := NewFsResource(dir) - r, err := rs.GetTemplate("foo", ctx) + r, err := rs.GetTemplate(ctx, "foo") if err != nil { t.Fatal(err) } @@ -44,7 +44,7 @@ func TestResourceLanguage(t *testing.T) { ctx = context.WithValue(ctx, "Language", lang) rs = NewFsResource(dir) - r, err = rs.GetTemplate("foo", ctx) + r, err = rs.GetTemplate(ctx, "foo") if err != nil { t.Fatal(err) } @@ -57,7 +57,7 @@ func TestResourceLanguage(t *testing.T) { if err != nil { t.Fatal(err) } - r, err = rs.GetTemplate("foo", ctx) + r, err = rs.GetTemplate(ctx, "foo") if err != nil { t.Fatal(err) } diff --git a/resource/mem.go b/resource/mem.go @@ -24,7 +24,7 @@ func NewMemResource() MemResource { return mr } -func(mr MemResource) getTemplate(sym string, ctx context.Context) (string, error) { +func(mr MemResource) getTemplate(ctx context.Context, sym string) (string, error) { r, ok := mr.templates[sym] if !ok { return "", fmt.Errorf("unknown template symbol: %s", sym) diff --git a/resource/mem_test.go b/resource/mem_test.go @@ -7,7 +7,7 @@ import ( "testing" ) -func testEntry(sym string, input []byte, ctx context.Context) (Result, error) { +func testEntry(ctx context.Context, sym string, input []byte) (Result, error) { return Result{ Content: fmt.Sprintf("%sbar", input), }, nil @@ -18,7 +18,7 @@ func TestMemResourceTemplate(t *testing.T) { rs.AddTemplate("foo", "bar") ctx := context.TODO() - r, err := rs.GetTemplate("foo", ctx) + r, err := rs.GetTemplate(ctx, "foo") if err != nil { t.Fatal(err) } @@ -26,7 +26,7 @@ func TestMemResourceTemplate(t *testing.T) { fmt.Errorf("expected 'bar', got %s", r) } - _, err = rs.GetTemplate("bar", ctx) + _, err = rs.GetTemplate(ctx, "bar") if err == nil { t.Fatalf("expected error") } @@ -60,7 +60,7 @@ func TestMemResourceEntry(t *testing.T) { } ctx := context.TODO() - r, err := fn("foo", []byte("xyzzy"), ctx) + r, err := fn(ctx, "foo", []byte("xyzzy")) if err != nil { t.Fatal(err) } diff --git a/resource/resource.go b/resource/resource.go @@ -13,14 +13,14 @@ type Result struct { } // EntryFunc is a function signature for retrieving value for a key -type EntryFunc func(sym string, input []byte, ctx context.Context) (Result, error) +type EntryFunc func(ctx context.Context, sym string, input []byte) (Result, error) type CodeFunc func(sym string) ([]byte, error) -type TemplateFunc func(sym string, ctx context.Context) (string, error) +type TemplateFunc func(ctx context.Context, sym string) (string, error) type FuncForFunc func(sym string) (EntryFunc, error) // Resource implementation are responsible for retrieving values and templates for symbols, and can render templates from value dictionaries. type Resource interface { - GetTemplate(sym string, ctx context.Context) (string, error) // Get the template for a given symbol. + GetTemplate(ctx context.Context, sym string) (string, error) // Get the template for a given symbol. GetCode(sym string) ([]byte, error) // Get the bytecode for the given symbol. FuncFor(sym string) (EntryFunc, error) // Resolve symbol content point for. } @@ -69,6 +69,6 @@ func(m MenuResource) GetCode(sym string) ([]byte, error) { } // GetTemplate implements Resource interface -func(m MenuResource) GetTemplate(sym string, ctx context.Context) (string, error) { - return m.templateFunc(sym, ctx) +func(m MenuResource) GetTemplate(ctx context.Context, sym string) (string, error) { + return m.templateFunc(ctx, sym) } diff --git a/resource/resource_test.go b/resource/resource_test.go @@ -7,37 +7,23 @@ import ( type TestSizeResource struct { - *MenuResource + *MemResource } -func getTemplate(sym string, ctx context.Context) (string, error) { - var tpl string - switch sym { - case "small": - tpl = "one {{.foo}} two {{.bar}} three {{.baz}}" - case "toobig": - tpl = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in mattis lorem. Aliquam erat volutpat. Ut vitae metus." - case "pages": - tpl = "one {{.foo}} two {{.bar}} three {{.baz}}\n{{.xyzzy}}" - } - return tpl, nil -} - -func funcFor(sym string) (EntryFunc, error) { - switch sym { - case "foo": - return get, nil - case "bar": - return get, nil - case "baz": - return get, nil - case "xyzzy": - return getXyzzy, nil - } - return nil, fmt.Errorf("unknown func: %s", sym) +func NewTestSizeResource() TestSizeResource { + mem := NewMemResource() + rs := TestSizeResource{&mem} + rs.AddTemplate("small", "one {{.foo}} two {{.bar}} three {{.baz}}") + rs.AddTemplate("toobug", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in mattis lorem. Aliquam erat volutpat. Ut vitae metus.") + rs.AddTemplate("pages", "one {{.foo}} two {{.bar}} three {{.baz}}\n{{.xyzzy}}") + rs.AddEntryFunc("foo", get) + rs.AddEntryFunc("bar", get) + rs.AddEntryFunc("baz", get) + rs.AddEntryFunc("xyzzy", getXyzzy) + return rs } -func get(sym string, input []byte, ctx context.Context) (Result, error) { +func get(ctx context.Context, sym string, input []byte) (Result, error) { switch sym { case "foo": return Result{ @@ -55,7 +41,7 @@ func get(sym string, input []byte, ctx context.Context) (Result, error) { return Result{}, fmt.Errorf("unknown sym: %s", sym) } -func getXyzzy(sym string, input []byte, ctx context.Context) (Result, error) { +func getXyzzy(ctx context.Context, sym string, input []byte) (Result, error) { r := "inky pinky\nblinky clyde sue\ntinkywinky dipsy\nlala poo\none two three four five six seven\neight nine ten\neleven twelve" return Result{ Content: r, diff --git a/vm/runner.go b/vm/runner.go @@ -77,7 +77,7 @@ func(vmi *Vm) Reset() { // Each step may update the state. // // On error, the remaining instructions will be returned. State will not be rolled back. -func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) Run(ctx context.Context, b []byte) ([]byte, error) { running := true for running { r, err := vm.st.MatchFlag(state.FLAG_TERMINATE, false) @@ -129,29 +129,29 @@ func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { Logg.DebugCtxf(ctx, "", "state", vm.st) switch op { case CATCH: - b, err = vm.runCatch(b, ctx) + b, err = vm.runCatch(ctx, b) case CROAK: - b, err = vm.runCroak(b, ctx) + b, err = vm.runCroak(ctx, b) case LOAD: - b, err = vm.runLoad(b, ctx) + b, err = vm.runLoad(ctx, b) case RELOAD: - b, err = vm.runReload(b, ctx) + b, err = vm.runReload(ctx, b) case MAP: - b, err = vm.runMap(b, ctx) + b, err = vm.runMap(ctx, b) case MOVE: - b, err = vm.runMove(b, ctx) + b, err = vm.runMove(ctx, b) case INCMP: - b, err = vm.runInCmp(b, ctx) + b, err = vm.runInCmp(ctx, b) case MSIZE: - b, err = vm.runMSize(b, ctx) + b, err = vm.runMSize(ctx, b) case MOUT: - b, err = vm.runMOut(b, ctx) + b, err = vm.runMOut(ctx, b) case MNEXT: - b, err = vm.runMNext(b, ctx) + b, err = vm.runMNext(ctx, b) case MPREV: - b, err = vm.runMPrev(b, ctx) + b, err = vm.runMPrev(ctx, b) case HALT: - b, err = vm.runHalt(b, ctx) + b, err = vm.runHalt(ctx, b) return b, err default: err = fmt.Errorf("Unhandled state: %v", op) @@ -161,7 +161,7 @@ func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { return b, err } if len(b) == 0 { - b, err = vm.runDeadCheck(b, ctx) + b, err = vm.runDeadCheck(ctx, b) if err != nil { return b, err } @@ -199,7 +199,7 @@ func(vm *Vm) runErrCheck(ctx context.Context, b []byte, err error) ([]byte, erro // If input has not been matched, a default invalid input page should be generated aswell as a possiblity of return to last screen (or exit). // // If the termination flag has been set but not yet handled, execution is allowed to terminate. -func(vm *Vm) runDeadCheck(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runDeadCheck(ctx context.Context, b []byte) ([]byte, error) { if len(b) > 0 { return b, nil } @@ -241,14 +241,14 @@ func(vm *Vm) runDeadCheck(b []byte, ctx context.Context) ([]byte, error) { } // executes the MAP opcode -func(vm *Vm) runMap(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMap(ctx context.Context, b []byte) ([]byte, error) { sym, b, err := ParseMap(b) err = vm.pg.Map(sym) return b, err } // executes the CATCH opcode -func(vm *Vm) runCatch(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runCatch(ctx context.Context, b []byte) ([]byte, error) { sym, sig, mode, b, err := ParseCatch(b) if err != nil { return b, err @@ -283,7 +283,7 @@ func(vm *Vm) runCatch(b []byte, ctx context.Context) ([]byte, error) { } // executes the CROAK opcode -func(vm *Vm) runCroak(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runCroak(ctx context.Context, b []byte) ([]byte, error) { sig, mode, b, err := ParseCroak(b) if err != nil { return b, err @@ -303,7 +303,7 @@ func(vm *Vm) runCroak(b []byte, ctx context.Context) ([]byte, error) { } // executes the LOAD opcode -func(vm *Vm) runLoad(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runLoad(ctx context.Context, b []byte) ([]byte, error) { sym, sz, b, err := ParseLoad(b) if err != nil { return b, err @@ -317,7 +317,7 @@ func(vm *Vm) runLoad(b []byte, ctx context.Context) ([]byte, error) { } // executes the RELOAD opcode -func(vm *Vm) runReload(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runReload(ctx context.Context, b []byte) ([]byte, error) { sym, b, err := ParseReload(b) if err != nil { return b, err @@ -338,7 +338,7 @@ func(vm *Vm) runReload(b []byte, ctx context.Context) ([]byte, error) { } // executes the MOVE opcode -func(vm *Vm) runMove(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMove(ctx context.Context, b []byte) ([]byte, error) { sym, b, err := ParseMove(b) if err != nil { return b, err @@ -359,7 +359,7 @@ func(vm *Vm) runMove(b []byte, ctx context.Context) ([]byte, error) { // executes the INCMP opcode // TODO: document state transition table and simplify flow -func(vm *Vm) runInCmp(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runInCmp(ctx context.Context, b []byte) ([]byte, error) { sym, target, b, err := ParseInCmp(b) if err != nil { return b, err @@ -434,7 +434,7 @@ func(vm *Vm) runInCmp(b []byte, ctx context.Context) ([]byte, error) { } // executes the HALT opcode -func(vm *Vm) runHalt(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runHalt(ctx context.Context, b []byte) ([]byte, error) { var err error b, err = ParseHalt(b) if err != nil { @@ -450,14 +450,14 @@ func(vm *Vm) runHalt(b []byte, ctx context.Context) ([]byte, error) { } // executes the MSIZE opcode -func(vm *Vm) runMSize(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMSize(ctx context.Context, b []byte) ([]byte, error) { Logg.WarnCtxf(ctx, "MSIZE not yet implemented") _, _, b, err := ParseMSize(b) return b, err } // executes the MOUT opcode -func(vm *Vm) runMOut(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMOut(ctx context.Context, b []byte) ([]byte, error) { choice, title, b, err := ParseMOut(b) if err != nil { return b, err @@ -467,7 +467,7 @@ func(vm *Vm) runMOut(b []byte, ctx context.Context) ([]byte, error) { } // executes the MNEXT opcode -func(vm *Vm) runMNext(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMNext(ctx context.Context, b []byte) ([]byte, error) { selector, display, b, err := ParseMNext(b) if err != nil { return b, err @@ -481,7 +481,7 @@ func(vm *Vm) runMNext(b []byte, ctx context.Context) ([]byte, error) { } // executes the MPREV opcode -func(vm *Vm) runMPrev(b []byte, ctx context.Context) ([]byte, error) { +func(vm *Vm) runMPrev(ctx context.Context, b []byte) ([]byte, error) { selector, display, b, err := ParseMPrev(b) if err != nil { return b, err @@ -504,15 +504,15 @@ func(vm *Vm) Render(ctx context.Context) (string, error) { return "", nil } sym, idx := vm.st.Where() - r, err := vm.pg.Render(sym, idx, ctx) + r, err := vm.pg.Render(ctx, sym, idx) var ok bool _, ok = err.(*render.BrowseError) if ok { vm.Reset() b := NewLine(nil, MOVE, []string{"_catch"}, nil, nil) - vm.Run(b, ctx) + vm.Run(ctx, b) sym, idx := vm.st.Where() - r, err = vm.pg.Render(sym, idx, ctx) + r, err = vm.pg.Render(ctx, sym, idx) } if err != nil { return "", err @@ -530,7 +530,7 @@ func(vm *Vm) refresh(key string, rs resource.Resource, ctx context.Context) (str return "", fmt.Errorf("no retrieve function for external symbol %v", key) } input, _ := vm.st.GetInput() - r, err := fn(key, input, ctx) + r, err := fn(ctx, key, input) if err != nil { var perr error _, perr = vm.st.SetFlag(state.FLAG_LOADFAIL) diff --git a/vm/runner_test.go b/vm/runner_test.go @@ -16,31 +16,55 @@ import ( var dynVal = "three" type TestResource struct { - resource.MenuResource + resource.MemResource state *state.State RootCode []byte CatchContent string } -func getOne(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func NewTestResource(st *state.State) TestResource { + tr := TestResource{ + MemResource: resource.NewMemResource(), + state: st, + } + tr.AddTemplate("foo", "inky pinky blinky clyde") + tr.AddTemplate("bar", "inky pinky {{.one}} blinky {{.two}} clyde") + tr.AddTemplate("baz", "inky pinky {{.baz}} blinky clyde") + tr.AddTemplate("three", "{{.one}} inky pinky {{.three}} blinky clyde {{.two}}") + tr.AddTemplate("root", "root") + tr.AddTemplate("_catch", tr.CatchContent) + tr.AddTemplate("ouf", "ouch") + tr.AddTemplate("flagCatch", "flagiee") + tr.AddEntryFunc("one", getOne) + tr.AddEntryFunc("two", getTwo) + tr.AddEntryFunc("dyn", getDyn) + tr.AddEntryFunc("arg", tr.getInput) + tr.AddEntryFunc("echo", getEcho) + tr.AddEntryFunc("setFlagOne", setFlag) + tr.AddEntryFunc("set_lang", set_lang) + tr.AddEntryFunc("aiee", uhOh) + return tr +} + +func getOne(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: "one", }, nil } -func getTwo(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func getTwo(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: "two", }, nil } -func getDyn(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func getDyn(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: dynVal, }, nil } -func getEcho(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func getEcho(ctx context.Context, sym string, input []byte) (resource.Result, error) { r := fmt.Sprintf("echo: %s", input) return resource.Result{ Content: r, @@ -48,11 +72,11 @@ func getEcho(sym string, input []byte, ctx context.Context) (resource.Result, er } -func uhOh(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func uhOh(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{}, fmt.Errorf("uh-oh spaghetti'ohs") } -func setFlag(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func setFlag(ctx context.Context, sym string, input []byte) (resource.Result, error) { s := fmt.Sprintf("ping") r := resource.Result{ Content: s, @@ -68,38 +92,16 @@ func setFlag(sym string, input []byte, ctx context.Context) (resource.Result, er } -func set_lang(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func set_lang(ctx context.Context, sym string, input []byte) (resource.Result, error) { return resource.Result{ Content: string(input), FlagSet: []uint32{state.FLAG_LANG}, }, nil } - -type TestStatefulResolver struct { - state *state.State -} - -func (r TestResource) GetTemplate(sym string, ctx context.Context) (string, error) { - switch sym { - case "foo": - return "inky pinky blinky clyde", nil - case "bar": - return "inky pinky {{.one}} blinky {{.two}} clyde", nil - case "baz": - return "inky pinky {{.baz}} blinky clyde", nil - case "three": - return "{{.one}} inky pinky {{.three}} blinky clyde {{.two}}", nil - case "root": - return "root", nil - case "_catch": - return r.CatchContent, nil - case "ouf": - return "ouch", nil - case "flagCatch": - return "flagiee", nil - } - return "", fmt.Errorf("unknown symbol %s", sym) -} +// +//type TestStatefulResolver struct { +// state *state.State +//} func (r TestResource) FuncFor(sym string) (resource.EntryFunc, error) { switch sym { @@ -123,7 +125,7 @@ func (r TestResource) FuncFor(sym string) (resource.EntryFunc, error) { return nil, fmt.Errorf("invalid function: '%s'", sym) } -func(r TestResource) getInput(sym string, input []byte, ctx context.Context) (resource.Result, error) { +func(r TestResource) getInput(ctx context.Context, sym string, input []byte) (resource.Result, error) { v, err := r.state.GetInput() return resource.Result{ Content: string(v), @@ -152,19 +154,20 @@ func(r TestResource) GetCode(sym string) ([]byte, error) { func TestRun(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err := vm.Run(b, context.TODO()) + ctx := context.TODO() + _, err := vm.Run(ctx, b) if err != nil { t.Errorf("run error: %v", err) } b = []byte{0x01, 0x02} - _, err = vm.Run(b, context.TODO()) + _, err = vm.Run(ctx, b) if err == nil { t.Errorf("no error on invalid opcode") } @@ -172,7 +175,7 @@ func TestRun(t *testing.T) { func TestRunLoadRender(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -185,7 +188,7 @@ func TestRunLoadRender(t *testing.T) { b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil) b = NewLine(b, MAP, []string{"two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -201,14 +204,14 @@ func TestRunLoadRender(t *testing.T) { b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil) b = NewLine(b, MAP, []string{"two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { 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) + _, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -224,7 +227,7 @@ func TestRunLoadRender(t *testing.T) { func TestRunMultiple(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -233,7 +236,7 @@ func TestRunMultiple(t *testing.T) { b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil) b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err := vm.Run(b, ctx) + b, err := vm.Run(ctx, b) if err != nil { t.Error(err) } @@ -244,7 +247,7 @@ func TestRunMultiple(t *testing.T) { func TestRunReload(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() szr := render.NewSizer(128) vm := NewVm(&st, &rs, ca, szr) @@ -254,7 +257,7 @@ func TestRunReload(t *testing.T) { b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0}) b = NewLine(b, MAP, []string{"dyn"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err := vm.Run(b, ctx) + _, err := vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -268,7 +271,7 @@ func TestRunReload(t *testing.T) { dynVal = "baz" b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err = vm.Run(b, ctx) + _, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -276,7 +279,7 @@ func TestRunReload(t *testing.T) { func TestHalt(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -285,7 +288,8 @@ func TestHalt(t *testing.T) { b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, MOVE, []string{"foo"}, nil, nil) var err error - b, err = vm.Run(b, context.TODO()) + ctx := context.TODO() + b, err = vm.Run(ctx, b) if err != nil { t.Error(err) } @@ -300,7 +304,7 @@ func TestHalt(t *testing.T) { func TestRunArg(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -309,7 +313,8 @@ func TestRunArg(t *testing.T) { bi := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil) bi = NewLine(bi, HALT, nil, nil, nil) - b, err := vm.Run(bi, context.TODO()) + ctx := context.TODO() + b, err := vm.Run(ctx, bi) if err != nil { t.Error(err) } @@ -325,7 +330,7 @@ func TestRunArg(t *testing.T) { func TestRunInputHandler(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -340,7 +345,8 @@ func TestRunInputHandler(t *testing.T) { bi = NewLine(bi, HALT, nil, nil, nil) var err error - _, err = vm.Run(bi, context.TODO()) + ctx := context.TODO() + _, err = vm.Run(ctx, bi) if err != nil { t.Fatal(err) } @@ -352,7 +358,7 @@ func TestRunInputHandler(t *testing.T) { func TestRunArgInvalid(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -364,7 +370,7 @@ func TestRunArgInvalid(t *testing.T) { b := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil) ctx := context.TODO() - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -386,7 +392,7 @@ func TestRunArgInvalid(t *testing.T) { func TestRunMenu(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -399,7 +405,7 @@ func TestRunMenu(t *testing.T) { b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Error(err) } @@ -421,7 +427,7 @@ func TestRunMenu(t *testing.T) { func TestRunMenuBrowse(t *testing.T) { log.Printf("This test is incomplete, it must check the output of a menu browser once one is implemented. For now it only checks whether it can execute the runner endpoints for the instrucitons.") st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -434,7 +440,7 @@ func TestRunMenuBrowse(t *testing.T) { b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Error(err) } @@ -455,7 +461,7 @@ func TestRunMenuBrowse(t *testing.T) { func TestRunReturn(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -470,7 +476,7 @@ func TestRunReturn(t *testing.T) { ctx := context.TODO() st.SetInput([]byte("0")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -479,7 +485,7 @@ func TestRunReturn(t *testing.T) { t.Fatalf("expected location 'bar', got '%s'", location) } st.SetInput([]byte("1")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -492,7 +498,7 @@ func TestRunReturn(t *testing.T) { func TestRunLoadInput(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -506,7 +512,7 @@ func TestRunLoadInput(t *testing.T) { ctx := context.TODO() - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -522,7 +528,7 @@ func TestRunLoadInput(t *testing.T) { func TestInputBranch(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -542,7 +548,7 @@ func TestInputBranch(t *testing.T) { ctx := context.TODO() st.SetInput([]byte{0x08}) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -552,7 +558,7 @@ func TestInputBranch(t *testing.T) { } st.SetInput([]byte{0x09, 0x08}) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -564,7 +570,7 @@ func TestInputBranch(t *testing.T) { func TestInputIgnore(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -579,7 +585,7 @@ func TestInputIgnore(t *testing.T) { ctx := context.TODO() st.SetInput([]byte("foo")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -592,7 +598,7 @@ func TestInputIgnore(t *testing.T) { func TestInputIgnoreWildcard(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -606,7 +612,7 @@ func TestInputIgnoreWildcard(t *testing.T) { ctx := context.TODO() st.SetInput([]byte("foo")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -619,7 +625,7 @@ func TestInputIgnoreWildcard(t *testing.T) { func TestCatchCleanMenu(t *testing.T) { st := state.NewState(5) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -636,13 +642,13 @@ func TestCatchCleanMenu(t *testing.T) { ctx := context.TODO() st.SetInput([]byte("foo")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } st.SetInput([]byte("foo")) - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -656,7 +662,7 @@ func TestCatchCleanMenu(t *testing.T) { func TestSetLang(t *testing.T) { st := state.NewState(0) - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -669,7 +675,7 @@ func TestSetLang(t *testing.T) { b = NewLine(b, HALT, nil, nil, nil) ctx := context.TODO() - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) } @@ -681,7 +687,7 @@ func TestSetLang(t *testing.T) { func TestLoadError(t *testing.T) { st := state.NewState(0).WithDebug() - rs := TestResource{} + rs := NewTestResource(&st) ca := cache.NewCache() vm := NewVm(&st, &rs, ca, nil) @@ -692,7 +698,7 @@ func TestLoadError(t *testing.T) { var err error ctx := context.TODO() - b, err = vm.Run(b, ctx) + b, err = vm.Run(ctx, b) if err != nil { t.Fatal(err) }