The three rules of Ruby Quiz:

1.  Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2.  Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3.  Enjoy!

Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion.  Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

by Ross Bamford

Note: This quiz isn't really as much work as it might seem!

This quiz involves writing (in Ruby, of course) a compiler for basic arithmetic
expressions. The output from this compiler should be an array of unsigned
byte-sized ints, which can be fed into the included interpreter
(http://www.rubyquiz.com/interp.rb) in order to execute the compiled expression.

The bytecode format is very simple, while the interpreter is also very simple,
implemented as a stack machine. They have the following general characteristics:

	* Bytecode is stored as an array of unsigned byte-sized Fixnums.
	* All stack-bound numbers are signed integers
	* The following operations are supported:
	  * Addition
	  * Subtraction
	  * Multiplication
	  * Division
	  * Raise to power
	  * Integer modulo
	* Where an operator would return a floating point value,
	  the value is truncated to an integer.
	* Short CONST and long LCONST instructions allow constants
	  to be pushed to the stack. These instructions expect their
	  operands to hold a signed short or long, respectively,
	  in network byte order.

Your compiler interface should be via a singleton method on a module 'Compiler',
taking a string, such that:

	Compiler.compile('3+2')

Returns an array of instructions (and operands) that, when fed to the
interpreter, will execute the expression 3+2 and return the result (hopefully
5). For example, a correct (but non-optimal) result from the above call would
be:

	[2,0,0,0,3,   # LCONST 3
	 2,0,0,0,2,   # LCONST 2
	 10]          # ADD

Your compiler should support all basic arithmetic operations and explicit
precedence (parenthesis). As standard, syntax/precedence/ associativity/etc.
should follow Ruby itself. Obviously, specific implementation is entirely up to
you, though bear in mind that your compiler must be capable of running inline in
the same Ruby process as the interpreter, without affecting any code outside
itself.

The quiz also includes a number of tests
(http://www.rubyquiz.com/test_bytecode.rb) that will test your compiler's
functionality, with expressions becoming more complex as the tests go on. To
pass all the tests, a compiler will have to not only generate correct bytecode,
but it will also need to generate the shortest code it can for a given
expression.

Here is the bytecode spec:

	# 0x01: CONST (cbyte1, cbyte2) ... => ..., const
	  Push a 15-bit signed integer to the stack.
	  The two bytes immediately following the instruction represent the
	  constant.
	
	# 0x02: LCONST (cbyte1, cbyte2, cbyte3, cbyte4) ... => ..., const
	  Push a 31-bit signed integer to the stack.
	  The four bytes immediately following the instruction represent the
	  constant.
	
	# 0x0a: ADD () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, add them, and push the result
	  back onto the stack.
	
	# 0x0b: SUB () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, subtract value2 from value1,
	  and push the result back onto the stack.
	
	# 0x0c: MUL () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, multiply value1 by value2,
	  and push the result back onto the stack.
	
	# 0x0d: POW () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, raise value1 to the power of
	  value2, and push the result back onto the stack.
	
	# 0x0e: DIV () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, divide value1 by value2,
	  and push the result back onto the stack.
	
	# 0x0f: MOD () ..., value1, value2 => ..., result
	  Pop the top two values from the stack, modulo value1 by value2,
	  and push the result back onto the stack.
	
	# 0xa0: SWAP () ..., value1, value2 => ..., value2, value1
	  Swap the top two stack values.