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

     1  package structs
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/lmorg/murex/lang"
     7  	"github.com/lmorg/murex/lang/types"
     8  )
     9  
    10  func init() {
    11  	lang.DefineFunction("return", cmdReturn, types.Null)
    12  	lang.DefineFunction("break", cmdBreak, types.Null)
    13  	lang.DefineFunction("continue", cmdContinue, types.Null)
    14  }
    15  
    16  func cmdReturn(p *lang.Process) error {
    17  	p.ExitNum, _ = p.Parameters.Int(0)
    18  	return breakUpwards(p, p.Scope.Name.String(), p.ExitNum)
    19  }
    20  
    21  func cmdBreak(p *lang.Process) error {
    22  	name, _ := p.Parameters.String(0)
    23  	if name == "" {
    24  		p.Done()
    25  		p.Parent.Done()
    26  		p.Parent.KillForks(0)
    27  		return fmt.Errorf(
    28  			"missing parameter. Stopping execution of `%s` as a precaution",
    29  			p.Parent.Name.String(),
    30  		)
    31  	}
    32  
    33  	return breakUpwards(p, name, 0)
    34  }
    35  
    36  func breakUpwards(p *lang.Process, name string, exitNum int) error {
    37  	scope := p.Scope.Id
    38  	proc := p.Parent
    39  	for {
    40  		proc.ExitNum = exitNum
    41  		proc.KillForks(exitNum)
    42  		proc.Done()
    43  
    44  		if proc.Name.String() == name {
    45  			return nil
    46  		}
    47  
    48  		if proc.Id == scope {
    49  			return fmt.Errorf(
    50  				"no block found named `%s` within the scope of `%s`",
    51  				name, p.Scope.Name.String(),
    52  			)
    53  		}
    54  
    55  		proc = proc.Parent
    56  	}
    57  }
    58  
    59  func cmdContinue(p *lang.Process) error {
    60  	var name string
    61  
    62  	name, _ = p.Parameters.String(0)
    63  	if name == "" {
    64  		name = p.Parent.Name.String()
    65  		p.Stderr.Writeln([]byte(fmt.Sprintf(
    66  			"missing parameter. Jumping to `%s` as a precaution", name)))
    67  	}
    68  
    69  	scope := p.Scope.Id
    70  	proc := p.Parent
    71  	for {
    72  		if proc.Name.String() == name {
    73  			//proc.IpcContinue <- true
    74  			//proc.Done()
    75  			return nil
    76  		}
    77  		if proc.Id == scope {
    78  			return fmt.Errorf(
    79  				"no block found named `%s` within the scope of `%s`",
    80  				name, p.Scope.Name.String(),
    81  			)
    82  		}
    83  		//go sendIpc(proc, true)
    84  		proc.Done()
    85  		proc = proc.Next
    86  	}
    87  }