code-ruby 0.10.4 → 0.11.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.lock +1 -1
- data/bin/console +5 -0
- data/lib/code/node/base_10.rb +10 -10
- data/lib/code/node/base_16.rb +7 -2
- data/lib/code/node/base_2.rb +7 -2
- data/lib/code/node/base_8.rb +7 -2
- data/lib/code/node/boolean.rb +5 -4
- data/lib/code/node/call.rb +10 -16
- data/lib/code/node/call_argument.rb +8 -4
- data/lib/code/node/code.rb +3 -2
- data/lib/code/node/decimal.rb +8 -7
- data/lib/code/node/dictionary.rb +11 -8
- data/lib/code/node/function.rb +4 -8
- data/lib/code/node/function_parameter.rb +3 -3
- data/lib/code/node/if.rb +13 -12
- data/lib/code/node/left_operation.rb +10 -10
- data/lib/code/node/list.rb +3 -3
- data/lib/code/node/negation.rb +8 -4
- data/lib/code/node/not.rb +8 -4
- data/lib/code/node/nothing.rb +4 -3
- data/lib/code/node/number.rb +3 -3
- data/lib/code/node/right_operation.rb +19 -16
- data/lib/code/node/splat.rb +8 -4
- data/lib/code/node/square_bracket.rb +8 -11
- data/lib/code/node/statement.rb +4 -4
- data/lib/code/node/string.rb +13 -11
- data/lib/code/node/ternary.rb +8 -8
- data/lib/code/node/unary_minus.rb +8 -4
- data/lib/code/node/while.rb +15 -13
- data/lib/code/node.rb +1 -7
- data/lib/code/object/function.rb +2 -4
- data/lib/code/object.rb +2 -6
- data/lib/code/parser/code.rb +1 -1
- data/lib/code/parser/left_operation.rb +2 -2
- data/lib/code/parser/list.rb +2 -2
- data/lib/code/parser/right_operation.rb +2 -2
- data/lib/code/parser/whitespace.rb +2 -2
- data/lib/code/type/sig.rb +2 -2
- data/lib/code/type.rb +3 -3
- data/lib/code/version.rb +1 -1
- data/lib/code-ruby.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97ce31f3a36a57e14f607ded3383aa3c71866824c6e57541c70d48962c77b9ef
|
4
|
+
data.tar.gz: '0229023c391084763f03d2ffbfd82af81da2d996666719a49ad169d7740c4d6c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 996b1594dbc1192dbad2b0c64d605d9eccff6d5622437ef5974464648e5f2cd2ee57aad50fce9279f8027f1378fc7c2652106265a2fc79bbe21b224210228c9d
|
7
|
+
data.tar.gz: ec405b4bc88648344f4860fb7350695aa447a5905e9a56e7230c771d5ea76e22515fe74ac0fc30771e27a9d67f4eda85b0d2475484d81a5d2c604c5a901913ae
|
data/Gemfile.lock
CHANGED
data/bin/console
ADDED
data/lib/code/node/base_10.rb
CHANGED
@@ -4,26 +4,26 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Base10 < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@whole = parsed.delete(:whole).presence
|
8
9
|
|
9
10
|
if parsed.key?(:exponent)
|
10
|
-
@exponent = Node::Statement.new(parsed.delete(:exponent))
|
11
|
+
@exponent = Node::Statement.new(parsed.delete(:exponent).presence)
|
11
12
|
end
|
12
|
-
|
13
|
-
super(parsed)
|
14
13
|
end
|
15
14
|
|
16
15
|
def evaluate(**args)
|
17
|
-
if @exponent
|
16
|
+
if @exponent && @whole
|
18
17
|
exponent = @exponent.evaluate(**args)
|
19
|
-
|
20
|
-
|
21
|
-
::Code::Object::Integer.new(@whole.to_i, exponent:)
|
18
|
+
if exponent.is_a?(Object::Integer)
|
19
|
+
Object::Integer.new(@whole, exponent:)
|
22
20
|
else
|
23
|
-
|
21
|
+
Object::Decimal.new(@whole, exponent:)
|
24
22
|
end
|
23
|
+
elsif @whole
|
24
|
+
Object::Integer.new(@whole.to_i)
|
25
25
|
else
|
26
|
-
|
26
|
+
Object::Nothing.new
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
data/lib/code/node/base_16.rb
CHANGED
@@ -4,11 +4,16 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Base16 < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@base_16 = parsed.presence
|
8
9
|
end
|
9
10
|
|
10
11
|
def evaluate(**_args)
|
11
|
-
|
12
|
+
if @base_16
|
13
|
+
Object::Integer.new(@base_16.to_i(16))
|
14
|
+
else
|
15
|
+
Object::Nothing.new
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
14
19
|
end
|
data/lib/code/node/base_2.rb
CHANGED
@@ -4,11 +4,16 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Base2 < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@base_2 = parsed.presence
|
8
9
|
end
|
9
10
|
|
10
11
|
def evaluate(**_args)
|
11
|
-
|
12
|
+
if @base_2
|
13
|
+
Object::Integer.new(@base_2.to_i(2))
|
14
|
+
else
|
15
|
+
Object::Nothing.new
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
14
19
|
end
|
data/lib/code/node/base_8.rb
CHANGED
@@ -4,11 +4,16 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Base8 < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@base_8 = parsed.presence
|
8
9
|
end
|
9
10
|
|
10
11
|
def evaluate(**_args)
|
11
|
-
|
12
|
+
if @base_8
|
13
|
+
Object::Integer.new(@base_8.to_i(8))
|
14
|
+
else
|
15
|
+
Object::Nothing.new
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
14
19
|
end
|
data/lib/code/node/boolean.rb
CHANGED
@@ -7,16 +7,17 @@ class Code
|
|
7
7
|
FALSE_KEYWORD = "false"
|
8
8
|
|
9
9
|
def initialize(parsed)
|
10
|
-
|
10
|
+
return if parsed.blank?
|
11
|
+
@boolean = parsed.presence
|
11
12
|
end
|
12
13
|
|
13
14
|
def evaluate(**_args)
|
14
15
|
if @boolean == TRUE_KEYWORD
|
15
|
-
|
16
|
+
Object::Boolean.new(true)
|
16
17
|
elsif @boolean == FALSE_KEYWORD
|
17
|
-
|
18
|
+
Object::Boolean.new(false)
|
18
19
|
else
|
19
|
-
|
20
|
+
Object::Nothing.new
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
data/lib/code/node/call.rb
CHANGED
@@ -5,14 +5,11 @@ class Code
|
|
5
5
|
class Call < Node
|
6
6
|
class Block < Node
|
7
7
|
def initialize(parsed)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
.map { |parameter| FunctionParameter.new(parameter) }
|
8
|
+
return if parsed.blank?
|
9
|
+
@parameters = parsed.delete(:parameters) { [] }.presence || []
|
10
|
+
@parameters.map! { |parameter| FunctionParameter.new(parameter) }
|
12
11
|
|
13
|
-
@body = Code.new(parsed.delete(:body))
|
14
|
-
|
15
|
-
super(parsed)
|
12
|
+
@body = Code.new(parsed.delete(:body).presence)
|
16
13
|
end
|
17
14
|
|
18
15
|
def evaluate(**_args)
|
@@ -23,21 +20,18 @@ class Code
|
|
23
20
|
end
|
24
21
|
|
25
22
|
def initialize(parsed)
|
26
|
-
|
27
|
-
@
|
28
|
-
|
29
|
-
|
30
|
-
.map { |argument| CallArgument.new(argument) }
|
31
|
-
|
32
|
-
@block = Call::Block.new(parsed.delete(:block)) if parsed.key?(:block)
|
23
|
+
return if parsed.blank?
|
24
|
+
@name = parsed.delete(:name).presence
|
25
|
+
@arguments = parsed.delete(:arguments).presence || []
|
26
|
+
@arguments.map! { |argument| CallArgument.new(argument) }
|
33
27
|
|
34
|
-
|
28
|
+
@block = Call::Block.new(parsed.delete(:block).presence) if parsed.key?(:block)
|
35
29
|
end
|
36
30
|
|
37
31
|
def evaluate(**args)
|
38
32
|
arguments = []
|
39
33
|
|
40
|
-
@arguments.each do |argument|
|
34
|
+
(@arguments || []).each do |argument|
|
41
35
|
if argument.keyword?
|
42
36
|
if arguments.last&.value.is_a?(Object::Dictionary)
|
43
37
|
arguments.last.value.code_set(
|
@@ -4,15 +4,19 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class CallArgument < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
7
|
+
return if parsed.blank?
|
8
|
+
@value = Node::Code.new(parsed.delete(:value).presence)
|
9
|
+
@name = parsed.delete(:name).presence
|
9
10
|
end
|
10
11
|
|
11
12
|
def evaluate(**args)
|
12
13
|
if @name
|
13
|
-
Object::Argument.new(
|
14
|
+
Object::Argument.new(
|
15
|
+
@value&.evaluate(**args) || Object::Nothing.new,
|
16
|
+
name:
|
17
|
+
)
|
14
18
|
else
|
15
|
-
Object::Argument.new(@value
|
19
|
+
Object::Argument.new(@value&.evaluate(**args) || Object::Nothing.new)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
data/lib/code/node/code.rb
CHANGED
@@ -4,13 +4,14 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Code < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@statements = (parsed.presence || []).map { |statement| Statement.new(statement) }
|
8
9
|
end
|
9
10
|
|
10
11
|
def evaluate(**args)
|
11
12
|
last = Object::Nothing.new
|
12
13
|
|
13
|
-
@statements.each do |statement|
|
14
|
+
(@statements || []).each do |statement|
|
14
15
|
last = statement.evaluate(**args.merge(object: Object::Global.new))
|
15
16
|
end
|
16
17
|
|
data/lib/code/node/decimal.rb
CHANGED
@@ -4,23 +4,24 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Decimal < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@decimal = parsed.delete(:decimal).presence
|
8
9
|
|
9
10
|
if parsed.key?(:exponent)
|
10
|
-
@exponent =
|
11
|
+
@exponent = Statement.new(parsed.delete(:exponent).presence)
|
11
12
|
end
|
12
|
-
|
13
|
-
super(parsed)
|
14
13
|
end
|
15
14
|
|
16
15
|
def evaluate(**args)
|
17
|
-
if @exponent
|
18
|
-
|
16
|
+
if @exponent && @decimal
|
17
|
+
Object::Decimal.new(
|
19
18
|
@decimal,
|
20
19
|
exponent: @exponent.evaluate(**args)
|
21
20
|
)
|
21
|
+
elsif @decimal
|
22
|
+
Object::Decimal.new(@decimal)
|
22
23
|
else
|
23
|
-
|
24
|
+
Object::Nothing.new
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
data/lib/code/node/dictionary.rb
CHANGED
@@ -5,17 +5,20 @@ class Code
|
|
5
5
|
class Dictionary < Node
|
6
6
|
class KeyValue < Node
|
7
7
|
def initialize(parsed)
|
8
|
+
return if parsed.blank?
|
8
9
|
if parsed.key?(:statement)
|
9
|
-
@key = Node::Statement.new(parsed.delete(:statement))
|
10
|
+
@key = Node::Statement.new(parsed.delete(:statement).presence)
|
10
11
|
elsif parsed.key?(:name)
|
11
|
-
@key = Node::String.new([{ text: parsed.delete(:name) }])
|
12
|
+
@key = Node::String.new([{ text: parsed.delete(:name).presence }])
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
+
if parsed[:value].presence
|
16
|
+
@value = Node::Code.new(parsed.delete(:value).presence)
|
17
|
+
end
|
15
18
|
end
|
16
19
|
|
17
20
|
def evaluate(**args)
|
18
|
-
key = @key
|
21
|
+
key = @key&.evaluate(**args) || Object::Nothing.new
|
19
22
|
|
20
23
|
if @value
|
21
24
|
value = @value.evaluate(**args)
|
@@ -27,14 +30,14 @@ class Code
|
|
27
30
|
end
|
28
31
|
|
29
32
|
def initialize(parsed)
|
30
|
-
|
31
|
-
@key_values =
|
32
|
-
|
33
|
+
return if parsed.blank?
|
34
|
+
@key_values = parsed.presence || []
|
35
|
+
@key_values.map! { |key_value| Node::Dictionary::KeyValue.new(key_value) }
|
33
36
|
end
|
34
37
|
|
35
38
|
def evaluate(**args)
|
36
39
|
::Code::Object::Dictionary.new(
|
37
|
-
@key_values.map { |key_value| key_value.evaluate(**args) }.to_h
|
40
|
+
(@key_values || []).map { |key_value| key_value.evaluate(**args) }.to_h
|
38
41
|
)
|
39
42
|
end
|
40
43
|
end
|
data/lib/code/node/function.rb
CHANGED
@@ -4,15 +4,11 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Function < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@parameters = []
|
7
|
+
return if parsed.blank?
|
8
|
+
@parameters = parsed.delete(:parameters).presence || []
|
9
|
+
@parameters.map! { |parameter| Node::FunctionParameter.new(parameter) }
|
9
10
|
|
10
|
-
@
|
11
|
-
@parameters.map { |parameter| Node::FunctionParameter.new(parameter) }
|
12
|
-
|
13
|
-
@body = Node::Code.new(parsed.delete(:body))
|
14
|
-
|
15
|
-
super(parsed)
|
11
|
+
@body = Node::Code.new(parsed.delete(:body).presence)
|
16
12
|
end
|
17
13
|
|
18
14
|
def evaluate(**_args)
|
@@ -4,9 +4,9 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class FunctionParameter < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@name = parsed.delete(:name).presence
|
9
|
+
@keyword = parsed.delete(:keyword).present?
|
10
10
|
end
|
11
11
|
|
12
12
|
def name
|
data/lib/code/node/if.rb
CHANGED
@@ -12,22 +12,23 @@ class Code
|
|
12
12
|
attr_reader :operator, :statement, :body
|
13
13
|
|
14
14
|
def initialize(parsed)
|
15
|
-
|
16
|
-
@
|
15
|
+
return if parsed.blank?
|
16
|
+
@operator = parsed.delete(:operator).presence
|
17
|
+
@body = Node::Code.new(parsed.delete(:body).presence)
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
if parsed.key?(:statement)
|
20
|
+
@statement = Node::Statement.new(parsed.delete(:statement).presence)
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
def initialize(parsed)
|
25
|
-
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@
|
29
|
-
|
30
|
-
|
26
|
+
return if parsed.blank?
|
27
|
+
@first_operator = parsed.delete(:first_operator).presence
|
28
|
+
@first_statement = Node::Statement.new(parsed.delete(:first_statement).presence)
|
29
|
+
@first_body = Node::Code.new(parsed.delete(:first_body).presence)
|
30
|
+
@elses = (parsed.delete(:elses).presence || [])
|
31
|
+
@elses.map! { |elses| Node::If::Else.new(elses) }
|
31
32
|
end
|
32
33
|
|
33
34
|
def evaluate(**args)
|
@@ -38,7 +39,7 @@ class Code
|
|
38
39
|
@first_statement.evaluate(**args).falsy?
|
39
40
|
@first_body.evaluate(**args)
|
40
41
|
else
|
41
|
-
@elses.each do |elses|
|
42
|
+
(@elses || []).each do |elses|
|
42
43
|
if elses.operator == ELSIF_KEYWORD &&
|
43
44
|
elses.statement.evaluate(**args).truthy?
|
44
45
|
return elses.body.evaluate(**args)
|
@@ -10,8 +10,9 @@ class Code
|
|
10
10
|
attr_reader :operator, :statement
|
11
11
|
|
12
12
|
def initialize(parsed)
|
13
|
-
|
14
|
-
@
|
13
|
+
return if parsed.blank?
|
14
|
+
@operator = parsed.delete(:operator).presence
|
15
|
+
@statement = Statement.new(parsed.delete(:statement).presence)
|
15
16
|
end
|
16
17
|
|
17
18
|
def call?
|
@@ -20,15 +21,14 @@ class Code
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def initialize(parsed)
|
23
|
-
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
super(parsed)
|
24
|
+
return if parsed.blank?
|
25
|
+
@first = Statement.new(parsed.delete(:first).presence)
|
26
|
+
@others = parsed.delete(:others).presence || []
|
27
|
+
@others.map! { |operator| Operator.new(operator) }
|
28
28
|
end
|
29
29
|
|
30
30
|
def evaluate(**args)
|
31
|
-
first = @first
|
31
|
+
first = @first&.evaluate(**args) || Object::Nothing.new
|
32
32
|
|
33
33
|
@others.reduce(first) do |left, right|
|
34
34
|
if right.call?
|
@@ -46,11 +46,11 @@ class Code
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def resolve(**args)
|
49
|
-
first = @first
|
49
|
+
first = @first&.resolve(**args) || Object::Nothing.new
|
50
50
|
|
51
51
|
list = Object::IdentifierList.new([first])
|
52
52
|
|
53
|
-
@others.each do |other|
|
53
|
+
(@others || []).each do |other|
|
54
54
|
list.code_append(
|
55
55
|
other.statement.resolve(**args, object: list.code_last)
|
56
56
|
)
|
data/lib/code/node/list.rb
CHANGED
@@ -4,13 +4,13 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class List < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@elements = parsed.map { |element| Node::Code.new(element) }
|
7
|
+
return if parsed.blank?
|
8
|
+
@elements = (parsed.presence || []).map { |element| Node::Code.new(element) }
|
9
9
|
end
|
10
10
|
|
11
11
|
def evaluate(**args)
|
12
12
|
::Code::Object::List.new(
|
13
|
-
@elements.map { |element| element.evaluate(**args) }
|
13
|
+
(@elements || []).map { |element| element.evaluate(**args) }
|
14
14
|
)
|
15
15
|
end
|
16
16
|
end
|
data/lib/code/node/negation.rb
CHANGED
@@ -4,13 +4,17 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Negation < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@operator = parsed.delete(:operator).presence
|
9
|
+
@right = Node::Statement.new(parsed.delete(:right).presence)
|
10
10
|
end
|
11
11
|
|
12
12
|
def evaluate(**args)
|
13
|
-
@right
|
13
|
+
if @right
|
14
|
+
@right.evaluate(**args).call(operator: @operator, **args)
|
15
|
+
else
|
16
|
+
Object::Nothing.new
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
data/lib/code/node/not.rb
CHANGED
@@ -4,13 +4,17 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Not < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@operator = parsed.delete(:operator).presence
|
9
|
+
@right = Node::Statement.new(parsed.delete(:right).presence)
|
10
10
|
end
|
11
11
|
|
12
12
|
def evaluate(**args)
|
13
|
-
@right
|
13
|
+
if @right
|
14
|
+
@right.evaluate(**args).call(operator: @operator, **args)
|
15
|
+
else
|
16
|
+
Object::Nothing.new
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
data/lib/code/node/nothing.rb
CHANGED
@@ -3,12 +3,13 @@
|
|
3
3
|
class Code
|
4
4
|
class Node
|
5
5
|
class Nothing < Node
|
6
|
-
def initialize(
|
7
|
-
|
6
|
+
def initialize(parsed)
|
7
|
+
return if parsed.blank?
|
8
|
+
@nothing = parsed.presence
|
8
9
|
end
|
9
10
|
|
10
11
|
def evaluate(**_args)
|
11
|
-
|
12
|
+
Object::Nothing.new
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
data/lib/code/node/number.rb
CHANGED
@@ -4,6 +4,8 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Number < Node
|
6
6
|
def initialize(parsed)
|
7
|
+
return if parsed.blank?
|
8
|
+
|
7
9
|
if parsed.key?(:decimal)
|
8
10
|
@statement = Node::Decimal.new(parsed.delete(:decimal))
|
9
11
|
elsif parsed.key?(:base_16)
|
@@ -15,12 +17,10 @@ class Code
|
|
15
17
|
elsif parsed.key?(:base_2)
|
16
18
|
@statement = Node::Base2.new(parsed.delete(:base_2))
|
17
19
|
end
|
18
|
-
|
19
|
-
super(parsed)
|
20
20
|
end
|
21
21
|
|
22
22
|
def evaluate(**args)
|
23
|
-
@statement
|
23
|
+
@statement&.evaluate(**args) || Object::Nothing.new
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -6,23 +6,22 @@ class Code
|
|
6
6
|
EQUAL = "="
|
7
7
|
|
8
8
|
def initialize(parsed)
|
9
|
-
|
10
|
-
@
|
11
|
-
@
|
12
|
-
|
13
|
-
super(parsed)
|
9
|
+
return if parsed.blank?
|
10
|
+
@left = Statement.new(parsed.delete(:left).presence)
|
11
|
+
@operator = parsed.delete(:operator).presence
|
12
|
+
@right = Statement.new(parsed.delete(:right).presence)
|
14
13
|
end
|
15
14
|
|
16
15
|
def evaluate(**args)
|
17
16
|
case @operator
|
18
17
|
when "if"
|
19
|
-
if @right
|
20
|
-
@left
|
18
|
+
if (@right&.evaluate(**args) || Object::Nothing.new).truthy?
|
19
|
+
@left&.evaluate(**args) || Object::Nothing.new
|
21
20
|
else
|
22
21
|
Object::Nothing.new
|
23
22
|
end
|
24
23
|
when "unless"
|
25
|
-
if @right
|
24
|
+
if (@right&.evaluate(**args) || Object::Nothing.new).truthy?
|
26
25
|
Object::Nothing.new
|
27
26
|
else
|
28
27
|
@left.evaluate(**args)
|
@@ -30,24 +29,28 @@ class Code
|
|
30
29
|
when "while"
|
31
30
|
left = Object::Nothing.new
|
32
31
|
|
33
|
-
|
32
|
+
while (@right&.evaluate(**args) || Object::Nothing.new).truthy?
|
33
|
+
left = @left&.evaluate(**args) || Object::Nothing.new
|
34
|
+
end
|
34
35
|
|
35
36
|
left
|
36
37
|
when "until"
|
37
38
|
left = Object::Nothing.new
|
38
39
|
|
39
|
-
|
40
|
+
while (@right&.evaluate(**args) || Object::Nothing.new).falsy?
|
41
|
+
left = @left&.evaluate(**args) || Object::Nothing.new
|
42
|
+
end
|
40
43
|
|
41
44
|
left
|
42
45
|
when "rescue"
|
43
46
|
begin
|
44
|
-
@left
|
47
|
+
@left&.evaluate(**args) || Object::Nothing.new
|
45
48
|
rescue Error
|
46
|
-
@right
|
49
|
+
@right&.evaluate(**args) || Object::Nothing.new
|
47
50
|
end
|
48
51
|
when /=$/
|
49
|
-
right = @right
|
50
|
-
left = @left
|
52
|
+
right = @right&.evaluate(**args) || Object::Nothing.new
|
53
|
+
left = @left&.resolve(**args) || Object::Nothing.new
|
51
54
|
|
52
55
|
left.call(
|
53
56
|
operator: @operator,
|
@@ -55,8 +58,8 @@ class Code
|
|
55
58
|
**args
|
56
59
|
)
|
57
60
|
else
|
58
|
-
right = @right
|
59
|
-
left = @left
|
61
|
+
right = @right&.evaluate(**args) || Object::Nothing.new
|
62
|
+
left = @left&.evaluate(**args) || Object::Nothing.new
|
60
63
|
|
61
64
|
left.call(
|
62
65
|
operator: @operator,
|
data/lib/code/node/splat.rb
CHANGED
@@ -4,13 +4,17 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Splat < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@operator = parsed.delete(:operator).presence
|
9
|
+
@right = Node::Statement.new(parsed.delete(:right).presence)
|
10
10
|
end
|
11
11
|
|
12
12
|
def evaluate(**args)
|
13
|
-
@right
|
13
|
+
if @right
|
14
|
+
@right.evaluate(**args).call(operator: @operator, **args)
|
15
|
+
else
|
16
|
+
Object::Nothing.new
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
@@ -4,29 +4,26 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class SquareBracket < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
10
|
-
|
11
|
-
.map { |statement| Node::Statement.new(statement) }
|
12
|
-
|
13
|
-
super(parsed)
|
7
|
+
return if parsed.blank?
|
8
|
+
@left = Node::Statement.new(parsed.delete(:left).presence)
|
9
|
+
@statements = parsed.delete(:statements).presence || []
|
10
|
+
@statements.map! { |statement| Node::Statement.new(statement) }
|
14
11
|
end
|
15
12
|
|
16
13
|
def evaluate(**args)
|
17
|
-
left = @left
|
14
|
+
left = @left&.evaluate(**args) || Object::Nothing.new
|
18
15
|
|
19
|
-
@statements.reduce(left) do |object, statement|
|
16
|
+
(@statements || []).reduce(left) do |object, statement|
|
20
17
|
object.code_fetch(statement.evaluate(**args))
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
24
21
|
def resolve(**args)
|
25
|
-
left = @left
|
22
|
+
left = @left&.resolve(**args) || Object::Nothing.new
|
26
23
|
|
27
24
|
list = Object::IdentifierList.new([left])
|
28
25
|
|
29
|
-
@statements.each do |statement|
|
26
|
+
(@statements || []).each do |statement|
|
30
27
|
list.code_append(statement.evaluate(**args))
|
31
28
|
end
|
32
29
|
|
data/lib/code/node/statement.rb
CHANGED
@@ -4,6 +4,8 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Statement < Node
|
6
6
|
def initialize(parsed)
|
7
|
+
return if parsed.blank?
|
8
|
+
|
7
9
|
if parsed.key?(:nothing)
|
8
10
|
@statement = Node::Nothing.new(parsed.delete(:nothing))
|
9
11
|
elsif parsed.key?(:boolean)
|
@@ -51,16 +53,14 @@ class Code
|
|
51
53
|
elsif parsed.key?(:square_bracket)
|
52
54
|
@statement = Node::SquareBracket.new(parsed.delete(:square_bracket))
|
53
55
|
end
|
54
|
-
|
55
|
-
super(parsed)
|
56
56
|
end
|
57
57
|
|
58
58
|
def evaluate(**args)
|
59
|
-
@statement
|
59
|
+
@statement&.evaluate(**args) || Object::Nothing.new
|
60
60
|
end
|
61
61
|
|
62
62
|
def resolve(**args)
|
63
|
-
@statement
|
63
|
+
@statement&.resolve(**args) || Object::Nothing.new
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/code/node/string.rb
CHANGED
@@ -6,22 +6,25 @@ class Code
|
|
6
6
|
class Part < Node
|
7
7
|
class Code < Node
|
8
8
|
def initialize(parsed)
|
9
|
-
|
9
|
+
return if parsed.blank?
|
10
|
+
@code = Node::Code.new(parsed.presence)
|
10
11
|
end
|
11
12
|
|
12
13
|
def evaluate(**args)
|
13
|
-
@code
|
14
|
+
@code&.evaluate(**args) || Object::Nothing.new
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
18
|
class Text < Node
|
18
19
|
def initialize(parsed)
|
20
|
+
return if parsed.blank?
|
19
21
|
@text = parsed
|
20
22
|
end
|
21
23
|
|
22
24
|
def evaluate(**_args)
|
23
25
|
::Code::Object::String.new(
|
24
26
|
@text
|
27
|
+
.to_s
|
25
28
|
.gsub('\n', "\n")
|
26
29
|
.gsub('\r', "\r")
|
27
30
|
.gsub('\t', "\t")
|
@@ -34,29 +37,28 @@ class Code
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def initialize(parsed)
|
40
|
+
return if parsed.blank?
|
41
|
+
|
37
42
|
if parsed.key?(:text)
|
38
|
-
@part = Node::String::Part::Text.new(parsed.delete(:text))
|
43
|
+
@part = Node::String::Part::Text.new(parsed.delete(:text).presence)
|
39
44
|
elsif parsed.key?(:code)
|
40
|
-
@part = Node::String::Part::Code.new(parsed.delete(:code))
|
45
|
+
@part = Node::String::Part::Code.new(parsed.delete(:code).presence)
|
41
46
|
end
|
42
|
-
|
43
|
-
super(parsed)
|
44
47
|
end
|
45
48
|
|
46
49
|
def evaluate(**args)
|
47
|
-
@part
|
50
|
+
@part&.evaluate(**args) || Object::Nothing.new
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
54
|
def initialize(parsed)
|
52
|
-
|
53
|
-
|
54
|
-
@parts = parsed.map { |part| Node::String::Part.new(part) }
|
55
|
+
return if parsed.blank?
|
56
|
+
@parts = (parsed.presence || []).map { |part| Node::String::Part.new(part) }
|
55
57
|
end
|
56
58
|
|
57
59
|
def evaluate(**args)
|
58
60
|
::Code::Object::String.new(
|
59
|
-
@parts.map { |part| part.evaluate(**args) }.map(&:to_s).join
|
61
|
+
(@parts || []).map { |part| part.evaluate(**args) }.map(&:to_s).join
|
60
62
|
)
|
61
63
|
end
|
62
64
|
end
|
data/lib/code/node/ternary.rb
CHANGED
@@ -4,17 +4,17 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class Ternary < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@left = Node::Statement.new(parsed.delete(:left).presence)
|
9
|
+
@middle = Node::Statement.new(parsed.delete(:middle).presence)
|
10
|
+
if parsed.key?(:right)
|
11
|
+
@right = Node::Statement.new(parsed.delete(:right).presence)
|
12
|
+
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def evaluate(**args)
|
16
|
-
if @left
|
17
|
-
@middle
|
16
|
+
if (@left&.evaluate(**args) || Object::Nothing.new).truthy?
|
17
|
+
@middle&.evaluate(**args) || Object::Nothing.new
|
18
18
|
elsif @right
|
19
19
|
@right.evaluate(**args)
|
20
20
|
else
|
@@ -4,13 +4,17 @@ class Code
|
|
4
4
|
class Node
|
5
5
|
class UnaryMinus < Node
|
6
6
|
def initialize(parsed)
|
7
|
-
|
8
|
-
@
|
9
|
-
|
7
|
+
return if parsed.blank?
|
8
|
+
@operator = parsed.delete(:operator).presence
|
9
|
+
@right = Node::Statement.new(parsed.delete(:right).presence)
|
10
10
|
end
|
11
11
|
|
12
12
|
def evaluate(**args)
|
13
|
-
@right
|
13
|
+
if @right
|
14
|
+
@right.evaluate(**args).call(operator: @operator, **args)
|
15
|
+
else
|
16
|
+
Object::Nothing.new
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
data/lib/code/node/while.rb
CHANGED
@@ -8,12 +8,12 @@ class Code
|
|
8
8
|
LOOP_KEYWORD = "loop"
|
9
9
|
|
10
10
|
def initialize(parsed)
|
11
|
-
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
return if parsed.blank?
|
12
|
+
@operator = parsed.delete(:operator).presence
|
13
|
+
if parsed.key?(:statement)
|
14
|
+
@statement = Statement.new(parsed.delete(:statement))
|
15
|
+
end
|
16
|
+
@body = Code.new(parsed.delete(:body).presence)
|
17
17
|
end
|
18
18
|
|
19
19
|
def evaluate(**args)
|
@@ -21,22 +21,24 @@ class Code
|
|
21
21
|
when WHILE_KEYWORD
|
22
22
|
last = Object::Nothing.new
|
23
23
|
|
24
|
-
|
25
|
-
**args
|
26
|
-
|
24
|
+
while (@statement&.evaluate(**args) || Object::Nothing.new).truthy?
|
25
|
+
last = @body&.evaluate(**args) || Object::Nothing.new
|
26
|
+
end
|
27
27
|
|
28
28
|
last
|
29
29
|
when UNTIL_KEYWORD
|
30
30
|
last = Object::Nothing.new
|
31
31
|
|
32
|
-
|
32
|
+
while (@statement&.evaluate(**args) || Object::Nothing.new).falsy?
|
33
|
+
last = @body&.evaluate(**args) || Object::Nothing.new
|
34
|
+
end
|
33
35
|
|
34
36
|
last
|
35
37
|
when LOOP_KEYWORD
|
36
|
-
loop { @body
|
37
|
-
|
38
|
+
loop { @body&.evaluate(**args) || Object::Nothing.new }
|
39
|
+
Object::Nothing.new
|
38
40
|
else
|
39
|
-
|
41
|
+
Object::Nothing.new
|
40
42
|
end
|
41
43
|
rescue Error::Break => e
|
42
44
|
e.value || Object::Nothing.new
|
data/lib/code/node.rb
CHANGED
@@ -2,14 +2,8 @@
|
|
2
2
|
|
3
3
|
class Code
|
4
4
|
class Node
|
5
|
-
def initialize(parsed)
|
6
|
-
return if parsed.nil? || parsed.empty?
|
7
|
-
|
8
|
-
raise NotImplementedError, "#{self.class.name}: #{parsed.inspect}"
|
9
|
-
end
|
10
|
-
|
11
5
|
def evaluate(**_args)
|
12
|
-
|
6
|
+
Object::Nothing.new
|
13
7
|
end
|
14
8
|
|
15
9
|
def resolve(...)
|
data/lib/code/object/function.rb
CHANGED
@@ -6,8 +6,8 @@ class Code
|
|
6
6
|
attr_reader :parameters, :body
|
7
7
|
|
8
8
|
def initialize(parameters:, body:)
|
9
|
-
@parameters = parameters
|
10
|
-
@body = body
|
9
|
+
@parameters = parameters.presence || []
|
10
|
+
@body = body.presence || Node::Code.new
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.name
|
@@ -57,8 +57,6 @@ class Code
|
|
57
57
|
&.value
|
58
58
|
argument = parameter.evaluate(**globals) if argument.nil?
|
59
59
|
context.code_set(parameter.name, argument)
|
60
|
-
else
|
61
|
-
raise NotImplementedError
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
data/lib/code/object.rb
CHANGED
@@ -292,10 +292,6 @@ class Code
|
|
292
292
|
end
|
293
293
|
|
294
294
|
def hash
|
295
|
-
unless respond_to?(:raw)
|
296
|
-
raise NotImplementedError, "#{self.class.name}#hash"
|
297
|
-
end
|
298
|
-
|
299
295
|
[self.class, raw].hash
|
300
296
|
end
|
301
297
|
|
@@ -309,7 +305,7 @@ class Code
|
|
309
305
|
end
|
310
306
|
|
311
307
|
def to_s
|
312
|
-
|
308
|
+
raw.to_s
|
313
309
|
end
|
314
310
|
|
315
311
|
def inspect
|
@@ -325,7 +321,7 @@ class Code
|
|
325
321
|
end
|
326
322
|
|
327
323
|
def as_json(...)
|
328
|
-
|
324
|
+
raw.as_json
|
329
325
|
end
|
330
326
|
end
|
331
327
|
end
|
data/lib/code/parser/code.rb
CHANGED
@@ -4,7 +4,7 @@ class Code
|
|
4
4
|
class Parser
|
5
5
|
class LeftOperation < Language
|
6
6
|
def statement
|
7
|
-
|
7
|
+
Statement
|
8
8
|
end
|
9
9
|
|
10
10
|
def whitespace
|
@@ -16,7 +16,7 @@ class Code
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def operator
|
19
|
-
|
19
|
+
str("")
|
20
20
|
end
|
21
21
|
|
22
22
|
def right_statement
|
data/lib/code/parser/list.rb
CHANGED
@@ -32,8 +32,8 @@ class Code
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def element
|
35
|
-
(whitespace? << code_present << (whitespace? << comma).maybe) |
|
36
|
-
(whitespace? << code << whitespace? << comma)
|
35
|
+
(whitespace? << code_present << (whitespace? << comma.ignore).maybe) |
|
36
|
+
(whitespace? << code << whitespace? << comma.ignore)
|
37
37
|
end
|
38
38
|
|
39
39
|
def root
|
@@ -4,7 +4,7 @@ class Code
|
|
4
4
|
class Parser
|
5
5
|
class RightOperation < Language
|
6
6
|
def statement
|
7
|
-
|
7
|
+
Statement
|
8
8
|
end
|
9
9
|
|
10
10
|
def whitespace
|
@@ -16,7 +16,7 @@ class Code
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def operator
|
19
|
-
|
19
|
+
str("")
|
20
20
|
end
|
21
21
|
|
22
22
|
def right_statement
|
@@ -37,14 +37,14 @@ class Code
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def without_newline
|
40
|
-
(space | multi_line_comment).repeat(1)
|
40
|
+
(space | multi_line_comment).repeat(1).ignore
|
41
41
|
end
|
42
42
|
|
43
43
|
def root
|
44
44
|
(
|
45
45
|
space | newline | hash_comment | double_slash_comment |
|
46
46
|
multi_line_comment
|
47
|
-
).repeat(1) | any.absent
|
47
|
+
).repeat(1).ignore | any.absent
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
data/lib/code/type/sig.rb
CHANGED
data/lib/code/type.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
class Code
|
4
4
|
class Type
|
5
5
|
def name
|
6
|
-
|
6
|
+
"Type"
|
7
7
|
end
|
8
8
|
|
9
|
-
def valid?(
|
10
|
-
|
9
|
+
def valid?(_argument)
|
10
|
+
false
|
11
11
|
end
|
12
12
|
|
13
13
|
def valid_for?(expected:, actual:)
|
data/lib/code/version.rb
CHANGED
data/lib/code-ruby.rb
CHANGED
@@ -4,6 +4,7 @@ require "active_support"
|
|
4
4
|
require "active_support/core_ext/date/conversions"
|
5
5
|
require "active_support/core_ext/numeric/time"
|
6
6
|
require "active_support/core_ext/object/json"
|
7
|
+
require "active_support/core_ext/object/blank"
|
7
8
|
require "bigdecimal"
|
8
9
|
require "json"
|
9
10
|
require "language-ruby"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dorian Marié
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- Gemfile.lock
|
96
96
|
- README.md
|
97
97
|
- bin/code
|
98
|
+
- bin/console
|
98
99
|
- code-ruby.gemspec
|
99
100
|
- lib/code-ruby.rb
|
100
101
|
- lib/code.rb
|