|
64 | 64 | "syntax.rkt" |
65 | 65 | "types.rkt") |
66 | 66 |
|
67 | | -(provide fpcore->prog |
| 67 | +(provide fpcore->spec |
| 68 | + fpcore->prog |
68 | 69 | prog->fpcore) |
69 | 70 |
|
70 | 71 | ;; Local copies to avoid depending on core/programs.rkt. |
|
85 | 86 | [(approx impl spec) (approx (loop impl) (loop spec))] |
86 | 87 | [(list op args ...) (cons op (map loop args))]))) |
87 | 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 | + |
88 | 101 | ;; Expression pre-processing for normalizing expressions. |
89 | 102 | ;; Used for conversion from FPCore to other IRs. |
90 | 103 | (define (expand-expr expr) |
|
146 | 159 | ; applications |
147 | 160 | [`(,op ,args ...) `(,op ,@(map (curryr loop env) args))] |
148 | 161 | ; constants |
149 | | - [(? operator-exists? op) (list expr)] |
| 162 | + [(? operator-exists? op) (list op)] |
150 | 163 | ; variables |
151 | 164 | [(? symbol?) (dict-ref env expr expr)] |
152 | 165 | ; other |
153 | 166 | [_ expr]))) |
154 | 167 |
|
| 168 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 169 | +;; FPCore -> LSpec |
| 170 | + |
| 171 | +(define (fpcore->spec prog) |
| 172 | + (let loop ([expr (expand-expr prog)]) |
| 173 | + (match expr |
| 174 | + [(? number?) |
| 175 | + (match expr |
| 176 | + [(or +inf.0 -inf.0 +nan.0) expr] |
| 177 | + [(? exact?) expr] |
| 178 | + [_ (inexact->exact expr)])] |
| 179 | + [(? symbol?) expr] |
| 180 | + [(list '! _ ... body) (loop body)] |
| 181 | + [(list 'cast arg) (loop arg)] |
| 182 | + [(list op args ...) |
| 183 | + (define args* (map loop args)) |
| 184 | + (define expr* `(,op ,@args*)) |
| 185 | + (match (fpcore-extension-spec expr*) |
| 186 | + [#f expr*] |
| 187 | + [(== expr*) expr*] |
| 188 | + [spec (loop spec)])]))) |
| 189 | + |
155 | 190 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
156 | 191 | ;; FPCore -> LImpl |
157 | 192 |
|
|
169 | 204 | (define ireprs (map (lambda (arg) (repr-of arg ctx)) args)) |
170 | 205 | (define impl (assert-fpcore-impl op prop-dict ireprs)) |
171 | 206 | (define vars (impl-info impl 'vars)) |
172 | | - (define pattern |
173 | | - (match (impl-info impl 'fpcore) |
174 | | - [(list '! _ ... body) body] |
175 | | - [body body])) |
176 | | - (define subst (pattern-match pattern (cons op args))) |
| 207 | + (define-values (_ body) (impl->fpcore impl)) |
| 208 | + (define subst (pattern-match body (cons op args))) |
177 | 209 | (pattern-substitute (cons impl vars) subst)) |
178 | 210 |
|
179 | 211 | ;; Translates from FPCore to an LImpl. |
|
209 | 241 | (define idx-repr (repr-of idx* ctx)) |
210 | 242 | (define impl (assert-fpcore-impl 'ref prop-dict (list arr-repr idx-repr))) |
211 | 243 | (define vars (impl-info impl 'vars)) |
212 | | - (define pattern |
213 | | - (match (impl-info impl 'fpcore) |
214 | | - [(list '! _ ... body) body] |
215 | | - [body body])) |
216 | | - (define subst (pattern-match pattern (list 'ref arr* idx*))) |
| 244 | + (define-values (_ body) (impl->fpcore impl)) |
| 245 | + (define subst (pattern-match body (list 'ref arr* idx*))) |
217 | 246 | (pattern-substitute (cons impl vars) subst)] |
218 | 247 | [(list op args ...) |
219 | 248 | (define args* (map (lambda (arg) (loop arg prop-dict)) args)) |
|
0 commit comments