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