rupkl 0.1.0 → 0.2.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 +99 -0
- data/lib/rupkl/node/base.rb +45 -0
- data/lib/rupkl/node/boolean.rb +12 -4
- data/lib/rupkl/node/context.rb +27 -0
- data/lib/rupkl/node/declared_type.rb +32 -0
- data/lib/rupkl/node/dynamic.rb +28 -59
- data/lib/rupkl/node/identifier.rb +16 -6
- data/lib/rupkl/node/listing.rb +61 -0
- data/lib/rupkl/node/mapping.rb +47 -0
- data/lib/rupkl/node/member_finder.rb +55 -0
- data/lib/rupkl/node/member_reference.rb +44 -21
- data/lib/rupkl/node/method_call.rb +64 -0
- data/lib/rupkl/node/method_definition.rb +143 -0
- data/lib/rupkl/node/node_common.rb +76 -0
- data/lib/rupkl/node/null.rb +27 -0
- data/lib/rupkl/node/number.rb +136 -6
- data/lib/rupkl/node/object.rb +369 -73
- data/lib/rupkl/node/operation.rb +97 -60
- data/lib/rupkl/node/pkl_module.rb +16 -28
- data/lib/rupkl/node/reference_resolver.rb +79 -0
- data/lib/rupkl/node/string.rb +388 -18
- data/lib/rupkl/node/struct_common.rb +119 -57
- 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 -9
- data/lib/rupkl/parser/expression.rb +158 -41
- 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 +4 -0
- data/lib/rupkl/parser/object.rb +57 -25
- data/lib/rupkl/parser/pkl_class.rb +28 -8
- 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 +26 -6
- data/lib/rupkl/version.rb +1 -1
- data/lib/rupkl.rb +25 -4
- metadata +33 -3
- data/lib/rupkl/node/pkl_class.rb +0 -30
data/lib/rupkl/node/operation.rb
CHANGED
@@ -3,36 +3,50 @@
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
5
|
module OperationCommon
|
6
|
-
|
7
|
-
evaluate(scopes).to_ruby(nil)
|
8
|
-
end
|
6
|
+
include NodeCommon
|
9
7
|
|
10
|
-
def
|
11
|
-
|
8
|
+
def initialize(parent, operator, *operands, position)
|
9
|
+
super(parent, *operands, position)
|
10
|
+
@operator = operator
|
11
|
+
@operands = operands
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
attr_reader :operator
|
15
|
+
attr_reader :operands
|
16
|
+
|
17
|
+
def copy(parent = nil)
|
18
|
+
copied_operands = operands.map(&:copy)
|
19
|
+
self.class.new(parent, operator, *copied_operands, position)
|
16
20
|
end
|
17
21
|
|
18
22
|
private
|
19
23
|
|
20
|
-
def s_op(
|
21
|
-
r = receiver.evaluate(
|
24
|
+
def s_op(context)
|
25
|
+
r = receiver.evaluate(context)
|
22
26
|
check_operator(r)
|
23
27
|
|
24
|
-
k = key.evaluate(
|
28
|
+
k = key.evaluate(context)
|
25
29
|
check_key_operand(r, k)
|
26
30
|
|
27
|
-
r.find_by_key(k) ||
|
31
|
+
(v = r.find_by_key(k)) ||
|
28
32
|
begin
|
29
|
-
message = "cannot find key '#{k.to_pkl_string(
|
33
|
+
message = "cannot find key '#{k.to_pkl_string(context)}'"
|
30
34
|
raise EvaluationError.new(message, position)
|
31
35
|
end
|
36
|
+
|
37
|
+
v.evaluate
|
32
38
|
end
|
33
39
|
|
34
|
-
def
|
35
|
-
o = operand.evaluate(
|
40
|
+
def non_null_op(context)
|
41
|
+
o = operand.evaluate(context)
|
42
|
+
return o unless o.null?
|
43
|
+
|
44
|
+
m = "expected a non-null value but got '#{o.to_pkl_string(context)}'"
|
45
|
+
raise EvaluationError.new(m, position)
|
46
|
+
end
|
47
|
+
|
48
|
+
def u_op(context)
|
49
|
+
o = operand.evaluate(context)
|
36
50
|
check_operator(o)
|
37
51
|
|
38
52
|
result =
|
@@ -44,18 +58,26 @@ module RuPkl
|
|
44
58
|
create_op_result(result)
|
45
59
|
end
|
46
60
|
|
47
|
-
def b_op(
|
48
|
-
l = l_operand.evaluate(
|
61
|
+
def b_op(context)
|
62
|
+
l = l_operand.evaluate(context)
|
49
63
|
check_operator(l)
|
50
64
|
return l if short_circuit?(l)
|
51
65
|
|
52
|
-
r = r_operand.evaluate(
|
66
|
+
r = r_operand.evaluate(context)
|
53
67
|
check_r_operand(l, r)
|
68
|
+
.then { return _1 if _1 }
|
54
69
|
|
55
70
|
l, r = l.coerce(operator, r)
|
56
71
|
create_op_result(l.__send__(ruby_op, r))
|
57
72
|
end
|
58
73
|
|
74
|
+
def null_coalescing_op(context)
|
75
|
+
l = l_operand.evaluate(context)
|
76
|
+
return l unless l.null?
|
77
|
+
|
78
|
+
r_operand.evaluate(context)
|
79
|
+
end
|
80
|
+
|
59
81
|
def check_operator(operand)
|
60
82
|
undefined_operator?(operand) &&
|
61
83
|
begin
|
@@ -87,13 +109,16 @@ module RuPkl
|
|
87
109
|
end
|
88
110
|
|
89
111
|
def check_r_operand(l_operand, r_operand)
|
90
|
-
invalid_r_operand?(l_operand, r_operand)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
112
|
+
return unless invalid_r_operand?(l_operand, r_operand)
|
113
|
+
|
114
|
+
if [:==, :'!='].include?(operator)
|
115
|
+
create_op_result(operator != :==)
|
116
|
+
else
|
117
|
+
message =
|
118
|
+
"invalid operand type #{r_operand.class.basename} is given " \
|
119
|
+
"for operator '#{operator}'"
|
120
|
+
raise EvaluationError.new(message, position)
|
121
|
+
end
|
97
122
|
end
|
98
123
|
|
99
124
|
def invalid_r_operand?(l_operand, r_operand)
|
@@ -115,10 +140,10 @@ module RuPkl
|
|
115
140
|
|
116
141
|
def create_op_result(result)
|
117
142
|
case result
|
118
|
-
when ::Integer then
|
119
|
-
when ::Float then Float.new(result, position)
|
120
|
-
when ::String then String.new(result, nil, position)
|
121
|
-
when
|
143
|
+
when ::Integer then Int.new(parent, result, position)
|
144
|
+
when ::Float then Float.new(parent, result, position)
|
145
|
+
when ::String then String.new(parent, result, nil, position)
|
146
|
+
when true, false then Boolean.new(parent, result, position)
|
122
147
|
end
|
123
148
|
end
|
124
149
|
end
|
@@ -126,60 +151,72 @@ module RuPkl
|
|
126
151
|
class SubscriptOperation
|
127
152
|
include OperationCommon
|
128
153
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
|
154
|
+
def receiver
|
155
|
+
operands.first
|
156
|
+
end
|
157
|
+
|
158
|
+
def key
|
159
|
+
operands.last
|
133
160
|
end
|
134
161
|
|
135
|
-
|
136
|
-
|
137
|
-
|
162
|
+
def evaluate(context = nil)
|
163
|
+
s_op(context)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class NonNullOperation
|
168
|
+
include OperationCommon
|
138
169
|
|
139
|
-
def
|
140
|
-
|
170
|
+
def operand
|
171
|
+
operands.first
|
141
172
|
end
|
142
173
|
|
143
|
-
def evaluate(
|
144
|
-
|
174
|
+
def evaluate(context = nil)
|
175
|
+
non_null_op(context)
|
145
176
|
end
|
146
177
|
end
|
147
178
|
|
148
179
|
class UnaryOperation
|
149
180
|
include OperationCommon
|
150
181
|
|
151
|
-
def
|
152
|
-
|
153
|
-
@operand = operand
|
154
|
-
@position = position
|
182
|
+
def operand
|
183
|
+
operands.first
|
155
184
|
end
|
156
185
|
|
157
|
-
|
158
|
-
|
159
|
-
attr_reader :position
|
160
|
-
|
161
|
-
def evaluate(scopes)
|
162
|
-
u_op(scopes)
|
186
|
+
def evaluate(context = nil)
|
187
|
+
u_op(context)
|
163
188
|
end
|
164
189
|
end
|
165
190
|
|
166
191
|
class BinaryOperation
|
167
192
|
include OperationCommon
|
168
193
|
|
169
|
-
def
|
170
|
-
|
171
|
-
@l_operand = l_operand
|
172
|
-
@r_operand = r_operand
|
173
|
-
@position = position
|
194
|
+
def l_operand
|
195
|
+
operands.first
|
174
196
|
end
|
175
197
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
198
|
+
def r_operand
|
199
|
+
operands.last
|
200
|
+
end
|
201
|
+
|
202
|
+
def evaluate(context = nil)
|
203
|
+
b_op(context)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class NullCoalescingOperation
|
208
|
+
include OperationCommon
|
209
|
+
|
210
|
+
def l_operand
|
211
|
+
operands.first
|
212
|
+
end
|
213
|
+
|
214
|
+
def r_operand
|
215
|
+
operands.last
|
216
|
+
end
|
180
217
|
|
181
|
-
def evaluate(
|
182
|
-
|
218
|
+
def evaluate(context = nil)
|
219
|
+
null_coalescing_op(context)
|
183
220
|
end
|
184
221
|
end
|
185
222
|
end
|
@@ -2,45 +2,33 @@
|
|
2
2
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
|
-
class PklModule
|
5
|
+
class PklModule < Any
|
6
6
|
include StructCommon
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
8
|
+
abstract_class
|
9
|
+
klass_name :Module
|
10
|
+
|
11
|
+
def properties
|
12
|
+
@body&.properties(visibility: :object)
|
15
13
|
end
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
def pkl_methods
|
16
|
+
@body&.pkl_methods
|
17
|
+
end
|
19
18
|
|
20
|
-
def
|
21
|
-
|
22
|
-
self.class.new(evaluate_properties(s), position)
|
23
|
-
end
|
19
|
+
def pkl_classes
|
20
|
+
@body&.pkl_classes
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
end
|
23
|
+
def evaluate(context = nil)
|
24
|
+
resolve_structure(context)
|
25
|
+
super
|
30
26
|
end
|
31
27
|
|
32
28
|
private
|
33
29
|
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def evaluate_properties(scopes)
|
39
|
-
properties&.each_with_object([]) do |property, result|
|
40
|
-
property
|
41
|
-
.evaluate(scopes)
|
42
|
-
.then { add_hash_member(result, _1, :name) }
|
43
|
-
end
|
30
|
+
def properties_not_allowed?
|
31
|
+
false
|
44
32
|
end
|
45
33
|
end
|
46
34
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
module ReferenceResolver
|
6
|
+
private
|
7
|
+
|
8
|
+
def resolve_member_reference(context, target, receiver, nullable)
|
9
|
+
scopes, raise_error, ifnone =
|
10
|
+
if receiver
|
11
|
+
evaluate_receiver(receiver, context)&.then do |r|
|
12
|
+
[[r], raise_error?(r, nullable), ifnone_value(r)]
|
13
|
+
end
|
14
|
+
else
|
15
|
+
exec_on(context) do |c|
|
16
|
+
[[c&.objects&.last, Base.instance, *c&.scopes], true]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
find_member(scopes, target, raise_error, ifnone)
|
20
|
+
end
|
21
|
+
|
22
|
+
def raise_error?(receiver, nullable)
|
23
|
+
!(nullable && receiver&.null?)
|
24
|
+
end
|
25
|
+
|
26
|
+
def evaluate_receiver(receiver, context)
|
27
|
+
return unless receiver
|
28
|
+
|
29
|
+
if receiver.structure?
|
30
|
+
receiver
|
31
|
+
.resolve_reference(context)
|
32
|
+
.resolve_structure(context)
|
33
|
+
else
|
34
|
+
receiver.evaluate(context)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_member(scopes, target, raise_error, ifnone)
|
39
|
+
if scope_index.index
|
40
|
+
get_member_node(scopes[scope_index.index], target)
|
41
|
+
else
|
42
|
+
search_member(scopes, target, raise_error, ifnone)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def search_member(scopes, target, raise_error, ifnone)
|
47
|
+
node, index = search_member_from_scopes(scopes, target)
|
48
|
+
if node
|
49
|
+
scope_index.index = index
|
50
|
+
return node
|
51
|
+
end
|
52
|
+
|
53
|
+
raise_error &&
|
54
|
+
(raise unresolve_reference_error(target))
|
55
|
+
|
56
|
+
ifnone
|
57
|
+
end
|
58
|
+
|
59
|
+
def search_member_from_scopes(scopes, target)
|
60
|
+
scopes.reverse_each.with_index do |scope, i|
|
61
|
+
node = get_member_node(scope, target)
|
62
|
+
return [node, scopes.size - i - 1] if node
|
63
|
+
end
|
64
|
+
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
ScopeIndex = Struct.new(:index)
|
69
|
+
|
70
|
+
def scope_index
|
71
|
+
@scope_index ||= ScopeIndex.new
|
72
|
+
end
|
73
|
+
|
74
|
+
def copy_scope_index(target)
|
75
|
+
target.instance_exec(scope_index) { @scope_index = _1 }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|