From: ptkwt@... (Phil Tomson) Date: 2004-04-03T17:54:23+09:00 Subject: Re: Learning Ruby, was a C geek... In article , Nicholas Paul Johnson wrote: >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