2017-01-19 08:02:29 +01:00
|
|
|
module Risc
|
2015-10-23 20:27:36 +02:00
|
|
|
|
|
|
|
# A label is a placeholder for it's next Instruction
|
|
|
|
# It's function is not to turn into code, but to be a valid brnch target
|
|
|
|
#
|
|
|
|
# So branches and Labels are pairs, fan out, fan in
|
|
|
|
#
|
|
|
|
#
|
|
|
|
|
|
|
|
class Label < Instruction
|
2016-12-28 18:01:58 +01:00
|
|
|
def initialize( source , name , nekst = nil)
|
2015-10-23 20:27:36 +02:00
|
|
|
super(source , nekst)
|
|
|
|
@name = name
|
|
|
|
end
|
|
|
|
attr_reader :name
|
|
|
|
|
|
|
|
def to_s
|
2018-03-22 17:38:19 +01:00
|
|
|
class_source "#{@name} (next: #{self.next.class.name.split("::").last})"
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
2016-12-28 20:40:06 +01:00
|
|
|
|
2015-11-14 21:53:01 +01:00
|
|
|
def sof_reference_name
|
2015-11-14 23:35:43 +01:00
|
|
|
@name
|
2015-11-14 21:53:01 +01:00
|
|
|
end
|
2015-10-23 20:27:36 +02:00
|
|
|
|
2015-11-03 15:22:24 +01:00
|
|
|
# a method start has a label of the form Class.method , test for that
|
|
|
|
def is_method
|
|
|
|
@name.split(".").length == 2
|
|
|
|
end
|
|
|
|
|
2017-01-04 20:32:09 +01:00
|
|
|
def to_arr labels = []
|
2015-10-23 20:27:36 +02:00
|
|
|
return [] if labels.include?(self)
|
|
|
|
labels << self
|
2015-10-24 16:12:36 +02:00
|
|
|
super
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def length labels = []
|
|
|
|
return 0 if labels.include?(self)
|
|
|
|
labels << self
|
2015-10-24 16:12:36 +02:00
|
|
|
ret = 1
|
|
|
|
ret += self.next.length(labels) if self.next
|
|
|
|
ret
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
|
|
|
|
2015-10-25 09:54:19 +01:00
|
|
|
def assemble io
|
|
|
|
end
|
|
|
|
|
|
|
|
def assemble_all io , labels = []
|
2018-03-21 11:32:46 +01:00
|
|
|
return if labels.include?(self) or self.next.nil?
|
2015-10-25 09:54:19 +01:00
|
|
|
labels << self
|
|
|
|
self.next.assemble_all(io,labels)
|
2015-10-24 16:12:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def total_byte_length labels = []
|
2018-03-21 11:32:46 +01:00
|
|
|
return 0 if labels.include?(self) or self.next.nil?
|
2015-10-24 16:12:36 +02:00
|
|
|
labels << self
|
2015-10-25 09:54:19 +01:00
|
|
|
ret = self.next.total_byte_length(labels)
|
|
|
|
#puts "#{self.class.name} return #{ret}"
|
|
|
|
ret
|
2015-10-24 16:12:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# labels have the same position as their next
|
|
|
|
def set_position position , labels = []
|
|
|
|
return position if labels.include?(self)
|
|
|
|
labels << self
|
2016-12-28 20:40:06 +01:00
|
|
|
super(position , labels)
|
2018-03-21 11:32:46 +01:00
|
|
|
self.next.set_position(position,labels) if self.next
|
2015-10-24 16:12:36 +02:00
|
|
|
end
|
2015-10-25 11:03:31 +01:00
|
|
|
|
2015-11-03 15:22:24 +01:00
|
|
|
# shame we need this, just for logging
|
|
|
|
def byte_length
|
|
|
|
0
|
|
|
|
end
|
|
|
|
|
2015-10-25 11:03:31 +01:00
|
|
|
def each_label labels =[] , &block
|
|
|
|
return if labels.include?(self)
|
|
|
|
labels << self
|
|
|
|
block.yield(self)
|
|
|
|
super
|
|
|
|
end
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
2016-12-28 18:01:58 +01:00
|
|
|
|
|
|
|
def self.label( source , name , nekst = nil)
|
|
|
|
Label.new( source , name , nekst = nil)
|
|
|
|
end
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|