From: Ross Bamford Date: 2006-11-09T03:19:55+09:00 Subject: Re: Bytecode Compiler (#100) This quiz has turned out to have some interesting solutions, I'm looking forward to writing up the summary :) For the record, here's the sample solution I made when I suggested the quiz to James - it takes a similar approach to some of the other solutions in letting Ruby's parser do the heavy lifting. I pulled _why's Sandbox into the mix again to let me keep dangerously modified core classes on a tight rein. # --- compiler.rb require 'sandbox' class Compiler class << self def sb unless @sb @sb = Sandbox.new @sb.eval <<-EOC class Object private def ldconsts(o) if (o > -32769) && (o < 32768) [].push(0x01, *[o].pack('n').unpack('C*')) else [].push(0x02, *[o].pack('N').unpack('C*')) end end end class Fixnum def +(o) if o.is_a? Array o.push(*ldconsts(self)).push(0x0a) else ldconsts(self).push(*ldconsts(o)).push(0x0a) end end def -(o) if o.is_a? Array o.push(*ldconsts(self)).push(0xa0, 0x0b) else ldconsts(self).push(*ldconsts(o)).push(0x0b) end end def *(o) if o.is_a? Array o.push(*ldconsts(self)).push(0x0c) else ldconsts(self).push(*ldconsts(o)).push(0x0c) end end def **(o) if o.is_a? Array o.push(*ldconsts(self)).push(0xa0, 0x0d) else ldconsts(self).push(*ldconsts(o)).push(0x0d) end end def /(o) if o.is_a? Array o.push(*ldconsts(self)).push(0xa0, 0x0e) else ldconsts(self).push(*ldconsts(o)).push(0x0e) end end def %(o) if o.is_a? Array o.push(*ldconsts(self)).push(0xa0, 0x0f) else ldconsts(self).push(*ldconsts(o)).push(0x0f) end end end class Array def +(o) if o.is_a? Array o.push(*self).push(0x0a) else self.push(*ldconsts(o)).push(0x0a) end end def -(o) if o.is_a? Array o.push(*self).push(0xa0, 0x0b) else self.push(*ldconsts(o)).push(0x0b) end end def *(o) if o.is_a? Array o.push(*self).push(0x0c) else self.push(*ldconsts(o)).push(0x0c) end end def **(o) if o.is_a? Array o.push(*self).push(0xa0, 0x0d) else self.push(*ldconsts(o)).push(0x0d) end end def /(o) if o.is_a? Array o.push(*self).push(0xa0, 0x0e) else self.push(*ldconsts(o)).push(0x0e) end end def %(o) if o.is_a? Array o.push(*self).push(0xa0, 0x0f) else self.push(*ldconsts(o)).push(0x0f) end end end EOC end @sb end def compile(code) [*sb.eval(code)] end end end