github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/structs/andor.go (about) 1 package structs 2 3 import ( 4 "errors" 5 6 "github.com/lmorg/murex/lang" 7 "github.com/lmorg/murex/lang/types" 8 ) 9 10 func init() { 11 lang.DefineFunction("and", cmdAnd, types.Boolean) 12 lang.DefineFunction("!and", cmdAnd, types.Boolean) 13 lang.DefineFunction("or", cmdOr, types.Boolean) 14 lang.DefineFunction("!or", cmdOr, types.Boolean) 15 } 16 17 const errCancelled = "user has cancelled processing mid-way through the execution of this control flow structure" 18 19 func cmdAnd(p *lang.Process) error { return cmdAndOr(p, true) } 20 func cmdOr(p *lang.Process) error { return cmdAndOr(p, false) } 21 22 func cmdAndOr(p *lang.Process, isAnd bool) error { 23 p.Stdout.SetDataType(types.Boolean) 24 25 for i := 0; i < p.Parameters.Len(); i++ { 26 if p.HasCancelled() { 27 return errors.New(errCancelled) 28 } 29 30 block, err := p.Parameters.Block(i) 31 if err != nil { 32 return err 33 } 34 35 //stdout := streams.NewStdin() 36 //i, err := lang.RunBlockExistingConfigSpace(block, nil, stdout, nil, p) 37 fork := p.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN | lang.F_CREATE_STDOUT | lang.F_NO_STDERR) 38 i, err := fork.Execute(block) 39 if err != nil { 40 return err 41 } 42 43 if p.HasCancelled() { 44 return errors.New(errCancelled) 45 } 46 47 b, err := fork.Stdout.ReadAll() 48 if err != nil { 49 return err 50 } 51 conditional := types.IsTrue(b, i) 52 53 if isAnd { 54 // --- and --- 55 if (!conditional && !p.IsNot) || (conditional && p.IsNot) { 56 p.ExitNum = 1 57 return nil 58 } 59 } else { 60 // --- or --- 61 if (conditional && !p.IsNot) || (!conditional && p.IsNot) { 62 p.ExitNum = -1 63 return nil 64 } 65 } 66 } 67 68 if isAnd { 69 // --- and --- 70 p.ExitNum = -1 71 return nil 72 } 73 74 // --- or --- 75 p.ExitNum = 1 76 return nil 77 }