diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-01-29 11:10:44 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-01-29 11:10:44 -0800 |
commit | 47f1f8a81450f2ff06ca08ec40bfd98c523d5adf (patch) | |
tree | 503108f8de9eaf3b885bc5e8bfb481f42d263d62 | |
parent | 15a113ed434eeda5e5b2ea85f29b82318bbdca39 (diff) | |
download | mu-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.mu | 49 |
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) |