code-ruby 0.11.0 → 0.13.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 +1 -0
- data/Gemfile.lock +5 -3
- data/Rakefile +5 -0
- data/bin/code +6 -0
- data/lib/code/node/base_10.rb +2 -2
- data/lib/code/node/base_16.rb +1 -5
- data/lib/code/node/base_2.rb +1 -5
- data/lib/code/node/base_8.rb +1 -5
- data/lib/code/node/call.rb +4 -4
- data/lib/code/node/code.rb +2 -1
- data/lib/code/node/decimal.rb +1 -4
- data/lib/code/node/dictionary.rb +6 -2
- data/lib/code/node/function.rb +3 -3
- data/lib/code/node/function_parameter.rb +5 -1
- data/lib/code/node/if.rb +2 -1
- data/lib/code/node/list.rb +2 -1
- data/lib/code/node/statement.rb +23 -23
- data/lib/code/node/string.rb +2 -1
- data/lib/code/object/argument.rb +4 -3
- data/lib/code/object/boolean.rb +4 -24
- data/lib/code/object/class.rb +3 -19
- data/lib/code/object/code.rb +16 -0
- data/lib/code/object/context.rb +6 -9
- data/lib/code/object/date.rb +25 -17
- data/lib/code/object/decimal.rb +30 -38
- data/lib/code/object/dictionary.rb +6 -21
- data/lib/code/object/duration.rb +7 -21
- data/lib/code/object/function.rb +29 -45
- data/lib/code/object/global.rb +56 -40
- data/lib/code/object/identifier_list.rb +0 -4
- data/lib/code/object/integer.rb +23 -46
- data/lib/code/object/json.rb +29 -0
- data/lib/code/object/list.rb +4 -21
- data/lib/code/object/nothing.rb +2 -20
- data/lib/code/object/parameter.rb +51 -0
- data/lib/code/object/range.rb +12 -27
- data/lib/code/object/string.rb +6 -27
- data/lib/code/object/time.rb +14 -24
- data/lib/code/object.rb +155 -15
- data/lib/code/parser.rb +1 -1
- data/lib/code/type.rb +10 -2
- data/lib/code/version.rb +1 -1
- data/lib/code-ruby.rb +6 -0
- data/lib/code.rb +8 -5
- data/spec/code/object/dictionary_spec.rb +0 -2
- data/spec/code_spec.rb +141 -29
- metadata +6 -3
- data/lib/code/object/number.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd20de2ab8f69a2256eb18bd2eea8cc2876d8f828cbdf7c086996934ef8b6eb7
|
4
|
+
data.tar.gz: df97885df1ee89d2e3766090980a1fd8467091b982dacf9c1505cb0684d7b466
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29c23d759b84cfb83e9dbc16913d77c6e2b95b86d3a5a65e2f8571199d58c671810806ed49939fe1e1931446571681c216fa261828b07908c43aa0832dfc8177
|
7
|
+
data.tar.gz: 46cbd45a6b53094ed19e2058728cbf6e76ba2fa34d253de4e6be6083cf61a8c26d84a3d943358311321cd32fd44201a55c00ee8605f2adee8216f46a0cfe715e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
code-ruby (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.
|
30
|
+
i18n (1.14.4)
|
31
31
|
concurrent-ruby (~> 1.0)
|
32
32
|
json (2.7.1)
|
33
|
-
language-ruby (0.
|
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
data/bin/code
CHANGED
@@ -42,6 +42,12 @@ argv =
|
|
42
42
|
"Set timeout in seconds"
|
43
43
|
) { |timeout| options[:timeout] = timeout.to_f }
|
44
44
|
|
45
|
+
opts.on(
|
46
|
+
"-z TIME_ZONE",
|
47
|
+
"--time-zone TIME_ZONE",
|
48
|
+
"Set time zone"
|
49
|
+
) { |time_zone| Time.zone = time_zone }
|
50
|
+
|
45
51
|
opts.on("--profile", "Profile Ruby code") do |_timeout|
|
46
52
|
require "ruby-prof"
|
47
53
|
options[:profile] = true
|
data/lib/code/node/base_10.rb
CHANGED
@@ -16,9 +16,9 @@ class Code
|
|
16
16
|
if @exponent && @whole
|
17
17
|
exponent = @exponent.evaluate(**args)
|
18
18
|
if exponent.is_a?(Object::Integer)
|
19
|
-
Object::Integer.new(@whole, exponent
|
19
|
+
Object::Integer.new(@whole, exponent)
|
20
20
|
else
|
21
|
-
Object::Decimal.new(@whole, exponent
|
21
|
+
Object::Decimal.new(@whole, exponent)
|
22
22
|
end
|
23
23
|
elsif @whole
|
24
24
|
Object::Integer.new(@whole.to_i)
|
data/lib/code/node/base_16.rb
CHANGED
data/lib/code/node/base_2.rb
CHANGED
data/lib/code/node/base_8.rb
CHANGED
data/lib/code/node/call.rb
CHANGED
@@ -13,9 +13,7 @@ class Code
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def evaluate(**_args)
|
16
|
-
Object::Argument.new(
|
17
|
-
Object::Function.new(parameters: @parameters, body: @body)
|
18
|
-
)
|
16
|
+
Object::Argument.new(Object::Function.new(@parameters, @body))
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
@@ -25,7 +23,9 @@ class Code
|
|
25
23
|
@arguments = parsed.delete(:arguments).presence || []
|
26
24
|
@arguments.map! { |argument| CallArgument.new(argument) }
|
27
25
|
|
28
|
-
|
26
|
+
if parsed.key?(:block)
|
27
|
+
@block = Call::Block.new(parsed.delete(:block).presence)
|
28
|
+
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def evaluate(**args)
|
data/lib/code/node/code.rb
CHANGED
@@ -5,7 +5,8 @@ class Code
|
|
5
5
|
class Code < Node
|
6
6
|
def initialize(parsed)
|
7
7
|
return if parsed.blank?
|
8
|
-
@statements =
|
8
|
+
@statements =
|
9
|
+
(parsed.presence || []).map { |statement| Statement.new(statement) }
|
9
10
|
end
|
10
11
|
|
11
12
|
def evaluate(**args)
|
data/lib/code/node/decimal.rb
CHANGED
@@ -14,10 +14,7 @@ class Code
|
|
14
14
|
|
15
15
|
def evaluate(**args)
|
16
16
|
if @exponent && @decimal
|
17
|
-
Object::Decimal.new(
|
18
|
-
@decimal,
|
19
|
-
exponent: @exponent.evaluate(**args)
|
20
|
-
)
|
17
|
+
Object::Decimal.new(@decimal, @exponent.evaluate(**args))
|
21
18
|
elsif @decimal
|
22
19
|
Object::Decimal.new(@decimal)
|
23
20
|
else
|
data/lib/code/node/dictionary.rb
CHANGED
@@ -32,12 +32,16 @@ class Code
|
|
32
32
|
def initialize(parsed)
|
33
33
|
return if parsed.blank?
|
34
34
|
@key_values = parsed.presence || []
|
35
|
-
@key_values.map!
|
35
|
+
@key_values.map! do |key_value|
|
36
|
+
Node::Dictionary::KeyValue.new(key_value)
|
37
|
+
end
|
36
38
|
end
|
37
39
|
|
38
40
|
def evaluate(**args)
|
39
41
|
::Code::Object::Dictionary.new(
|
40
|
-
(@key_values || [])
|
42
|
+
(@key_values || [])
|
43
|
+
.map { |key_value| key_value.evaluate(**args) }
|
44
|
+
.to_h
|
41
45
|
)
|
42
46
|
end
|
43
47
|
end
|
data/lib/code/node/function.rb
CHANGED
@@ -6,13 +6,13 @@ class Code
|
|
6
6
|
def initialize(parsed)
|
7
7
|
return if parsed.blank?
|
8
8
|
@parameters = parsed.delete(:parameters).presence || []
|
9
|
-
@parameters.map! { |parameter|
|
9
|
+
@parameters.map! { |parameter| FunctionParameter.new(parameter) }
|
10
10
|
|
11
|
-
@body =
|
11
|
+
@body = Code.new(parsed.delete(:body).presence)
|
12
12
|
end
|
13
13
|
|
14
14
|
def evaluate(**_args)
|
15
|
-
|
15
|
+
Object::Function.new(@parameters, @body)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -10,7 +10,7 @@ class Code
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def name
|
13
|
-
|
13
|
+
Object::String.new(@name)
|
14
14
|
end
|
15
15
|
|
16
16
|
def regular?
|
@@ -28,6 +28,10 @@ class Code
|
|
28
28
|
def keyword_splat?
|
29
29
|
false
|
30
30
|
end
|
31
|
+
|
32
|
+
def default
|
33
|
+
nil
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
data/lib/code/node/if.rb
CHANGED
@@ -25,7 +25,8 @@ class Code
|
|
25
25
|
def initialize(parsed)
|
26
26
|
return if parsed.blank?
|
27
27
|
@first_operator = parsed.delete(:first_operator).presence
|
28
|
-
@first_statement =
|
28
|
+
@first_statement =
|
29
|
+
Node::Statement.new(parsed.delete(:first_statement).presence)
|
29
30
|
@first_body = Node::Code.new(parsed.delete(:first_body).presence)
|
30
31
|
@elses = (parsed.delete(:elses).presence || [])
|
31
32
|
@elses.map! { |elses| Node::If::Else.new(elses) }
|
data/lib/code/node/list.rb
CHANGED
@@ -5,7 +5,8 @@ class Code
|
|
5
5
|
class List < Node
|
6
6
|
def initialize(parsed)
|
7
7
|
return if parsed.blank?
|
8
|
-
@elements =
|
8
|
+
@elements =
|
9
|
+
(parsed.presence || []).map { |element| Node::Code.new(element) }
|
9
10
|
end
|
10
11
|
|
11
12
|
def evaluate(**args)
|
data/lib/code/node/statement.rb
CHANGED
@@ -7,51 +7,51 @@ class Code
|
|
7
7
|
return if parsed.blank?
|
8
8
|
|
9
9
|
if parsed.key?(:nothing)
|
10
|
-
@statement =
|
10
|
+
@statement = Nothing.new(parsed.delete(:nothing))
|
11
11
|
elsif parsed.key?(:boolean)
|
12
|
-
@statement =
|
12
|
+
@statement = Boolean.new(parsed.delete(:boolean))
|
13
13
|
elsif parsed.key?(:group)
|
14
|
-
@statement =
|
14
|
+
@statement = Code.new(parsed.delete(:group))
|
15
15
|
elsif parsed.key?(:call)
|
16
|
-
@statement =
|
16
|
+
@statement = Call.new(parsed.delete(:call))
|
17
17
|
elsif parsed.key?(:number)
|
18
|
-
@statement =
|
18
|
+
@statement = Number.new(parsed.delete(:number))
|
19
19
|
elsif parsed.key?(:string)
|
20
|
-
@statement =
|
20
|
+
@statement = String.new(parsed.delete(:string))
|
21
21
|
elsif parsed.key?(:list)
|
22
|
-
@statement =
|
22
|
+
@statement = List.new(parsed.delete(:list))
|
23
23
|
elsif parsed.key?(:dictionnary)
|
24
|
-
@statement =
|
24
|
+
@statement = Dictionary.new(parsed.delete(:dictionnary))
|
25
25
|
elsif parsed.key?(:chained_call)
|
26
|
-
@statement =
|
26
|
+
@statement = ChainedCall.new(parsed.delete(:chained_call))
|
27
27
|
elsif parsed.key?(:left_operation)
|
28
|
-
@statement =
|
28
|
+
@statement = LeftOperation.new(parsed.delete(:left_operation))
|
29
29
|
elsif parsed.key?(:right_operation)
|
30
|
-
@statement =
|
30
|
+
@statement = RightOperation.new(parsed.delete(:right_operation))
|
31
31
|
elsif parsed.key?(:function)
|
32
|
-
@statement =
|
32
|
+
@statement = Function.new(parsed.delete(:function))
|
33
33
|
elsif parsed.key?(:negation)
|
34
|
-
@statement =
|
34
|
+
@statement = Negation.new(parsed.delete(:negation))
|
35
35
|
elsif parsed.key?(:power)
|
36
|
-
@statement =
|
36
|
+
@statement = Power.new(parsed.delete(:power))
|
37
37
|
elsif parsed.key?(:unary_minus)
|
38
|
-
@statement =
|
38
|
+
@statement = UnaryMinus.new(parsed.delete(:unary_minus))
|
39
39
|
elsif parsed.key?(:ternary)
|
40
|
-
@statement =
|
40
|
+
@statement = Ternary.new(parsed.delete(:ternary))
|
41
41
|
elsif parsed.key?(:rescue)
|
42
|
-
@statement =
|
42
|
+
@statement = Rescue.new(parsed.delete(:rescue))
|
43
43
|
elsif parsed.key?(:not)
|
44
|
-
@statement =
|
44
|
+
@statement = Not.new(parsed.delete(:not))
|
45
45
|
elsif parsed.key?(:if_modifier)
|
46
|
-
@statement =
|
46
|
+
@statement = IfModifier.new(parsed.delete(:if_modifier))
|
47
47
|
elsif parsed.key?(:if)
|
48
|
-
@statement =
|
48
|
+
@statement = If.new(parsed.delete(:if))
|
49
49
|
elsif parsed.key?(:while)
|
50
|
-
@statement =
|
50
|
+
@statement = While.new(parsed.delete(:while))
|
51
51
|
elsif parsed.key?(:splat)
|
52
|
-
@statement =
|
52
|
+
@statement = Splat.new(parsed.delete(:splat))
|
53
53
|
elsif parsed.key?(:square_bracket)
|
54
|
-
@statement =
|
54
|
+
@statement = SquareBracket.new(parsed.delete(:square_bracket))
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
data/lib/code/node/string.rb
CHANGED
@@ -53,7 +53,8 @@ class Code
|
|
53
53
|
|
54
54
|
def initialize(parsed)
|
55
55
|
return if parsed.blank?
|
56
|
-
@parts =
|
56
|
+
@parts =
|
57
|
+
(parsed.presence || []).map { |part| Node::String::Part.new(part) }
|
57
58
|
end
|
58
59
|
|
59
60
|
def evaluate(**args)
|
data/lib/code/object/argument.rb
CHANGED
@@ -5,9 +5,10 @@ class Code
|
|
5
5
|
class Argument < Object
|
6
6
|
attr_reader :value, :name
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@value =
|
10
|
-
@name =
|
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])
|
11
12
|
end
|
12
13
|
|
13
14
|
def keyword?
|
data/lib/code/object/boolean.rb
CHANGED
@@ -3,14 +3,10 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Boolean < ::Code::Object
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@raw =
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.name
|
13
|
-
"Boolean"
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
raw = args.first || Nothing.new
|
8
|
+
raw = raw.raw if raw.is_a?(Object)
|
9
|
+
@raw = !!raw
|
14
10
|
end
|
15
11
|
|
16
12
|
def call(**args)
|
@@ -45,25 +41,9 @@ class Code
|
|
45
41
|
Boolean.new(raw ^ value.raw)
|
46
42
|
end
|
47
43
|
|
48
|
-
def inspect
|
49
|
-
to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
def succ
|
53
|
-
Boolean.new(!raw)
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_s
|
57
|
-
raw.to_s
|
58
|
-
end
|
59
|
-
|
60
44
|
def truthy?
|
61
45
|
raw
|
62
46
|
end
|
63
|
-
|
64
|
-
def as_json(...)
|
65
|
-
raw.as_json(...)
|
66
|
-
end
|
67
47
|
end
|
68
48
|
end
|
69
49
|
end
|
data/lib/code/object/class.rb
CHANGED
@@ -3,32 +3,16 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Class < Object
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(raw)
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
raw = args.first || Nothing.new
|
9
8
|
raw = raw.raw if raw.is_a?(Class)
|
9
|
+
raw = raw.class if raw.is_an?(Object)
|
10
10
|
@raw = raw
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(...)
|
14
14
|
raw.call(...)
|
15
15
|
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
raw.name
|
19
|
-
end
|
20
|
-
|
21
|
-
def inspect
|
22
|
-
to_s
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.name
|
26
|
-
"Class"
|
27
|
-
end
|
28
|
-
|
29
|
-
def as_json(...)
|
30
|
-
raw.name.as_json(...)
|
31
|
-
end
|
32
16
|
end
|
33
17
|
end
|
34
18
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Object
|
5
|
+
class Code < Object
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
raw = args.first.presence || Nothing.new
|
8
|
+
@raw = raw.is_a?(Node) ? raw : Node::Code.new(::Code.parse(raw.to_s))
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate(...)
|
12
|
+
raw.evaluate(...)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/code/object/context.rb
CHANGED
@@ -5,14 +5,11 @@ class Code
|
|
5
5
|
class Context < Dictionary
|
6
6
|
attr_reader :parent
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
raw =
|
8
|
+
def initialize(*args, **_kargs, &_block)
|
9
|
+
raw = args.first || Dictionary.new
|
10
|
+
raw = raw.raw if raw.is_a?(Object)
|
10
11
|
@raw = raw.to_h
|
11
|
-
@parent =
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.name
|
15
|
-
"Context"
|
12
|
+
@parent = Context.new(args.second) if args.second
|
16
13
|
end
|
17
14
|
|
18
15
|
def lookup!(identifier)
|
@@ -21,12 +18,12 @@ class Code
|
|
21
18
|
elsif parent?
|
22
19
|
parent.lookup!(identifier)
|
23
20
|
else
|
24
|
-
|
21
|
+
raise Error::Undefined, "#{identifier} is not defined"
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
25
|
def merge(other)
|
29
|
-
Context.new(raw.merge(other.raw), parent
|
26
|
+
Context.new(raw.merge(other.raw), parent || other.parent)
|
30
27
|
end
|
31
28
|
|
32
29
|
def parent?
|
data/lib/code/object/date.rb
CHANGED
@@ -3,15 +3,11 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Date < Object
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.name
|
14
|
-
"Date"
|
6
|
+
def initialize(*args, **_kargs, &_block)
|
7
|
+
raw = args.map(&:to_s).join("-").presence || ::Date.current.to_s
|
8
|
+
@raw = ::Date.parse(raw)
|
9
|
+
rescue ::Date::Error
|
10
|
+
raise Error, "#{raw.inspect} is an invalid date"
|
15
11
|
end
|
16
12
|
|
17
13
|
def self.call(**args)
|
@@ -21,26 +17,38 @@ class Code
|
|
21
17
|
when "tomorrow"
|
22
18
|
sig(args)
|
23
19
|
code_tomorrow
|
20
|
+
when "yesterday"
|
21
|
+
sig(args)
|
22
|
+
code_yesterday
|
23
|
+
when "today"
|
24
|
+
sig(args)
|
25
|
+
code_today
|
26
|
+
when "now"
|
27
|
+
sig(args)
|
28
|
+
code_now
|
24
29
|
else
|
25
30
|
super
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
29
|
-
def self.
|
34
|
+
def self.code_now
|
30
35
|
::Time.zone ||= Time::DEFAULT_ZONE
|
31
|
-
new(::Time.zone.
|
36
|
+
new(::Time.zone.now.beginning_of_day)
|
32
37
|
end
|
33
38
|
|
34
|
-
def
|
35
|
-
|
39
|
+
def self.code_today
|
40
|
+
::Time.zone ||= Time::DEFAULT_ZONE
|
41
|
+
new(::Time.zone.now.beginning_of_day)
|
36
42
|
end
|
37
43
|
|
38
|
-
def
|
39
|
-
|
44
|
+
def self.code_tomorrow
|
45
|
+
::Time.zone ||= Time::DEFAULT_ZONE
|
46
|
+
new(::Time.zone.tomorrow.beginning_of_day)
|
40
47
|
end
|
41
48
|
|
42
|
-
def
|
43
|
-
|
49
|
+
def self.code_yesterday
|
50
|
+
::Time.zone ||= Time::DEFAULT_ZONE
|
51
|
+
new(::Time.zone.yesterday.beginning_of_day)
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|