about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-01-29 11:10:44 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-01-29 11:10:44 -0800
commit47f1f8a81450f2ff06ca08ec40bfd98c523d5adf (patch)
tree503108f8de9eaf3b885bc5e8bfb481f42d263d62
parent15a113ed434eeda5e5b2ea85f29b82318bbdca39 (diff)
downloadmu-47f1f8a81450f2ff06ca08ec40bfd98c523d5adf.tar.gz
672 - replace label 'next-key' with continuation
Works beautifully!

This is the first step to hoisting all the code for reading a key into
its own function. In other languages extracting arbitrary code into a
function requires passing all arguments into it, which is annoying and
hard to read. In mu you can just pass your default-space to it to share
all local variables. But there's been one additional complication until
now: labels, which are namespaced by function. Now we can replace
labels with continuations and extract arbitrary code into new functions.

Might be confusing to lose a few stack frames. Might end up undoing
values of some important local. We'll see if we run into that.
-rw-r--r--color-repl.mu49
1 files changed, 35 insertions, 14 deletions
diff --git a/color-repl.mu b/color-repl.mu
index 85e2c05d..dd63a08c 100644
--- a/color-repl.mu
+++ b/color-repl.mu
@@ -20,15 +20,18 @@
   { begin
     ; repeatedly read keys from the keyboard
     ;   test: 34<enter>
-    next-key
+    (next-key:continuation <- current-continuation)
     (c:character <- $wait-for-key-from-host)
+;?     (print-primitive-to-host 1:literal) ;? 1
     (maybe-cancel-this-sexp c:character abort:continuation)
+;?     (print-primitive-to-host 2:literal) ;? 1
     ; check for ctrl-d and exit
     { begin
       (eof?:boolean <- equal c:character ((ctrl-d literal)))
       (break-unless eof?:boolean)
       (reply nil:literal)
     }
+;?     (print-primitive-to-host 3:literal) ;? 1
     ; check for backspace
     ;   test: 3<backspace>4<enter>
     ;   todo: backspace past newline
@@ -49,7 +52,7 @@
           (backspaced-over-close-quote?:boolean <- backspaced-over-unescaped? result:buffer-address ((#\" literal)) escapes:buffer-address)  ; "
           (break-unless backspaced-over-close-quote?:boolean)
           (slurp-string result:buffer-address escapes:buffer-address abort:continuation)
-          (jump next-key:offset)
+          (continue-from next-key:continuation)
         }
         ;   test: (+ 1 (<backspace>2)
         ;   test: (+ 1 #\(<backspace><backspace><backspace>2)
@@ -57,7 +60,7 @@
           (backspaced-over-open-paren?:boolean <- backspaced-over-unescaped? result:buffer-address ((#\( literal)) escapes:buffer-address)
           (break-unless backspaced-over-open-paren?:boolean)
           (open-parens:integer <- subtract open-parens:integer 1:literal)
-          (jump next-key:offset)
+          (continue-from next-key:continuation)
         }
         ;   test: (+ 1 2)<backspace> 3)
         ;   test: (+ 1 2#\)<backspace><backspace><backspace> 3)
@@ -65,24 +68,27 @@
           (backspaced-over-close-paren?:boolean <- backspaced-over-unescaped? result:buffer-address ((#\) literal)) escapes:buffer-address)
           (break-unless backspaced-over-close-paren?:boolean)
           (open-parens:integer <- add open-parens:integer 1:literal)
-          (jump next-key:offset)
+          (continue-from next-key:continuation)
         }
       }
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 4:literal) ;? 1
     ; not a backspace; save character
 ;?     (print-primitive-to-host (("append\n" literal))) ;? 1
     (result:buffer-address <- append result:buffer-address c:character)
 ;?     (print-primitive-to-host (("done\n" literal))) ;? 1
     ; if it's backslash, read, save and print one additional character
     ;   test: (prn #\()
+;?     (print-primitive-to-host 5:literal) ;? 1
     { begin
       (backslash?:boolean <- equal c:character ((#\\ literal)))
       (break-unless backslash?:boolean)
       ($print-key-to-host c:character 7:literal/white)
       (result:buffer-address escapes:buffer-address <- slurp-escaped-character result:buffer-address 7:literal/white escapes:buffer-address abort:continuation)
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 6:literal) ;? 1
     ; if it's a semi-colon, parse a comment
     { begin
       (comment?:boolean <- equal c:character ((#\; literal)))
@@ -91,7 +97,10 @@
       (comment-read?:boolean <- slurp-comment result:buffer-address escapes:buffer-address abort:continuation)
       ; return if comment was read (i.e. consumed a newline)
       ; test: ;a<backspace><backspace> (shouldn't end command until <enter>)
-      (jump-unless comment-read?:boolean next-key:offset)
+      { begin
+        (break-if comment-read?:boolean)
+        (continue-from next-key:continuation)
+      }
       ; and we're not within parens
       ;   test: (+ 1 2)  ; comment<enter>
       ;   test: (+ 1<enter>; abc<enter>2)<enter>
@@ -99,9 +108,13 @@
       ;   too expensive to build: 3<backspace>; comment<enter>(+ 1 2)<enter>
       (at-top-level?:boolean <- lesser-or-equal open-parens:integer 0:literal)
       (end-sexp?:boolean <- and at-top-level?:boolean not-empty?:boolean)
-      (jump-unless end-sexp?:boolean next-key:offset)
+      { begin
+        (break-if end-sexp?:boolean)
+        (continue-from next-key:continuation)
+      }
       (jump end:offset)
     }
+;?     (print-primitive-to-host 7:literal) ;? 1
     ; if it's not whitespace, set not-empty? and continue
     { begin
       (space?:boolean <- equal c:character ((#\space literal)))
@@ -113,14 +126,16 @@
       (not-empty?:boolean <- copy t:literal)
       ; fall through
     }
+;?     (print-primitive-to-host 8:literal) ;? 1
     ; if it's a quote, parse a string
     { begin
       (string-started?:boolean <- equal c:character ((#\" literal)))  ; for vim: "
       (break-unless string-started?:boolean)
       ($print-key-to-host c:character 6:literal/fg/cyan)
       (slurp-string result:buffer-address escapes:buffer-address abort:continuation)
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 9:literal) ;? 1
     ; color parens by depth, so they're easy to balance
     ;   test: (+ 1 1)<enter>
     ;   test: (def foo () (+ 1 (* 2 3)))<enter>
@@ -132,8 +147,9 @@
       ($print-key-to-host c:character color-code:integer)
       (open-parens:integer <- add open-parens:integer 1:literal)
 ;?       (print-primitive-to-host open-parens:integer) ;? 1
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 10:literal) ;? 1
     { begin
       (close-paren?:boolean <- equal c:character ((#\) literal)))
       (break-unless close-paren?:boolean)
@@ -142,8 +158,9 @@
       (color-code:integer <- add color-code:integer 1:literal)
       ($print-key-to-host c:character color-code:integer)
 ;?       (print-primitive-to-host open-parens:integer) ;? 1
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 11:literal) ;? 1
     ; if it's a newline, decide whether to return
     ;   test: <enter>34<enter>
     { begin
@@ -152,17 +169,21 @@
       ($print-key-to-host c:character)
       (at-top-level?:boolean <- lesser-or-equal open-parens:integer 0:literal)
       (end-sexp?:boolean <- and at-top-level?:boolean not-empty?:boolean)
-      (jump-unless end-sexp?:boolean next-key:offset)
+      { begin
+        (break-if end-sexp?:boolean)
+        (continue-from next-key:continuation)
+      }
       (jump-if end-sexp?:boolean end:offset)
-      (jump next-key:offset)
+      (continue-from next-key:continuation)
     }
+;?     (print-primitive-to-host 12:literal) ;? 1
     ; if all else fails, print the character without color
     ($print-key-to-host c:character)
     ;   todo: error on space outside parens, like python
     ;   todo: []
     ;   todo: history on up/down
     ;   todo: don't return if there's no non-whitespace in result
-    (jump next-key:offset)
+    (continue-from next-key:continuation)
   }
   end
   (s:string-address <- get result:buffer-address/deref data:offset)