123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- package muesli
- import "fmt"
- /* Run time values */
- type Value interface {
- String() string
- Type() TypeValue
- // Convert the value to a normal go value which must be passed
- // in as a pointer to which the value mmust be set,
- // or return an error if the concversion is not possible.
- Convert(to interface{}) error
- }
- type IntValue int64
- type FloatValue float64
- type StringValue string
- type BoolValue bool
- type WordValue string
- type TypeValue string
- type ErrorValue struct {
- error
- }
- type EmptyValue struct {
- }
- type ListValue struct {
- List []Value
- }
- // Values is simply a shorthand alias for []Value
- type Values = []Value
- const (
- TrueValue = BoolValue(true)
- FalseValue = BoolValue(false)
- IntTypeValue = TypeValue("Int")
- FloatTypeValue = TypeValue("Float")
- StringTypeValue = TypeValue("String")
- BoolTypeValue = TypeValue("Bool")
- WordTypeValue = TypeValue("Word")
- ErrorTypeValue = TypeValue("Error")
- TypeTypeValue = TypeValue("Type")
- EmptyTypeValue = TypeValue("Empty")
- ListTypeValue = TypeValue("List")
- AnyTypeValue = TypeValue("Any")
- )
- var NilValue = Value(nil)
- func (val IntValue) String() string {
- return fmt.Sprintf("%d", int64(val))
- }
- func (val FloatValue) String() string {
- return fmt.Sprintf("%f", float64(val))
- }
- func (val BoolValue) String() string {
- if bool(val) {
- return "true"
- } else {
- return "false"
- }
- }
- func (val StringValue) String() string {
- return string(val)
- }
- func (val WordValue) String() string {
- return string(val)
- }
- func (val TypeValue) String() string {
- return string(val)
- }
- func (val ErrorValue) String() string {
- return fmt.Sprintf("%s", val.Error())
- }
- func (val EmptyValue) String() string {
- return "<empty>"
- }
- func (val ListValue) String() string {
- res := "["
- sep := ""
- for _, elt := range val.List {
- res = res + sep + elt.String()
- sep = ", "
- }
- res += "]"
- return res
- }
- func (v IntValue) Type() TypeValue { return IntTypeValue }
- func (v FloatValue) Type() TypeValue { return FloatTypeValue }
- func (v StringValue) Type() TypeValue { return StringTypeValue }
- func (v BoolValue) Type() TypeValue { return BoolTypeValue }
- func (v WordValue) Type() TypeValue { return WordTypeValue }
- func (v TypeValue) Type() TypeValue { return TypeTypeValue }
- func (v ErrorValue) Type() TypeValue { return ErrorTypeValue }
- func (v EmptyValue) Type() TypeValue { return EmptyTypeValue }
- func (v ListValue) Type() TypeValue { return ListTypeValue }
- func NewErrorValuef(format string, args ...interface{}) ErrorValue {
- err := fmt.Errorf(format, args...)
- return ErrorValue{err}
- }
- func NewListValue(elements ...Value) ListValue {
- return ListValue{elements}
- }
- func (list *ListValue) Append(elements ...Value) {
- list.List = append(list.List, elements...)
- }
- func (list *ListValue) AppendList(toAppend ListValue) {
- list.List = append(list.List, toAppend.List...)
- }
- func (list ListValue) Length() int {
- return len(list.List)
- }
- func (list *ListValue) Index(i int) Value {
- if i >= len(list.List) {
- return NilValue
- }
- return list.List[i]
- }
- func (list *ListValue) First() Value {
- return list.Index(0)
- }
- func (list *ListValue) Last() Value {
- return list.Index(list.Length()-1)
- }
- func EmptyListValue() ListValue {
- return ListValue{make([]Value, 0)}
- }
- func EmptyValueArray() []Value {
- return make([]Value, 0)
- }
- func NewValueArray(elements ...Value) []Value {
- return elements
- }
- func (from IntValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- case *int8:
- (*toPtr) = int8(from)
- case *int16:
- (*toPtr) = int16(from)
- case *int32:
- (*toPtr) = int32(from)
- case *int64:
- (*toPtr) = int64(from)
- case *int:
- (*toPtr) = int(from)
- case *bool:
- (*toPtr) = (from != 0)
- case *float32:
- (*toPtr) = float32(from)
- case *float64:
- (*toPtr) = float64(from)
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from FloatValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- case *int8:
- (*toPtr) = int8(from)
- case *int16:
- (*toPtr) = int16(from)
- case *int32:
- (*toPtr) = int32(from)
- case *int64:
- (*toPtr) = int64(from)
- case *int:
- (*toPtr) = int(from)
- case *bool:
- (*toPtr) = (from != 0)
- case *float32:
- (*toPtr) = float32(from)
- case *float64:
- (*toPtr) = float64(from)
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
-
- func (from StringValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from WordValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from TypeValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from BoolValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *bool:
- (*toPtr) = bool(from)
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from ErrorValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *string:
- (*toPtr) = from.String()
- case *error:
- (*toPtr) = from.error
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- func (from EmptyValue) Convert(to interface{}) error {
- return NewErrorValuef("Cannot convert the empty value %v to %v", from, to)
- }
- func (from ListValue) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *[]Value:
- (*toPtr) = from.List
- default:
- return NewErrorValuef("Cannot convert value %v to %v", from, to)
- }
- return nil
- }
- /* Helpers to easily convert Muesli values to "normal" Go values. */
- func From(from Value, to interface{}) error {
- return from.Convert(to)
- }
- /* Helpers to easily convert Muesli value lists to "normal" Go values. */
- func ParseArgs(args []Value, to...interface{}) ([]interface{}, error) {
- if len(to) > len(args) {
- return nil, NewErrorValuef("Too few arguments, expected %d, got %d", len(to), len(args))
- }
- i:= 0
- for ; i < len(to) ; i ++ {
- fromElt := args[i]
- toElt := to[i]
- err := fromElt.Convert(toElt)
- if err != nil {
- return nil, err
- }
- }
- rest := args[i:len(args)]
- return ListFromList(rest), nil
- }
- /* Helpers to easily convert Muesli values from "normal" Go values. */
- func To(from interface{}) Value {
- switch val := from.(type) {
- case string:
- return StringValue(val)
- case int8:
- return IntValue(val)
- case int16:
- return IntValue(val)
- case int32:
- return IntValue(val)
- case int64:
- return IntValue(val)
- case int:
- return IntValue(val)
- case bool:
- return BoolValue(val)
- case float32:
- return FloatValue(val)
- case float64:
- return FloatValue(val)
- case error:
- return ErrorValue{val}
- case Value:
- return val
- default:
- return NewErrorValuef("Cannot convert value %v", from)
- }
- }
- func ListTo(froms ...interface{}) []Value {
- list := make([]Value, 0)
- for _, from := range froms {
- val := To(from)
- list = append(list, val)
- }
- return list
- }
- func ListFrom(froms []Value, tos ...interface{}) error {
- for i, from := range froms {
- if i >= len(tos) {
- break
- }
- err := From(from, tos[i])
- if err != nil {
- return err
- }
- }
- return nil
- }
- func ListFromList(froms []Value) []interface{} {
- res := make([]interface{}, len(froms))
- for i, from := range froms {
- res[i] = from
- }
- return res
- }
|