|
107 | 107 | (define fl-proc* |
108 | 108 | (match fl-proc |
109 | 109 | [(? generator?) ((generator-gen fl-proc) spec ctx)] |
110 | | - [(? procedure?) fl-proc] |
111 | | - [#f (error 'define-operation "fl-proc is not provided for `~a` implementation" name)])) |
| 110 | + [(? procedure?) fl-proc])) |
112 | 111 | (unless (procedure-arity-includes? fl-proc* (length (context-vars ctx)) #t) |
113 | 112 | (error 'define-operation |
114 | 113 | "Procedure `~a` accepts ~a arguments, but ~a is provided" |
|
121 | 120 | (match cost |
122 | 121 | [(? number?) (values cost +)] |
123 | 122 | [(? procedure?) (values 0 cost)] |
124 | | - [#f (error 'define-operation "Missing cost for ~a" name)] |
125 | 123 | [_ (error 'define-operation "Invalid cost for ~a: ~a" name cost)])) |
126 | 124 |
|
127 | 125 | (define/contract (create-operator-impl! name |
128 | 126 | ctx |
129 | | - spec |
130 | | - #:impl [fl-proc #f] |
131 | | - #:fpcore [fpcore #f] |
132 | | - #:cost [cost #f]) |
133 | | - (->* (symbol? context? any/c) |
134 | | - (#:impl (or/c procedure? generator? #f) #:fpcore any/c #:cost (or/c #f real? procedure?)) |
135 | | - operator-impl?) |
| 127 | + #:spec spec |
| 128 | + #:impl fl-proc |
| 129 | + #:fpcore fpcore |
| 130 | + #:cost cost) |
| 131 | + (-> symbol? |
| 132 | + context? |
| 133 | + #:spec any/c |
| 134 | + #:impl (or/c procedure? generator?) |
| 135 | + #:fpcore any/c |
| 136 | + #:cost (or/c real? procedure?) |
| 137 | + operator-impl?) |
136 | 138 | (check-spec! name ctx spec) |
137 | | - (check-fpcore! name (or fpcore spec)) |
| 139 | + (check-fpcore! name fpcore) |
138 | 140 | (define fl-proc* (check-fl-proc! name ctx fl-proc spec)) |
139 | 141 | (define-values (cost* aggregate*) (check-cost! name cost)) |
140 | | - (operator-impl name ctx spec (fpcore-parameterize (or fpcore spec)) fl-proc* cost* aggregate*)) |
| 142 | + (operator-impl name ctx spec (fpcore-parameterize fpcore) fl-proc* cost* aggregate*)) |
141 | 143 |
|
142 | 144 | ;; Generic keyword parser for syntax (at compile-time) |
143 | 145 | (begin-for-syntax |
144 | | - (define (parse-keyword-fields stx fields-stx allowed-keywords) |
145 | | - (define macro-name (syntax-e (car (syntax-e stx)))) |
| 146 | + (define (parse-keyword-fields stx fields-stx allowed-keywords op-name) |
146 | 147 | (define (oops! why [sub-stx #f]) |
147 | | - (raise-syntax-error macro-name why stx sub-stx)) |
| 148 | + (raise-syntax-error op-name why stx sub-stx)) |
148 | 149 |
|
149 | 150 | (define result-hash (make-hasheq)) |
150 | 151 |
|
|
170 | 171 | (raise-syntax-error 'make-operator-impl why stx sub-stx)) |
171 | 172 | (syntax-case stx (:) |
172 | 173 | [(_ (id [var : repr] ...) rtype . fields) |
173 | | - (let ([id #'id] |
| 174 | + (let ([op-name #'id] |
174 | 175 | [vars (syntax->list #'(var ...))]) |
175 | | - (unless (identifier? id) |
176 | | - (oops! "expected identifier" id)) |
| 176 | + (unless (identifier? op-name) |
| 177 | + (oops! "expected identifier" op-name)) |
177 | 178 | (for ([var (in-list vars)] |
178 | 179 | #:unless (identifier? var)) |
179 | 180 | (oops! "expected identifier" var)) |
180 | 181 |
|
181 | | - (define keywords (parse-keyword-fields stx #'fields '(spec fpcore impl cost))) |
| 182 | + (define keywords (parse-keyword-fields stx #'fields '(spec fpcore impl cost) op-name)) |
182 | 183 |
|
183 | 184 | (unless (hash-has-key? keywords 'spec) |
184 | | - (oops! "missing `#:spec` keyword")) |
| 185 | + (raise-syntax-error op-name "missing `#:spec` keyword" stx)) |
| 186 | + (unless (hash-has-key? keywords 'impl) |
| 187 | + (raise-syntax-error op-name "missing `#:impl` keyword" stx)) |
| 188 | + (unless (hash-has-key? keywords 'cost) |
| 189 | + (raise-syntax-error op-name "missing `#:cost` keyword" stx)) |
185 | 190 |
|
186 | 191 | ;; Build argument list for create-operator-impl! |
187 | 192 | ;; Quote spec and fpcore, leave impl and cost unquoted |
188 | | - (with-syntax ([name (datum->syntax stx (syntax->datum id))] |
189 | | - [spec-val (hash-ref keywords 'spec)] |
190 | | - [fpcore-val (hash-ref keywords 'fpcore #f)] |
191 | | - [impl-val (hash-ref keywords 'impl #f)] |
192 | | - [cost-val (hash-ref keywords 'cost #f)]) |
193 | | - #'(create-operator-impl! 'name |
| 193 | + ;; Default fpcore to spec if not provided |
| 194 | + (with-syntax ([spec-val (hash-ref keywords 'spec)] |
| 195 | + [fpcore-val (hash-ref keywords 'fpcore (hash-ref keywords 'spec))] |
| 196 | + [impl-val (hash-ref keywords 'impl)] |
| 197 | + [cost-val (hash-ref keywords 'cost)]) |
| 198 | + #'(create-operator-impl! 'id |
194 | 199 | (context '(var ...) rtype (list repr ...)) |
195 | | - 'spec-val |
| 200 | + #:spec 'spec-val |
196 | 201 | #:impl impl-val |
197 | 202 | #:fpcore 'fpcore-val |
198 | 203 | #:cost cost-val)))] |
|
0 commit comments