code-ruby 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b04f0e4774e945bbf969c0159eaf23db99d9208faa98e4ae2ed575c1a363baf9
4
- data.tar.gz: bf3de392fa1af6540d653d35248089d49b39da4addfd539e7594e0ac66c15def
3
+ metadata.gz: dd20de2ab8f69a2256eb18bd2eea8cc2876d8f828cbdf7c086996934ef8b6eb7
4
+ data.tar.gz: df97885df1ee89d2e3766090980a1fd8467091b982dacf9c1505cb0684d7b466
5
5
  SHA512:
6
- metadata.gz: 05a921e1f388872311df4f61df4dcf808cc1d4bdaccbf2bdbdd65cc58b5495edac205c003397c83254f257a9ad114b093f2470018dc12fc4d7998ae7e1feaa7d
7
- data.tar.gz: f856f404a8bebf4d802d2d0ab427e091f5c556da3cd24c3f583a09bf646dedef086e31b933c8933f86868ec9b501d1594f8d7e5272bcdbf1a7dea9571e825cf6
6
+ metadata.gz: 29c23d759b84cfb83e9dbc16913d77c6e2b95b86d3a5a65e2f8571199d58c671810806ed49939fe1e1931446571681c216fa261828b07908c43aa0832dfc8177
7
+ data.tar.gz: 46cbd45a6b53094ed19e2058728cbf6e76ba2fa34d253de4e6be6083cf61a8c26d84a3d943358311321cd32fd44201a55c00ee8605f2adee8216f46a0cfe715e
data/Gemfile CHANGED
@@ -6,5 +6,6 @@ gemspec
6
6
 
7
7
  ruby "3.3.0"
8
8
 
9
+ gem "rake"
9
10
  gem "rspec"
10
11
  gem "ruby-prof"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code-ruby (0.11.0)
4
+ code-ruby (0.13.0)
5
5
  activesupport (~> 7)
6
6
  bigdecimal (~> 3)
7
7
  json (~> 2)
@@ -27,13 +27,14 @@ GEM
27
27
  connection_pool (2.4.1)
28
28
  diff-lcs (1.5.1)
29
29
  drb (2.2.1)
30
- i18n (1.14.1)
30
+ i18n (1.14.4)
31
31
  concurrent-ruby (~> 1.0)
32
32
  json (2.7.1)
33
33
  language-ruby (0.8.0)
34
34
  zeitwerk (~> 2)
35
35
  minitest (5.22.2)
36
36
  mutex_m (0.2.0)
37
+ rake (13.1.0)
37
38
  rspec (3.13.0)
38
39
  rspec-core (~> 3.13.0)
39
40
  rspec-expectations (~> 3.13.0)
@@ -58,6 +59,7 @@ PLATFORMS
58
59
 
59
60
  DEPENDENCIES
60
61
  code-ruby!
62
+ rake
61
63
  rspec
62
64
  ruby-prof
63
65
 
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:default) { |task| task.verbose = false }
@@ -8,7 +8,7 @@ class Code
8
8
  def initialize(*args, **_kargs, &_block)
9
9
  @value = args.first.presence || Nothing.new
10
10
  @name = args.second.present? ? String.new(args.second) : nil
11
- super
11
+ @raw = List.new([@value, @name])
12
12
  end
13
13
 
14
14
  def keyword?
@@ -7,11 +7,6 @@ class Code
7
7
  raw = args.first || Nothing.new
8
8
  raw = raw.raw if raw.is_a?(Object)
9
9
  @raw = !!raw
10
- super
11
- end
12
-
13
- def self.name
14
- "Boolean"
15
10
  end
16
11
 
17
12
  def call(**args)
@@ -46,25 +41,9 @@ class Code
46
41
  Boolean.new(raw ^ value.raw)
47
42
  end
48
43
 
49
- def inspect
50
- to_s
51
- end
52
-
53
- def succ
54
- Boolean.new(!raw)
55
- end
56
-
57
- def to_s
58
- raw.to_s
59
- end
60
-
61
44
  def truthy?
62
45
  raw
63
46
  end
64
-
65
- def as_json(...)
66
- raw.as_json(...)
67
- end
68
47
  end
69
48
  end
70
49
  end
@@ -8,28 +8,11 @@ class Code
8
8
  raw = raw.raw if raw.is_a?(Class)
9
9
  raw = raw.class if raw.is_an?(Object)
10
10
  @raw = raw
11
- super
12
11
  end
13
12
 
14
13
  def call(...)
15
14
  raw.call(...)
16
15
  end
17
-
18
- def to_s
19
- raw.name
20
- end
21
-
22
- def inspect
23
- to_s
24
- end
25
-
26
- def self.name
27
- "Class"
28
- end
29
-
30
- def as_json(...)
31
- raw.name.as_json(...)
32
- end
33
16
  end
34
17
  end
35
18
  end
@@ -6,28 +6,11 @@ class Code
6
6
  def initialize(*args, **_kargs, &_block)
7
7
  raw = args.first.presence || Nothing.new
8
8
  @raw = raw.is_a?(Node) ? raw : Node::Code.new(::Code.parse(raw.to_s))
9
- super
10
- end
11
-
12
- def self.name
13
- "Code"
14
9
  end
15
10
 
16
11
  def evaluate(...)
17
12
  raw.evaluate(...)
18
13
  end
19
-
20
- def inspect
21
- "code"
22
- end
23
-
24
- def to_s
25
- "code"
26
- end
27
-
28
- def as_json(...)
29
- "code".as_json(...)
30
- end
31
14
  end
32
15
  end
33
16
  end
@@ -10,11 +10,6 @@ class Code
10
10
  raw = raw.raw if raw.is_a?(Object)
11
11
  @raw = raw.to_h
12
12
  @parent = Context.new(args.second) if args.second
13
- super
14
- end
15
-
16
- def self.name
17
- "Context"
18
13
  end
19
14
 
20
15
  def lookup!(identifier)
@@ -23,7 +18,7 @@ class Code
23
18
  elsif parent?
24
19
  parent.lookup!(identifier)
25
20
  else
26
- raise Error::Undefined, "#{identifier} is not defined"
21
+ raise Error::Undefined, "#{identifier} is not defined"
27
22
  end
28
23
  end
29
24
 
@@ -6,15 +6,10 @@ class Code
6
6
  def initialize(*args, **_kargs, &_block)
7
7
  raw = args.map(&:to_s).join("-").presence || ::Date.current.to_s
8
8
  @raw = ::Date.parse(raw)
9
- super
10
9
  rescue ::Date::Error
11
10
  raise Error, "#{raw.inspect} is an invalid date"
12
11
  end
13
12
 
14
- def self.name
15
- "Date"
16
- end
17
-
18
13
  def self.call(**args)
19
14
  operator = args.fetch(:operator, nil)
20
15
 
@@ -55,18 +50,6 @@ class Code
55
50
  ::Time.zone ||= Time::DEFAULT_ZONE
56
51
  new(::Time.zone.yesterday.beginning_of_day)
57
52
  end
58
-
59
- def inspect
60
- to_s
61
- end
62
-
63
- def to_s
64
- raw.to_s
65
- end
66
-
67
- def as_json(...)
68
- raw.as_json(...)
69
- end
70
53
  end
71
54
  end
72
55
  end
@@ -9,15 +9,10 @@ class Code
9
9
  decimal = decimal.raw if decimal.is_an?(Object)
10
10
  exponent = exponent.raw if exponent.is_an?(Object)
11
11
  @raw = decimal.to_d * 10**exponent.to_d
12
- super
13
12
  rescue FloatDomainError => e
14
13
  raise Error, "#{decimal.inspect} * 10**#{exponent.inspect} is invalid"
15
14
  end
16
15
 
17
- def self.name
18
- "Decimal"
19
- end
20
-
21
16
  def call(**args)
22
17
  operator = args.fetch(:operator, nil)
23
18
  arguments = args.fetch(:arguments, [])
@@ -300,10 +295,6 @@ class Code
300
295
  Boolean.new(raw.zero?)
301
296
  end
302
297
 
303
- def inspect
304
- to_s
305
- end
306
-
307
298
  def whole?
308
299
  whole == raw
309
300
  end
@@ -312,12 +303,8 @@ class Code
312
303
  raw.round
313
304
  end
314
305
 
315
- def to_s
316
- whole? ? raw.to_i.to_s : raw.to_s("F")
317
- end
318
-
319
306
  def as_json(...)
320
- whole? ? whole.as_json(...) : raw.as_json(...)
307
+ whole? ? whole.as_json(...) : super
321
308
  end
322
309
  end
323
310
  end
@@ -4,14 +4,11 @@ class Code
4
4
  class Object
5
5
  class Dictionary < ::Code::Object
6
6
  def initialize(*args, **_kargs, &_block)
7
- raw = args.first || {}
8
- raw = raw.raw if raw.is_a?(Object)
9
- @raw = raw.to_h
10
- super
11
- end
12
-
13
- def self.name
14
- "Dictionary"
7
+ @raw = (args.first.presence || {})
8
+ .as_json
9
+ .to_h
10
+ .transform_keys { |key| Json.to_code(key) }
11
+ .transform_values { |value| Json.to_code(value) }
15
12
  end
16
13
 
17
14
  def call(**args)
@@ -654,18 +651,6 @@ class Code
654
651
  def code_zero?
655
652
  code_size.code_zero?
656
653
  end
657
-
658
- def inspect
659
- to_s
660
- end
661
-
662
- def to_s
663
- "{#{raw.map { |key, value| "#{key.inspect} => #{value.inspect}" }.join(", ")}}"
664
- end
665
-
666
- def as_json(...)
667
- raw.as_json(...)
668
- end
669
654
  end
670
655
  end
671
656
  end
@@ -8,15 +8,10 @@ class Code
8
8
  raw = raw.raw if raw.is_an?(Object)
9
9
  raw = raw.iso8601 if raw.is_an?(::ActiveSupport::Duration)
10
10
  @raw = ::ActiveSupport::Duration.parse(raw.to_s)
11
- super
12
11
  rescue ::ActiveSupport::Duration::ISO8601Parser::ParsingError
13
12
  raise Error, "#{raw.inspect} is not a valid duration"
14
13
  end
15
14
 
16
- def self.name
17
- "Duration"
18
- end
19
-
20
15
  def call(**args)
21
16
  operator = args.fetch(:operator, nil)
22
17
 
@@ -39,18 +34,6 @@ class Code
39
34
  def code_from_now
40
35
  Time.new(raw.from_now)
41
36
  end
42
-
43
- def inspect
44
- to_s
45
- end
46
-
47
- def to_s
48
- raw.to_s
49
- end
50
-
51
- def as_json(...)
52
- raw.as_json(...)
53
- end
54
37
  end
55
38
  end
56
39
  end
@@ -6,30 +6,10 @@ class Code
6
6
  attr_reader :parameters, :body
7
7
 
8
8
  def initialize(*args, **_kargs, &_block)
9
- parameters = args.first.presence || List.new
10
- parameters = parameters.raw if parameters.is_an?(Object)
11
- @parameters = List.new(parameters)
12
- @parameters.raw.map! do |parameter|
13
- if parameter.is_a?(Node::FunctionParameter)
14
- Parameter.new(
15
- Dictionary.new({
16
- String.new(:name) => String.new(parameter.name),
17
- String.new(:keyword) => Boolean.new(parameter.keyword?),
18
- String.new(:regular_splat) => Boolean.new(parameter.regular_splat?),
19
- String.new(:keyword_splat) => Boolean.new(parameter.keyword_splat?),
20
- String.new(:default) => Code.new(parameter.default),
21
- })
22
- )
23
- else
24
- Parameter.new(parameter)
25
- end
26
- end
9
+ @parameters = List.new(args.first.presence || [])
10
+ @parameters.raw.map! { |parameter| Parameter.new(parameter) }
27
11
  @body = Code.new(args.second.presence || Nothing.new)
28
- super
29
- end
30
-
31
- def self.name
32
- "Function"
12
+ @raw = List.new(parameters, body)
33
13
  end
34
14
 
35
15
  def call(**args)
@@ -52,12 +32,12 @@ class Code
52
32
  parameters.raw.each.with_index do |parameter, index|
53
33
  if parameter.regular_splat?
54
34
  context.code_set(
55
- parameter.name,
35
+ parameter.code_name,
56
36
  List.new(arguments.select(&:regular?).map(&:value))
57
37
  )
58
38
  elsif parameter.keyword_splat?
59
39
  context.code_set(
60
- parameter.name,
40
+ parameter.code_name,
61
41
  Dictionary.new(
62
42
  arguments.select(&:keyword?).map(&:name_value).to_h
63
43
  )
@@ -65,46 +45,34 @@ class Code
65
45
  elsif parameter.keyword?
66
46
  argument =
67
47
  arguments
68
- .detect { |argument| argument.name == parameter.name }
48
+ .detect { |argument| argument.name == parameter.code_name }
69
49
  &.value
70
50
  argument = parameter.evaluate(**globals) if argument.nil?
71
- context.code_set(parameter.name, argument)
51
+ context.code_set(parameter.code_name, argument)
72
52
  elsif parameter.regular?
73
53
  argument = arguments[index]&.value
74
54
  argument = parameter.evaluate(**globals) if argument.nil?
75
- context.code_set(parameter.name, argument)
55
+ context.code_set(parameter.code_name, argument)
76
56
  end
77
57
  end
78
58
 
79
59
  body.evaluate(**globals, context:)
80
60
  end
81
61
 
82
- def inspect
83
- "function"
84
- end
85
-
86
62
  def signature_for_call
87
63
  parameters.raw.inject([]) do |signature, parameter|
88
64
  if parameter.keyword?
89
65
  if signature.last.is_a?(::Hash)
90
- signature.last.code_set(parameter.name, Object)
66
+ signature.last.code_set(parameter.code_name, Object)
91
67
  signature
92
68
  else
93
- signature + [{ parameter.name => Object }]
69
+ signature + [{ parameter.code_name => Object }]
94
70
  end
95
71
  else
96
72
  signature + [Object]
97
73
  end
98
74
  end + [Object.repeat]
99
75
  end
100
-
101
- def to_s
102
- ""
103
- end
104
-
105
- def as_json(...)
106
- raw.as_json(...)
107
- end
108
76
  end
109
77
  end
110
78
  end
@@ -3,10 +3,6 @@
3
3
  class Code
4
4
  class Object
5
5
  class Global < Object
6
- def self.name
7
- "Global"
8
- end
9
-
10
6
  def initialize(...)
11
7
  super
12
8
  end
@@ -3,10 +3,6 @@
3
3
  class Code
4
4
  class Object
5
5
  class IdentifierList < List
6
- def self.name
7
- "IdentifierList"
8
- end
9
-
10
6
  def call(**args)
11
7
  operator = args.fetch(:operator, nil)
12
8
  arguments = args.fetch(:arguments, [])
@@ -13,10 +13,6 @@ class Code
13
13
  raise Error, "#{decimal.inspect} * 10**#{exponent.inspect} is invalid"
14
14
  end
15
15
 
16
- def self.name
17
- "Integer"
18
- end
19
-
20
16
  def call(**args)
21
17
  operator = args.fetch(:operator, nil)
22
18
  arguments = args.fetch(:arguments, [])
@@ -391,22 +387,6 @@ class Code
391
387
  def code_days
392
388
  Duration.new(raw.days)
393
389
  end
394
-
395
- def inspect
396
- to_s
397
- end
398
-
399
- def succ
400
- Integer.new(raw + 1)
401
- end
402
-
403
- def to_s
404
- raw.to_s
405
- end
406
-
407
- def as_json(...)
408
- raw.as_json(...)
409
- end
410
390
  end
411
391
  end
412
392
  end
@@ -0,0 +1,29 @@
1
+ class Code
2
+ class Object
3
+ class Json < Object
4
+ def self.to_code(json)
5
+ if json.is_an?(Object)
6
+ json
7
+ elsif json.is_a?(::Hash)
8
+ Dictionary.new(json)
9
+ elsif json.is_a?(::Array)
10
+ List.new(json)
11
+ elsif json.is_a?(::String)
12
+ String.new(json)
13
+ elsif json.is_a?(::Float)
14
+ Decimal.new(json)
15
+ elsif json.is_an?(::Integer)
16
+ Integer.new(json)
17
+ elsif json.is_a?(::TrueClass)
18
+ Boolean.new(json)
19
+ elsif json.is_a?(::FalseClass)
20
+ Boolean.new(json)
21
+ elsif json.is_a?(::NilClass)
22
+ Nothing.new(json)
23
+ else
24
+ Nothing.new
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -7,11 +7,6 @@ class Code
7
7
  raw = args.first || Nothing.new
8
8
  raw = raw.raw if raw.is_an?(Object)
9
9
  @raw = raw.to_a
10
- super
11
- end
12
-
13
- def self.name
14
- "List"
15
10
  end
16
11
 
17
12
  def call(**args)
@@ -234,18 +229,6 @@ class Code
234
229
  def code_sum
235
230
  raw.inject(&:code_plus) || Nothing.new
236
231
  end
237
-
238
- def inspect
239
- to_s
240
- end
241
-
242
- def to_s
243
- "[#{raw.map(&:inspect).join(", ")}]"
244
- end
245
-
246
- def as_json(...)
247
- raw.as_json(...)
248
- end
249
232
  end
250
233
  end
251
234
  end
@@ -7,25 +7,9 @@ class Code
7
7
  @raw = nil
8
8
  end
9
9
 
10
- def self.name
11
- "Nothing"
12
- end
13
-
14
- def inspect
15
- "nothing"
16
- end
17
-
18
- def to_s
19
- ""
20
- end
21
-
22
10
  def truthy?
23
11
  false
24
12
  end
25
-
26
- def as_json(...)
27
- raw.as_json(...)
28
- end
29
13
  end
30
14
  end
31
15
  end
@@ -3,20 +3,28 @@
3
3
  class Code
4
4
  class Object
5
5
  class Parameter < Object
6
- attr_reader :name, :keyword, :regular_splat, :keyword_splat, :default
6
+ def initialize(*args, **_kargs, &_block)
7
+ @raw = Dictionary.new(args.first.presence || {})
8
+ end
7
9
 
8
- def self.name
9
- "Parameter"
10
+ def code_name
11
+ String.new(raw.code_get(String.new(:name)))
10
12
  end
11
13
 
12
- def initialize(*args, **_kargs, &_block)
13
- @raw = Dictionary.new(args.first.presence || {})
14
- @name = String.new(@raw.code_get(String.new(:name)))
15
- @keyword = Boolean.new(@raw.code_get(String.new(:keyword)))
16
- @regular_splat = Boolean.new(@raw.code_get(String.new(:regular_splat)))
17
- @keyword_splat = Boolean.new(@raw.code_get(String.new(:keyword_splat)))
18
- @default = Code.new(@raw.code_get(String.new(:default)))
19
- super
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)))
20
28
  end
21
29
 
22
30
  def evaluate(...)
@@ -28,15 +36,15 @@ class Code
28
36
  end
29
37
 
30
38
  def keyword?
31
- keyword.truthy?
39
+ code_keyword.truthy?
32
40
  end
33
41
 
34
42
  def regular_splat?
35
- regular_splat.truthy?
43
+ code_regular_splat.truthy?
36
44
  end
37
45
 
38
46
  def keyword_splat?
39
- keyword_splat.truthy?
47
+ code_keyword_splat.truthy?
40
48
  end
41
49
  end
42
50
  end
@@ -8,14 +8,9 @@ class Code
8
8
  def initialize(*args, **_kargs, &_block)
9
9
  @left = args.first.presence || Integer.new(0)
10
10
  @right = args.second.presence || Integer.new(0)
11
- @options = Dictionary.new(args.third.presence || Dictionary.new)
12
- @exclude_end = Boolean.new(@options.code_get(String.new(:exclude_end)))
11
+ @options = Dictionary.new(args.third.presence || {})
12
+ @exclude_end = Boolean.new(options.code_get(String.new(:exclude_end)))
13
13
  @raw = ::Range.new(left, right, exclude_end?)
14
- super
15
- end
16
-
17
- def self.name
18
- "Range"
19
14
  end
20
15
 
21
16
  def call(**args)
@@ -132,18 +127,6 @@ class Code
132
127
  def code_to_list
133
128
  List.new(raw.to_a)
134
129
  end
135
-
136
- def inspect
137
- to_s
138
- end
139
-
140
- def to_s
141
- raw.to_s
142
- end
143
-
144
- def as_json(...)
145
- raw.as_json(...)
146
- end
147
130
  end
148
131
  end
149
132
  end
@@ -7,11 +7,6 @@ class Code
7
7
  raw = args.first || Nothing.new
8
8
  raw = raw.raw if raw.is_a?(Object)
9
9
  @raw = raw.to_s
10
- super
11
- end
12
-
13
- def self.name
14
- "String"
15
10
  end
16
11
 
17
12
  def call(**args)
@@ -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
@@ -10,11 +10,6 @@ class Code
10
10
  raw = args.first.presence || ::Time.zone.now
11
11
  raw = raw.raw if raw.is_an?(Object)
12
12
  @raw = ::Time.zone.parse(raw.to_s)
13
- super
14
- end
15
-
16
- def self.name
17
- "Time"
18
13
  end
19
14
 
20
15
  def self.call(**args)
@@ -90,18 +85,6 @@ class Code
90
85
  def code_future?
91
86
  code_after?
92
87
  end
93
-
94
- def inspect
95
- to_s
96
- end
97
-
98
- def to_s
99
- raw.to_s
100
- end
101
-
102
- def as_json(...)
103
- raw.as_json(...)
104
- end
105
88
  end
106
89
  end
107
90
  end
data/lib/code/object.rb CHANGED
@@ -5,17 +5,12 @@ class Code
5
5
  attr_reader :raw
6
6
 
7
7
  def initialize(*_args, **_kargs, &_block)
8
- @raw = nil unless defined?(@raw)
9
8
  end
10
9
 
11
10
  def self.maybe
12
11
  Type::Maybe.new(self)
13
12
  end
14
13
 
15
- def self.name
16
- "Object"
17
- end
18
-
19
14
  def self.repeat(minimum = 0, maximum = nil)
20
15
  Type::Repeat.new(self, minimum:, maximum:)
21
16
  end
@@ -110,6 +105,12 @@ class Code
110
105
  when "to_time"
111
106
  sig(args)
112
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)))
113
114
  when /=$/
114
115
  sig(args) { Object }
115
116
 
@@ -194,10 +195,6 @@ class Code
194
195
  nil
195
196
  end
196
197
 
197
- def self.name
198
- "Object"
199
- end
200
-
201
198
  def self.to_s
202
199
  name
203
200
  end
@@ -210,6 +207,26 @@ class Code
210
207
  true
211
208
  end
212
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
+
213
230
  def <=>(other)
214
231
  if respond_to?(:raw)
215
232
  raw <=> (other.respond_to?(:raw) ? other.raw : other)
@@ -305,6 +322,12 @@ class Code
305
322
  when "to_time"
306
323
  sig(args)
307
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)))
308
331
  when /=$/
309
332
  sig(args) { Object }
310
333
 
@@ -414,11 +437,31 @@ class Code
414
437
  end
415
438
 
416
439
  def to_json(...)
417
- as_json(...).to_json
440
+ as_json(...).to_json(...)
418
441
  end
419
442
 
420
443
  def as_json(...)
421
- 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
422
465
  end
423
466
  end
424
467
  end
data/lib/code/version.rb CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require_relative "../code"
4
4
 
5
- Code::Version = Gem::Version.new("0.12.0")
5
+ Code::Version = Gem::Version.new("0.13.0")
data/spec/code_spec.rb CHANGED
@@ -3,6 +3,71 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe Code do
6
+
7
+ %w[
8
+ 1.day.ago
9
+ 1.day.from_now
10
+ 1.hour.ago
11
+ 1.hour.from_now
12
+ 2.days.ago
13
+ 2.days.from_now
14
+ 2.hours.ago
15
+ 2.hours.from_now
16
+ Boolean.new
17
+ Boolean.new(true)
18
+ Boolean.new(false)
19
+ Class.new
20
+ Class.new(Boolean)
21
+ Class.new(Class)
22
+ Context.new
23
+ Context.new(a:1)
24
+ Date.new
25
+ Date.new("2024-03-05")
26
+ Date.today
27
+ Date.yesterday
28
+ Date.tomorrow
29
+ Decimal.new
30
+ Decimal.new(0)
31
+ Decimal.new(1.2)
32
+ Dictionary.new
33
+ Dictionary.new(a:1)
34
+ Duration.new
35
+ Duration.new(1.day)
36
+ Duration.new("P1D")
37
+ Function.new
38
+ Integer.new
39
+ Integer.new(0)
40
+ Integer.new(1)
41
+ Integer.new(1.2)
42
+ List.new
43
+ List.new([])
44
+ List.new([1,2])
45
+ Nothing.new
46
+ Nothing.new(1)
47
+ Object.new
48
+ Object.new(1)
49
+ Range.new
50
+ Range.new(1,2)
51
+ Range.new(-1)
52
+ Range.new(1,2,exclude_end:false)
53
+ Range.new(1,2,exclude_end:true)
54
+ String.new
55
+ String.new(:hello)
56
+ Time.new
57
+ Time.new("2024-03-05.06:10:59.UTC")
58
+ Time.now
59
+ Time.tomorrow
60
+ Time.yesterday
61
+ Time.tomorrow
62
+ Code.new
63
+ Parameter.new
64
+ Argument.new
65
+ Argument.new(1)
66
+ Argument.new(1,name:"index")
67
+ IdentifierList.new
68
+ IdentifierList.new([])
69
+ ].each { |input| it(input) { Code.evaluate(input) } }
70
+
6
71
  [
7
72
  [
8
73
  "user = { name: :Dorian, age: 31 } user.delete_if(String) user.keys",
@@ -204,6 +269,11 @@ RSpec.describe Code do
204
269
  ['user = {} user.name = "Dorian" user.name', ":Dorian"],
205
270
  ['user = {} user[:name] = "Dorian" user[:name]', ":Dorian"],
206
271
  ['{ "first_name": "Dorian" }', '{"first_name" => "Dorian"}'],
272
+ ['{ "first_name": "Dorian" }.as_json', '{"first_name" => "Dorian"}'],
273
+ ["nothing.to_json", ":null"],
274
+ ["1.to_json", ":1"],
275
+ ["1.0.to_json", ":1"],
276
+ ["1.1.to_json", %{'"1.1"'}],
207
277
  ["", ""]
208
278
  ].each do |input, expected|
209
279
  it "#{input} == #{expected}" do
@@ -214,70 +284,6 @@ RSpec.describe Code do
214
284
  end
215
285
  end
216
286
 
217
- %w[
218
- 1.day.ago
219
- 1.day.from_now
220
- 1.hour.ago
221
- 1.hour.from_now
222
- 2.days.ago
223
- 2.days.from_now
224
- 2.hours.ago
225
- 2.hours.from_now
226
- Boolean.new
227
- Boolean.new(true)
228
- Boolean.new(false)
229
- Class.new
230
- Class.new(Boolean)
231
- Class.new(Class)
232
- Context.new
233
- Context.new(a:1)
234
- Date.new
235
- Date.new("2024-03-05")
236
- Date.today
237
- Date.yesterday
238
- Date.tomorrow
239
- Decimal.new
240
- Decimal.new(0)
241
- Decimal.new(1.2)
242
- Dictionary.new
243
- Dictionary.new(a:1)
244
- Duration.new
245
- Duration.new(1.day)
246
- Duration.new("P1D")
247
- Function.new
248
- Integer.new
249
- Integer.new(0)
250
- Integer.new(1)
251
- Integer.new(1.2)
252
- List.new
253
- List.new([])
254
- List.new([1,2])
255
- Nothing.new
256
- Nothing.new(1)
257
- Object.new
258
- Object.new(1)
259
- Range.new
260
- Range.new(1,2)
261
- Range.new(-1)
262
- Range.new(1,2,exclude_end:false)
263
- Range.new(1,2,exclude_end:true)
264
- String.new
265
- String.new(:hello)
266
- Time.new
267
- Time.new("2024-03-05.06:10:59.UTC")
268
- Time.now
269
- Time.tomorrow
270
- Time.yesterday
271
- Time.tomorrow
272
- Code.new
273
- Parameter.new
274
- Argument.new
275
- Argument.new(1)
276
- Argument.new(1,name:"index")
277
- IdentifierList.new
278
- IdentifierList.new([])
279
- ].each { |input| it(input) { Code.evaluate(input) } }
280
-
281
287
  [["puts(true)", "true\n"], %w[print(false) false]].each do |input, expected|
282
288
  it "#{input} prints #{expected}" do
283
289
  output = StringIO.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Marié
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-05 00:00:00.000000000 Z
11
+ date: 2024-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,7 @@ files:
94
94
  - Gemfile
95
95
  - Gemfile.lock
96
96
  - README.md
97
+ - Rakefile
97
98
  - bin/code
98
99
  - bin/console
99
100
  - code-ruby.gemspec
@@ -142,6 +143,7 @@ files:
142
143
  - lib/code/object/global.rb
143
144
  - lib/code/object/identifier_list.rb
144
145
  - lib/code/object/integer.rb
146
+ - lib/code/object/json.rb
145
147
  - lib/code/object/list.rb
146
148
  - lib/code/object/nothing.rb
147
149
  - lib/code/object/parameter.rb