code-ruby 1.2.7 → 1.4.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.lock +79 -63
- data/TODO +219 -0
- data/VERSION +1 -1
- data/bin/code +3 -0
- data/lib/code/concerns/shared.rb +423 -0
- data/lib/code/concerns.rb +6 -0
- data/lib/code/object/code.rb +6 -0
- data/lib/code/object/dictionary.rb +6 -0
- data/lib/code/object/global.rb +6 -1
- data/lib/code/object/list.rb +17 -0
- data/lib/code/object/nothing.rb +8 -0
- data/lib/code/object/string.rb +23 -3
- data/lib/code/object.rb +8 -446
- data/lib/code/parser/call.rb +7 -2
- data/lib/code/parser/class.rb +1 -34
- data/lib/code/parser/function.rb +18 -2
- data/lib/code/parser/group.rb +14 -0
- data/lib/code/parser/if.rb +25 -4
- data/lib/code/parser/name.rb +11 -2
- data/lib/code/parser/while.rb +26 -1
- data/lib/code-ruby.rb +12 -0
- data/lib/code.rb +25 -18
- data/spec/code_spec.rb +2 -0
- metadata +5 -2
@@ -0,0 +1,423 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
module Concerns
|
5
|
+
module Shared
|
6
|
+
attr_reader :raw
|
7
|
+
|
8
|
+
def call(**args)
|
9
|
+
code_operator = args.fetch(:operator, nil).to_code
|
10
|
+
code_arguments = args.fetch(:arguments, []).to_code
|
11
|
+
code_value = code_arguments.code_first
|
12
|
+
|
13
|
+
case code_operator.to_s
|
14
|
+
when "new"
|
15
|
+
sig(args) { Object.repeat }
|
16
|
+
code_new(*code_arguments.raw)
|
17
|
+
when "!", "not"
|
18
|
+
sig(args)
|
19
|
+
code_exclamation_point
|
20
|
+
when "!=", "different"
|
21
|
+
sig(args) { Object }
|
22
|
+
code_different(code_value)
|
23
|
+
when "&&", "and"
|
24
|
+
sig(args) { Object }
|
25
|
+
code_and(code_value)
|
26
|
+
when "+", "self"
|
27
|
+
sig(args)
|
28
|
+
code_self
|
29
|
+
when "..", "inclusive_range"
|
30
|
+
sig(args) { Object }
|
31
|
+
code_inclusive_range(code_value)
|
32
|
+
when "...", "exclusive_range"
|
33
|
+
sig(args) { Object }
|
34
|
+
code_exclusive_range(code_value)
|
35
|
+
when "==", "equal"
|
36
|
+
sig(args) { Object }
|
37
|
+
code_equal_equal(code_value)
|
38
|
+
when "===", "strict_equal"
|
39
|
+
sig(args) { Object }
|
40
|
+
code_equal_equal_equal(code_value)
|
41
|
+
when "falsy?"
|
42
|
+
sig(args)
|
43
|
+
code_falsy?
|
44
|
+
when "truthy?"
|
45
|
+
sig(args)
|
46
|
+
code_truthy?
|
47
|
+
when "||", "or"
|
48
|
+
sig(args) { Object }
|
49
|
+
code_or(code_value)
|
50
|
+
when "to_boolean"
|
51
|
+
sig(args)
|
52
|
+
code_to_boolean
|
53
|
+
when "to_class"
|
54
|
+
sig(args)
|
55
|
+
code_to_class
|
56
|
+
when "to_date"
|
57
|
+
sig(args)
|
58
|
+
code_to_date
|
59
|
+
when "to_decimal"
|
60
|
+
sig(args)
|
61
|
+
code_to_decimal
|
62
|
+
when "to_dictionary"
|
63
|
+
sig(args)
|
64
|
+
code_to_dictionary
|
65
|
+
when "to_duration"
|
66
|
+
sig(args)
|
67
|
+
code_to_duration
|
68
|
+
when "to_integer"
|
69
|
+
sig(args)
|
70
|
+
code_to_integer
|
71
|
+
when "to_list"
|
72
|
+
sig(args)
|
73
|
+
code_to_list
|
74
|
+
when "to_nothing"
|
75
|
+
sig(args)
|
76
|
+
code_to_nothing
|
77
|
+
when "to_range"
|
78
|
+
sig(args)
|
79
|
+
code_to_range
|
80
|
+
when "to_string"
|
81
|
+
sig(args)
|
82
|
+
code_to_string
|
83
|
+
when "to_time"
|
84
|
+
sig(args)
|
85
|
+
code_to_time
|
86
|
+
when "as_json"
|
87
|
+
sig(args)
|
88
|
+
code_as_json
|
89
|
+
when "duplicate"
|
90
|
+
sig(args)
|
91
|
+
code_duplicate
|
92
|
+
when "deep_duplicate"
|
93
|
+
sig(args)
|
94
|
+
code_deep_duplicate
|
95
|
+
when "to_parameter"
|
96
|
+
sig(args)
|
97
|
+
code_to_parameter
|
98
|
+
when "to_json"
|
99
|
+
sig(args) { { pretty: Object::Boolean.maybe } }
|
100
|
+
|
101
|
+
if code_arguments.any?
|
102
|
+
code_to_json(pretty: code_value.code_get(:pretty))
|
103
|
+
else
|
104
|
+
code_to_json
|
105
|
+
end
|
106
|
+
when "name"
|
107
|
+
sig(args)
|
108
|
+
code_name
|
109
|
+
when /=$/
|
110
|
+
sig(args) { Object }
|
111
|
+
|
112
|
+
if code_operator.to_s == "="
|
113
|
+
code_context = args.fetch(:context)
|
114
|
+
code_context.code_set(self, code_value)
|
115
|
+
else
|
116
|
+
code_context = args.fetch(:context).code_lookup!(self)
|
117
|
+
code_context.code_set(
|
118
|
+
self,
|
119
|
+
code_context.code_fetch(self).call(
|
120
|
+
**args,
|
121
|
+
operator: code_operator.to_s.chop,
|
122
|
+
arguments: Object::List.new([code_value])
|
123
|
+
)
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
code_context.code_fetch(self)
|
128
|
+
else
|
129
|
+
raise(
|
130
|
+
Error,
|
131
|
+
"#{code_operator.inspect} not defined on #{code_inspect}:#{code_name}"
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def <=>(other)
|
137
|
+
code_other = other.to_code
|
138
|
+
|
139
|
+
[raw, self.class] <=> [code_other.raw, code_other.class]
|
140
|
+
end
|
141
|
+
|
142
|
+
def ==(other)
|
143
|
+
code_other = other.to_code
|
144
|
+
|
145
|
+
[raw, self.class] == [code_other.raw, code_other.class]
|
146
|
+
end
|
147
|
+
|
148
|
+
def eql?(other)
|
149
|
+
code_other = other.to_code
|
150
|
+
|
151
|
+
[raw, self.class].eql?([code_other.raw, code_other.class])
|
152
|
+
end
|
153
|
+
|
154
|
+
def code_and(other)
|
155
|
+
code_other = other.to_code
|
156
|
+
|
157
|
+
truthy? ? code_other : self
|
158
|
+
end
|
159
|
+
|
160
|
+
def code_different(other)
|
161
|
+
code_other = other.to_code
|
162
|
+
|
163
|
+
Object::Boolean.new(self != code_other)
|
164
|
+
end
|
165
|
+
|
166
|
+
def code_equal_equal(other)
|
167
|
+
code_other = other.to_code
|
168
|
+
|
169
|
+
Object::Boolean.new(self == code_other)
|
170
|
+
end
|
171
|
+
|
172
|
+
def code_exclamation_point
|
173
|
+
Object::Boolean.new(falsy?)
|
174
|
+
end
|
175
|
+
|
176
|
+
def code_exclusive_range(value)
|
177
|
+
code_value = value.to_code
|
178
|
+
|
179
|
+
Object::Range.new(self, code_value, exclude_end: true)
|
180
|
+
end
|
181
|
+
|
182
|
+
def code_inclusive_range(value)
|
183
|
+
code_value = value.to_code
|
184
|
+
|
185
|
+
Object::Range.new(self, code_value, exclude_end: false)
|
186
|
+
end
|
187
|
+
|
188
|
+
def code_or(other)
|
189
|
+
code_other = other.to_code
|
190
|
+
|
191
|
+
truthy? ? self : code_other
|
192
|
+
end
|
193
|
+
|
194
|
+
def code_self
|
195
|
+
self
|
196
|
+
end
|
197
|
+
|
198
|
+
def code_equal_equal_equal(other)
|
199
|
+
code_other = other.to_code
|
200
|
+
|
201
|
+
Object::Boolean.new(self === code_other)
|
202
|
+
end
|
203
|
+
|
204
|
+
def falsy?
|
205
|
+
!truthy?
|
206
|
+
end
|
207
|
+
|
208
|
+
def hash
|
209
|
+
[self.class, raw].hash
|
210
|
+
end
|
211
|
+
|
212
|
+
def multi_fetch(hash, *keys)
|
213
|
+
keys.to_h { |key| [key, hash.fetch(key)] }
|
214
|
+
end
|
215
|
+
|
216
|
+
def sig(args, &)
|
217
|
+
Type::Sig.sig(args, object: self, &)
|
218
|
+
|
219
|
+
Object::Nothing.new
|
220
|
+
end
|
221
|
+
|
222
|
+
def truthy?
|
223
|
+
true
|
224
|
+
end
|
225
|
+
|
226
|
+
def to_json(...)
|
227
|
+
as_json(...).to_json(...)
|
228
|
+
end
|
229
|
+
|
230
|
+
def as_json(...)
|
231
|
+
raw.as_json(...)
|
232
|
+
end
|
233
|
+
|
234
|
+
def code_to_json(pretty: nil)
|
235
|
+
if Object::Boolean.new(pretty).truthy?
|
236
|
+
Object::String.new(::JSON.pretty_generate(self))
|
237
|
+
else
|
238
|
+
Object::String.new(to_json)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def code_as_json
|
243
|
+
as_json.to_code
|
244
|
+
end
|
245
|
+
|
246
|
+
def to_code
|
247
|
+
self
|
248
|
+
end
|
249
|
+
|
250
|
+
def succ
|
251
|
+
self.class.new(raw.succ)
|
252
|
+
end
|
253
|
+
|
254
|
+
def code_duplicate
|
255
|
+
self.class.new(self)
|
256
|
+
end
|
257
|
+
|
258
|
+
def code_deep_duplicate
|
259
|
+
self.class.new(self)
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.code_fetch(...)
|
263
|
+
Object::Nothing.new
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.code_set(...)
|
267
|
+
Object::Nothing.new
|
268
|
+
end
|
269
|
+
|
270
|
+
def self.code_get(...)
|
271
|
+
Object::Nothing.new
|
272
|
+
end
|
273
|
+
|
274
|
+
def code_fetch(...)
|
275
|
+
Object::Nothing.new
|
276
|
+
end
|
277
|
+
|
278
|
+
def code_set(...)
|
279
|
+
Object::Nothing.new
|
280
|
+
end
|
281
|
+
|
282
|
+
def code_get(...)
|
283
|
+
Object::Nothing.new
|
284
|
+
end
|
285
|
+
|
286
|
+
def code_to_parameter
|
287
|
+
code_to_string.code_parameterize
|
288
|
+
end
|
289
|
+
|
290
|
+
def code_falsy?
|
291
|
+
Object::Boolean.new(falsy?)
|
292
|
+
end
|
293
|
+
|
294
|
+
def code_truthy?
|
295
|
+
Object::Boolean.new(truthy?)
|
296
|
+
end
|
297
|
+
|
298
|
+
def code_to_boolean
|
299
|
+
Object::Boolean.new(self)
|
300
|
+
end
|
301
|
+
|
302
|
+
def code_to_class
|
303
|
+
Object::Class.new(self)
|
304
|
+
end
|
305
|
+
|
306
|
+
def code_to_date
|
307
|
+
Object::Date.new(self)
|
308
|
+
end
|
309
|
+
|
310
|
+
def code_to_decimal
|
311
|
+
Object::Decimal.new(self)
|
312
|
+
end
|
313
|
+
|
314
|
+
def code_to_dictionary
|
315
|
+
Object::Dictionary.new(self)
|
316
|
+
end
|
317
|
+
|
318
|
+
def code_to_duration
|
319
|
+
Object::Duration.new(self)
|
320
|
+
end
|
321
|
+
|
322
|
+
def code_to_integer
|
323
|
+
Object::Integer.new(self)
|
324
|
+
end
|
325
|
+
|
326
|
+
def code_to_list
|
327
|
+
Object::List.new(self)
|
328
|
+
end
|
329
|
+
|
330
|
+
def code_to_nothing
|
331
|
+
Object::Nothing.new(self)
|
332
|
+
end
|
333
|
+
|
334
|
+
def code_to_range
|
335
|
+
Object::Range.new(self)
|
336
|
+
end
|
337
|
+
|
338
|
+
def code_to_string
|
339
|
+
Object::String.new(self)
|
340
|
+
end
|
341
|
+
|
342
|
+
def code_to_time
|
343
|
+
Object::Time.new(self)
|
344
|
+
end
|
345
|
+
|
346
|
+
def to_s
|
347
|
+
code_to_string.raw
|
348
|
+
end
|
349
|
+
|
350
|
+
def inspect
|
351
|
+
code_inspect.raw
|
352
|
+
end
|
353
|
+
|
354
|
+
def nothing?
|
355
|
+
false
|
356
|
+
end
|
357
|
+
|
358
|
+
def code_falsy?
|
359
|
+
Object::Boolean.new(falsy?)
|
360
|
+
end
|
361
|
+
|
362
|
+
def code_truthy?
|
363
|
+
Object::Boolean.new(truthy?)
|
364
|
+
end
|
365
|
+
|
366
|
+
def code_to_boolean
|
367
|
+
Object::Boolean.new(self)
|
368
|
+
end
|
369
|
+
|
370
|
+
def code_to_class
|
371
|
+
Object::Class.new(self)
|
372
|
+
end
|
373
|
+
|
374
|
+
def code_to_date
|
375
|
+
Object::Date.new(self)
|
376
|
+
end
|
377
|
+
|
378
|
+
def code_to_decimal
|
379
|
+
Object::Decimal.new(self)
|
380
|
+
end
|
381
|
+
|
382
|
+
def code_to_dictionary
|
383
|
+
Object::Dictionary.new(self)
|
384
|
+
end
|
385
|
+
|
386
|
+
def code_to_duration
|
387
|
+
Object::Duration.new(self)
|
388
|
+
end
|
389
|
+
|
390
|
+
def code_to_integer
|
391
|
+
Object::Integer.new(self)
|
392
|
+
end
|
393
|
+
|
394
|
+
def code_to_list
|
395
|
+
Object::List.new(self)
|
396
|
+
end
|
397
|
+
|
398
|
+
def code_to_nothing
|
399
|
+
Object::Nothing.new(self)
|
400
|
+
end
|
401
|
+
|
402
|
+
def code_to_range
|
403
|
+
Object::Range.new(self)
|
404
|
+
end
|
405
|
+
|
406
|
+
def code_to_string
|
407
|
+
Object::String.new(self)
|
408
|
+
end
|
409
|
+
|
410
|
+
def code_to_time
|
411
|
+
Object::Time.new(self)
|
412
|
+
end
|
413
|
+
|
414
|
+
def code_inspect
|
415
|
+
code_to_string
|
416
|
+
end
|
417
|
+
|
418
|
+
def code_name
|
419
|
+
Object::String.new(name.to_s.split("::")[2..].join("::"))
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
data/lib/code/object/code.rb
CHANGED
data/lib/code/object/global.rb
CHANGED
@@ -7,8 +7,10 @@ class Code
|
|
7
7
|
code_operator = args.fetch(:operator, nil).to_code
|
8
8
|
code_arguments = args.fetch(:arguments, []).to_code
|
9
9
|
output = args.fetch(:output)
|
10
|
+
input = args.fetch(:input)
|
10
11
|
code_context = args.fetch(:context).to_code
|
11
12
|
code_value = code_arguments.code_first
|
13
|
+
globals = multi_fetch(args, *GLOBALS)
|
12
14
|
|
13
15
|
case code_operator.to_s
|
14
16
|
when "Boolean"
|
@@ -145,7 +147,7 @@ class Code
|
|
145
147
|
code_arguments.any? ? Json.new(*code_arguments.raw) : Class.new(Json)
|
146
148
|
when "evaluate"
|
147
149
|
sig(args) { Object }
|
148
|
-
Code.
|
150
|
+
Code.code_evaluate(code_value.code_to_string, **globals)
|
149
151
|
when "p"
|
150
152
|
sig(args) { Object.repeat }
|
151
153
|
output.puts(*code_arguments.raw.map(&:inspect))
|
@@ -154,6 +156,9 @@ class Code
|
|
154
156
|
sig(args) { Object.repeat }
|
155
157
|
output.print(*code_arguments.raw)
|
156
158
|
Nothing.new
|
159
|
+
when "read"
|
160
|
+
sig(args) { Object.repeat }
|
161
|
+
input.gets.to_code
|
157
162
|
when "puts"
|
158
163
|
sig(args) { Object.repeat }
|
159
164
|
output.puts(*code_arguments.raw)
|
data/lib/code/object/list.rb
CHANGED
@@ -436,12 +436,29 @@ class Code
|
|
436
436
|
raw.inject(&:code_plus) || Nothing.new
|
437
437
|
end
|
438
438
|
|
439
|
+
def code_deep_duplicate
|
440
|
+
List.new(raw.dup.map(&:code_deep_duplicate))
|
441
|
+
end
|
442
|
+
|
439
443
|
def code_get(argument)
|
440
444
|
code_argument = argument.to_code
|
441
445
|
|
442
446
|
raw[code_argument] || Nothing.new
|
443
447
|
end
|
444
448
|
|
449
|
+
def code_set(key, value)
|
450
|
+
code_key = key.to_code.code_to_integer
|
451
|
+
code_value = value.to_code
|
452
|
+
raw[code_key.raw] = code_value
|
453
|
+
code_value
|
454
|
+
end
|
455
|
+
|
456
|
+
def code_fetch(key)
|
457
|
+
code_key = key.to_code.code_to_integer
|
458
|
+
|
459
|
+
raw.fetch(code_key.raw, Nothing.new)
|
460
|
+
end
|
461
|
+
|
445
462
|
def any?
|
446
463
|
code_any?.truthy?
|
447
464
|
end
|
data/lib/code/object/nothing.rb
CHANGED
data/lib/code/object/string.rb
CHANGED
@@ -4,9 +4,18 @@ class Code
|
|
4
4
|
class Object
|
5
5
|
class String < Object
|
6
6
|
def initialize(*args, **_kargs, &)
|
7
|
-
raw =
|
8
|
-
|
9
|
-
|
7
|
+
@raw =
|
8
|
+
if args.first.is_an?(Class)
|
9
|
+
args.first.raw.name
|
10
|
+
elsif args.first.is_an?(Object)
|
11
|
+
args.first.raw.to_s
|
12
|
+
elsif args.first.is_a?(::Class)
|
13
|
+
args.first.name
|
14
|
+
elsif args.first
|
15
|
+
args.first.to_s
|
16
|
+
else
|
17
|
+
""
|
18
|
+
end
|
10
19
|
end
|
11
20
|
|
12
21
|
def call(**args)
|
@@ -37,6 +46,9 @@ class Code
|
|
37
46
|
when "reverse"
|
38
47
|
sig(args)
|
39
48
|
code_reverse
|
49
|
+
when "parameterize"
|
50
|
+
sig(args)
|
51
|
+
code_parameterize
|
40
52
|
else
|
41
53
|
super
|
42
54
|
end
|
@@ -69,6 +81,14 @@ class Code
|
|
69
81
|
Function.new([{ name: "_" }], "_.#{raw}")
|
70
82
|
end
|
71
83
|
|
84
|
+
def code_inspect
|
85
|
+
String.new(raw.inspect)
|
86
|
+
end
|
87
|
+
|
88
|
+
def code_parameterize
|
89
|
+
String.new(raw.parameterize)
|
90
|
+
end
|
91
|
+
|
72
92
|
def code_first(n = nil)
|
73
93
|
code_n = n.to_code
|
74
94
|
code_n = Integer.new(1) if code_n.nothing?
|