github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/structs/for.go (about)

     1  package structs
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  
     7  	"github.com/lmorg/murex/lang"
     8  	"github.com/lmorg/murex/lang/types"
     9  )
    10  
    11  func init() {
    12  	lang.DefineFunction("for", cmdFor, types.Generic)
    13  }
    14  
    15  // Example usage:
    16  // for ( i=1; i<6; i++ ) { echo $i }
    17  func cmdFor(p *lang.Process) (err error) {
    18  	p.Stdout.SetDataType(types.Generic)
    19  
    20  	cblock, err := p.Parameters.String(0)
    21  	if err != nil {
    22  		return err
    23  	}
    24  
    25  	block, err := p.Parameters.Block(1)
    26  	if err != nil {
    27  		return err
    28  	}
    29  
    30  	parameters := strings.Split(string(cblock), ";")
    31  	if len(parameters) != 3 {
    32  		return errors.New("invalid syntax. Must be ( variable; conditional; incremental )")
    33  	}
    34  
    35  	variable := "let " + parameters[0]
    36  	conditional := "= " + parameters[1]
    37  	incremental := "let " + parameters[2]
    38  
    39  	_, err = p.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN | lang.F_NO_STDOUT).Execute([]rune(variable))
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	rConditional := []rune(conditional)
    45  	rIncremental := []rune(incremental)
    46  
    47  	for {
    48  		if p.HasCancelled() {
    49  			return errors.New(errCancelled)
    50  		}
    51  
    52  		fork := p.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN | lang.F_CREATE_STDOUT)
    53  		i, err := fork.Execute(rConditional)
    54  		if err != nil {
    55  			return err
    56  		}
    57  
    58  		b, err := fork.Stdout.ReadAll()
    59  		if err != nil {
    60  			return err
    61  		}
    62  		if !types.IsTrue(b, i) {
    63  			return nil
    64  		}
    65  
    66  		// Execute block
    67  		p.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN).Execute(block)
    68  
    69  		// Increment counter
    70  		_, err = p.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN | lang.F_NO_STDOUT).Execute(rIncremental)
    71  		if err != nil {
    72  			return err
    73  		}
    74  	}
    75  
    76  	//return nil
    77  }