Class: RubyLabs::MARSLab::PC
- Inherits:
-
Object
- Object
- RubyLabs::MARSLab::PC
- Defined in:
- lib/marslab.rb
Overview
PC
The PC (program counter) class is used to keep track of the next instruction to execute when a program is running. A PC object has an array of locations to hold the next instruction from each thread, plus the index of the thread to use on the next instruction fetch cycle.
Constant Summary collapse
- @@hmax =
see also @@threadMax in Draw – allowed to be a different value
10
Instance Attribute Summary collapse
-
#addrs ⇒ Object
readonly
Returns the value of attribute addrs.
-
#current ⇒ Object
readonly
Returns the value of attribute current.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#thread ⇒ Object
readonly
Returns the value of attribute thread.
Instance Method Summary collapse
-
#add_thread(addr) ⇒ Object
Add a new thread, which will begin execution at location
addr
. -
#branch(loc) ⇒ Object
Implement a branch instruction by setting the next instruction address for the current thread to
loc
. -
#history ⇒ Object
Return a reference to the set of history vectors for this Warrior object.
-
#initialize(id, addr) ⇒ PC
constructor
Create a new program counter.
-
#inspect ⇒ Object
(also: #to_s)
Create a string showing the name of the program and the current instruction for each thread.
-
#kill_thread ⇒ Object
Remove the current thread from the list of active threads.
-
#log(loc) ⇒ Object
Record the location of a memory operation in the history vector for the current thread.
-
#next ⇒ Object
Return the address of the next instruction to execute for this program.
-
#reset ⇒ Object
Restore this program counter to its original state, a single thread starting at the location passed when the object was created.
Constructor Details
#initialize(id, addr) ⇒ PC
Create a new program counter. The id
argument is a tag that can be used to identify which program is running at this location. The PC is intialized with one thread starting at location addr
.
483 484 485 486 487 488 489 490 |
# File 'lib/marslab.rb', line 483 def initialize(id, addr) @id = id @addrs = [addr] @history = [ Array.new ] @thread = 0 @current = {:thread => nil, :addr => nil} @first = addr end |
Instance Attribute Details
#addrs ⇒ Object (readonly)
Returns the value of attribute addrs.
475 476 477 |
# File 'lib/marslab.rb', line 475 def addrs @addrs end |
#current ⇒ Object (readonly)
Returns the value of attribute current.
475 476 477 |
# File 'lib/marslab.rb', line 475 def current @current end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
475 476 477 |
# File 'lib/marslab.rb', line 475 def id @id end |
#thread ⇒ Object (readonly)
Returns the value of attribute thread.
475 476 477 |
# File 'lib/marslab.rb', line 475 def thread @thread end |
Instance Method Details
#add_thread(addr) ⇒ Object
Add a new thread, which will begin execution at location addr
. – Not sure if this is right – new thread appended to list, as per Durham, but the execution stays with the current thread (thread switch happens in ‘next’ method)
523 524 525 526 527 |
# File 'lib/marslab.rb', line 523 def add_thread(addr) @addrs << addr @history << Array.new self end |
#branch(loc) ⇒ Object
Implement a branch instruction by setting the next instruction address for the current thread to loc
.
546 547 548 |
# File 'lib/marslab.rb', line 546 def branch(loc) @addrs[@current[:thread]] = loc end |
#history ⇒ Object
Return a reference to the set of history vectors for this Warrior object.
573 574 575 |
# File 'lib/marslab.rb', line 573 def history return @history end |
#inspect ⇒ Object Also known as: to_s
Create a string showing the name of the program and the current instruction for each thread.
506 507 508 509 510 511 512 513 514 |
# File 'lib/marslab.rb', line 506 def inspect s = "[ " @addrs.each_with_index do |x,i| s << "*" if i == @thread s << x.to_s s << " " end s << "]" end |
#kill_thread ⇒ Object
Remove the current thread from the list of active threads. The return value is the number of remaining threads.
553 554 555 556 557 558 559 |
# File 'lib/marslab.rb', line 553 def kill_thread return 0 if @addrs.empty? @addrs.slice!(@current[:thread]) @history.slice!(@current[:thread]) @thread -= 1 return @addrs.length end |
#log(loc) ⇒ Object
Record the location of a memory operation in the history vector for the current thread. The history vector is used by the methods that display the progress of a program on the RubyLabs canvas.
565 566 567 568 569 |
# File 'lib/marslab.rb', line 565 def log(loc) a = @history[@current[:thread]] a << loc a.shift if a.length > @@hmax end |
#next ⇒ Object
Return the address of the next instruction to execute for this program. If more than one thread is active, make the next thread the current thread.
532 533 534 535 536 537 538 539 540 541 |
# File 'lib/marslab.rb', line 532 def next return nil if @addrs.empty? addr = @addrs[@thread] @current[:thread] = @thread @current[:addr] = addr @addrs[@thread] = (@addrs[@thread] + 1) % @@mem.size @thread = (@thread + 1) % @addrs.size log(addr) return addr end |
#reset ⇒ Object
Restore this program counter to its original state, a single thread starting at the location passed when the object was created.
495 496 497 498 499 500 501 |
# File 'lib/marslab.rb', line 495 def reset @addrs = [@first] @history.clear @thread = 0 @current = {:thread => nil, :addr => nil} return @first end |