(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