main.go (3406B)
1 // Example: Use db.Db provider for all local data. 2 // 3 // BUG: This will be stuck on _catch if quit before first write. 4 package main 5 6 import ( 7 "bytes" 8 "context" 9 "fmt" 10 "os" 11 "path" 12 13 testdataloader "github.com/peteole/testdata-loader" 14 15 "git.defalsify.org/vise.git/asm" 16 "git.defalsify.org/vise.git/engine" 17 "git.defalsify.org/vise.git/persist" 18 "git.defalsify.org/vise.git/resource" 19 "git.defalsify.org/vise.git/state" 20 "git.defalsify.org/vise.git/db" 21 fsdb "git.defalsify.org/vise.git/db/fs" 22 "git.defalsify.org/vise.git/logging" 23 ) 24 25 var ( 26 logg = logging.NewVanilla() 27 baseDir = testdataloader.GetBasePath() 28 scriptDir = path.Join(baseDir, "examples", "db") 29 store = fsdb.NewFsDb() 30 pr = persist.NewPersister(store) 31 data_selector = []byte("my_data") 32 ) 33 34 func say(ctx context.Context, sym string, input []byte) (resource.Result, error) { 35 var r resource.Result 36 store.SetPrefix(db.DATATYPE_USERDATA) 37 38 st := pr.GetState() 39 if st.MatchFlag(state.FLAG_USERSTART, false) { 40 r.FlagSet = []uint32{8} 41 r.Content = "0" 42 return r, nil 43 } 44 if len(input) > 0 { 45 err := store.Put(ctx, data_selector, input) 46 if err != nil { 47 return r, err 48 } 49 } 50 51 v, err := store.Get(ctx, data_selector) 52 if err != nil { 53 return r, err 54 } 55 56 r.Content = string(v) 57 return r, nil 58 } 59 60 func genCode(ctx context.Context, store db.Db) error { 61 b := bytes.NewBuffer(nil) 62 asm.Parse("LOAD say 0\n", b) 63 asm.Parse("MAP say\n", b) 64 asm.Parse("MOUT quit 0\n", b) 65 asm.Parse("HALT\n", b) 66 asm.Parse("INCMP argh 0\n", b) 67 asm.Parse("INCMP update *\n", b) 68 store.SetPrefix(db.DATATYPE_BIN) 69 err := store.Put(ctx, []byte("root"), b.Bytes()) 70 if err != nil { 71 return err 72 } 73 74 b = bytes.NewBuffer(nil) 75 asm.Parse("HALT\n", b) 76 err = store.Put(ctx, []byte("argh"), b.Bytes()) 77 if err != nil { 78 return err 79 } 80 81 b = bytes.NewBuffer(nil) 82 asm.Parse("RELOAD say\n", b) 83 asm.Parse("MOVE _\n", b) 84 err = store.Put(ctx, []byte("update"), b.Bytes()) 85 if err != nil { 86 return err 87 } 88 return nil 89 } 90 91 func genMenu(ctx context.Context, store db.Db) error { 92 store.SetPrefix(db.DATATYPE_MENU) 93 return store.Put(ctx, []byte("quit"), []byte("give up")) 94 } 95 96 func genTemplate(ctx context.Context, store db.Db) error { 97 store.SetPrefix(db.DATATYPE_TEMPLATE) 98 return store.Put(ctx, []byte("root"), []byte("current data is {{.say}}")) 99 } 100 101 func main() { 102 ctx := context.Background() 103 root := "root" 104 fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, scriptDir) 105 106 dataDir := path.Join(scriptDir, ".store") 107 err := store.Connect(ctx, dataDir) 108 if err != nil { 109 panic(err) 110 } 111 store.SetSession("xyzzy") 112 store.SetLock(db.DATATYPE_TEMPLATE | db.DATATYPE_MENU | db.DATATYPE_BIN, false) 113 err = genCode(ctx, store) 114 if err != nil { 115 panic(err) 116 } 117 118 err = genMenu(ctx, store) 119 if err != nil { 120 panic(err) 121 } 122 123 err = genTemplate(ctx, store) 124 if err != nil { 125 panic(err) 126 } 127 store.SetLock(db.DATATYPE_TEMPLATE | db.DATATYPE_MENU | db.DATATYPE_BIN, true) 128 129 tg := resource.NewDbResource(store) 130 rs := resource.NewMenuResource() 131 rs.WithTemplateGetter(tg.GetTemplate) 132 rs.WithMenuGetter(tg.GetMenu) 133 rs.WithCodeGetter(tg.GetCode) 134 rs.AddLocalFunc("say", say) 135 136 cfg := engine.Config{ 137 Root: "root", 138 FlagCount: 1, 139 } 140 141 en := engine.NewEngine(cfg, rs) 142 en = en.WithPersister(pr) 143 144 err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil) 145 if err != nil { 146 fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) 147 os.Exit(1) 148 } 149 150 }