Add hello world example
This commit is contained in:
parent
100f7f3b48
commit
afb3ff3a36
5
Makefile
5
Makefile
@ -1,4 +1,4 @@
|
||||
examples: profile session
|
||||
examples: profile session helloworld
|
||||
|
||||
.PHONY: examples
|
||||
|
||||
@ -7,3 +7,6 @@ profile:
|
||||
|
||||
session:
|
||||
bash examples/compile.bash examples/session
|
||||
|
||||
helloworld:
|
||||
bash examples/compile.bash examples/helloworld
|
||||
|
@ -38,6 +38,7 @@ Original motivation was to create a simple templating renderer for USSD clients,
|
||||
|
||||
* Breakpoints.
|
||||
* Key/value database reference example.
|
||||
* Same-page catch with dedicated error string to prepend to template
|
||||
|
||||
|
||||
## Opcodes
|
||||
|
@ -23,11 +23,20 @@ func main() {
|
||||
|
||||
ctx := context.Background()
|
||||
en := engine.NewSizedEngine(dir, uint32(size))
|
||||
err := en.Init(ctx)
|
||||
cont, err := en.Init(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "engine init exited with error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if !cont {
|
||||
_, err = en.WriteResult(os.Stdout, ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "dead init write error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stdout.Write([]byte{0x0a})
|
||||
os.Exit(0)
|
||||
}
|
||||
err = engine.Loop(&en, os.Stdin, os.Stdout, ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
|
||||
|
@ -53,37 +53,34 @@ func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memor
|
||||
// Init must be explicitly called before using the Engine instance.
|
||||
//
|
||||
// It loads and executes code for the start node.
|
||||
func(en *Engine) Init(ctx context.Context) error {
|
||||
func(en *Engine) Init(ctx context.Context) (bool, error) {
|
||||
if en.initd {
|
||||
log.Printf("already initialized")
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
sym := en.root
|
||||
if sym == "" {
|
||||
return fmt.Errorf("start sym empty")
|
||||
return false, fmt.Errorf("start sym empty")
|
||||
}
|
||||
inSave, _ := en.st.GetInput()
|
||||
err := en.st.SetInput([]byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil)
|
||||
log.Printf("start new init VM run with code %x", b)
|
||||
b, err = en.vm.Run(b, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return fmt.Errorf("no code left after init, that's just useless and sad")
|
||||
return false, err
|
||||
}
|
||||
|
||||
log.Printf("ended init VM run with code %x", b)
|
||||
en.st.SetCode(b)
|
||||
err = en.st.SetInput(inSave)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
en.initd = true
|
||||
return nil
|
||||
return len(b) > 0, nil
|
||||
}
|
||||
|
||||
// Exec processes user input against the current state of the virtual machine environment.
|
||||
@ -99,13 +96,11 @@ func(en *Engine) Init(ctx context.Context) error {
|
||||
func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||
var err error
|
||||
if en.st.Moves == 0 {
|
||||
err = en.Init(ctx)
|
||||
cont, err := en.Init(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(input) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
return cont, nil
|
||||
}
|
||||
err = vm.ValidInput(input)
|
||||
if err != nil {
|
||||
@ -146,7 +141,7 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||
en.st.SetCode(code)
|
||||
if len(code) == 0 {
|
||||
log.Printf("runner finished with no remaining code")
|
||||
err = en.reset(ctx)
|
||||
_, err = en.reset(ctx)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -168,17 +163,17 @@ func(en *Engine) WriteResult(w io.Writer, ctx context.Context) (int, error) {
|
||||
}
|
||||
|
||||
// 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) (bool, error) {
|
||||
var err error
|
||||
var isTop bool
|
||||
for !isTop {
|
||||
isTop, err = en.st.Top()
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
_, err = en.st.Up()
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
en.ca.Pop()
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func TestEngineInit(t *testing.T) {
|
||||
Root: "root",
|
||||
}, &st, &rs, ca, ctx)
|
||||
|
||||
err = en.Init(ctx)
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -141,7 +141,8 @@ func TestEngineExecInvalidInput(t *testing.T) {
|
||||
en := NewEngine(Config{
|
||||
Root: "root",
|
||||
}, &st, &rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -161,7 +162,8 @@ func TestEngineResumeTerminated(t *testing.T) {
|
||||
en := NewEngine(Config{
|
||||
Root: "root",
|
||||
}, &st, &rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ func TestLoopTop(t *testing.T) {
|
||||
Root: "root",
|
||||
}
|
||||
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -60,7 +61,8 @@ func TestLoopBackForth(t *testing.T) {
|
||||
Root: "root",
|
||||
}
|
||||
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -94,7 +96,8 @@ func TestLoopBrowse(t *testing.T) {
|
||||
Root: "root",
|
||||
}
|
||||
en := NewEngine(cfg, &st, &rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
1
examples/helloworld/que.txt.orig
Normal file
1
examples/helloworld/que.txt.orig
Normal file
@ -0,0 +1 @@
|
||||
world
|
1
examples/helloworld/root
Normal file
1
examples/helloworld/root
Normal file
@ -0,0 +1 @@
|
||||
hello, {{.que}}!
|
2
examples/helloworld/root.vis
Normal file
2
examples/helloworld/root.vis
Normal file
@ -0,0 +1,2 @@
|
||||
LOAD que 5
|
||||
MAP que
|
@ -124,7 +124,8 @@ func main() {
|
||||
}
|
||||
ctx := context.Background()
|
||||
en := engine.NewEngine(cfg, &st, rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
@ -72,7 +72,8 @@ func main() {
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||
en := engine.NewEngine(cfg, &st, rs, ca, ctx)
|
||||
err := en.Init(ctx)
|
||||
var err error
|
||||
_, err = en.Init(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "engine init fail: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
Loading…
Reference in New Issue
Block a user