In article Pine.LNX.4.44.0404021817070.6456-100000@localhost.localdomain,
Hello all,
As I’m learning Ruby, I’ve decided to write a few programs in Ruby to get
a feel for the language.
I’ve been a C programmer for a long time. As such, I worry that I’m
thinking too much like a C programmer, and not like a Ruby programmer…
My first attempt has been an emulator for a cs-toy processor called IBCM
(itty-bitty computing machine). Its spec (only 5 pages) is available at:
http://www.cs.virginia.edu/~cs216/notes/ibcm-poo.pdf
I’ve written it, and it works correctly when compared to my program
written in C, but at its core is a large case-when-end statement.
This is not `sexy.’ I was wondering if there was a better way to do
this in Ruby, or if I’m just missing the point.
My code is at: http://manjac.ath.cx/nick/ruby-ibcm.rb
One thing I notice about your code that seems very C-ish is that you use
only integers as options for your case statements. Ruby’s case
statements are a lot more flexible than C’s switch. (Maybe you need to do
this because you’re reading & executing a binary file of IBCM code.) If
you’d rather work at a higher level of abstraction with assembly code you
could perhaps do something like:
case opcode
when :halt
#do halt stuff
when :and
#do and stuff
when …
end
Or perhaps you could even define a set of opcode classes that each
ecapsulate the bahavior of each opcode. Then instead of a case statement
you could just call a ‘execute’ (or whatever you want to call it) on each
statement that you read, so it would look something like:
class Machine
include Singleton
attr_accessor :accum
def initialize
@accum = 0
#define registers, states of the machine here
end
end
class Add
def initialize(value)
@value=value
@machine = Machine.instance
end
def execute
@machine.accum += value #scope of accum is an issue here, of course
end
def to_code #so you can convert the mnemonic to a code
5 #this gives you an assembler for free, but I’m not sure
end
end
def Add(value)
Add.new(value)
end
#…main loop
File.foreach(“IBCM.program”){ |line| #no more case statement
op = eval(line.strip)
op.execute #or if you want to convert to machine code: op.to_code
}
#contents of IBCM.program:
Load(0x55)
Add(2)
And(0xFF)
Xor(0x0F)
#…
So then your IBCM.program files are actually valid Ruby code.
…but then again, if you’ve got to read in binary data anyway,
maybe it wouldn’t make sense to do it this way.
Phil
···
Nicholas Paul Johnson nickjohnson@virginia.edu wrote: