about summary refs log tree commit diff stats
path: root/052tangle.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 /052tangle.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 '052tangle.cc')
-rw-r--r--052tangle.cc28
1 files changed, 16 insertions, 12 deletions
diff --git a/052tangle.cc b/052tangle.cc
index 8aaecbd1..39e9856d 100644
--- a/052tangle.cc
+++ b/052tangle.cc
@@ -1,10 +1,18 @@
 //: Allow code for recipes to be pulled in from multiple places and inserted
-//: at special labels called 'waypoints'. Unlike jump targets, a recipe can
-//: have multiple ambiguous waypoints with the same name. Any 'before' and
-//: 'after' fragments will simply be inserted at all applicable waypoints.
+//: at special labels called 'waypoints' using two new top-level commands:
+//:   before
+//:   after
+
+//: Most labels are local: they must be unique to a recipe, and are invisible
+//: outside the recipe. However, waypoints are global: a recipe can have
+//: multiple of them, you can't use them as jump targets.
+:(before "End is_jump_target Special-cases")
+if (is_waypoint(label)) return false;
 //: Waypoints are always surrounded by '<>', e.g. <handle-request>.
-//:
-//: todo: switch recipe.steps to a more efficient data structure.
+:(code)
+bool is_waypoint(string label) {
+  return *label.begin() == '<' && *label.rbegin() == '>';
+}
 
 :(scenario tangle_before)
 def main [
@@ -44,7 +52,7 @@ else if (command == "before") {
   if (is_waypoint(label))
     Before_fragments[label].steps.insert(Before_fragments[label].steps.end(), tmp.steps.begin(), tmp.steps.end());
   else
-    raise << "can't tangle before label " << label << '\n' << end();
+    raise << "can't tangle before non-waypoint " << label << '\n' << end();
   // End before Command Handler
 }
 else if (command == "after") {
@@ -59,7 +67,7 @@ else if (command == "after") {
   if (is_waypoint(label))
     After_fragments[label].steps.insert(After_fragments[label].steps.begin(), tmp.steps.begin(), tmp.steps.end());
   else
-    raise << "can't tangle after label " << label << '\n' << end();
+    raise << "can't tangle after non-waypoint " << label << '\n' << end();
   // End after Command Handler
 }
 
@@ -148,10 +156,6 @@ void append_fragment(vector<instruction>& base, const vector<instruction>& patch
   }
 }
 
-bool is_waypoint(string label) {
-  return *label.begin() == '<' && *label.rbegin() == '>';
-}
-
 //: complain about unapplied fragments
 //: This can't run during transform because later (shape-shifting recipes)
 //: we'll encounter situations where fragments might get used long after
@@ -202,7 +206,7 @@ def main [
 before +label1 [
   2:num <- copy 0
 ]
-+error: can't tangle before label +label1
++error: can't tangle before non-waypoint +label1
 
 :(scenario tangle_keeps_labels_separate)
 def main [