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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/rupkl/node/amend_expression.rb +48 -0
  4. data/lib/rupkl/node/any.rb +110 -0
  5. data/lib/rupkl/node/base.rb +75 -0
  6. data/lib/rupkl/node/boolean.rb +30 -5
  7. data/lib/rupkl/node/collection.rb +176 -0
  8. data/lib/rupkl/node/context.rb +27 -0
  9. data/lib/rupkl/node/data_size.rb +254 -0
  10. data/lib/rupkl/node/declared_type.rb +32 -0
  11. data/lib/rupkl/node/duration.rb +266 -0
  12. data/lib/rupkl/node/dynamic.rb +33 -60
  13. data/lib/rupkl/node/identifier.rb +19 -5
  14. data/lib/rupkl/node/if_expression.rb +45 -0
  15. data/lib/rupkl/node/intseq.rb +84 -0
  16. data/lib/rupkl/node/listing.rb +68 -0
  17. data/lib/rupkl/node/map.rb +120 -0
  18. data/lib/rupkl/node/mapping.rb +54 -0
  19. data/lib/rupkl/node/member_finder.rb +49 -0
  20. data/lib/rupkl/node/member_reference.rb +46 -21
  21. data/lib/rupkl/node/method_call.rb +63 -0
  22. data/lib/rupkl/node/method_definition.rb +199 -0
  23. data/lib/rupkl/node/node_common.rb +76 -0
  24. data/lib/rupkl/node/null.rb +24 -0
  25. data/lib/rupkl/node/number.rb +228 -10
  26. data/lib/rupkl/node/object.rb +626 -74
  27. data/lib/rupkl/node/operation.rb +175 -115
  28. data/lib/rupkl/node/pair.rb +58 -0
  29. data/lib/rupkl/node/pkl_module.rb +16 -28
  30. data/lib/rupkl/node/reference_resolver.rb +79 -0
  31. data/lib/rupkl/node/regex.rb +196 -0
  32. data/lib/rupkl/node/string.rb +415 -23
  33. data/lib/rupkl/node/struct_common.rb +150 -53
  34. data/lib/rupkl/node/this.rb +17 -0
  35. data/lib/rupkl/node/type_common.rb +34 -0
  36. data/lib/rupkl/node/value_common.rb +18 -13
  37. data/lib/rupkl/parser/expression.rb +197 -43
  38. data/lib/rupkl/parser/identifier.rb +2 -2
  39. data/lib/rupkl/parser/literal.rb +18 -12
  40. data/lib/rupkl/parser/method.rb +41 -0
  41. data/lib/rupkl/parser/misc.rb +24 -0
  42. data/lib/rupkl/parser/object.rb +141 -26
  43. data/lib/rupkl/parser/pkl_class.rb +37 -10
  44. data/lib/rupkl/parser/pkl_module.rb +5 -3
  45. data/lib/rupkl/parser/type.rb +28 -0
  46. data/lib/rupkl/parser.rb +8 -0
  47. data/lib/rupkl/pkl_object.rb +11 -7
  48. data/lib/rupkl/version.rb +1 -1
  49. data/lib/rupkl.rb +35 -6
  50. metadata +45 -7
  51. 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
- def to_string(_scopes)
7
- "new #{self.class.basename} #{to_pkl_string(nil)}"
6
+ include NodeCommon
7
+ include MemberFinder
8
+
9
+ def initialize(parent, body, position)
10
+ super
11
+ @body = body
8
12
  end
9
13
 
10
- def coerce(_operator, r_operand)
11
- [self, r_operand]
14
+ attr_reader :body
15
+
16
+ def properties(visibility: :object)
17
+ @body&.properties(visibility: visibility)
12
18
  end
13
19
 
14
- private
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 push_scope(scopes)
17
- yield([*scopes, self])
69
+ def copy(parent = nil, position = @position)
70
+ self.class.new(parent, @body&.copy, position)
18
71
  end
19
72
 
20
- def add_hash_member(members, member, accessor)
21
- duplicate_member?(members, member, accessor) &&
22
- begin
23
- message = 'duplicate definition of member'
24
- raise EvaluationError.new(message, member.position)
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
- members << member
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 duplicate_member?(members, member, accessor)
30
- members
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 add_array_member(members, member)
35
- members << member
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
- def merge_hash_members(lhs, rhs, accessor)
48
- return nil unless lhs || rhs
49
- return rhs unless lhs
135
+ SELF = Object.new.freeze
50
136
 
51
- rhs&.each do |r|
52
- if (index = find_index(lhs, r, accessor))
53
- lhs[index] = r
54
- else
55
- lhs << r
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 find_index(lhs, rhs, accessor)
63
- lhs.find_index { _1.__send__(accessor) == rhs.__send__(accessor) }
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 merge_array_members(lhs, rhs)
67
- return nil unless lhs || rhs
68
- return rhs unless lhs
69
- return lhs unless rhs
70
-
71
- lhs.concat(rhs)
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 create_pkl_object(scopes, properties, entries, elements)
75
- RuPkl::PklObject.new(
76
- to_ruby_hash_members(scopes, properties),
77
- to_ruby_hash_members(scopes, entries),
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 to_ruby_hash_members(scopes, members)
83
- members
84
- &.to_h { _1.to_ruby(scopes) }
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 to_ruby_array_members(scopes, members)
88
- members
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 to_pkl_string_object(*members)
183
+ def to_string_members(context)
93
184
  return '{}' if members.empty?
94
185
 
95
- members
96
- .map { _1.to_pkl_string(nil) }
97
- .join('; ')
98
- .then { "{ #{_1} }" }
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
- def initialize(value, position)
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 to_ruby(scopes)
15
- evaluate(scopes).value
15
+ def evaluate(_context = nil)
16
+ self
16
17
  end
17
18
 
18
- def to_string(scopes)
19
- to_ruby(scopes).to_s
19
+ def to_ruby(context = nil)
20
+ evaluate(context).value
20
21
  end
21
22
 
22
- def to_pkl_string(scopes)
23
- to_string(scopes)
23
+ def to_string(context = nil)
24
+ to_ruby(context).to_s
24
25
  end
25
26
 
26
- def ==(other)
27
- other.instance_of?(self.class) && value == other.value
27
+ def to_pkl_string(context = nil)
28
+ to_string(context)
28
29
  end
29
30
 
30
- def coerce(_operator, r_operand)
31
- [value, r_operand.value]
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
- id.as(:unqualified_member_ref)
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, integer_literal, boolean_literal, string_literal,
13
- unqualified_member_ref, bracketed(expression)
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
- primary.as(:receiver) >>
20
- (ws? >> str('.') >> ws? >> id).repeat(1).as(:member)
21
- ).as(:qualified_member_ref) | primary
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(:subscript_operation) do
80
+ rule(:qualified_member_ref_or_subscript_operation) do
25
81
  (
26
- qualified_member_ref.as(:receiver) >>
82
+ primary.as(:receiver) >>
27
83
  (
28
- pure_ws? >> bracketed(expression, '[', ']') >>
29
- (ws? >> str('=')).absent?
30
- ).repeat(1).as(:key)
31
- ).as(:subscript_operation) | qualified_member_ref
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
- (str(:-) | str(:!)).as(:unary_operator) >>
37
- ws? >> subscript_operation.as(:operand)
38
- ) | subscript_operation
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) | unary_operation
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
- '||': 1, '&&': 2,
57
- '==': 3, '!=': 3,
58
- '<': 4, '>': 4, '<=': 4, '>=': 4,
59
- '+': 5, '-': 5,
60
- '*': 6, '/': 6, '~/': 6, '%': 6,
61
- '**': 7
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
- if operator == :**
76
- [atom, priority, :right]
77
- else
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(unqualified_member_ref: simple(:member)) do
85
- Node::MemberReference.new(nil, member, member.position)
149
+ rule(argument_list: subtree(:arguments)) do
150
+ arguments == '' ? nil : Array(arguments)
86
151
  end
87
152
 
88
153
  rule(
89
- qualified_member_ref:
90
- { receiver: simple(:receiver), member: sequence(:member) }
154
+ unqualified_member_ref:
155
+ { name: simple(:name) }
91
156
  ) do
92
- member.inject(receiver) do |r, m|
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
- subscript_operation:
99
- { receiver: simple(:receiver), key: sequence(:key) }
161
+ unqualified_member_ref:
162
+ { name: simple(:name), arguments: subtree(:arguments) }
100
163
  ) do
101
- key.inject(receiver) do |r, k|
102
- Node::SubscriptOperation.new(r, k, r.position)
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(unary_operator: simple(:operator), operand: simple(:operand)) do
107
- Node::UnaryOperation.new(operator.to_sym, operand, node_position(operator))
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
- Node::BinaryOperation.new(
115
- operator.to_sym, l_operand, r_operand, l_operand.position
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