(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"