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

     1  package operators
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/MontFerret/ferret/pkg/runtime/core"
     7  	"github.com/MontFerret/ferret/pkg/runtime/values"
     8  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
     9  )
    10  
    11  type RangeOperator struct {
    12  	*baseOperator
    13  }
    14  
    15  func NewRangeOperator(
    16  	src core.SourceMap,
    17  	left core.Expression,
    18  	right core.Expression,
    19  ) (*RangeOperator, error) {
    20  	if left == nil {
    21  		return nil, core.Error(core.ErrMissedArgument, "left expression")
    22  	}
    23  
    24  	if right == nil {
    25  		return nil, core.Error(core.ErrMissedArgument, "right expression")
    26  	}
    27  
    28  	return &RangeOperator{&baseOperator{src, left, right}}, nil
    29  }
    30  
    31  func (operator *RangeOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
    32  	left, err := operator.left.Exec(ctx, scope)
    33  
    34  	if err != nil {
    35  		return values.None, core.SourceError(operator.src, err)
    36  	}
    37  
    38  	right, err := operator.right.Exec(ctx, scope)
    39  
    40  	if err != nil {
    41  		return values.None, core.SourceError(operator.src, err)
    42  	}
    43  
    44  	return operator.Eval(ctx, left, right)
    45  }
    46  
    47  func (operator *RangeOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) {
    48  	err := core.ValidateType(left, types.Int, types.Float)
    49  
    50  	if err != nil {
    51  		return values.None, core.SourceError(operator.src, err)
    52  	}
    53  
    54  	err = core.ValidateType(right, types.Int, types.Float)
    55  
    56  	if err != nil {
    57  		return values.None, core.SourceError(operator.src, err)
    58  	}
    59  
    60  	var start int
    61  	var end int
    62  
    63  	if left.Type() == types.Float {
    64  		start = int(left.(values.Float))
    65  	} else {
    66  		start = int(left.(values.Int))
    67  	}
    68  
    69  	if right.Type() == types.Float {
    70  		end = int(right.(values.Float))
    71  	} else {
    72  		end = int(right.(values.Int))
    73  	}
    74  
    75  	arr := values.NewArray(10)
    76  
    77  	for i := start; i <= end; i++ {
    78  		arr.Push(values.NewInt(i))
    79  	}
    80  
    81  	return arr, nil
    82  }