Sha256: 11e8d09b845aae9617258b170e93a6f93bd622cef994a5d4f80fd2eeb2925c6c

Contents?: true

Size: 1.91 KB

Versions: 3

Compression:

Stored size: 1.91 KB

Contents

# frozen_string_literal: true

class Code
  class Object
    class Function < Object
      attr_reader :parameters, :body

      def initialize(*args, **_kargs, &)
        @parameters = List.new(args.first.presence || [])
        @parameters.raw.map! { |parameter| Parameter.new(parameter) }
        @body = Code.new(args.second.presence || Nothing.new)
        @raw = List.new(parameters, body)
      end

      def call(**args)
        operator = args.fetch(:operator, nil)
        arguments = args.fetch(:arguments, List.new)
        globals = multi_fetch(args, *GLOBALS)

        case operator.to_s
        when "", "call"
          sig(args) { signature_for_call }
          code_call(*arguments.raw, **globals)
        else
          super
        end
      end

      def code_call(*arguments, **globals)
        context = Context.new({}, globals[:context])

        parameters.raw.each.with_index do |parameter, index|
          argument =
            if parameter.keyword?
              arguments
                .detect do |dictionary|
                  dictionary.code_has_value?(parameter.code_name)
                end
                &.code_get(parameter.code_name)
            else
              arguments[index]
            end
          argument = parameter.evaluate(**globals) if argument.nil?
          context.code_set(parameter.code_name, argument)
        end

        body.evaluate(**globals, context:)
      end

      def signature_for_call
        parameters
          .raw
          .inject([]) do |signature, parameter|
            if parameter.keyword?
              if signature.last.is_a?(::Hash)
                signature.last.code_set(parameter.code_name, Object)
                signature
              else
                signature + [{ parameter.code_name => Object }]
              end
            else
              signature + [Object]
            end
          end + [Object.repeat]
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
code-ruby-1.1.3 lib/code/object/function.rb
code-ruby-1.1.1 lib/code/object/function.rb
code-ruby-1.1.0 lib/code/object/function.rb