Class: CodeDoRangeInstruction
- Inherits:
-
Instruction
- Object
- Instruction
- CodeDoRangeInstruction
- Defined in:
- lib/instructions/code/code_do_range.rb
Overview
Pops two values from the :int
stack (“destination” and “counter”), and one item from the :code
stack. The net effect of the instruction (unless interfered with by another operation) is to evaluate the :code
item once for every integer in the range (inclusive), and at the same time push the counter integer onto the :int
stack.
note: rather than duplicating the functionality of the ExecDoRangeInstruction, that is used as a macro here
note: the first integer popped is the “destination”, the second one the “counter” (regardless of their values or signs)
note: unlike the CodeDoTimes instruction, the counter is pushed
If the counter and destination have the same value, then a new :int
is pushed with that value, and the :code
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_range
popped item
}
«int» new_counter
«int» destination
where popped_item
is the code from the :code
stack, and new_counter
and destination
are the numeric values that were derived above.
Finally,
-
a new ValuePoint whose value is
new_counter
is pushed to the:int
stack; -
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 :code
item will be executed (at least once), the counter will be pushed onto the :int
stack, the macro will be encountered, and this cycle will repeat via the ExecDoRangeInstruction.
note: if the popped_item
itself manipulates the :exec
stack, “complicated behavior” may arise
needs: 2 :int
items, 1 :code
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
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/instructions/code/code_do_range.rb', line 73 def cleanup if @finished pushes :int, @counter pushes :exec, @codeblock else pushes :int, @counter pushes :exec, @recursor pushes :exec, @codeblock end end |
#derive ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/instructions/code/code_do_range.rb', line 59 def derive @codeblock = NudgeProgram.new(@code).linked_code @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 @recursor = CodeblockPoint.new([@new_counter, @destination, InstructionPoint.new("exec_do_range"),@codeblock]) end |
#preconditions? ⇒ Boolean
47 48 49 50 51 |
# File 'lib/instructions/code/code_do_range.rb', line 47 def preconditions? needs ExecDoRangeInstruction needs :code, 1 needs :int, 2 end |
#setup ⇒ Object
53 54 55 56 57 |
# File 'lib/instructions/code/code_do_range.rb', line 53 def setup @destination = @context.pop(:int) @counter = @context.pop(:int) @code = @context.pop_value(:code) end |