https://github.com/akkartik/mu/blob/master/024jump.cc
  1 //: Jump primitives
  2 
  3 :(scenario jump_can_skip_instructions)
  4 def main [
  5   jump 1:offset
  6   1:num <- copy 1
  7 ]
  8 +run: jump {1: "offset"}
  9 -run: {1: "number"} <- copy {1: "literal"}
 10 -mem: storing 1 in location 1
 11 
 12 :(before "End Primitive Recipe Declarations")
 13 JUMP,
 14 :(before "End Primitive Recipe Numbers")
 15 put(Recipe_ordinal, "jump", JUMP);
 16 :(before "End Primitive Recipe Checks")
 17 case JUMP: {
 18   if (SIZE(inst.ingredients) != 1) {
 19     raise << 
# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

if __name__ == '__main__': from __init__ import init; init()

from unittest import TestCase, main

class Test(TestCase):
	def test_wrapper(self):
		from ranger.api.keys import Wrapper

		class dummyfm(object):
			def move(self, relative):
				return "I move down by {0}".format(relative)

		class commandarg(object):
			def __init__(self):
				self.fm = dummyfm()
				self.n = None
				self.direction = None

		arg = commandarg()

		do = Wrapper('fm')
		command = do.move(relative=4)

		self.assertEqual(command(arg), 'I move down by 4')

if __name__ == '__main__': main()
nt">"'" << to_original_string(inst) << "' should get exactly two ingredients\n" << end(); 73 break; 74 } 75 if (!is_mu_address(inst.ingredients.at(0)) && !is_mu_scalar(inst.ingredients.at(0))) { 76 raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a boolean for its first ingredient, but '" << inst.ingredients.at(0).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(0).type) << "'\n" << end(); 77 break; 78 } 79 if (!is_literal(inst.ingredients.at(1))) { 80 raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a label or offset for its second ingredient, but '" << inst.ingredients.at(1).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(1).type) << "'\n" << end(); 81 break; 82 } 83 if (!inst.products.empty()) { 84 raise << maybe(get(Recipe, r).name) << "'jump-if' instructions write no products\n" << end(); 85 break; 86 } 87 // End JUMP_IF Checks 88 break; 89 } 90 :(before "End Primitive Recipe Implementations") 91 case JUMP_IF: { 92 assert(current_instruction().ingredients.at(1).initialized); 93 if (!scalar_ingredient(ingredients, 0)) { 94 trace(9998, "run") << "jump-if fell through" << end(); 95 break; 96 } 97 current_step_index() += ingredients.at(1).at(0)+1; 98 trace(9998, "run") << "jumping to instruction " << current_step_index() << end(); 99 // skip rest of this instruction 100 write_products = false; 101 fall_through_to_next_instruction = false; 102 break; 103 } 104 105 :(scenario jump_if) 106 def main [ 107 jump-if 999, 1:offset 108 123:num <- copy 1 109 ] 110 +run: jump-if {999: "literal"}, {1: "offset"} 111 +run: jumping to instruction 2 112 -run: {123: "number"} <- copy {1: "literal"} 113 -mem: storing 1 in location 123 114 115 :(scenario jump_if_fallthrough) 116 def main [ 117 jump-if 0, 1:offset 118 123:num <- copy 1 119 ] 120 +run: jump-if {0: "literal"}, {1: "offset"} 121 +run: jump-if fell through 122 +run: {123: "number"} <- copy {1: "literal"} 123 +mem: storing 1 in location 123 124 125 :(scenario jump_if_on_address) 126 def main [ 127 10:num/alloc-id, 11:num <- copy 0, 999 128 jump-if 10:&:number, 1:offset 129 123:num <- copy 1 130 ] 131 +run: jump-if {10: ("address" "number")}, {1: "offset"} 132 +run: jumping to instruction 3 133 -run: {123: "number"} <- copy {1: "literal"} 134 -mem: storing 1 in location 123 135 136 :(before "End Primitive Recipe Declarations") 137 JUMP_UNLESS, 138 :(before "End Primitive Recipe Numbers") 139 put(Recipe_ordinal, "jump-unless", JUMP_UNLESS); 140 :(before "End Primitive Recipe Checks") 141 case JUMP_UNLESS: { 142 if (SIZE(inst.ingredients) != 2) { 143 raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' should get exactly two ingredients\n" << end(); 144 break; 145 } 146 if (!is_mu_address(inst.ingredients.at(0)) && !is_mu_scalar(inst.ingredients.at(0))) { 147 raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a boolean for its first ingredient, but '" << inst.ingredients.at(0).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(0).type) << "'\n" << end(); 148 break; 149 } 150 if (!is_literal(inst.ingredients.at(1))) { 151 raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a label or offset for its second ingredient, but '" << inst.ingredients.at(1).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(1).type) << "'\n" << end(); 152 break; 153 } 154 if (!inst.products.empty()) { 155 raise << maybe(get(Recipe, r).name) << "'jump' instructions write no products\n" << end(); 156 break; 157 } 158 // End JUMP_UNLESS Checks 159 break; 160 } 161 :(before "End Primitive Recipe Implementations") 162 case JUMP_UNLESS: { 163 assert(current_instruction().ingredients.at(1).initialized); 164 if (scalar_ingredient(ingredients, 0)) { 165 trace(9998, "run") << "jump-unless fell through" << end(); 166 break; 167 } 168 current_step_index() += ingredients.at(1).at(0)+1; 169 trace(9998, "run") << "jumping to instruction " << current_step_index() << end(); 170 // skip rest of this instruction 171 write_products = false; 172 fall_through_to_next_instruction = false; 173 break; 174 } 175 176 :(scenario jump_unless) 177 def main [ 178 jump-unless 0, 1:offset 179 123:num <- copy 1 180 ] 181 +run: jump-unless {0: "literal"}, {1: "offset"} 182 +run: jumping to instruction 2 183 -run: {123: "number"} <- copy {1: "literal"} 184 -mem: storing 1 in location 123 185 186 :(scenario jump_unless_fallthrough) 187 def main [ 188 jump-unless 999, 1:offset 189 123:num <- copy 1 190 ] 191 +run: jump-unless {999: "literal"}, {1: "offset"} 192 +run: jump-unless fell through 193 +run: {123: "number"} <- copy {1: "literal"} 194 +mem: storing 1 in location 123