wisp
 
(Arne Babenhauserheide)
2014-10-16: wisp-scheme: FIX: Recognized two empty lines in the REPL only while

wisp-scheme: FIX: Recognized two empty lines in the REPL only while typing the third. Fixed by ignore #\return completely in the wisp chunk parser.

diff --git a/wisp-reader.w b/wisp-reader.w
--- a/wisp-reader.w
+++ b/wisp-reader.w
@@ -57,7 +57,9 @@ define-language wisp
   . #:title "Wisp Scheme Syntax THIS IS EXPERIMENTAL, USE AT YOUR OWN RISK"
   ; . #:reader read-one-wisp-sexp
   . #:reader wisp-scheme-read-chunk-env
-  . #:compilers `((scheme . ,compile-scheme)) ; I do not touch quasiquotes yet.
+  . #: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
@@ -120,118 +120,140 @@ 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 ; FIXME: if emptylines is now 2,
-                                     ; we should return here to avoid
-                                     ; blocking on the next text
-                                     ; entry. or maybe earlier in
-                                     ; recursion.
+                     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
-               : 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) (equal? #\return next-next-char) (eof-object? next-next-char)
-                     unread-char next-char port
+                       . '()
+                       . 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) ; 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
@@ -239,27 +261,9 @@ define : wisp-scheme-read-chunk-lines po
                      . #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) (equal? #\return next-next-char) (eof-object? next-next-char)
-                         list : read port
-                         list dotrepr
+                     ; TODO: If used from Guile, activate curly infix via read-options.
+                     append currentsymbols : list : read port
                      . 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