Add nomove state transition option, session partitioned interactive example
This commit is contained in:
parent
bf1d634474
commit
f06bca7abf
7
Makefile
7
Makefile
@ -1,6 +1,9 @@
|
|||||||
examples: profile
|
examples: profile session
|
||||||
|
|
||||||
.PHONY: profile
|
.PHONY: examples
|
||||||
|
|
||||||
profile:
|
profile:
|
||||||
bash examples/compile.bash examples/profile
|
bash examples/compile.bash examples/profile
|
||||||
|
|
||||||
|
session:
|
||||||
|
bash examples/compile.bash examples/session
|
||||||
|
@ -260,7 +260,7 @@ var (
|
|||||||
{"Comment", `(?:#)[^\n]*`},
|
{"Comment", `(?:#)[^\n]*`},
|
||||||
{"Ident", `^[A-Z]+`},
|
{"Ident", `^[A-Z]+`},
|
||||||
{"Size", `[0-9]+`},
|
{"Size", `[0-9]+`},
|
||||||
{"Sym", `[a-zA-Z_\*][a-zA-Z0-9_]*`},
|
{"Sym", `[a-zA-Z_\*\.][a-zA-Z0-9_]*`},
|
||||||
{"Whitespace", `[ \t]+`},
|
{"Whitespace", `[ \t]+`},
|
||||||
{"EOL", `[\n\r]+`},
|
{"EOL", `[\n\r]+`},
|
||||||
{"Quote", `["']`},
|
{"Quote", `["']`},
|
||||||
|
@ -22,12 +22,8 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
|
fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
en, err := engine.NewSizedEngine(dir, uint32(size))
|
en := engine.NewSizedEngine(dir, uint32(size))
|
||||||
if err != nil {
|
err := engine.Loop(&en, os.Stdin, os.Stdout, ctx)
|
||||||
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 {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints.
|
// NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints.
|
||||||
func NewDefaultEngine(dir string) (Engine, error) {
|
func NewDefaultEngine(dir string) Engine {
|
||||||
st := state.NewState(0)
|
st := state.NewState(0)
|
||||||
rs := resource.NewFsResource(dir)
|
rs := resource.NewFsResource(dir)
|
||||||
ca := cache.NewCache()
|
ca := cache.NewCache()
|
||||||
@ -21,7 +21,7 @@ func NewDefaultEngine(dir string) (Engine, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewSizedEngine is a convenience function to instantiate a filesystem-backed engine with a specified output constraint.
|
// NewSizedEngine is a convenience function to instantiate a filesystem-backed engine with a specified output constraint.
|
||||||
func NewSizedEngine(dir string, size uint32) (Engine, error) {
|
func NewSizedEngine(dir string, size uint32) Engine {
|
||||||
st := state.NewState(0)
|
st := state.NewState(0)
|
||||||
rs := resource.NewFsResource(dir)
|
rs := resource.NewFsResource(dir)
|
||||||
ca := cache.NewCache()
|
ca := cache.NewCache()
|
||||||
|
@ -33,7 +33,7 @@ type Engine struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewEngine creates a new Engine
|
// NewEngine creates a new Engine
|
||||||
func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memory, ctx context.Context) (Engine, error) {
|
func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memory, ctx context.Context) Engine {
|
||||||
var szr *render.Sizer
|
var szr *render.Sizer
|
||||||
if cfg.OutputSize > 0 {
|
if cfg.OutputSize > 0 {
|
||||||
szr = render.NewSizer(cfg.OutputSize)
|
szr = render.NewSizer(cfg.OutputSize)
|
||||||
@ -46,17 +46,19 @@ func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memor
|
|||||||
vm: vm.NewVm(st, rs, ca, szr),
|
vm: vm.NewVm(st, rs, ca, szr),
|
||||||
}
|
}
|
||||||
engine.root = cfg.Root
|
engine.root = cfg.Root
|
||||||
return engine, nil
|
|
||||||
|
return engine
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init must be explicitly called before using the Engine instance.
|
// Init must be explicitly called before using the Engine instance.
|
||||||
//
|
//
|
||||||
// It loads and executes code for the start node.
|
// It loads and executes code for the start node.
|
||||||
func(en *Engine) Init(sym string, ctx context.Context) error {
|
func(en *Engine) Init(ctx context.Context) error {
|
||||||
if en.initd {
|
if en.initd {
|
||||||
log.Printf("already initialized")
|
log.Printf("already initialized")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
sym := en.root
|
||||||
if sym == "" {
|
if sym == "" {
|
||||||
return fmt.Errorf("start sym empty")
|
return fmt.Errorf("start sym empty")
|
||||||
}
|
}
|
||||||
@ -97,7 +99,7 @@ func(en *Engine) Init(sym string, ctx context.Context) error {
|
|||||||
func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
if en.st.Moves == 0 {
|
if en.st.Moves == 0 {
|
||||||
err = en.Init(en.root, ctx)
|
err = en.Init(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -165,6 +167,7 @@ func(en *Engine) WriteResult(w io.Writer, ctx context.Context) (int, error) {
|
|||||||
return io.WriteString(w, r)
|
return io.WriteString(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start execution over at top node while keeping current state of client error flags.
|
||||||
func(en *Engine) reset(ctx context.Context) error {
|
func(en *Engine) reset(ctx context.Context) error {
|
||||||
var err error
|
var err error
|
||||||
var isTop bool
|
var isTop bool
|
||||||
@ -181,5 +184,5 @@ func(en *Engine) reset(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
en.st.Restart()
|
en.st.Restart()
|
||||||
en.initd = false
|
en.initd = false
|
||||||
return en.Init(en.root, ctx)
|
return en.Init(ctx)
|
||||||
}
|
}
|
||||||
|
@ -81,14 +81,11 @@ func TestEngineInit(t *testing.T) {
|
|||||||
rs := NewFsWrapper(dataDir, &st)
|
rs := NewFsWrapper(dataDir, &st)
|
||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
|
|
||||||
en, err := NewEngine(Config{
|
en := NewEngine(Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}, &st, &rs, ca, ctx)
|
}, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = en.Init("root", ctx)
|
err = en.Init(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -141,13 +138,10 @@ func TestEngineExecInvalidInput(t *testing.T) {
|
|||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
|
|
||||||
|
|
||||||
en, err := NewEngine(Config{
|
en := NewEngine(Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}, &st, &rs, ca, ctx)
|
}, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
err := en.Init(ctx)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = en.Init("root", ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -164,13 +158,10 @@ func TestEngineResumeTerminated(t *testing.T) {
|
|||||||
rs := NewFsWrapper(dataDir, &st)
|
rs := NewFsWrapper(dataDir, &st)
|
||||||
ca := cache.NewCache().WithCacheSize(1024)
|
ca := cache.NewCache().WithCacheSize(1024)
|
||||||
|
|
||||||
en, err := NewEngine(Config{
|
en := NewEngine(Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}, &st, &rs, ca, ctx)
|
}, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
err := en.Init(ctx)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = en.Init("root", ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,8 @@ func TestLoopTop(t *testing.T) {
|
|||||||
cfg := Config{
|
cfg := Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}
|
}
|
||||||
en, err := NewEngine(cfg, &st, &rs, ca, ctx)
|
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
err := en.Init(ctx)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = en.Init("root", ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -62,11 +59,8 @@ func TestLoopBackForth(t *testing.T) {
|
|||||||
cfg := Config{
|
cfg := Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}
|
}
|
||||||
en, err := NewEngine(cfg, &st, &rs, ca, ctx)
|
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
err := en.Init(ctx)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = en.Init("root", ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -99,11 +93,8 @@ func TestLoopBrowse(t *testing.T) {
|
|||||||
OutputSize: 68,
|
OutputSize: 68,
|
||||||
Root: "root",
|
Root: "root",
|
||||||
}
|
}
|
||||||
en, err := NewEngine(cfg, &st, &rs, ca, ctx)
|
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||||
if err != nil {
|
err := en.Init(ctx)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = en.Init("root", ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,7 @@ func RunPersisted(cfg Config, rs resource.Resource, pr persist.Persister, input
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
en, err := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx)
|
en := NewEngine(cfg, pr.GetState(), rs, pr.GetMemory(), ctx)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := en.WriteResult(w, ctx)
|
c, err := en.WriteResult(w, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -122,9 +122,10 @@ func main() {
|
|||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
en, err := engine.NewEngine(cfg, &st, rs, ca, ctx)
|
en := engine.NewEngine(cfg, &st, rs, ca, ctx)
|
||||||
|
err := en.Init(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "engine create fail: %v\n", err)
|
fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
examples/session/data.txt.orig
Normal file
0
examples/session/data.txt.orig
Normal file
2
examples/session/input
Normal file
2
examples/session/input
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
hey hey hey
|
||||||
|
your data is {{.do_save}}
|
4
examples/session/input.vis
Normal file
4
examples/session/input.vis
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
MAP do_save
|
||||||
|
HALT
|
||||||
|
RELOAD do_save
|
||||||
|
INCMP * .
|
85
examples/session/main.go
Normal file
85
examples/session/main.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"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", "session")
|
||||||
|
emptyResult = resource.Result{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func save(sym string, input []byte, ctx context.Context) (resource.Result, error) {
|
||||||
|
sessionId := ctx.Value("SessionId").(string)
|
||||||
|
sessionDir := path.Join(scriptDir, sessionId)
|
||||||
|
err := os.MkdirAll(sessionDir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return emptyResult, err
|
||||||
|
}
|
||||||
|
fp := path.Join(sessionDir, "data.txt")
|
||||||
|
if len(input) > 0 {
|
||||||
|
log.Printf("write data %s session %s", input, sessionId)
|
||||||
|
err = ioutil.WriteFile(fp, input, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return emptyResult, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r, err := ioutil.ReadFile(fp)
|
||||||
|
if err != nil {
|
||||||
|
err = ioutil.WriteFile(fp, []byte("(not set)"), 0600)
|
||||||
|
if err != nil {
|
||||||
|
return emptyResult, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resource.Result{
|
||||||
|
Content: string(r),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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(0)
|
||||||
|
rs := resource.NewFsResource(scriptDir)
|
||||||
|
rs.AddLocalFunc("do_save", save)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
2
examples/session/root.vis
Normal file
2
examples/session/root.vis
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
LOAD do_save 0
|
||||||
|
MOVE input
|
@ -1,11 +1,12 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FLAG_READIN = 1
|
FLAG_READIN = iota
|
||||||
FLAG_INMATCH = 2
|
FLAG_INMATCH
|
||||||
FLAG_TERMINATE = 3
|
FLAG_TERMINATE
|
||||||
FLAG_DIRTY = 4
|
FLAG_DIRTY
|
||||||
FLAG_LOADFAIL = 5
|
FLAG_WAIT
|
||||||
|
FLAG_LOADFAIL
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsWriteableFlag(flag uint32) bool {
|
func IsWriteableFlag(flag uint32) bool {
|
||||||
@ -17,3 +18,6 @@ func IsWriteableFlag(flag uint32) bool {
|
|||||||
//}
|
//}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FlagDebugger struct {
|
||||||
|
}
|
||||||
|
@ -208,6 +208,10 @@ func(st *State) Next() (uint16, error) {
|
|||||||
return st.SizeIdx, nil
|
return st.SizeIdx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func(st *State) Same() {
|
||||||
|
st.Moves += 1
|
||||||
|
}
|
||||||
|
|
||||||
// Previous moves to the next sink page index.
|
// Previous moves to the next sink page index.
|
||||||
//
|
//
|
||||||
// Fails if try to move beyond index 0.
|
// Fails if try to move beyond index 0.
|
||||||
@ -338,7 +342,7 @@ func(st *State) Restart() error {
|
|||||||
|
|
||||||
// String implements String interface
|
// String implements String interface
|
||||||
func(st State) String() string {
|
func(st State) String() string {
|
||||||
return fmt.Sprintf("moves %v idx %v path: %s", st.Moves, st.SizeIdx, strings.Join(st.ExecPath, "/"))
|
return fmt.Sprintf("moves %v idx %v flags: 0x%x path: %s", st.Moves, st.SizeIdx, st.Flags, strings.Join(st.ExecPath, "/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializes all flags not in control of client.
|
// initializes all flags not in control of client.
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
inputRegexStr = "^[a-zA-Z0-9].*$"
|
inputRegexStr = "^[a-zA-Z0-9].*$"
|
||||||
inputRegex = regexp.MustCompile(inputRegexStr)
|
inputRegex = regexp.MustCompile(inputRegexStr)
|
||||||
ctrlRegexStr = "^[><_^]$"
|
ctrlRegexStr = "^[><_^.]$"
|
||||||
ctrlRegex = regexp.MustCompile(ctrlRegexStr)
|
ctrlRegex = regexp.MustCompile(ctrlRegexStr)
|
||||||
symRegexStr = "^[a-zA-Z0-9][a-zA-Z0-9_]+$"
|
symRegexStr = "^[a-zA-Z0-9][a-zA-Z0-9_]+$"
|
||||||
symRegex = regexp.MustCompile(symRegexStr)
|
symRegex = regexp.MustCompile(symRegexStr)
|
||||||
@ -76,7 +76,7 @@ func CheckTarget(target []byte, st *state.State) (bool, error) {
|
|||||||
switch target[0] {
|
switch target[0] {
|
||||||
case '_':
|
case '_':
|
||||||
topOk, err := st.Top()
|
topOk, err := st.Top()
|
||||||
if err!= nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return topOk, nil
|
return topOk, nil
|
||||||
@ -137,6 +137,10 @@ func applyTarget(target []byte, st *state.State, ca cache.Memory, ctx context.Co
|
|||||||
return sym, idx, err
|
return sym, idx, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case '.':
|
||||||
|
st.Same()
|
||||||
|
location, idx := st.Where()
|
||||||
|
return location, idx, nil
|
||||||
default:
|
default:
|
||||||
sym = string(target)
|
sym = string(target)
|
||||||
err := st.Down(sym)
|
err := st.Down(sym)
|
||||||
|
42
vm/runner.go
42
vm/runner.go
@ -31,6 +31,7 @@ func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, sizer *render
|
|||||||
sizer: sizer,
|
sizer: sizer,
|
||||||
}
|
}
|
||||||
vmi.Reset()
|
vmi.Reset()
|
||||||
|
log.Printf("vm created with state: %v", st)
|
||||||
return vmi
|
return vmi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +66,19 @@ func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitChange, err := vm.st.ResetFlag(state.FLAG_WAIT)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if waitChange {
|
||||||
|
log.Printf("waitchange")
|
||||||
|
_, err = vm.st.ResetFlag(state.FLAG_INMATCH)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_, err = vm.st.SetFlag(state.FLAG_DIRTY)
|
_, err = vm.st.SetFlag(state.FLAG_DIRTY)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -295,12 +309,7 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if have {
|
if have {
|
||||||
if !reading {
|
if reading {
|
||||||
_, err = vm.st.ResetFlag(state.FLAG_INMATCH)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("ignoring input %s, already have match", sym)
|
log.Printf("ignoring input %s, already have match", sym)
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
@ -320,11 +329,11 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
log.Printf("input wildcard match ('%s'), target '%s'", input, target)
|
log.Printf("input wildcard match ('%s'), target '%s'", input, target)
|
||||||
} else {
|
} else {
|
||||||
if sym != string(input) {
|
if sym != string(input) {
|
||||||
|
log.Printf("foo")
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
log.Printf("input match for '%s', target '%s'", input, target)
|
log.Printf("input match for '%s', target '%s'", input, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = vm.st.SetFlag(state.FLAG_INMATCH)
|
_, err = vm.st.SetFlag(state.FLAG_INMATCH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -334,13 +343,10 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
target, _, err = applyTarget([]byte(target), vm.st, vm.ca, ctx)
|
newTarget, _, err := applyTarget([]byte(target), vm.st, vm.ca, ctx)
|
||||||
|
|
||||||
_, ok := err.(*state.IndexError)
|
_, ok := err.(*state.IndexError)
|
||||||
if ok {
|
if ok {
|
||||||
_, err = vm.st.ResetFlag(state.FLAG_INMATCH)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_, err = vm.st.SetFlag(state.FLAG_READIN)
|
_, err = vm.st.SetFlag(state.FLAG_READIN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -349,12 +355,16 @@ func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target = newTarget
|
||||||
|
|
||||||
vm.Reset()
|
vm.Reset()
|
||||||
|
|
||||||
code, err := vm.rs.GetCode(target)
|
code, err := vm.rs.GetCode(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
log.Printf("bar")
|
||||||
log.Printf("loaded additional code for target '%s': %x", target, code)
|
log.Printf("loaded additional code for target '%s': %x", target, code)
|
||||||
b = append(b, code...)
|
b = append(b, code...)
|
||||||
return b, err
|
return b, err
|
||||||
@ -368,7 +378,12 @@ func(vm *Vm) RunHalt(b []byte, ctx context.Context) ([]byte, error) {
|
|||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
log.Printf("found HALT, stopping")
|
log.Printf("found HALT, stopping")
|
||||||
return b, err
|
|
||||||
|
_, err = vm.st.SetFlag(state.FLAG_WAIT)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunMSize executes the MSIZE opcode
|
// RunMSize executes the MSIZE opcode
|
||||||
@ -454,6 +469,7 @@ func(vm *Vm) refresh(key string, rs resource.Resource, ctx context.Context) (str
|
|||||||
input, _ := vm.st.GetInput()
|
input, _ := vm.st.GetInput()
|
||||||
r, err := fn(key, input, ctx)
|
r, err := fn(key, input, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("loadfail %v", err)
|
||||||
var perr error
|
var perr error
|
||||||
_, perr = vm.st.SetFlag(state.FLAG_LOADFAIL)
|
_, perr = vm.st.SetFlag(state.FLAG_LOADFAIL)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
|
@ -541,6 +541,7 @@ func TestInputIgnore(t *testing.T) {
|
|||||||
|
|
||||||
b := NewLine(nil, INCMP, []string{"foo", "one"}, nil, nil)
|
b := NewLine(nil, INCMP, []string{"foo", "one"}, nil, nil)
|
||||||
b = NewLine(b, INCMP, []string{"bar", "two"}, nil, nil)
|
b = NewLine(b, INCMP, []string{"bar", "two"}, nil, nil)
|
||||||
|
b = NewLine(b, HALT, nil, nil, nil)
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user