|
86 | 86 | [(approx impl spec) (approx (loop impl) (loop spec))] |
87 | 87 | [(list op args ...) (cons op (map loop args))]))) |
88 | 88 |
|
| 89 | +(define (fpcore-extension-spec expr) |
| 90 | + (define specs |
| 91 | + (remove-duplicates (filter identity |
| 92 | + (for/list ([impl (in-list (platform-impls (*active-platform*)))]) |
| 93 | + (define-values (_ body) (impl->fpcore impl)) |
| 94 | + (define subst (pattern-match (expand-expr body) expr)) |
| 95 | + (and subst (pattern-substitute (impl-info impl 'spec) subst)))))) |
| 96 | + (match specs |
| 97 | + ['() #f] |
| 98 | + [(list spec) spec] |
| 99 | + [_ (error 'fpcore->spec "ambiguous platform specs for `~a`: ~a" expr specs)])) |
| 100 | + |
89 | 101 | ;; Expression pre-processing for normalizing expressions. |
90 | 102 | ;; Used for conversion from FPCore to other IRs. |
91 | 103 | (define (expand-expr expr) |
|
156 | 168 | ; applications |
157 | 169 | [`(,op ,args ...) `(,op ,@(map (curryr loop env) args))] |
158 | 170 | ; constants |
159 | | - [(? operator-exists? op) (list expr)] |
| 171 | + [(? operator-exists? op) (list op)] |
160 | 172 | ; variables |
161 | 173 | [(? symbol?) (dict-ref env expr expr)] |
162 | 174 | ; other |
|
176 | 188 | [(? symbol?) expr] |
177 | 189 | [(list '! _ ... body) (loop body)] |
178 | 190 | [(list 'cast arg) (loop arg)] |
179 | | - [(list op args ...) `(,op ,@(map loop args))]))) |
| 191 | + [(list op args ...) |
| 192 | + (define args* (map loop args)) |
| 193 | + (define expr* `(,op ,@args*)) |
| 194 | + (match (fpcore-extension-spec expr*) |
| 195 | + [#f expr*] |
| 196 | + [(== expr*) expr*] |
| 197 | + [spec (loop spec)])]))) |
180 | 198 |
|
181 | 199 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
182 | 200 | ;; FPCore -> LImpl |
|
195 | 213 | (define ireprs (map (lambda (arg) (repr-of arg ctx)) args)) |
196 | 214 | (define impl (assert-fpcore-impl op prop-dict ireprs)) |
197 | 215 | (define vars (impl-info impl 'vars)) |
198 | | - (define pattern |
199 | | - (match (impl-info impl 'fpcore) |
200 | | - [(list '! _ ... body) body] |
201 | | - [body body])) |
202 | | - (define subst (pattern-match pattern (cons op args))) |
| 216 | + (define-values (_ body) (impl->fpcore impl)) |
| 217 | + (define subst (pattern-match body (cons op args))) |
203 | 218 | (pattern-substitute (cons impl vars) subst)) |
204 | 219 |
|
205 | 220 | ;; Translates from FPCore to an LImpl. |
|
235 | 250 | (define idx-repr (repr-of idx* ctx)) |
236 | 251 | (define impl (assert-fpcore-impl 'ref prop-dict (list arr-repr idx-repr))) |
237 | 252 | (define vars (impl-info impl 'vars)) |
238 | | - (define pattern |
239 | | - (match (impl-info impl 'fpcore) |
240 | | - [(list '! _ ... body) body] |
241 | | - [body body])) |
242 | | - (define subst (pattern-match pattern (list 'ref arr* idx*))) |
| 253 | + (define-values (_ body) (impl->fpcore impl)) |
| 254 | + (define subst (pattern-match body (list 'ref arr* idx*))) |
243 | 255 | (pattern-substitute (cons impl vars) subst)] |
244 | 256 | [(list op args ...) |
245 | 257 | (define args* (map (lambda (arg) (loop arg prop-dict)) args)) |
|
0 commit comments