⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srfi-19.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 4 页
字号:
                                          #\0 2) port))))   (cons #\y (lambda (date pad-with port)               (display (priv:padding (priv:last-n-digits                                       (date-year date) 2)                                      pad-with                                      2)                        port)))   (cons #\Y (lambda (date pad-with port)               (display (date-year date) port)))   (cons #\z (lambda (date pad-with port)               (priv:tz-printer (date-zone-offset date) port)))   (cons #\Z (lambda (date pad-with port)               (priv:locale-print-time-zone date port)))   (cons #\1 (lambda (date pad-with port)               (display (date->string date "~Y-~m-~d") port)))   (cons #\2 (lambda (date pad-with port)               (display (date->string date "~k:~M:~S~z") port)))   (cons #\3 (lambda (date pad-with port)               (display (date->string date "~k:~M:~S") port)))   (cons #\4 (lambda (date pad-with port)               (display (date->string date "~Y-~m-~dT~k:~M:~S~z") port)))   (cons #\5 (lambda (date pad-with port)               (display (date->string date "~Y-~m-~dT~k:~M:~S") port)))))(define (priv:get-formatter char)  (let ((associated (assoc char priv:directives)))    (if associated (cdr associated) #f)))(define (priv:date-printer date index format-string str-len port)  (if (>= index str-len)      (values)      (let ((current-char (string-ref format-string index)))        (if (not (char=? current-char #\~))            (begin              (display current-char port)              (priv:date-printer date (+ index 1) format-string str-len port))            (if (= (+ index 1) str-len) ; bad format string.                (priv:time-error 'priv:date-printer 'bad-date-format-string                                 format-string)                (let ((pad-char? (string-ref format-string (+ index 1))))                  (cond                   ((char=? pad-char? #\-)                    (if (= (+ index 2) str-len) ; bad format string.                        (priv:time-error 'priv:date-printer                                         'bad-date-format-string                                         format-string)                        (let ((formatter (priv:get-formatter                                          (string-ref format-string                                                      (+ index 2)))))                          (if (not formatter)                              (priv:time-error 'priv:date-printer                                               'bad-date-format-string                                               format-string)                              (begin                                (formatter date #f port)                                (priv:date-printer date                                                   (+ index 3)                                                   format-string                                                   str-len                                                   port))))))                   ((char=? pad-char? #\_)                    (if (= (+ index 2) str-len) ; bad format string.                        (priv:time-error 'priv:date-printer                                         'bad-date-format-string                                         format-string)                        (let ((formatter (priv:get-formatter                                          (string-ref format-string                                                      (+ index 2)))))                          (if (not formatter)                              (priv:time-error 'priv:date-printer                                               'bad-date-format-string                                               format-string)                              (begin                                (formatter date #\Space port)                                (priv:date-printer date                                                   (+ index 3)                                                   format-string                                                   str-len                                                   port))))))                   (else                    (let ((formatter (priv:get-formatter                                      (string-ref format-string                                                  (+ index 1)))))                      (if (not formatter)                          (priv:time-error 'priv:date-printer                                           'bad-date-format-string                                           format-string)                          (begin                            (formatter date #\0 port)                            (priv:date-printer date                                               (+ index 2)                                               format-string                                               str-len                                               port))))))))))))(define (date->string date .  format-string)  (let ((str-port (open-output-string))        (fmt-str (if (null? format-string) "~c" (car format-string))))    (priv:date-printer date 0 fmt-str (string-length fmt-str) str-port)    (get-output-string str-port)))(define (priv:char->int ch)  (case ch   ((#\0) 0)   ((#\1) 1)   ((#\2) 2)   ((#\3) 3)   ((#\4) 4)   ((#\5) 5)   ((#\6) 6)   ((#\7) 7)   ((#\8) 8)   ((#\9) 9)   (else (priv:time-error 'bad-date-template-string                          (list "Non-integer character" ch i)))));; read an integer upto n characters long on port; upto -> #f is any length(define (priv:integer-reader upto port)  (let loop ((accum 0) (nchars 0))    (let ((ch (peek-char port)))      (if (or (eof-object? ch)              (not (char-numeric? ch))              (and upto (>= nchars  upto)))          accum          (loop (+ (* accum 10) (priv:char->int (read-char port)))                (+ nchars 1))))))(define (priv:make-integer-reader upto)  (lambda (port)    (priv:integer-reader upto port)));; read *exactly* n characters and convert to integer; could be padded(define (priv:integer-reader-exact n port)  (let ((padding-ok #t))    (define (accum-int port accum nchars)      (let ((ch (peek-char port)))	(cond	 ((>= nchars n) accum)	 ((eof-object? ch)	  (priv:time-error 'string->date 'bad-date-template-string                           "Premature ending to integer read."))	 ((char-numeric? ch)	  (set! padding-ok #f)	  (accum-int port                     (+ (* accum 10) (priv:char->int (read-char port)))		     (+ nchars 1)))	 (padding-ok	  (read-char port) ; consume padding	  (accum-int port accum (+ nchars 1)))	 (else ; padding where it shouldn't be	  (priv:time-error 'string->date 'bad-date-template-string                           "Non-numeric characters in integer read.")))))    (accum-int port 0 0)))(define (priv:make-integer-exact-reader n)  (lambda (port)    (priv:integer-reader-exact n port)))(define (priv:zone-reader port)  (let ((offset 0)        (positive? #f))    (let ((ch (read-char port)))      (if (eof-object? ch)          (priv:time-error 'string->date 'bad-date-template-string                           (list "Invalid time zone +/-" ch)))      (if (or (char=? ch #\Z) (char=? ch #\z))          0          (begin            (cond             ((char=? ch #\+) (set! positive? #t))             ((char=? ch #\-) (set! positive? #f))             (else              (priv:time-error 'string->date 'bad-date-template-string                               (list "Invalid time zone +/-" ch))))            (let ((ch (read-char port)))              (if (eof-object? ch)                  (priv:time-error 'string->date 'bad-date-template-string                                   (list "Invalid time zone number" ch)))              (set! offset (* (priv:char->int ch)                              10 60 60)))            (let ((ch (read-char port)))              (if (eof-object? ch)                  (priv:time-error 'string->date 'bad-date-template-string                                   (list "Invalid time zone number" ch)))              (set! offset (+ offset (* (priv:char->int ch)                                        60 60))))            (let ((ch (read-char port)))              (if (eof-object? ch)                  (priv:time-error 'string->date 'bad-date-template-string                                   (list "Invalid time zone number" ch)))              (set! offset (+ offset (* (priv:char->int ch)                                        10 60))))            (let ((ch (read-char port)))              (if (eof-object? ch)                  (priv:time-error 'string->date 'bad-date-template-string                                   (list "Invalid time zone number" ch)))              (set! offset (+ offset (* (priv:char->int ch)                                        60))))            (if positive? offset (- offset)))))));; looking at a char, read the char string, run thru indexer, return index(define (priv:locale-reader port indexer)  (define (read-char-string result)    (let ((ch (peek-char port)))      (if (char-alphabetic? ch)          (read-char-string (cons (read-char port) result))          (list->string (reverse! result)))))  (let* ((str (read-char-string '()))         (index (indexer str)))    (if index index (priv:time-error 'string->date                                     'bad-date-template-string                                     (list "Invalid string for " indexer)))))(define (priv:make-locale-reader indexer)  (lambda (port)    (priv:locale-reader port indexer)))(define (priv:make-char-id-reader char)  (lambda (port)    (if (char=? char (read-char port))        char        (priv:time-error 'string->date                         'bad-date-template-string                         "Invalid character match."))));; A List of formatted read directives.;; Each entry is a list.;; 1. the character directive;;; a procedure, which takes a character as input & returns;; 2. #t as soon as a character on the input port is acceptable;; for input,;; 3. a port reader procedure that knows how to read the current port;; for a value. Its one parameter is the port.;; 4. a action procedure, that takes the value (from 3.) and some;; object (here, always the date) and (probably) side-effects it.;; In some cases (e.g., ~A) the action is to do nothing(define priv:read-directives  (let ((ireader4 (priv:make-integer-reader 4))        (ireader2 (priv:make-integer-reader 2))        (ireaderf (priv:make-integer-reader #f))        (eireader2 (priv:make-integer-exact-reader 2))        (eireader4 (priv:make-integer-exact-reader 4))        (locale-reader-abbr-weekday (priv:make-locale-reader                                     priv:locale-abbr-weekday->index))        (locale-reader-long-weekday (priv:make-locale-reader                                     priv:locale-long-weekday->index))        (locale-reader-abbr-month   (priv:make-locale-reader                                     priv:locale-abbr-month->index))        (locale-reader-long-month   (priv:make-locale-reader                                     priv:locale-long-month->index))        (char-fail (lambda (ch) #t))        (do-nothing (lambda (val object) (values))))    (list     (list #\~ char-fail (priv:make-char-id-reader #\~) do-nothing)     (list #\a char-alphabetic? locale-reader-abbr-weekday do-nothing)     (list #\A char-alphabetic? locale-reader-long-weekday do-nothing)     (list #\b char-alphabetic? locale-reader-abbr-month           (lambda (val object)             (set-date-month! object val)))     (list #\B char-alphabetic? locale-reader-long-month           (lambda (val object)             (set-date-month! object val)))     (list #\d char-numeric? ireader2 (lambda (val object)                                        (set-date-day!                                         object val)))     (list #\e char-fail eireader2 (lambda (val object)                                     (set-date-day! object val)))     (list #\h char-alphabetic? locale-reader-abbr-month           (lambda (val object)             (set-date-month! object val)))     (list #\H char-numeric? ireader2 (lambda (val object)                                        (set-date-hour! object val)))     (list #\k char-fail eireader2 (lambda (val object)                                     (set-date-hour! object val)))     (list #\m char-numeric? ireader2 (lambda (val object)                                        (set-date-month! object val)))     (list #\M char-numeric? ireader2 (lambda (val object)                                        (set-date-minute!                                         object val)))     (list #\S char-numeric? ireader2 (lambda (val object)                                        (set-date-second! object val)))     (list #\y char-fail eireader2           (lambda (val object)             (set-date-year! object (priv:natural-year val))))     (list #\Y char-numeric? ireader4 (lambda (val object)                                        (set-date-year! object val)))     (list #\z (lambda (c)                 (or (char=? c #\Z)                     (char=? c #\z)                     (char=? c #\+)                     (char=? c #\-)))           priv:zone-reader (lambda (val object)                              (set-date-zone-offset! object val))))))(define (priv:string->date date index format-string str-len port template-string)  (define (skip-until port skipper)    (let ((ch (peek-char port)))      (if (eof-object? port)          (priv:time-error 'string->date 'bad-date-format-string template-string)          (if (not (skipper ch))              (begin (read-char port) (skip-until port skipper))))))  (if (>= index str-len)      (begin        (values))      (let ((current-char (string-ref format-string index)))        (if (not (char=? current-char #\~))            (let ((port-char (read-char port)))              (if (or (eof-object? port-char)                      (not (char=? current-char port-char)))                  (priv:time-error 'string->date                                   'bad-date-format-string template-string))              (priv:string->date date                                 (+ index 1)                                 format-string                                 str-len                                 port                                 template-string))            ;; otherwise, it's an escape, we hope            (if (> (+ index 1) str-len)                (priv:time-error 'string->date                                 'bad-date-format-string template-string)                (let* ((format-char (string-ref format-string (+ index 1)))                       (format-info (assoc format-char priv:read-directives)))                  (if (not format-info)                      (priv:time-error 'string->date                                       'bad-date-format-string template-string)                      (begin                        (let ((skipper (cadr format-info))                              (reader  (caddr format-info))                              (actor   (cadddr format-info)))                          (skip-until port skipper)                          (let ((val (reader port)))                            (if (eof-object? val)                                (priv:time-error 'string->date                                                 'bad-date-format-string                                                 template-string)                                (actor val date)))                          (priv:string->date date                                             (+ index 2)                                             format-string                                             str-len                                             port                                             template-string))))))))))(define (string->date input-string template-string)  (define (priv:date-ok? date)    (and (date-nanosecond date)         (date-second date)         (date-minute date)         (date-hour date)         (date-day date)         (date-month date)         (date-year date)         (date-zone-offset date)))  (let ((newdate (make-date 0 0 0 0 #f #f #f #f)))    (priv:string->date newdate                       0                       template-string                       (string-length template-string)                       (open-input-string input-string)                       template-string)    (if (not (date-zone-offset newdate))	(begin	  ;; this is necessary to get DST right -- as far as we can	  ;; get it right (think of the double/missing hour in the	  ;; night when we are switching between normal time and DST).	  (set-date-zone-offset! newdate				 (priv:local-tz-offset				  (make-time time-utc 0 0)))	  (set-date-zone-offset! newdate				 (priv:local-tz-offset				  (date->time-utc newdate)))))    (if (priv:date-ok? newdate)        newdate        (priv:time-error         'string->date         'bad-date-format-string         (list "Incomplete date read. " newdate template-string)))));;; srfi-19.scm ends here

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -