Class: ExecDoTimesInstruction
- Inherits:
-
Instruction
- Object
- Instruction
- ExecDoTimesInstruction
- Defined in:
- lib/instructions/exec/exec_do_times.rb
Overview
Pops two values from the :int
stack (“destination” and “counter”), 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 once for every integer in the range (inclusive).
note: the top integer is the “destination”, the second one the “counter” (regardless of their values or signs)
note: unlike the ExecDoRange instruction, the counter is not pushed
If the counter and destination have the same value, then a copy of the :exec
item is pushed onto the :exec
stack.
If the counter and destination have different values, then a “new_counter” value is calculated that is *one step closer to the destination*.
A ValuePoint containing the following “macro” is created:
block {
value «int»
value «int»
do exec_do_times
popped item
}
«int» new_counter
«int» destination
where popped_item
is the code from the :exec
stack, and new_counter
and destination
are the numeric values that were derived above.
Finally,
-
the macro is pushed onto the
:exec
stack -
another copy of the
popped_item
is pushed onto the:exec
stack (on top of the macro)
The consequence is that the original item will be executed, then the macro will be encountered, and this process will repeat.
note: if the popped_item
itself manipulates the :exec
stack, “complicated behavior” may arise
needs: 2 :int
items, 1 :exec
item
pushes: well, it’s complicated…
Instance Attribute Summary
Attributes inherited from Instruction
Instance Method Summary collapse
Methods inherited from Instruction
all_instructions, #go, inherited, #initialize, #needs, #pushes, to_nudgecode
Constructor Details
This class inherits a constructor from Instruction
Instance Method Details
#cleanup ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/instructions/exec/exec_do_times.rb', line 64 def cleanup if @finished pushes :exec, @code else recursor = CodeblockPoint.new([@new_counter, @destination, InstructionPoint.new("exec_do_times"),@code]) pushes :exec, recursor pushes :exec, @code end end |
#derive ⇒ Object
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/instructions/exec/exec_do_times.rb', line 53 def derive @finished = false if @counter.value == @destination.value @finished = true elsif @counter.value < @destination.value @new_counter = ValuePoint.new("int", @counter.value + 1) else @new_counter = ValuePoint.new("int", @counter.value - 1) end end |
#preconditions? ⇒ Boolean
42 43 44 45 |
# File 'lib/instructions/exec/exec_do_times.rb', line 42 def preconditions? needs :exec, 1 needs :int, 2 end |
#setup ⇒ Object
47 48 49 50 51 |
# File 'lib/instructions/exec/exec_do_times.rb', line 47 def setup @destination = @context.pop(:int) @counter = @context.pop(:int) @code = @context.pop(:exec) end |