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

     1  package primitives
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/lmorg/murex/lang/expressions/symbols"
     7  	"github.com/lmorg/murex/lang/types"
     8  )
     9  
    10  //go:generate stringer -linecomment -type=Primitive
    11  type Primitive int
    12  
    13  const (
    14  	Number   Primitive = Primitive(symbols.Number)      // number
    15  	String   Primitive = Primitive(symbols.QuoteSingle) // string
    16  	Boolean  Primitive = Primitive(symbols.Boolean)     // boolean
    17  	Array    Primitive = Primitive(symbols.ArrayBegin)  // array
    18  	Object   Primitive = Primitive(symbols.ObjectBegin) // object
    19  	Null     Primitive = Primitive(symbols.Null)        // null
    20  	Bareword Primitive = 0                              // bareword
    21  	Other    Primitive = -1                             // other
    22  	Function Primitive = -2                             // functions and subshells
    23  )
    24  
    25  type DataType struct {
    26  	v  *Value
    27  	fn FunctionT
    28  }
    29  
    30  type FunctionT func() (*Value, error)
    31  
    32  func NewPrimitive(primitive Primitive, value any) *DataType {
    33  	return &DataType{
    34  		v: &Value{
    35  			Primitive: primitive,
    36  			Value:     value,
    37  		},
    38  	}
    39  }
    40  
    41  func NewFunction(fn FunctionT) *DataType {
    42  	/*if fn == nil {
    43  		panic("undefined function")
    44  	}*/
    45  
    46  	return &DataType{
    47  		v:  &Value{Primitive: Function},
    48  		fn: fn,
    49  	}
    50  }
    51  
    52  func NewScalar(mxdt string, value any) *DataType {
    53  	return &DataType{
    54  		v: &Value{
    55  			Primitive: DataType2Primitive(mxdt),
    56  			DataType:  mxdt,
    57  			Value:     value,
    58  		},
    59  	}
    60  }
    61  
    62  func DataType2Primitive(dt string) Primitive {
    63  	switch dt {
    64  	case types.Number, types.Integer, types.Float:
    65  		return Number
    66  	case types.Boolean:
    67  		return Boolean
    68  	case types.Null:
    69  		return Null
    70  	case types.String:
    71  		return String
    72  	default:
    73  		return Other
    74  	}
    75  }
    76  
    77  func (v *Value) Marshal() ([]rune, error) {
    78  	b, err := json.Marshal(v.Value)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	r := []rune(string(b))
    84  	return r, nil
    85  }
    86  
    87  func (dt *DataType) NotValue() {
    88  	dt.v.Value = !dt.v.Value.(bool)
    89  }
    90  
    91  type Value struct {
    92  	Primitive Primitive
    93  	Value     any
    94  	DataType  string
    95  	ExitNum   int
    96  }
    97  
    98  func (dt *DataType) GetValue() (*Value, error) {
    99  	if dt.v.Primitive == Function {
   100  		if dt.fn == nil {
   101  			panic("undefined function")
   102  		}
   103  
   104  		var err error
   105  		dt.v, err = dt.fn()
   106  		dt.v.Primitive = DataType2Primitive(dt.v.DataType)
   107  		return dt.v, err
   108  	}
   109  
   110  	if dt.v.DataType == "" {
   111  		dt.v.DataType = dt.dataType()
   112  	}
   113  
   114  	return dt.v, nil
   115  }
   116  
   117  func (dt *DataType) dataType() string {
   118  	switch dt.v.Primitive {
   119  	case Number:
   120  		return types.Number
   121  	case String:
   122  		return types.String
   123  	case Boolean:
   124  		return types.Boolean
   125  	case Array:
   126  		return types.Json
   127  	case Object:
   128  		return types.Json
   129  	case Null:
   130  		return types.Null
   131  	case Bareword:
   132  		return types.Null
   133  	case Other:
   134  		return dt.v.DataType
   135  	default:
   136  		return types.Generic
   137  	}
   138  }