/
nodes.rb
229 lines (187 loc) · 5.3 KB
/
nodes.rb
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
module JsonQuery
class Query < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
object = identifier.value(root, symbols, current)
filters.inject(object) { |value, filter| filter.value(value, root, symbols, current) }
end
def filters
elements[1].elements
end
end
module Identifier
end
class Root < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
root
end
end
class Current < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
current
end
end
class Symbol < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
symbols[text_value]
end
end
module Filter
end
module FieldAccess
def index(object, root, symbols, current = nil)
element = elements[1]
return element.text_value if Symbol === element
element.value(root, symbols, object)
end
def value(object, root, symbols, current = nil)
index = index(object, root, symbols, current)
return (Hash === object ? object.values : object) if index == :*
return object[index] if Array === object and Numeric === index
if Hash === object
key = [index, index.to_s, index.to_sym].find { |i| object.has_key?(i) }
return object[key] if key
end
return object.__send__(index) if object.respond_to?(index)
object.instance_variable_get("@#{ index }")
end
end
class AllFilter < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
:*
end
end
class BooleanFilter < Treetop::Runtime::SyntaxNode
def value(list, root, symbols, current = nil)
list.select do |object|
boolean_expression.value(root, symbols, object)
end
end
end
class And < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
first.value(root, symbols, current) && second.value(root, symbols, current)
end
end
class Or < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
first.value(root, symbols, current) || second.value(root, symbols, current)
end
end
class BooleanAtom < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
element = elements[1]
return element.boolean_expression.value(root, symbols, current) if element.respond_to?(:boolean_expression)
comparator.value(first.value(root, symbols, current), second.value(root, symbols, current))
end
def comparator
elements[1].comparator
end
def first
elements[1].first
end
def second
elements[1].second
end
end
class Multiplicative < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
operator.value(first.value(root, symbols, current), second.value(root, symbols, current))
end
end
class Additive < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
operator.value(first.value(root, symbols, current), second.value(root, symbols, current))
end
end
class Atom < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
element = elements[1]
return element.expression.value(root, symbols, current) if element.respond_to?(:expression)
element.value(root, symbols, current)
end
end
class Multiplication < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 * expr2
end
end
class Division < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 / expr2
end
end
class Addition < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
String === expr1 || String === expr2 ?
expr1.to_s + expr2.to_s :
expr1 + expr2
end
end
class Subtraction < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 - expr2
end
end
module Comparator
end
class Equal < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 == expr2
end
end
class NotEqual < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 != expr2
end
end
class LessThan < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 < expr2
end
end
class LessThanOrEqual < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 <= expr2
end
end
class GreaterThan < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 > expr2
end
end
class GreaterThanOrEqual < Treetop::Runtime::SyntaxNode
def value(expr1, expr2)
expr1 >= expr2
end
end
class String < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
@value ||= eval(text_value)
end
end
class Number < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
@value ||= eval(text_value)
end
end
module Boolean
def value(root, symbols, current = nil)
data.value
end
end
class True < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
true
end
end
class False < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
false
end
end
class Null < Treetop::Runtime::SyntaxNode
def value(root, symbols, current = nil)
nil
end
end
end