about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-10-22 12:08:10 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-10-22 12:08:10 -0700
commitada5eb55cb185edf30dcac48b25cc485d44677ef (patch)
treee147838f053a582e33146ac4fc4ab30ac8434e0e
parenta6deb48067f8049922f16ed3489896f7749fd39f (diff)
downloadmu-ada5eb55cb185edf30dcac48b25cc485d44677ef.tar.gz
3552
Stop requiring jump instructions to explicitly provide a ':label' type
for jump targets.

This has been a source of repeated confusion for my students:
  a) They'd add the ':label' to the label definition rather than the
  jump target (label use)
  b) They'd spend time thinking about whether the initial '+' prefix was
  part of the label name.

In the process I cleaned up a couple of things:

  - the space of names is more cleanly partitioned into labels and
    non-labels (clarifying that '_' and '-' are non-label prefixes)
  - you can't use label names as regular variables anymore
  - you can infer the type of a label just from its name
-rw-r--r--011load.cc2
-rw-r--r--047check_type_by_name.cc24
-rw-r--r--052tangle.cc3
-rw-r--r--061text.mu2
-rw-r--r--075channel.mu2
-rw-r--r--chessboard.mu2
-rw-r--r--edit/001-editor.mu12
-rw-r--r--edit/002-typing.mu6
-rw-r--r--edit/003-shortcuts.mu2
-rw-r--r--edit/004-programming-environment.mu30
-rw-r--r--edit/005-sandbox.mu18
-rw-r--r--edit/006-sandbox-copy.mu2
-rw-r--r--edit/007-sandbox-delete.mu2
-rw-r--r--edit/008-sandbox-edit.mu2
-rw-r--r--edit/009-sandbox-test.mu4
-rw-r--r--edit/010-sandbox-trace.mu2
-rw-r--r--edit/011-errors.mu2
-rw-r--r--edit/012-editor-undo.mu8
-rw-r--r--lambda-to-mu.mu2
-rw-r--r--sandbox/001-editor.mu12
-rw-r--r--sandbox/002-typing.mu6
-rw-r--r--sandbox/004-programming-environment.mu22
-rw-r--r--sandbox/005-sandbox.mu10
-rw-r--r--sandbox/006-sandbox-copy.mu2
-rw-r--r--sandbox/007-sandbox-delete.mu2
-rw-r--r--sandbox/008-sandbox-edit.mu2
-rw-r--r--sandbox/009-sandbox-test.mu4
-rw-r--r--sandbox/010-sandbox-trace.mu2
-rw-r--r--sandbox/011-errors.mu2
-rw-r--r--sandbox/012-editor-undo.mu8
30 files changed, 111 insertions, 88 deletions
diff --git a/011load.cc b/011load.cc
index c129ba4b..5dd64335 100644
--- a/011load.cc
+++ b/011load.cc
@@ -178,7 +178,7 @@ string next_word(istream& in) {
 
 bool is_label_word(const string& word) {
   assert(!word.empty());
-  return !isalnum(word.at(0)) && word.at(0) != '$';
+  return !isalnum(word.at(0)) && string("$_-").find(word.at(0)) == string::npos;
 }
 
 bool ends_with(const string& s, const char c) {
diff --git a/047check_type_by_name.cc b/047check_type_by_name.cc
index 62a6107c..96a703ce 100644
--- a/047check_type_by_name.cc
+++ b/047check_type_by_name.cc
@@ -37,6 +37,10 @@ void check_or_set_types_by_name(const recipe_ordinal r) {
 
 void deduce_missing_type(set<reagent>& known, reagent& x) {
   if (x.type) return;
+  if (is_jump_target(x.name)) {
+    x.type = new type_tree("label");
+    return;
+  }
   if (known.find(x) == known.end()) return;
   x.type = new type_tree(*known.find(x)->type);
   trace(9992, "transform") << x.name << " <= " << names_to_string(x.type) << end();
@@ -46,6 +50,11 @@ void check_type(set<reagent>& known, const reagent& x, const recipe& caller) {
   if (is_literal(x)) return;
   if (is_integer(x.name)) return;  // if you use raw locations you're probably doing something unsafe
   if (!x.type) return;  // might get filled in by other logic later
+  if (is_jump_target(x.name)) {
+    if (!x.type->atom || x.type->name != "label")
+      raise << maybe(caller.name) << "non-label '" << x.name << "' must begin with a letter\n" << end();
+    return;
+  }
   if (known.find(x) == known.end()) {
     trace(9992, "transform") << x.name << " => " << names_to_string(x.type) << end();
     known.insert(x);
@@ -90,6 +99,14 @@ def main [
 # x is in location 1
 +mem: storing 2 in location 1
 
+:(scenario transform_fills_in_missing_label_type)
+def main [
+  jump +target
+  1:num <- copy 0
+  +target
+]
+-mem: storing 0 in location 1
+
 :(scenario transform_fails_on_missing_types_in_first_mention)
 % Hide_errors = true;
 def main [
@@ -98,6 +115,13 @@ def main [
 ]
 +error: main: missing type for 'x' in 'x <- copy 1'
 
+:(scenario transform_fails_on_wrong_type_for_label)
+% Hide_errors = true;
+def main [
+  +foo:num <- copy 34
+]
++error: main: non-label '+foo' must begin with a letter
+
 :(scenario typo_in_address_type_fails)
 % Hide_errors = true;
 def main [
diff --git a/052tangle.cc b/052tangle.cc
index 39e9856d..f53e8736 100644
--- a/052tangle.cc
+++ b/052tangle.cc
@@ -148,8 +148,7 @@ void append_fragment(vector<instruction>& base, const vector<instruction>& patch
     }
     for (int j = 0;  j < SIZE(inst.ingredients);  ++j) {
       reagent& x = inst.ingredients.at(j);
-      if (!is_literal(x)) continue;
-      if (x.type->name == "label" && contains_key(jump_targets, x.name))
+      if (is_jump_target(x.name) && contains_key(jump_targets, x.name))
         x.name = prefix+x.name;
     }
     base.push_back(inst);
diff --git a/061text.mu b/061text.mu
index f01c4c58..eeb90829 100644
--- a/061text.mu
+++ b/061text.mu
@@ -506,7 +506,7 @@ def interpolate template:text -> result:text [
     {
       # while i < template.length
       tem-done?:bool <- greater-or-equal i, tem-len
-      break-if tem-done?, +done:label
+      break-if tem-done?, +done
       # while template[i] != '_'
       in:char <- index *template, i
       underscore?:bool <- equal in, 95/_
diff --git a/075channel.mu b/075channel.mu
index 6f26d49b..a023b294 100644
--- a/075channel.mu
+++ b/075channel.mu
@@ -404,7 +404,7 @@ def buffer-lines in:&:source:char, buffered-out:&:sink:char -> buffered-out:&:si
           *line <- put *line, length:offset, buffer-length
         }
         # and don't append this one
-        loop +next-character:label
+        loop +next-character
       }
       # append anything else
       line <- append line, c
diff --git a/chessboard.mu b/chessboard.mu
index 2030d910..f78027ab 100644
--- a/chessboard.mu
+++ b/chessboard.mu
@@ -90,7 +90,7 @@ def chessboard screen:&:screen, console:&:console -> screen:&:screen, console:&:
       cursor-to-next-line screen
       screen <- print screen, [move: ]
       m:&:move, quit:bool, error:bool <- read-move buffered-stdin-in, screen
-      break-if quit, +quit:label
+      break-if quit, +quit
       buffered-stdin-in <- clear buffered-stdin-in  # cleanup after error. todo: test this?
       loop-if error
     }
diff --git a/edit/001-editor.mu b/edit/001-editor.mu
index bbe16390..82f4c4fa 100644
--- a/edit/001-editor.mu
+++ b/edit/001-editor.mu
@@ -180,7 +180,7 @@ def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, sc
       screen <- move-cursor screen, row, column
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -194,7 +194,7 @@ def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, sc
       row <- add row, 1
       screen <- move-cursor screen, row, column
       # don't increment curr
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     curr <- next curr
@@ -414,7 +414,7 @@ def get-color color:num, c:char -> color:num [
     break-unless starting-comment?
     trace 90, [app], [switch color back to blue]
     color <- copy 12/lightblue
-    jump +exit:label
+    jump +exit
   }
   # if color is blue and next character is newline, switch color to white
   {
@@ -424,7 +424,7 @@ def get-color color:num, c:char -> color:num [
     break-unless ending-comment?
     trace 90, [app], [switch color back to white]
     color <- copy 7/white
-    jump +exit:label
+    jump +exit
   }
   # if color is white (no comments) and next character is '<', switch color to red
   {
@@ -432,7 +432,7 @@ def get-color color:num, c:char -> color:num [
     starting-assignment?:bool <- equal c, 60/<
     break-unless starting-assignment?
     color <- copy 1/red
-    jump +exit:label
+    jump +exit
   }
   # if color is red and next character is space, switch color to white
   {
@@ -441,7 +441,7 @@ def get-color color:num, c:char -> color:num [
     ending-assignment?:bool <- equal c, 32/space
     break-unless ending-assignment?
     color <- copy 7/white
-    jump +exit:label
+    jump +exit
   }
   # otherwise no change
   +exit
diff --git a/edit/002-typing.mu b/edit/002-typing.mu
index 2f94f362..12448e18 100644
--- a/edit/002-typing.mu
+++ b/edit/002-typing.mu
@@ -29,7 +29,7 @@ def editor-event-loop screen:&:screen, console:&:console, editor:&:editor -> scr
     {
       break-unless is-touch?
       move-cursor-in-editor screen, editor, t
-      loop +next-event:label
+      loop +next-event
     }
     # keyboard events
     {
@@ -125,7 +125,7 @@ def snap-cursor screen:&:screen, editor:&:editor, target-row:num, target-column:
       column <- copy left
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -135,7 +135,7 @@ def snap-cursor screen:&:screen, editor:&:editor, target-row:num, target-column:
       column <- copy left
       row <- add row, 1
       # don't increment curr/prev
-      loop +next-character:label
+      loop +next-character
     }
     curr <- next curr
     prev <- next prev
diff --git a/edit/003-shortcuts.mu b/edit/003-shortcuts.mu
index 2dbc481a..4c4caf38 100644
--- a/edit/003-shortcuts.mu
+++ b/edit/003-shortcuts.mu
@@ -1242,7 +1242,7 @@ def move-to-next-line editor:&:editor, screen-height:num -> editor:&:editor, go-
       no-motion?:bool <- equal next-line, before-cursor
       break-unless no-motion?
       scroll?:bool <- greater-than cursor-row, 1
-      break-if scroll?, +try-to-scroll:label
+      break-if scroll?, +try-to-scroll
       go-render? <- copy 0/false
       return
     }
diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu
index 4355aaef..d7107b35 100644
--- a/edit/004-programming-environment.mu
+++ b/edit/004-programming-environment.mu
@@ -85,7 +85,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
       # todo: test this
       touch-type:num <- get t, type:offset
       is-left-click?:bool <- equal touch-type, 65513/mouse-left
-      loop-unless is-left-click?, +next-event:label
+      loop-unless is-left-click?, +next-event
       click-row:num <- get t, row:offset
       click-column:num <- get t, column:offset
       # later exceptions for non-editor touches will go here
@@ -95,7 +95,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
       sandbox-in-focus?:bool <- move-cursor-in-editor screen, current-sandbox, t
       *env <- put *env, sandbox-in-focus?:offset, sandbox-in-focus?
       screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
-      loop +next-event:label
+      loop +next-event
     }
     # 'resize' event - redraw editor
     # todo: test this after supporting resize in assume-console
@@ -114,7 +114,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
         screen <- render-all screen, env, render-without-moving-cursor
         render-all-on-no-more-events? <- copy 0/false  # full render done
       }
-      loop +next-event:label
+      loop +next-event
     }
     # if it's not global and not a touch event, send to appropriate editor
     {
@@ -129,7 +129,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
         {
           break-unless more-events?
           render-all-on-no-more-events? <- copy 1/true  # no rendering now, full rendering on some future event
-          jump +finish-event:label
+          jump +finish-event
         }
         {
           break-if more-events?
@@ -138,13 +138,13 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
             # no more events, and we have to force render
             screen <- render-all screen, env, render
             render-all-on-no-more-events? <- copy 0/false
-            jump +finish-event:label
+            jump +finish-event
           }
           # no more events, no force render
           {
             break-unless render?
             screen <- render-recipes screen, env, render
-            jump +finish-event:label
+            jump +finish-event
           }
         }
       }
@@ -157,7 +157,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
         {
           break-unless more-events?
           render-all-on-no-more-events? <- copy 1/true  # no rendering now, full rendering on some future event
-          jump +finish-event:label
+          jump +finish-event
         }
         {
           break-if more-events?
@@ -166,13 +166,13 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
             # no more events, and we have to force render
             screen <- render-all screen, env, render
             render-all-on-no-more-events? <- copy 0/false
-            jump +finish-event:label
+            jump +finish-event
           }
           # no more events, no force render
           {
             break-unless render?
             screen <- render-sandbox-side screen, env, render
-            jump +finish-event:label
+            jump +finish-event
           }
         }
       }
@@ -263,7 +263,7 @@ def render-without-moving-cursor screen:&:screen, editor:&:editor -> last-row:nu
       screen <- move-cursor screen, row, column
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -277,7 +277,7 @@ def render-without-moving-cursor screen:&:screen, editor:&:editor -> last-row:nu
       row <- add row, 1
       screen <- move-cursor screen, row, column
       # don't increment curr
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     curr <- next curr
@@ -564,7 +564,7 @@ def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
-      loop +next-character:label  # retry i
+      loop +next-character  # retry i
     }
     i <- add i, 1
     {
@@ -583,7 +583,7 @@ def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num
       row <- add row, 1
       column <- copy left
       screen <- move-cursor screen, row, column
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     column <- add column, 1
@@ -606,7 +606,7 @@ after <global-type> [
     break-unless redraw-screen?
     screen <- render-all screen, env:&:environment, render
     sync-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -621,7 +621,7 @@ after <global-type> [
     sandbox-in-focus? <- not sandbox-in-focus?
     *env <- put *env, sandbox-in-focus?:offset, sandbox-in-focus?
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu
index 1b9343a5..bc0488f7 100644
--- a/edit/005-sandbox.mu
+++ b/edit/005-sandbox.mu
@@ -137,7 +137,7 @@ after <global-keypress> [
       screen <- update-status screen, [                 ], 245/grey
     }
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -380,7 +380,7 @@ def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
-      loop +next-character:label  # retry i
+      loop +next-character  # retry i
     }
     i <- add i, 1
     {
@@ -399,7 +399,7 @@ def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num
       row <- add row, 1
       column <- copy left
       screen <- move-cursor screen, row, column
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     column <- add column, 1
@@ -706,7 +706,7 @@ after <global-keypress> [
     break-unless at-bottom-of-editor?
     more-to-scroll?:bool <- more-to-scroll? env, screen
     break-if more-to-scroll?
-    loop +next-event:label
+    loop +next-event
   }
   {
     break-if sandbox-in-focus?
@@ -714,7 +714,7 @@ after <global-keypress> [
     break-unless page-down?
     more-to-scroll?:bool <- more-to-scroll? env, screen
     break-if more-to-scroll?
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -725,7 +725,7 @@ after <global-type> [
     break-unless page-down?
     more-to-scroll?:bool <- more-to-scroll? env, screen
     break-if more-to-scroll?
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -863,14 +863,14 @@ after <global-keypress> [
       number-of-sandboxes:num <- get *env, number-of-sandboxes:offset
       max:num <- subtract number-of-sandboxes, 1
       at-end?:bool <- greater-or-equal render-from, max
-      jump-if at-end?, +finish-event:label  # render nothing
+      jump-if at-end?, +finish-event  # render nothing
       render-from <- add render-from, 1
       *env <- put *env, render-from:offset, render-from
     }
     hide-screen screen
     screen <- render-sandbox-side screen, env, render
     show-screen screen
-    jump +finish-event:label
+    jump +finish-event
   }
 ]
 
@@ -901,7 +901,7 @@ after <global-keypress> [
     hide-screen screen
     screen <- render-sandbox-side screen, env, render
     show-screen screen
-    jump +finish-event:label
+    jump +finish-event
   }
 ]
 
diff --git a/edit/006-sandbox-copy.mu b/edit/006-sandbox-copy.mu
index 404601cd..e3f7fe55 100644
--- a/edit/006-sandbox-copy.mu
+++ b/edit/006-sandbox-copy.mu
@@ -136,7 +136,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/edit/007-sandbox-delete.mu b/edit/007-sandbox-delete.mu
index 0458449e..c7c01451 100644
--- a/edit/007-sandbox-delete.mu
+++ b/edit/007-sandbox-delete.mu
@@ -74,7 +74,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/edit/008-sandbox-edit.mu b/edit/008-sandbox-edit.mu
index 0bdc7db5..5ca39e14 100644
--- a/edit/008-sandbox-edit.mu
+++ b/edit/008-sandbox-edit.mu
@@ -131,7 +131,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/edit/009-sandbox-test.mu b/edit/009-sandbox-test.mu
index 564c6cf9..fe9ef059 100644
--- a/edit/009-sandbox-test.mu
+++ b/edit/009-sandbox-test.mu
@@ -134,7 +134,7 @@ after <global-touch> [
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
     # no change in cursor
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -197,7 +197,7 @@ after <render-sandbox-response> [
       break-unless response-is-expected?:bool
       row, screen <- render-text screen, sandbox-response, left, right, 2/green, row
     }
-    jump +render-sandbox-end:label
+    jump +render-sandbox-end
   }
 ]
 
diff --git a/edit/010-sandbox-trace.mu b/edit/010-sandbox-trace.mu
index 1de23a3b..90ee417e 100644
--- a/edit/010-sandbox-trace.mu
+++ b/edit/010-sandbox-trace.mu
@@ -197,7 +197,7 @@ after <global-touch> [
     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
     # no change in cursor
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/edit/011-errors.mu b/edit/011-errors.mu
index d53fa80d..c0d4a63b 100644
--- a/edit/011-errors.mu
+++ b/edit/011-errors.mu
@@ -110,7 +110,7 @@ after <render-sandbox-trace-done> [
     *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0  # no response
     row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row
     # don't try to print anything more for this sandbox
-    jump +render-sandbox-end:label
+    jump +render-sandbox-end
   }
 ]
 
diff --git a/edit/012-editor-undo.mu b/edit/012-editor-undo.mu
index 9ea67e03..d991b25f 100644
--- a/edit/012-editor-undo.mu
+++ b/edit/012-editor-undo.mu
@@ -162,7 +162,7 @@ before <insert-character-end> [
     typing <- put typing, after-column:offset, cursor-column
     typing <- put typing, after-top-of-screen:offset, top-after
     *op <- merge 0/insert-operation, typing
-    break +done-adding-insert-operation:label
+    break +done-adding-insert-operation
   }
   # if not, create a new operation
   insert-from:&:duplex-list:char <- next cursor-before
@@ -742,7 +742,7 @@ before <move-cursor-end> [
     move <- put move, after-column:offset, cursor-column
     move <- put move, after-top-of-screen:offset, top-after
     *op <- merge 1/move-operation, move
-    break +done-adding-move-operation:label
+    break +done-adding-move-operation
   }
   op:&:operation <- new operation:type
   *op <- merge 1/move-operation, cursor-row-before, cursor-column-before, top-before, cursor-row/after, cursor-column/after, top-after, undo-coalesce-tag
@@ -1643,7 +1643,7 @@ before <backspace-character-end> [
       deletion <- put deletion, after-column:offset, cursor-column
       deletion <- put deletion, after-top-of-screen:offset, top-after
       *op <- merge 2/delete-operation, deletion
-      break +done-adding-backspace-operation:label
+      break +done-adding-backspace-operation
     }
     # if not, create a new operation
     op:&:operation <- new operation:type
@@ -1870,7 +1870,7 @@ before <delete-character-end> [
       deletion <- put deletion, after-column:offset, cursor-column
       deletion <- put deletion, after-top-of-screen:offset, top-after
       *op <- merge 2/delete-operation, deletion
-      break +done-adding-delete-operation:label
+      break +done-adding-delete-operation
     }
     # if not, create a new operation
     op:&:operation <- new operation:type
diff --git a/lambda-to-mu.mu b/lambda-to-mu.mu
index 6c358d9f..4cd9da7d 100644
--- a/lambda-to-mu.mu
+++ b/lambda-to-mu.mu
@@ -232,7 +232,7 @@ def parse in:&:stream:char -> out:&:cell, in:&:stream:char [
         close-paren?:bool <- equal c, 41/close-paren
         break-unless close-paren?
         read in  # skip ')'
-        break +end-pair:label
+        break +end-pair
       }
       # still here? read next element of pair
       next:&:cell, in <- parse in
diff --git a/sandbox/001-editor.mu b/sandbox/001-editor.mu
index 7f799445..034d4cc9 100644
--- a/sandbox/001-editor.mu
+++ b/sandbox/001-editor.mu
@@ -180,7 +180,7 @@ def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, sc
       screen <- move-cursor screen, row, column
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -194,7 +194,7 @@ def render screen:&:screen, editor:&:editor -> last-row:num, last-column:num, sc
       row <- add row, 1
       screen <- move-cursor screen, row, column
       # don't increment curr
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     curr <- next curr
@@ -414,7 +414,7 @@ def get-color color:num, c:char -> color:num [
     break-unless starting-comment?
     trace 90, [app], [switch color back to blue]
     color <- copy 12/lightblue
-    jump +exit:label
+    jump +exit
   }
   # if color is blue and next character is newline, switch color to white
   {
@@ -424,7 +424,7 @@ def get-color color:num, c:char -> color:num [
     break-unless ending-comment?
     trace 90, [app], [switch color back to white]
     color <- copy 7/white
-    jump +exit:label
+    jump +exit
   }
   # if color is white (no comments) and next character is '<', switch color to red
   {
@@ -432,7 +432,7 @@ def get-color color:num, c:char -> color:num [
     starting-assignment?:bool <- equal c, 60/<
     break-unless starting-assignment?
     color <- copy 1/red
-    jump +exit:label
+    jump +exit
   }
   # if color is red and next character is space, switch color to white
   {
@@ -441,7 +441,7 @@ def get-color color:num, c:char -> color:num [
     ending-assignment?:bool <- equal c, 32/space
     break-unless ending-assignment?
     color <- copy 7/white
-    jump +exit:label
+    jump +exit
   }
   # otherwise no change
   +exit
diff --git a/sandbox/002-typing.mu b/sandbox/002-typing.mu
index 2f94f362..12448e18 100644
--- a/sandbox/002-typing.mu
+++ b/sandbox/002-typing.mu
@@ -29,7 +29,7 @@ def editor-event-loop screen:&:screen, console:&:console, editor:&:editor -> scr
     {
       break-unless is-touch?
       move-cursor-in-editor screen, editor, t
-      loop +next-event:label
+      loop +next-event
     }
     # keyboard events
     {
@@ -125,7 +125,7 @@ def snap-cursor screen:&:screen, editor:&:editor, target-row:num, target-column:
       column <- copy left
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -135,7 +135,7 @@ def snap-cursor screen:&:screen, editor:&:editor, target-row:num, target-column:
       column <- copy left
       row <- add row, 1
       # don't increment curr/prev
-      loop +next-character:label
+      loop +next-character
     }
     curr <- next curr
     prev <- next prev
diff --git a/sandbox/004-programming-environment.mu b/sandbox/004-programming-environment.mu
index af136deb..76938021 100644
--- a/sandbox/004-programming-environment.mu
+++ b/sandbox/004-programming-environment.mu
@@ -73,14 +73,14 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
       # todo: test this
       touch-type:num <- get t, type:offset
       is-left-click?:bool <- equal touch-type, 65513/mouse-left
-      loop-unless is-left-click?, +next-event:label
+      loop-unless is-left-click?, +next-event
       click-row:num <- get t, row:offset
       click-column:num <- get t, column:offset
       # later exceptions for non-editor touches will go here
       <global-touch>
       move-cursor-in-editor screen, current-sandbox, t
       screen <- update-cursor screen, current-sandbox, env
-      loop +next-event:label
+      loop +next-event
     }
     # 'resize' event - redraw editor
     # todo: test this after supporting resize in assume-console
@@ -99,7 +99,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
         screen <- render-all screen, env, render-without-moving-cursor
         render-all-on-no-more-events? <- copy 0/false  # full render done
       }
-      loop +next-event:label
+      loop +next-event
     }
     # if it's not global and not a touch event, send to appropriate editor
     {
@@ -111,7 +111,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
       {
         break-unless more-events?
         render-all-on-no-more-events? <- copy 1/true  # no rendering now, full rendering on some future event
-        jump +finish-event:label
+        jump +finish-event
       }
       {
         break-if more-events?
@@ -120,13 +120,13 @@ def event-loop screen:&:screen, console:&:console, env:&:environment -> screen:&
           # no more events, and we have to force render
           screen <- render-all screen, env, render
           render-all-on-no-more-events? <- copy 0/false
-          jump +finish-event:label
+          jump +finish-event
         }
         # no more events, no force render
         {
           break-unless render?
           screen <- render-sandbox-side screen, env, render
-          jump +finish-event:label
+          jump +finish-event
         }
       }
       +finish-event
@@ -206,7 +206,7 @@ def render-without-moving-cursor screen:&:screen, editor:&:editor -> last-row:nu
       screen <- move-cursor screen, row, column
       curr <- next curr
       prev <- next prev
-      loop +next-character:label
+      loop +next-character
     }
     {
       # at right? wrap. even if there's only one more letter left; we need
@@ -220,7 +220,7 @@ def render-without-moving-cursor screen:&:screen, editor:&:editor -> last-row:nu
       row <- add row, 1
       screen <- move-cursor screen, row, column
       # don't increment curr
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     curr <- next curr
@@ -312,7 +312,7 @@ def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
-      loop +next-character:label  # retry i
+      loop +next-character  # retry i
     }
     i <- add i, 1
     {
@@ -331,7 +331,7 @@ def render-code screen:&:screen, s:text, left:num, right:num, row:num -> row:num
       row <- add row, 1
       column <- copy left
       screen <- move-cursor screen, row, column
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     column <- add column, 1
@@ -354,7 +354,7 @@ after <global-type> [
     break-unless redraw-screen?
     screen <- render-all screen, env:&:environment, render
     sync-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/sandbox/005-sandbox.mu b/sandbox/005-sandbox.mu
index 45dc259c..7787b50c 100644
--- a/sandbox/005-sandbox.mu
+++ b/sandbox/005-sandbox.mu
@@ -118,7 +118,7 @@ after <global-keypress> [
       screen <- update-status screen, [                 ], 245/grey
     }
     screen <- update-cursor screen, current-sandbox, env
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -366,7 +366,7 @@ def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num
       column <- copy left
       row <- add row, 1
       screen <- move-cursor screen, row, column
-      loop +next-character:label  # retry i
+      loop +next-character  # retry i
     }
     i <- add i, 1
     {
@@ -385,7 +385,7 @@ def render-text screen:&:screen, s:text, left:num, right:num, color:num, row:num
       row <- add row, 1
       column <- copy left
       screen <- move-cursor screen, row, column
-      loop +next-character:label
+      loop +next-character
     }
     print screen, c, color
     column <- add column, 1
@@ -708,7 +708,7 @@ after <global-keypress> [
     hide-screen screen
     screen <- render-sandbox-side screen, env, render
     show-screen screen
-    jump +finish-event:label
+    jump +finish-event
   }
 ]
 
@@ -737,7 +737,7 @@ after <global-keypress> [
     hide-screen screen
     screen <- render-sandbox-side screen, env, render
     show-screen screen
-    jump +finish-event:label
+    jump +finish-event
   }
 ]
 
diff --git a/sandbox/006-sandbox-copy.mu b/sandbox/006-sandbox-copy.mu
index fdc1409a..ddec749f 100644
--- a/sandbox/006-sandbox-copy.mu
+++ b/sandbox/006-sandbox-copy.mu
@@ -136,7 +136,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, current-sandbox, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/sandbox/007-sandbox-delete.mu b/sandbox/007-sandbox-delete.mu
index dba40a8f..9577a3b3 100644
--- a/sandbox/007-sandbox-delete.mu
+++ b/sandbox/007-sandbox-delete.mu
@@ -71,7 +71,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, current-sandbox, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/sandbox/008-sandbox-edit.mu b/sandbox/008-sandbox-edit.mu
index 42778faa..f4fe0498 100644
--- a/sandbox/008-sandbox-edit.mu
+++ b/sandbox/008-sandbox-edit.mu
@@ -60,7 +60,7 @@ after <global-touch> [
     screen <- render-sandbox-side screen, env, render
     screen <- update-cursor screen, current-sandbox, env
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/sandbox/009-sandbox-test.mu b/sandbox/009-sandbox-test.mu
index f27b4a06..1c36a769 100644
--- a/sandbox/009-sandbox-test.mu
+++ b/sandbox/009-sandbox-test.mu
@@ -131,7 +131,7 @@ after <global-touch> [
     screen <- update-cursor screen, current-sandbox, env
     # no change in cursor
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
@@ -194,7 +194,7 @@ after <render-sandbox-response> [
       break-unless response-is-expected?:bool
       row, screen <- render-text screen, sandbox-response, left, right, 2/green, row
     }
-    jump +render-sandbox-end:label
+    jump +render-sandbox-end
   }
 ]
 
diff --git a/sandbox/010-sandbox-trace.mu b/sandbox/010-sandbox-trace.mu
index 15a4f931..3368c491 100644
--- a/sandbox/010-sandbox-trace.mu
+++ b/sandbox/010-sandbox-trace.mu
@@ -189,7 +189,7 @@ after <global-touch> [
     screen <- update-cursor screen, current-sandbox, env
     # no change in cursor
     show-screen screen
-    loop +next-event:label
+    loop +next-event
   }
 ]
 
diff --git a/sandbox/011-errors.mu b/sandbox/011-errors.mu
index bd6d4e7c..6755af2d 100644
--- a/sandbox/011-errors.mu
+++ b/sandbox/011-errors.mu
@@ -120,7 +120,7 @@ after <render-sandbox-trace-done> [
     }
     row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row
     # don't try to print anything more for this sandbox
-    jump +render-sandbox-end:label
+    jump +render-sandbox-end
   }
 ]
 
diff --git a/sandbox/012-editor-undo.mu b/sandbox/012-editor-undo.mu
index ce8c9e21..27f49377 100644
--- a/sandbox/012-editor-undo.mu
+++ b/sandbox/012-editor-undo.mu
@@ -162,7 +162,7 @@ before <insert-character-end> [
     typing <- put typing, after-column:offset, cursor-column
     typing <- put typing, after-top-of-screen:offset, top-after
     *op <- merge 0/insert-operation, typing
-    break +done-adding-insert-operation:label
+    break +done-adding-insert-operation
   }
   # if not, create a new operation
   insert-from:&:duplex-list:char <- next cursor-before
@@ -742,7 +742,7 @@ before <move-cursor-end> [
     move <- put move, after-column:offset, cursor-column
     move <- put move, after-top-of-screen:offset, top-after
     *op <- merge 1/move-operation, move
-    break +done-adding-move-operation:label
+    break +done-adding-move-operation
   }
   op:&:operation <- new operation:type
   *op <- merge 1/move-operation, cursor-row-before, cursor-column-before, top-before, cursor-row/after, cursor-column/after, top-after, undo-coalesce-tag
@@ -1441,7 +1441,7 @@ before <backspace-character-end> [
       deletion <- put deletion, after-column:offset, cursor-column
       deletion <- put deletion, after-top-of-screen:offset, top-after
       *op <- merge 2/delete-operation, deletion
-      break +done-adding-backspace-operation:label
+      break +done-adding-backspace-operation
     }
     # if not, create a new operation
     op:&:operation <- new operation:type
@@ -1668,7 +1668,7 @@ before <delete-character-end> [
       deletion <- put deletion, after-column:offset, cursor-column
       deletion <- put deletion, after-top-of-screen:offset, top-after
       *op <- merge 2/delete-operation, deletion
-      break +done-adding-delete-operation:label
+      break +done-adding-delete-operation
     }
     # if not, create a new operation
     op:&:operation <- new operation:type