diff --git a/dev/interactive/main.go b/dev/interactive/main.go index 1b85bb8..13d451a 100644 --- a/dev/interactive/main.go +++ b/dev/interactive/main.go @@ -22,10 +22,14 @@ func main() { fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir) ctx := context.Background() - en := engine.NewSizedEngine(dir, uint32(size)) - err := engine.Loop(&en, os.Stdin, os.Stdout, ctx) + en, err := engine.NewSizedEngine(dir, uint32(size)) if err != nil { - fmt.Fprintf(os.Stderr, "loop exited with error: %v", err) + fmt.Fprintf(os.Stderr, "engine create 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/engine/default.go b/engine/default.go index aea3a5a..8fc2442 100644 --- a/engine/default.go +++ b/engine/default.go @@ -9,7 +9,7 @@ import ( ) // NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints. -func NewDefaultEngine(dir string) Engine { +func NewDefaultEngine(dir string) (Engine, error) { st := state.NewState(0) rs := resource.NewFsResource(dir) ca := cache.NewCache() @@ -21,7 +21,7 @@ func NewDefaultEngine(dir string) Engine { } // NewSizedEngine is a convenience function to instantiate a filesystem-backed engine with a specified output constraint. -func NewSizedEngine(dir string, size uint32) Engine { +func NewSizedEngine(dir string, size uint32) (Engine, error) { st := state.NewState(0) rs := resource.NewFsResource(dir) ca := cache.NewCache() diff --git a/engine/engine.go b/engine/engine.go index 9efd98f..b5dc4e8 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -32,7 +32,7 @@ type Engine struct { } // NewEngine creates a new Engine -func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memory, ctx context.Context) Engine { +func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memory, ctx context.Context) (Engine, error) { var szr *render.Sizer if cfg.OutputSize > 0 { szr = render.NewSizer(cfg.OutputSize) @@ -44,10 +44,11 @@ func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memor ca: ca, vm: vm.NewVm(st, rs, ca, szr), } + var err error if st.Moves == 0 { - engine.Init(cfg.Root, ctx) + err = engine.Init(cfg.Root, ctx) } - return engine + return engine, err } // Init must be explicitly called before using the Engine instance. @@ -71,6 +72,9 @@ func(en *Engine) Init(sym string, ctx context.Context) error { if err != nil { return err } + if len(b) == 0 { + return fmt.Errorf("no code left after init, that's just useless and sad") + } log.Printf("ended init VM run with code %x", b) en.st.SetCode(b) en.initd = true diff --git a/engine/engine_test.go b/engine/engine_test.go index 7cd65c7..7a272ad 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -81,9 +81,12 @@ func TestEngineInit(t *testing.T) { rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - en := NewEngine(Config{ + en, err := NewEngine(Config{ Root: "root", }, &st, &rs, ca, ctx) + if err != nil { + t.Fatal(err) + } // w := bytes.NewBuffer(nil) _, err = en.WriteResult(w, ctx) @@ -133,8 +136,14 @@ func TestEngineExecInvalidInput(t *testing.T) { rs := NewFsWrapper(dataDir, &st) ca := cache.NewCache().WithCacheSize(1024) - en := NewEngine(Config{}, &st, &rs, ca, ctx) - err := en.Init("root", ctx) + + en, err := NewEngine(Config{ + Root: "root", + }, &st, &rs, ca, ctx) + if err != nil { + t.Fatal(err) + } + err = en.Init("root", ctx) if err != nil { t.Fatal(err) } diff --git a/engine/loop_test.go b/engine/loop_test.go index 3fd0a4b..4b4e665 100644 --- a/engine/loop_test.go +++ b/engine/loop_test.go @@ -23,8 +23,11 @@ func TestLoopTop(t *testing.T) { cfg := Config{ Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) - err := en.Init("root", ctx) + en, err := NewEngine(cfg, &st, &rs, ca, ctx) + if err != nil { + t.Fatal(err) + } + err = en.Init("root", ctx) if err != nil { t.Fatal(err) } @@ -59,8 +62,11 @@ func TestLoopBackForth(t *testing.T) { cfg := Config{ Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) - err := en.Init("root", ctx) + en, err := NewEngine(cfg, &st, &rs, ca, ctx) + if err != nil { + t.Fatal(err) + } + err = en.Init("root", ctx) if err != nil { t.Fatal(err) } @@ -93,8 +99,11 @@ func TestLoopBrowse(t *testing.T) { OutputSize: 68, Root: "root", } - en := NewEngine(cfg, &st, &rs, ca, ctx) - err := en.Init("root", ctx) + en, err := NewEngine(cfg, &st, &rs, ca, ctx) + if err != nil { + t.Fatal(err) + } + err = en.Init("root", ctx) if err != nil { t.Fatal(err) } diff --git a/engine/persist.go b/engine/persist.go index 2b7ad90..be2555e 100644 --- a/engine/persist.go +++ b/engine/persist.go @@ -24,7 +24,10 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input return err } - en := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx) + en, err := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx) + if err != nil { + return err + } c, err := en.WriteResult(w, ctx) if err != nil { diff --git a/examples/profile/main.go b/examples/profile/main.go index 2894db7..2ed4907 100644 --- a/examples/profile/main.go +++ b/examples/profile/main.go @@ -17,6 +17,10 @@ import ( "git.defalsify.org/vise/state" ) +const ( + USERFLAG_IDENTIFIED = iota + state.FLAG_USERSTART +) + var ( baseDir = testdataloader.GetBasePath() scriptDir = path.Join(baseDir, "examples", "profile") @@ -47,7 +51,7 @@ func main() { flag.Parse() fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir) - st := state.NewState(0) + st := state.NewState(1) rs := resource.NewFsResource(scriptDir) rs.AddLocalFunc("do_name_save", nameSave) rs.AddLocalFunc("do_email_save", emailSave) @@ -58,11 +62,15 @@ func main() { OutputSize: uint32(size), } ctx := context.Background() - en := engine.NewEngine(cfg, &st, &rs, ca, ctx) - - err := engine.Loop(&en, os.Stdin, os.Stdout, ctx) + en, err := engine.NewEngine(cfg, &st, &rs, ca, ctx) if err != nil { - fmt.Fprintf(os.Stderr, "loop exited with error: %v", err) + fmt.Fprintf(os.Stderr, "engine create 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/profile/root.vis b/examples/profile/root.vis index b77977b..40f8b0b 100644 --- a/examples/profile/root.vis +++ b/examples/profile/root.vis @@ -1,3 +1,3 @@ +CATCH identified 9 0 DOWN entry_name 0 "name" DOWN entry_email 1 "email" -DOWN entry_sex 2 "sex" diff --git a/state/flag.go b/state/flag.go index 295358c..075621f 100644 --- a/state/flag.go +++ b/state/flag.go @@ -6,6 +6,7 @@ const ( FLAG_TERMINATE = 3 FLAG_DIRTY = 4 FLAG_LOADFAIL = 5 + FLAG_USERSTART = 9 //FLAG_WRITEABLE = FLAG_LOADFAIL ) diff --git a/vm/runner.go b/vm/runner.go index d7acca3..6eacd3b 100644 --- a/vm/runner.go +++ b/vm/runner.go @@ -178,6 +178,11 @@ 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) + } + log.Printf("terminate set") return b, err } if r { @@ -190,7 +195,7 @@ func(vm *Vm) RunCatch(b []byte, ctx context.Context) ([]byte, error) { vm.st.Down(sym) vm.ca.Push() vm.Reset() - } + } return b, nil }