Created a new DSL for writing OpCode definitions more concisely
Fixed a bunch of issues with reinterpretation, signed/unsigned instructions, and demotions. Everything should be a good amount more correct now.
Cleaned up tests
Changed values on the stack from being represented as Elixir numbers to being represented as binaries. Now all stack values as little-endian binaries which are interpreted by each instruction depending on how it needs to.
Because of the above change, numbers passed into the VM and returned from the VM needed to be represented in binary before getting added to the stack, so now we're making use of function signatures (as opposed to before when we ignored them) to convert the numbers to and from their correct binary representation
In this PR: