#lang racket
(require (for-syntax syntax/parse))
(require (for-syntax "indent.rkt"))
(require (for-syntax racket/list))
(provide make-fun-and-def)
(define-syntax (make-fun-and-def stx)
(syntax-parse stx
[(_ fun-name:id def-name:id fun-to-use:id def-to-use:id)
(syntax/loc stx
(begin
(define-syntax (def-name stx)
(syntax-parse stx
[(_ name:id expr:expr)
(syntax/loc stx
(def-to-use name expr))]))
(define-syntax (fun-name stx)
(syntax-parse stx
[(kw_ name:id (args:id (... ...)) body:expr ...+)
(let ([body-list (syntax->list (syntax (body (... ...))))]
[kw (syntax kw_)])
(for-each (lambda (stx) (check-indent 'SLGC kw stx))
body-list)
(let ([f (first body-list)]
[r (rest body-list)])
(for-each (lambda (stx) (check-indent 'SLSC f stx))
r))
(let ([num-body-exprs (length body-list)]
[l (reverse (rest (reverse body-list)))]
[def-ctx (syntax-local-make-definition-context)]
[expand-context (cons (gensym 'intdef)
(let ([orig-ctx (syntax-local-context)])
(if (pair? orig-ctx)
orig-ctx
'())))])
(let ([expanded
(map
(lambda (stx)
(local-expand stx
expand-context
(list (syntax fun-to-use) (syntax def-to-use))
def-ctx))
(reverse (rest (reverse body-list))))])
(internal-definition-context-seal def-ctx)
(with-syntax ([lst (last body-list)])
(quasisyntax/loc stx
(fun-to-use (name args (... ...))
(unsyntax-splicing expanded)
lst))))))]))))]))