vise/engine/loop.go

53 lines
1.1 KiB
Go
Raw Permalink Normal View History

2023-04-09 16:58:35 +02:00
package engine
import (
"bufio"
"context"
"fmt"
"io"
"log"
2023-04-09 16:58:35 +02:00
"strings"
)
2023-04-12 19:04:36 +02:00
// Loop starts an engine execution loop with the given symbol as the starting node.
//
// The root reads inputs from the provided reader, one line at a time.
//
// It will execute until running out of bytecode in the buffer.
//
// Any error not handled by the engine will terminate the oop and return an error.
//
// Rendered output is written to the provided writer.
2023-04-13 01:38:33 +02:00
func Loop(en *Engine, reader io.Reader, writer io.Writer, ctx context.Context) error {
err := en.WriteResult(writer, ctx)
2023-04-12 19:04:36 +02:00
if err != nil {
return err
}
writer.Write([]byte{0x0a})
2023-04-09 16:58:35 +02:00
running := true
bufReader := bufio.NewReader(reader)
2023-04-09 16:58:35 +02:00
for running {
in, err := bufReader.ReadString('\n')
if err == io.EOF {
log.Printf("EOF found, that's all folks")
return nil
}
2023-04-09 16:58:35 +02:00
if err != nil {
return fmt.Errorf("cannot read input: %v\n", err)
}
in = strings.TrimSpace(in)
running, err = en.Exec([]byte(in), ctx)
if err != nil {
return fmt.Errorf("unexpected termination: %v\n", err)
}
2023-04-12 09:30:35 +02:00
err = en.WriteResult(writer, ctx)
if err != nil {
return err
}
writer.Write([]byte{0x0a})
2023-04-09 16:58:35 +02:00
}
return nil
}