(Arne Babenhauserheide)
2014-09-02: wisp can recreate improper lists thanks to the awesome match. wisp can recreate improper lists thanks to the awesome match.
diff --git a/wisp-scheme.w b/wisp-scheme.w --- a/wisp-scheme.w +++ b/wisp-scheme.w @@ -14,7 +14,11 @@ ;; directly create a list of codelines with indentation. For this we ;; then simply reuse the appropriate function from the generic wisp ;; preprocessor. - +;; +;; TODO: use match: +;; (use-modules (ice-9 match)) +;; (define dot (call-with-input-string "." read)) +;; (match (list 'u 'v dot 'w) ((a ... b '#{.}# c) (append a (cons b c))) ) define-module : wisp-scheme . #:export (wisp-scheme-read-chunk wisp-scheme-read-all @@ -25,6 +29,7 @@ use-modules srfi srfi-1 srfi srfi-11 ; for let-values ice-9 rw ; for write-string/partial + ice-9 match ;; Helper functions for the indent-and-symbols data structure: '((indent token token ...) ...) define : line-indent line @@ -411,7 +416,7 @@ define : wisp-scheme-strip-indentation-m append processed : cdr : car unprocessed cdr unprocessed -define : wisp-scheme-recreate-improper-lists expressions +define : wisp-make-improper code . "Turn (a #{.}# b) into the correct (a . b). read called on a single dot creates a variable named #{.}# (|.| @@ -420,67 +425,22 @@ structure is known, the reader cannot cr when it reads a dot. So we have to take another pass over the code to recreate the improper lists. -Traverse each list and sublist backwards, and if it contains a -readdot, cons every element in the list on the last element. +Match is awesome!" + match code + : a ... b '#{.}# c + append (map wisp-make-improper a) + cons (wisp-make-improper b) (wisp-make-improper c) + : a ... + map wisp-make-improper a + a + . a -TODO: Find out how I can do that, when the second element is a -function call (a list). Problem: (cons 1 '(2)) -> '(1 2). - -TODO: Find out whether this would actually be legal scheme code. - (write (1 . (+ 1 2))) -> error - (write . (+ 1 2)) -> strange - (write (list 1 . (+ 1 2))) -> (1 #<procedure + (#:optional _ _ . _)> 1 2) ??? - (list 1 . (list 2 3)) -> (1 #<procedure list _> 2 3) - (list . (list 2 3)) -> (#<procedure list _> 2 3) == (list list 2 3)" - ; FIXME: Implement recreating improper lists! - let loop - : processed '() - unprocessed-reversed expressions - cond - : null? unprocessed-reversed - . processed - : not : list? unprocessed-reversed - ; FIXME: This requires unlimited amounts of memory. - cons unprocessed-reversed processed - : not : member readdot unprocessed-reversed - cond - : list? : car unprocessed-reversed - loop - cons - loop '() : car unprocessed-reversed - . processed - . unprocessed-reversed - else - loop - cons (car unprocessed-reversed) processed - cdr unprocessed-reversed - else ; cons unprocessed on its tail - let conser - : proc-reversed : car unprocessed-reversed - unproc : cdr unprocessed-reversed - cond - : null? unproc - ; back to the main loop - loop - . processed - . proc-reversed - : equal? readdot : car unproc ; just skip the dot. It is why we cons. - conser - . proc-reversed - cdr unproc - else - conser - cons (car unproc) proc-reversed - cdr unproc define : wisp-scheme-read-chunk port . "Read and parse one chunk of wisp-code" let : : lines : wisp-scheme-read-chunk-lines port - ; display lines - ; newline - ; FIXME: incmoplete list recreation does not work yet - ; wisp-scheme-recreate-improper-lists - wisp-scheme-indentation-to-parens lines + wisp-make-improper + wisp-scheme-indentation-to-parens lines define : wisp-scheme-read-all port . "Read all chunks from the given port" @@ -488,7 +448,6 @@ define : wisp-scheme-read-all port : tokens '() cond : eof-object? : peek-char port - ; TODO: Join as string. . tokens else loop @@ -503,8 +462,11 @@ define : wisp-scheme-read-file-chunk pat define : wisp-scheme-read-string str call-with-input-string str wisp-scheme-read-all +define : wisp-scheme-read-string-chunk str + call-with-input-string str wisp-scheme-read-chunk -; TODO: Recreate improper lists. + +; Test improper lists write wisp-scheme-read-string "foo . bar" newline