code-ruby 0.8.4 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5dda57442d7fc50b08ceb9998021e623f226a0b8de3cdaf58fecd05d0ba3a30
4
- data.tar.gz: bead8ebd992882ea955f10d24e10f110a5c9955926e0e4850cddbcb4e3afe34c
3
+ metadata.gz: 53b06f45f6875d9e78c0554c660567fcfc7837b2e3fc3bfa8f3773bbdf133831
4
+ data.tar.gz: 894638c2797c729099e577a8c7f10d21990d291a0cc2376760f5e61d58f0c6e4
5
5
  SHA512:
6
- metadata.gz: 136c900a7f0efab8fbf2ada6bc90c018689f5545b350b1b3b77c19e07ebd2eb18addb6852a12ede8c7bb692ad48af341c9decab8740b26d92fd5f45ec2a5ffa6
7
- data.tar.gz: 24881df454cb5e179265232a37c45a1d1322ed0606ed3caf82fc56ee3526df1b3dc3c1f06301f5887e48b5da65e2b01b9c4e8424c703ab47923325c3b5ee1d6f
6
+ metadata.gz: 387dde40ad9948f938cdaea2a94dfcaabe4e94cef99f8941340184287a8b79efcd378f1012d3a0b4215b394090efc51368b9770429a5b60e63804721487c3546
7
+ data.tar.gz: a5939cfca0ff262ac86075c141cb133b39126f0f99f61b4715a018e3f746a45513dce30b4a45520a5f95117cbd67716a6984236199ef45b6d527853a31dae3f0
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code-ruby (0.8.4)
4
+ code-ruby (0.9.0)
5
5
  activesupport (~> 7)
6
6
  bigdecimal (~> 3)
7
+ json (~> 2)
7
8
  language-ruby (~> 0)
8
9
  zeitwerk (~> 2)
9
10
 
@@ -29,6 +30,7 @@ GEM
29
30
  ruby2_keywords
30
31
  i18n (1.14.1)
31
32
  concurrent-ruby (~> 1.0)
33
+ json (2.7.1)
32
34
  language-ruby (0.6.2)
33
35
  zeitwerk (~> 2)
34
36
  minitest (5.22.2)
@@ -45,7 +47,7 @@ GEM
45
47
  rspec-mocks (3.13.0)
46
48
  diff-lcs (>= 1.2.0, < 2.0)
47
49
  rspec-support (~> 3.13.0)
48
- rspec-support (3.13.0)
50
+ rspec-support (3.13.1)
49
51
  ruby-prof (1.7.0)
50
52
  ruby2_keywords (0.0.5)
51
53
  tzinfo (2.0.6)
data/README.md CHANGED
@@ -1,7 +1,3 @@
1
1
  # code-ruby
2
2
 
3
3
  A programming language, like `Code.evaluate("1 + 1") # => 2`
4
-
5
- TODO
6
-
7
- - [ ] `code` command
data/code-ruby.gemspec CHANGED
@@ -10,14 +10,15 @@ Gem::Specification.new do |s|
10
10
  s.description = 'A programming language, like Code.evaluate("1 + 1") # => 2'
11
11
  s.authors = ["Dorian Marié"]
12
12
  s.email = "dorian@dorianmarie.fr"
13
- s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
13
+ s.files = `git ls-files`.lines.map(&:strip)
14
14
  s.require_paths = ["lib"]
15
15
  s.homepage = "https://github.com/dorianmariecom/code-ruby"
16
16
  s.license = "MIT"
17
17
  s.executables = "code"
18
18
 
19
+ s.add_dependency "activesupport", "~> 7"
19
20
  s.add_dependency "bigdecimal", "~> 3"
21
+ s.add_dependency "json", "~> 2"
20
22
  s.add_dependency "language-ruby", "~> 0"
21
- s.add_dependency "activesupport", "~> 7"
22
23
  s.add_dependency "zeitwerk", "~> 2"
23
24
  end
@@ -6,15 +6,11 @@ class Code
6
6
  attr_reader :raw
7
7
 
8
8
  def initialize(whole, exponent: nil)
9
+ whole = whole.raw if whole.is_a?(Integer)
9
10
  @raw = whole.to_i
10
-
11
11
  return unless exponent
12
-
13
- unless exponent.is_a?(Number)
14
- raise Code::Error::TypeError, "exponent is not a number"
15
- end
16
-
17
- @raw *= 10**exponent.raw
12
+ exponent = exponent.raw if exponent.is_a?(Number)
13
+ @raw *= 10**exponent
18
14
  end
19
15
 
20
16
  def self.name
@@ -8,7 +8,10 @@ class Code
8
8
  attr_reader :raw
9
9
 
10
10
  def initialize(time)
11
- @raw = time
11
+ ::Time.zone ||= DEFAULT_ZONE
12
+ time = time.raw if time.is_a?(Time)
13
+ time = time.to_s if time.is_a?(::Time)
14
+ @raw = ::Time.zone.parse(time)
12
15
  end
13
16
 
14
17
  def self.name
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.8.4")
5
+ Code::Version = Gem::Version.new("0.9.0")
data/lib/code.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Code
4
- EMPTY_STRING = ""
5
4
  GLOBALS = %i[output error context object].freeze
6
5
  DEFAULT_TIMEOUT = 0
7
6
 
@@ -9,50 +8,35 @@ class Code
9
8
  input,
10
9
  output: StringIO.new,
11
10
  error: StringIO.new,
12
- timeout: DEFAULT_TIMEOUT,
13
- ruby: {}
11
+ timeout: DEFAULT_TIMEOUT
14
12
  )
15
13
  @input = input
16
- @parsed = Timeout.timeout(timeout) { ::Code::Parser.parse(input).to_raw }
17
14
  @output = output
18
15
  @error = error
19
16
  @timeout = timeout || DEFAULT_TIMEOUT
20
- @ruby = ::Code::Ruby.to_code(ruby || {}).code_to_context
17
+ @context = Object::Context.new
21
18
  end
22
19
 
23
20
  def self.evaluate(
24
21
  input,
25
- context = EMPTY_STRING,
26
22
  output: StringIO.new,
27
23
  error: StringIO.new,
28
- timeout: DEFAULT_TIMEOUT,
29
- ruby: {}
24
+ timeout: DEFAULT_TIMEOUT
30
25
  )
31
- new(input, output:, error:, timeout:, ruby:).evaluate(context)
26
+ new(input, output:, error:, timeout:).evaluate
32
27
  end
33
28
 
34
- def evaluate(context = EMPTY_STRING)
29
+ def evaluate
35
30
  Timeout.timeout(timeout) do
36
- context =
37
- if context == EMPTY_STRING
38
- Object::Context.new
39
- else
40
- Code.evaluate(
41
- context,
42
- timeout:,
43
- output:,
44
- error:,
45
- ruby:
46
- ).code_to_context
47
- end
48
-
49
- context = ruby.merge(context)
50
-
51
- Node::Code.new(parsed).evaluate(context:, output:, error:)
31
+ Node::Code.new(::Code::Parser.parse(input).to_raw).evaluate(
32
+ context:,
33
+ output:,
34
+ error:
35
+ )
52
36
  end
53
37
  end
54
38
 
55
39
  private
56
40
 
57
- attr_reader :input, :parsed, :timeout, :output, :error, :ruby
41
+ attr_reader :input, :timeout, :output, :error, :context
58
42
  end
@@ -3,95 +3,95 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe Code::Object::Dictionary do
6
- let(:context) { '{ first_name: "Dorian", language: :code }' }
6
+ let(:dictionary) { 'dictionary = { first_name: "Dorian", language: :code }' }
7
7
 
8
8
  [
9
- ["{} == {}", "true"],
10
- ['{ "name" => "Dorian" } == { name: :Dorian }', "true"],
11
- %w[context.first_name :Dorian],
12
- ["context[:first_name]", ":Dorian"],
13
- %w[context.language :code],
14
- ["context > { first_name: :Dorian", "true"],
15
- ["{ first_name: :Dorian } < context", "true"],
16
- ["context <= context", "true"],
17
- ["context >= {}", "true"],
18
- ["context <=> context", "0"],
19
- ["context === context", "true"],
20
- ["{ first_name: :Dorian }.any? { |_, value| value == :Dorian }", "true"],
21
- %w[context.any?(String) true],
22
- ["{ a: nothing }.compact", "{}"],
23
- ["d = { a: nothing } d.compact! d", "{}"],
24
- %w[context.dig(:first_name) :Dorian],
25
- %w[context.empty? false],
26
- %w[context.truthy? true],
27
- %w[context.falsy? false],
28
- %w[context.fetch(:first_name) :Dorian],
29
- ["context.fetch(:unknown) { :Good }", ":Good"],
30
- ["context.fetch(:first_name, :language)", "context"],
31
9
  [
32
- "context.fetch(:first_name, :last_name) { :Marié }",
33
- "{ first_name: :Dorian, last_name: :Marié }"
10
+ "dictionary.select { |key, value, dictionnary, index| key == :first_name }",
11
+ "{ first_name: :Dorian }"
34
12
  ],
35
- ["context.delete(:last_name) { true }", "true"],
36
13
  [
37
- "context.delete(:first_name, :language)",
38
- "{ first_name: :Dorian, language: :code }"
14
+ "dictionary.select { |key, value, dictionnary, index| value == :Dorian }",
15
+ "{ first_name: :Dorian }"
39
16
  ],
40
- ["{ first_name: :Dorian }.delete_if(String)", "{}"],
41
- ["{ age: 31 }.delete_unless(Number)", "{ age: 31 }"],
42
- ["{ age: 31 }.delete_unless(Integer)", "{ age: 31 }"],
43
- ["{ first_name: :Dorian }.delete_if { |_, value| value == :Dorian }", "{}"],
44
- ["{ age: 31 }.delete_unless { |key| key == :age }", "{ age: 31 }"],
45
- ["{ first_name: :Dorian }.keep_if(String)", "{ first_name: :Dorian }"],
46
- ["{ age: 31 }.keep_unless(Number)", "{}"],
47
- ["{ age: 31 }.keep_unless(Integer)", "{}"],
48
- ["{ first_name: :Dorian }.keep_if { |_, value| value != :Dorian }", "{}"],
49
- ["{ age: 31 }.keep_unless { |key| key == :age }", "{}"],
50
- ["context.except(:first_name, :language)", "{}"],
51
- ["context.fetch_values(:first_name, :language)", "[:Dorian, :code]"],
52
- ["context.fetch_values(:first_name)", "[:Dorian]"],
53
- %w[context.select(String) context],
54
- %w[context.select(Integer) {}],
55
- ["context.select(Integer) context", "context"],
56
- %w[context.select!(Integer) {}],
57
- ["context.select!(Integer) context", "{}"],
58
17
  [
59
- "context.select { |key, value, dictionnary, index| key == :first_name }",
60
- "{ first_name: :Dorian }"
18
+ "dictionary.select { |key, value, dictionnary, index| dictionnary.two? }",
19
+ "dictionary"
61
20
  ],
62
21
  [
63
- "context.select { |key, value, dictionnary, index| value == :Dorian }",
22
+ "dictionary.select { |key, value, dictionnary, index| index.zero? }",
64
23
  "{ first_name: :Dorian }"
65
24
  ],
66
25
  [
67
- "context.select { |key, value, dictionnary, index| dictionnary.two? }",
68
- "context"
26
+ "dictionary.fetch(:first_name, :last_name) { :Marié }",
27
+ "{ first_name: :Dorian, last_name: :Marié }"
69
28
  ],
29
+ ["dictionary.delete(:last_name) { true }", "true"],
70
30
  [
71
- "context.select { |key, value, dictionnary, index| index.zero? }",
72
- "{ first_name: :Dorian }"
31
+ "dictionary.delete(:first_name, :language)",
32
+ "{ first_name: :Dorian, language: :code }"
73
33
  ],
74
- ["{ a: 1, b: [2, 3] }.to_list", "[[:a, 1], [:b, [2, 3]]]"],
34
+ %w[dictionary.any?(String) true],
35
+ %w[dictionary.dig(:first_name) :Dorian],
36
+ %w[dictionary.empty? false],
37
+ %w[dictionary.falsy? false],
38
+ %w[dictionary.fetch(:first_name) :Dorian],
39
+ %w[dictionary.first_name :Dorian],
40
+ %w[dictionary.has_key?(:first_name) true],
41
+ %w[dictionary.has_key?(:unknown) false],
42
+ %w[dictionary.has_value?(:Dorian) true],
43
+ %w[dictionary.has_value?(:Unknown) false],
44
+ %w[dictionary.key(:Dorian) :first_name],
45
+ %w[dictionary.key(:Unknown) nothing],
46
+ %w[dictionary.language :code],
47
+ %w[dictionary.select!(Integer) {}],
48
+ %w[dictionary.select(Integer) {}],
49
+ %w[dictionary.select(String) dictionary],
50
+ %w[dictionary.truthy? true],
51
+ ["d = { a: nothing } d.compact! d", "{}"],
52
+ ["dictionary <= dictionary", "true"],
53
+ ["dictionary <=> dictionary", "0"],
54
+ ["dictionary === dictionary", "true"],
55
+ ["dictionary > { first_name: :Dorian", "true"],
56
+ ["dictionary >= {}", "true"],
57
+ ["dictionary.except(:first_name, :language)", "{}"],
58
+ ["dictionary.fetch(:first_name, :language)", "dictionary"],
59
+ ["dictionary.fetch(:unknown) { :Good }", ":Good"],
60
+ ["dictionary.fetch_values(:first_name)", "[:Dorian]"],
61
+ ["dictionary.fetch_values(:first_name, :language)", "[:Dorian, :code]"],
62
+ ["dictionary.invert", "{ Dorian: :first_name, code: :language }"],
63
+ ["dictionary.key(:Unknown) { true }", "true"],
64
+ ["dictionary.select!(Integer) dictionary", "{}"],
65
+ ["dictionary.select(Integer) dictionary", "dictionary"],
66
+ ["dictionary[:first_name]", ":Dorian"],
67
+ ["{ a: 1 }.merge(b: 2)", "{ a: 1, b: 2 }"],
68
+ ["{ a: 1 }.merge({ a: 2 }) { |_, old, new| old + new }", "{ a: 3 }"],
69
+ ["{ a: 1 }.merge({ a: 2 })", "{ a: 2 }"],
70
+ ["{ a: 1 }.merge({ b: 2 })", "{ a: 1, b: 2 }"],
75
71
  ["{ a: 1, b: [2, 3] }.flatten", "[:a, 1, :b, 2, 3]"],
72
+ ["{ a: 1, b: [2, 3] }.flatten(-1)", "[:a, 1, :b, 2, 3]"],
76
73
  ["{ a: 1, b: [2, 3] }.flatten(0)", "[[:a, 1], [:b, [2, 3]]]"],
77
74
  ["{ a: 1, b: [2, 3] }.flatten(1)", "[:a, 1, :b, [2, 3]]"],
78
- ["{ a: 1, b: [2, 3] }.flatten(-1)", "[:a, 1, :b, 2, 3]"],
79
- %w[context.has_key?(:first_name) true],
80
- %w[context.has_key?(:unknown) false],
81
- %w[context.has_value?(:Dorian) true],
82
- %w[context.has_value?(:Unknown) false],
83
- ["context.invert", "{ Dorian: :first_name, code: :language }"],
84
- %w[context.key(:Dorian) :first_name],
85
- %w[context.key(:Unknown) nothing],
86
- ["context.key(:Unknown) { true }", "true"],
87
- ["{ a: 1 }.merge(b: 2)", "{ a: 1, b: 2 }"],
88
- ["{ a: 1 }.merge({ b: 2 })", "{ a: 1, b: 2 }"],
89
- ["{ a: 1 }.merge({ a: 2 })", "{ a: 2 }"],
90
- ["{ a: 1 }.merge({ a: 2 }) { |_, old, new| old + new }", "{ a: 3 }"]
75
+ ["{ a: 1, b: [2, 3] }.to_list", "[[:a, 1], [:b, [2, 3]]]"],
76
+ ["{ a: nothing }.compact", "{}"],
77
+ ["{ age: 31 }.delete_unless { |key| key == :age }", "{ age: 31 }"],
78
+ ["{ age: 31 }.delete_unless(Integer)", "{ age: 31 }"],
79
+ ["{ age: 31 }.delete_unless(Number)", "{ age: 31 }"],
80
+ ["{ age: 31 }.keep_unless { |key| key == :age }", "{}"],
81
+ ["{ age: 31 }.keep_unless(Integer)", "{}"],
82
+ ["{ age: 31 }.keep_unless(Number)", "{}"],
83
+ ["{ first_name: :Dorian } < dictionary", "true"],
84
+ ["{ first_name: :Dorian }.any? { |_, value| value == :Dorian }", "true"],
85
+ ["{ first_name: :Dorian }.delete_if { |_, value| value == :Dorian }", "{}"],
86
+ ["{ first_name: :Dorian }.delete_if(String)", "{}"],
87
+ ["{ first_name: :Dorian }.keep_if { |_, value| value != :Dorian }", "{}"],
88
+ ["{ first_name: :Dorian }.keep_if(String)", "{ first_name: :Dorian }"],
89
+ ["{} == {}", "true"],
90
+ ['{ "name" => "Dorian" } == { name: :Dorian }', "true"]
91
91
  ].each do |input, expected|
92
92
  it "#{input} == #{expected}" do
93
- expect(Code.evaluate(input, context)).to eq(
94
- Code.evaluate(expected, context)
93
+ expect(Code.evaluate("#{dictionary} #{input}")).to eq(
94
+ Code.evaluate("#{dictionary} #{expected}")
95
95
  )
96
96
  end
97
97
  end
@@ -2,12 +2,12 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe Code::Object::String do
4
4
  [
5
- [":a", "a"],
6
- [":a_b_c_0123", "a_b_c_0123"],
7
- ['"Hello"', "Hello"],
8
- ["'Hello'", "Hello"],
5
+ %w[:a a],
6
+ %w[:a_b_c_0123 a_b_c_0123],
7
+ %w["Hello" Hello],
8
+ %w['Hello' Hello],
9
9
  ['"Hello\nWorld"', "Hello\nWorld"],
10
- ["'Hello\\nWorld'", "Hello\nWorld"],
10
+ ["'Hello\\nWorld'", "Hello\nWorld"]
11
11
  ].each do |input, expected|
12
12
  it "(#{input}).to_s == #{expected.inspect}" do
13
13
  expect(Code.evaluate(input).to_s).to eq(expected)
data/spec/code_spec.rb CHANGED
@@ -57,14 +57,14 @@ RSpec.describe Code do
57
57
  ["1 >> 1", "0"],
58
58
  ["1 ^ 2", "3"],
59
59
  ["1 | 2", "3"],
60
- ["1.day.ago.after?(1.day.from_now)", 'false'],
61
- ["1.day.ago.before?(1.day.from_now)", 'true'],
62
- ["1.day.from_now.after?(1.day.ago)", 'true'],
63
- ["1.day.from_now.before?(1.day.ago)", 'false'],
64
- ["1.day.ago.after?", 'false'],
65
- ["1.day.ago.before?", 'true'],
66
- ["1.day.from_now.after?", "true"],
67
- ["1.day.from_now.before?", "false"],
60
+ %w[1.day.ago.after?(1.day.from_now) false],
61
+ %w[1.day.ago.before?(1.day.from_now) true],
62
+ %w[1.day.from_now.after?(1.day.ago) true],
63
+ %w[1.day.from_now.before?(1.day.ago) false],
64
+ %w[1.day.ago.after? false],
65
+ %w[1.day.ago.before? true],
66
+ %w[1.day.from_now.after? true],
67
+ %w[1.day.from_now.before? false],
68
68
  ["2 * 3 + 2", "8"],
69
69
  ["2 * 3", "6"],
70
70
  ["2 ** 3 ** 2", "512"],
@@ -141,13 +141,26 @@ RSpec.describe Code do
141
141
  ['"Hello {1}"', '"Hello 1"'],
142
142
  ['user = {} user.name = "Dorian" user.name', ":Dorian"],
143
143
  ['user = {} user[:name] = "Dorian" user[:name]', ":Dorian"],
144
- ['{ "first_name": "Dorian" }', '{"first_name" => "Dorian"}'],
144
+ ['{ "first_name": "Dorian" }', '{"first_name" => "Dorian"}']
145
145
  ].each do |input, expected|
146
146
  it "#{input} == #{expected}" do
147
147
  expect(Code.evaluate(input)).to eq(Code.evaluate(expected))
148
148
  end
149
149
  end
150
150
 
151
+ %w[
152
+ 1.day.ago
153
+ 1.day.from_now
154
+ 1.hour.ago
155
+ 1.hour.from_now
156
+ 2.days.ago
157
+ 2.days.from_now
158
+ 2.hours.ago
159
+ 2.hours.from_now
160
+ Date.tomorrow
161
+ Time.tomorrow
162
+ ].each { |input| it(input) { Code.evaluate(input) } }
163
+
151
164
  [["puts(true)", "true\n"], %w[print(false) false]].each do |input, expected|
152
165
  it "#{input} prints #{expected}" do
153
166
  output = StringIO.new
@@ -155,62 +168,4 @@ RSpec.describe Code do
155
168
  expect(output.string).to eq(expected)
156
169
  end
157
170
  end
158
-
159
- it "converts nil" do
160
- ruby = Code::Ruby.from_code(Code.evaluate("a", ruby: { a: nil }))
161
-
162
- expect(ruby).to eq(nil)
163
- end
164
-
165
- it "works with downcase" do
166
- expect(Code.evaluate("downcase", "{ downcase: 1 }")).to eq(
167
- Code.evaluate("1")
168
- )
169
- end
170
-
171
- describe "#fetch" do
172
- it "returns the value when present" do
173
- expect(Code.evaluate("fetch(:downcase)", "{ downcase: 1 }")).to eq(
174
- Code.evaluate("1")
175
- )
176
- end
177
-
178
- it "returns the default value when not present" do
179
- expect(Code.evaluate("fetch(:downcase) { 2 }")).to eq(
180
- Code.evaluate("2")
181
- )
182
- end
183
- end
184
-
185
- it "works with nested objects" do
186
- expect(
187
- Code.evaluate("items.first.title", ruby: { items: [{ title: "Hello" }] })
188
- ).to eq(Code.evaluate(":Hello"))
189
- end
190
-
191
- it "works with arrays" do
192
- expect(
193
- Code.evaluate(
194
- "items.map { |item| item.title }",
195
- ruby: {
196
- items: [{ title: "Hello" }]
197
- }
198
- )
199
- ).to eq(Code.evaluate("[:Hello]"))
200
- end
201
-
202
- [
203
- "1.day.ago",
204
- "1.day.from_now",
205
- "1.hour.ago",
206
- "1.hour.from_now",
207
- "2.days.ago",
208
- "2.days.from_now",
209
- "2.hours.ago",
210
- "2.hours.from_now",
211
- "Date.tomorrow",
212
- "Time.tomorrow",
213
- ].each do |input|
214
- it(input) { Code.evaluate(input) }
215
- end
216
171
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.9.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-02-26 00:00:00.000000000 Z
11
+ date: 2024-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bigdecimal
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,33 +39,33 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '3'
27
41
  - !ruby/object:Gem::Dependency
28
- name: language-ruby
42
+ name: json
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '0'
47
+ version: '2'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '0'
54
+ version: '2'
41
55
  - !ruby/object:Gem::Dependency
42
- name: activesupport
56
+ name: language-ruby
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '7'
61
+ version: '0'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '7'
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: zeitwerk
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -130,7 +144,6 @@ files:
130
144
  - lib/code/object/nothing.rb
131
145
  - lib/code/object/number.rb
132
146
  - lib/code/object/range.rb
133
- - lib/code/object/ruby_function.rb
134
147
  - lib/code/object/string.rb
135
148
  - lib/code/object/time.rb
136
149
  - lib/code/parser.rb
@@ -174,7 +187,6 @@ files:
174
187
  - lib/code/parser/unary_minus.rb
175
188
  - lib/code/parser/while.rb
176
189
  - lib/code/parser/whitespace.rb
177
- - lib/code/ruby.rb
178
190
  - lib/code/type.rb
179
191
  - lib/code/type/hash.rb
180
192
  - lib/code/type/maybe.rb
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Code
4
- class Object
5
- class RubyFunction < Function
6
- attr_reader :raw
7
-
8
- def initialize(raw)
9
- @raw = raw
10
- end
11
-
12
- def self.name
13
- "RubyFunction"
14
- end
15
-
16
- # TODO: fix / refactor
17
- def code_call(args:, globals:)
18
- regular_arguments =
19
- args
20
- .select(&:regular?)
21
- .map(&:value)
22
- .map { |argument| Ruby.from_code(argument) }
23
-
24
- keyword_arguments =
25
- args
26
- .select(&:keyword?)
27
- .map do |argument|
28
- [argument.name.to_sym, Ruby.from_code(argument.value)]
29
- end
30
- .to_h
31
-
32
- Ruby.to_code(raw.call(*regular_arguments, **keyword_arguments))
33
- end
34
- end
35
- end
36
- end
data/lib/code/ruby.rb DELETED
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Code
4
- class Ruby
5
- def initialize(raw = {})
6
- @raw = raw
7
- end
8
-
9
- def self.to_code(raw)
10
- new(raw).to_code
11
- end
12
-
13
- def self.from_code(raw)
14
- new(raw).from_code
15
- end
16
-
17
- def to_code
18
- if code?
19
- raw
20
- elsif nil?
21
- ::Code::Object::Nothing.new
22
- elsif true?
23
- ::Code::Object::Boolean.new(raw)
24
- elsif false?
25
- ::Code::Object::Boolean.new(raw)
26
- elsif string?
27
- ::Code::Object::String.new(raw)
28
- elsif symbol?
29
- ::Code::Object::String.new(raw.to_s)
30
- elsif integer?
31
- ::Code::Object::Integer.new(raw)
32
- elsif float?
33
- ::Code::Object::Decimal.new(raw.to_s)
34
- elsif big_decimal?
35
- ::Code::Object::Decimal.new(raw)
36
- elsif hash?
37
- ::Code::Object::Dictionary.new(
38
- raw
39
- .map do |key, value|
40
- [::Code::Ruby.to_code(key), ::Code::Ruby.to_code(value)]
41
- end
42
- .to_h
43
- )
44
- elsif array?
45
- ::Code::Object::List.new(
46
- raw.map { |element| ::Code::Ruby.to_code(element) }
47
- )
48
- elsif proc?
49
- ::Code::Object::RubyFunction.new(raw)
50
- else
51
- raise "Unsupported class #{raw.class} for Ruby to Code conversion"
52
- end
53
- end
54
-
55
- def from_code
56
- if code?
57
- if code_nothing? || code_boolean? || code_decimal? || code_integer? ||
58
- code_range? || code_string?
59
- raw.raw
60
- elsif code_dictionnary?
61
- raw
62
- .raw
63
- .map do |key, value|
64
- [::Code::Ruby.from_code(key), ::Code::Ruby.from_code(value)]
65
- end
66
- .to_h
67
- elsif code_list?
68
- raw.raw.map { |element| ::Code::Ruby.from_code(element) }
69
- else
70
- raise "Unsupported class #{raw.class} for Code to Ruby conversion"
71
- end
72
- else
73
- raw
74
- end
75
- end
76
-
77
- private
78
-
79
- attr_reader :raw
80
-
81
- def code?
82
- raw.is_a?(::Code::Object)
83
- end
84
-
85
- def nil?
86
- raw.is_a?(::NilClass)
87
- end
88
-
89
- def true?
90
- raw.is_a?(::TrueClass)
91
- end
92
-
93
- def false?
94
- raw.is_a?(::FalseClass)
95
- end
96
-
97
- def hash?
98
- raw.is_a?(::Hash)
99
- end
100
-
101
- def array?
102
- raw.is_a?(::Array)
103
- end
104
-
105
- def string?
106
- raw.is_a?(::String)
107
- end
108
-
109
- def symbol?
110
- raw.is_a?(::Symbol)
111
- end
112
-
113
- def integer?
114
- raw.is_a?(::Integer)
115
- end
116
-
117
- def float?
118
- raw.is_a?(::Float)
119
- end
120
-
121
- def big_decimal?
122
- raw.is_a?(::BigDecimal)
123
- end
124
-
125
- def proc?
126
- raw.is_a?(::Proc)
127
- end
128
-
129
- def code_nothing?
130
- raw.is_a?(::Code::Object::Nothing)
131
- end
132
-
133
- def code_boolean?
134
- raw.is_a?(::Code::Object::Boolean)
135
- end
136
-
137
- def code_decimal?
138
- raw.is_a?(::Code::Object::Decimal)
139
- end
140
-
141
- def code_integer?
142
- raw.is_a?(::Code::Object::Integer)
143
- end
144
-
145
- def code_range?
146
- raw.is_a?(::Code::Object::Range)
147
- end
148
-
149
- def code_string?
150
- raw.is_a?(::Code::Object::String)
151
- end
152
-
153
- def code_dictionnary?
154
- raw.is_a?(::Code::Object::Dictionary)
155
- end
156
-
157
- def code_list?
158
- raw.is_a?(::Code::Object::List)
159
- end
160
- end
161
- end