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
         |