~ chicken-r7rs (master) /scheme.read.scm
Trap1(module scheme.read (read)2 (import (except scheme read)3 (only chicken.base case-sensitive define-constant define-inline)4 (only chicken.base fluid-let parameterize optional unless when)5 (only chicken.fixnum fx+ fx=)6 (only chicken.platform feature?)7 (only chicken.read-syntax current-read-table set-read-syntax!)8 (only chicken.type :))910 ;;;11 ;;; 2.1 Identifiers12 ;;;1314 ;; XXX Slot 14 indicates whether or not a port is case-folded.15 ;; Hopefully this doesn't interfere with anything else.1617 (define-constant port-fold-case-slot 14)1819 (define-inline (port-fold-case p)20 (##sys#slot p port-fold-case-slot))2122 (set-read-syntax!23 'fold-case24 (lambda (p)25 (##sys#setslot p port-fold-case-slot 'fold-case)26 (read p)))2728 (set-read-syntax!29 'no-fold-case30 (lambda (p)31 (##sys#setslot p port-fold-case-slot 'no-fold-case)32 (read p)))3334 (define sys-read ##sys#read)3536 (set! ##sys#read37 (lambda (port hook)38 (parameterize ((case-sensitive39 (case (port-fold-case port)40 ((fold-case) #f)41 ((no-fold-case) #t)42 (else (case-sensitive)))))43 (fluid-let ((##sys#default-read-info-hook hook))44 (read port)))))4546 ;;;47 ;;; 6.13.2 Input48 ;;;4950 (define (data? o)51 (not (procedure? o)))5253 (define (unthunk o fail)54 (let ((v (o)))55 (cond ((data? v) v)56 ((eq? v o)57 (fail "self-referential datum"))58 (else59 (unthunk v fail)))))6061 ;; Fills holes in `o` destructively.62 (define (unthunkify! o fail)63 (let loop! ((o o))64 (cond ((pair? o)65 (if (data? (car o))66 (loop! (car o))67 (set-car! o (unthunk (car o) fail)))68 (if (data? (cdr o))69 (loop! (cdr o))70 (set-cdr! o (unthunk (cdr o) fail))))71 ((vector? o)72 (let ((len (vector-length o)))73 (do ((i 0 (fx+ i 1)))74 ((fx= i len))75 (let ((v (vector-ref o i)))76 (if (data? v)77 (loop! v)78 (vector-set! o i (unthunk v fail))))))))))7980 (define (read-with-shared-structure port)8182 (define read-table (current-read-table))83 (unless (##sys#slot read-table 3)84 (##sys#setslot read-table 3 (##sys#make-vector 256 #f)))8586 (define read-hash/orig (##sys#slot (##sys#slot read-table 3) 35))87 (define read-equal/orig (##sys#slot (##sys#slot read-table 3) 61))8889 (define shared '())90 (define (register-shared! n thunk)91 (set! shared (cons (cons n thunk) shared)))9293 (define (read-hash/shared _ p n)94 (##sys#read-char-0 p)95 (cond ((assv n shared) => cdr)96 (else (##sys#read-error p "undefined datum" n))))9798 (define (read-equal/shared _ p n)99 (##sys#read-char-0 p)100 (letrec ((o (begin101 (register-shared! n (lambda () o))102 (sys-read p ##sys#default-read-info-hook))))103 o))104105 (define (read/shared p)106 (let ((o (sys-read port ##sys#default-read-info-hook)))107 (when (pair? shared)108 (unthunkify! o (lambda a (apply ##sys#read-error p a))))109 o))110111 (dynamic-wind112 (lambda ()113 (##sys#setslot (##sys#slot read-table 3) 35 read-hash/shared)114 (##sys#setslot (##sys#slot read-table 3) 61 read-equal/shared))115 (lambda ()116 (##sys#check-input-port port #t 'read)117 (read/shared port))118 (lambda ()119 (##sys#setslot (##sys#slot read-table 3) 35 read-hash/orig)120 (##sys#setslot (##sys#slot read-table 3) 61 read-equal/orig))))121122 (: read (#!optional input-port -> *))123 (define (read . port)124 (read-with-shared-structure125 (optional port (current-input-port)))))