rupkl 0.2.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/lib/rupkl/node/amend_expression.rb +2 -2
- data/lib/rupkl/node/any.rb +15 -4
- data/lib/rupkl/node/base.rb +32 -2
- data/lib/rupkl/node/boolean.rb +26 -9
- data/lib/rupkl/node/collection.rb +176 -0
- data/lib/rupkl/node/data_size.rb +254 -0
- data/lib/rupkl/node/duration.rb +266 -0
- data/lib/rupkl/node/dynamic.rb +19 -15
- data/lib/rupkl/node/identifier.rb +5 -1
- data/lib/rupkl/node/if_expression.rb +45 -0
- data/lib/rupkl/node/intseq.rb +84 -0
- data/lib/rupkl/node/listing.rb +11 -4
- data/lib/rupkl/node/map.rb +120 -0
- data/lib/rupkl/node/mapping.rb +13 -6
- data/lib/rupkl/node/member_finder.rb +4 -10
- data/lib/rupkl/node/member_reference.rb +5 -3
- data/lib/rupkl/node/method_call.rb +2 -3
- data/lib/rupkl/node/method_definition.rb +74 -18
- data/lib/rupkl/node/node_common.rb +1 -1
- data/lib/rupkl/node/null.rb +1 -4
- data/lib/rupkl/node/number.rb +133 -45
- data/lib/rupkl/node/object.rb +322 -66
- data/lib/rupkl/node/operation.rb +123 -100
- data/lib/rupkl/node/pair.rb +58 -0
- data/lib/rupkl/node/pkl_module.rb +4 -4
- data/lib/rupkl/node/regex.rb +196 -0
- data/lib/rupkl/node/string.rb +155 -133
- data/lib/rupkl/node/struct_common.rb +70 -35
- data/lib/rupkl/node/value_common.rb +1 -5
- data/lib/rupkl/parser/expression.rb +43 -6
- data/lib/rupkl/parser/misc.rb +20 -0
- data/lib/rupkl/parser/object.rb +96 -13
- data/lib/rupkl/parser/pkl_class.rb +12 -5
- data/lib/rupkl/pkl_object.rb +2 -18
- data/lib/rupkl/version.rb +1 -1
- data/lib/rupkl.rb +10 -2
- metadata +17 -9
@@ -4,7 +4,7 @@ module RuPkl
|
|
4
4
|
module Node
|
5
5
|
module MemberFinder
|
6
6
|
def property(name)
|
7
|
-
value = find_property(name)
|
7
|
+
value = find_property(name)&.value
|
8
8
|
return value if value
|
9
9
|
|
10
10
|
super if self.class <= Any
|
@@ -22,17 +22,13 @@ module RuPkl
|
|
22
22
|
def find_property(name)
|
23
23
|
return unless respond_to?(:properties)
|
24
24
|
|
25
|
-
properties
|
26
|
-
&.find { _1.name == name }
|
27
|
-
&.value
|
25
|
+
properties&.find { _1.name == name }
|
28
26
|
end
|
29
27
|
|
30
28
|
def find_entry(key)
|
31
29
|
return unless respond_to?(:entries)
|
32
30
|
|
33
|
-
entries
|
34
|
-
&.find { _1.key == key }
|
35
|
-
&.value
|
31
|
+
entries&.find { _1.key == key }
|
36
32
|
end
|
37
33
|
|
38
34
|
def find_element(index)
|
@@ -40,9 +36,7 @@ module RuPkl
|
|
40
36
|
return unless elements
|
41
37
|
return unless index.value.is_a?(::Integer)
|
42
38
|
|
43
|
-
elements
|
44
|
-
.find.with_index { |_, i| i == index.value }
|
45
|
-
&.value
|
39
|
+
elements.find.with_index { |_, i| i == index.value }
|
46
40
|
end
|
47
41
|
|
48
42
|
def find_pkl_method(name)
|
@@ -22,17 +22,19 @@ module RuPkl
|
|
22
22
|
|
23
23
|
def evaluate(context = nil)
|
24
24
|
do_evaluate do
|
25
|
-
resolve_member_reference(context, member, receiver, nullable?)
|
25
|
+
result = resolve_member_reference(context, member, receiver, nullable?)
|
26
|
+
result.evaluate
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
30
|
def resolve_reference(context = nil)
|
30
31
|
do_evaluate do
|
31
|
-
resolve_member_reference(context, member, receiver, nullable?)
|
32
|
+
result = resolve_member_reference(context, member, receiver, nullable?)
|
33
|
+
result.resolve_reference
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
def copy(parent = nil)
|
37
|
+
def copy(parent = nil, position = @position)
|
36
38
|
self
|
37
39
|
.class.new(parent, receiver&.copy, member&.copy, nullable?, position)
|
38
40
|
.tap { copy_scope_index(_1) }
|
@@ -30,7 +30,7 @@ module RuPkl
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def copy(parent = nil)
|
33
|
+
def copy(parent = nil, position = @position)
|
34
34
|
copied_args = arguments&.map(&:copy)
|
35
35
|
self.class
|
36
36
|
.new(parent, receiver&.copy, method_name, copied_args, nullable?, position)
|
@@ -56,8 +56,7 @@ module RuPkl
|
|
56
56
|
|
57
57
|
def execute_method(pkl_method, receiver, context)
|
58
58
|
pkl_method
|
59
|
-
.call(receiver, arguments, context, position)
|
60
|
-
.tap { parent&.add_child(_1) }
|
59
|
+
.call(receiver, arguments, context, parent, position)
|
61
60
|
end
|
62
61
|
end
|
63
62
|
end
|
@@ -17,6 +17,20 @@ module RuPkl
|
|
17
17
|
def check_type(value, context, position)
|
18
18
|
type&.check_type(value, context, position)
|
19
19
|
end
|
20
|
+
|
21
|
+
def varparam?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class VariadicMethodParam < MethodParam
|
27
|
+
def check_type(values, context, position)
|
28
|
+
values.each { |v| super(v, context, position) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def varparam?
|
32
|
+
true
|
33
|
+
end
|
20
34
|
end
|
21
35
|
|
22
36
|
class MethodDefinition
|
@@ -35,9 +49,13 @@ module RuPkl
|
|
35
49
|
attr_reader :type
|
36
50
|
attr_reader :body
|
37
51
|
|
38
|
-
def call(receiver, arguments, context, position)
|
52
|
+
def call(receiver, arguments, context, parent, position)
|
39
53
|
args = evaluate_arguments(arguments, context, position)
|
40
|
-
execute_method(receiver, args)
|
54
|
+
execute_method(receiver, args, parent, position)
|
55
|
+
end
|
56
|
+
|
57
|
+
def coexistable?(other)
|
58
|
+
name != other.name
|
41
59
|
end
|
42
60
|
|
43
61
|
private
|
@@ -45,29 +63,46 @@ module RuPkl
|
|
45
63
|
def evaluate_arguments(arguments, context, position)
|
46
64
|
check_arity(arguments, position)
|
47
65
|
|
48
|
-
|
49
|
-
|
66
|
+
params&.each_with_index&.to_h do |param, i|
|
67
|
+
arg =
|
68
|
+
if param.varparam?
|
69
|
+
Array(arguments&.[](i..))
|
70
|
+
else
|
71
|
+
arguments&.[](i)
|
72
|
+
end
|
73
|
+
evaluate_argument(param, arg, context)
|
50
74
|
end
|
51
75
|
end
|
52
76
|
|
53
|
-
def evaluate_argument(arg, param, context)
|
54
|
-
value = arg.evaluate(context)
|
55
|
-
param.check_type(value, context, position)
|
56
|
-
[param.name, value]
|
57
|
-
end
|
58
|
-
|
59
77
|
def check_arity(arguments, position)
|
60
78
|
n_args = arguments&.size || 0
|
61
|
-
n_params =
|
62
|
-
return if n_args
|
79
|
+
n_params = n_params_range
|
80
|
+
return if n_args in ^n_params
|
63
81
|
|
64
82
|
m = "expected #{n_params} method arguments but got #{n_args}"
|
65
83
|
raise EvaluationError.new(m, position)
|
66
84
|
end
|
67
85
|
|
68
|
-
def
|
86
|
+
def n_params_range
|
87
|
+
n_params = params&.size || 0
|
88
|
+
params&.last&.varparam? && (n_params - 1..) || n_params
|
89
|
+
end
|
90
|
+
|
91
|
+
def evaluate_argument(param, arg, context)
|
92
|
+
value =
|
93
|
+
if param.varparam?
|
94
|
+
arg.map { _1.evaluate(context) }
|
95
|
+
else
|
96
|
+
arg.evaluate(context)
|
97
|
+
end
|
98
|
+
param.check_type(value, context, position)
|
99
|
+
[param.name, value]
|
100
|
+
end
|
101
|
+
|
102
|
+
def execute_method(receiver, arguments, parent, position)
|
69
103
|
context = create_call_context(receiver, arguments)
|
70
104
|
execute_body(context)
|
105
|
+
.copy(parent, position) # set parent and position given from the caller
|
71
106
|
end
|
72
107
|
|
73
108
|
def create_call_context(receiver, arguments)
|
@@ -94,7 +129,7 @@ module RuPkl
|
|
94
129
|
def initialize(arguments)
|
95
130
|
@properties =
|
96
131
|
arguments&.map do |(name, value)|
|
97
|
-
ObjectProperty.new(nil, name, value, nil)
|
132
|
+
ObjectProperty.new(nil, name, value, nil, nil)
|
98
133
|
end
|
99
134
|
super(nil, *@properties, nil)
|
100
135
|
end
|
@@ -125,18 +160,39 @@ module RuPkl
|
|
125
160
|
end
|
126
161
|
end
|
127
162
|
|
163
|
+
class BuiltinVariadicMethodParam < VariadicMethodParam
|
164
|
+
def initialize(name, klass)
|
165
|
+
id = Identifier.new(nil, name, nil)
|
166
|
+
type = BuiltinMethodTypeChecker.new(klass)
|
167
|
+
super(nil, id, type, nil)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
128
171
|
class BuiltinMethodDefinition < MethodDefinition
|
129
172
|
def initialize(name, **params, &body)
|
130
|
-
param_list = params.map { |n, t| BuiltinMethodParams.new(n, t) }
|
131
173
|
id = Identifier.new(nil, name, nil)
|
132
|
-
|
174
|
+
list = param_list(params)
|
175
|
+
super(nil, id, list, nil, nil, nil)
|
133
176
|
@body = body
|
134
177
|
end
|
135
178
|
|
179
|
+
def execute_method(receiver, arguments, parent, position)
|
180
|
+
args = arguments&.transform_keys(&:to_sym)
|
181
|
+
receiver
|
182
|
+
.instance_exec(args, parent, position, &body)
|
183
|
+
end
|
184
|
+
|
136
185
|
private
|
137
186
|
|
138
|
-
def
|
139
|
-
|
187
|
+
def param_list(params)
|
188
|
+
params.map do |name, type|
|
189
|
+
case type
|
190
|
+
in [klass, { varparams: true }]
|
191
|
+
BuiltinVariadicMethodParam.new(name, klass)
|
192
|
+
else
|
193
|
+
BuiltinMethodParams.new(name, type)
|
194
|
+
end
|
195
|
+
end
|
140
196
|
end
|
141
197
|
end
|
142
198
|
end
|
data/lib/rupkl/node/null.rb
CHANGED
@@ -4,6 +4,7 @@ module RuPkl
|
|
4
4
|
module Node
|
5
5
|
class Null < Any
|
6
6
|
include ValueCommon
|
7
|
+
include Operatable
|
7
8
|
|
8
9
|
uninstantiable_class
|
9
10
|
|
@@ -15,10 +16,6 @@ module RuPkl
|
|
15
16
|
'null'
|
16
17
|
end
|
17
18
|
|
18
|
-
def undefined_operator?(operator)
|
19
|
-
[:==, :'!='].none?(operator)
|
20
|
-
end
|
21
|
-
|
22
19
|
def null?
|
23
20
|
true
|
24
21
|
end
|
data/lib/rupkl/node/number.rb
CHANGED
@@ -4,31 +4,56 @@ module RuPkl
|
|
4
4
|
module Node
|
5
5
|
class Number < Any
|
6
6
|
include ValueCommon
|
7
|
+
include Operatable
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
abstract_class
|
10
|
+
uninstantiable_class
|
11
|
+
|
12
|
+
def u_op_minus(position)
|
13
|
+
self.class.new(nil, -value, position)
|
10
14
|
end
|
11
15
|
|
12
|
-
|
13
|
-
|
16
|
+
{
|
17
|
+
b_op_exp: [:**, false], b_op_div: [:/, false],
|
18
|
+
b_op_truncating_div: [:/, true], b_op_rem: [:%, false],
|
19
|
+
b_op_add: [:+, false], b_op_sub: [:-, false]
|
20
|
+
}.each do |method_name, (op, result_int)|
|
21
|
+
class_eval(<<~M, __FILE__, __LINE__ + 1)
|
22
|
+
# def b_op_exp(r_operand, position)
|
23
|
+
# b_op_arithmetic(:'**', r_operand, false, position)
|
24
|
+
# end
|
25
|
+
def #{method_name}(r_operand, position)
|
26
|
+
b_op_arithmetic(:'#{op}', r_operand, #{result_int}, position)
|
27
|
+
end
|
28
|
+
M
|
14
29
|
end
|
15
30
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
[value.to_i, r_operand.value.to_i]
|
31
|
+
def b_op_mul(r_operand, position)
|
32
|
+
case r_operand
|
33
|
+
when Number then b_op_arithmetic(:*, r_operand, false, position)
|
34
|
+
else r_operand.b_op_mul(self, position)
|
21
35
|
end
|
22
36
|
end
|
23
37
|
|
24
|
-
|
25
|
-
|
26
|
-
|
38
|
+
{
|
39
|
+
b_op_lt: :<, b_op_gt: :>,
|
40
|
+
b_op_le: :<=, b_op_ge: :>=,
|
41
|
+
b_op_eq: :==, b_op_ne: :'!='
|
42
|
+
}.each do |method_name, op|
|
43
|
+
class_eval(<<~M, __FILE__, __LINE__ + 1)
|
44
|
+
# def b_op_lt(r_operand, position)
|
45
|
+
# l, r = coerce(:'<', r_operand)
|
46
|
+
# result = l < r
|
47
|
+
# Boolean.new(nil, result, position)
|
48
|
+
# end
|
49
|
+
def #{method_name}(r_operand, position)
|
50
|
+
l, r = coerce(:'#{op}', r_operand)
|
51
|
+
result = l #{op} r
|
52
|
+
Boolean.new(nil, result, position)
|
53
|
+
end
|
54
|
+
M
|
27
55
|
end
|
28
56
|
|
29
|
-
abstract_class
|
30
|
-
uninstantiable_class
|
31
|
-
|
32
57
|
define_builtin_property(:sign) do
|
33
58
|
result =
|
34
59
|
case value
|
@@ -39,6 +64,30 @@ module RuPkl
|
|
39
64
|
self.class.new(self, result, position)
|
40
65
|
end
|
41
66
|
|
67
|
+
[
|
68
|
+
:b, :kb, :kib, :mb, :mib, :gb, :gib, :tb, :tib, :pb, :pib
|
69
|
+
].each do |unit|
|
70
|
+
class_eval(<<~P, __FILE__, __LINE__ + 1)
|
71
|
+
# define_builtin_property(:b) do
|
72
|
+
# DataSize.new(self, self, :b, position)
|
73
|
+
# end
|
74
|
+
define_builtin_property(:#{unit}) do
|
75
|
+
DataSize.new(self, self, :#{unit}, position)
|
76
|
+
end
|
77
|
+
P
|
78
|
+
end
|
79
|
+
|
80
|
+
[:ns, :us, :ms, :s, :min, :h, :d].each do |unit|
|
81
|
+
class_eval(<<~P, __FILE__, __LINE__ + 1)
|
82
|
+
# define_builtin_property(:ns) do
|
83
|
+
# Duration.new(self, self, :ns, position)
|
84
|
+
# end
|
85
|
+
define_builtin_property(:#{unit}) do
|
86
|
+
Duration.new(self, self, :#{unit}, position)
|
87
|
+
end
|
88
|
+
P
|
89
|
+
end
|
90
|
+
|
42
91
|
define_builtin_property(:abs) do
|
43
92
|
self.class.new(self, value.abs, position)
|
44
93
|
end
|
@@ -76,33 +125,72 @@ module RuPkl
|
|
76
125
|
Boolean.new(self, !value.zero?, position)
|
77
126
|
end
|
78
127
|
|
79
|
-
define_builtin_method(:toString) do
|
80
|
-
String.new(
|
128
|
+
define_builtin_method(:toString) do |_, parent, position|
|
129
|
+
String.new(parent, value.to_s, nil, position)
|
81
130
|
end
|
82
131
|
|
83
|
-
define_builtin_method(:toInt) do
|
84
|
-
Int.new(
|
132
|
+
define_builtin_method(:toInt) do |_, parent, position|
|
133
|
+
Int.new(parent, value.to_i, position)
|
85
134
|
end
|
86
135
|
|
87
|
-
define_builtin_method(:toFloat) do
|
88
|
-
Float.new(
|
136
|
+
define_builtin_method(:toFloat) do |_, parent, position|
|
137
|
+
Float.new(parent, value.to_f, position)
|
89
138
|
end
|
90
139
|
|
91
|
-
define_builtin_method(:round) do
|
140
|
+
define_builtin_method(:round) do |_, parent, position|
|
92
141
|
result = value.finite? && value.round || value
|
93
|
-
self.class.new(
|
142
|
+
self.class.new(parent, result, position)
|
94
143
|
end
|
95
144
|
|
96
|
-
define_builtin_method(:truncate) do
|
145
|
+
define_builtin_method(:truncate) do |_, parent, position|
|
97
146
|
result = value.finite? && value.truncate || value
|
98
|
-
self.class.new(
|
147
|
+
self.class.new(parent, result, position)
|
99
148
|
end
|
100
149
|
|
101
|
-
define_builtin_method(
|
150
|
+
define_builtin_method(
|
151
|
+
:isBetween, first: Number, last: Number
|
152
|
+
) do |args, parent, position|
|
153
|
+
f = args[:first].value
|
154
|
+
l = args[:last].value
|
102
155
|
result =
|
103
|
-
[f
|
104
|
-
(f
|
105
|
-
Boolean.new(
|
156
|
+
[f, l, value].all? { _1.finite? || _1.infinite? } &&
|
157
|
+
(f..l).include?(value)
|
158
|
+
Boolean.new(parent, result, position)
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def defined_operator?(operator)
|
164
|
+
[:[], :'!@', :'&&', :'||'].none?(operator)
|
165
|
+
end
|
166
|
+
|
167
|
+
def valid_r_operand?(operator, operand)
|
168
|
+
case operator
|
169
|
+
when :* then operand in Number | DataSize | Duration
|
170
|
+
else operand in Number
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def coerce(operator, r_operand)
|
175
|
+
if force_float?(operator, r_operand)
|
176
|
+
[value.to_f, r_operand.value.to_f]
|
177
|
+
else
|
178
|
+
[value.to_i, r_operand.value.to_i]
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def force_float?(operator, r_operand)
|
183
|
+
operator == :/ || [self, r_operand].any?(Float)
|
184
|
+
end
|
185
|
+
|
186
|
+
def b_op_arithmetic(operator, r_operand, result_int, position)
|
187
|
+
l, r = coerce(operator, r_operand)
|
188
|
+
result = l.__send__(operator, r)
|
189
|
+
if result_int || result.integer?
|
190
|
+
Int.new(nil, result, position)
|
191
|
+
else
|
192
|
+
Float.new(nil, result, position)
|
193
|
+
end
|
106
194
|
end
|
107
195
|
end
|
108
196
|
|
@@ -125,37 +213,37 @@ module RuPkl
|
|
125
213
|
self.class.new(self, ~value, position)
|
126
214
|
end
|
127
215
|
|
128
|
-
define_builtin_method(:shl, n: Int) do |
|
129
|
-
result = value << n.value
|
130
|
-
self.class.new(
|
216
|
+
define_builtin_method(:shl, n: Int) do |args, parent, position|
|
217
|
+
result = value << args[:n].value
|
218
|
+
self.class.new(parent, result, position)
|
131
219
|
end
|
132
220
|
|
133
|
-
define_builtin_method(:shr, n: Int) do |
|
134
|
-
result = value >> n.value
|
135
|
-
self.class.new(
|
221
|
+
define_builtin_method(:shr, n: Int) do |args, parent, position|
|
222
|
+
result = value >> args[:n].value
|
223
|
+
self.class.new(parent, result, position)
|
136
224
|
end
|
137
225
|
|
138
|
-
define_builtin_method(:ushr, n: Int) do |
|
226
|
+
define_builtin_method(:ushr, n: Int) do |args, parent, position|
|
139
227
|
result =
|
140
228
|
if value.negative?
|
141
229
|
mask = (1 << 63) - 1
|
142
|
-
n.value.times.inject(value) { |v, _| (v >> 1) & mask }
|
230
|
+
args[:n].value.times.inject(value) { |v, _| (v >> 1) & mask }
|
143
231
|
else
|
144
|
-
value >> n.value
|
232
|
+
value >> args[:n].value
|
145
233
|
end
|
146
|
-
self.class.new(
|
234
|
+
self.class.new(parent, result, position)
|
147
235
|
end
|
148
236
|
|
149
|
-
define_builtin_method(:and, n: Int) do |
|
150
|
-
self.class.new(
|
237
|
+
define_builtin_method(:and, n: Int) do |args, parent, position|
|
238
|
+
self.class.new(parent, value & args[:n].value, position)
|
151
239
|
end
|
152
240
|
|
153
|
-
define_builtin_method(:or, n: Int) do |
|
154
|
-
self.class.new(
|
241
|
+
define_builtin_method(:or, n: Int) do |args, parent, position|
|
242
|
+
self.class.new(parent, value | args[:n].value, position)
|
155
243
|
end
|
156
244
|
|
157
|
-
define_builtin_method(:xor, n: Int) do |
|
158
|
-
self.class.new(
|
245
|
+
define_builtin_method(:xor, n: Int) do |args, parent, position|
|
246
|
+
self.class.new(parent, value ^ args[:n].value, position)
|
159
247
|
end
|
160
248
|
end
|
161
249
|
|