module Risc

  def self.operators
    [:+, :-, :>>, :<<, :*, :&, :|]
  end

  # Operator instructions on the first two registers given
  # # Result into the last register
  #
  # result = left OP right
  #
  # With OP being the normal logical and mathematical operations provided by
  # cpus. Ie  "+" , "-", ">>", "<<", "*", "&", "|"
  #
  # Result may be nil, then register is autogenerated
  #
  class OperatorInstruction < Instruction
    def initialize( source , operator , left , right , result = nil)
      super(source)
      operator = operator.value if operator.is_a?(Sol::Constant)
      @operator = operator
      raise "unsuported operator :#{operator}:#{operator.class}:" unless Risc.operators.include?(operator)
      @left = left
      @right = right
      raise "Not register #{left}" unless left.is_a?(RegisterValue)
      raise "Not register #{right}" unless right.is_a?(RegisterValue)
      unless result
        result = RegisterValue.new("op_#{operator}_#{object_id.to_s(16)}".to_sym , :Integer)
      end
      raise "Not register #{result}" unless result.is_a?(RegisterValue)
      @result = result
    end
    attr_reader :operator, :left , :right , :result

    def to_s
      class_source "#{left} #{operator} #{right}"
    end

  end
  def self.op( source , operator , left , right , result = nil)
    OperatorInstruction.new( source , operator , left , right , result)
  end

end