nudge 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/instructions/bool/bool_and.rb +8 -0
- data/lib/instructions/bool/bool_define.rb +9 -0
- data/lib/instructions/bool/bool_depth.rb +5 -0
- data/lib/instructions/bool/bool_duplicate.rb +7 -0
- data/lib/instructions/bool/bool_equal_q.rb +8 -0
- data/lib/instructions/bool/bool_flush.rb +3 -0
- data/lib/instructions/bool/bool_not.rb +8 -0
- data/lib/instructions/bool/bool_or.rb +8 -0
- data/lib/instructions/bool/bool_pop.rb +3 -0
- data/lib/instructions/bool/bool_random.rb +3 -0
- data/lib/instructions/bool/bool_rotate.rb +11 -0
- data/lib/instructions/bool/bool_shove.rb +14 -0
- data/lib/instructions/bool/bool_swap.rb +3 -0
- data/lib/instructions/bool/bool_xor.rb +8 -0
- data/lib/instructions/bool/bool_yank.rb +12 -0
- data/lib/instructions/bool/bool_yankdup.rb +12 -0
- data/lib/instructions/code/code_atom_q.rb +9 -0
- data/lib/instructions/code/code_backbone_points.rb +17 -0
- data/lib/instructions/code/code_car.rb +15 -0
- data/lib/instructions/code/code_cdr.rb +13 -1
- data/lib/instructions/code/code_concatenate.rb +20 -0
- data/lib/instructions/code/code_cons.rb +22 -1
- data/lib/instructions/code/code_container.rb +21 -2
- data/lib/instructions/code/code_contains_q.rb +11 -0
- data/lib/instructions/code/code_define.rb +9 -0
- data/lib/instructions/code/code_depth.rb +5 -0
- data/lib/instructions/code/code_discrepancy.rb +13 -7
- data/lib/instructions/code/code_do_count.rb +21 -1
- data/lib/instructions/code/code_do_range.rb +44 -3
- data/lib/instructions/code/code_do_times.rb +39 -1
- data/lib/instructions/code/code_duplicate.rb +7 -0
- data/lib/instructions/code/code_equal_q.rb +9 -0
- data/lib/instructions/code/code_execute.rb +7 -0
- data/lib/instructions/code/code_execute_then_pop.rb +9 -0
- data/lib/instructions/code/code_flush.rb +3 -0
- data/lib/instructions/code/code_gsub.rb +11 -3
- data/lib/instructions/code/code_if.rb +8 -0
- data/lib/instructions/code/code_instructions.rb +12 -0
- data/lib/instructions/code/code_list.rb +10 -0
- data/lib/instructions/code/code_member_q.rb +14 -0
- data/lib/instructions/code/code_name_lookup.rb +10 -0
- data/lib/instructions/code/code_noop.rb +3 -0
- data/lib/instructions/code/code_nth.rb +12 -0
- data/lib/instructions/code/code_nth_cdr.rb +14 -2
- data/lib/instructions/code/code_nth_point.rb +15 -0
- data/lib/instructions/code/code_null_q.rb +11 -0
- data/lib/instructions/code/code_parses_q.rb +8 -0
- data/lib/instructions/code/code_points.rb +8 -0
- data/lib/instructions/code/code_pop.rb +3 -0
- data/lib/instructions/code/code_position.rb +11 -0
- data/lib/instructions/code/code_quote.rb +11 -0
- data/lib/instructions/code/code_replace_nth_point.rb +11 -0
- data/lib/instructions/code/code_rotate.rb +11 -0
- data/lib/instructions/code/code_shove.rb +14 -0
- data/lib/instructions/code/code_swap.rb +3 -0
- data/lib/instructions/code/code_yank.rb +12 -0
- data/lib/instructions/code/code_yankdup.rb +12 -0
- data/lib/instructions/conversion/bool_from_float.rb +9 -0
- data/lib/instructions/conversion/bool_from_int.rb +9 -0
- data/lib/instructions/conversion/code_from_bool.rb +9 -1
- data/lib/instructions/conversion/code_from_float.rb +10 -1
- data/lib/instructions/conversion/code_from_int.rb +10 -1
- data/lib/instructions/conversion/code_from_name.rb +10 -1
- data/lib/instructions/conversion/float_from_bool.rb +9 -0
- data/lib/instructions/conversion/float_from_int.rb +9 -0
- data/lib/instructions/conversion/int_from_bool.rb +9 -0
- data/lib/instructions/conversion/int_from_float.rb +9 -0
- data/lib/instructions/exec/exec_define.rb +9 -0
- data/lib/instructions/exec/exec_depth.rb +5 -0
- data/lib/instructions/exec/exec_do_count.rb +22 -0
- data/lib/instructions/exec/exec_do_range.rb +43 -0
- data/lib/instructions/exec/exec_do_times.rb +40 -0
- data/lib/instructions/exec/exec_duplicate.rb +7 -0
- data/lib/instructions/exec/exec_equal_q.rb +9 -0
- data/lib/instructions/exec/exec_flush.rb +5 -0
- data/lib/instructions/exec/exec_if.rb +8 -0
- data/lib/instructions/exec/exec_k.rb +4 -0
- data/lib/instructions/exec/exec_pop.rb +3 -0
- data/lib/instructions/exec/exec_rotate.rb +11 -0
- data/lib/instructions/exec/exec_s.rb +11 -0
- data/lib/instructions/exec/exec_shove.rb +14 -0
- data/lib/instructions/exec/exec_swap.rb +3 -0
- data/lib/instructions/exec/exec_y.rb +18 -0
- data/lib/instructions/exec/exec_yank.rb +12 -0
- data/lib/instructions/exec/exec_yankdup.rb +12 -0
- data/lib/instructions/float/float_abs.rb +8 -0
- data/lib/instructions/float/float_add.rb +8 -0
- data/lib/instructions/float/float_cosine.rb +8 -0
- data/lib/instructions/float/float_define.rb +9 -0
- data/lib/instructions/float/float_depth.rb +5 -0
- data/lib/instructions/float/float_divide.rb +12 -0
- data/lib/instructions/float/float_duplicate.rb +7 -0
- data/lib/instructions/float/float_equal_q.rb +8 -0
- data/lib/instructions/float/float_flush.rb +3 -0
- data/lib/instructions/float/float_greater_than_q.rb +9 -0
- data/lib/instructions/float/float_if.rb +8 -0
- data/lib/instructions/float/float_less_than_q.rb +9 -0
- data/lib/instructions/float/float_max.rb +8 -0
- data/lib/instructions/float/float_min.rb +8 -0
- data/lib/instructions/float/float_modulo.rb +12 -0
- data/lib/instructions/float/float_multiply.rb +8 -0
- data/lib/instructions/float/float_negative.rb +8 -0
- data/lib/instructions/float/float_pop.rb +3 -0
- data/lib/instructions/float/float_power.rb +12 -0
- data/lib/instructions/float/float_random.rb +3 -0
- data/lib/instructions/float/float_rotate.rb +11 -0
- data/lib/instructions/float/float_shove.rb +14 -0
- data/lib/instructions/float/float_sine.rb +8 -0
- data/lib/instructions/float/float_sqrt.rb +10 -0
- data/lib/instructions/float/float_subtract.rb +10 -0
- data/lib/instructions/float/float_swap.rb +3 -0
- data/lib/instructions/float/float_tangent.rb +8 -0
- data/lib/instructions/float/float_yank.rb +12 -0
- data/lib/instructions/float/float_yankdup.rb +12 -0
- data/lib/instructions/int/int_abs.rb +9 -1
- data/lib/instructions/int/int_add.rb +8 -0
- data/lib/instructions/int/int_define.rb +10 -1
- data/lib/instructions/int/int_depth.rb +5 -0
- data/lib/instructions/int/int_divide.rb +12 -0
- data/lib/instructions/int/int_duplicate.rb +7 -0
- data/lib/instructions/int/int_equal_q.rb +8 -0
- data/lib/instructions/int/int_flush.rb +3 -0
- data/lib/instructions/int/int_greater_than_q.rb +9 -0
- data/lib/instructions/int/int_if.rb +8 -0
- data/lib/instructions/int/int_less_than_q.rb +9 -0
- data/lib/instructions/int/int_max.rb +8 -0
- data/lib/instructions/int/int_min.rb +8 -0
- data/lib/instructions/int/int_modulo.rb +12 -0
- data/lib/instructions/int/int_multiply.rb +8 -0
- data/lib/instructions/int/int_negative.rb +8 -0
- data/lib/instructions/int/int_pop.rb +3 -0
- data/lib/instructions/int/int_power.rb +12 -0
- data/lib/instructions/int/int_random.rb +3 -0
- data/lib/instructions/int/int_rotate.rb +11 -0
- data/lib/instructions/int/int_shove.rb +14 -0
- data/lib/instructions/int/int_subtract.rb +10 -0
- data/lib/instructions/int/int_swap.rb +3 -0
- data/lib/instructions/int/int_yank.rb +14 -0
- data/lib/instructions/int/int_yankdup.rb +14 -0
- data/lib/instructions/name/name_depth.rb +5 -0
- data/lib/instructions/name/name_disable_lookup.rb +11 -0
- data/lib/instructions/name/name_duplicate.rb +7 -0
- data/lib/instructions/name/name_equal_q.rb +8 -0
- data/lib/instructions/name/name_flush.rb +3 -0
- data/lib/instructions/name/name_next.rb +7 -0
- data/lib/instructions/name/name_pop.rb +3 -0
- data/lib/instructions/name/name_random_bound.rb +9 -0
- data/lib/instructions/name/name_rotate.rb +11 -0
- data/lib/instructions/name/name_shove.rb +14 -0
- data/lib/instructions/name/name_swap.rb +3 -0
- data/lib/instructions/name/name_unbind.rb +7 -0
- data/lib/instructions/name/name_yank.rb +12 -0
- data/lib/instructions/name/name_yankdup.rb +12 -0
- data/spec/instructions/code/code_nth_cdr_spec.rb +10 -2
- metadata +3 -3
@@ -1,4 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# Pops one "count" item from the +:int+ stack, and one item from the +:code+ stack.
|
2
|
+
# The net effect of the instruction (unless interfered with by another operation)
|
3
|
+
# is to evaluate the +:code+ item "count" times.
|
4
|
+
#
|
5
|
+
# If the count is negative, an +:error+ item will be pushed to the +:error+ stack. Otherwise,
|
6
|
+
# a ValuePoint containing the following "macro" is created and pushed onto the +:exec+ stack:
|
7
|
+
# block {
|
8
|
+
# value «int»
|
9
|
+
# value «int»
|
10
|
+
# do exec_do_range
|
11
|
+
# popped item
|
12
|
+
# }
|
13
|
+
# «int» 0
|
14
|
+
# «int» count - 1
|
15
|
+
# where +popped_item+ is the code from the +:code+ stack, and +count - 1+ is a decrement of
|
16
|
+
# the "count" value.
|
17
|
+
#
|
18
|
+
# *needs:* ExecDoRangeInstruction must be active in the context for this to work; needs 1 +:int+ and 1 +:code+ item
|
19
|
+
#
|
20
|
+
# *pushes:* it's complicated...
|
21
|
+
#
|
2
22
|
|
3
23
|
class CodeDoCountInstruction < Instruction
|
4
24
|
def preconditions?
|
@@ -1,6 +1,47 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
1
|
+
# Pops two values from the +:int+ stack ("destination" and "counter"), and one item from the +:code+ stack.
|
2
|
+
# The net effect of the instruction (unless interfered with by another operation)
|
3
|
+
# is to evaluate the +:code+ item once for every integer in the range (inclusive), and
|
4
|
+
# at the same time push the counter integer onto the +:int+ stack.
|
5
|
+
#
|
6
|
+
# note: rather than duplicating the functionality of the ExecDoRangeInstruction, that is used as a macro here
|
7
|
+
#
|
8
|
+
# note: the first integer popped is the "destination", the second one the "counter"
|
9
|
+
# (regardless of their values or signs)
|
10
|
+
#
|
11
|
+
# note: unlike the CodeDoTimes instruction, the counter is pushed
|
12
|
+
#
|
13
|
+
# <b>If the counter and destination have the same value</b>, then a new +:int+ is pushed with that value,
|
14
|
+
# and the +:code+ item is pushed onto the +:exec+ stack.
|
15
|
+
#
|
16
|
+
# <b>If the counter and destination have different values</b>, then a "new_counter" value
|
17
|
+
# is calculated that is *one step closer to the destination*.
|
18
|
+
#
|
19
|
+
# A ValuePoint containing the following "macro" is created:
|
20
|
+
# block {
|
21
|
+
# value «int»
|
22
|
+
# value «int»
|
23
|
+
# do exec_do_range
|
24
|
+
# popped item
|
25
|
+
# }
|
26
|
+
# «int» new_counter
|
27
|
+
# «int» destination
|
28
|
+
# where +popped_item+ is the code from the +:code+ stack, and +new_counter+ and +destination+ are the numeric values that were derived above.
|
29
|
+
#
|
30
|
+
# Finally,
|
31
|
+
# 1. a new ValuePoint whose value is +new_counter+ is pushed to the +:int+ stack;
|
32
|
+
# 2. the macro is pushed onto the +:exec+ stack
|
33
|
+
# 3. another copy of the +popped_item+ is pushed onto the +:exec+ stack (on top of the macro)
|
34
|
+
#
|
35
|
+
# The consequence is that the original +:code+ item will be executed (at least once),
|
36
|
+
# the counter will be pushed onto the +:int+ stack,
|
37
|
+
# the macro will be encountered, and this cycle will repeat via the ExecDoRangeInstruction.
|
38
|
+
#
|
39
|
+
# note: if the +popped_item+ itself manipulates the +:exec+ stack, "complicated behavior" may arise
|
40
|
+
#
|
41
|
+
# *needs:* 2 +:int+ items, 1 +:code+ item
|
42
|
+
#
|
43
|
+
# *pushes:* well, it's complicated...
|
44
|
+
#
|
4
45
|
|
5
46
|
class CodeDoRangeInstruction < Instruction
|
6
47
|
def preconditions?
|
@@ -1,4 +1,42 @@
|
|
1
|
-
#
|
1
|
+
# Pops two values from the +:int+ stack ("destination" and "counter"), and one item from the +:code+ stack.
|
2
|
+
# The net effect of the instruction (unless interfered with by another operation)
|
3
|
+
# is to evaluate the +:exec+ item once for every integer in the range (inclusive).
|
4
|
+
#
|
5
|
+
# note: the top integer is the "destination", the second one the "counter"
|
6
|
+
# (regardless of their values or signs)
|
7
|
+
#
|
8
|
+
# note: unlike the CodeDoRange instruction, the counter is not pushed
|
9
|
+
#
|
10
|
+
# <b>If the counter and destination have the same value</b>, then a copy of the +:code+ item is
|
11
|
+
# pushed onto the +:exec+ stack.
|
12
|
+
#
|
13
|
+
# <b>If the counter and destination have different values</b>, then a "new_counter" value
|
14
|
+
# is calculated that is *one step closer to the destination*.
|
15
|
+
#
|
16
|
+
# A ValuePoint containing the following "macro" is created:
|
17
|
+
# block {
|
18
|
+
# value «int»
|
19
|
+
# value «int»
|
20
|
+
# do exec_do_times
|
21
|
+
# popped item
|
22
|
+
# }
|
23
|
+
# «int» new_counter
|
24
|
+
# «int» destination
|
25
|
+
# where +popped_item+ is the code from the +:code+ stack, and +new_counter+ and +destination+ are the numeric values that were derived above.
|
26
|
+
#
|
27
|
+
# Finally,
|
28
|
+
# 1. the macro is pushed onto the +:exec+ stack
|
29
|
+
# 2. another copy of the +popped_item+ is pushed onto the +:exec+ stack (on top of the macro)
|
30
|
+
#
|
31
|
+
# The consequence is that the original item will be executed,
|
32
|
+
# then the macro will be encountered, and this process will repeat.
|
33
|
+
#
|
34
|
+
# note: if the +popped_item+ itself manipulates the +:exec+ stack, "complicated behavior" may arise
|
35
|
+
#
|
36
|
+
# *needs:* ExecDoTimesInstruction must be active; 2 +:int+ items, 1 +:exec+ item
|
37
|
+
#
|
38
|
+
# *pushes:* well, it's complicated...
|
39
|
+
#
|
2
40
|
|
3
41
|
class CodeDoTimesInstruction < Instruction
|
4
42
|
def preconditions?
|
@@ -1,3 +1,12 @@
|
|
1
|
+
# pops the top 2 items of the +:code+ stack;
|
2
|
+
# pushes a new ValuePoint onto the +:bool+ stack, with value +true+ if the
|
3
|
+
# two items' blueprint strings are identical
|
4
|
+
#
|
5
|
+
# *needs:* 2 +:code+
|
6
|
+
#
|
7
|
+
# *pushes:* 1 +:bool+
|
8
|
+
#
|
9
|
+
|
1
10
|
class CodeEqualQInstruction < Instruction
|
2
11
|
def preconditions?
|
3
12
|
needs :code, 2
|
@@ -1,3 +1,12 @@
|
|
1
|
+
# peeks at the top item from the +:code+ stack (without popping it!);
|
2
|
+
# pushes a new block containing that code value and "do code_pop" onto the +:exec+ stack,
|
3
|
+
# so the item is executed, then removed from the +:code+ stack
|
4
|
+
#
|
5
|
+
# *needs:* 1 +:code+
|
6
|
+
#
|
7
|
+
# *pushes:* 1 +:exec+
|
8
|
+
#
|
9
|
+
|
1
10
|
class CodeExecuteThenPopInstruction < Instruction
|
2
11
|
def preconditions?
|
3
12
|
needs CodePopInstruction
|
@@ -1,6 +1,14 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
1
|
+
# pops three items from the +:code+ stack: the "host", the "old_subtree" and the "new_subtree";
|
2
|
+
# pushes a new +:code+ item which contants the +host+, with every occurrence of the +old_subtree+
|
3
|
+
# (if any) replaced by the +new_subtree+
|
4
|
+
#
|
5
|
+
# note: the order of arguments counts; the top +:code+ stack item is the +host+,
|
6
|
+
# the second is the +old_subtree+, and the third is the +new_subtree+
|
7
|
+
#
|
8
|
+
# *needs:* 3 +:code+
|
9
|
+
#
|
10
|
+
# *pushes:* 1 +:code+
|
11
|
+
#
|
4
12
|
|
5
13
|
class CodeGsubInstruction < Instruction # was CODE.SUBST in Push3
|
6
14
|
def preconditions?
|
@@ -1,3 +1,11 @@
|
|
1
|
+
# pops the top 2 items of the +:code+ stack, and one +:bool+;
|
2
|
+
# returns the top +:code+ item if the +:bool+ is +false+, the second one if +true+
|
3
|
+
#
|
4
|
+
# *needs:* 2 +:code+, 1 +:bool+
|
5
|
+
#
|
6
|
+
# *pushes:* 1 +:code+
|
7
|
+
#
|
8
|
+
|
1
9
|
class CodeIfInstruction < Instruction
|
2
10
|
|
3
11
|
def preconditions?
|
@@ -1,14 +1,26 @@
|
|
1
|
+
# pushes a new +:code+ item whose value is a block containing one call to every
|
2
|
+
# Instruction active in the context
|
3
|
+
#
|
4
|
+
# note: the order of instructions is determined by the order they appear in the context's library
|
5
|
+
#
|
6
|
+
# *needs:* nothing
|
7
|
+
#
|
8
|
+
# *pushes:* 1 +:code+
|
9
|
+
|
1
10
|
class CodeInstructionsInstruction < Instruction
|
2
11
|
def preconditions?
|
3
12
|
true
|
4
13
|
end
|
14
|
+
|
5
15
|
def setup
|
6
16
|
end
|
17
|
+
|
7
18
|
def derive
|
8
19
|
all_instructions = @context.instructions
|
9
20
|
list_as_block = all_instructions.inject("block {") {|b,i| b + " do #{i.to_nudgecode}"} + "}"
|
10
21
|
@result = ValuePoint.new("code", list_as_block)
|
11
22
|
end
|
23
|
+
|
12
24
|
def cleanup
|
13
25
|
pushes :code, @result
|
14
26
|
end
|
@@ -1,3 +1,13 @@
|
|
1
|
+
# pops the top 2 items from the +:code+ stack;
|
2
|
+
# pushes a new +:code+ item containing a block obtained by combining the other listings into one block
|
3
|
+
#
|
4
|
+
# note: the top stack item (the "attachment") is the second item of the resulting list
|
5
|
+
#
|
6
|
+
# *needs:* 2 +:code+
|
7
|
+
#
|
8
|
+
# *pushes:* 1 +:code+
|
9
|
+
#
|
10
|
+
|
1
11
|
class CodeListInstruction < Instruction
|
2
12
|
def preconditions?
|
3
13
|
needs :code, 2
|
@@ -1,3 +1,17 @@
|
|
1
|
+
# pops the top 2 item of the +:code+ stack;
|
2
|
+
# pushes a new ValuePoint onto the +:bool+ stack, with value +true+ if the
|
3
|
+
# second argument appears as a block in the _backbone_ of the first argument
|
4
|
+
#
|
5
|
+
# note: order matters, and the top stack item is the second argument, the second stack item is the first
|
6
|
+
#
|
7
|
+
# note: compare to CodeContainsQInstruction, which checks for matches at all subtrees, not just the "root"
|
8
|
+
#
|
9
|
+
# *needs:* 2 +:code+
|
10
|
+
#
|
11
|
+
# *pushes:* 1 +:bool+
|
12
|
+
#
|
13
|
+
|
14
|
+
|
1
15
|
class CodeMemberQInstruction < Instruction
|
2
16
|
def preconditions?
|
3
17
|
needs :code, 2
|
@@ -1,3 +1,13 @@
|
|
1
|
+
# pops the top +:name+ item;
|
2
|
+
# pushes a new +:code+ item that has a value equal to the current context binding
|
3
|
+
#
|
4
|
+
# note: if there is no binding, the resulting +:code+ value will be an empty string
|
5
|
+
#
|
6
|
+
# *needs:* 1 +:name+
|
7
|
+
#
|
8
|
+
# *pushes:* 1 +:code+
|
9
|
+
#
|
10
|
+
|
1
11
|
class CodeNameLookupInstruction < Instruction # was Push3 CODE.DEFINITION
|
2
12
|
def preconditions?
|
3
13
|
needs :name, 1
|
@@ -1,3 +1,15 @@
|
|
1
|
+
# pops the top +:code+ item and +:int+ item ("N");
|
2
|
+
# pushes a new +:code+ item containing the Nth backbone element of the +:code+, if it's a block
|
3
|
+
#
|
4
|
+
# If the +:code+ is not a block, it's replaced intact;
|
5
|
+
# if the +:code+ is an empty block, an +:error+ is pushed instead of a +:code+ item;
|
6
|
+
# otherwise, the index is chosen as +N+ modulo the length of the block's backbone.
|
7
|
+
#
|
8
|
+
# *needs:* 1 +:code+ and 1 +:int+
|
9
|
+
#
|
10
|
+
# *pushes:* 1 +:code+
|
11
|
+
#
|
12
|
+
|
1
13
|
class CodeNthInstruction < Instruction
|
2
14
|
def preconditions?
|
3
15
|
needs :int, 1
|
@@ -1,3 +1,15 @@
|
|
1
|
+
# pops the top +:code+ item and +:int+ item ("N");
|
2
|
+
# pushes a new +:code+ item, which is the result of removing the first +N+ backbone elements of the +:code+
|
3
|
+
#
|
4
|
+
# If the +:code+ is not a block, it is wrapped in one first;
|
5
|
+
# if +N+ is less than 1, the original code (or newly wrapped atom) is returned;
|
6
|
+
# otherwise, the number of items removed is actually the backbone length *modulo* +N+
|
7
|
+
#
|
8
|
+
# *needs:* 1 +:code+, 1 +:int+
|
9
|
+
#
|
10
|
+
# *pushes:* 1 +:code+
|
11
|
+
#
|
12
|
+
|
1
13
|
class CodeNthCdrInstruction < Instruction
|
2
14
|
def preconditions?
|
3
15
|
needs :int, 1
|
@@ -17,10 +29,10 @@ class CodeNthCdrInstruction < Instruction
|
|
17
29
|
if b_len > 0
|
18
30
|
new_tree = CodeblockPoint.new(backbone.contents.slice(@arg1 % b_len, b_len))
|
19
31
|
else
|
20
|
-
new_tree =
|
32
|
+
new_tree = backbone
|
21
33
|
end
|
22
34
|
else
|
23
|
-
new_tree = @arg1
|
35
|
+
new_tree = @arg1 < 1 ? CodeblockPoint.new([tree.linked_code]) : CodeblockPoint.new([])
|
24
36
|
end
|
25
37
|
@result = ValuePoint.new("code", new_tree.blueprint)
|
26
38
|
end
|
@@ -1,12 +1,26 @@
|
|
1
|
+
# pops the top +:code+ item and +:int+ item ("N");
|
2
|
+
# pushes a new +:code+ item containing the Nth program point of the +:code+
|
3
|
+
#
|
4
|
+
# If the +:code+ is not a block, it's replaced intact;
|
5
|
+
# if the +:code+ value cannot be parsed, an +:error+ is pushed instead of a +:code+ item;
|
6
|
+
# otherwise, the index is chosen as +N+ modulo the length of the number of program points.
|
7
|
+
#
|
8
|
+
# *needs:* 1 +:code+ and 1 +:int+
|
9
|
+
#
|
10
|
+
# *pushes:* 1 +:code+
|
11
|
+
#
|
12
|
+
|
1
13
|
class CodeNthPointInstruction < Instruction # was CODE.EXTRACT in Push3
|
2
14
|
def preconditions?
|
3
15
|
needs :int, 1
|
4
16
|
needs :code, 1
|
5
17
|
end
|
18
|
+
|
6
19
|
def setup
|
7
20
|
@arg1 = @context.pop_value(:int)
|
8
21
|
@arg2 = @context.pop_value(:code)
|
9
22
|
end
|
23
|
+
|
10
24
|
def derive
|
11
25
|
tree = NudgeProgram.new(@arg2)
|
12
26
|
tree_size = tree.points
|
@@ -15,6 +29,7 @@ class CodeNthPointInstruction < Instruction # was CODE.EXTRACT in Push3
|
|
15
29
|
pt = tree[which]
|
16
30
|
@result = ValuePoint.new("code", pt.blueprint)
|
17
31
|
end
|
32
|
+
|
18
33
|
def cleanup
|
19
34
|
pushes :code, @result
|
20
35
|
end
|
@@ -1,14 +1,25 @@
|
|
1
|
+
# pops the top +:code+ item;
|
2
|
+
# pushes a new +:bool+ item with value +true+ if the +:code+ is an empty block
|
3
|
+
#
|
4
|
+
# *needs:* 1 +:code+
|
5
|
+
#
|
6
|
+
# *pushes:* 1 +:bool+
|
7
|
+
#
|
8
|
+
|
1
9
|
class CodeNullQInstruction < Instruction
|
2
10
|
def preconditions?
|
3
11
|
needs :code, 1
|
4
12
|
end
|
13
|
+
|
5
14
|
def setup
|
6
15
|
arg_blueprint = @context.pop_value(:code)
|
7
16
|
@arg1 = NudgeProgram.new(arg_blueprint).blueprint
|
8
17
|
end
|
18
|
+
|
9
19
|
def derive
|
10
20
|
@result = ValuePoint.new("bool", @arg1 == "block {}")
|
11
21
|
end
|
22
|
+
|
12
23
|
def cleanup
|
13
24
|
pushes :bool, @result
|
14
25
|
end
|
@@ -1,3 +1,14 @@
|
|
1
|
+
# pops the top two +:code+ items;
|
2
|
+
# pushes a new +:int+ item, with value equal to the program point number in the first argument
|
3
|
+
# where the second argument appears as a subtree (or 0 otherwise)
|
4
|
+
#
|
5
|
+
# note: order of arguments is important; the top stack item is the second argument
|
6
|
+
#
|
7
|
+
# *needs:* 2 +:code+
|
8
|
+
#
|
9
|
+
# *pushes:* 1 +:int+
|
10
|
+
#
|
11
|
+
|
1
12
|
class CodePositionInstruction < Instruction
|
2
13
|
def preconditions?
|
3
14
|
needs :code, 2
|