(module translate-class-utils mzscheme (require (lib "list.ss" "srfi" "1") (only (lib "list.ss") quicksort) (lib "plt-match.ss") "../../ast.ss" "../../readerr.ss" "../../tenv.ss" "../../utils.ss" "../typechecker/type-utils.ss" "translate-expression.ss" "translate-utils.ss") (define-struct comp:export (stx type binds) #f) (define-struct comp:exp-bind (old new method?) #f) (provide translate-class-exports translate-subclass-exports) (define (translate-class-exports exports) (let ([exports (filter-exports (generate-exports exports))]) (map (lambda (e) (translate-export #f e)) exports))) (define (translate-subclass-exports super-types exports) (let ([exports (filter-exports (generate-exports exports))]) (map (lambda (e) (if (ormap (lambda (t) (<:_P t (comp:export-type e))) super-types) (translate-export #t e) (translate-export #f e))) exports))) (define (generate-super-exports type-entry comp-binds) (let loop ([super-types (tenv:type-supers type-entry)] [super-comp-exps '()]) (if (null? super-types) super-comp-exps (let ([super-entry (get-type-entry (car super-types))]) (let loop2 ([super-members (append (tenv:type-members super-entry) (tenv:type-inherited super-entry))] [super-comp-binds '()]) (if (null? super-members) (loop (cdr super-types) (cons (make-comp:export #f (car super-types) super-comp-binds) (append (generate-super-exports super-entry comp-binds) super-comp-exps))) (let ([matched (find (lambda (eb) (tenv-key=? (tenv:member-name (car super-members)) (comp:exp-bind-new eb))) comp-binds)]) (loop2 (cdr super-members) (cons matched super-comp-binds))))))))) (define (generate-exports exports) (let loop ([exports exports] [comp-exps '()]) (if (null? exports) comp-exps (let* ([export (car exports)] [type-entry (get-type-entry (honu:export-type export))]) (let loop2 ([exp-binds (honu:export-binds export)] [members (append (tenv:type-members type-entry) (tenv:type-inherited type-entry))] [comp-binds '()]) (if (null? exp-binds) (let ([super-exports (generate-super-exports type-entry comp-binds)]) (loop (cdr exports) (cons (make-comp:export (honu:ast-stx export) (honu:export-type export) comp-binds) (append super-exports comp-exps)))) (let-values ([(matched non-matches) (partition-first (lambda (m) (tenv-key=? (honu:exp-bind-new (car exp-binds)) (tenv:member-name m))) members)]) (loop2 (cdr exp-binds) non-matches (cons (make-comp:exp-bind (honu:exp-bind-old (car exp-binds)) (honu:exp-bind-new (car exp-binds)) (honu:type-disp? (tenv:member-type matched))) comp-binds))))))))) (define (sort-binds export) (quicksort (comp:export-binds export) (lambda (b1 b2) (tenv-keysymbol (string-append "init-" (symbol->string (syntax-e name)))))) (define (translate-member member) (match member [(struct honu:init-field (stx name type value)) (if value (at stx`(begin (init ([,(mangle-init-name name) ,(at-ctxt name)] ,(translate-expression value))) (define ,(at-ctxt name) ,(mangle-init-name)))) (at stx `(begin (init ([,(mangle-init-name name) ,(at-ctxt name)])) (define ,(at-ctxt name) ,(mangle-init-name name)))))] [(struct honu:field (stx name type value)) (at stx `(define ,(at-ctxt name) ,(translate-expression value)))] [(struct honu:method (stx name type formals body)) (translate-function stx name formals (translate-expression body))])) )