code-ruby 0.10.4 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/bin/code +6 -0
  4. data/bin/console +5 -0
  5. data/lib/code/node/base_10.rb +10 -10
  6. data/lib/code/node/base_16.rb +3 -2
  7. data/lib/code/node/base_2.rb +3 -2
  8. data/lib/code/node/base_8.rb +3 -2
  9. data/lib/code/node/boolean.rb +5 -4
  10. data/lib/code/node/call.rb +13 -19
  11. data/lib/code/node/call_argument.rb +8 -4
  12. data/lib/code/node/code.rb +4 -2
  13. data/lib/code/node/decimal.rb +8 -10
  14. data/lib/code/node/dictionary.rb +15 -8
  15. data/lib/code/node/function.rb +5 -9
  16. data/lib/code/node/function_parameter.rb +8 -4
  17. data/lib/code/node/if.rb +14 -12
  18. data/lib/code/node/left_operation.rb +10 -10
  19. data/lib/code/node/list.rb +4 -3
  20. data/lib/code/node/negation.rb +8 -4
  21. data/lib/code/node/not.rb +8 -4
  22. data/lib/code/node/nothing.rb +4 -3
  23. data/lib/code/node/number.rb +3 -3
  24. data/lib/code/node/right_operation.rb +19 -16
  25. data/lib/code/node/splat.rb +8 -4
  26. data/lib/code/node/square_bracket.rb +8 -11
  27. data/lib/code/node/statement.rb +27 -27
  28. data/lib/code/node/string.rb +14 -11
  29. data/lib/code/node/ternary.rb +8 -8
  30. data/lib/code/node/unary_minus.rb +8 -4
  31. data/lib/code/node/while.rb +15 -13
  32. data/lib/code/node.rb +1 -7
  33. data/lib/code/object/argument.rb +4 -3
  34. data/lib/code/object/boolean.rb +5 -4
  35. data/lib/code/object/class.rb +4 -3
  36. data/lib/code/object/code.rb +33 -0
  37. data/lib/code/object/context.rb +7 -5
  38. data/lib/code/object/date.rb +31 -6
  39. data/lib/code/object/decimal.rb +36 -31
  40. data/lib/code/object/dictionary.rb +4 -4
  41. data/lib/code/object/duration.rb +8 -5
  42. data/lib/code/object/function.rb +42 -28
  43. data/lib/code/object/global.rb +58 -38
  44. data/lib/code/object/integer.rb +23 -26
  45. data/lib/code/object/list.rb +5 -5
  46. data/lib/code/object/nothing.rb +2 -4
  47. data/lib/code/object/parameter.rb +43 -0
  48. data/lib/code/object/range.rb +13 -11
  49. data/lib/code/object/string.rb +7 -7
  50. data/lib/code/object/time.rb +15 -8
  51. data/lib/code/object.rb +104 -11
  52. data/lib/code/parser/code.rb +1 -1
  53. data/lib/code/parser/left_operation.rb +2 -2
  54. data/lib/code/parser/list.rb +2 -2
  55. data/lib/code/parser/right_operation.rb +2 -2
  56. data/lib/code/parser/whitespace.rb +2 -2
  57. data/lib/code/parser.rb +1 -1
  58. data/lib/code/type/sig.rb +2 -2
  59. data/lib/code/type.rb +12 -4
  60. data/lib/code/version.rb +1 -1
  61. data/lib/code-ruby.rb +7 -0
  62. data/lib/code.rb +8 -5
  63. data/spec/code/object/dictionary_spec.rb +0 -2
  64. data/spec/code_spec.rb +122 -16
  65. metadata +5 -3
  66. data/lib/code/object/number.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fb166c32bc6cf7c79dd6e1743329312c9a922efc1cfb111a00cc3d87cac9c41
4
- data.tar.gz: 284f096cf17419c0688b36d000e77350580fb7f3ce7ad3ad221e6e1589e1ab4c
3
+ metadata.gz: b04f0e4774e945bbf969c0159eaf23db99d9208faa98e4ae2ed575c1a363baf9
4
+ data.tar.gz: bf3de392fa1af6540d653d35248089d49b39da4addfd539e7594e0ac66c15def
5
5
  SHA512:
6
- metadata.gz: 3d294d5f00bd9f474585eb25392122a355e4202b99a4d62045e5237880c7835d555b8cd43b07c3791d0471c98c32587a7491d05aab14fcbd50daf0cd2268c958
7
- data.tar.gz: 38785eb41a2a7c28a421e8d0be54bd6cda5bf042503d9b31c2c3141a163877b68433141307520ab4cf666a5762f3c0f2b66d951ba03102374eec51a6531c500b
6
+ metadata.gz: 05a921e1f388872311df4f61df4dcf808cc1d4bdaccbf2bdbdd65cc58b5495edac205c003397c83254f257a9ad114b093f2470018dc12fc4d7998ae7e1feaa7d
7
+ data.tar.gz: f856f404a8bebf4d802d2d0ab427e091f5c556da3cd24c3f583a09bf646dedef086e31b933c8933f86868ec9b501d1594f8d7e5272bcdbf1a7dea9571e825cf6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code-ruby (0.10.3)
4
+ code-ruby (0.11.0)
5
5
  activesupport (~> 7)
6
6
  bigdecimal (~> 3)
7
7
  json (~> 2)
@@ -30,7 +30,7 @@ GEM
30
30
  i18n (1.14.1)
31
31
  concurrent-ruby (~> 1.0)
32
32
  json (2.7.1)
33
- language-ruby (0.7.0)
33
+ language-ruby (0.8.0)
34
34
  zeitwerk (~> 2)
35
35
  minitest (5.22.2)
36
36
  mutex_m (0.2.0)
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/bin/console ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/code-ruby"
4
+
5
+ binding.irb
@@ -4,26 +4,26 @@ class Code
4
4
  class Node
5
5
  class Base10 < Node
6
6
  def initialize(parsed)
7
- @whole = parsed.delete(:whole)
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
- if exponent.is_a?(::Code::Object::Integer)
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
- ::Code::Object::Decimal.new(@whole, exponent:)
21
+ Object::Decimal.new(@whole, exponent)
24
22
  end
23
+ elsif @whole
24
+ Object::Integer.new(@whole.to_i)
25
25
  else
26
- ::Code::Object::Integer.new(@whole.to_i)
26
+ Object::Nothing.new
27
27
  end
28
28
  end
29
29
  end
@@ -4,11 +4,12 @@ class Code
4
4
  class Node
5
5
  class Base16 < Node
6
6
  def initialize(parsed)
7
- @base_16 = parsed
7
+ return if parsed.blank?
8
+ @base_16 = parsed.presence
8
9
  end
9
10
 
10
11
  def evaluate(**_args)
11
- ::Code::Object::Integer.new(@base_16.to_i(16))
12
+ @base_16 ? Object::Integer.new(@base_16.to_i(16)) : Object::Nothing.new
12
13
  end
13
14
  end
14
15
  end
@@ -4,11 +4,12 @@ class Code
4
4
  class Node
5
5
  class Base2 < Node
6
6
  def initialize(parsed)
7
- @base_2 = parsed
7
+ return if parsed.blank?
8
+ @base_2 = parsed.presence
8
9
  end
9
10
 
10
11
  def evaluate(**_args)
11
- ::Code::Object::Integer.new(@base_2.to_i(2))
12
+ @base_2 ? Object::Integer.new(@base_2.to_i(2)) : Object::Nothing.new
12
13
  end
13
14
  end
14
15
  end
@@ -4,11 +4,12 @@ class Code
4
4
  class Node
5
5
  class Base8 < Node
6
6
  def initialize(parsed)
7
- @base_8 = parsed
7
+ return if parsed.blank?
8
+ @base_8 = parsed.presence
8
9
  end
9
10
 
10
11
  def evaluate(**_args)
11
- ::Code::Object::Integer.new(@base_8.to_i(8))
12
+ @base_8 ? Object::Integer.new(@base_8.to_i(8)) : Object::Nothing.new
12
13
  end
13
14
  end
14
15
  end
@@ -7,16 +7,17 @@ class Code
7
7
  FALSE_KEYWORD = "false"
8
8
 
9
9
  def initialize(parsed)
10
- @boolean = parsed
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
- ::Code::Object::Boolean.new(true)
16
+ Object::Boolean.new(true)
16
17
  elsif @boolean == FALSE_KEYWORD
17
- ::Code::Object::Boolean.new(false)
18
+ Object::Boolean.new(false)
18
19
  else
19
- raise NotImplementedError, @boolean
20
+ Object::Nothing.new
20
21
  end
21
22
  end
22
23
  end
@@ -5,39 +5,33 @@ class Code
5
5
  class Call < Node
6
6
  class Block < Node
7
7
  def initialize(parsed)
8
- @parameters =
9
- parsed
10
- .delete(:parameters) { [] }
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)
19
- Object::Argument.new(
20
- Object::Function.new(parameters: @parameters, body: @body)
21
- )
16
+ Object::Argument.new(Object::Function.new(@parameters, @body))
22
17
  end
23
18
  end
24
19
 
25
20
  def initialize(parsed)
26
- @name = parsed.delete(:name)
27
- @arguments =
28
- parsed
29
- .delete(:arguments) { [] }
30
- .map { |argument| CallArgument.new(argument) }
31
-
32
- @block = Call::Block.new(parsed.delete(:block)) if parsed.key?(:block)
21
+ return if parsed.blank?
22
+ @name = parsed.delete(:name).presence
23
+ @arguments = parsed.delete(:arguments).presence || []
24
+ @arguments.map! { |argument| CallArgument.new(argument) }
33
25
 
34
- super(parsed)
26
+ if parsed.key?(:block)
27
+ @block = Call::Block.new(parsed.delete(:block).presence)
28
+ end
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
- @value = Node::Code.new(parsed.delete(:value))
8
- @name = parsed.delete(:name)
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(@value.evaluate(**args), name:)
14
+ Object::Argument.new(
15
+ @value&.evaluate(**args) || Object::Nothing.new,
16
+ name:
17
+ )
14
18
  else
15
- Object::Argument.new(@value.evaluate(**args))
19
+ Object::Argument.new(@value&.evaluate(**args) || Object::Nothing.new)
16
20
  end
17
21
  end
18
22
 
@@ -4,13 +4,15 @@ class Code
4
4
  class Node
5
5
  class Code < Node
6
6
  def initialize(parsed)
7
- @statements = parsed.map { |statement| Statement.new(statement) }
7
+ return if parsed.blank?
8
+ @statements =
9
+ (parsed.presence || []).map { |statement| Statement.new(statement) }
8
10
  end
9
11
 
10
12
  def evaluate(**args)
11
13
  last = Object::Nothing.new
12
14
 
13
- @statements.each do |statement|
15
+ (@statements || []).each do |statement|
14
16
  last = statement.evaluate(**args.merge(object: Object::Global.new))
15
17
  end
16
18
 
@@ -4,23 +4,21 @@ class Code
4
4
  class Node
5
5
  class Decimal < Node
6
6
  def initialize(parsed)
7
- @decimal = parsed.delete(:decimal)
7
+ return if parsed.blank?
8
+ @decimal = parsed.delete(:decimal).presence
8
9
 
9
10
  if parsed.key?(:exponent)
10
- @exponent = Node::Statement.new(parsed.delete(: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
- ::Code::Object::Decimal.new(
19
- @decimal,
20
- exponent: @exponent.evaluate(**args)
21
- )
16
+ if @exponent && @decimal
17
+ Object::Decimal.new(@decimal, @exponent.evaluate(**args))
18
+ elsif @decimal
19
+ Object::Decimal.new(@decimal)
22
20
  else
23
- ::Code::Object::Decimal.new(@decimal)
21
+ Object::Nothing.new
24
22
  end
25
23
  end
26
24
  end
@@ -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
- @value = Node::Code.new(parsed.delete(:value)) if parsed[:value]
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.evaluate(**args)
21
+ key = @key&.evaluate(**args) || Object::Nothing.new
19
22
 
20
23
  if @value
21
24
  value = @value.evaluate(**args)
@@ -27,14 +30,18 @@ class Code
27
30
  end
28
31
 
29
32
  def initialize(parsed)
30
- parsed = [] if parsed == ""
31
- @key_values =
32
- parsed.map { |key_value| Node::Dictionary::KeyValue.new(key_value) }
33
+ return if parsed.blank?
34
+ @key_values = parsed.presence || []
35
+ @key_values.map! do |key_value|
36
+ Node::Dictionary::KeyValue.new(key_value)
37
+ end
33
38
  end
34
39
 
35
40
  def evaluate(**args)
36
41
  ::Code::Object::Dictionary.new(
37
- @key_values.map { |key_value| key_value.evaluate(**args) }.to_h
42
+ (@key_values || [])
43
+ .map { |key_value| key_value.evaluate(**args) }
44
+ .to_h
38
45
  )
39
46
  end
40
47
  end
@@ -4,19 +4,15 @@ class Code
4
4
  class Node
5
5
  class Function < Node
6
6
  def initialize(parsed)
7
- @parameters = parsed.delete(:parameters) { [] }
8
- @parameters = [] if @parameters.empty?
7
+ return if parsed.blank?
8
+ @parameters = parsed.delete(:parameters).presence || []
9
+ @parameters.map! { |parameter| FunctionParameter.new(parameter) }
9
10
 
10
- @parameters =
11
- @parameters.map { |parameter| Node::FunctionParameter.new(parameter) }
12
-
13
- @body = Node::Code.new(parsed.delete(:body))
14
-
15
- super(parsed)
11
+ @body = Code.new(parsed.delete(:body).presence)
16
12
  end
17
13
 
18
14
  def evaluate(**_args)
19
- ::Code::Object::Function.new(parameters: @parameters, body: @body)
15
+ Object::Function.new(@parameters, @body)
20
16
  end
21
17
  end
22
18
  end
@@ -4,13 +4,13 @@ class Code
4
4
  class Node
5
5
  class FunctionParameter < Node
6
6
  def initialize(parsed)
7
- @name = parsed.delete(:name)
8
- @keyword = !parsed.delete(:keyword).nil?
9
- super(parsed)
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
13
- ::Code::Object::String.new(@name)
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
@@ -12,22 +12,24 @@ class Code
12
12
  attr_reader :operator, :statement, :body
13
13
 
14
14
  def initialize(parsed)
15
- @operator = parsed.delete(:operator)
16
- @body = Node::Code.new(parsed.delete(:body))
15
+ return if parsed.blank?
16
+ @operator = parsed.delete(:operator).presence
17
+ @body = Node::Code.new(parsed.delete(:body).presence)
17
18
 
18
- return unless parsed.key?(:statement)
19
-
20
- @statement = Node::Statement.new(parsed.delete(:statement))
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
- @first_operator = parsed.delete(:first_operator)
26
- @first_statement = Node::Statement.new(parsed.delete(:first_statement))
27
- @first_body = Node::Code.new(parsed.delete(:first_body))
28
- @elses =
29
- parsed.delete(:elses) { [] }.map { |elses| Node::If::Else.new(elses) }
30
- super(parsed)
26
+ return if parsed.blank?
27
+ @first_operator = parsed.delete(:first_operator).presence
28
+ @first_statement =
29
+ Node::Statement.new(parsed.delete(:first_statement).presence)
30
+ @first_body = Node::Code.new(parsed.delete(:first_body).presence)
31
+ @elses = (parsed.delete(:elses).presence || [])
32
+ @elses.map! { |elses| Node::If::Else.new(elses) }
31
33
  end
32
34
 
33
35
  def evaluate(**args)
@@ -38,7 +40,7 @@ class Code
38
40
  @first_statement.evaluate(**args).falsy?
39
41
  @first_body.evaluate(**args)
40
42
  else
41
- @elses.each do |elses|
43
+ (@elses || []).each do |elses|
42
44
  if elses.operator == ELSIF_KEYWORD &&
43
45
  elses.statement.evaluate(**args).truthy?
44
46
  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
- @operator = parsed.delete(:operator)
14
- @statement = Statement.new(parsed.delete(:statement))
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
- @first = Statement.new(parsed.delete(:first))
24
- @others =
25
- parsed.delete(:others).map { |operator| Operator.new(operator) }
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.evaluate(**args)
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.resolve(**args)
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
  )
@@ -4,13 +4,14 @@ class Code
4
4
  class Node
5
5
  class List < Node
6
6
  def initialize(parsed)
7
- parsed = [] if parsed == ""
8
- @elements = parsed.map { |element| Node::Code.new(element) }
7
+ return if parsed.blank?
8
+ @elements =
9
+ (parsed.presence || []).map { |element| Node::Code.new(element) }
9
10
  end
10
11
 
11
12
  def evaluate(**args)
12
13
  ::Code::Object::List.new(
13
- @elements.map { |element| element.evaluate(**args) }
14
+ (@elements || []).map { |element| element.evaluate(**args) }
14
15
  )
15
16
  end
16
17
  end
@@ -4,13 +4,17 @@ class Code
4
4
  class Node
5
5
  class Negation < Node
6
6
  def initialize(parsed)
7
- @operator = parsed.delete(:operator)
8
- @right = Node::Statement.new(parsed.delete(:right))
9
- super(parsed)
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.evaluate(**args).call(operator: @operator, arguments: [], **args)
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
- @operator = parsed.delete(:operator)
8
- @right = Node::Statement.new(parsed.delete(:right))
9
- super(parsed)
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.evaluate(**args).call(operator: @operator, arguments: [], **args)
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
@@ -3,12 +3,13 @@
3
3
  class Code
4
4
  class Node
5
5
  class Nothing < Node
6
- def initialize(nothing)
7
- @nothing = nothing
6
+ def initialize(parsed)
7
+ return if parsed.blank?
8
+ @nothing = parsed.presence
8
9
  end
9
10
 
10
11
  def evaluate(**_args)
11
- ::Code::Object::Nothing.new
12
+ Object::Nothing.new
12
13
  end
13
14
  end
14
15
  end
@@ -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.evaluate(**args)
23
+ @statement&.evaluate(**args) || Object::Nothing.new
24
24
  end
25
25
  end
26
26
  end