#lang scheme

(define-for-syntax cert-key (gensym 'local-expand))

;; recertifiable-transform :
;;   (syntax? -> syntax?) syntax? -> syntax? (syntax? -> syntax?)
;; Returns the transformed syntax and a procedure to recertify any further
;; transforms
(define-for-syntax (recertifiable-transform transform stx)
  (let ([certifier  (syntax-local-certifier)]
        [introducer  (make-syntax-introducer)])
    (define (certify s) (certifier s cert-key introducer))
    (let ([new-stx (certify (introducer (transform (introducer stx))))]
          [inspector (current-code-inspector)])
      (define (recertify s) (syntax-recertify s new-stx inspector cert-key))
      (values new-stx recertify))))

;; Wrapper for local-expand that returns a syntax object and a recertifier
(define-for-syntax (recertifiable-local-expand stx context-v stop-ids)
  (recertifiable-transform 
   (lambda (s) (local-expand s context-v stop-ids)) stx))

(define-for-syntax (reverse-syntax-list stx)
  (with-syntax ([(e ...)  (reverse (syntax->list stx))])
    (syntax/loc stx (e ...))))

(define-syntax (expandify stx)
  (syntax-case stx ()
    [(_ e)  (let-values ([(stx recertify)  (recertifiable-local-expand
                                            #'e (syntax-local-context) #f)])
              (recertify
               (syntax-case stx ()
                 [(e ...)  (with-syntax ([inner  (reverse-syntax-list
                                                  (reverse-syntax-list #'(e ...)))])
                             (syntax/loc stx (list inner)))]
                 [_  stx])))]))

(define y 20)
(define-syntax-rule (get-two-ys) (list y y))

(provide expandify get-two-ys)
