Sha256: b35a609f1337045b30a7be12f1d8c14a2cead1affa50bfce9812f5ad5e69988d

Contents?: true

Size: 1.37 KB

Versions: 3

Compression:

Stored size: 1.37 KB

Contents

# Pops one "count" item from the +:int+ stack, and one item from the +:exec+ stack.
# The net effect of the instruction (unless interfered with by another operation)
# is to evaluate the +:exec+ item "count" times.
#
# If the count is negative, an +:error+ item will be pushed to the +:error+ stack. Otherwise,
# a ValuePoint containing the following "macro" is created and pushed onto the +:exec+ stack:
#   block {
#     value «int»
#     value «int»
#     do exec_do_range
#     popped item
#   }
#   «int» 0
#   «int» count - 1
# where +popped_item+ is the code from the +:exec+ stack, and +count - 1+ is a decrement of
# the "count" value.
#
# *needs:* ExecDoRangeInstruction must be active in the context for this to work; needs 1 +:int+ and 1 +:exec+ item
#
# *pushes:* it's complicated...
#

class ExecDoCountInstruction < Instruction
  def preconditions?
    needs ExecDoRangeInstruction
    needs :exec, 1
    needs :int, 1
  end
  
  def setup
    @destination = @context.pop(:int)
    @code = @context.pop(:exec)
  end
  
  def derive
    raise InstructionMethodError, "#{self.class} needs a positive argument" if @destination.value < 1
    @one_less = ValuePoint.new("int",@destination.value-1)
  end
  
  def cleanup
    recursor = CodeblockPoint.new([ValuePoint.new("int",0), @one_less,
      InstructionPoint.new("exec_do_range"),@code])
    pushes :exec, recursor
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
nudge-0.2.9 lib/instructions/exec/exec_do_count.rb
nudge-0.2.8 lib/instructions/exec/exec_do_count.rb
nudge-0.2.7 lib/instructions/exec/exec_do_count.rb