code-ruby 0.11.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|