From: Mike Harris Date: 2006-11-06T12:21:36+09:00 Subject: Re: [QUIZ] Bytecode Compiler (#100) My solution is a bit different than all the ones I've seen so far. I had no intention of writing an expression parser :-) All it does is 1. Define a method (to_bc) to have a fixnum return its own bytecode 2. Redefine the array operators to return the appropriate bytecode representations 3. Add .to_bc after every number in the expression string Here it is: class Compiler def self.compile(str) eval(str.gsub(/(\d+)([^\d])/,'\1.to_bc\2').gsub(/([^\d])(\d+)$/,'\1\2.to_bc')) end end class Fixnum def to_bc return (self >= 0 ? [1,self/256,self%256] : [1,(self+32768)/256+128,(self+32768)%256]) if self <= 32767 and self >= -32768 res = [(24..30),(16..23),(8..15),(0..7)].map { |range| range.map { |x| self[x] } }.map { |byte| byte.inject_with_index(0) { |s,x,i| s+x*2**i } } ([2] << (self > 0 ? res[0] : res[0]+128) << res[1..3]).flatten end end class Array {:+ => 10, :- => 11, :* => 12, :** => 13, :/ => 14, :% => 15}.each do |op,opcode| define_method(op) { |x| self.concat(x).concat([opcode]) } end def inject_with_index(sum) each_with_index { |x,i| sum = yield(sum,x,i) } sum end end