diff --git a/Makefile b/Makefile index f5e543c..54ac4dc 100644 --- a/Makefile +++ b/Makefile @@ -3,4 +3,4 @@ examples: profile .PHONY: profile profile: - bash examples/compile.sh examples/profile + bash examples/compile.bash examples/profile diff --git a/examples/compile.bash b/examples/compile.bash index c77eeb2..119da1f 100644 --- a/examples/compile.bash +++ b/examples/compile.bash @@ -1,4 +1,4 @@ -for f in $(ls $1); do +for f in $(ls $1/*.vis); do b=$(basename $f) b=${b%.*} go run ./dev/asm $1/$b.vis > $1/$b.bin diff --git a/examples/profile/entry_email b/examples/profile/entry_email new file mode 100644 index 0000000..da93ff1 --- /dev/null +++ b/examples/profile/entry_email @@ -0,0 +1,2 @@ +Your email is now: {{.myemail}} +Enter new email. diff --git a/examples/profile/entry_email.save.vis b/examples/profile/entry_email.save.vis new file mode 100644 index 0000000..f00c7b5 --- /dev/null +++ b/examples/profile/entry_email.save.vis @@ -0,0 +1,3 @@ +LOAD entry_email_save 0 +RELOAD myemail +MOVE _ diff --git a/examples/profile/entry_email.vis b/examples/profile/entry_email.vis new file mode 100644 index 0000000..8a9d461 --- /dev/null +++ b/examples/profile/entry_email.vis @@ -0,0 +1,6 @@ +LOAD myemail 32 +MAP myemail +MOUT 0 "abort" +HALT +INCMP 0 _ +INCMP * entry_email_save diff --git a/examples/profile/entry_name_save b/examples/profile/entry_name_save deleted file mode 100644 index e69de29..0000000 diff --git a/examples/profile/entry_name_save.vis b/examples/profile/entry_name_save.vis index 9a28f13..570f91b 100644 --- a/examples/profile/entry_name_save.vis +++ b/examples/profile/entry_name_save.vis @@ -1,3 +1,2 @@ -LOAD entry_name_save 0 RELOAD myname MOVE _ diff --git a/examples/profile/main.go b/examples/profile/main.go index 8bfce79..6c74ff4 100644 --- a/examples/profile/main.go +++ b/examples/profile/main.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "io/ioutil" + "log" "os" "path" @@ -22,6 +23,7 @@ var ( ) func nameSave(sym string, input []byte, ctx context.Context) (resource.Result, error) { + log.Printf("writing name to file") fp := path.Join(scriptDir, "myname.txt") err := ioutil.WriteFile(fp, input, 0600) return resource.Result{}, err diff --git a/examples/profile/myemail.txt b/examples/profile/myemail.txt new file mode 100644 index 0000000..a85db9c --- /dev/null +++ b/examples/profile/myemail.txt @@ -0,0 +1 @@ +not set \ No newline at end of file diff --git a/examples/profile/myname.txt b/examples/profile/myname.txt index c01de2b..a85db9c 100644 --- a/examples/profile/myname.txt +++ b/examples/profile/myname.txt @@ -1 +1 @@ -inky \ No newline at end of file +not set \ No newline at end of file diff --git a/state/state.go b/state/state.go index 6e3978c..11700bc 100644 --- a/state/state.go +++ b/state/state.go @@ -113,11 +113,6 @@ func(st *State) ResetFlag(bitIndex uint32) (bool, error) { return true, nil } -// ResetBaseFlags restes all builtin flags not writeable by client. -func(st *State) ResetBaseFlags() { - st.Flags[0] = 0 -} - // GetFlag returns the state of the flag at the given bit field index. // // Fails if bit field index is out of range. diff --git a/vm/runner.go b/vm/runner.go index db62bda..d7acca3 100644 --- a/vm/runner.go +++ b/vm/runner.go @@ -60,7 +60,11 @@ func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { log.Printf("terminate set! bailing!") return []byte{}, nil } - vm.st.ResetBaseFlags() + //vm.st.ResetBaseFlags() + _, err = vm.st.ResetFlag(state.FLAG_TERMINATE) + if err != nil { + panic(err) + } _, err = vm.st.SetFlag(state.FLAG_DIRTY) if err != nil { panic(err) @@ -271,13 +275,14 @@ func(vm *Vm) RunMove(b []byte, ctx context.Context) ([]byte, error) { } // RunIncmp executes the INCMP opcode +// TODO: create state transition table and simplify flow func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) { sym, target, b, err := ParseInCmp(b) if err != nil { return b, err } - change, err := vm.st.SetFlag(state.FLAG_READIN) + reading, err := vm.st.GetFlag(state.FLAG_READIN) if err != nil { panic(err) } @@ -286,7 +291,7 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) { panic(err) } if have { - if change { + if !reading { _, err = vm.st.ResetFlag(state.FLAG_INMATCH) if err != nil { panic(err) @@ -295,18 +300,24 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) { log.Printf("ignoring input %s, already have match", sym) return b, nil } + } else { + _, err = vm.st.SetFlag(state.FLAG_READIN) + if err != nil { + panic(err) + } } input, err := vm.st.GetInput() if err != nil { return b, err } - log.Printf("sym is %s", sym) - if sym == "*" { + log.Printf("testing sym %s input %s", sym, input) + + if !have && sym == "*" { log.Printf("input wildcard match ('%s'), target '%s'", input, target) } else { if sym != string(input) { return b, nil - } + } log.Printf("input match for '%s', target '%s'", input, target) } diff --git a/vm/runner_test.go b/vm/runner_test.go index b26e18e..fc18c63 100644 --- a/vm/runner_test.go +++ b/vm/runner_test.go @@ -426,7 +426,6 @@ func TestRunReturn(t *testing.T) { var err error st.Down("root") - st.SetInput([]byte("0")) b := NewLine(nil, INCMP, []string{"0", "bar"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, INCMP, []string{"1", "_"}, nil, nil) @@ -434,6 +433,7 @@ func TestRunReturn(t *testing.T) { ctx := context.TODO() + st.SetInput([]byte("0")) b, err = vm.Run(b, ctx) if err != nil { t.Fatal(err) @@ -522,3 +522,57 @@ func TestInputBranch(t *testing.T) { t.Fatalf("expected 'one', got %s", location) } } + +func TestInputIgnore(t *testing.T) { + st := state.NewState(5) + rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil) + + var err error + + st.Down("root") + + b := NewLine(nil, INCMP, []string{"foo", "one"}, nil, nil) + b = NewLine(b, INCMP, []string{"bar", "two"}, nil, nil) + + ctx := context.TODO() + + st.SetInput([]byte("foo")) + b, err = vm.Run(b, ctx) + if err != nil { + t.Fatal(err) + } + + location, _ := st.Where() + if location != "one" { + t.Fatalf("expected 'one', got %s", location) + } +} + +func TestInputIgnoreWildcard(t *testing.T) { + st := state.NewState(5) + rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil) + + var err error + + st.Down("root") + + b := NewLine(nil, INCMP, []string{"foo", "one"}, nil, nil) + b = NewLine(b, INCMP, []string{"*", "two"}, nil, nil) + + ctx := context.TODO() + + st.SetInput([]byte("foo")) + b, err = vm.Run(b, ctx) + if err != nil { + t.Fatal(err) + } + + location, _ := st.Where() + if location != "one" { + t.Fatalf("expected 'one', got %s", location) + } +}