(Arne Babenhauserheide)
2016-10-09: Working version, including mood markers, but only with runtime three-witches-space-in-name Working version, including mood markers, but only with runtime checking of second (and further) names.
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 @@ -23,7 +23,7 @@ of name parts. let ;; symbols starting with : are not treated as part of the ;; name. They can be used as actor instructions - : pure-name : remove (lambda (x) (string-prefix? ":" (symbol->string x))) nameparts + : pure-name : remove (lambda (x) (string-prefix? ":" (symbol->string x))) : remove pair? nameparts if : not : member pure-name introduced-names error format #f "Tried to use ~A who did not Enter. Introduced names: ~A" @@ -35,43 +35,18 @@ of name parts. . lines . "\n " -define-syntax Speak - syntax-rules ::: () - ;; 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 - quote : name ::: mod ::: - quote : (word :::) line ::: - ;; extend mod keywords - : _ (((name :::))) ((mod :::)) modifier line ::: - begin - ;; extend the modifier keyword list - Speak (((name :::))) ((mod ::: modifier)) line ::: - ;; say form without modifier - : _ (((name :::))) (word :::) line ::: - Speak (((name :::))) (()) (word :::) line ::: - ;; first modifier keyword after the name - : _ (((name :::))) modifier line ::: - begin - ;; append to mod helper form - Speak (((name :::))) ((modifier)) line ::: - ;; Strip the name from lines with empty arguments - : _ (((name :::))) symbol ::: - begin #t symbol ::: - -define : longest-common-prefix-in introduced-names li +define : longest-common-prefix li introduced-names . "Get the name with the longest common prefix with list li" let loop : names introduced-names longest '() if : null? names - . longest + reverse longest let lp : prefix '() name : car names - l : li + l li if or null? name @@ -88,6 +63,38 @@ define : longest-common-prefix-in 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 ::: + syntax-case x () + ;; 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 + quote : name ::: mod ::: + quote : (word :::) line ::: + ;; extend mod keywords + : _ (((name :::))) ((mod :::)) modifier line ::: + ;; extend the modifier keyword list + #` Speak (((name :::))) ((mod ::: modifier)) line ::: + ;; say form without modifier + : _ (((name :::))) (word :::) line ::: + #` Speak (((name :::))) (()) (word :::) line ::: + ;; first modifier keyword after the name + : _ (((name :::))) modifier line ::: + ;; append to mod helper form + #` Speak (((name :::))) ((modifier)) line ::: + ;; Strip the name from lines with empty arguments + : _ (((name :::))) symbol ::: + #` begin #t symbol ::: + + define-syntax Enter lambda (x) syntax-case x () @@ -105,14 +112,20 @@ define-syntax Enter ; just forward matching rules to Speak : _ more ... symbol ::: #' Speak (((name more ...))) symbol ::: - ; : _ more ... symbol ::: - ; syntax-error - ; . "Name not introduced:" name more ... : _ symbol ::: ; FIXME: This prevents checking at compiletime :( - ; FIXME: this does not correctly make the second name - ; part of the name, preventing differentiation between - ; name and modifier - #` Speak (((name))) symbol ::: + ; 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 ;; process the rest of the names Enter b ... ;; record that the name was introduced. I do not see a way to do @@ -142,20 +155,28 @@ define : main args When shall we three meet again In thunder, lightning, or in rain? - Second Witch + Second Witch :resolute When the hurlyburly's done, When the battle's lost and won. Third Witch That will be ere the set of sun. - First Eldritch + First Eldritch :crazy gnignigni! Enter : Second Eldritch - Second Eldritch + Second Eldritch :quick Guh! + ; . :goo ; invalid ⇒ would be an error + ; . foo ; invalid ⇒ would be an error + Moo + +;; Making the name longer throws an Error, but only at runtime: +; Second Eldritch shoo +; Guh! +;; ⇒ ERROR: Tried to use (Second Eldritch shoo) who did not Enter. Introduced names: ((Second Eldritch) (First Witch) (Second Witch) (Third Witch) (First Eldritch)) ;; Adding one who did not enter throws an Error, but only at runtime: ; Third Eldritch