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.
data/lib/code/object.rb CHANGED
@@ -12,21 +12,12 @@ class Code
12
12
  ::BigDecimal
13
13
  ].freeze
14
14
 
15
- attr_reader :raw
16
-
17
- delegate :to_s, :inspect, to: :raw
15
+ include Concerns::Shared
16
+ extend Concerns::Shared
18
17
 
19
18
  def initialize(...)
20
19
  end
21
20
 
22
- def self.nothing?
23
- false
24
- end
25
-
26
- def nothing?
27
- false
28
- end
29
-
30
21
  def self.maybe
31
22
  Type::Maybe.new(self)
32
23
  end
@@ -39,445 +30,16 @@ class Code
39
30
  Type::Or.new(self, other)
40
31
  end
41
32
 
42
- def self.call(**args)
43
- code_operator = args.fetch(:operator, nil).to_code
44
- code_arguments = args.fetch(:arguments, []).to_code
45
- code_value = code_arguments.code_first
46
-
47
- case code_operator.to_s
48
- when "new"
49
- sig(args) { Object.repeat }
50
- code_new(*code_arguments.raw)
51
- when "!", "not"
52
- sig(args)
53
- code_exclamation_point
54
- when "!=", "different"
55
- sig(args) { Object }
56
- code_different(code_value)
57
- when "&&", "and"
58
- sig(args) { Object }
59
- code_and_operator(code_value)
60
- when "+", "self"
61
- sig(args)
62
- code_self
63
- when "..", "inclusive_range"
64
- sig(args) { Object }
65
- code_inclusive_range(code_value)
66
- when "...", "exclusive_range"
67
- sig(args) { Object }
68
- code_exclusive_range(code_value)
69
- when "==", "equal"
70
- sig(args) { Object }
71
- code_equal_equal(code_value)
72
- when "===", "strict_equal"
73
- sig(args) { Object }
74
- code_equal_equal_equal(code_value)
75
- when "falsy?"
76
- sig(args)
77
- Boolean.new(falsy?)
78
- when "truthy?"
79
- sig(args)
80
- Boolean.new(truthy?)
81
- when "||", "or"
82
- sig(args) { Object }
83
- code_or_operator(code_value)
84
- when "to_boolean"
85
- sig(args)
86
- Boolean.new(self)
87
- when "to_class"
88
- sig(args)
89
- Class.new(self)
90
- when "to_date"
91
- sig(args)
92
- Date.new(self)
93
- when "to_decimal"
94
- sig(args)
95
- Decimal.new(self)
96
- when "to_dictionary"
97
- sig(args)
98
- Dictionary.new(self)
99
- when "to_duration"
100
- sig(args)
101
- Duration.new(self)
102
- when "to_integer"
103
- sig(args)
104
- Integer.new(self)
105
- when "to_list"
106
- sig(args)
107
- List.new(self)
108
- when "to_nothing"
109
- sig(args)
110
- Nothing.new(self)
111
- when "to_range"
112
- sig(args)
113
- Range.new(self)
114
- when "to_string"
115
- sig(args)
116
- String.new(self)
117
- when "to_time"
118
- sig(args)
119
- Time.new(self)
120
- when "as_json"
121
- sig(args)
122
- code_as_json
123
- when "to_json"
124
- sig(args) { { pretty: Boolean.maybe } }
125
-
126
- if code_arguments.any?
127
- code_to_json(pretty: code_value.code_get(:pretty))
128
- else
129
- code_to_json
130
- end
131
- when /=$/
132
- sig(args) { Object }
133
-
134
- if code_operator.to_s == "="
135
- code_context = args.fetch(:context)
136
- code_context.code_set(self, value)
137
- else
138
- code_context = args.fetch(:context).code_lookup!(self)
139
- code_context.code_set(
140
- self,
141
- code_context.code_fetch(self).call(
142
- **args,
143
- operator: operator.to_s.chop,
144
- arguments: List.new([code_value])
145
- )
146
- )
147
- end
148
-
149
- context.code_fetch(self)
150
- else
151
- raise(Error, "#{code_operator.inspect} not defined on #{inspect}:Class")
152
- end
153
- end
154
-
155
- def self.code_new(*arguments)
156
- code_arguments = arguments.to_code
157
-
158
- new(*code_arguments.raw)
159
- end
160
-
161
- def self.code_and_operator(other)
162
- code_other = other.to_code
163
-
164
- truthy? ? code_other : self
165
- end
166
-
167
- def self.code_different(other)
168
- code_other = other.to_code
169
-
170
- Boolean.new(self != code_other)
171
- end
172
-
173
- def self.code_equal_equal(other)
174
- code_other = other.to_code
175
-
176
- Boolean.new(self == code_other)
177
- end
178
-
179
- def self.code_exclamation_point
180
- Boolean.new(falsy?)
181
- end
182
-
183
- def self.code_exclusive_range(value)
184
- code_value = value.to_code
185
-
186
- Range.new(self, code_value, exclude_end: true)
187
- end
188
-
189
- def self.code_inclusive_range(value)
190
- code_value = value.to_code
191
-
192
- Range.new(self, code_value, exclude_end: false)
193
- end
194
-
195
- def self.code_or_operator(other)
196
- code_other = other.to_code
197
-
198
- truthy? ? self : code_other
199
- end
200
-
201
- def self.code_self
202
- self
203
- end
204
-
205
- def self.code_equal_equal_equal(other)
206
- code_other = other.to_code
207
-
208
- Boolean.new(self === code_other)
209
- end
210
-
211
- def self.falsy?
212
- !truthy?
213
- end
214
-
215
- def self.multi_fetch(hash, *keys)
216
- keys.to_h { |key| [key, hash.fetch(key)] }
217
- end
218
-
219
- def self.sig(args, &)
220
- Type::Sig.sig(args, object: self, &)
221
-
222
- Nothing.new
223
- end
224
-
225
- def self.to_s
226
- name
227
- end
228
-
229
- def self.inspect
230
- name
231
- end
232
-
233
- def self.truthy?
234
- true
235
- end
236
-
237
- def self.to_json(...)
238
- as_json(...).to_json(...)
239
- end
240
-
241
- def self.as_json(...)
242
- name.as_json(...)
243
- end
244
-
245
- def self.code_to_json(pretty: nil)
246
- if Boolean.new(pretty).truthy?
247
- String.new(::JSON.pretty_generate(self))
248
- else
249
- String.new(to_json)
250
- end
251
- end
252
-
253
- def self.code_as_json
254
- to_ruby.as_json.to_code
255
- end
256
-
257
- def <=>(other)
258
- code_other = other.to_code
259
-
260
- raw <=> code_other.raw
261
- end
262
-
263
- def ==(other)
264
- code_other = other.to_code
265
-
266
- raw == code_other.raw
267
- end
268
- alias eql? ==
269
-
270
- def call(**args)
271
- code_operator = args.fetch(:operator, nil).to_code
272
- code_arguments = args.fetch(:arguments, []).to_code
273
- code_value = code_arguments.code_first
274
-
275
- case code_operator.to_s
276
- when "!", "not"
277
- sig(args)
278
- code_exclamation_point
279
- when "!=", "different"
280
- sig(args) { Object }
281
- code_different(code_value)
282
- when "&&", "and"
283
- sig(args) { Object }
284
- code_and_operator(code_value)
285
- when "+", "self"
286
- sig(args)
287
- code_self
288
- when "..", "inclusive_range"
289
- sig(args) { Object }
290
- code_inclusive_range(code_value)
291
- when "...", "exclusive_range"
292
- sig(args) { Object }
293
- code_exclusive_range(code_value)
294
- when "==", "equal"
295
- sig(args) { Object }
296
- code_equal_equal(code_value)
297
- when "===", "strict_equal"
298
- sig(args) { Object }
299
- code_equal_equal_equal(code_value)
300
- when "falsy?"
301
- sig(args)
302
- Boolean.new(falsy?)
303
- when "truthy?"
304
- sig(args)
305
- Boolean.new(truthy?)
306
- when "||", "or"
307
- sig(args) { Object }
308
- code_or_operator(code_value)
309
- when "to_boolean"
310
- sig(args)
311
- Boolean.new(self)
312
- when "to_class"
313
- sig(args)
314
- Class.new(self)
315
- when "to_date"
316
- sig(args)
317
- Date.new(self)
318
- when "to_decimal"
319
- sig(args)
320
- Decimal.new(self)
321
- when "to_duration"
322
- sig(args)
323
- Duration.new(self)
324
- when "to_dictionary"
325
- sig(args)
326
- Dictionary.new(self)
327
- when "to_integer"
328
- sig(args)
329
- Integer.new(self)
330
- when "to_list"
331
- sig(args)
332
- List.new(self)
333
- when "to_nothing"
334
- sig(args)
335
- Nothing.new(self)
336
- when "to_range"
337
- sig(args)
338
- Range.new(self)
339
- when "to_string"
340
- sig(args)
341
- String.new(self)
342
- when "to_time"
343
- sig(args)
344
- Time.new(self)
345
- when "as_json"
346
- sig(args)
347
- code_as_json
348
- when "to_json"
349
- sig(args) { { pretty: Boolean.maybe } }
350
-
351
- if code_arguments.any?
352
- code_to_json(pretty: code_value.code_get(:pretty))
353
- else
354
- code_to_json
355
- end
356
- when /=$/
357
- sig(args) { Object }
358
-
359
- if code_operator.to_s == "="
360
- code_context = args.fetch(:context)
361
- code_context.code_set(self, code_value)
362
- else
363
- code_context = args.fetch(:context).code_lookup!(self)
364
- code_context.code_set(
365
- self,
366
- code_context.code_fetch(self).call(
367
- **args,
368
- operator: code_operator.to_s.chop,
369
- arguments: List.new([code_value])
370
- )
371
- )
372
- end
373
-
374
- code_context.code_fetch(self)
375
- else
376
- raise(
377
- Error,
378
- "#{code_operator.inspect} not defined on #{inspect}:#{self.class.name}"
379
- )
380
- end
381
- end
382
-
383
- def code_and_operator(other)
384
- code_other = other.to_code
385
-
386
- truthy? ? code_other : self
387
- end
388
-
389
- def code_different(other)
390
- code_other = other.to_code
391
-
392
- Boolean.new(self != code_other)
393
- end
394
-
395
- def code_equal_equal(other)
396
- code_other = other.to_code
397
-
398
- Boolean.new(self == code_other)
399
- end
400
-
401
- def code_exclamation_point
402
- Boolean.new(falsy?)
403
- end
404
-
405
- def code_exclusive_range(value)
406
- code_value = value.to_code
407
-
408
- Range.new(self, code_value, exclude_end: true)
409
- end
410
-
411
- def code_inclusive_range(value)
412
- code_value = value.to_code
413
-
414
- Range.new(self, code_value, exclude_end: false)
415
- end
416
-
417
- def code_or_operator(other)
418
- code_other = other.to_code
419
-
420
- truthy? ? self : code_other
421
- end
422
-
423
- def code_self
424
- self
425
- end
426
-
427
- def code_equal_equal_equal(other)
428
- code_other = other.to_code
429
-
430
- Boolean.new(self === code_other)
431
- end
432
-
433
- def falsy?
434
- !truthy?
435
- end
436
-
437
- def hash
438
- [self.class, raw].hash
439
- end
440
-
441
- def multi_fetch(hash, *keys)
442
- keys.to_h { |key| [key, hash.fetch(key)] }
443
- end
444
-
445
- def sig(args, &)
446
- Type::Sig.sig(args, object: self, &)
447
-
448
- Nothing.new
449
- end
450
-
451
- def truthy?
452
- true
453
- end
454
-
455
- def to_json(...)
456
- as_json(...).to_json(...)
457
- end
458
-
459
- def as_json(...)
460
- raw.as_json(...)
461
- end
462
-
463
- def code_to_json(pretty: nil)
464
- if Boolean.new(pretty).truthy?
465
- String.new(::JSON.pretty_generate(self))
466
- else
467
- String.new(to_json)
468
- end
469
- end
470
-
471
- def code_as_json
472
- as_json.to_code
33
+ def self.code_new(*)
34
+ new(*)
473
35
  end
474
36
 
475
- def to_code
476
- self
37
+ def name
38
+ self.class.name
477
39
  end
478
40
 
479
- def succ
480
- self.class.new(raw.succ)
41
+ def code_new(*)
42
+ self.class.code_new(*)
481
43
  end
482
44
  end
483
45
  end
@@ -59,6 +59,10 @@ class Code
59
59
  str("do")
60
60
  end
61
61
 
62
+ def begin_keyword
63
+ str("do")
64
+ end
65
+
62
66
  def end_keyword
63
67
  str("end")
64
68
  end
@@ -107,8 +111,9 @@ class Code
107
111
 
108
112
  def block
109
113
  (
110
- do_keyword << whitespace? << parameters.aka(:parameters).maybe <<
111
- code.aka(:body) << end_keyword.maybe
114
+ (do_keyword | begin_keyword) << whitespace? <<
115
+ parameters.aka(:parameters).maybe << code.aka(:body) <<
116
+ end_keyword.maybe
112
117
  ) |
113
118
  (
114
119
  opening_curly_bracket << whitespace? <<
@@ -7,41 +7,8 @@ class Code
7
7
  While
8
8
  end
9
9
 
10
- def name
11
- Name
12
- end
13
-
14
- def code
15
- Code
16
- end
17
-
18
- def whitespace
19
- Whitespace
20
- end
21
-
22
- def whitespace?
23
- whitespace.maybe
24
- end
25
-
26
- def class_keyword
27
- str("class")
28
- end
29
-
30
- def end_keyword
31
- str("end")
32
- end
33
-
34
- def lesser
35
- str("<")
36
- end
37
-
38
10
  def root
39
- (
40
- class_keyword << whitespace? << name.aka(:name) <<
41
- (
42
- whitespace? << lesser << whitespace? << name.aka(:superclass)
43
- ).maybe << code.aka(:body) << end_keyword.maybe
44
- ).aka(:class) | statement
11
+ statement
45
12
  end
46
13
  end
47
14
  end
@@ -23,6 +23,18 @@ class Code
23
23
  whitespace.maybe
24
24
  end
25
25
 
26
+ def do_keyword
27
+ str("do")
28
+ end
29
+
30
+ def begin_keyword
31
+ str("begin")
32
+ end
33
+
34
+ def end_keyword
35
+ str("end")
36
+ end
37
+
26
38
  def opening_parenthesis
27
39
  str("(")
28
40
  end
@@ -88,11 +100,15 @@ class Code
88
100
  (whitespace? << closing_parenthesis.ignore).maybe
89
101
  end
90
102
 
103
+ def body
104
+ ((begin_keyword | do_keyword) << code << end_keyword.maybe) |
105
+ (opening_curly_bracket << code << closing_curly_bracket.maybe) | code
106
+ end
107
+
91
108
  def root
92
109
  (
93
110
  parameters.aka(:parameters) << whitespace? << equal << greater <<
94
- whitespace? << opening_curly_bracket << code.aka(:body) <<
95
- closing_curly_bracket.maybe
111
+ whitespace? << body.aka(:body)
96
112
  ).aka(:function) | Dictionary
97
113
  end
98
114
  end
@@ -15,8 +15,22 @@ class Code
15
15
  str(")")
16
16
  end
17
17
 
18
+ def end_keyword
19
+ str("end")
20
+ end
21
+
22
+ def do_keyword
23
+ str("do")
24
+ end
25
+
26
+ def begin_keyword
27
+ str("begin")
28
+ end
29
+
18
30
  def root
19
31
  (opening_parenthesis << code << closing_parenthesis.maybe).aka(:group) |
32
+ (begin_keyword << code << end_keyword.maybe).aka(:group) |
33
+ (do_keyword << code << end_keyword.maybe).aka(:group) |
20
34
  Call
21
35
  end
22
36
  end
@@ -23,6 +23,22 @@ class Code
23
23
  whitespace.maybe
24
24
  end
25
25
 
26
+ def do_keyword
27
+ str("do")
28
+ end
29
+
30
+ def begin_keyword
31
+ str("begin")
32
+ end
33
+
34
+ def opening_curly_bracket
35
+ str("{")
36
+ end
37
+
38
+ def closing_curly_bracket
39
+ str("{")
40
+ end
41
+
26
42
  def if_keyword
27
43
  str("if")
28
44
  end
@@ -43,20 +59,25 @@ class Code
43
59
  str("end")
44
60
  end
45
61
 
62
+ def body
63
+ ((begin_keyword | do_keyword) << code << end_keyword.maybe) |
64
+ (opening_curly_bracket << code << closing_curly_bracket.maybe) | code
65
+ end
66
+
46
67
  def root
47
68
  (
48
69
  (if_keyword | unless_keyword).aka(:first_operator) << whitespace <<
49
- statement.aka(:first_statement) << code.aka(:first_body) <<
70
+ statement.aka(:first_statement) << body.aka(:first_body) <<
50
71
  (
51
72
  (
52
73
  elsif_keyword.aka(:operator) << whitespace <<
53
- statement.aka(:statement) << code.aka(:body)
74
+ statement.aka(:statement) << body.aka(:body)
54
75
  ) |
55
76
  (
56
77
  else_keyword << whitespace <<
57
78
  (if_keyword | unless_keyword).aka(:operator) <<
58
- whitespace << statement.aka(:statement) << code.aka(:body)
59
- ) | (else_keyword.aka(:operator) << code.aka(:body))
79
+ whitespace << statement.aka(:statement) << body.aka(:body)
80
+ ) | (else_keyword.aka(:operator) << body.aka(:body))
60
81
  ).repeat(1).aka(:elses).maybe << end_keyword.maybe
61
82
  ).aka(:if) | statement
62
83
  end
@@ -91,10 +91,18 @@ class Code
91
91
  str("elsif")
92
92
  end
93
93
 
94
+ def begin_keyword
95
+ str("begin")
96
+ end
97
+
94
98
  def else_keyword
95
99
  str("else")
96
100
  end
97
101
 
102
+ def begin_keyword
103
+ str("begin")
104
+ end
105
+
98
106
  def special_character
99
107
  ampersand | equal | pipe | dot | colon | comma | space | newline |
100
108
  opening_curly_bracket | closing_curly_bracket | opening_parenthesis |
@@ -113,8 +121,9 @@ class Code
113
121
 
114
122
  def root
115
123
  (do_keyword << separator).absent << (
116
- else_keyword << separator
117
- ).absent << (elsif_keyword << separator).absent <<
124
+ begin_keyword << separator
125
+ ).absent << (else_keyword << separator).absent <<
126
+ (elsif_keyword << separator).absent <<
118
127
  (end_keyword << separator).absent << character.repeat(1)
119
128
  end
120
129
  end