Class: RubyLabs::MARSLab::PC

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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

#addrsObject (readonly)

Returns the value of attribute addrs.



475
476
477
# File 'lib/marslab.rb', line 475

def addrs
  @addrs
end

#currentObject (readonly)

Returns the value of attribute current.



475
476
477
# File 'lib/marslab.rb', line 475

def current
  @current
end

#idObject (readonly)

Returns the value of attribute id.



475
476
477
# File 'lib/marslab.rb', line 475

def id
  @id
end

#threadObject (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

#historyObject

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

#inspectObject 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_threadObject

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

#nextObject

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

#resetObject

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