class Lignite::Assembler
Assemble a complete RBF program file.
The compilation has two passes:
-
pass1, Declaration
-
pass2, Resolution
After P1, the instruction sequence is iterated. If an item responds to :pass2, it is replaced by the result of that call. After pass2 we have a sequence of ByteStrings which are just concatenated
No, pass1, gather names, pass2 do all the rest
Constants
- HEADER_SIZE
- SIGNATURE
Attributes
globals[RW]
@return [Variables]
objects[RW]
@return [Array<RbfObject>]
Public Class Methods
new()
click to toggle source
# File lib/lignite/assembler.rb, line 34 def initialize @objects = [] @globals = Variables.new end
Public Instance Methods
assemble(rb_filename, rbf_filename, version: 109)
click to toggle source
Assemble a complete RBF program file. (it is OK to reuse an Assembler
and call this several times in a sequence) TODO: redesign for Assembler.new(rb_filename)
.assemble(rbf_filename)? @param rb_filename [String] input @param rbf_filename [String] output
# File lib/lignite/assembler.rb, line 44 def assemble(rb_filename, rbf_filename, version: 109) initialize rb_text = File.read(rb_filename) @declarer = RbfDeclarer.new @declarer.instance_eval(rb_text, rb_filename, 1) # 1 is the line number instance_eval(rb_text, rb_filename, 1) # 1 is the line number write(rbf_filename, version) end
compile(&block)
click to toggle source
# File lib/lignite/assembler.rb, line 55 def compile(&block) @declarer = RbfDeclarer.new @declarer.instance_exec(&block) instance_exec(&block) end
image_header(image_size:, version:, object_count:, global_bytes:)
click to toggle source
# File lib/lignite/assembler.rb, line 24 def image_header(image_size:, version:, object_count:, global_bytes:) SIGNATURE + u32(image_size) + u16(version) + u16(object_count) + u32(global_bytes) end
sub(_name, &body)
click to toggle source
# File lib/lignite/assembler.rb, line 101 def sub(_name, &body) @locals = Variables.new bodyc = BodyCompiler.new(@globals, @locals, @declarer) bodyc.instance_exec(&body) bodyc.instance_exec do self.return object_end end @objects << RbfObject.subcall(body: bodyc.param_decl_header + bodyc.bytes, local_bytes: @locals.bytesize) end
variables()
click to toggle source
# File lib/lignite/assembler.rb, line 85 def variables globals end
vmthread(name, &body)
click to toggle source
# File lib/lignite/assembler.rb, line 90 def vmthread(name, &body) @locals = Variables.new bodyc = BodyCompiler.new(@globals, @locals, @declarer) bodyc.instance_exec(&body) bodyc.instance_exec { object_end } logger.debug "VMTHREAD #{name}" logger.debug " size #{bodyc.bytes.bytesize}" logger.debug " " + bin_to_hex(bodyc.bytes) @objects << RbfObject.vmthread(body: bodyc.bytes, local_bytes: @locals.bytesize) end
write(rbf_filename, version = 109)
click to toggle source
# File lib/lignite/assembler.rb, line 61 def write(rbf_filename, version = 109) image_size = HEADER_SIZE + @objects.map(&:size).reduce(0, :+) File.open(rbf_filename, "w") do |f| header = image_header(image_size: image_size, version: version, object_count: @objects.size, global_bytes: @globals.bytesize) f.write(header) object_instruction_offset = HEADER_SIZE + @objects.count * RbfObject::HEADER_SIZE @objects.each do |obj| h = obj.header(object_instruction_offset) f.write(h) object_instruction_offset += obj.body.bytesize end @objects.each do |obj| f.write(obj.body) # align?? end end end