github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/condition.go (about)

     1  package expressions
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/MontFerret/ferret/pkg/runtime/core"
     7  	"github.com/MontFerret/ferret/pkg/runtime/values"
     8  )
     9  
    10  type ConditionExpression struct {
    11  	src        core.SourceMap
    12  	test       core.Expression
    13  	consequent core.Expression
    14  	alternate  core.Expression
    15  }
    16  
    17  func NewConditionExpression(
    18  	src core.SourceMap,
    19  	test core.Expression,
    20  	consequent core.Expression,
    21  	alternate core.Expression,
    22  ) (*ConditionExpression, error) {
    23  	if test == nil {
    24  		return nil, core.Error(core.ErrMissedArgument, "test expression")
    25  	}
    26  
    27  	if alternate == nil {
    28  		return nil, core.Error(core.ErrMissedArgument, "alternate expression")
    29  	}
    30  
    31  	return &ConditionExpression{
    32  		src,
    33  		test,
    34  		consequent,
    35  		alternate,
    36  	}, nil
    37  }
    38  
    39  func (e *ConditionExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
    40  	out, err := e.test.Exec(ctx, scope)
    41  
    42  	if err != nil {
    43  		return values.None, core.SourceError(e.src, err)
    44  	}
    45  
    46  	cond := values.ToBoolean(out)
    47  
    48  	var next core.Expression
    49  
    50  	if cond == values.True {
    51  		next = e.consequent
    52  
    53  		// shortcut version
    54  		if next == nil {
    55  			return out, nil
    56  		}
    57  	} else {
    58  		next = e.alternate
    59  	}
    60  
    61  	res, err := next.Exec(ctx, scope)
    62  
    63  	if err != nil {
    64  		return values.None, core.SourceError(e.src, err)
    65  	}
    66  
    67  	return res, nil
    68  }