Sha256: 189f7e52c257c377e65a38e8410067b9c0c04482cba173f4d7282daf7b43e3eb

Contents?: true

Size: 1.99 KB

Versions: 1

Compression:

Stored size: 1.99 KB

Contents

module Furnace
  class SSA::InstructionSyntax
    def initialize(klass)
      @klass    = klass
      @operands = []
      @splat    = nil
    end

    def evaluate
      yield self

      codegen
    end

    def operand(name)
      check_for_splat

      @operands << name.to_sym
    end

    def splat(name)
      check_for_splat

      @splat = name.to_sym
    end

    protected

    def check_for_splat
      if @splat
        raise ArgumentError, "There should be at most one splat operand in tail position"
      end
    end

    def codegen
      operands, splat = @operands, @splat

      @klass.class_eval do
        operands.each_with_index do |operand, index|
          define_method(operand) do
            @operands[index]
          end

          define_method(:"#{operand}=") do |value|
            value = value.to_value

            return if @operands[index] == value

            @operands[index].remove_use self if @operands[index]
            @operands[index] = value
            value.add_use self if value

            SSA.instrument(self)

            value
          end
        end

        if splat
          define_method splat do
            @operands[operands.size..-1]
          end

          define_method(:"#{splat}=") do |values|
            values = values.map(&:to_value)

            update_use_lists do
              @operands[operands.size, @operands.size - operands.size] = values
            end

            values
          end
        end

        define_method(:operands=) do |values|
          if splat && values.size < operands.size
            raise ArgumentError, "Not enough operands provided: #{values.size} for #{operands.size}"
          elsif !splat && values.size != operands.size
            raise ArgumentError, "Incorrect number of operands provided: #{values.size} for #{operands.size}"
          end

          values = values.map(&:to_value)

          update_use_lists do
            @operands = values
          end

          values
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
furnace-0.4.0.beta.2 lib/furnace/ssa/instruction_syntax.rb