wisp
 
(Arne Babenhauserheide)
2014-10-16: v0.6.5 now uses the clean scheme read using wisp in the REPL. stable v0.6.5

v0.6.5 now uses the clean scheme read using wisp in the REPL.

diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+wisp 0.6.5 (2014-10-16):
+- use wisp-scheme in the REPL.
+- safe dot representation for reading a literal dot (.) for creating improper lists.
+
 wisp 0.6.4 (2014-09-02):
 - an actually working wisp implementation for scheme (only) which uses the guile reader. This should be actually correct for scheme. And match-magic ☺
 - polishing.
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl run `autoreconf -i` to generate a configure script. 
 dnl Then run ./configure to generate a Makefile.
 dnl Finally run make to generate the project.
-AC_INIT([wisp], [0.6.4],
+AC_INIT([wisp], [0.6.5],
         [arne_bab@web.de])
 # Check for programs I need for my build
 AC_CANONICAL_TARGET
diff --git a/tests/strangecomments.scm b/tests/strangecomments.scm
--- a/tests/strangecomments.scm
+++ b/tests/strangecomments.scm
@@ -8,8 +8,6 @@
 
 ; broken
 ; expected:
-; ((2 (foo)) (2) (0) (0) (2 foo : moo 
-; ) (4 #{.}# [goo #{.}# hoo]))
 (display  
   (call-with-input-string  "  (foo) ; bar\n  ; nop \n\n; nup\n; nup \n  \n\n\n  foo : moo \"\n\" \n___ . [goo . hoo]" wisp-scheme-read-chunk))
 (newline)
diff --git a/tests/strangecomments.w b/tests/strangecomments.w
--- a/tests/strangecomments.w
+++ b/tests/strangecomments.w
@@ -8,8 +8,6 @@ newline
 
 ; broken
 ; expected:
-; ((2 (foo)) (2) (0) (0) (2 foo : moo 
-; ) (4 #{.}# [goo #{.}# hoo]))
 display  
   call-with-input-string  "  (foo) ; bar\n  ; nop \n\n; nup\n; nup \n  \n\n\n  foo : moo \"\n\" \n___ . [goo . hoo]" wisp-scheme-read-chunk
 newline
diff --git a/wisp-reader.w b/wisp-reader.w
--- a/wisp-reader.w
+++ b/wisp-reader.w
@@ -11,6 +11,7 @@
 ; adapted from spec.scm: https://gitorious.org/nacre/guile-sweet/source/ae306867e371cb4b56e00bb60a50d9a0b8353109:sweet/spec.scm
 define-module : language wisp spec
   . #:use-module : wisp
+  . #:use-module : wisp-scheme
   . #:use-module : system base compile
   . #:use-module : system base language
   . #:export : wisp
@@ -49,10 +50,16 @@ define : read-one-wisp-sexp port env
           read-wisp-chunk
   try-pending
 
+define : wisp-scheme-read-chunk-env port env
+       cons 'begin : wisp-scheme-read-chunk port
+
 define-language wisp
   . #:title "Wisp Scheme Syntax THIS IS EXPERIMENTAL, USE AT YOUR OWN RISK"
-  . #:reader read-one-wisp-sexp
-  . #:compilers `((scheme . ,compile-scheme)) ; I do not touch quasiquotes yet.
+  ; . #:reader read-one-wisp-sexp
+  . #:reader wisp-scheme-read-chunk-env
+  . #:compilers `((scheme . ,compile-scheme)) ; this is scheme, not
+                                              ; wisp, because I do not
+                                              ; touch quasiquotes yet.
   . #:decompilers `((scheme . ,decompile-scheme))
   . #:evaluator : lambda (x module) : primitive-eval x
   . #:printer write
diff --git a/wisp-scheme.w b/wisp-scheme.w
--- a/wisp-scheme.w
+++ b/wisp-scheme.w
@@ -48,11 +48,14 @@ define : line-code line
 ; literal values I need
 define readcolon 
        string->symbol ":"
-define readdot
-       string->symbol "."
+
+; define an intermediate dot replacement with UUID to avoid clashes.
+define dotrepr 
+       string->symbol "DOTREPR-e749c73d-c826-47e2-a798-c16c13cb89dd"
+
 
 define : line-continues? line
-         equal? readdot : car : line-code line
+         equal? dotrepr : car : line-code line
 
 define : line-only-colon? line
          and
@@ -77,7 +80,7 @@ define : line-strip-continuation line
               . line
 
 define : line-strip-indentation-marker line
-         ' "Strip the indentation markers from the beginning of the line"
+         . "Strip the indentation markers from the beginning of the line"
          cdr line
 
 define : indent-level-reduction indentation-levels level select-fun
@@ -117,120 +120,154 @@ define : wisp-scheme-read-chunk-lines po
              currentindent 0
              currentsymbols '()
              emptylines 0
-           let : : next-char : peek-char port
-             cond
-               : eof-object? next-char
-                 append indent-and-symbols : list : append (list currentindent) currentsymbols
-               : <= 2 emptylines
-                 . indent-and-symbols
-               : and inindent : equal? #\space next-char
-                 read-char port ; remove char
-                 loop
-                   . indent-and-symbols
-                   . #t ; inindent
-                   . #f ; inunderscoreindent
-                   . #f ; incomment
-                   1+ currentindent
-                   . currentsymbols
-                   . emptylines
-               : and inunderscoreindent : equal? #\_ next-char
-                 read-char port ; remove char
-                 loop 
-                   . indent-and-symbols
-                   . #t ; inindent
-                   . #t ; inunderscoreindent
-                   . #f ; incomment
-                   1+ currentindent
-                   . currentsymbols
-                   . emptylines
-               ; any char but whitespace *after* underscoreindent is
-               ; an error. This is stricter than the current wisp
-               ; syntax definition. TODO: Fix the definition. Better
-               ; start too strict.
-               : and inunderscoreindent : not : equal? #\space next-char
-                 throw 'wisp-syntax-error "initial underscores without following whitespace at beginning of the line after" : last indent-and-symbols
-               : or (equal? #\newline next-char) (equal? #\return next-char)
-                 read-char port ; remove the newline
-                 ; TODO: Check whether when or if should be preferred here. guile 1.8 only has if.
-                 if : and (equal? #\newline next-char) : equal? #\return : peek-char port
-                      read-char port ; remove a full \n\r. Damn special cases...
-                 let* ; distinguish pure whitespace lines and lines
-                      ; with comment by giving the former zero
-                      ; indent. Lines with a comment at zero indent
-                      ; get indent -1 for the same reason - meaning
-                      ; not actually empty.
-                   :
-                     indent 
-                       cond 
-                         incomment 
-                           if : = 0 currentindent ; specialcase
-                             . -1
-                             . currentindent 
-                         : not : null? currentsymbols ; pure whitespace
-                           . currentindent
-                         else
-                           . 0
-                     parsedline : append (list indent) currentsymbols
-                   ; TODO: If the line is empty. Either do it here and do not add it, just
-                   ; increment the empty line counter, or strip it later. Replace indent
-                   ; -1 by indent 0 afterwards.
+           if : <= 2 emptylines ; the chunk end has to be checked
+                                ; before we look for new chars in the
+                                ; port to make execution in the REPL
+                                ; after two empty lines work
+                                ; (otherwise it shows one more line).
+             . indent-and-symbols
+             let : : next-char : peek-char port
+               cond
+                 : eof-object? next-char
+                   append indent-and-symbols : list : append (list currentindent) currentsymbols
+                 : and inindent : equal? #\space next-char
+                   read-char port ; remove char
                    loop
-                     append indent-and-symbols : list parsedline
+                     . indent-and-symbols
                      . #t ; inindent
-                     equal? #\_ : peek-char port
+                     . #f ; inunderscoreindent
                      . #f ; incomment
-                     . 0
-                     . '()
-                     if : line-empty? parsedline
-                       1+ emptylines
+                     1+ currentindent
+                     . currentsymbols
+                     . emptylines
+                 : and inunderscoreindent : equal? #\_ next-char
+                   read-char port ; remove char
+                   loop 
+                     . indent-and-symbols
+                     . #t ; inindent
+                     . #t ; inunderscoreindent
+                     . #f ; incomment
+                     1+ currentindent
+                     . currentsymbols
+                     . emptylines
+                 ; any char but whitespace *after* underscoreindent is
+                 ; an error. This is stricter than the current wisp
+                 ; syntax definition. TODO: Fix the definition. Better
+                 ; start too strict.
+                 : and inunderscoreindent : not : equal? #\space next-char
+                   throw 'wisp-syntax-error "initial underscores without following whitespace at beginning of the line after" : last indent-and-symbols
+                 : or (equal? #\newline next-char) ; (equal? #\return next-char)
+                   read-char port ; remove the newline
+                   ; The following two lines would break the REPL by requiring one char too many.
+                   ; if : and (equal? #\newline next-char) : equal? #\return : peek-char port
+                   ;      read-char port ; remove a full \n\r. Damn special cases...
+                   let* ; distinguish pure whitespace lines and lines
+                        ; with comment by giving the former zero
+                        ; indent. Lines with a comment at zero indent
+                        ; get indent -1 for the same reason - meaning
+                        ; not actually empty.
+                     :
+                       indent 
+                         cond 
+                           incomment 
+                             if : = 0 currentindent ; specialcase
+                               . -1
+                               . currentindent 
+                           : not : null? currentsymbols ; pure whitespace
+                             . currentindent
+                           else
+                             . 0
+                       parsedline : append (list indent) currentsymbols
+                       emptylines 
+                         if : not : line-empty? parsedline
+                            . 0 
+                            1+ emptylines
+                     ; TODO: If the line is empty. Either do it here and do not add it, just
+                     ; increment the empty line counter, or strip it later. Replace indent
+                     ; -1 by indent 0 afterwards.
+                     loop
+                       append indent-and-symbols : list parsedline
+                       . #t ; inindent
+                       if : <= 2 emptylines
+                         . #f ; chunk ends here
+                         equal? #\_ : peek-char port
+                       . #f ; incomment
                        . 0
-               : equal? #t incomment
-                 read-char port ; remove one comment character
-                 loop 
-                   . indent-and-symbols
-                   . #f ; inindent 
-                   . #f ; inunderscoreindent 
-                   . #t ; incomment
-                   . currentindent
-                   . currentsymbols
-                   . emptylines
-               : or (equal? #\space next-char) (equal? #\tab next-char) ; remove whitespace when not in indent
-                 read-char port ; remove char
-                 loop 
-                   . indent-and-symbols
-                   . #f ; inindent
-                   . #f ; inunderscoreindent
-                   . #f ; incomment
-                   . currentindent
-                   . currentsymbols
-                   . emptylines
-                        ; | cludge to appease the former wisp parser
-                        ; | which had a problem with the literal comment
-                        ; v char.
-               : equal? (string-ref ";" 0) next-char
-                 loop 
-                   . indent-and-symbols
-                   . #f ; inindent 
-                   . #f ; inunderscoreindent 
-                   . #t ; incomment
-                   . currentindent
-                   . currentsymbols
-                   . emptylines
-               else ; use the reader
-                 loop 
-                   . indent-and-symbols
-                   . #f ; inindent
-                   . #f ; inunderscoreindent
-                   . #f ; incomment
-                   . currentindent
-                   ; this also takes care of the hashbang and leading comments.
-                   ; TODO: If used from Guile, activate curly infix via read-options.
-                   append currentsymbols : list : read port
-                   . emptylines
+                       . '()
+                       . emptylines
+                 : equal? #t incomment
+                   read-char port ; remove one comment character
+                   loop 
+                     . indent-and-symbols
+                     . #f ; inindent 
+                     . #f ; inunderscoreindent 
+                     . #t ; incomment
+                     . currentindent
+                     . currentsymbols
+                     . emptylines
+                 : or (equal? #\space next-char) (equal? #\tab next-char) (equal? #\return next-char) ; remove whitespace when not in indent
+                   read-char port ; remove char
+                   loop 
+                     . indent-and-symbols
+                     . #f ; inindent
+                     . #f ; inunderscoreindent
+                     . #f ; incomment
+                     . currentindent
+                     . currentsymbols
+                     . emptylines
+                          ; | cludge to appease the former wisp parser
+                          ; | which had a problem with the literal comment
+                          ; v char.
+                 : equal? (string-ref ";" 0) next-char
+                   loop 
+                     . indent-and-symbols
+                     . #f ; inindent 
+                     . #f ; inunderscoreindent 
+                     . #t ; incomment
+                     . currentindent
+                     . currentsymbols
+                     . emptylines
+                 : equal? (string-ref "." 0) next-char
+                   ; TODO: special case for the dot using the dotrepr as
+                   ; intermediate representation
+                   read-char port ; remove next-char
+                   let : : next-next-char : peek-char port
+                     ; if we don’t need the special handling, add the
+                     ; next char to the port again
+                     if : not : or (equal? #\space next-next-char) (equal? #\newline next-next-char) (eof-object? next-next-char) (equal? #\return next-next-char) 
+                       unread-char next-char port
+                     loop 
+                       . indent-and-symbols
+                       . #f ; inindent
+                       . #f ; inunderscoreindent
+                       . #f ; incomment
+                       . currentindent
+                       ; this also takes care of the hashbang and leading comments.
+                       append currentsymbols 
+                         ; if we don’t need the special handling, just
+                         ; use the reader. Otherwise append the special
+                         ; representation of the dot to avoid triggering
+                         ; this for the dot escaped as |.| or #{.}#
+                         if : not : or (equal? #\space next-next-char) (equal? #\newline next-next-char) (eof-object? next-next-char) (equal? #\return next-next-char)
+                           list : read port
+                           list dotrepr
+                       . emptylines
+                       ; TODO: finish 
+                 else ; use the reader
+                   loop 
+                     . indent-and-symbols
+                     . #f ; inindent
+                     . #f ; inunderscoreindent
+                     . #f ; incomment
+                     . currentindent
+                     ; this also takes care of the hashbang and leading comments.
+                     ; TODO: If used from Guile, activate curly infix via read-options.
+                     append currentsymbols : list : read port
+                     . emptylines
 
 
 define : line-code-replace-inline-colons line
-         ' "Replace inline colons by opening parens which close at the end of the line"
+         . "Replace inline colons by opening parens which close at the end of the line"
          ; format #t "replace inline colons for line ~A\n" line
          let loop
            : processed '()
@@ -394,7 +431,7 @@ define : wisp-scheme-indentation-to-pare
 
 
 define : wisp-scheme-replace-inline-colons lines
-         ' "Replace inline colons by opening parens which close at the end of the line"
+         . "Replace inline colons by opening parens which close at the end of the line"
          let loop
            : processed '()
              unprocessed lines
@@ -406,7 +443,7 @@ define : wisp-scheme-replace-inline-colo
                   
 
 define : wisp-scheme-strip-indentation-markers lines
-         ' "Strip the indentation markers from the beginning of the lines"
+         . "Strip the indentation markers from the beginning of the lines"
          let loop
            : processed '()
              unprocessed lines
@@ -426,52 +463,52 @@ when it reads a dot. So we have to take 
 code to recreate the improper lists.
 
 Match is awesome!"
-      let 
-        : 
-          improper
-            match code
-               : a ... b '#{.}# c
-                 append (map wisp-make-improper a) 
-                   cons (wisp-make-improper b) (wisp-make-improper c)
+         let 
+           : 
+             improper
+               match code
+                  : a ... b 'DOTREPR-e749c73d-c826-47e2-a798-c16c13cb89dd c
+                    append (map wisp-make-improper a) 
+                      cons (wisp-make-improper b) (wisp-make-improper c)
+                  : a ...
+                    map wisp-make-improper a
+                  a
+                    . a
+           define : syntax-error li
+                   throw 'wisp-syntax-error (format #f "incorrect dot-syntax #{.}# in code: not a proper pair: ~A" li)
+           let check
+             : tocheck improper
+             match tocheck
+               ; lists with only one member
+               : 'DOTREPR-e749c73d-c826-47e2-a798-c16c13cb89dd
+                 syntax-error tocheck
+               ; list with remaining dot.
                : a ...
-                 map wisp-make-improper a
+                 if : member dotrepr a
+                      syntax-error tocheck
+                      map check a
+               ; simple pair
+               : 'DOTREPR-e749c73d-c826-47e2-a798-c16c13cb89dd . c
+                 syntax-error tocheck
+               ; simple pair, other way round
+               : a . 'DOTREPR-e749c73d-c826-47e2-a798-c16c13cb89dd
+                 syntax-error tocheck
+               ; more complex pairs
+               : ? pair? a
+                 let 
+                   : head : drop-right a 1
+                     tail : last-pair a
+                   cond
+                    : equal? dotrepr : car tail
+                      syntax-error tocheck
+                    : equal? dotrepr : cdr tail
+                      syntax-error tocheck
+                    : member dotrepr head
+                      syntax-error tocheck
+                    else
+                      . a
                a
                  . a
-        define : syntax-error li
-                throw 'wisp-syntax-error (format #f "incorrect dot-syntax #{.}# in code: not a proper pair: ~A" li)
-        let check
-          : tocheck improper
-          match tocheck
-            ; lists with only one member
-            : '#{.}#
-              syntax-error tocheck
-            ; list with remaining dot.
-            : a ...
-              if : member readdot a
-                   syntax-error tocheck
-                   map check a
-            ; simple pair
-            : '#{.}# . c
-              syntax-error tocheck
-            ; simple pair, other way round
-            : a . '#{.}#
-              syntax-error tocheck
-            ; more complex pairs
-            : ? pair? a
-              let 
-                : head : drop-right a 1
-                  tail : last-pair a
-                cond
-                 : equal? readdot : car tail
-                   syntax-error tocheck
-                 : equal? readdot : cdr tail
-                   syntax-error tocheck
-                 : member readdot head
-                   syntax-error tocheck
-                 else
-                   . a
-            a
-              . a
 
 
 define : wisp-scheme-read-chunk port