code-ruby 0.13.1 → 0.14.1

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +15 -0
  3. data/.github/workflows/ci.yml +31 -0
  4. data/.rubocop.yml +8 -0
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +52 -4
  7. data/bin/bundle-audit +31 -0
  8. data/bin/bundler-audit +31 -0
  9. data/bin/console +1 -0
  10. data/bin/rspec +31 -0
  11. data/bin/rubocop +31 -0
  12. data/lib/code/error.rb +0 -3
  13. data/lib/code/node/base_10.rb +4 -3
  14. data/lib/code/node/base_16.rb +1 -0
  15. data/lib/code/node/base_2.rb +1 -0
  16. data/lib/code/node/base_8.rb +1 -0
  17. data/lib/code/node/boolean.rb +1 -0
  18. data/lib/code/node/call.rb +14 -15
  19. data/lib/code/node/call_argument.rb +4 -4
  20. data/lib/code/node/code.rb +1 -0
  21. data/lib/code/node/decimal.rb +4 -3
  22. data/lib/code/node/dictionary.rb +5 -3
  23. data/lib/code/node/function.rb +1 -0
  24. data/lib/code/node/function_parameter.rb +14 -0
  25. data/lib/code/node/if.rb +6 -4
  26. data/lib/code/node/left_operation.rb +3 -3
  27. data/lib/code/node/list.rb +1 -0
  28. data/lib/code/node/negation.rb +1 -0
  29. data/lib/code/node/not.rb +1 -0
  30. data/lib/code/node/nothing.rb +1 -0
  31. data/lib/code/node/right_operation.rb +3 -2
  32. data/lib/code/node/splat.rb +1 -0
  33. data/lib/code/node/square_bracket.rb +1 -0
  34. data/lib/code/node/string.rb +3 -0
  35. data/lib/code/node/ternary.rb +4 -3
  36. data/lib/code/node/unary_minus.rb +1 -0
  37. data/lib/code/node/while.rb +4 -3
  38. data/lib/code/object/boolean.rb +2 -2
  39. data/lib/code/object/context.rb +1 -1
  40. data/lib/code/object/decimal.rb +9 -21
  41. data/lib/code/object/dictionary.rb +80 -113
  42. data/lib/code/object/function.rb +25 -35
  43. data/lib/code/object/global.rb +33 -32
  44. data/lib/code/object/identifier_list.rb +4 -4
  45. data/lib/code/object/integer.rb +14 -23
  46. data/lib/code/object/json.rb +10 -2
  47. data/lib/code/object/list.rb +50 -23
  48. data/lib/code/object/parameter.rb +18 -10
  49. data/lib/code/object/range.rb +33 -10
  50. data/lib/code/object/string.rb +2 -2
  51. data/lib/code/object/time.rb +4 -4
  52. data/lib/code/object.rb +31 -50
  53. data/lib/code/parser/string.rb +1 -1
  54. data/lib/code/type/repeat.rb +1 -1
  55. data/lib/code/type/sig.rb +1 -3
  56. data/lib/code/version.rb +1 -1
  57. data/lib/code-ruby.rb +2 -7
  58. data/lib/code.rb +1 -3
  59. data/spec/code/object/dictionary_spec.rb +6 -6
  60. data/spec/code_spec.rb +7 -8
  61. data/yarn.lock +4 -0
  62. metadata +10 -3
  63. data/lib/code/object/argument.rb +0 -27
data/lib/code/object.rb CHANGED
@@ -4,7 +4,7 @@ class Code
4
4
  class Object
5
5
  attr_reader :raw
6
6
 
7
- def initialize(*_args, **_kargs, &_block)
7
+ def initialize(...)
8
8
  end
9
9
 
10
10
  def self.maybe
@@ -19,20 +19,15 @@ class Code
19
19
  Type::Or.new(self, other)
20
20
  end
21
21
 
22
- def self.sig(args, &block)
23
- Type::Sig.sig(args, object: self, &block)
24
- nil
25
- end
26
-
27
22
  def self.call(**args)
28
23
  operator = args.fetch(:operator, nil)
29
- arguments = args.fetch(:arguments, [])
30
- value = arguments.first&.value
24
+ arguments = args.fetch(:arguments, List.new)
25
+ value = arguments.code_first
31
26
 
32
27
  case operator.to_s
33
28
  when "new"
34
29
  sig(args) { Object.repeat }
35
- code_new(*arguments.map(&:value))
30
+ code_new(*arguments.raw)
36
31
  when "!", "not"
37
32
  sig(args)
38
33
  code_exclamation_point
@@ -60,9 +55,6 @@ class Code
60
55
  when "falsy?"
61
56
  sig(args)
62
57
  Boolean.new(falsy?)
63
- when "to_string"
64
- sig(args)
65
- code_to_string
66
58
  when "truthy?"
67
59
  sig(args)
68
60
  Boolean.new(truthy?)
@@ -110,7 +102,11 @@ class Code
110
102
  code_as_json
111
103
  when "to_json"
112
104
  sig(args) { { pretty: Boolean.maybe } }
113
- code_to_json(pretty: value&.code_get(String.new(:pretty)))
105
+ if arguments.any?
106
+ code_to_json(pretty: value.code_get(String.new(:pretty)))
107
+ else
108
+ code_to_json
109
+ end
114
110
  when /=$/
115
111
  sig(args) { Object }
116
112
 
@@ -123,8 +119,8 @@ class Code
123
119
  self,
124
120
  context.code_fetch(self).call(
125
121
  **args,
126
- operator: operator[..-2],
127
- arguments: [Argument.new(value)]
122
+ operator: operator.chop,
123
+ arguments: List.new([value])
128
124
  )
129
125
  )
130
126
  end
@@ -133,13 +129,13 @@ class Code
133
129
  else
134
130
  raise(
135
131
  Error::Undefined,
136
- "#{operator} not defined on #{inspect}:Class"
132
+ "#{operator.inspect} not defined on #{inspect}:Class"
137
133
  )
138
134
  end
139
135
  end
140
136
 
141
- def self.code_new(*arguments)
142
- new(*arguments)
137
+ def self.code_new(*)
138
+ new(*)
143
139
  end
144
140
 
145
141
  def self.code_and_operator(other)
@@ -178,10 +174,6 @@ class Code
178
174
  Boolean.new(self === other)
179
175
  end
180
176
 
181
- def self.code_to_string
182
- String.new(to_s)
183
- end
184
-
185
177
  def self.falsy?
186
178
  !truthy?
187
179
  end
@@ -190,8 +182,8 @@ class Code
190
182
  keys.map { |key| [key, hash.fetch(key)] }.to_h
191
183
  end
192
184
 
193
- def self.sig(args, &block)
194
- Type::Sig.sig(args, object: self, &block)
185
+ def self.sig(args, &)
186
+ Type::Sig.sig(args, object: self, &)
195
187
  nil
196
188
  end
197
189
 
@@ -242,12 +234,12 @@ class Code
242
234
  other == self
243
235
  end
244
236
  end
245
- alias eql? ==
237
+ alias_method :eql?, :==
246
238
 
247
239
  def call(**args)
248
240
  operator = args.fetch(:operator, nil)
249
- arguments = args.fetch(:arguments, [])
250
- value = arguments.first&.value
241
+ arguments = args.fetch(:arguments, List.new)
242
+ value = arguments.code_first
251
243
 
252
244
  case operator.to_s
253
245
  when "!", "not"
@@ -277,9 +269,6 @@ class Code
277
269
  when "falsy?"
278
270
  sig(args)
279
271
  Boolean.new(falsy?)
280
- when "to_string"
281
- sig(args)
282
- code_to_string
283
272
  when "truthy?"
284
273
  sig(args)
285
274
  Boolean.new(truthy?)
@@ -327,7 +316,11 @@ class Code
327
316
  code_as_json
328
317
  when "to_json"
329
318
  sig(args) { { pretty: Boolean.maybe } }
330
- code_to_json(pretty: value&.code_get(String.new(:pretty)))
319
+ if arguments.any?
320
+ code_to_json(pretty: value.code_get(String.new(:pretty)))
321
+ else
322
+ code_to_json
323
+ end
331
324
  when /=$/
332
325
  sig(args) { Object }
333
326
 
@@ -340,8 +333,8 @@ class Code
340
333
  self,
341
334
  context.code_fetch(self).call(
342
335
  **args,
343
- operator: operator[..-2],
344
- arguments: [Argument.new(value)]
336
+ operator: operator.chop,
337
+ arguments: List.new([value])
345
338
  )
346
339
  )
347
340
  end
@@ -375,9 +368,7 @@ class Code
375
368
  Range.new(
376
369
  self,
377
370
  value,
378
- Dictionary.new({
379
- String.new(:exclude_end) => Boolean.new(true)
380
- })
371
+ Dictionary.new({ String.new(:exclude_end) => Boolean.new(true) })
381
372
  )
382
373
  end
383
374
 
@@ -385,9 +376,7 @@ class Code
385
376
  Range.new(
386
377
  self,
387
378
  value,
388
- Dictionary.new({
389
- String.new(:exclude_end) => Boolean.new(false)
390
- })
379
+ Dictionary.new({ String.new(:exclude_end) => Boolean.new(false) })
391
380
  )
392
381
  end
393
382
 
@@ -403,10 +392,6 @@ class Code
403
392
  Boolean.new(self === other)
404
393
  end
405
394
 
406
- def code_to_string
407
- String.new(to_s)
408
- end
409
-
410
395
  def falsy?
411
396
  !truthy?
412
397
  end
@@ -419,8 +404,8 @@ class Code
419
404
  keys.map { |key| [key, hash.fetch(key)] }.to_h
420
405
  end
421
406
 
422
- def sig(args, &block)
423
- Type::Sig.sig(args, object: self, &block)
407
+ def sig(args, &)
408
+ Type::Sig.sig(args, object: self, &)
424
409
  nil
425
410
  end
426
411
 
@@ -457,11 +442,7 @@ class Code
457
442
  end
458
443
 
459
444
  def succ
460
- if raw.respond_to?(:succ)
461
- self.class.new(raw.succ)
462
- else
463
- self.class.new(self)
464
- end
445
+ raw.respond_to?(:succ) ? self.class.new(raw.succ) : self.class.new(self)
465
446
  end
466
447
  end
467
448
  end
@@ -20,7 +20,7 @@ class Code
20
20
  end
21
21
 
22
22
  def backslash
23
- str('\\')
23
+ str("\\")
24
24
  end
25
25
 
26
26
  def opening_curly_bracket
@@ -21,7 +21,7 @@ class Code
21
21
 
22
22
  def max_arguments
23
23
  max_arguments = max_arguments_of(clazz)
24
- max_arguments.nil? || maximum.nil? ? nil : maximum * max_arguments
24
+ (max_arguments.nil? || maximum.nil?) ? nil : maximum * max_arguments
25
25
  end
26
26
 
27
27
  def name
data/lib/code/type/sig.rb CHANGED
@@ -40,7 +40,7 @@ class Code
40
40
  end
41
41
 
42
42
  def actual_arguments
43
- args.fetch(:arguments, []).map(&:value)
43
+ args[:arguments]&.raw || []
44
44
  end
45
45
 
46
46
  def operator
@@ -94,8 +94,6 @@ class Code
94
94
  Error::ArityError,
95
95
  "#{function}: Expected #{expected_count} but got #{actual_count}"
96
96
  )
97
-
98
- nil
99
97
  end
100
98
 
101
99
  def valid_for?(expected:, actual:)
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.13.1")
5
+ Code::Version = Gem::Version.new("0.14.1")
data/lib/code-ruby.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support"
4
- require "active_support/core_ext/date/conversions"
5
- require "active_support/core_ext/numeric/time"
6
- require "active_support/core_ext/object/json"
7
- require "active_support/core_ext/object/blank"
8
- require "active_support/core_ext/array/access"
3
+ require "active_support/all"
9
4
  require "bigdecimal"
10
5
  require "bigdecimal/util"
11
6
  require "json"
@@ -19,5 +14,5 @@ loader.ignore("#{__dir__}/code-ruby.rb")
19
14
  loader.setup
20
15
 
21
16
  class Object
22
- alias is_an? is_a?
17
+ alias_method :is_an?, :is_a?
23
18
  end
data/lib/code.rb CHANGED
@@ -18,9 +18,7 @@ class Code
18
18
  end
19
19
 
20
20
  def self.parse(input, timeout: DEFAULT_TIMEOUT)
21
- Timeout.timeout(timeout) do
22
- Parser.parse(input).to_raw
23
- end
21
+ Timeout.timeout(timeout) { Parser.parse(input).to_raw }
24
22
  end
25
23
 
26
24
  def self.evaluate(
@@ -7,20 +7,20 @@ RSpec.describe Code::Object::Dictionary do
7
7
 
8
8
  [
9
9
  [
10
- "dictionary.select { |key, value, dictionnary, index| key == :first_name }",
10
+ "dictionary.select { |key| key == :first_name }",
11
11
  "{ first_name: :Dorian }"
12
12
  ],
13
13
  [
14
- "dictionary.select { |key, value, dictionnary, index| value == :Dorian }",
14
+ "dictionary.select { |_, value| value == :Dorian }",
15
15
  "{ first_name: :Dorian }"
16
16
  ],
17
17
  [
18
- "dictionary.select { |key, value, dictionnary, index| dictionnary.two? }",
19
- "dictionary"
18
+ "dictionary.select { |_, _, index, _| index.zero? }",
19
+ "{ first_name: :Dorian }"
20
20
  ],
21
21
  [
22
- "dictionary.select { |key, value, dictionnary, index| index.zero? }",
23
- "{ first_name: :Dorian }"
22
+ "dictionary.select { |_, _, _, dictionary| dictionary.two? }",
23
+ "dictionary"
24
24
  ],
25
25
  [
26
26
  "dictionary.fetch(:first_name, :last_name) { :Marié }",
data/spec/code_spec.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe Code do
6
-
7
6
  %w[
8
7
  1.day.ago
9
8
  1.day.from_now
@@ -61,9 +60,6 @@ RSpec.describe Code do
61
60
  Time.tomorrow
62
61
  Code.new
63
62
  Parameter.new
64
- Argument.new
65
- Argument.new(1)
66
- Argument.new(1,name:"index")
67
63
  IdentifierList.new
68
64
  IdentifierList.new([])
69
65
  ].each { |input| it(input) { Code.evaluate(input) } }
@@ -270,14 +266,17 @@ RSpec.describe Code do
270
266
  ['user = {} user[:name] = "Dorian" user[:name]', ":Dorian"],
271
267
  ['{ "first_name": "Dorian" }', '{"first_name" => "Dorian"}'],
272
268
  ['{ "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"'}],
269
+ %w[nothing.to_json :null],
270
+ %w[1.to_json "1"],
271
+ %w[1.0.to_json '"1.0"'],
272
+ %w[1.1.to_json '"1.1"'],
273
+ ["a = {} a.merge!(a: 1) a", "{a: 1}"],
274
+ ["a = {} a.merge(a: 1) a", "{}"],
277
275
  ["", ""]
278
276
  ].each do |input, expected|
279
277
  it "#{input} == #{expected}" do
280
278
  expect(Code.evaluate(input)).to eq(Code.evaluate(expected))
279
+ next if Code.evaluate(input).is_a?(Code::Object::Decimal)
281
280
  expect(Code.evaluate(input).to_json).to eq(
282
281
  Code.evaluate(expected).to_json
283
282
  )
data/yarn.lock ADDED
@@ -0,0 +1,4 @@
1
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
+ # yarn lockfile v1
3
+
4
+
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.13.1
4
+ version: 0.14.1
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-09 00:00:00.000000000 Z
11
+ date: 2024-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -87,16 +87,23 @@ executables:
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - ".github/dependabot.yml"
91
+ - ".github/workflows/ci.yml"
90
92
  - ".gitignore"
91
93
  - ".rspec"
94
+ - ".rubocop.yml"
92
95
  - ".ruby-version"
93
96
  - ".tool-versions"
94
97
  - Gemfile
95
98
  - Gemfile.lock
96
99
  - README.md
97
100
  - Rakefile
101
+ - bin/bundle-audit
102
+ - bin/bundler-audit
98
103
  - bin/code
99
104
  - bin/console
105
+ - bin/rspec
106
+ - bin/rubocop
100
107
  - code-ruby.gemspec
101
108
  - lib/code-ruby.rb
102
109
  - lib/code.rb
@@ -130,7 +137,6 @@ files:
130
137
  - lib/code/node/unary_minus.rb
131
138
  - lib/code/node/while.rb
132
139
  - lib/code/object.rb
133
- - lib/code/object/argument.rb
134
140
  - lib/code/object/boolean.rb
135
141
  - lib/code/object/class.rb
136
142
  - lib/code/object/code.rb
@@ -221,6 +227,7 @@ files:
221
227
  - spec/code/type_spec.rb
222
228
  - spec/code_spec.rb
223
229
  - spec/spec_helper.rb
230
+ - yarn.lock
224
231
  homepage: https://github.com/dorianmariecom/code-ruby
225
232
  licenses:
226
233
  - MIT
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Code
4
- class Object
5
- class Argument < Object
6
- attr_reader :value, :name
7
-
8
- def initialize(*args, **_kargs, &_block)
9
- @value = args.first.presence || Nothing.new
10
- @name = args.second.present? ? String.new(args.second) : nil
11
- @raw = List.new([@value, @name])
12
- end
13
-
14
- def keyword?
15
- !regular?
16
- end
17
-
18
- def name_value
19
- [name, value]
20
- end
21
-
22
- def regular?
23
- !name
24
- end
25
- end
26
- end
27
- end