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 }