(Arne Babenhauserheide)
2016-10-10: three witches: refactor to allow word-by-word output with aligned three-witches-space-in-name three witches: refactor to allow word-by-word output with aligned inline code execution This requires piing everything through macros
diff --git a/examples/enter-three-witches.w b/examples/enter-three-witches.w
--- a/examples/enter-three-witches.w
+++ b/examples/enter-three-witches.w
@@ -25,10 +25,31 @@ define : ->string x
else
format #f "~A" x
-define : say nameparts lines
- . "Show the lines as said by the name defined by the list
-of name parts.
- "
+
+define-syntax say-words
+ lambda (x)
+ syntax-case x ()
+ : _ (((word words ...))) (() lines ...)
+ #` begin
+ display : ->string `word
+ display " "
+ say-words (((words ...))) (() lines ...)
+ : _ ((())) (() lines ...)
+ #` begin
+ newline
+ say-words (lines ...)
+ : _ ((word words ...) lines ...)
+ #` begin
+ display " "
+ say-words (((word words ...))) (() lines ...)
+ : _ (() lines ...)
+ #` say-words (lines ...)
+ : _ (lines ...)
+ #` begin
+ newline
+
+
+define : say-name nameparts
let
;; symbols starting with : are not treated as part of the
;; name. They can be used as actor instructions
@@ -37,12 +58,17 @@ of name parts.
error
format #f "Tried to use ~A who did not Enter. Introduced names: ~A"
. pure-name introduced-names
- format #t "~A\n ~A\n\n"
+ format #t "~A\n"
string-join : map symbol->string nameparts
- string-join
- map : lambda (x) (string-join (map ->string x))
- . lines
- . "\n "
+
+
+define-syntax say
+ lambda (x)
+ syntax-case x ()
+ : _ nameparts lines
+ #` begin
+ say-name nameparts
+ say-words lines
define : longest-common-prefix li introduced-names
@@ -72,12 +98,6 @@ define : longest-common-prefix li introd
cdr l
-define : Squeak . li
- . "somehow say the given list"
- let : : name : longest-common-prefix li introduced-names
- say name : drop li (length name)
-
-
define-syntax Speak
lambda (x)
with-ellipsis :::
@@ -85,9 +105,9 @@ define-syntax Speak
;; Support form for modifiers: enclose by double parens (used later)
;; when using this name, print all lines indented, with the name in front.
: _ (((name :::))) ((mod :::)) (word :::) line :::
- #` say
- quasiquote : name ::: mod :::
- quasiquote : (word :::) line :::
+ #` begin
+ say-name : quasiquote : name ::: mod :::
+ say-words : (word :::) line :::
;; extend mod keywords
: _ (((name :::))) ((mod :::)) modifier line :::
;; extend the modifier keyword list
@@ -104,6 +124,21 @@ define-syntax Speak
#` begin #t symbol :::
+define-syntax Speak-indirect
+ lambda (x)
+ syntax-case x ()
+ ;; Adjust name and lines for Speak
+ ;; input: (name1 name2 ... (word ...) ...)
+ : _ ((((name ...)))) ((lines ...))
+ #` Speak (((name ...))) lines ...
+ : _ ((lines ...)) symbols ... (lastline ...)
+ #` Speak-indirect ((lines ... (lastline ...))) symbols ...
+ : _ symbols ... (lastline ...)
+ #` Speak-indirect (((lastline ...))) symbols ...
+ : _ ((lines ...)) name ...
+ #` Speak-indirect ((((name ...)))) ((lines ...))
+
+
define-syntax Enter
lambda (x)
syntax-case x ()
@@ -121,20 +156,12 @@ define-syntax Enter
; just forward matching rules to Speak
: _ more ... symbol :::
#' Speak (((name more ...))) symbol :::
- : _ symbol ::: ; FIXME: This prevents checking at compiletime :(
+ : _ symbols ::: ; FIXME: This prevents checking at compiletime :(
; this does not correctly make the second name part of
; the name, preventing differentiation between name and
; modifier, therefore we have to do that in the Speak
; macro
- #` let*
- : n : longest-common-prefix '(name symbol :::) introduced-names
- lines : drop '(symbol :::) : 1- : length n
- line-start-index : list-index pair? lines
- line-head : drop-right lines : - (length lines) line-start-index
- line-tail : drop lines line-start-index
- say
- append n line-head ; add mood markers
- . line-tail
+ #` Speak-indirect name symbols :::
;; process the rest of the names
Enter b ...
;; record that the name was introduced. I do not see a way to do