rupkl 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rupkl/node/amend_expression.rb +48 -0
- data/lib/rupkl/node/any.rb +110 -0
- data/lib/rupkl/node/base.rb +75 -0
- data/lib/rupkl/node/boolean.rb +30 -5
- data/lib/rupkl/node/collection.rb +176 -0
- data/lib/rupkl/node/context.rb +27 -0
- data/lib/rupkl/node/data_size.rb +254 -0
- data/lib/rupkl/node/declared_type.rb +32 -0
- data/lib/rupkl/node/duration.rb +266 -0
- data/lib/rupkl/node/dynamic.rb +33 -60
- data/lib/rupkl/node/identifier.rb +19 -5
- data/lib/rupkl/node/if_expression.rb +45 -0
- data/lib/rupkl/node/intseq.rb +84 -0
- data/lib/rupkl/node/listing.rb +68 -0
- data/lib/rupkl/node/map.rb +120 -0
- data/lib/rupkl/node/mapping.rb +54 -0
- data/lib/rupkl/node/member_finder.rb +49 -0
- data/lib/rupkl/node/member_reference.rb +46 -21
- data/lib/rupkl/node/method_call.rb +63 -0
- data/lib/rupkl/node/method_definition.rb +199 -0
- data/lib/rupkl/node/node_common.rb +76 -0
- data/lib/rupkl/node/null.rb +24 -0
- data/lib/rupkl/node/number.rb +228 -10
- data/lib/rupkl/node/object.rb +626 -74
- data/lib/rupkl/node/operation.rb +175 -115
- data/lib/rupkl/node/pair.rb +58 -0
- data/lib/rupkl/node/pkl_module.rb +16 -28
- data/lib/rupkl/node/reference_resolver.rb +79 -0
- data/lib/rupkl/node/regex.rb +196 -0
- data/lib/rupkl/node/string.rb +415 -23
- data/lib/rupkl/node/struct_common.rb +150 -53
- data/lib/rupkl/node/this.rb +17 -0
- data/lib/rupkl/node/type_common.rb +34 -0
- data/lib/rupkl/node/value_common.rb +18 -13
- data/lib/rupkl/parser/expression.rb +197 -43
- data/lib/rupkl/parser/identifier.rb +2 -2
- data/lib/rupkl/parser/literal.rb +18 -12
- data/lib/rupkl/parser/method.rb +41 -0
- data/lib/rupkl/parser/misc.rb +24 -0
- data/lib/rupkl/parser/object.rb +141 -26
- data/lib/rupkl/parser/pkl_class.rb +37 -10
- data/lib/rupkl/parser/pkl_module.rb +5 -3
- data/lib/rupkl/parser/type.rb +28 -0
- data/lib/rupkl/parser.rb +8 -0
- data/lib/rupkl/pkl_object.rb +11 -7
- data/lib/rupkl/version.rb +1 -1
- data/lib/rupkl.rb +35 -6
- metadata +45 -7
- data/lib/rupkl/node/pkl_class.rb +0 -30
|
@@ -3,36 +3,124 @@
|
|
|
3
3
|
module RuPkl
|
|
4
4
|
module Node
|
|
5
5
|
module StructCommon
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include NodeCommon
|
|
7
|
+
include MemberFinder
|
|
8
|
+
|
|
9
|
+
def initialize(parent, body, position)
|
|
10
|
+
super
|
|
11
|
+
@body = body
|
|
8
12
|
end
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
attr_reader :body
|
|
15
|
+
|
|
16
|
+
def properties(visibility: :object)
|
|
17
|
+
@body&.properties(visibility: visibility)
|
|
12
18
|
end
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
def entries
|
|
21
|
+
@body&.entries
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def elements
|
|
25
|
+
@body&.elements
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def members(visibility: :object)
|
|
29
|
+
@body&.members(visibility: visibility)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def items
|
|
33
|
+
@body&.items
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def evaluate(context = nil)
|
|
37
|
+
do_evaluation(__method__, context, 1) do |c|
|
|
38
|
+
@body&.evaluate(c)
|
|
39
|
+
end
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def resolve_structure(context = nil)
|
|
44
|
+
do_evaluation(__method__, context, 1) do |c|
|
|
45
|
+
@body&.resolve_structure(c)
|
|
46
|
+
end
|
|
47
|
+
@body && check_members
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_pkl_string(context = nil)
|
|
52
|
+
to_string(context)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_string(context = nil)
|
|
56
|
+
do_evaluation(__method__, context, 2, invalid_string) do |c|
|
|
57
|
+
to_string_object(c)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def current_context
|
|
62
|
+
super&.push_object(self) || Context.new(nil, [self])
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def structure?
|
|
66
|
+
true
|
|
67
|
+
end
|
|
15
68
|
|
|
16
|
-
def
|
|
17
|
-
|
|
69
|
+
def copy(parent = nil, position = @position)
|
|
70
|
+
self.class.new(parent, @body&.copy, position)
|
|
18
71
|
end
|
|
19
72
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
73
|
+
def merge!(*bodies)
|
|
74
|
+
return unless @body
|
|
75
|
+
|
|
76
|
+
@body.merge!(*bodies.compact)
|
|
77
|
+
check_members
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def check_members
|
|
83
|
+
message =
|
|
84
|
+
if properties_not_allowed?
|
|
85
|
+
"'#{class_name}' cannot have a property"
|
|
86
|
+
elsif entries_not_allowed?
|
|
87
|
+
"'#{class_name}' cannot have an entry"
|
|
88
|
+
elsif elements_not_allowed?
|
|
89
|
+
"'#{class_name}' cannot have an element"
|
|
25
90
|
end
|
|
26
|
-
|
|
91
|
+
message &&
|
|
92
|
+
(raise EvaluationError.new(message, position))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def properties_not_allowed?
|
|
96
|
+
properties.then { _1 && !_1.empty? }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def entries_not_allowed?
|
|
100
|
+
entries
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def elements_not_allowed?
|
|
104
|
+
elements
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def do_evaluation(method, context, limit, ifreachlimit = nil)
|
|
108
|
+
return ifreachlimit if reach_limit?(method, limit)
|
|
109
|
+
|
|
110
|
+
call_depth[method] += 1
|
|
111
|
+
result = yield(context&.push_object(self) || current_context)
|
|
112
|
+
call_depth.delete(method)
|
|
113
|
+
|
|
114
|
+
result
|
|
27
115
|
end
|
|
28
116
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
.any? { _1.__send__(accessor) == member.__send__(accessor) }
|
|
117
|
+
def call_depth
|
|
118
|
+
@call_depth ||= Hash.new { |h, k| h[k] = 0 }
|
|
32
119
|
end
|
|
33
120
|
|
|
34
|
-
def
|
|
35
|
-
|
|
121
|
+
def reach_limit?(method, limit)
|
|
122
|
+
depth = call_depth[method]
|
|
123
|
+
depth >= 1 && depth >= limit
|
|
36
124
|
end
|
|
37
125
|
|
|
38
126
|
def match_members?(lhs, rhs, match_order)
|
|
@@ -44,58 +132,67 @@ module RuPkl
|
|
|
44
132
|
end
|
|
45
133
|
end
|
|
46
134
|
|
|
47
|
-
|
|
48
|
-
return nil unless lhs || rhs
|
|
49
|
-
return rhs unless lhs
|
|
135
|
+
SELF = Object.new.freeze
|
|
50
136
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
137
|
+
def to_pkl_object(context)
|
|
138
|
+
to_ruby_object(context) do |properties, entries, elements|
|
|
139
|
+
PklObject.new do |object|
|
|
140
|
+
[
|
|
141
|
+
replace_self_hash(properties, object),
|
|
142
|
+
replace_self_hash(entries, object),
|
|
143
|
+
replace_self_array(elements, object)
|
|
144
|
+
]
|
|
56
145
|
end
|
|
57
146
|
end
|
|
58
|
-
|
|
59
|
-
lhs
|
|
60
147
|
end
|
|
61
148
|
|
|
62
|
-
def
|
|
63
|
-
|
|
149
|
+
def to_ruby_object(context)
|
|
150
|
+
do_evaluation(__method__, context, 1, SELF) do |c|
|
|
151
|
+
results = convert_members(c)
|
|
152
|
+
yield(*results)
|
|
153
|
+
end
|
|
64
154
|
end
|
|
65
155
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
156
|
+
def convert_members(context)
|
|
157
|
+
context.push_scope(@body).then do |c|
|
|
158
|
+
to_ruby = proc { _1.to_ruby(c) }
|
|
159
|
+
[
|
|
160
|
+
properties&.to_h(&to_ruby),
|
|
161
|
+
entries&.to_h(&to_ruby),
|
|
162
|
+
elements&.map(&to_ruby)
|
|
163
|
+
]
|
|
164
|
+
end
|
|
72
165
|
end
|
|
73
166
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
to_ruby_array_members(scopes, elements)
|
|
79
|
-
)
|
|
167
|
+
def replace_self_hash(hash, replacement)
|
|
168
|
+
hash&.each do |key, value|
|
|
169
|
+
hash[key] = replacement if value.equal?(SELF)
|
|
170
|
+
end
|
|
80
171
|
end
|
|
81
172
|
|
|
82
|
-
def
|
|
83
|
-
|
|
84
|
-
|
|
173
|
+
def replace_self_array(array, replacement)
|
|
174
|
+
array&.each_with_index do |value, i|
|
|
175
|
+
array[i] = replacement if value.equal?(SELF)
|
|
176
|
+
end
|
|
85
177
|
end
|
|
86
178
|
|
|
87
|
-
def
|
|
88
|
-
|
|
89
|
-
&.map { _1.to_ruby(scopes) }
|
|
179
|
+
def to_string_object(context)
|
|
180
|
+
"new #{class_name} #{to_string_members(context)}"
|
|
90
181
|
end
|
|
91
182
|
|
|
92
|
-
def
|
|
183
|
+
def to_string_members(context)
|
|
93
184
|
return '{}' if members.empty?
|
|
94
185
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
186
|
+
context.push_scope(@body).then do |c|
|
|
187
|
+
members
|
|
188
|
+
.map { _1.to_pkl_string(c) }
|
|
189
|
+
.join('; ')
|
|
190
|
+
.then { "{ #{_1} }" }
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def defined_operator?(operator)
|
|
195
|
+
operator == :[]
|
|
99
196
|
end
|
|
100
197
|
end
|
|
101
198
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuPkl
|
|
4
|
+
module Node
|
|
5
|
+
class This
|
|
6
|
+
include NodeCommon
|
|
7
|
+
|
|
8
|
+
def evaluate(context = nil)
|
|
9
|
+
resolve_reference(context)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resolve_reference(context = nil)
|
|
13
|
+
(context || current_context).objects.last
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuPkl
|
|
4
|
+
module Node
|
|
5
|
+
module TypeCommon
|
|
6
|
+
include NodeCommon
|
|
7
|
+
|
|
8
|
+
def check_type(value, context, position)
|
|
9
|
+
klass = value.class
|
|
10
|
+
return if match_type?(klass, context)
|
|
11
|
+
|
|
12
|
+
message =
|
|
13
|
+
"expected type '#{self}', but got type '#{klass.class_name}'"
|
|
14
|
+
raise EvaluationError.new(message, position)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def find_type(type, context)
|
|
20
|
+
exec_on(context) do |c|
|
|
21
|
+
[Base.instance, *c&.objects]
|
|
22
|
+
.reverse_each do |scope|
|
|
23
|
+
next unless scope.respond_to?(:pkl_classes)
|
|
24
|
+
|
|
25
|
+
klass = scope.pkl_classes&.fetch(type.last.id, nil)
|
|
26
|
+
return klass if klass
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
raise EvaluationError.new("cannot find type '#{type.last.id}'", position)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -3,32 +3,37 @@
|
|
|
3
3
|
module RuPkl
|
|
4
4
|
module Node
|
|
5
5
|
module ValueCommon
|
|
6
|
-
|
|
6
|
+
include NodeCommon
|
|
7
|
+
|
|
8
|
+
def initialize(parent, value, position)
|
|
9
|
+
super(parent, position)
|
|
7
10
|
@value = value
|
|
8
|
-
@position = position
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
attr_reader :value
|
|
12
|
-
attr_reader :position
|
|
13
14
|
|
|
14
|
-
def
|
|
15
|
-
|
|
15
|
+
def evaluate(_context = nil)
|
|
16
|
+
self
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
def
|
|
19
|
-
|
|
19
|
+
def to_ruby(context = nil)
|
|
20
|
+
evaluate(context).value
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
def
|
|
23
|
-
|
|
23
|
+
def to_string(context = nil)
|
|
24
|
+
to_ruby(context).to_s
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
def
|
|
27
|
-
|
|
27
|
+
def to_pkl_string(context = nil)
|
|
28
|
+
to_string(context)
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
def
|
|
31
|
-
|
|
31
|
+
def copy(parent = nil, position = @position)
|
|
32
|
+
self.class.new(parent, @value, position)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def ==(other)
|
|
36
|
+
other.instance_of?(self.class) && value == other.value
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
end
|
|
@@ -3,46 +3,112 @@
|
|
|
3
3
|
module RuPkl
|
|
4
4
|
class Parser
|
|
5
5
|
define_parser do
|
|
6
|
+
rule(:argument_list) do
|
|
7
|
+
bracketed(list(expression).maybe, '(', ')').as(:argument_list)
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
rule(:unqualified_member_ref) do
|
|
7
|
-
|
|
11
|
+
(
|
|
12
|
+
id.as(:name) >>
|
|
13
|
+
(pure_ws? >> argument_list.as(:arguments)).maybe
|
|
14
|
+
).as(:unqualified_member_ref)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
rule(:parenthesized_expression) do
|
|
18
|
+
bracketed(expression)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
rule(:this_expression) do
|
|
22
|
+
kw_this.as(:this_expression)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
rule(:null_expression) do
|
|
26
|
+
kw_null.as(:null_expression)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
rule(:new_expression) do
|
|
30
|
+
(
|
|
31
|
+
kw_new.as(:kw_new) >>
|
|
32
|
+
(ws? >> type.as(:type)).maybe >>
|
|
33
|
+
(ws? >> object_body).repeat(1).as(:bodies)
|
|
34
|
+
).as(:new_expression)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
rule(:amend_expression) do
|
|
38
|
+
(
|
|
39
|
+
parenthesized_expression.as(:target) >>
|
|
40
|
+
(ws? >> object_body).repeat(1).as(:bodies)
|
|
41
|
+
).as(:amend_expression)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
rule(:if_expression) do
|
|
45
|
+
(
|
|
46
|
+
kw_if.as(:kw_if) >> ws? >>
|
|
47
|
+
bracketed(expression.as(:condition), '(', ')') >> ws? >>
|
|
48
|
+
expression.as(:if_expression) >> ws >>
|
|
49
|
+
kw_else.ignore >> ws >>
|
|
50
|
+
expression.as(:else_expression)
|
|
51
|
+
).as(:if_expression)
|
|
8
52
|
end
|
|
9
53
|
|
|
10
54
|
rule(:primary) do
|
|
11
55
|
[
|
|
12
|
-
float_literal,
|
|
13
|
-
|
|
56
|
+
float_literal, int_literal, boolean_literal, string_literal,
|
|
57
|
+
this_expression, null_expression, new_expression, amend_expression,
|
|
58
|
+
if_expression, unqualified_member_ref, parenthesized_expression
|
|
14
59
|
].inject(:|)
|
|
15
60
|
end
|
|
16
61
|
|
|
62
|
+
rule(:qualifier) do
|
|
63
|
+
(str('?.') | str('.'))
|
|
64
|
+
end
|
|
65
|
+
|
|
17
66
|
rule(:qualified_member_ref) do
|
|
18
67
|
(
|
|
19
|
-
|
|
20
|
-
(
|
|
21
|
-
).as(:qualified_member_ref)
|
|
68
|
+
ws? >> qualifier.as(:qualifier) >> ws? >>
|
|
69
|
+
id.as(:member) >> (pure_ws? >> argument_list.as(:arguments)).maybe
|
|
70
|
+
).as(:qualified_member_ref)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
rule(:subscript_key) do
|
|
74
|
+
(
|
|
75
|
+
pure_ws? >> bracketed(expression, '[', ']') >>
|
|
76
|
+
(ws? >> str('=')).absent?
|
|
77
|
+
).as(:subscript_key)
|
|
22
78
|
end
|
|
23
79
|
|
|
24
|
-
rule(:
|
|
80
|
+
rule(:qualified_member_ref_or_subscript_operation) do
|
|
25
81
|
(
|
|
26
|
-
|
|
82
|
+
primary.as(:receiver) >>
|
|
27
83
|
(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
84
|
+
qualified_member_ref | subscript_key
|
|
85
|
+
).repeat(1).as(:member_ref_or_subscript_key)
|
|
86
|
+
).as(:qualified_member_ref_or_subscript_operation) | primary
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
rule(:non_null_operation) do
|
|
90
|
+
(
|
|
91
|
+
qualified_member_ref_or_subscript_operation.as(:operand) >>
|
|
92
|
+
ws? >> str(:'!!').as(:non_null_operator)
|
|
93
|
+
) | qualified_member_ref_or_subscript_operation
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
rule(:unary_operator) do
|
|
97
|
+
(str('-') | str('!')).as(:unary_operator)
|
|
32
98
|
end
|
|
33
99
|
|
|
34
100
|
rule(:unary_operation) do
|
|
35
101
|
(
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
) |
|
|
102
|
+
(unary_operator >> ws?).repeat(1).as(:operators) >>
|
|
103
|
+
non_null_operation.as(:operand)
|
|
104
|
+
).as(:unary_operation) | non_null_operation
|
|
39
105
|
end
|
|
40
106
|
|
|
41
107
|
rule(:binary_operation) do
|
|
42
108
|
expression = unary_operation
|
|
43
109
|
operators = binary_operators
|
|
44
110
|
reducer = proc { |l, o, r| { binary_operator: o, l_operand: l, r_operand: r } }
|
|
45
|
-
infix_expression(expression, *operators, &reducer)
|
|
111
|
+
infix_expression(expression, *operators, &reducer)
|
|
46
112
|
end
|
|
47
113
|
|
|
48
114
|
rule(:expression) do
|
|
@@ -53,12 +119,13 @@ module RuPkl
|
|
|
53
119
|
|
|
54
120
|
def binary_operators
|
|
55
121
|
operators = {
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
122
|
+
'??': 1,
|
|
123
|
+
'||': 2, '&&': 3,
|
|
124
|
+
'==': 4, '!=': 4,
|
|
125
|
+
'<': 5, '>': 5, '<=': 5, '>=': 5,
|
|
126
|
+
'+': 6, '-': 6,
|
|
127
|
+
'*': 7, '/': 7, '~/': 7, '%': 7,
|
|
128
|
+
'**': 8
|
|
62
129
|
}
|
|
63
130
|
operators
|
|
64
131
|
.sort_by { |op, _| op.length }.reverse
|
|
@@ -72,48 +139,135 @@ module RuPkl
|
|
|
72
139
|
else
|
|
73
140
|
ws? >> str(operator) >> ws?
|
|
74
141
|
end
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
[atom, priority, :left]
|
|
79
|
-
end
|
|
142
|
+
associativity =
|
|
143
|
+
(operator in :** | :'??') && :right || :left
|
|
144
|
+
[atom, priority, associativity]
|
|
80
145
|
end
|
|
81
146
|
end
|
|
82
147
|
|
|
83
148
|
define_transform do
|
|
84
|
-
rule(
|
|
85
|
-
|
|
149
|
+
rule(argument_list: subtree(:arguments)) do
|
|
150
|
+
arguments == '' ? nil : Array(arguments)
|
|
86
151
|
end
|
|
87
152
|
|
|
88
153
|
rule(
|
|
89
|
-
|
|
90
|
-
{
|
|
154
|
+
unqualified_member_ref:
|
|
155
|
+
{ name: simple(:name) }
|
|
91
156
|
) do
|
|
92
|
-
|
|
93
|
-
Node::MemberReference.new(r, m, r.position)
|
|
94
|
-
end
|
|
157
|
+
Node::MemberReference.new(nil, nil, name, false, name.position)
|
|
95
158
|
end
|
|
96
159
|
|
|
97
160
|
rule(
|
|
98
|
-
|
|
99
|
-
{
|
|
161
|
+
unqualified_member_ref:
|
|
162
|
+
{ name: simple(:name), arguments: subtree(:arguments) }
|
|
100
163
|
) do
|
|
101
|
-
|
|
102
|
-
|
|
164
|
+
Node::MethodCall.new(nil, nil, name, arguments, false, name.position)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
rule(
|
|
168
|
+
qualified_member_ref_or_subscript_operation:
|
|
169
|
+
{
|
|
170
|
+
receiver: simple(:receiver),
|
|
171
|
+
member_ref_or_subscript_key: subtree(:member_ref_or_subscript_key)
|
|
172
|
+
}
|
|
173
|
+
) do
|
|
174
|
+
member_ref_or_subscript_key.inject(receiver) do |r, ref_or_key|
|
|
175
|
+
if ref_or_key.key?(:subscript_key)
|
|
176
|
+
process_subscript_operation(r, ref_or_key[:subscript_key])
|
|
177
|
+
else
|
|
178
|
+
process_member_ref(r, ref_or_key[:qualified_member_ref])
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
define_helper(:process_subscript_operation) do |receiver, key|
|
|
184
|
+
Node::SubscriptOperation.new(nil, :[], receiver, key, receiver.position)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
define_helper(:process_member_ref) do |receiver, member_ref|
|
|
188
|
+
nullable = member_ref[:qualifier] == '?.'
|
|
189
|
+
if member_ref.key?(:arguments)
|
|
190
|
+
Node::MethodCall.new(
|
|
191
|
+
nil, receiver, member_ref[:member], member_ref[:arguments],
|
|
192
|
+
nullable, receiver.position
|
|
193
|
+
)
|
|
194
|
+
else
|
|
195
|
+
Node::MemberReference.new(
|
|
196
|
+
nil, receiver, member_ref[:member], nullable, receiver.position
|
|
197
|
+
)
|
|
103
198
|
end
|
|
104
199
|
end
|
|
105
200
|
|
|
106
|
-
rule(
|
|
107
|
-
Node::
|
|
201
|
+
rule(this_expression: simple(:this)) do
|
|
202
|
+
Node::This.new(nil, node_position(this))
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
rule(null_expression: simple(:null)) do
|
|
206
|
+
Node::Null.new(nil, node_position(null))
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
rule(
|
|
210
|
+
new_expression:
|
|
211
|
+
{ kw_new: simple(:n), bodies: subtree(:b) }
|
|
212
|
+
) do
|
|
213
|
+
Node::UnresolvedObject.new(nil, nil, b, node_position(n))
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
rule(
|
|
217
|
+
new_expression:
|
|
218
|
+
{ kw_new: simple(:n), type: simple(:t), bodies: subtree(:b) }
|
|
219
|
+
) do
|
|
220
|
+
Node::UnresolvedObject.new(nil, t, b, node_position(n))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
rule(
|
|
224
|
+
amend_expression:
|
|
225
|
+
{ target: simple(:t), bodies: subtree(:b) }
|
|
226
|
+
) do
|
|
227
|
+
Node::AmendExpression.new(nil, t, Array(b), t.position)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
rule(
|
|
231
|
+
if_expression:
|
|
232
|
+
{
|
|
233
|
+
kw_if: simple(:kw), condition: simple(:condition),
|
|
234
|
+
if_expression: simple(:if_expression),
|
|
235
|
+
else_expression: simple(:else_expression)
|
|
236
|
+
}
|
|
237
|
+
) do
|
|
238
|
+
Node::IfExpression.new(
|
|
239
|
+
nil, condition, if_expression, else_expression, node_position(kw)
|
|
240
|
+
)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
rule(operand: simple(:operand), non_null_operator: simple(:operator)) do
|
|
244
|
+
Node::NonNullOperation.new(nil, operator.to_sym, operand, operand.position)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
rule(unary_operator: simple(:op)) do
|
|
248
|
+
op
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
rule(
|
|
252
|
+
unary_operation: {
|
|
253
|
+
operators: sequence(:operators), operand: simple(:operand)
|
|
254
|
+
}
|
|
255
|
+
) do
|
|
256
|
+
operators.reverse.inject(operand) do |result, operator|
|
|
257
|
+
Node::UnaryOperation.new(nil, operator.to_sym, result, node_position(operator))
|
|
258
|
+
end
|
|
108
259
|
end
|
|
109
260
|
|
|
110
261
|
rule(
|
|
111
262
|
binary_operator: simple(:operator),
|
|
112
263
|
l_operand: simple(:l_operand), r_operand: simple(:r_operand)
|
|
113
264
|
) do
|
|
114
|
-
|
|
115
|
-
operator.to_sym
|
|
116
|
-
|
|
265
|
+
klass =
|
|
266
|
+
case operator.to_sym
|
|
267
|
+
when :'??' then Node::NullCoalescingOperation
|
|
268
|
+
else Node::BinaryOperation
|
|
269
|
+
end
|
|
270
|
+
klass.new(nil, operator.to_sym, l_operand, r_operand, l_operand.position)
|
|
117
271
|
end
|
|
118
272
|
end
|
|
119
273
|
end
|
|
@@ -41,11 +41,11 @@ module RuPkl
|
|
|
41
41
|
parse_error(message, node_position(id))
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
Node::Identifier.new(id.to_sym, node_position(id))
|
|
44
|
+
Node::Identifier.new(nil, id.to_sym, node_position(id))
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
rule(quoted_id: simple(:id)) do
|
|
48
|
-
Node::Identifier.new(id.to_s[1..-2].to_sym, node_position(id))
|
|
48
|
+
Node::Identifier.new(nil, id.to_s[1..-2].to_sym, node_position(id))
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
private
|