|
19 | 19 | (srfi srfi-2) |
20 | 20 | (srfi srfi-8) |
21 | 21 | ) ;import |
22 | | - (export |
| 22 | + (re-export |
| 23 | + ; (scheme base) defined by R7RS |
| 24 | + let-values |
| 25 | + ; R7RS 5: Program Structure |
| 26 | + define-values define-record-type |
| 27 | + ; R7RS 6.2: Numbers |
| 28 | + square exact inexact max min floor floor/ s7-floor ceiling s7-ceiling truncate truncate/ s7-truncate |
| 29 | + round s7-round floor-quotient floor-remainder gcd lcm s7-lcm modulo exact-integer-sqrt |
| 30 | + numerator denominator exact-integer? number->string string->number |
| 31 | + ; R7RS 6.3: Booleans |
| 32 | + boolean=? |
| 33 | + ; R7RS 6.4: list |
| 34 | + pair? cons car cdr set-car! set-cdr! caar cadr cdar cddr |
| 35 | + null? list? make-list list length append reverse list-tail |
| 36 | + list-ref list-set! memq memv member assq assv assoc list-copy |
| 37 | + ; R7RS 6.5: Symbol |
| 38 | + symbol? symbol=? string->symbol symbol->string |
| 39 | + ; R7RS 6.6: Characters |
| 40 | + digit-value |
| 41 | + ; R7RS 6.7: String |
| 42 | + string-copy |
| 43 | + ; R7RS 6.8 Vector |
| 44 | + vector->string string->vector vector-copy vector-copy! vector-fill! |
| 45 | + ; R7RS 6.9 Bytevectors |
| 46 | + bytevector? make-bytevector bytevector bytevector-length bytevector-u8-ref |
| 47 | + bytevector-u8-set! bytevector-copy bytevector-append |
| 48 | + utf8->string string->utf8 utf8-string-length u8-substring bytevector-advance-utf8 |
| 49 | + ; Input and Output |
| 50 | + call-with-port port? binary-port? textual-port? input-port-open? output-port-open? |
| 51 | + open-binary-input-file open-binary-output-file close-port eof-object |
| 52 | + ; Control flow |
| 53 | + string-map vector-map string-for-each vector-for-each |
| 54 | + ; Exception |
| 55 | + raise guard read-error? file-error? |
23 | 56 | ; SRFI-2 |
24 | 57 | and-let* |
25 | 58 | ; SRFI-8 |
|
38 | 71 | string->keyword |
39 | 72 | symbol->keyword |
40 | 73 | keyword->symbol |
| 74 | + ) ;re-export |
| 75 | + (export |
| 76 | + ; workaround for binding s7 primitives |
| 77 | + (rename vector-append vector-append) |
41 | 78 | ; Extra routines |
42 | 79 | loose-car |
43 | 80 | loose-cdr |
|
73 | 110 | ) ;lambda |
74 | 111 | ) ;if |
75 | 112 | ) ;define |
76 | | - |
| 113 | + |
77 | 114 | (define (any? x) #t) |
78 | 115 |
|
79 | | - ; 0 clause BSD, from S7 repo stuff.scm |
80 | | - (define-macro (typed-lambda args . body) |
81 | | - ; (typed-lambda ((var [type])...) ...) |
82 | | - (if (symbol? args) |
83 | | - (apply lambda args body) |
84 | | - (let ((new-args (copy args))) |
85 | | - (do ((p new-args (cdr p))) |
86 | | - ((not (pair? p))) |
87 | | - (if (pair? (car p)) |
88 | | - (set-car! p (caar p)) |
89 | | - ) ;if |
90 | | - ) ;do |
91 | | - `(lambda ,new-args |
92 | | - ,@(map |
93 | | - (lambda (arg) |
94 | | - (if (pair? arg) |
95 | | - `(unless (,(cadr arg) ,(car arg)) |
96 | | - (error 'type-error |
97 | | - "~S is not ~S~%" ',(car arg) ',(cadr arg))) |
98 | | - (values))) |
99 | | - args) |
100 | | - ,@body) |
101 | | - ) ;let |
102 | | - ) ;if |
103 | | - ) ;define-macro |
| 116 | + (define-syntax let1 |
| 117 | + (syntax-rules () |
| 118 | + ((_ name1 value1 body ...) |
| 119 | + (let ((name1 value1)) |
| 120 | + body ...)))) |
| 121 | + |
| 122 | + (define-syntax typed-lambda |
| 123 | + (lambda (stx) |
| 124 | + (define (split-args args) |
| 125 | + (let loop ((args args)) |
| 126 | + (syntax-case args () |
| 127 | + ;; 结束条件 |
| 128 | + (() (values '() '())) |
| 129 | + |
| 130 | + ;; 带有类型的变量: ((var type) . rest) |
| 131 | + (((var type) . rest) |
| 132 | + (let-values (((clean-rest checks-rest) (loop (syntax rest)))) |
| 133 | + (values (cons (syntax var) clean-rest) |
| 134 | + (cons #'(unless (type var) |
| 135 | + (error 'type-error "~S is not ~S" 'var 'type)) |
| 136 | + checks-rest)))) |
| 137 | + |
| 138 | + ;; 普通变量或 rest 变量: (var . rest) 或只是 var |
| 139 | + ((var . rest) |
| 140 | + (let-values (((clean-rest checks-rest) (loop (syntax rest)))) |
| 141 | + (values (cons (syntax var) clean-rest) checks-rest))) |
| 142 | + |
| 143 | + ;; 点号后面的最后一个标识符 (例如 rest) |
| 144 | + (var |
| 145 | + (if (identifier? (syntax var)) |
| 146 | + (values (syntax var) '()) |
| 147 | + (raise-syntax-error #f "Invalid argument specification" stx (syntax var))))))) |
| 148 | + |
| 149 | + (syntax-case stx () |
| 150 | + ((_ args body1 body2 ...) |
| 151 | + (let-values (((clean-args checks) (split-args (syntax args)))) |
| 152 | + (with-syntax ((clean-args clean-args) |
| 153 | + ((check ...) checks) |
| 154 | + ((body ...) #'(body1 body2 ...))) |
| 155 | + #'(lambda clean-args |
| 156 | + check ... |
| 157 | + body ...))))))) |
104 | 158 |
|
105 | | - ) ;begin |
106 | | -) ;define-library |
| 159 | + ) ; end of begin |
| 160 | +) ; end of define-library |
0 commit comments