#lang racket/base (provide definition-unparser Ref-unparser-name) (require preserves) (require racket/match) (require (only-in racket/syntax format-symbol)) (require (only-in racket/list append-map)) (require "type.rkt") (require "gen/schema.rkt") (define (definition-unparser name def) (define ty (definition-ty def)) `(define (,(format-symbol "~a->preserves" name) input) ,(match def [(Definition-or p0 p1 pN) `(match input ,@(for/list [(named-alt (in-list (list* p0 p1 pN))) (alt-ty (in-list (map cadr (ty-union-variants ty))))] (match-define (NamedAlternative variant-label-str pattern) named-alt) `[,(deconstruct (format-symbol "~a-~a" name variant-label-str) #t alt-ty) ,(pattern->unparser pattern 'src)]))] [(Definition-and p0 p1 pN) `(match input [,(deconstruct name #f ty) (merge-preserves (lambda (a b) (if (equal? a b) a (error 'merge-preserves "Cannot merge"))) ,@(append-map (lambda (named-pat) (match named-pat [(NamedPattern-anonymous (Pattern-SimplePattern _)) '()] [_ (list (pattern->unparser named-pat 'src))])) (list* p0 p1 pN)))])] [(Definition-Pattern pattern) `(match input [,(deconstruct name #f ty) ,(pattern->unparser pattern 'src)])]))) (define (deconstruct name wrap? ty) (match ty [(ty-record fields) `(,name ,@(map escape (map car fields)))] [(ty-unit) `(,name)] [_ (if wrap? `(,name src) 'src)])) (define (pattern->unparser pattern src-stx) (match (unwrap pattern) [(NamedSimplePattern_ n p) (pattern->unparser p (escape n))] [(SimplePattern-any) src-stx] [(SimplePattern-atom _) src-stx] [(SimplePattern-embedded) `(embedded (:embedded->preserves ,src-stx))] [(SimplePattern-lit v) `',v] [(SimplePattern-seqof variable-pat) `(for/list [(item (in-list ,src-stx))] ,(pattern->unparser variable-pat 'item))] [(SimplePattern-setof pat) `(for/set [(item (in-set ,src-stx))] ,(pattern->unparser pat 'item))] [(SimplePattern-dictof key-pat value-pat) `(for/hash [((key value) (in-dict ,src-stx))] (values ,(pattern->unparser key-pat 'key) ,(pattern->unparser value-pat 'value)))] [(SimplePattern-Ref r) `(,(Ref-unparser-name r) ,src-stx)] [(CompoundPattern-rec label-pat fields-pat) `(record ,(pattern->unparser label-pat src-stx) ,(pattern->unparser fields-pat src-stx))] [(CompoundPattern-tuple named-pats) `(list ,@(for/list [(p (in-list named-pats))] (pattern->unparser p src-stx)))] [(CompoundPattern-tuple* fixed-named-pats variable-named-pat) `(list* ,@(for/list [(p (in-list fixed-named-pats))] (pattern->unparser p src-stx)) ,(pattern->unparser variable-named-pat src-stx))] [(CompoundPattern-dict entries) `(hash ,@(append-map (lambda (entry) (list `',(car entry) (pattern->unparser (cdr entry) src-stx))) (sorted-dict-entries entries)))])) (define (Ref-unparser-name r) (match-define (Ref module-path name) r) (format-symbol "~a~a->preserves" (module-path-prefix module-path) name))