about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
0 files changed, 0 insertions, 0 deletions
a id='n54' href='#n54'>54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
//: Jump primitives

:(scenario jump_can_skip_instructions)
def main [
  jump 1:offset
  1:num <- copy 1
]
+run: jump {1: "offset"}
-run: {1: "number"} <- copy {1: "literal"}
-mem: storing 1 in location 1

:(before "End Primitive Recipe Declarations")
JUMP,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "jump", JUMP);
:(before "End Primitive Recipe Checks")
case JUMP: {
  if (SIZE(inst.ingredients) != 1) {
    raise << maybe(get(Recipe, r).name) << "'jump' requires exactly one ingredient, but got '" << inst.original_string << "'\n" << end();
    break;
  }
  if (!is_literal(inst.ingredients.at(0))) {
    raise << maybe(get(Recipe, r).name) << "first ingredient of 'jump' should be a label or offset, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  break;
}
:(before "End Primitive Recipe Implementations")
case JUMP: {
  assert(current_instruction().ingredients.at(0).initialized);
  current_step_index() += ingredients.at(0).at(0)+1;
  trace(9998, "run") << "jumping to instruction " << current_step_index() << end();
  continue;  // skip rest of this instruction
}

//: special type to designate jump targets
:(before "End Mu Types Initialization")
put(Type_ordinal, "offset", 0);

:(scenario jump_backward)
def main [
  jump 1:offset  # 0 -+
  jump 3:offset  #    |   +-+ 1
                 #   \/  /\ |
  jump -2:offset #  2 +-->+ |
]                #         \/ 3
+run: jump {1: "offset"}
+run: jump {-2: "offset"}
+run: jump {3: "offset"}

:(before "End Primitive Recipe Declarations")
JUMP_IF,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "jump-if", JUMP_IF);
:(before "End Primitive Recipe Checks")
case JUMP_IF: {
  if (SIZE(inst.ingredients) != 2) {
    raise << maybe(get(Recipe, r).name) << "'jump-if' requires exactly two ingredients, but got '" << inst.original_string << "'\n" << end();
    break;
  }
  if (!is_mu_scalar(inst.ingredients.at(0))) {
    raise << maybe(get(Recipe, r).name) << "'jump-if' requires a boolean for its first ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  if (!is_literal(inst.ingredients.at(1))) {
    raise << maybe(get(Recipe, r).name) << "'jump-if' requires a label or offset for its second ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  // End JUMP_IF Checks
  break;
}
:(before "End Primitive Recipe Implementations")
case JUMP_IF: {
  assert(current_instruction().ingredients.at(1).initialized);
  if (!ingredients.at(0).at(0)) {
    trace(9998, "run") << "jump-if fell through" << end();
    break;
  }
  current_step_index() += ingredients.at(1).at(0)+1;
  trace(9998, "run") << "jumping to instruction " << current_step_index() << end();
  continue;  // skip rest of this instruction
}

:(scenario jump_if)
def main [
  jump-if 999, 1:offset
  123:num <- copy 1
]
+run: jump-if {999: "literal"}, {1: "offset"}
+run: jumping to instruction 2
-run: {1: "number"} <- copy {1: "literal"}
-mem: storing 1 in location 123

:(scenario jump_if_fallthrough)
def main [
  jump-if 0, 1:offset
  123:num <- copy 1
]
+run: jump-if {0: "literal"}, {1: "offset"}
+run: jump-if fell through
+run: {123: "number"} <- copy {1: "literal"}
+mem: storing 1 in location 123

:(before "End Primitive Recipe Declarations")
JUMP_UNLESS,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "jump-unless", JUMP_UNLESS);
:(before "End Primitive Recipe Checks")
case JUMP_UNLESS: {
  if (SIZE(inst.ingredients) != 2) {
    raise << maybe(get(Recipe, r).name) << "'jump-unless' requires exactly two ingredients, but got '" << inst.original_string << "'\n" << end();
    break;
  }
  if (!is_mu_scalar(inst.ingredients.at(0))) {
    raise << maybe(get(Recipe, r).name) << "'jump-unless' requires a boolean for its first ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  if (!is_literal(inst.ingredients.at(1))) {
    raise << maybe(get(Recipe, r).name) << "'jump-unless' requires a label or offset for its second ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  // End JUMP_UNLESS Checks
  break;
}
:(before "End Primitive Recipe Implementations")
case JUMP_UNLESS: {
  assert(current_instruction().ingredients.at(1).initialized);
  if (ingredients.at(0).at(0)) {
    trace(9998, "run") << "jump-unless fell through" << end();
    break;
  }
  current_step_index() += ingredients.at(1).at(0)+1;
  trace(9998, "run") << "jumping to instruction " << current_step_index() << end();
  continue;  // skip rest of this instruction
}

:(scenario jump_unless)
def main [
  jump-unless 0, 1:offset
  123:num <- copy 1
]
+run: jump-unless {0: "literal"}, {1: "offset"}
+run: jumping to instruction 2
-run: {123: "number"} <- copy {1: "literal"}
-mem: storing 1 in location 123

:(scenario jump_unless_fallthrough)
def main [
  jump-unless 999, 1:offset
  123:num <- copy 1
]
+run: jump-unless {999: "literal"}, {1: "offset"}
+run: jump-unless fell through
+run: {123: "number"} <- copy {1: "literal"}
+mem: storing 1 in location 123