go-vise

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

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 }