Class: RubyLabs::MARSLab::Word

Inherits:
Object
  • Object
show all
Defined in:
lib/marslab.rb

Overview

Word

An object of the Word class represents a single item from memory, either a machine instruction or a piece of data. Attributes are the opcode, the A operand mode, and the B operand (all strings). Instruction execution proceeds according to the description in Durham’s spec.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Word

Create a new Word from op, a, b, and n. :call-seq:

Word.new(op, a, b, n) => Word


109
110
111
# File 'lib/marslab.rb', line 109

def initialize(*args)
  @op, @a, @b, @lineno = args
end

Instance Attribute Details

#aObject

Returns the value of attribute a.



102
103
104
# File 'lib/marslab.rb', line 102

def a
  @a
end

#bObject

Returns the value of attribute b.



102
103
104
# File 'lib/marslab.rb', line 102

def b
  @b
end

#linenoObject (readonly)

Returns the value of attribute lineno.



101
102
103
# File 'lib/marslab.rb', line 101

def lineno
  @lineno
end

#opObject (readonly)

Returns the value of attribute op.



101
102
103
# File 'lib/marslab.rb', line 101

def op
  @op
end

Instance Method Details

#==(other) ⇒ Object

Two Words are the same if the strings representing the opcode and both operands are the same.



124
125
126
# File 'lib/marslab.rb', line 124

def ==(other)
  return (op == other.op && a == other.a && b == other.b)
end

#cloneObject

Make a new Word object with all the same attributes as this object.



130
131
132
# File 'lib/marslab.rb', line 130

def clone
  Word.new(@op.clone, @a.clone, @b.clone, @lineno)
end

#dereference(field, pc, mem) ⇒ Object

Return the address of an operand; note that for immediate operands the address is the address of the current instruction.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/marslab.rb', line 144

def dereference(field, pc, mem)
  case field[0]
  when ?#
    return pc.current[:addr]
  when ?@
    ptrloc = (field_value(field) + pc.current[:addr]) % mem.size
    ptr = mem.fetch(ptrloc)
    return (field_value(ptr.b) + ptrloc) % mem.size
  when ?<
    ptrloc = (field_value(field) + pc.current[:addr]) % mem.size
    ptr = mem.fetch(ptrloc)
    newb = field_value(ptr.b) - 1
    mem.store_field(ptrloc, (newb % mem.size), :b)
    return (newb + ptrloc) % mem.size
  else
    return (field_value(field) + pc.current[:addr]) % mem.size
  end
end

#execute(pc, mem) ⇒ Object

Execute the instruction represented by this word. The first parameter is the program counter used to fetch the instruction, the second is the machine’s memory array.

The semantics for each type of instruction are defined by private methods that have the same name as the opcode, e.g. then the opcode is “ADD” execute calls ADD, sending it the pc and mem arguments so the instruction can dereference its arguments and carry out the specified operation.



170
171
172
173
# File 'lib/marslab.rb', line 170

def execute(pc, mem)
  self.send(@op, pc, mem)
  return (@op == "DAT") ? (:halt) : (:continue) 
end

#field_value(field) ⇒ Object

Convert a field specification into an integer value, stripping off a leading addressing mode character if it’s there



137
138
139
# File 'lib/marslab.rb', line 137

def field_value(field)
  return @@modes.include?(field[0]) ? field[1..-1].to_i : field.to_i
end

#inspectObject Also known as: to_s

Return a string representation of this word.



115
116
117
# File 'lib/marslab.rb', line 115

def inspect
  sprintf "%s %s %s", @op, @a, @b
end