guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/04: More format refactors


From: Andy Wingo
Subject: [Guile-commits] 02/04: More format refactors
Date: Tue, 13 Aug 2019 17:09:47 -0400 (EDT)

wingo pushed a commit to branch master
in repository guile.

commit a2aec7157c55bbf82c31c848b3a41876111251e4
Author: Andy Wingo <address@hidden>
Date:   Tue Aug 13 22:31:43 2019 +0200

    More format refactors
    
    * module/ice-9/format.scm (format): Use internal defines rather than
      letrec, to prevent things from creeping rightwards so much.
---
 module/ice-9/format.scm | 1192 +++++++++++++++++++++++------------------------
 1 file changed, 586 insertions(+), 606 deletions(-)

diff --git a/module/ice-9/format.scm b/module/ice-9/format.scm
index 31409c6..b638125 100644
--- a/module/ice-9/format.scm
+++ b/module/ice-9/format.scm
@@ -132,637 +132,617 @@
       '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\- #\+ #\v #\# #\'))
 
     (define (format:format-work format-string arglist) ; does the formatting 
work
-      (letrec
-          ((format-string-len (string-length format-string))
-           (arg-pos 0)               ; argument position in arglist
-           (arg-len (length arglist))   ; number of arguments
-           (modifier #f)                ; 'colon | 'at | 'colon-at | #f
-           (params '())                 ; directive parameter list
-           (param-value-found #f)       ; a directive
-                                       ; parameter value
-                                       ; found
-           (conditional-nest 0)         ; conditional nesting level
-           (clause-pos 0)               ; last cond. clause
-                                       ; beginning char pos
-           (clause-default #f)         ; conditional default
-                                       ; clause string
-           (clauses '())                ; conditional clause
-                                       ; string list
-           (conditional-type #f)        ; reflects the
-                                       ; contional modifiers
-           (conditional-arg #f)      ; argument to apply the conditional
-           (iteration-nest 0)        ; iteration nesting level
-           (iteration-pos 0)         ; iteration string
-                                       ; beginning char pos
-           (iteration-type #f)         ; reflects the
-                                       ; iteration modifiers
-           (max-iterations #f)         ; maximum number of
-                                       ; iterations
-           (recursive-pos-save format:pos)
-              
-           (next-char                  ; gets the next char
-                                       ; from format-string
-            (lambda ()
-              (let ((ch (peek-next-char)))
-                (set! format:pos (+ 1 format:pos))
-                ch)))
-              
-           (peek-next-char
-            (lambda ()
-              (when (>= format:pos format-string-len)
-                (format:error "illegal format string"))
-              (string-ref format-string format:pos)))
-              
-           (one-positive-integer?
-            (lambda (params)
+      (define format-string-len (string-length format-string))
+      (define arg-pos 0)                ; argument position in arglist
+      (define arg-len (length arglist)) ; number of arguments
+      (define modifier #f)              ; 'colon | 'at | 'colon-at | #f
+      (define params '())               ; directive parameter list
+      (define param-value-found #f)     ; a directive parameter value found
+      (define conditional-nest 0)       ; conditional nesting level
+      (define clause-pos 0)             ; last cond. clause beginning char pos
+      (define clause-default #f)        ; conditional default clause string
+      (define clauses '())              ; conditional clause string list
+      (define conditional-type #f)      ; reflects the conditional modifiers
+      (define conditional-arg #f)       ; argument to apply the conditional
+      (define iteration-nest 0)         ; iteration nesting level
+      (define iteration-pos 0)          ; iteration string beginning char pos
+      (define iteration-type #f)        ; reflects the iteration modifiers
+      (define max-iterations #f)        ; maximum number of iterations
+      (define recursive-pos-save format:pos)
+
+      (define (next-char)               ; gets the next char from format-string
+        (let ((ch (peek-next-char)))
+          (set! format:pos (+ 1 format:pos))
+          ch))
+
+      (define (peek-next-char)
+        (when (>= format:pos format-string-len)
+          (format:error "illegal format string"))
+        (string-ref format-string format:pos))
+
+      (define (one-positive-integer? params )
+        (cond
+         ((null? params) #f)
+         ((and (integer? (car params))
+               (>= (car params) 0)
+               (= (length params) 1)) #t)
+         (else
+          (format:error
+           "one positive integer parameter expected"))))
+
+      (define (next-arg)
+        (when (>= arg-pos arg-len)
+          (set! format:arg-pos (+ arg-len 1))
+          (format:error "missing argument(s)"))
+        (add-arg-pos 1)
+        (list-ref arglist (- arg-pos 1)))
+
+      (define (prev-arg)
+        (add-arg-pos -1)
+        (when (negative? arg-pos)
+          (format:error "missing backward argument(s)"))
+        (list-ref arglist arg-pos))
+
+      (define (rest-args)
+        (let loop ((l arglist) (k arg-pos)) ; list-tail definition
+          (if (= k 0) l (loop (cdr l) (- k 1)))))
+
+      (define (add-arg-pos n)
+        (set! arg-pos (+ n arg-pos))
+        (set! format:arg-pos arg-pos))
+
+      (define (anychar-dispatch)        ; dispatches the format-string
+        (if (>= format:pos format-string-len)
+            arg-pos                     ; used for ~? continuance
+            (let ((char (next-char)))
               (cond
-               ((null? params) #f)
-               ((and (integer? (car params))
-                     (>= (car params) 0)
-                     (= (length params) 1)) #t)
+               ((char=? char #\~)
+                (set! modifier #f)
+                (set! params '())
+                (set! param-value-found #f)
+                (tilde-dispatch))
                (else
-                (format:error
-                 "one positive integer parameter expected")))))
-              
-           (next-arg
-            (lambda ()
-              (when (>= arg-pos arg-len)
-                (set! format:arg-pos (+ arg-len 1))
-                (format:error "missing argument(s)"))
-              (add-arg-pos 1)
-              (list-ref arglist (- arg-pos 1))))
-              
-           (prev-arg
-            (lambda ()
-              (add-arg-pos -1)
-              (when (negative? arg-pos)
-                (format:error "missing backward argument(s)"))
-              (list-ref arglist arg-pos)))
-              
-           (rest-args
-            (lambda ()
-              (let loop ((l arglist) (k arg-pos)) ; list-tail definition
-                (if (= k 0) l (loop (cdr l) (- k 1))))))
-              
-           (add-arg-pos
-            (lambda (n) 
-              (set! arg-pos (+ n arg-pos))
-              (set! format:arg-pos arg-pos)))
-              
-           (anychar-dispatch           ; dispatches the format-string
-            (lambda ()
-              (if (>= format:pos format-string-len)
-                  arg-pos               ; used for ~? continuance
-                  (let ((char (next-char)))
-                    (cond
-                     ((char=? char #\~)
-                      (set! modifier #f)
-                      (set! params '())
-                      (set! param-value-found #f)
-                      (tilde-dispatch))
-                     (else
-                      (when (and (zero? conditional-nest)
-                                 (zero? iteration-nest))
-                        (format:out-char char))
-                      (anychar-dispatch)))))))
-              
-           (tilde-dispatch
-            (lambda ()
-              (cond
-               ((>= format:pos format-string-len)
-                (format:out-str "~")   ; tilde at end of
+                (when (and (zero? conditional-nest)
+                           (zero? iteration-nest))
+                  (format:out-char char))
+                (anychar-dispatch))))))
+
+      (define (tilde-dispatch)
+        (cond
+         ((>= format:pos format-string-len)
+          (format:out-str "~")          ; tilde at end of
                                        ; string is just
                                        ; output
-                arg-pos)                ; used for ~?
+          arg-pos)                      ; used for ~?
                                        ; continuance
-               ((and (or (zero? conditional-nest)
-                         (memv (peek-next-char) ; find conditional
+         ((and (or (zero? conditional-nest)
+                   (memv (peek-next-char) ; find conditional
                                        ; directives
-                               (append '(#\[ #\] #\; #\: #\@ #\^)
-                                       format:parameter-characters)))
-                     (or (zero? iteration-nest)
-                         (memv (peek-next-char) ; find iteration
+                         (append '(#\[ #\] #\; #\: #\@ #\^)
+                                 format:parameter-characters)))
+               (or (zero? iteration-nest)
+                   (memv (peek-next-char) ; find iteration
                                        ; directives
-                               (append '(#\{ #\} #\: #\@ #\^)
-                                       format:parameter-characters))))
-                (case (char-upcase (next-char))
-                     
-                  ;; format directives
-                     
-                  ((#\A)                ; Any -- for humans
-                   (set! format:read-proof
-                         (memq modifier '(colon colon-at)))
-                   (format:out-obj-padded (memq modifier '(at colon-at))
-                                          (next-arg) #f params)
-                   (anychar-dispatch))
-                  ((#\S)                ; Slashified -- for parsers
-                   (set! format:read-proof
-                         (memq modifier '(colon colon-at)))
-                   (format:out-obj-padded (memq modifier '(at colon-at))
-                                          (next-arg) #t params)
-                   (anychar-dispatch))
-                  ((#\D)                ; Decimal
-                   (format:out-num-padded modifier (next-arg) params 10)
-                   (anychar-dispatch))
-                  ((#\H)                ; Localized number
-                   (let* ((num      (next-arg))
-                          (locale   (case modifier
-                                      ((colon) (next-arg))
-                                      (else    %global-locale)))
-                          (argc     (length params))
-                          (width    (format:par params argc 0 #f "width"))
-                          (decimals (format:par params argc 1 #t "decimals"))
-                          (padchar  (integer->char
-                                     (format:par params argc 2 format:space-ch
-                                                 "padchar")))
-                          (str      (number->locale-string num decimals
-                                                           locale)))
-                     (format:out-str (if (and width
-                                              (< (string-length str) width))
-                                         (string-pad str width padchar)
-                                         str)))
-                   (anychar-dispatch))
-                  ((#\X)                ; Hexadecimal
-                   (format:out-num-padded modifier (next-arg) params 16)
-                   (anychar-dispatch))
-                  ((#\O)                ; Octal
-                   (format:out-num-padded modifier (next-arg) params 8)
-                   (anychar-dispatch))
-                  ((#\B)                ; Binary
-                   (format:out-num-padded modifier (next-arg) params 2)
-                   (anychar-dispatch))
-                  ((#\R)
-                   (if (null? params)
-                       (format:out-obj-padded ; Roman, cardinal,
+                         (append '(#\{ #\} #\: #\@ #\^)
+                                 format:parameter-characters))))
+          (case (char-upcase (next-char))
+
+            ;; format directives
+
+            ((#\A)                      ; Any -- for humans
+             (set! format:read-proof
+                   (memq modifier '(colon colon-at)))
+             (format:out-obj-padded (memq modifier '(at colon-at))
+                                    (next-arg) #f params)
+             (anychar-dispatch))
+            ((#\S)                      ; Slashified -- for parsers
+             (set! format:read-proof
+                   (memq modifier '(colon colon-at)))
+             (format:out-obj-padded (memq modifier '(at colon-at))
+                                    (next-arg) #t params)
+             (anychar-dispatch))
+            ((#\D)                      ; Decimal
+             (format:out-num-padded modifier (next-arg) params 10)
+             (anychar-dispatch))
+            ((#\H)                      ; Localized number
+             (let* ((num      (next-arg))
+                    (locale   (case modifier
+                                ((colon) (next-arg))
+                                (else    %global-locale)))
+                    (argc     (length params))
+                    (width    (format:par params argc 0 #f "width"))
+                    (decimals (format:par params argc 1 #t "decimals"))
+                    (padchar  (integer->char
+                               (format:par params argc 2 format:space-ch
+                                           "padchar")))
+                    (str      (number->locale-string num decimals
+                                                     locale)))
+               (format:out-str (if (and width
+                                        (< (string-length str) width))
+                                   (string-pad str width padchar)
+                                   str)))
+             (anychar-dispatch))
+            ((#\X)                      ; Hexadecimal
+             (format:out-num-padded modifier (next-arg) params 16)
+             (anychar-dispatch))
+            ((#\O)                      ; Octal
+             (format:out-num-padded modifier (next-arg) params 8)
+             (anychar-dispatch))
+            ((#\B)                      ; Binary
+             (format:out-num-padded modifier (next-arg) params 2)
+             (anychar-dispatch))
+            ((#\R)
+             (if (null? params)
+                 (format:out-obj-padded ; Roman, cardinal,
                                        ; ordinal numerals
-                        #f
-                        ((case modifier
-                           ((at) format:num->roman)
-                           ((colon-at) format:num->old-roman)
-                           ((colon) format:num->ordinal)
-                           (else format:num->cardinal))
-                         (next-arg))
-                        #f params)
-                       (format:out-num-padded ; any Radix
-                        modifier (next-arg) (cdr params) (car params)))
-                   (anychar-dispatch))
-                  ((#\F)                ; Fixed-format floating-point
-                   (format:out-fixed modifier (next-arg) params)
-                   (anychar-dispatch))
-                  ((#\E)                ; Exponential floating-point
-                   (format:out-expon modifier (next-arg) params)
-                   (anychar-dispatch))
-                  ((#\G)                ; General floating-point
-                   (format:out-general modifier (next-arg) params)
-                   (anychar-dispatch))
-                  ((#\$)                ; Dollars floating-point
-                   (format:out-dollar modifier (next-arg) params)
-                   (anychar-dispatch))
-                  ((#\I)                ; Complex numbers
-                   (let ((z (next-arg)))
-                     (unless (complex? z)
-                       (format:error "argument not a complex number"))
-                     (format:out-fixed modifier (real-part z) params)
-                     (format:out-fixed 'at (imag-part z) params)
-                     (format:out-char #\i))
-                   (anychar-dispatch))
-                  ((#\C)                ; Character
-                   (let ((ch (if (one-positive-integer? params)
-                                 (integer->char (car params))
-                                 (next-arg))))
-                     (unless (char? ch)
-                       (format:error "~~c expects a character"))
-                     (case modifier
-                       ((at)
-                        (format:out-str (object->string ch)))
-                       ((colon)
-                        (let ((c (char->integer ch)))
-                          (when (< c 0)
-                            (set! c (+ c 256))) ; compensate
+                  #f
+                  ((case modifier
+                     ((at) format:num->roman)
+                     ((colon-at) format:num->old-roman)
+                     ((colon) format:num->ordinal)
+                     (else format:num->cardinal))
+                   (next-arg))
+                  #f params)
+                 (format:out-num-padded ; any Radix
+                  modifier (next-arg) (cdr params) (car params)))
+             (anychar-dispatch))
+            ((#\F)                      ; Fixed-format floating-point
+             (format:out-fixed modifier (next-arg) params)
+             (anychar-dispatch))
+            ((#\E)                      ; Exponential floating-point
+             (format:out-expon modifier (next-arg) params)
+             (anychar-dispatch))
+            ((#\G)                      ; General floating-point
+             (format:out-general modifier (next-arg) params)
+             (anychar-dispatch))
+            ((#\$)                      ; Dollars floating-point
+             (format:out-dollar modifier (next-arg) params)
+             (anychar-dispatch))
+            ((#\I)                      ; Complex numbers
+             (let ((z (next-arg)))
+               (unless (complex? z)
+                 (format:error "argument not a complex number"))
+               (format:out-fixed modifier (real-part z) params)
+               (format:out-fixed 'at (imag-part z) params)
+               (format:out-char #\i))
+             (anychar-dispatch))
+            ((#\C)                      ; Character
+             (let ((ch (if (one-positive-integer? params)
+                           (integer->char (car params))
+                           (next-arg))))
+               (unless (char? ch)
+                 (format:error "~~c expects a character"))
+               (case modifier
+                 ((at)
+                  (format:out-str (object->string ch)))
+                 ((colon)
+                  (let ((c (char->integer ch)))
+                    (when (< c 0)
+                      (set! c (+ c 256))) ; compensate
                                        ; complement
                                        ; impl.
-                          (cond
-                           ((< c #x20) ; assumes that control
+                    (cond
+                     ((< c #x20)       ; assumes that control
                                        ; chars are < #x20
-                            (format:out-char #\^)
-                            (format:out-char
-                             (integer->char (+ c #x40))))
-                           ((>= c #x7f)
-                            (format:out-str "#\\")
-                            (format:out-str
-                             (number->string c 8)))
-                           (else
-                            (format:out-char ch)))))
-                       (else (format:out-char ch))))
-                   (anychar-dispatch))
-                  ((#\P)                ; Plural
-                   (when (memq modifier '(colon colon-at))
-                     (prev-arg))
-                   (let ((arg (next-arg)))
-                     (unless (number? arg)
-                       (format:error "~~p expects a number argument"))
-                     (if (= arg 1)
-                         (when (memq modifier '(at colon-at))
-                           (format:out-char #\y))
-                         (if (memq modifier '(at colon-at))
-                             (format:out-str "ies")
-                             (format:out-char #\s))))
-                   (anychar-dispatch))
-                  ((#\~)                ; Tilde
-                   (if (one-positive-integer? params)
-                       (format:out-fill (car params) #\~)
-                       (format:out-char #\~))
-                   (anychar-dispatch))
-                  ((#\%)                ; Newline
-                   (if (one-positive-integer? params)
-                       (format:out-fill (car params) #\newline)
-                       (format:out-char #\newline))
-                   (set! output-col 0)
-                   (anychar-dispatch))
-                  ((#\&)                ; Fresh line
-                   (if (one-positive-integer? params)
-                       (begin
-                         (when (> (car params) 0)
-                           (format:out-fill (- (car params)
-                                               (if (> output-col 0) 0 1))
-                                            #\newline))
-                         (set! output-col 0))
-                       (when (> output-col 0)
-                         (format:out-char #\newline)))
-                   (anychar-dispatch))
-                  ((#\_)                ; Space character
-                   (if (one-positive-integer? params)
-                       (format:out-fill (car params) #\space)
-                       (format:out-char #\space))
-                   (anychar-dispatch))
-                  ((#\/)                ; Tabulator character
-                   (if (one-positive-integer? params)
-                       (format:out-fill (car params) #\tab)
-                       (format:out-char #\tab))
-                   (anychar-dispatch))
-                  ((#\|)                ; Page seperator
-                   (if (one-positive-integer? params)
-                       (format:out-fill (car params) #\page)
-                       (format:out-char #\page))
-                   (set! output-col 0)
-                   (anychar-dispatch))
-                  ((#\T)                ; Tabulate
-                   (format:tabulate modifier params)
-                   (anychar-dispatch))
-                  ((#\Y)                ; Structured print
-                   (let ((width (if (one-positive-integer? params)
-                                    (car params)
-                                    79)))
+                      (format:out-char #\^)
+                      (format:out-char
+                       (integer->char (+ c #x40))))
+                     ((>= c #x7f)
+                      (format:out-str "#\\")
+                      (format:out-str
+                       (number->string c 8)))
+                     (else
+                      (format:out-char ch)))))
+                 (else (format:out-char ch))))
+             (anychar-dispatch))
+            ((#\P)                      ; Plural
+             (when (memq modifier '(colon colon-at))
+               (prev-arg))
+             (let ((arg (next-arg)))
+               (unless (number? arg)
+                 (format:error "~~p expects a number argument"))
+               (if (= arg 1)
+                   (when (memq modifier '(at colon-at))
+                     (format:out-char #\y))
+                   (if (memq modifier '(at colon-at))
+                       (format:out-str "ies")
+                       (format:out-char #\s))))
+             (anychar-dispatch))
+            ((#\~)                      ; Tilde
+             (if (one-positive-integer? params)
+                 (format:out-fill (car params) #\~)
+                 (format:out-char #\~))
+             (anychar-dispatch))
+            ((#\%)                      ; Newline
+             (if (one-positive-integer? params)
+                 (format:out-fill (car params) #\newline)
+                 (format:out-char #\newline))
+             (set! output-col 0)
+             (anychar-dispatch))
+            ((#\&)                      ; Fresh line
+             (if (one-positive-integer? params)
+                 (begin
+                   (when (> (car params) 0)
+                     (format:out-fill (- (car params)
+                                         (if (> output-col 0) 0 1))
+                                      #\newline))
+                   (set! output-col 0))
+                 (when (> output-col 0)
+                   (format:out-char #\newline)))
+             (anychar-dispatch))
+            ((#\_)                      ; Space character
+             (if (one-positive-integer? params)
+                 (format:out-fill (car params) #\space)
+                 (format:out-char #\space))
+             (anychar-dispatch))
+            ((#\/)                      ; Tabulator character
+             (if (one-positive-integer? params)
+                 (format:out-fill (car params) #\tab)
+                 (format:out-char #\tab))
+             (anychar-dispatch))
+            ((#\|)                      ; Page seperator
+             (if (one-positive-integer? params)
+                 (format:out-fill (car params) #\page)
+                 (format:out-char #\page))
+             (set! output-col 0)
+             (anychar-dispatch))
+            ((#\T)                      ; Tabulate
+             (format:tabulate modifier params)
+             (anychar-dispatch))
+            ((#\Y)                      ; Structured print
+             (let ((width (if (one-positive-integer? params)
+                              (car params)
+                              79)))
+               (case modifier
+                 ((at)
+                  (format:out-str
+                   (call-with-output-string
+                    (lambda (p)
+                      (truncated-print (next-arg) p
+                                       #:width width)))))
+                 ((colon-at)
+                  (format:out-str
+                   (call-with-output-string
+                    (lambda (p)
+                      (truncated-print (next-arg) p
+                                       #:width
+                                       (max (- width
+                                               output-col)
+                                            1))))))
+                 ((colon)
+                  (format:error "illegal modifier in ~~?"))
+                 (else
+                  (pretty-print (next-arg) port
+                                #:width width)
+                  (set! output-col 0))))
+             (anychar-dispatch))
+            ((#\? #\K)               ; Indirection (is "~K" in T-Scheme)
+             (cond
+              ((memq modifier '(colon colon-at))
+               (format:error "illegal modifier in ~~?"))
+              ((eq? modifier 'at)
+               (let* ((frmt (next-arg))
+                      (args (rest-args)))
+                 (add-arg-pos (format:format-work frmt args))))
+              (else
+               (let* ((frmt (next-arg))
+                      (args (next-arg)))
+                 (format:format-work frmt args))))
+             (anychar-dispatch))
+            ((#\!)                      ; Flush output
+             (set! flush-output? #t)
+             (anychar-dispatch))
+            ((#\newline)               ; Continuation lines
+             (when (eq? modifier 'at)
+               (format:out-char #\newline))
+             (if (< format:pos format-string-len)
+                 (do ((ch (peek-next-char) (peek-next-char)))
+                     ((or (not (char-whitespace? ch))
+                          (= format:pos (- format-string-len 1))))
+                   (if (eq? modifier 'colon)
+                       (format:out-char (next-char))
+                       (next-char))))
+             (anychar-dispatch))
+            ((#\*)                      ; Argument jumping
+             (case modifier
+               ((colon)                 ; jump backwards
+                (if (one-positive-integer? params)
+                    (do ((i 0 (+ i 1)))
+                        ((= i (car params)))
+                      (prev-arg))
+                    (prev-arg)))
+               ((at)                    ; jump absolute
+                (set! arg-pos
+                      (if (one-positive-integer? params) (car params) 0)))
+               ((colon-at)
+                (format:error "illegal modifier `:@' in ~~* directive"))
+               (else                    ; jump forward
+                (if (one-positive-integer? params)
+                    (do ((i 0 (+ i 1)))
+                        ((= i (car params)))
+                      (next-arg))
+                    (next-arg))))
+             (anychar-dispatch))
+            ((#\()                      ; Case conversion begin
+             (set! format:case-conversion
+                   (case modifier
+                     ((at) string-capitalize-first)
+                     ((colon) string-capitalize)
+                     ((colon-at) string-upcase)
+                     (else string-downcase)))
+             (anychar-dispatch))
+            ((#\))                      ; Case conversion end
+             (unless format:case-conversion
+               (format:error "missing ~~("))
+             (set! format:case-conversion #f)
+             (anychar-dispatch))
+            ((#\[)                      ; Conditional begin
+             (set! conditional-nest (+ conditional-nest 1))
+             (cond
+              ((= conditional-nest 1)
+               (set! clause-pos format:pos)
+               (set! clause-default #f)
+               (set! clauses '())
+               (set! conditional-type
                      (case modifier
-                       ((at)
-                        (format:out-str
-                         (call-with-output-string
-                           (lambda (p)
-                             (truncated-print (next-arg) p
-                                              #:width width)))))
-                       ((colon-at)
-                        (format:out-str
-                         (call-with-output-string
-                           (lambda (p)
-                             (truncated-print (next-arg) p
-                                              #:width
-                                              (max (- width
-                                                      output-col)
-                                                   1))))))
-                       ((colon)
-                        (format:error "illegal modifier in ~~?"))
+                       ((at) 'if-then)
+                       ((colon) 'if-else-then)
+                       ((colon-at) (format:error "illegal modifier in ~~["))
+                       (else 'num-case)))
+               (set! conditional-arg
+                     (if (one-positive-integer? params)
+                         (car params)
+                         (next-arg)))))
+             (anychar-dispatch))
+            ((#\;)                      ; Conditional separator
+             (when (zero? conditional-nest)
+               (format:error "~~; not in ~~[~~] conditional"))
+             (unless (null? params)
+               (format:error "no parameter allowed in ~~;"))
+             (when (= conditional-nest 1)
+               (let ((clause-str
+                      (cond
+                       ((eq? modifier 'colon)
+                        (set! clause-default #t)
+                        (substring format-string clause-pos
+                                   (- format:pos 3)))
+                       ((memq modifier '(at colon-at))
+                        (format:error "illegal modifier in ~~;"))
                        (else
-                        (pretty-print (next-arg) port
-                                      #:width width)
-                        (set! output-col 0))))
-                   (anychar-dispatch))
-                  ((#\? #\K)         ; Indirection (is "~K" in T-Scheme)
-                   (cond
-                    ((memq modifier '(colon colon-at))
-                     (format:error "illegal modifier in ~~?"))
-                    ((eq? modifier 'at)
-                     (let* ((frmt (next-arg))
-                            (args (rest-args)))
-                       (add-arg-pos (format:format-work frmt args))))
-                    (else
-                     (let* ((frmt (next-arg))
-                            (args (next-arg)))
-                       (format:format-work frmt args))))
-                   (anychar-dispatch))
-                  ((#\!)                ; Flush output
-                   (set! flush-output? #t)
-                   (anychar-dispatch))
-                  ((#\newline)         ; Continuation lines
-                   (when (eq? modifier 'at)
-                     (format:out-char #\newline))
-                   (if (< format:pos format-string-len)
-                       (do ((ch (peek-next-char) (peek-next-char)))
-                           ((or (not (char-whitespace? ch))
-                                (= format:pos (- format-string-len 1))))
-                         (if (eq? modifier 'colon)
-                             (format:out-char (next-char))
-                             (next-char))))
-                   (anychar-dispatch))
-                  ((#\*)                ; Argument jumping
-                   (case modifier
-                     ((colon)          ; jump backwards
-                      (if (one-positive-integer? params)
-                          (do ((i 0 (+ i 1)))
-                              ((= i (car params)))
-                            (prev-arg))
-                          (prev-arg)))
-                     ((at)              ; jump absolute
-                      (set! arg-pos
-                            (if (one-positive-integer? params) (car params) 
0)))
-                     ((colon-at)
-                      (format:error "illegal modifier `:@' in ~~* directive"))
-                     (else              ; jump forward
-                      (if (one-positive-integer? params)
-                          (do ((i 0 (+ i 1)))
-                              ((= i (car params)))
-                            (next-arg))
-                          (next-arg))))
-                   (anychar-dispatch))
-                  ((#\()                ; Case conversion begin
-                   (set! format:case-conversion
-                         (case modifier
-                           ((at) string-capitalize-first)
-                           ((colon) string-capitalize)
-                           ((colon-at) string-upcase)
-                           (else string-downcase)))
-                   (anychar-dispatch))
-                  ((#\))                ; Case conversion end
-                   (unless format:case-conversion
-                     (format:error "missing ~~("))
-                   (set! format:case-conversion #f)
-                   (anychar-dispatch))
-                  ((#\[)                ; Conditional begin
-                   (set! conditional-nest (+ conditional-nest 1))
-                   (cond
-                    ((= conditional-nest 1)
-                     (set! clause-pos format:pos)
-                     (set! clause-default #f)
-                     (set! clauses '())
-                     (set! conditional-type
-                           (case modifier
-                             ((at) 'if-then)
-                             ((colon) 'if-else-then)
-                             ((colon-at) (format:error "illegal modifier in 
~~["))
-                             (else 'num-case)))
-                     (set! conditional-arg
-                           (if (one-positive-integer? params)
-                               (car params)
-                               (next-arg)))))
-                   (anychar-dispatch))
-                  ((#\;)                ; Conditional separator
-                   (when (zero? conditional-nest)
-                     (format:error "~~; not in ~~[~~] conditional"))
-                   (unless (null? params)
-                     (format:error "no parameter allowed in ~~;"))
-                   (when (= conditional-nest 1)
-                     (let ((clause-str
-                            (cond
-                             ((eq? modifier 'colon)
-                              (set! clause-default #t)
-                              (substring format-string clause-pos
-                                         (- format:pos 3)))
-                             ((memq modifier '(at colon-at))
-                              (format:error "illegal modifier in ~~;"))
-                             (else
-                              (substring format-string clause-pos
-                                         (- format:pos 2))))))
-                       (set! clauses (append clauses (list clause-str)))
-                       (set! clause-pos format:pos)))
-                   (anychar-dispatch))
-                  ((#\])                ; Conditional end
-                   (when (zero? conditional-nest)
-                     (format:error "missing ~~["))
-                   (set! conditional-nest (- conditional-nest 1))
-                   (when modifier
-                     (format:error "no modifier allowed in ~~]"))
-                   (unless (null? params)
-                     (format:error "no parameter allowed in ~~]"))
-                   (cond
-                    ((zero? conditional-nest)
-                     (let ((clause-str (substring format-string clause-pos
-                                                  (- format:pos 2))))
-                       (if clause-default
-                           (set! clause-default clause-str)
-                           (set! clauses (append clauses (list clause-str)))))
-                     (case conditional-type
-                       ((if-then)
-                        (when conditional-arg
-                          (format:format-work (car clauses)
-                                              (list conditional-arg))))
-                       ((if-else-then)
-                        (add-arg-pos
-                         (format:format-work (if conditional-arg
-                                                 (cadr clauses)
-                                                 (car clauses))
-                                             (rest-args))))
-                       ((num-case)
-                        (when (or (not (integer? conditional-arg))
-                                  (< conditional-arg 0))
-                          (format:error "argument not a positive integer"))
-                        (unless (and (>= conditional-arg (length clauses))
-                                     (not clause-default))
-                          (add-arg-pos
-                           (format:format-work
-                            (if (>= conditional-arg (length clauses))
-                                clause-default
-                                (list-ref clauses conditional-arg))
-                            (rest-args))))))))
-                   (anychar-dispatch))
-                  ((#\{)                ; Iteration begin
-                   (set! iteration-nest (+ iteration-nest 1))
-                   (cond
-                    ((= iteration-nest 1)
-                     (set! iteration-pos format:pos)
-                     (set! iteration-type
-                           (case modifier
-                             ((at) 'rest-args)
-                             ((colon) 'sublists)
-                             ((colon-at) 'rest-sublists)
-                             (else 'list)))
-                     (set! max-iterations
-                           (if (one-positive-integer? params)
-                               (car params)
-                               #f))))
-                   (anychar-dispatch))
-                  ((#\})                ; Iteration end
-                   (when (zero? iteration-nest) (format:error "missing ~~{"))
-                   (set! iteration-nest (- iteration-nest 1))
-                   (case modifier
-                     ((colon)
-                      (unless max-iterations (set! max-iterations 1)))
-                     ((colon-at at) (format:error "illegal modifier")))
-                   (unless (null? params)
-                     (format:error "no parameters allowed in ~~}"))
-                   (if (zero? iteration-nest)
-                       (let ((iteration-str
-                              (substring format-string iteration-pos
-                                         (- format:pos (if modifier 3 2)))))
-                         (when (string=? iteration-str "")
-                           (set! iteration-str (next-arg)))
-                         (case iteration-type
-                           ((list)
-                            (let ((args (next-arg))
-                                  (args-len 0))
-                              (unless (list? args)
-                                (format:error "expected a list argument"))
-                              (set! args-len (length args))
+                        (substring format-string clause-pos
+                                   (- format:pos 2))))))
+                 (set! clauses (append clauses (list clause-str)))
+                 (set! clause-pos format:pos)))
+             (anychar-dispatch))
+            ((#\])                      ; Conditional end
+             (when (zero? conditional-nest)
+               (format:error "missing ~~["))
+             (set! conditional-nest (- conditional-nest 1))
+             (when modifier
+               (format:error "no modifier allowed in ~~]"))
+             (unless (null? params)
+               (format:error "no parameter allowed in ~~]"))
+             (cond
+              ((zero? conditional-nest)
+               (let ((clause-str (substring format-string clause-pos
+                                            (- format:pos 2))))
+                 (if clause-default
+                     (set! clause-default clause-str)
+                     (set! clauses (append clauses (list clause-str)))))
+               (case conditional-type
+                 ((if-then)
+                  (when conditional-arg
+                    (format:format-work (car clauses)
+                                        (list conditional-arg))))
+                 ((if-else-then)
+                  (add-arg-pos
+                   (format:format-work (if conditional-arg
+                                           (cadr clauses)
+                                           (car clauses))
+                                       (rest-args))))
+                 ((num-case)
+                  (when (or (not (integer? conditional-arg))
+                            (< conditional-arg 0))
+                    (format:error "argument not a positive integer"))
+                  (unless (and (>= conditional-arg (length clauses))
+                               (not clause-default))
+                    (add-arg-pos
+                     (format:format-work
+                      (if (>= conditional-arg (length clauses))
+                          clause-default
+                          (list-ref clauses conditional-arg))
+                      (rest-args))))))))
+             (anychar-dispatch))
+            ((#\{)                      ; Iteration begin
+             (set! iteration-nest (+ iteration-nest 1))
+             (cond
+              ((= iteration-nest 1)
+               (set! iteration-pos format:pos)
+               (set! iteration-type
+                     (case modifier
+                       ((at) 'rest-args)
+                       ((colon) 'sublists)
+                       ((colon-at) 'rest-sublists)
+                       (else 'list)))
+               (set! max-iterations
+                     (if (one-positive-integer? params)
+                         (car params)
+                         #f))))
+             (anychar-dispatch))
+            ((#\})                      ; Iteration end
+             (when (zero? iteration-nest) (format:error "missing ~~{"))
+             (set! iteration-nest (- iteration-nest 1))
+             (case modifier
+               ((colon)
+                (unless max-iterations (set! max-iterations 1)))
+               ((colon-at at) (format:error "illegal modifier")))
+             (unless (null? params)
+               (format:error "no parameters allowed in ~~}"))
+             (if (zero? iteration-nest)
+                 (let ((iteration-str
+                        (substring format-string iteration-pos
+                                   (- format:pos (if modifier 3 2)))))
+                   (when (string=? iteration-str "")
+                     (set! iteration-str (next-arg)))
+                   (case iteration-type
+                     ((list)
+                      (let ((args (next-arg))
+                            (args-len 0))
+                        (unless (list? args)
+                          (format:error "expected a list argument"))
+                        (set! args-len (length args))
+                        (do ((arg-pos 0 (+ arg-pos
+                                           (format:format-work
+                                            iteration-str
+                                            (list-tail args arg-pos))))
+                             (i 0 (+ i 1)))
+                            ((or (>= arg-pos args-len)
+                                 (and max-iterations
+                                      (>= i max-iterations)))))))
+                     ((sublists)
+                      (let ((args (next-arg))
+                            (args-len 0))
+                        (unless (list? args)
+                          (format:error "expected a list argument"))
+                        (set! args-len (length args))
+                        (do ((arg-pos 0 (+ arg-pos 1)))
+                            ((or (>= arg-pos args-len)
+                                 (and max-iterations
+                                      (>= arg-pos max-iterations))))
+                          (let ((sublist (list-ref args arg-pos)))
+                            (unless (list? sublist)
+                              (format:error "expected a list of lists 
argument"))
+                            (format:format-work iteration-str sublist)))))
+                     ((rest-args)
+                      (let* ((args (rest-args))
+                             (args-len (length args))
+                             (usedup-args
                               (do ((arg-pos 0 (+ arg-pos
                                                  (format:format-work
                                                   iteration-str
-                                                  (list-tail args arg-pos))))
+                                                  (list-tail
+                                                   args arg-pos))))
                                    (i 0 (+ i 1)))
                                   ((or (>= arg-pos args-len)
                                        (and max-iterations
-                                            (>= i max-iterations)))))))
-                           ((sublists)
-                            (let ((args (next-arg))
-                                  (args-len 0))
-                              (unless (list? args)
-                                (format:error "expected a list argument"))
-                              (set! args-len (length args))
+                                            (>= i max-iterations)))
+                                   arg-pos))))
+                        (add-arg-pos usedup-args)))
+                     ((rest-sublists)
+                      (let* ((args (rest-args))
+                             (args-len (length args))
+                             (usedup-args
                               (do ((arg-pos 0 (+ arg-pos 1)))
                                   ((or (>= arg-pos args-len)
                                        (and max-iterations
-                                            (>= arg-pos max-iterations))))
+                                            (>= arg-pos max-iterations)))
+                                   arg-pos)
                                 (let ((sublist (list-ref args arg-pos)))
                                   (unless (list? sublist)
-                                    (format:error "expected a list of lists 
argument"))
+                                    (format:error "expected list arguments"))
                                   (format:format-work iteration-str 
sublist)))))
-                           ((rest-args)
-                            (let* ((args (rest-args))
-                                   (args-len (length args))
-                                   (usedup-args
-                                    (do ((arg-pos 0 (+ arg-pos
-                                                       (format:format-work
-                                                        iteration-str
-                                                        (list-tail
-                                                         args arg-pos))))
-                                         (i 0 (+ i 1)))
-                                        ((or (>= arg-pos args-len)
-                                             (and max-iterations
-                                                  (>= i max-iterations)))
-                                         arg-pos))))
-                              (add-arg-pos usedup-args)))
-                           ((rest-sublists)
-                            (let* ((args (rest-args))
-                                   (args-len (length args))
-                                   (usedup-args
-                                    (do ((arg-pos 0 (+ arg-pos 1)))
-                                        ((or (>= arg-pos args-len)
-                                             (and max-iterations
-                                                  (>= arg-pos max-iterations)))
-                                         arg-pos)
-                                      (let ((sublist (list-ref args arg-pos)))
-                                        (unless (list? sublist)
-                                          (format:error "expected list 
arguments"))
-                                        (format:format-work iteration-str 
sublist)))))
-                              (add-arg-pos usedup-args)))
-                           (else (format:error "internal error in ~~}")))))
-                   (anychar-dispatch))
-                  ((#\^)                ; Up and out
-                   (let* ((continue
-                           (cond
-                            ((not (null? params))
-                             (not
-                              (case (length params)
-                                ((1) (zero? (car params)))
-                                ((2) (= (list-ref params 0) (list-ref params 
1)))
-                                ((3) (<= (list-ref params 0)
-                                         (list-ref params 1)
-                                         (list-ref params 2)))
-                                (else (format:error "too much parameters")))))
-                            (format:case-conversion ; if conversion stop 
conversion
-                             (set! format:case-conversion string-copy) #t)
-                            ((= iteration-nest 1) #t)
-                            ((= conditional-nest 1) #t)
-                            ((>= arg-pos arg-len)
-                             (set! format:pos format-string-len) #f)
-                            (else #t))))
-                     (when continue
-                       (anychar-dispatch))))
-
-                  ;; format directive modifiers and parameters
-
-                  ((#\@)                ; `@' modifier
-                   (when (memq modifier '(at colon-at))
-                     (format:error "double `@' modifier"))
-                   (set! modifier (if (eq? modifier 'colon) 'colon-at 'at))
-                   (tilde-dispatch))
-                  ((#\:)                ; `:' modifier
-                   (when (memq modifier '(colon colon-at))
-                     (format:error "double `:' modifier"))
-                   (set! modifier (if (eq? modifier 'at) 'colon-at 'colon))
-                   (tilde-dispatch))
-                  ((#\')                ; Character parameter
-                   (when modifier
-                     (format:error "misplaced modifier"))
-                   (set! params (append params (list (char->integer 
(next-char)))))
-                   (set! param-value-found #t)
-                   (tilde-dispatch))
-                  ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\- #\+) ; num. 
paramtr
-                   (when modifier
-                     (format:error "misplaced modifier"))
-                   (let ((num-str-beg (- format:pos 1))
-                         (num-str-end format:pos))
-                     (do ((ch (peek-next-char) (peek-next-char)))
-                         ((not (char-numeric? ch)))
-                       (next-char)
-                       (set! num-str-end (+ 1 num-str-end)))
-                     (set! params
-                           (append params
-                                   (list (string->number
-                                          (substring format-string
-                                                     num-str-beg
-                                                     num-str-end))))))
-                   (set! param-value-found #t)
-                   (tilde-dispatch))
-                  ((#\V)           ; Variable parameter from next argum.
-                   (when modifier
-                     (format:error "misplaced modifier"))
-                   (set! params (append params (list (next-arg))))
-                   (set! param-value-found #t)
-                   (tilde-dispatch))
-                  ((#\#)         ; Parameter is number of remaining args
-                   (when param-value-found
-                     (format:error "misplaced '#'"))
-                   (when modifier
-                     (format:error "misplaced modifier"))
-                   (set! params (append params (list (length (rest-args)))))
-                   (set! param-value-found #t)
-                   (tilde-dispatch))
-                  ((#\,)                ; Parameter separators
-                   (when modifier
-                     (format:error "misplaced modifier"))
-                   (unless param-value-found
-                     (set! params (append params '(#f)))) ; append empty 
paramtr
-                   (set! param-value-found #f)
-                   (tilde-dispatch))
-                  ((#\Q)                ; Inquiry messages
-                   (if (eq? modifier 'colon)
-                       (format:out-str format:version)
-                       (let ((nl (string #\newline)))
-                         (format:out-str
-                          (string-append
-                           "SLIB Common LISP format version " format:version nl
-                           "  (C) copyright 1992-1994 by Dirk Lutzebaeck" nl
-                           "  please send bug reports to `address@hidden'"
-                           nl))))
-                   (anychar-dispatch))
-                  (else                 ; Unknown tilde directive
-                   (format:error "unknown control character `~c'"
-                                 (string-ref format-string (- format:pos 
1))))))
-               (else (anychar-dispatch)))))) ; in case of conditional
-
-        (set! format:pos 0)
-        (set! format:arg-pos 0)
-        (anychar-dispatch)              ; start the formatting
-        (set! format:pos recursive-pos-save)
-        arg-pos))                 ; return the position in the arg. list
+                        (add-arg-pos usedup-args)))
+                     (else (format:error "internal error in ~~}")))))
+             (anychar-dispatch))
+            ((#\^)                      ; Up and out
+             (let* ((continue
+                     (cond
+                      ((not (null? params))
+                       (not
+                        (case (length params)
+                          ((1) (zero? (car params)))
+                          ((2) (= (list-ref params 0) (list-ref params 1)))
+                          ((3) (<= (list-ref params 0)
+                                   (list-ref params 1)
+                                   (list-ref params 2)))
+                          (else (format:error "too much parameters")))))
+                      (format:case-conversion ; if conversion stop conversion
+                       (set! format:case-conversion string-copy) #t)
+                      ((= iteration-nest 1) #t)
+                      ((= conditional-nest 1) #t)
+                      ((>= arg-pos arg-len)
+                       (set! format:pos format-string-len) #f)
+                      (else #t))))
+               (when continue
+                 (anychar-dispatch))))
+
+            ;; format directive modifiers and parameters
+
+            ((#\@)                      ; `@' modifier
+             (when (memq modifier '(at colon-at))
+               (format:error "double `@' modifier"))
+             (set! modifier (if (eq? modifier 'colon) 'colon-at 'at))
+             (tilde-dispatch))
+            ((#\:)                      ; `:' modifier
+             (when (memq modifier '(colon colon-at))
+               (format:error "double `:' modifier"))
+             (set! modifier (if (eq? modifier 'at) 'colon-at 'colon))
+             (tilde-dispatch))
+            ((#\')                      ; Character parameter
+             (when modifier
+               (format:error "misplaced modifier"))
+             (set! params (append params (list (char->integer (next-char)))))
+             (set! param-value-found #t)
+             (tilde-dispatch))
+            ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\- #\+) ; num. paramtr
+             (when modifier
+               (format:error "misplaced modifier"))
+             (let ((num-str-beg (- format:pos 1))
+                   (num-str-end format:pos))
+               (do ((ch (peek-next-char) (peek-next-char)))
+                   ((not (char-numeric? ch)))
+                 (next-char)
+                 (set! num-str-end (+ 1 num-str-end)))
+               (set! params
+                     (append params
+                             (list (string->number
+                                    (substring format-string
+                                               num-str-beg
+                                               num-str-end))))))
+             (set! param-value-found #t)
+             (tilde-dispatch))
+            ((#\V)                 ; Variable parameter from next argum.
+             (when modifier
+               (format:error "misplaced modifier"))
+             (set! params (append params (list (next-arg))))
+             (set! param-value-found #t)
+             (tilde-dispatch))
+            ((#\#)               ; Parameter is number of remaining args
+             (when param-value-found
+               (format:error "misplaced '#'"))
+             (when modifier
+               (format:error "misplaced modifier"))
+             (set! params (append params (list (length (rest-args)))))
+             (set! param-value-found #t)
+             (tilde-dispatch))
+            ((#\,)                      ; Parameter separators
+             (when modifier
+               (format:error "misplaced modifier"))
+             (unless param-value-found
+               (set! params (append params '(#f)))) ; append empty paramtr
+             (set! param-value-found #f)
+             (tilde-dispatch))
+            ((#\Q)                      ; Inquiry messages
+             (if (eq? modifier 'colon)
+                 (format:out-str format:version)
+                 (let ((nl (string #\newline)))
+                   (format:out-str
+                    (string-append
+                     "SLIB Common LISP format version " format:version nl
+                     "  (C) copyright 1992-1994 by Dirk Lutzebaeck" nl
+                     "  please send bug reports to `address@hidden'"
+                     nl))))
+             (anychar-dispatch))
+            (else                       ; Unknown tilde directive
+             (format:error "unknown control character `~c'"
+                           (string-ref format-string (- format:pos 1))))))
+         (else (anychar-dispatch))))    ; in case of conditional
+
+      (set! format:pos 0)
+      (set! format:arg-pos 0)
+      (anychar-dispatch)                ; start the formatting
+      (set! format:pos recursive-pos-save)
+      arg-pos)                 ; return the position in the arg. list
 
     ;; when format:read-proof is true, format:obj->str will wrap
     ;; result strings starting with "#<" in an extra pair of double



reply via email to

[Prev in Thread] Current Thread [Next in Thread]