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
|