github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/exp13.go (about)

     1  package expressions
     2  
     3  import (
     4  	"github.com/lmorg/murex/lang/expressions/primitives"
     5  	"github.com/lmorg/murex/lang/expressions/symbols"
     6  	"github.com/lmorg/murex/lang/types"
     7  )
     8  
     9  func expNullCoalescing(tree *ParserT) error {
    10  	leftNode, rightNode, err := tree.getLeftAndRightSymbols()
    11  	if err != nil {
    12  		return err
    13  	}
    14  
    15  	left, err := leftNode.dt.GetValue()
    16  
    17  	switch {
    18  	case err != nil:
    19  		return expElvisRightValue(tree, rightNode)
    20  
    21  	case left.DataType == types.Null:
    22  		return expElvisRightValue(tree, rightNode)
    23  
    24  	default:
    25  		// valid left operand
    26  		return tree.foldAst(&astNodeT{
    27  			key: symbols.Calculated,
    28  			pos: tree.ast[tree.astPos].pos,
    29  			dt:  primitives.NewScalar(left.DataType, left.Value),
    30  		})
    31  	}
    32  }
    33  
    34  func expElvis(tree *ParserT) error {
    35  	leftNode, rightNode, err := tree.getLeftAndRightSymbols()
    36  	if err != nil {
    37  		return err
    38  	}
    39  
    40  	left, err := leftNode.dt.GetValue()
    41  
    42  	if err != nil {
    43  		return expElvisRightValue(tree, rightNode)
    44  	}
    45  
    46  	v, err := types.ConvertGoType(left.Value, types.Boolean)
    47  	if err != nil {
    48  		return expElvisRightValue(tree, rightNode)
    49  	}
    50  
    51  	if !v.(bool) {
    52  		return expElvisRightValue(tree, rightNode)
    53  	}
    54  
    55  	// valid left operand
    56  	return tree.foldAst(&astNodeT{
    57  		key: symbols.Calculated,
    58  		pos: tree.ast[tree.astPos].pos,
    59  		dt:  primitives.NewScalar(left.DataType, left.Value),
    60  	})
    61  }
    62  
    63  func expElvisRightValue(tree *ParserT, rightNode *astNodeT) error {
    64  	right, err := rightNode.dt.GetValue()
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	return tree.foldAst(&astNodeT{
    70  		key: symbols.Calculated,
    71  		pos: tree.ast[tree.astPos].pos,
    72  		dt:  primitives.NewScalar(right.DataType, right.Value),
    73  	})
    74  }