about summary refs log tree commit diff stats
path: root/041jump_target.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-10-22 11:05:18 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-10-22 11:28:46 -0700
commitd3c120c1e298c74235843e5b5c702decec17f0c2 (patch)
tree16f86b111a4b4bc5e1a5073e25e73676e66b0073 /041jump_target.cc
parent48f6d48ac99e321278fbab857566fe4ea4d53c4b (diff)
downloadmu-d3c120c1e298c74235843e5b5c702decec17f0c2.tar.gz
3549
More consistent definitions for jump targets and waypoints.

1. A label is a word starting with something other than a letter or
digit or '$'.

2. A waypoint is a label that starts with '<' and ends with '>'. It has
no restrictions. A recipe can define any number of waypoints, and
recipes can have duplicate waypoints.

3. The special labels '{' and '}' can also be duplicated any number of
times in a recipe. The only constraint on them is that they have to
balance in any recipe. Every '{' must be followed by a matching '}'.

4. All other labels are 'jump targets'. You can't have duplicate jump
targets in a recipe; that would make jumps ambiguous.
Diffstat (limited to '041jump_target.cc')
-rw-r--r--041jump_target.cc29
1 files changed, 16 insertions, 13 deletions
diff --git a/041jump_target.cc b/041jump_target.cc
index fc22c659..02d933fc 100644
--- a/041jump_target.cc
+++ b/041jump_target.cc
@@ -1,11 +1,18 @@
-//: Support jumps to special labels called 'targets'. Targets must be in the
-//: same recipe as the jump, and must be unique in that recipe. Targets always
-//: start with a '+'.
+//: Support jumps to a specific label (the 'jump target') in the same recipe.
+//: Jump targets must be unique and unambiguous within any recipe.
 //:
-//: We'll also treat 'break' and 'loop' as jumps. The choice of name is
-//: just documentation about intent; use 'break' to indicate you're exiting
-//: one or more loop nests, and 'loop' to indicate you're skipping to the next
-//: iteration of some containing loop nest.
+//: The 'break' and 'loop' pseudo instructions can also take jump targets.
+//: Which instruction you use is just documentation about intent; use 'break'
+//: to indicate you're exiting one or more loop nests, and 'loop' to indicate
+//: you're skipping to the next iteration of some containing loop nest.
+
+//: Since they have to be unique in a recipe, not all labels can be jump
+//: targets.
+bool is_jump_target(const string& label) {
+  if (label == "{" || label == "}") return false;
+  // End is_jump_target Special-cases
+  return is_label_word(label);
+}
 
 :(scenario jump_to_label)
 def main [
@@ -26,7 +33,8 @@ void transform_labels(const recipe_ordinal r) {
   map<string, int> offset;
   for (int i = 0;  i < SIZE(get(Recipe, r).steps);  ++i) {
     const instruction& inst = get(Recipe, r).steps.at(i);
-    if (starts_with(inst.label, "+")) {
+    if (!inst.is_label) continue;
+    if (is_jump_target(inst.label)) {
       if (!contains_key(offset, inst.label)) {
         put(offset, inst.label, i);
       }
@@ -65,7 +73,6 @@ void transform_labels(const recipe_ordinal r) {
   }
 }
 
-:(code)
 void replace_offset(reagent& x, /*const*/ map<string, int>& offset, const int current_offset, const recipe_ordinal r) {
   if (!is_literal(x)) {
     raise << maybe(get(Recipe, r).name) << "jump target must be offset or label but is '" << x.original_string << "'\n" << end();
@@ -87,10 +94,6 @@ void replace_offset(reagent& x, /*const*/ map<string, int>& offset, const int cu
   x.set_value(get(offset, x.name) - current_offset);
 }
 
-bool is_jump_target(string label) {
-  return starts_with(label, "+");
-}
-
 :(scenario break_to_label)
 def main [
   {