go-vise

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

commit 9208b68f29b20f26dbb3438fe6049f033ecd1209
parent c6e2b0b5a41a8d8839b79663b5f55321ba8e2060
Author: lash <dev@holbrook.no>
Date:   Fri, 30 Aug 2024 22:00:52 +0100

WIP fully db inproc implemented example

Diffstat:
Aexamples/db/main.go | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mresource/fs.go | 14+++-----------
Mresource/resource.go | 20+++++++++++++++++++-
3 files changed, 159 insertions(+), 12 deletions(-)

diff --git a/examples/db/main.go b/examples/db/main.go @@ -0,0 +1,137 @@ +package main + +import ( + "bytes" + "context" + "fmt" + "os" + "path" + + testdataloader "github.com/peteole/testdata-loader" + + "git.defalsify.org/vise.git/asm" + "git.defalsify.org/vise.git/cache" + "git.defalsify.org/vise.git/engine" + "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/state" + "git.defalsify.org/vise.git/db" +) + +var ( + baseDir = testdataloader.GetBasePath() + scriptDir = path.Join(baseDir, "examples", "db") + ctx = context.Background() + store = db.NewMemDb(ctx) + data_selector = []byte("my_data") +) + +func say(ctx context.Context, sym string, input []byte) (resource.Result, error) { + var r resource.Result + store.SetPrefix(db.DATATYPE_USERSTART) + + if len(input) > 0 { + err := store.Put(ctx, data_selector, input) + if err != nil { + return r, err + } + } + + v, err := store.Get(ctx, data_selector) + if err != nil { + return r, err + } + + r.Content = string(v) + return r, nil +} + +func genCode(ctx context.Context, store db.Db) error { + b := bytes.NewBuffer(nil) + asm.Parse("LOAD say 0\n", b) + asm.Parse("RELOAD say\n", b) + asm.Parse("MAP say\n", b) + asm.Parse("MOUT quit 0\n", b) + asm.Parse("HALT\n", b) + asm.Parse("INCMP argh 0\n", b) + asm.Parse("INCMP ^ *\n", b) + store.SetPrefix(db.DATATYPE_BIN) + err := store.Put(ctx, []byte("root"), b.Bytes()) + if err != nil { + return err + } + + b = bytes.NewBuffer(nil) + asm.Parse("HALT\n", b) + return store.Put(ctx, []byte("argh"), b.Bytes()) +} + +func genMenu(ctx context.Context, store db.Db) error { + store.SetPrefix(db.DATATYPE_MENU) + return store.Put(ctx, []byte("quit"), []byte("give up")) +} + +func genTemplate(ctx context.Context, store db.Db) error { + store.SetPrefix(db.DATATYPE_TEMPLATE) + return store.Put(ctx, []byte("root"), []byte("current data is {{.say}}")) +} + +func main() { + root := "root" + fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, scriptDir) + + st := state.NewState(1) + + store.SetSession("xyzzy") + store.SetPrefix(db.DATATYPE_USERSTART) + err := store.Put(ctx, data_selector, []byte("0")) + if err != nil { + panic(err) + } + + err = genCode(ctx, store) + if err != nil { + panic(err) + } + + err = genMenu(ctx, store) + if err != nil { + panic(err) + } + + err = genTemplate(ctx, store) + if err != nil { + panic(err) + } + + tg, err := resource.NewDbFuncGetter(store, db.DATATYPE_TEMPLATE, db.DATATYPE_MENU, db.DATATYPE_BIN) + if err != nil { + panic(err) + } + rs := resource.NewMenuResource() + rs.WithTemplateGetter(tg.GetTemplate) + rs.WithMenuGetter(tg.GetMenu) + rs.WithCodeGetter(tg.GetCode) + rs.WithCodeGetter(tg.GetCode) + rs.AddLocalFunc("say", say) + + ca := cache.NewCache() + if err != nil { + panic(err) + } + cfg := engine.Config{ + Root: "root", + } + en := engine.NewEngine(ctx, cfg, &st, rs, ca) + + _, err = en.Init(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err) + os.Exit(1) + } + 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/resource/fs.go b/resource/fs.go @@ -16,7 +16,6 @@ import ( type FsResource struct { MenuResource Path string - fns map[string]EntryFunc // languageStrict bool } @@ -97,11 +96,11 @@ func(fsr FsResource) GetMenu(ctx context.Context, sym string) (string, error) { func(fsr FsResource) FuncFor(sym string) (EntryFunc, error) { - fn, ok := fsr.fns[sym] - if ok { + fn, err := fsr.MenuResource.FallbackFunc(sym) + if err == nil { return fn, nil } - _, err := fsr.getFuncNoCtx(sym, nil, nil) + _, err = fsr.getFuncNoCtx(sym, nil, nil) if err != nil { return nil, fmt.Errorf("unknown sym: %s", sym) } @@ -148,10 +147,3 @@ func(fsr FsResource) getFuncNoCtx(sym string, input []byte, language *lang.Langu Content: strings.TrimSpace(s), }, nil } - -func(fsr *FsResource) AddLocalFunc(sym string, fn EntryFunc) { - if fsr.fns == nil { - fsr.fns = make(map[string]EntryFunc) - } - fsr.fns[sym] = fn -} diff --git a/resource/resource.go b/resource/resource.go @@ -2,6 +2,7 @@ package resource import ( "context" + "fmt" ) @@ -37,11 +38,14 @@ type MenuResource struct { templateFunc TemplateFunc menuFunc MenuFunc funcFunc FuncForFunc + fns map[string]EntryFunc } // NewMenuResource creates a new MenuResource instance. func NewMenuResource() *MenuResource { - return &MenuResource{} + rs := &MenuResource{} + rs.funcFunc = rs.FallbackFunc + return rs } // WithCodeGetter sets the code symbol resolver method. @@ -88,3 +92,17 @@ func(m MenuResource) GetMenu(ctx context.Context, sym string) (string, error) { return m.menuFunc(ctx, sym) } +func(m *MenuResource) AddLocalFunc(sym string, fn EntryFunc) { + if m.fns == nil { + m.fns = make(map[string]EntryFunc) + } + m.fns[sym] = fn +} + +func(m *MenuResource) FallbackFunc(sym string) (EntryFunc, error) { + fn, ok := m.fns[sym] + if !ok { + return nil, fmt.Errorf("unknown function: %s", sym) + } + return fn, nil +}