code-ruby 0.11.0 → 0.13.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/Gemfile +1 -0
- data/Gemfile.lock +5 -3
- data/Rakefile +5 -0
- data/bin/code +6 -0
- data/lib/code/node/base_10.rb +2 -2
- data/lib/code/node/base_16.rb +1 -5
- data/lib/code/node/base_2.rb +1 -5
- data/lib/code/node/base_8.rb +1 -5
- data/lib/code/node/call.rb +4 -4
- data/lib/code/node/code.rb +2 -1
- data/lib/code/node/decimal.rb +1 -4
- data/lib/code/node/dictionary.rb +6 -2
- data/lib/code/node/function.rb +3 -3
- data/lib/code/node/function_parameter.rb +5 -1
- data/lib/code/node/if.rb +2 -1
- data/lib/code/node/list.rb +2 -1
- data/lib/code/node/statement.rb +23 -23
- data/lib/code/node/string.rb +2 -1
- data/lib/code/object/argument.rb +4 -3
- data/lib/code/object/boolean.rb +4 -24
- data/lib/code/object/class.rb +3 -19
- data/lib/code/object/code.rb +16 -0
- data/lib/code/object/context.rb +6 -9
- data/lib/code/object/date.rb +25 -17
- data/lib/code/object/decimal.rb +30 -38
- data/lib/code/object/dictionary.rb +6 -21
- data/lib/code/object/duration.rb +7 -21
- data/lib/code/object/function.rb +29 -45
- data/lib/code/object/global.rb +56 -40
- data/lib/code/object/identifier_list.rb +0 -4
- data/lib/code/object/integer.rb +23 -46
- data/lib/code/object/json.rb +29 -0
- data/lib/code/object/list.rb +4 -21
- data/lib/code/object/nothing.rb +2 -20
- data/lib/code/object/parameter.rb +51 -0
- data/lib/code/object/range.rb +12 -27
- data/lib/code/object/string.rb +6 -27
- data/lib/code/object/time.rb +14 -24
- data/lib/code/object.rb +155 -15
- data/lib/code/parser.rb +1 -1
- data/lib/code/type.rb +10 -2
- data/lib/code/version.rb +1 -1
- data/lib/code-ruby.rb +6 -0
- data/lib/code.rb +8 -5
- data/spec/code/object/dictionary_spec.rb +0 -2
- data/spec/code_spec.rb +141 -29
- metadata +6 -3
- data/lib/code/object/number.rb +0 -11
data/lib/code/object/nothing.rb
CHANGED
@@ -2,32 +2,14 @@
|
|
2
2
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
|
-
class Nothing <
|
6
|
-
|
7
|
-
|
8
|
-
def initialize
|
5
|
+
class Nothing < Object
|
6
|
+
def initialize(*_args, **_kargs, &_block)
|
9
7
|
@raw = nil
|
10
8
|
end
|
11
9
|
|
12
|
-
def self.name
|
13
|
-
"Nothing"
|
14
|
-
end
|
15
|
-
|
16
|
-
def inspect
|
17
|
-
"nothing"
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_s
|
21
|
-
""
|
22
|
-
end
|
23
|
-
|
24
10
|
def truthy?
|
25
11
|
false
|
26
12
|
end
|
27
|
-
|
28
|
-
def as_json(...)
|
29
|
-
raw.as_json(...)
|
30
|
-
end
|
31
13
|
end
|
32
14
|
end
|
33
15
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Object
|
5
|
+
class Parameter < Object
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
@raw = Dictionary.new(args.first.presence || {})
|
8
|
+
end
|
9
|
+
|
10
|
+
def code_name
|
11
|
+
String.new(raw.code_get(String.new(:name)))
|
12
|
+
end
|
13
|
+
|
14
|
+
def code_keyword
|
15
|
+
Boolean.new(raw.code_get(String.new(:keyword)))
|
16
|
+
end
|
17
|
+
|
18
|
+
def code_regular_splat
|
19
|
+
Boolean.new(raw.code_get(String.new(:regular_splat)))
|
20
|
+
end
|
21
|
+
|
22
|
+
def code_keyword_splat
|
23
|
+
Boolean.new(raw.code_get(String.new(:keyword_splat)))
|
24
|
+
end
|
25
|
+
|
26
|
+
def code_default
|
27
|
+
Code.new(raw.code_get(String.new(:default)))
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate(...)
|
31
|
+
default.evaluate(...)
|
32
|
+
end
|
33
|
+
|
34
|
+
def regular?
|
35
|
+
!keyword?
|
36
|
+
end
|
37
|
+
|
38
|
+
def keyword?
|
39
|
+
code_keyword.truthy?
|
40
|
+
end
|
41
|
+
|
42
|
+
def regular_splat?
|
43
|
+
code_regular_splat.truthy?
|
44
|
+
end
|
45
|
+
|
46
|
+
def keyword_splat?
|
47
|
+
code_keyword_splat.truthy?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/code/object/range.rb
CHANGED
@@ -3,17 +3,14 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Range < Object
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :left, :right, :options, :exclude_end
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@left =
|
10
|
-
@right =
|
11
|
-
@
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
def self.name
|
16
|
-
"Range"
|
8
|
+
def initialize(*args, **_kargs, &_block)
|
9
|
+
@left = args.first.presence || Integer.new(0)
|
10
|
+
@right = args.second.presence || Integer.new(0)
|
11
|
+
@options = Dictionary.new(args.third.presence || {})
|
12
|
+
@exclude_end = Boolean.new(options.code_get(String.new(:exclude_end)))
|
13
|
+
@raw = ::Range.new(left, right, exclude_end?)
|
17
14
|
end
|
18
15
|
|
19
16
|
def call(**args)
|
@@ -45,7 +42,7 @@ class Code
|
|
45
42
|
sig(args) { Function }
|
46
43
|
code_select(value, **globals)
|
47
44
|
when "step"
|
48
|
-
sig(args) {
|
45
|
+
sig(args) { Integer | Decimal }
|
49
46
|
code_step(value)
|
50
47
|
when "to_list"
|
51
48
|
sig(args)
|
@@ -102,6 +99,10 @@ class Code
|
|
102
99
|
)
|
103
100
|
end
|
104
101
|
|
102
|
+
def exclude_end?
|
103
|
+
exclude_end.truthy?
|
104
|
+
end
|
105
|
+
|
105
106
|
def code_step(argument)
|
106
107
|
list = List.new
|
107
108
|
element = left
|
@@ -126,22 +127,6 @@ class Code
|
|
126
127
|
def code_to_list
|
127
128
|
List.new(raw.to_a)
|
128
129
|
end
|
129
|
-
|
130
|
-
def exclude_end?
|
131
|
-
!!exclude_end
|
132
|
-
end
|
133
|
-
|
134
|
-
def inspect
|
135
|
-
to_s
|
136
|
-
end
|
137
|
-
|
138
|
-
def to_s
|
139
|
-
raw.to_s
|
140
|
-
end
|
141
|
-
|
142
|
-
def as_json(...)
|
143
|
-
raw.as_json(...)
|
144
|
-
end
|
145
130
|
end
|
146
131
|
end
|
147
132
|
end
|
data/lib/code/object/string.rb
CHANGED
@@ -3,15 +3,10 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class String < Object
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@raw = string.to_s
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.name
|
14
|
-
"String"
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
raw = args.first || Nothing.new
|
8
|
+
raw = raw.raw if raw.is_a?(Object)
|
9
|
+
@raw = raw.to_s
|
15
10
|
end
|
16
11
|
|
17
12
|
def call(**args)
|
@@ -25,7 +20,7 @@ class Code
|
|
25
20
|
sig(args)
|
26
21
|
code_to_function(**globals)
|
27
22
|
when "*"
|
28
|
-
sig(args) {
|
23
|
+
sig(args) { Integer | Decimal }
|
29
24
|
code_multiplication(value)
|
30
25
|
when "+"
|
31
26
|
sig(args) { Object }
|
@@ -65,7 +60,7 @@ class Code
|
|
65
60
|
end
|
66
61
|
|
67
62
|
def code_to_function(**globals)
|
68
|
-
|
63
|
+
Node::Code.new(
|
69
64
|
[
|
70
65
|
{
|
71
66
|
function: {
|
@@ -89,22 +84,6 @@ class Code
|
|
89
84
|
]
|
90
85
|
).evaluate(**globals)
|
91
86
|
end
|
92
|
-
|
93
|
-
def inspect
|
94
|
-
raw.inspect
|
95
|
-
end
|
96
|
-
|
97
|
-
def succ
|
98
|
-
String.new(raw.succ)
|
99
|
-
end
|
100
|
-
|
101
|
-
def to_s
|
102
|
-
raw
|
103
|
-
end
|
104
|
-
|
105
|
-
def as_json(...)
|
106
|
-
raw.as_json(...)
|
107
|
-
end
|
108
87
|
end
|
109
88
|
end
|
110
89
|
end
|
data/lib/code/object/time.rb
CHANGED
@@ -5,17 +5,11 @@ class Code
|
|
5
5
|
class Time < Object
|
6
6
|
DEFAULT_ZONE = "Etc/UTC"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(time)
|
8
|
+
def initialize(*args, **_kargs, &_block)
|
11
9
|
::Time.zone ||= DEFAULT_ZONE
|
12
|
-
|
13
|
-
|
14
|
-
@raw = ::Time.zone.parse(
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.name
|
18
|
-
"Time"
|
10
|
+
raw = args.first.presence || ::Time.zone.now
|
11
|
+
raw = raw.raw if raw.is_an?(Object)
|
12
|
+
@raw = ::Time.zone.parse(raw.to_s)
|
19
13
|
end
|
20
14
|
|
21
15
|
def self.call(**args)
|
@@ -28,6 +22,9 @@ class Code
|
|
28
22
|
when "tomorrow"
|
29
23
|
sig(args)
|
30
24
|
code_tomorrow
|
25
|
+
when "yesterday"
|
26
|
+
sig(args)
|
27
|
+
code_yesterday
|
31
28
|
else
|
32
29
|
super
|
33
30
|
end
|
@@ -35,12 +32,17 @@ class Code
|
|
35
32
|
|
36
33
|
def self.code_tomorrow
|
37
34
|
::Time.zone ||= DEFAULT_ZONE
|
38
|
-
new(::Time.zone.tomorrow
|
35
|
+
new(::Time.zone.tomorrow)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.code_yesterday
|
39
|
+
::Time.zone ||= DEFAULT_ZONE
|
40
|
+
new(::Time.zone.yesterday)
|
39
41
|
end
|
40
42
|
|
41
43
|
def self.code_now
|
42
44
|
::Time.zone ||= DEFAULT_ZONE
|
43
|
-
new(::Time.zone.now
|
45
|
+
new(::Time.zone.now)
|
44
46
|
end
|
45
47
|
|
46
48
|
def call(**args)
|
@@ -83,18 +85,6 @@ class Code
|
|
83
85
|
def code_future?
|
84
86
|
code_after?
|
85
87
|
end
|
86
|
-
|
87
|
-
def inspect
|
88
|
-
to_s
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_s
|
92
|
-
raw.to_s
|
93
|
-
end
|
94
|
-
|
95
|
-
def as_json(...)
|
96
|
-
raw.as_json(...)
|
97
|
-
end
|
98
88
|
end
|
99
89
|
end
|
100
90
|
end
|
data/lib/code/object.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
|
-
|
6
|
-
|
5
|
+
attr_reader :raw
|
6
|
+
|
7
|
+
def initialize(*_args, **_kargs, &_block)
|
7
8
|
end
|
8
9
|
|
9
|
-
def self.
|
10
|
-
|
10
|
+
def self.maybe
|
11
|
+
Type::Maybe.new(self)
|
11
12
|
end
|
12
13
|
|
13
14
|
def self.repeat(minimum = 0, maximum = nil)
|
@@ -29,6 +30,9 @@ class Code
|
|
29
30
|
value = arguments.first&.value
|
30
31
|
|
31
32
|
case operator.to_s
|
33
|
+
when "new"
|
34
|
+
sig(args) { Object.repeat }
|
35
|
+
code_new(*arguments.map(&:value))
|
32
36
|
when "!", "not"
|
33
37
|
sig(args)
|
34
38
|
code_exclamation_point
|
@@ -65,6 +69,48 @@ class Code
|
|
65
69
|
when "||", "or"
|
66
70
|
sig(args) { Object }
|
67
71
|
code_or_operator(value)
|
72
|
+
when "to_boolean"
|
73
|
+
sig(args)
|
74
|
+
Boolean.new(self)
|
75
|
+
when "to_class"
|
76
|
+
sig(args)
|
77
|
+
Class.new(self)
|
78
|
+
when "to_date"
|
79
|
+
sig(args)
|
80
|
+
Date.new(self)
|
81
|
+
when "to_decimal"
|
82
|
+
sig(args)
|
83
|
+
Decimal.new(self)
|
84
|
+
when "to_dictionary"
|
85
|
+
sig(args)
|
86
|
+
Dictionary.new(self)
|
87
|
+
when "to_duration"
|
88
|
+
sig(args)
|
89
|
+
Duration.new(self)
|
90
|
+
when "to_integer"
|
91
|
+
sig(args)
|
92
|
+
Integer.new(self)
|
93
|
+
when "to_list"
|
94
|
+
sig(args)
|
95
|
+
List.new(self)
|
96
|
+
when "to_nothing"
|
97
|
+
sig(args)
|
98
|
+
Nothing.new(self)
|
99
|
+
when "to_range"
|
100
|
+
sig(args)
|
101
|
+
Range.new(self)
|
102
|
+
when "to_string"
|
103
|
+
sig(args)
|
104
|
+
String.new(self)
|
105
|
+
when "to_time"
|
106
|
+
sig(args)
|
107
|
+
Time.new(self)
|
108
|
+
when "as_json"
|
109
|
+
sig(args)
|
110
|
+
code_as_json
|
111
|
+
when "to_json"
|
112
|
+
sig(args) { { pretty: Boolean.maybe } }
|
113
|
+
code_to_json(pretty: value&.code_get(String.new(:pretty)))
|
68
114
|
when /=$/
|
69
115
|
sig(args) { Object }
|
70
116
|
|
@@ -86,12 +132,16 @@ class Code
|
|
86
132
|
context.code_fetch(self)
|
87
133
|
else
|
88
134
|
raise(
|
89
|
-
|
135
|
+
Error::Undefined,
|
90
136
|
"#{operator} not defined on #{inspect}:Class"
|
91
137
|
)
|
92
138
|
end
|
93
139
|
end
|
94
140
|
|
141
|
+
def self.code_new(*arguments)
|
142
|
+
new(*arguments)
|
143
|
+
end
|
144
|
+
|
95
145
|
def self.code_and_operator(other)
|
96
146
|
truthy? ? other : self
|
97
147
|
end
|
@@ -145,10 +195,6 @@ class Code
|
|
145
195
|
nil
|
146
196
|
end
|
147
197
|
|
148
|
-
def self.name
|
149
|
-
"Object"
|
150
|
-
end
|
151
|
-
|
152
198
|
def self.to_s
|
153
199
|
name
|
154
200
|
end
|
@@ -161,6 +207,26 @@ class Code
|
|
161
207
|
true
|
162
208
|
end
|
163
209
|
|
210
|
+
def self.to_json(...)
|
211
|
+
as_json(...).to_json(...)
|
212
|
+
end
|
213
|
+
|
214
|
+
def self.as_json(...)
|
215
|
+
name.as_json(...)
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.code_to_json(pretty: nil)
|
219
|
+
if Boolean.new(pretty).truthy?
|
220
|
+
String.new(::JSON.pretty_generate(self))
|
221
|
+
else
|
222
|
+
String.new(to_json)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.code_as_json
|
227
|
+
Json.to_code(as_json)
|
228
|
+
end
|
229
|
+
|
164
230
|
def <=>(other)
|
165
231
|
if respond_to?(:raw)
|
166
232
|
raw <=> (other.respond_to?(:raw) ? other.raw : other)
|
@@ -220,6 +286,48 @@ class Code
|
|
220
286
|
when "||", "or"
|
221
287
|
sig(args) { Object }
|
222
288
|
code_or_operator(value)
|
289
|
+
when "to_boolean"
|
290
|
+
sig(args)
|
291
|
+
Boolean.new(self)
|
292
|
+
when "to_class"
|
293
|
+
sig(args)
|
294
|
+
Class.new(self)
|
295
|
+
when "to_date"
|
296
|
+
sig(args)
|
297
|
+
Date.new(self)
|
298
|
+
when "to_decimal"
|
299
|
+
sig(args)
|
300
|
+
Decimal.new(self)
|
301
|
+
when "to_duration"
|
302
|
+
sig(args)
|
303
|
+
Duration.new(self)
|
304
|
+
when "to_dictionary"
|
305
|
+
sig(args)
|
306
|
+
Dictionary.new(self)
|
307
|
+
when "to_integer"
|
308
|
+
sig(args)
|
309
|
+
Integer.new(self)
|
310
|
+
when "to_list"
|
311
|
+
sig(args)
|
312
|
+
List.new(self)
|
313
|
+
when "to_nothing"
|
314
|
+
sig(args)
|
315
|
+
Nothing.new(self)
|
316
|
+
when "to_range"
|
317
|
+
sig(args)
|
318
|
+
Range.new(self)
|
319
|
+
when "to_string"
|
320
|
+
sig(args)
|
321
|
+
String.new(self)
|
322
|
+
when "to_time"
|
323
|
+
sig(args)
|
324
|
+
Time.new(self)
|
325
|
+
when "as_json"
|
326
|
+
sig(args)
|
327
|
+
code_as_json
|
328
|
+
when "to_json"
|
329
|
+
sig(args) { { pretty: Boolean.maybe } }
|
330
|
+
code_to_json(pretty: value&.code_get(String.new(:pretty)))
|
223
331
|
when /=$/
|
224
332
|
sig(args) { Object }
|
225
333
|
|
@@ -241,8 +349,8 @@ class Code
|
|
241
349
|
context.code_fetch(self)
|
242
350
|
else
|
243
351
|
raise(
|
244
|
-
|
245
|
-
"#{operator} not defined on #{inspect}:#{self.class.name}"
|
352
|
+
Error::Undefined,
|
353
|
+
"#{operator.inspect} not defined on #{inspect}:#{self.class.name}"
|
246
354
|
)
|
247
355
|
end
|
248
356
|
end
|
@@ -264,11 +372,23 @@ class Code
|
|
264
372
|
end
|
265
373
|
|
266
374
|
def code_exclusive_range(value)
|
267
|
-
Range.new(
|
375
|
+
Range.new(
|
376
|
+
self,
|
377
|
+
value,
|
378
|
+
Dictionary.new({
|
379
|
+
String.new(:exclude_end) => Boolean.new(true)
|
380
|
+
})
|
381
|
+
)
|
268
382
|
end
|
269
383
|
|
270
384
|
def code_inclusive_range(value)
|
271
|
-
Range.new(
|
385
|
+
Range.new(
|
386
|
+
self,
|
387
|
+
value,
|
388
|
+
Dictionary.new({
|
389
|
+
String.new(:exclude_end) => Boolean.new(false)
|
390
|
+
})
|
391
|
+
)
|
272
392
|
end
|
273
393
|
|
274
394
|
def code_or_operator(other)
|
@@ -317,11 +437,31 @@ class Code
|
|
317
437
|
end
|
318
438
|
|
319
439
|
def to_json(...)
|
320
|
-
as_json(...).to_json
|
440
|
+
as_json(...).to_json(...)
|
321
441
|
end
|
322
442
|
|
323
443
|
def as_json(...)
|
324
|
-
raw.as_json
|
444
|
+
raw.as_json(...)
|
445
|
+
end
|
446
|
+
|
447
|
+
def code_to_json(pretty: nil)
|
448
|
+
if Boolean.new(pretty).truthy?
|
449
|
+
String.new(::JSON.pretty_generate(self))
|
450
|
+
else
|
451
|
+
String.new(to_json)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
def code_as_json
|
456
|
+
Json.to_code(as_json)
|
457
|
+
end
|
458
|
+
|
459
|
+
def succ
|
460
|
+
if raw.respond_to?(:succ)
|
461
|
+
self.class.new(raw.succ)
|
462
|
+
else
|
463
|
+
self.class.new(self)
|
464
|
+
end
|
325
465
|
end
|
326
466
|
end
|
327
467
|
end
|
data/lib/code/parser.rb
CHANGED
data/lib/code/type.rb
CHANGED
@@ -2,8 +2,16 @@
|
|
2
2
|
|
3
3
|
class Code
|
4
4
|
class Type
|
5
|
-
def
|
6
|
-
|
5
|
+
def maybe
|
6
|
+
Maybe.new(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def repeat(minimum = 0, maximum = nil)
|
10
|
+
Repeat.new(self, minimum:, maximum:)
|
11
|
+
end
|
12
|
+
|
13
|
+
def |(other)
|
14
|
+
Or.new(self, other)
|
7
15
|
end
|
8
16
|
|
9
17
|
def valid?(_argument)
|
data/lib/code/version.rb
CHANGED
data/lib/code-ruby.rb
CHANGED
@@ -5,7 +5,9 @@ require "active_support/core_ext/date/conversions"
|
|
5
5
|
require "active_support/core_ext/numeric/time"
|
6
6
|
require "active_support/core_ext/object/json"
|
7
7
|
require "active_support/core_ext/object/blank"
|
8
|
+
require "active_support/core_ext/array/access"
|
8
9
|
require "bigdecimal"
|
10
|
+
require "bigdecimal/util"
|
9
11
|
require "json"
|
10
12
|
require "language-ruby"
|
11
13
|
require "stringio"
|
@@ -15,3 +17,7 @@ require "zeitwerk"
|
|
15
17
|
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
16
18
|
loader.ignore("#{__dir__}/code-ruby.rb")
|
17
19
|
loader.setup
|
20
|
+
|
21
|
+
class Object
|
22
|
+
alias is_an? is_a?
|
23
|
+
end
|
data/lib/code.rb
CHANGED
@@ -17,6 +17,12 @@ class Code
|
|
17
17
|
@context = Object::Context.new
|
18
18
|
end
|
19
19
|
|
20
|
+
def self.parse(input, timeout: DEFAULT_TIMEOUT)
|
21
|
+
Timeout.timeout(timeout) do
|
22
|
+
Parser.parse(input).to_raw
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
20
26
|
def self.evaluate(
|
21
27
|
input,
|
22
28
|
output: StringIO.new,
|
@@ -28,11 +34,8 @@ class Code
|
|
28
34
|
|
29
35
|
def evaluate
|
30
36
|
Timeout.timeout(timeout) do
|
31
|
-
|
32
|
-
|
33
|
-
output:,
|
34
|
-
error:
|
35
|
-
)
|
37
|
+
parsed = Code.parse(input)
|
38
|
+
Node::Code.new(parsed).evaluate(context:, output:, error:)
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
@@ -76,10 +76,8 @@ RSpec.describe Code::Object::Dictionary do
|
|
76
76
|
["{ a: nothing }.compact", "{}"],
|
77
77
|
["{ age: 31 }.delete_unless { |key| key == :age }", "{ age: 31 }"],
|
78
78
|
["{ age: 31 }.delete_unless(Integer)", "{ age: 31 }"],
|
79
|
-
["{ age: 31 }.delete_unless(Number)", "{ age: 31 }"],
|
80
79
|
["{ age: 31 }.keep_unless { |key| key == :age }", "{}"],
|
81
80
|
["{ age: 31 }.keep_unless(Integer)", "{}"],
|
82
|
-
["{ age: 31 }.keep_unless(Number)", "{}"],
|
83
81
|
["{ first_name: :Dorian } < dictionary", "true"],
|
84
82
|
["{ first_name: :Dorian }.any? { |_, value| value == :Dorian }", "true"],
|
85
83
|
["{ first_name: :Dorian }.delete_if { |_, value| value == :Dorian }", "{}"],
|