mirror of
https://github.com/samsonjs/compiler.git
synced 2026-03-25 08:45:52 +00:00
98 lines
2.2 KiB
Ruby
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
|