(Arne Babenhauserheide)
2014-08-19: the new algorithm seems to be correct. the new algorithm seems to be correct.
diff --git a/wisp-scheme.w b/wisp-scheme.w
--- a/wisp-scheme.w
+++ b/wisp-scheme.w
@@ -30,6 +30,13 @@ use-modules
define : line-indent line
car line
+define : line-real-indent line
+ . "Get the indentation without the comment-marker for unindented lines (-1 is treated as 0)."
+ let : : indent : line-indent line
+ if : = -1 indent
+ . 0
+ . indent
+
define : line-code line
cdr line
@@ -47,6 +54,7 @@ define : line-empty-code? line
define : line-empty? line
and
+ ; if indent is -1, we stripped a comment, so the line was not really empty.
= 0 : line-indent line
line-empty-code? line
@@ -153,7 +161,7 @@ define : wisp-scheme-read-chunk-lines po
else
. 0
parsedline : append (list indent) currentsymbols
- ; TODO: If the line is empty, . Either do it here and do not add it, just
+ ; 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
@@ -232,31 +240,52 @@ define : line-prepend-n-parens n line
. '("(")
cdr l
+define readcolon
+ call-with-input-string ":" read
define : line-code-replace-inline-colons line
' "Replace inline colons by opening parens which close at the end of the line"
- let : : readcolon : call-with-input-string ":" read
- let loop
- : processed '()
- unprocessed line
- cond
- : null? unprocessed
- . processed
- : equal? readcolon : car unprocessed
- loop
- ; FIXME: This should turn unprocessed into a list.
- append processed : list : loop '() (cdr unprocessed)
- . '()
- else
- loop
- append processed : list : car unprocessed
- cdr unprocessed
+ format #t "replace inline colons for line ~A\n" line
+ let loop
+ : processed '()
+ unprocessed line
+ cond
+ : null? unprocessed
+ format #t "inline-colons processed line: ~A\n" processed
+ . processed
+ : equal? readcolon : car unprocessed
+ loop
+ ; FIXME: This should turn unprocessed into a list.
+ append processed
+ list : loop '() (cdr unprocessed)
+ . '()
+ else
+ loop
+ append processed
+ list : car unprocessed
+ cdr unprocessed
define : line-replace-inline-colons line
cons
line-indent line
line-code-replace-inline-colons : line-code line
+define : line-strip-lone-colon line
+ . "A line consisting only of a colon is just a marked indentation level. We need to kill the colon before replacing inline colons."
+ if
+ equal?
+ line-code line
+ list readcolon
+ list : line-indent line
+ . line
+
+define : line-finalize line
+ . "Process all wisp-specific information in a line and strip it"
+ line-code-replace-inline-colons
+ line-strip-indentation-marker
+ line-strip-lone-colon
+ line-strip-continuation line
+
define : wisp-scheme-indentation-to-parens lines
. "Add parentheses to lines and remove the indentation markers"
@@ -267,15 +296,15 @@ define : wisp-scheme-indentation-to-pare
and
not : null? lines
not : line-empty-code? : car lines
- not : = 0 : line-indent : car lines
+ not : = 0 : line-real-indent : car lines ; -1 is a line with a comment
throw 'wisp-syntax-error
- format #f "The first symbol in a chunk must start at zero indentation. Line: ~A"
+ format #f "The first symbol in a chunk must start at zero indentation. Indentation and line: ~A"
car lines
let loop
: processed '()
unprocessed lines
indentation-levels '(0)
- let
+ let*
:
current-line
if : <= 1 : length unprocessed
@@ -287,6 +316,7 @@ define : wisp-scheme-indentation-to-pare
list 0 ; empty code
current-indentation
car indentation-levels
+ current-line-indentation : line-real-indent current-line
format #t "processed: ~A\ncurrent-line: ~A\nnext-line: ~A\nunprocessed: ~A\nindentation-levels: ~A\ncurrent-indentation: ~A\n\n"
. processed current-line next-line unprocessed indentation-levels current-indentation
cond
@@ -294,7 +324,7 @@ define : wisp-scheme-indentation-to-pare
: and (null? unprocessed) (not (null? indentation-levels)) (null? (cdr indentation-levels))
display "done\n"
; reverse the processed lines, because I use cons.
- reverse processed
+ . processed
; the recursion end-condition
: and (null? unprocessed)
display "last step\n"
@@ -327,47 +357,50 @@ define : wisp-scheme-indentation-to-pare
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
- cons (line-indent current-line) indentation-levels
- loop
- append subprocessed processed
- if : null? subunprocessed
- . subunprocessed
- cdr subunprocessed
- ; we need to add an indentation level for the next-line.
- . indentation-levels
- : > current-indentation (line-indent next-line)
+ : > current-indentation current-line-indentation
display "current-indent > next-line\n"
; this just steps back one level via the side-recursion.
values processed unprocessed
+ : = current-indentation current-line-indentation
+ display "current-indent = next-line\n"
+ let
+ : line : line-finalize current-line
+ next-line-indentation : line-real-indent next-line
+ cond
+ : >= current-line-indentation next-line-indentation
+ ; simple recursiive step to the next line
+ display "current-line-indent >= next-line-indent\n"
+ loop
+ append processed
+ if : line-continues? current-line
+ . line
+ list line
+ cdr unprocessed ; recursion here
+ . indentation-levels
+ : < current-line-indentation next-line-indentation
+ display "current-line-indent < next-line-indent\n"
+ format #t "line: ~A\n" line
+ ; side-recursion via a sublist
+ let-values
+ :
+ : sub-processed sub-unprocessed
+ loop
+ . line
+ cdr unprocessed ; recursion here
+ . indentation-levels
+ format #t "side-recursion:\n sub-processed: ~A\n processed: ~A\n\n" sub-processed processed
+ loop
+ append processed : list sub-processed
+ . sub-unprocessed ; simply use the recursion from the sub-recursion
+ . indentation-levels
+ : < current-indentation current-line-indentation
+ display "current-indent < next-line\n"
+ loop
+ . processed
+ . unprocessed
+ cons ; recursion via the indentation-levels
+ . current-line-indentation
+ . indentation-levels
else
throw 'wisp-not-implemented
format #f "Need to implement further line comparison: current: ~A, next: ~A, processed: ~A."
@@ -400,8 +433,10 @@ define : wisp-scheme-strip-indentation-m
define : wisp-scheme-read-chunk port
. "Read and parse one chunk of wisp-code"
- wisp-scheme-indentation-to-parens
- wisp-scheme-read-chunk-lines port
+ let : : lines : wisp-scheme-read-chunk-lines port
+ display lines
+ newline
+ wisp-scheme-indentation-to-parens lines
define : wisp-scheme-read-all port
. "Read all chunks from the given port"
@@ -425,14 +460,16 @@ define : wisp-scheme-read-string str
call-with-input-string str wisp-scheme-read-all
-display
- wisp-scheme-read-string "foo ; bar\n ; nop \n\n; nup\n; nup \n \n\n\nfoo : moo \"\n\" \n___ . goo . hoo"
-newline
-display
- wisp-scheme-read-string " foo ; bar\n ; nop \n\n; nup\n; nup \n \n\n\ nfoo : moo"
-newline
+; display
+; wisp-scheme-read-string "foo ; bar\n ; nop \n\n; nup\n; nup \n \n\n\nfoo : moo \"\n\" \n___ . goo . hoo"
+; newline
+; display
+; wisp-scheme-read-string " foo ; bar\n ; nop \n\n; nup\n; nup \n \n\n\nfoo : moo"
+; newline
; display : wisp-scheme-read-file-chunk "wisp-scheme.w"
; newline
+display : wisp-scheme-read-file-chunk "wisp-guile.w"
+newline
; This correctly throws an error.
; display
; wisp-scheme-read-string " foo \n___. goo . hoo"