From d3c120c1e298c74235843e5b5c702decec17f0c2 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 22 Oct 2016 11:05:18 -0700 Subject: 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. --- 041jump_target.cc | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to '041jump_target.cc') 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 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& 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& 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 [ { -- cgit 1.4.1-2-gfad0