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:
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
+}