1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
package ast
import (
"fmt"
"strconv"
"strings"
)
type ValueKind int
const (
Variable ValueKind = iota
IntValue
FloatValue
StringValue
BlockValue
BooleanValue
NullValue
EnumValue
ListValue
ObjectValue
)
type Value struct {
Raw string
Children ChildValueList
Kind ValueKind
Position *Position `dump:"-"`
Comment *CommentGroup
// Require validation
Definition *Definition
VariableDefinition *VariableDefinition
ExpectedType *Type
}
type ChildValue struct {
Name string
Value *Value
Position *Position `dump:"-"`
Comment *CommentGroup
}
func (v *Value) Value(vars map[string]interface{}) (interface{}, error) {
if v == nil {
return nil, nil
}
switch v.Kind {
case Variable:
if value, ok := vars[v.Raw]; ok {
return value, nil
}
if v.VariableDefinition != nil && v.VariableDefinition.DefaultValue != nil {
return v.VariableDefinition.DefaultValue.Value(vars)
}
return nil, nil
case IntValue:
return strconv.ParseInt(v.Raw, 10, 64)
case FloatValue:
return strconv.ParseFloat(v.Raw, 64)
case StringValue, BlockValue, EnumValue:
return v.Raw, nil
case BooleanValue:
return strconv.ParseBool(v.Raw)
case NullValue:
return nil, nil
case ListValue:
var val []interface{}
for _, elem := range v.Children {
elemVal, err := elem.Value.Value(vars)
if err != nil {
return val, err
}
val = append(val, elemVal)
}
return val, nil
case ObjectValue:
val := map[string]interface{}{}
for _, elem := range v.Children {
elemVal, err := elem.Value.Value(vars)
if err != nil {
return val, err
}
val[elem.Name] = elemVal
}
return val, nil
default:
panic(fmt.Errorf("unknown value kind %d", v.Kind))
}
}
func (v *Value) String() string {
if v == nil {
return "<nil>"
}
switch v.Kind {
case Variable:
return "$" + v.Raw
case IntValue, FloatValue, EnumValue, BooleanValue, NullValue:
return v.Raw
case StringValue, BlockValue:
return strconv.Quote(v.Raw)
case ListValue:
var val []string
for _, elem := range v.Children {
val = append(val, elem.Value.String())
}
return "[" + strings.Join(val, ",") + "]"
case ObjectValue:
var val []string
for _, elem := range v.Children {
val = append(val, elem.Name+":"+elem.Value.String())
}
return "{" + strings.Join(val, ",") + "}"
default:
panic(fmt.Errorf("unknown value kind %d", v.Kind))
}
}
func (v *Value) Dump() string {
return v.String()
}
|