diff --git a/Makefile b/Makefile index ad93bda..4b3d476 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -examples: profile session helloworld +examples: profile session helloworld validate .PHONY: examples @@ -10,3 +10,6 @@ session: helloworld: bash examples/compile.bash examples/helloworld + +validate: + bash examples/compile.bash examples/validate diff --git a/examples/validate/end b/examples/validate/end new file mode 100644 index 0000000..5806299 --- /dev/null +++ b/examples/validate/end @@ -0,0 +1,2 @@ +You made it. +Any input to go again. diff --git a/examples/validate/end.vis b/examples/validate/end.vis new file mode 100644 index 0000000..5a059f3 --- /dev/null +++ b/examples/validate/end.vis @@ -0,0 +1,3 @@ +HALT +LOAD again 0 +INCMP * _ diff --git a/examples/validate/main.go b/examples/validate/main.go new file mode 100644 index 0000000..7add04e --- /dev/null +++ b/examples/validate/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + "path" + + testdataloader "github.com/peteole/testdata-loader" + + "git.defalsify.org/vise/cache" + "git.defalsify.org/vise/engine" + "git.defalsify.org/vise/resource" + "git.defalsify.org/vise/state" +) + +var ( + baseDir = testdataloader.GetBasePath() + scriptDir = path.Join(baseDir, "examples", "validate") + emptyResult = resource.Result{} +) + +const ( + USERFLAG_HAVESOMETHING = state.FLAG_USERSTART +) + +type verifyResource struct { + *resource.FsResource + st *state.State +} + +func(vr *verifyResource) verify(sym string, input []byte, ctx context.Context) (resource.Result, error) { + var err error + if string(input) == "something" { + _, err = vr.st.SetFlag(USERFLAG_HAVESOMETHING) + } + return resource.Result{ + Content: "", + }, err +} + +func(vr *verifyResource) again(sym string, input []byte, ctx context.Context) (resource.Result, error) { + var err error + _, err = vr.st.ResetFlag(USERFLAG_HAVESOMETHING) + return resource.Result{}, err +} + +func main() { + var root string + var size uint + var sessionId string + flag.UintVar(&size, "s", 0, "max size of output") + flag.StringVar(&root, "root", "root", "entry point symbol") + flag.StringVar(&sessionId, "session-id", "default", "session id") + flag.Parse() + fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, scriptDir) + + st := state.NewState(1) + rsf := resource.NewFsResource(scriptDir) + rs := verifyResource{&rsf, &st} + rs.AddLocalFunc("verifyinput", rs.verify) + rs.AddLocalFunc("again", rs.again) + ca := cache.NewCache() + cfg := engine.Config{ + Root: "root", + SessionId: sessionId, + OutputSize: uint32(size), + } + ctx := context.Background() + ctx = context.WithValue(ctx, "SessionId", sessionId) + en := engine.NewEngine(cfg, &st, rs, ca, ctx) + 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) + if err != nil { + fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) + os.Exit(1) + } +} diff --git a/examples/validate/root b/examples/validate/root new file mode 100644 index 0000000..6021dd8 --- /dev/null +++ b/examples/validate/root @@ -0,0 +1 @@ +Please write "something" diff --git a/examples/validate/root.vis b/examples/validate/root.vis new file mode 100644 index 0000000..3125a8f --- /dev/null +++ b/examples/validate/root.vis @@ -0,0 +1,6 @@ +LOAD verifyinput 0 +MAP verifyinput +HALT +RELOAD verifyinput +CATCH . 8 1 +MOVE end diff --git a/vm/runner.go b/vm/runner.go index cffdd7d..43240fa 100644 --- a/vm/runner.go +++ b/vm/runner.go @@ -192,23 +192,29 @@ func(vm *Vm) RunCatch(b []byte, ctx context.Context) ([]byte, error) { } r, err := vm.st.MatchFlag(sig, mode) if err != nil { - _, err = vm.st.SetFlag(state.FLAG_TERMINATE) - if err != nil { - panic(err) + var perr error + _, perr = vm.st.SetFlag(state.FLAG_TERMINATE) + if perr != nil { + panic(perr) } log.Printf("terminate set") return b, err } if r { - log.Printf("catch at flag %v, moving to %v", sig, sym) //bitField, d) + //b = append(bh, b...) + //vm.st.Down(sym) + //vm.ca.Push() + actualSym, _, err := applyTarget([]byte(sym), vm.st, vm.ca, ctx) + if err != nil { + return b, err + } + log.Printf("catch at flag %v, moving to '%v' ('%v')", sig, sym, actualSym) + sym = actualSym bh, err := vm.rs.GetCode(sym) if err != nil { return b, err } - //b = append(bh, b...) b = bh - vm.st.Down(sym) - vm.ca.Push() } return b, nil }