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
@@ -0,0 +1,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class MethodParam
|
6
|
+
include NodeCommon
|
7
|
+
|
8
|
+
def initialize(parent, name, type, position)
|
9
|
+
super
|
10
|
+
@name = name
|
11
|
+
@type = type
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :name
|
15
|
+
attr_reader :type
|
16
|
+
|
17
|
+
def check_type(value, context, position)
|
18
|
+
type&.check_type(value, context, position)
|
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
|
34
|
+
end
|
35
|
+
|
36
|
+
class MethodDefinition
|
37
|
+
include NodeCommon
|
38
|
+
|
39
|
+
def initialize(parent, name, params, type, body, position)
|
40
|
+
super(parent, name, *params, type, body, position)
|
41
|
+
@name = name
|
42
|
+
@params = params
|
43
|
+
@type = type
|
44
|
+
@body = body&.copy # reset `#parent` handle
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :name
|
48
|
+
attr_reader :params
|
49
|
+
attr_reader :type
|
50
|
+
attr_reader :body
|
51
|
+
|
52
|
+
def call(receiver, arguments, context, parent, position)
|
53
|
+
args = evaluate_arguments(arguments, context, position)
|
54
|
+
execute_method(receiver, args, parent, position)
|
55
|
+
end
|
56
|
+
|
57
|
+
def coexistable?(other)
|
58
|
+
name != other.name
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def evaluate_arguments(arguments, context, position)
|
64
|
+
check_arity(arguments, position)
|
65
|
+
|
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)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_arity(arguments, position)
|
78
|
+
n_args = arguments&.size || 0
|
79
|
+
n_params = n_params_range
|
80
|
+
return if n_args in ^n_params
|
81
|
+
|
82
|
+
m = "expected #{n_params} method arguments but got #{n_args}"
|
83
|
+
raise EvaluationError.new(m, position)
|
84
|
+
end
|
85
|
+
|
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)
|
103
|
+
context = create_call_context(receiver, arguments)
|
104
|
+
execute_body(context)
|
105
|
+
.copy(parent, position) # set parent and position given from the caller
|
106
|
+
end
|
107
|
+
|
108
|
+
def create_call_context(receiver, arguments)
|
109
|
+
local_context = MethodCallContext.new(arguments)
|
110
|
+
method_context = current_context
|
111
|
+
if receiver
|
112
|
+
Context.new([*method_context.scopes, local_context], [receiver])
|
113
|
+
else
|
114
|
+
method_context.push_scope(local_context)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def execute_body(context)
|
119
|
+
body
|
120
|
+
.evaluate(context)
|
121
|
+
.tap { type&.check_type(_1, context, position) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class MethodCallContext
|
126
|
+
include NodeCommon
|
127
|
+
include MemberFinder
|
128
|
+
|
129
|
+
def initialize(arguments)
|
130
|
+
@properties =
|
131
|
+
arguments&.map do |(name, value)|
|
132
|
+
ObjectProperty.new(nil, name, value, nil, nil)
|
133
|
+
end
|
134
|
+
super(nil, *@properties, nil)
|
135
|
+
end
|
136
|
+
|
137
|
+
attr_reader :properties
|
138
|
+
end
|
139
|
+
|
140
|
+
class BuiltinMethodTypeChecker
|
141
|
+
include TypeCommon
|
142
|
+
|
143
|
+
def initialize(klass)
|
144
|
+
super(nil, nil)
|
145
|
+
@klass = klass
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def match_type?(klass, _context)
|
151
|
+
klass <= @klass
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class BuiltinMethodParams < MethodParam
|
156
|
+
def initialize(name, klass)
|
157
|
+
id = Identifier.new(nil, name, nil)
|
158
|
+
type = BuiltinMethodTypeChecker.new(klass)
|
159
|
+
super(nil, id, type, nil)
|
160
|
+
end
|
161
|
+
end
|
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
|
+
|
171
|
+
class BuiltinMethodDefinition < MethodDefinition
|
172
|
+
def initialize(name, **params, &body)
|
173
|
+
id = Identifier.new(nil, name, nil)
|
174
|
+
list = param_list(params)
|
175
|
+
super(nil, id, list, nil, nil, nil)
|
176
|
+
@body = body
|
177
|
+
end
|
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
|
+
|
185
|
+
private
|
186
|
+
|
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
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
module NodeCommon
|
6
|
+
def initialize(parent, *children, position)
|
7
|
+
@position = position
|
8
|
+
parent&.add_child(self)
|
9
|
+
children.each { add_child(_1) }
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :parent
|
13
|
+
attr_reader :children
|
14
|
+
attr_reader :position
|
15
|
+
|
16
|
+
def resolve_reference(_context = nil)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def resolve_structure(_context = nil)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_ruby(context = nil)
|
25
|
+
evaluate(context).to_ruby(context)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_string(context = nil)
|
29
|
+
evaluate(context).to_string(context)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_pkl_string(context = nil)
|
33
|
+
evaluate(context).to_pkl_string(context)
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_child(child)
|
37
|
+
return unless child
|
38
|
+
|
39
|
+
child.parent ||
|
40
|
+
child.instance_exec(self) { @parent = _1 }
|
41
|
+
|
42
|
+
@children&.any? { _1.equal?(child) } ||
|
43
|
+
(@children ||= []) << child
|
44
|
+
end
|
45
|
+
|
46
|
+
def copy(parent = nil, position = @position)
|
47
|
+
copied_children = children&.map(&:copy)
|
48
|
+
self.class.new(parent, *copied_children, position)
|
49
|
+
end
|
50
|
+
|
51
|
+
def current_context
|
52
|
+
parent&.current_context
|
53
|
+
end
|
54
|
+
|
55
|
+
def structure?
|
56
|
+
false
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
INVALID_STRING = String.new('?').freeze
|
62
|
+
|
63
|
+
def invalid_string
|
64
|
+
INVALID_STRING
|
65
|
+
end
|
66
|
+
|
67
|
+
def invalid_string?(string)
|
68
|
+
string.equal?(INVALID_STRING)
|
69
|
+
end
|
70
|
+
|
71
|
+
def exec_on(context)
|
72
|
+
yield(context || current_context)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Null < Any
|
6
|
+
include ValueCommon
|
7
|
+
include Operatable
|
8
|
+
|
9
|
+
uninstantiable_class
|
10
|
+
|
11
|
+
def initialize(parent, position)
|
12
|
+
super(parent, nil, position)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_string(_context = nil)
|
16
|
+
'null'
|
17
|
+
end
|
18
|
+
|
19
|
+
def null?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/rupkl/node/number.rb
CHANGED
@@ -2,19 +2,173 @@
|
|
2
2
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
|
-
class Number
|
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)
|
14
|
+
end
|
15
|
+
|
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
|
29
|
+
end
|
30
|
+
|
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)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
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
|
55
|
+
end
|
56
|
+
|
57
|
+
define_builtin_property(:sign) do
|
58
|
+
result =
|
59
|
+
case value
|
60
|
+
when :positive?.to_proc then 1
|
61
|
+
when :negative?.to_proc then -1
|
62
|
+
else value
|
63
|
+
end
|
64
|
+
self.class.new(self, result, position)
|
65
|
+
end
|
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
|
+
|
91
|
+
define_builtin_property(:abs) do
|
92
|
+
self.class.new(self, value.abs, position)
|
93
|
+
end
|
94
|
+
|
95
|
+
define_builtin_property(:ceil) do
|
96
|
+
result = value.finite? && value.ceil || value
|
97
|
+
self.class.new(self, result, position)
|
98
|
+
end
|
99
|
+
|
100
|
+
define_builtin_property(:floor) do
|
101
|
+
result = value.finite? && value.floor || value
|
102
|
+
self.class.new(self, result, position)
|
103
|
+
end
|
104
|
+
|
105
|
+
define_builtin_property(:isPositive) do
|
106
|
+
result = value.zero? || value.positive?
|
107
|
+
Boolean.new(self, result, position)
|
108
|
+
end
|
109
|
+
|
110
|
+
define_builtin_property(:isFinite) do
|
111
|
+
Boolean.new(self, value.finite?, position)
|
112
|
+
end
|
113
|
+
|
114
|
+
define_builtin_property(:isInfinite) do
|
115
|
+
result = value.infinite? && true || false
|
116
|
+
Boolean.new(self, result, position)
|
117
|
+
end
|
118
|
+
|
119
|
+
define_builtin_property(:isNaN) do
|
120
|
+
result = !value.integer? && value.nan?
|
121
|
+
Boolean.new(self, result, position)
|
122
|
+
end
|
123
|
+
|
124
|
+
define_builtin_property(:isNonZero) do
|
125
|
+
Boolean.new(self, !value.zero?, position)
|
126
|
+
end
|
127
|
+
|
128
|
+
define_builtin_method(:toString) do |_, parent, position|
|
129
|
+
String.new(parent, value.to_s, nil, position)
|
130
|
+
end
|
131
|
+
|
132
|
+
define_builtin_method(:toInt) do |_, parent, position|
|
133
|
+
Int.new(parent, value.to_i, position)
|
134
|
+
end
|
135
|
+
|
136
|
+
define_builtin_method(:toFloat) do |_, parent, position|
|
137
|
+
Float.new(parent, value.to_f, position)
|
138
|
+
end
|
139
|
+
|
140
|
+
define_builtin_method(:round) do |_, parent, position|
|
141
|
+
result = value.finite? && value.round || value
|
142
|
+
self.class.new(parent, result, position)
|
143
|
+
end
|
144
|
+
|
145
|
+
define_builtin_method(:truncate) do |_, parent, position|
|
146
|
+
result = value.finite? && value.truncate || value
|
147
|
+
self.class.new(parent, result, position)
|
10
148
|
end
|
11
149
|
|
12
|
-
|
13
|
-
|
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
|
155
|
+
result =
|
156
|
+
[f, l, value].all? { _1.finite? || _1.infinite? } &&
|
157
|
+
(f..l).include?(value)
|
158
|
+
Boolean.new(parent, result, position)
|
14
159
|
end
|
15
160
|
|
16
|
-
|
17
|
-
|
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
|
18
172
|
end
|
19
173
|
|
20
174
|
def coerce(operator, r_operand)
|
@@ -26,15 +180,79 @@ module RuPkl
|
|
26
180
|
end
|
27
181
|
|
28
182
|
def force_float?(operator, r_operand)
|
29
|
-
operator == :/ ||
|
30
|
-
|
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
|
31
194
|
end
|
32
195
|
end
|
33
196
|
|
34
|
-
class
|
197
|
+
class Int < Number
|
198
|
+
def initialize(parent, value, position)
|
199
|
+
super(parent, value.to_i, position)
|
200
|
+
end
|
201
|
+
|
202
|
+
uninstantiable_class
|
203
|
+
|
204
|
+
define_builtin_property(:isEven) do
|
205
|
+
Boolean.new(self, value.even?, position)
|
206
|
+
end
|
207
|
+
|
208
|
+
define_builtin_property(:isOdd) do
|
209
|
+
Boolean.new(self, value.odd?, position)
|
210
|
+
end
|
211
|
+
|
212
|
+
define_builtin_property(:inv) do
|
213
|
+
self.class.new(self, ~value, position)
|
214
|
+
end
|
215
|
+
|
216
|
+
define_builtin_method(:shl, n: Int) do |args, parent, position|
|
217
|
+
result = value << args[:n].value
|
218
|
+
self.class.new(parent, result, position)
|
219
|
+
end
|
220
|
+
|
221
|
+
define_builtin_method(:shr, n: Int) do |args, parent, position|
|
222
|
+
result = value >> args[:n].value
|
223
|
+
self.class.new(parent, result, position)
|
224
|
+
end
|
225
|
+
|
226
|
+
define_builtin_method(:ushr, n: Int) do |args, parent, position|
|
227
|
+
result =
|
228
|
+
if value.negative?
|
229
|
+
mask = (1 << 63) - 1
|
230
|
+
args[:n].value.times.inject(value) { |v, _| (v >> 1) & mask }
|
231
|
+
else
|
232
|
+
value >> args[:n].value
|
233
|
+
end
|
234
|
+
self.class.new(parent, result, position)
|
235
|
+
end
|
236
|
+
|
237
|
+
define_builtin_method(:and, n: Int) do |args, parent, position|
|
238
|
+
self.class.new(parent, value & args[:n].value, position)
|
239
|
+
end
|
240
|
+
|
241
|
+
define_builtin_method(:or, n: Int) do |args, parent, position|
|
242
|
+
self.class.new(parent, value | args[:n].value, position)
|
243
|
+
end
|
244
|
+
|
245
|
+
define_builtin_method(:xor, n: Int) do |args, parent, position|
|
246
|
+
self.class.new(parent, value ^ args[:n].value, position)
|
247
|
+
end
|
35
248
|
end
|
36
249
|
|
37
250
|
class Float < Number
|
251
|
+
def initialize(parent, value, position)
|
252
|
+
super(parent, value.to_f, position)
|
253
|
+
end
|
254
|
+
|
255
|
+
uninstantiable_class
|
38
256
|
end
|
39
257
|
end
|
40
258
|
end
|