go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

loop.go (1214B)


      1 package engine
      2 
      3 import (
      4 	"bufio"
      5 	"context"
      6 	"fmt"
      7 	"io"
      8 	"strings"
      9 )
     10 
     11 // Loop starts an engine execution loop with the given symbol as the starting node.
     12 //
     13 // The root reads inputs from the provided reader, one line at a time.
     14 //
     15 // It will execute until running out of bytecode in the buffer.
     16 //
     17 // Any error not handled by the engine will terminate the oop and return an error.
     18 //
     19 // Rendered output is written to the provided writer.
     20 func Loop(ctx context.Context, en EngineIsh, reader io.Reader, writer io.Writer) error {
     21 	defer en.Finish()
     22 	var err error
     23 	_, err = en.WriteResult(ctx, writer)
     24 	if err != nil {
     25 		return err
     26 	}
     27 	writer.Write([]byte{0x0a})
     28 
     29 	running := true
     30 	bufReader := bufio.NewReader(reader)
     31 	for running {
     32 		in, err := bufReader.ReadString('\n')
     33 		if err == io.EOF {
     34 			Logg.DebugCtxf(ctx, "EOF found, that's all folks")
     35 			return nil
     36 		}
     37 		if err != nil {
     38 			return fmt.Errorf("cannot read input: %v\n", err)
     39 		}
     40 		in = strings.TrimSpace(in)
     41 		running, err = en.Exec(ctx, []byte(in))
     42 		if err != nil {
     43 			return fmt.Errorf("unexpected termination: %v\n", err)
     44 		}
     45 		_, err = en.WriteResult(ctx, writer)
     46 		if err != nil {
     47 			return err
     48 		}
     49 		writer.Write([]byte{0x0a})
     50 
     51 	}
     52 	return nil
     53 }