class Lignite::BodyCompiler
Extends {OpCompiler} by
-
variable declarations: {VariableDeclarer}
-
high level flow control: {#loop}
Attributes
bytes[R]
@return [ByteString]
declared_objects[R]
locals[R]
@return [Variables]
Public Class Methods
new(globals, locals, declared_objects)
click to toggle source
# File lib/lignite/body_compiler.rb, line 27 def initialize(globals, locals, declared_objects) @bytes = "" @globals = globals @locals = locals @declared_objects = declared_objects @op_compiler = OpCompiler.new(@globals, @locals) end
Public Instance Methods
call(name, *args)
click to toggle source
Calls superclass method
# File lib/lignite/body_compiler.rb, line 101 def call(name, *args) obj_id = declared_objects.index_of(name) raise "Name #{name} not found" if obj_id.nil? # TODO: check that args match their declaration # In particular, mixing up data32 with dataf passes the VM validity check # but then misinterprets the bits. super(obj_id, *args) # Ev3Ops::call end
clone_context()
click to toggle source
# File lib/lignite/body_compiler.rb, line 35 def clone_context BodyCompiler.new(@globals, @locals, @declared_objects) end
if(cond, &body)
click to toggle source
# File lib/lignite/body_compiler.rb, line 39 def if(cond, &body) cond = Flag.new(cond) unless cond.is_a? Condition subc = clone_context subc.instance_exec(&body) cond.not.jump_forward(self, subc.bytes.bytesize) @bytes << subc.bytes end
if_else(flag8, body_true, body_false)
click to toggle source
# File lib/lignite/body_compiler.rb, line 49 def if_else(flag8, body_true, body_false) truec = clone_context falsec = clone_context truec.instance_exec(&body_true) falsec.instance_exec(&body_false) # 4 is the unconditional jump size jr_false(flag8, JumpOffset.new(truec.bytes.bytesize + 4)) @bytes << truec.bytes jr(JumpOffset.new(falsec.bytes.bytesize)) @bytes << falsec.bytes end
loop(&body)
click to toggle source
# File lib/lignite/body_compiler.rb, line 62 def loop(&body) subc = clone_context subc.instance_exec(&body) @bytes << subc.bytes # the jump takes up 4 bytes: JR, LC2, LO, HI jr(JumpOffset.new(- (subc.bytes.bytesize + 4))) end
loop_until_pre(condition, &body)
click to toggle source
# File lib/lignite/body_compiler.rb, line 90 def loop_until_pre(condition, &body) subc = clone_context subc.instance_exec(&body) ofs1 = @bytes.bytesize condition.jump_forward(self, subc.bytes.bytesize + 4) ofs2 = @bytes.bytesize fw_jump_size = ofs2 - ofs1 @bytes << subc.bytes jr(JumpOffset.new(-(fw_jump_size + subc.bytes.bytesize + 4))) end
loop_while(a, b)
click to toggle source
# File lib/lignite/body_compiler.rb, line 74 def loop_while(a, b) if a.respond_to? :call loop_while_post(b, &a) else loop_while_pre(a, &b) end end
loop_while_post(condition, &body)
click to toggle source
# File lib/lignite/body_compiler.rb, line 82 def loop_while_post(condition, &body) subc = clone_context subc.instance_exec(&body) @bytes << subc.bytes body_size = subc.bytes.bytesize condition.jump_back(self, body_size) end
loop_while_postcond(flag8, &body)
click to toggle source
# File lib/lignite/body_compiler.rb, line 70 def loop_while_postcond(flag8, &body) loop_while(body, Flag.new(flag8)) end
method_missing(name, *args)
click to toggle source
Delegate the ops to the {OpCompiler}, but also aggregate the result in @bytes.
Calls superclass method
# File lib/lignite/body_compiler.rb, line 113 def method_missing(name, *args) super unless @op_compiler.respond_to?(name) @bytes += @op_compiler.send(name, *args) end
param_decl_header()
click to toggle source
# File lib/lignite/body_compiler.rb, line 23 def param_decl_header parameters.param_decl_header end
parameters()
click to toggle source
# File lib/lignite/body_compiler.rb, line 18 def parameters locals end
respond_to_missing?(name, _include_private)
click to toggle source
Calls superclass method
# File lib/lignite/body_compiler.rb, line 119 def respond_to_missing?(name, _include_private) @op_compiler.respond_to?(name) || super end
variables()
click to toggle source
# File lib/lignite/body_compiler.rb, line 13 def variables locals end