wisp
 
(Arne Babenhauserheide)
2014-08-18: wisp-scheme: try out a new, cleaner algorithm which currently is

wisp-scheme: try out a new, cleaner algorithm which currently is wrong.

diff --git a/wisp-scheme.w b/wisp-scheme.w
--- a/wisp-scheme.w
+++ b/wisp-scheme.w
@@ -21,7 +21,9 @@ define-module : wisp-scheme
                wisp-scheme-read-file-chunk wisp-scheme-read-file
                wisp-scheme-read-string)
 
-use-modules : srfi srfi-1
+use-modules 
+  srfi srfi-1
+  srfi srfi-11 ; let-values
 
 
 ;; Helper functions for the indent-and-symbols data structure: '((indent token token ...) ...)
@@ -56,6 +58,10 @@ define : line-strip-continuation line
                 cdr : line-code line
               . line
 
+define : line-strip-indentation-marker line
+         ' "Strip the indentation markers from the beginning of the line"
+         cdr line
+
 define : indent-level-reduction indentation-levels level select-fun
          . "Reduce the INDENTATION-LEVELS to the given LEVEL and return the value selected by SELECT-FUN"
          let loop 
@@ -226,133 +232,6 @@ define : line-prepend-n-parens n line
                    . '("(")
                    cdr l
 
-; TODO: process inline colons
-
-define : wisp-scheme-indentation-to-parens lines
-         . "Add parentheses to lines and remove the indentation markers"
-         let loop
-           : processed '()
-             current-line : car lines
-             unprocessed : cdr lines
-             indentation-levels '(0)
-           ; format #t "processed: ~A\ncurrent-line: ~A\nunprocessed: ~A\nindentation-levels: ~A\n\n"
-           ;     .      processed      current-line      unprocessed      indentation-levels
-           cond
-             ; the recursion end-condition
-             : and (null? current-line) (null? unprocessed) (not (null? indentation-levels))
-               throw 'wisp-programming-error "The current-line is null but there are indentation-levels: Something returned a broken line as new current-line."
-             : and (not (null? current-line)) (null? indentation-levels)
-               throw 'wisp-programming-error "The indentation-levels are null but the current-line is null: Something killed the indentation-levels."
-             ; the recursion end-condition
-             : and (null? current-line) (null? unprocessed)
-               . processed
-             ; now care for the last step
-             : null? unprocessed 
-               ; current is the last line
-               cond
-                 : line-continues? current-line
-                   loop
-                     append processed 
-                       list
-                         line-append-n-parens 
-                           1- : length indentation-levels
-                           line-strip-continuation current-line
-                     . '() ; current-line empty: required end condition 1
-                     . '() ; unprocessed empty: required end condition 2
-                     . '() ; indentation-levels: There is nothing more to process
-                 else
-                   loop
-                     append processed
-                       list
-                         line-prepend-n-parens 1 
-                           line-append-n-parens
-                             length indentation-levels
-                             line-strip-continuation current-line
-                     . '() ; current-line empty: required end condition 1
-                     . '() ; unprocessed empty: required end condition 2
-                     . '() ; indentation-levels: There is nothing more to process
-             else ; now we come to the line-comparisons and indentation-counting.
-               let
-                 : next-line : car unprocessed
-                 cond
-                   : line-empty-code? current-line
-                     ; We cannot process indentation without
-                     ; code. Just switch to the next line. This should
-                     ; only happen at the start of the recursion.
-                     ; TODO: Somehow preserve the line-numbers.
-                     loop
-                       . processed
-                       . next-line
-                       cdr unprocessed
-                       . indentation-levels
-                   : line-empty-code? next-line
-                     ; TODO: Somehow preserve the line-numbers.
-                     loop
-                       . processed
-                       . current-line
-                       cdr unprocessed
-                       . indentation-levels
-                   : = (line-indent current-line) (line-indent next-line)
-                     let 
-                       : parens-to-add : if (line-continues? current-line) 0 1
-                       loop
-                         append processed 
-                           list 
-                             line-prepend-n-parens parens-to-add
-                               line-append-n-parens parens-to-add
-                                 line-strip-continuation current-line
-                         . next-line
-                         cdr unprocessed
-                         . indentation-levels
-                   : < (line-indent current-line) (line-indent next-line)
-                     ; FIXME: This should get a sublist via recursion
-                     ; and add that to processed instead of using the
-                     ; atrocity of adding parens by hand (which I
-                     ; perceived as very nice up to an hour ago). The
-                     ; sublist should end when we have to pop an
-                     ; indentation-level - level by level.
-                     if : line-continues? current-line
-                          ; this is a syntax error.
-                          throw 'wisp-syntax-error "Line with deeper indentation follows after a continuation line: current: ~A, next: ~A."
-                             . current-line next-line
-                          loop
-                            append processed 
-                              list
-                                line-prepend-n-parens 1 
-                                  line-strip-continuation current-line
-                            . next-line
-                            cdr unprocessed
-                            ; we need to add an indentation level for the next-line.
-                            cons (line-indent next-line) indentation-levels
-                   : > (line-indent current-line) (line-indent next-line)
-                     ; first we need to find out how many indentation levels we need to pop.
-                     let*
-                       : newlevels : indent-reduce-to-level indentation-levels : line-indent next-line
-                         level-difference : indent-level-difference indentation-levels : line-indent next-line
-                         parens-to-prepend 
-                           if : line-continues? current-line
-                                . 0
-                                . 1
-                         parens-to-append 
-                           if : line-continues? current-line
-                                ; FIXME: This looks wrong, but it has
-                                ; the right result.
-                                1- level-difference
-                                . level-difference
-                       loop
-                         append processed 
-                           list
-                             line-prepend-n-parens parens-to-prepend
-                               line-append-n-parens parens-to-append
-                                 line-strip-continuation current-line
-                         . next-line
-                         cdr unprocessed
-                         . newlevels
-                   else
-                     throw 'wisp-not-implemented 
-                           format #f "Need to implement further line comparison: current: ~A, next: ~A, processed: ~A."
-                             . current-line next-line processed
-
 
 define : line-code-replace-inline-colons line
          ' "Replace inline colons by opening parens which close at the end of the line"
@@ -378,6 +257,115 @@ define : line-replace-inline-colons line
            line-indent line
            line-code-replace-inline-colons : line-code line
 
+
+define : wisp-scheme-indentation-to-parens lines
+         . "Add parentheses to lines and remove the indentation markers"
+         ; FIXME: Find new algorithm which mostly uses current-line
+         ; and the indentation-levels for tracking. The try I have in
+         ; here right now is wrong.
+         let loop
+           : processed '()
+             unprocessed lines
+             indentation-levels '(0)
+           let
+             : 
+               current-line 
+                 if : <= 1 : length unprocessed
+                      car unprocessed
+                      list 0 ; empty code
+               next-line
+                 if : <= 2 : length unprocessed
+                      car : cdr unprocessed
+                      list 0 ; empty code
+               current-indentation
+                      car indentation-levels
+             format #t "processed: ~A\ncurrent-line: ~A\nnext-line: ~A\nunprocessed: ~A\nindentation-levels: ~A\n\n"
+                 . processed current-line next-line unprocessed indentation-levels
+             cond
+                 ; the real end: this is reported to the outside world.
+               : and (null? unprocessed) (not (null? indentation-levels)) (null? (cdr indentation-levels))
+                 display "done\n"
+                 ; reverse the processed lines, because I use cons.
+                 reverse processed
+               ; the recursion end-condition
+               : and (null? unprocessed)
+                 display "last step\n"
+                 ; this is the last step. Nothing more to do except
+                 ; for rolling up the indentation levels.  return the
+                 ; new processed and unprocessed lists: this is a
+                 ; side-recursion
+                 values processed unprocessed
+               : null? indentation-levels
+                 display "indentation-levels null\n"
+                 throw 'wisp-programming-error "The indentation-levels are null but the current-line is null: Something killed the indentation-levels."
+               else ; now we come to the line-comparisons and indentation-counting.
+                   cond
+                     : line-empty-code? current-line
+                       display "current-line empty\n"
+                       ; We cannot process indentation without
+                       ; code. Just switch to the next line. This should
+                       ; only happen at the start of the recursion.
+                       ; TODO: Somehow preserve the line-numbers.
+                       loop
+                         . processed
+                         cdr unprocessed
+                         . indentation-levels
+                     : and (line-empty-code? next-line) : <= 2 : length unprocessed 
+                       display "next-line empty\n"
+                       ; TODO: Somehow preserve the line-numbers.
+                       ; take out the next-line from unprocessed.
+                       loop
+                         . processed
+                         cons current-line
+                           cdr : cdr unprocessed
+                         . indentation-levels
+                     : = current-indentation (line-indent current-line)
+                       display "current-indent = next-line\n"
+                       loop
+                         cons
+                           if : line-continues? current-line
+                             line-code-replace-inline-colons 
+                               line-strip-indentation-marker 
+                                 line-strip-continuation current-line
+                             list
+                               line-code-replace-inline-colons 
+                                 line-strip-indentation-marker 
+                                   line-strip-continuation current-line
+                           . processed
+                         cdr unprocessed
+                         . indentation-levels
+                     : < current-indentation (line-indent current-line)
+                       display "current indent < current-line\n"
+                       ; when : line-continues? current-line ; FIXME: Recreate in new structure.
+                            ; this is a syntax error.
+                       ;      throw 'wisp-syntax-error "Line with deeper indentation follows after a continuation line: current: ~A, next: ~A."
+                       ;         . current-line next-line
+                       let-values 
+                         : 
+                           : subprocessed subunprocessed
+                             loop
+                               . '() ; start with empty processed: this is a sublist.
+                               . unprocessed ; no cdr: the recursion happens in the indentation-levels
+                               cons 
+                                 line-indent current-line
+                                 . indentation-levels
+                         loop
+                           cons subprocessed processed
+                           if : null? subunprocessed
+                             . subunprocessed
+                             cdr subunprocessed
+                           ; we need to add an indentation level for the next-line.
+                           cons (line-indent next-line) indentation-levels
+                     : > current-indentation (line-indent next-line)
+                       display "current-indent > next-line\n"
+                       ; this just steps back one level via the side-recursion.
+                       values processed unprocessed
+                     else
+                       throw 'wisp-not-implemented 
+                             format #f "Need to implement further line comparison: current: ~A, next: ~A, processed: ~A."
+                               . current-line next-line processed
+
+
 define : wisp-scheme-replace-inline-colons lines
          ' "Replace inline colons by opening parens which close at the end of the line"
          let loop
@@ -404,10 +392,8 @@ define : wisp-scheme-strip-indentation-m
 
 define : wisp-scheme-read-chunk port
          . "Read and parse one chunk of wisp-code"
-         wisp-scheme-strip-indentation-markers
-           wisp-scheme-replace-inline-colons 
-             wisp-scheme-indentation-to-parens 
-               wisp-scheme-read-chunk-lines port
+         wisp-scheme-indentation-to-parens 
+             wisp-scheme-read-chunk-lines port
 
 define : wisp-scheme-read-all port
          . "Read all chunks from the given port"
@@ -434,8 +420,8 @@ define : wisp-scheme-read-string str
 display
   wisp-scheme-read-string  "  foo ; bar\n  ; nop \n\n; nup\n; nup \n  \n\n\n  foo : moo \"\n\" \n___ . goo . hoo"
 newline 
-display : wisp-scheme-read-file-chunk "wisp-scheme.w"
-newline 
+; display : wisp-scheme-read-file-chunk "wisp-scheme.w"
+; newline 
 ; This correctly throws an error.
 ; display
 ;   wisp-scheme-read-string  "  foo \n___. goo . hoo"