compiler/asm/symtab.rb

98 lines
2.2 KiB
Ruby

module Assembler
# Abstract symbol table.
#
# Basically a big map of variable, constant, and label names to
# offsets within their respective sections. Final addresses are
# calculated from these offsets on the 2nd pass when we know where
# things will actually live in memory.
class Symtab
attr_accessor :text_offset, :bss_offset, :const_offset
attr_reader :const_data, :const_size, :bss_size, :reloc_info
def initialize
@vars = {} # Map of variable names to offsets. (bss vars)
@consts = {} # Map of constant names to offsets.
@funcs = {} # map of function names to offsets.
# Initial data to load into memory (data for __DATA segment).
@const_data = ''
@const_size = 0 # Size of const section.
@bss_size = 0 # Size of bss section.
# Map names to locations.
@labels = Hash.new {|h, key| raise "undefined label: #{key}"}
@num_labels = 0 # Used to generate unique labels.
@num_labels_with_suffix = Hash.new(0)
# Relocation info. Subclasses should define a reloc method.
@reloc_info = []
@text_offset = 0
@bss_offset = 0
@const_offset = 0
end
# Generate a unique label.
def unique_label(suffix=nil)
@num_labels += 1
if suffix
@num_labels_with_suffix[suffix] += 1
suffix = "_#{suffix}_#{@num_labels_with_suffix[suffix]}"
end
name = "L#{sprintf "%06d", @num_labels}#{suffix}"
return name
end
def deflabel(name, offset)
@labels[name] = offset
return name
end
def lookup_label(name)
@labels[name]
end
def defvar(name, bytes)
@vars[name] = @bss_size
@bss_size += bytes
end
def defconst(name, value, bytes)
@consts[name] = @const_size
@const_size += bytes
@const_data << [value].pack('i')
end
def defun(name, offset)
@funcs[name] = offset
end
def var(name)
@vars[name]
end
def var?(name)
@vars.has_key?(name)
end
def const(name)
@consts[name]
end
def const?(name)
@consts.has_key?(name)
end
end
end