Skip to content

Instantly share code, notes, and snippets.

@lexi-lambda
Created September 21, 2018 19:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lexi-lambda/65d69043023b519694f50dfca2dc7d33 to your computer and use it in GitHub Desktop.
Save lexi-lambda/65d69043023b519694f50dfca2dc7d33 to your computer and use it in GitHub Desktop.
#lang racket
(require (for-syntax racket/function
syntax/apply-transformer)
syntax/parse/define)
(define-syntax ($expand stx)
(raise-syntax-error #f "illegal outside an ‘expand-inside’ form" stx))
(begin-for-syntax
(define-syntax-class do-expand-inside
#:literals [$expand]
#:attributes [expansion]
[pattern {~or $expand ($expand . _)}
#:with :do-expand-inside (do-$expand this-syntax)]
[pattern (a:do-expand-inside . b:do-expand-inside)
#:attr expansion (datum->syntax (if (syntax? this-syntax) this-syntax #f)
(cons (attribute a.expansion) (attribute b.expansion))
(if (syntax? this-syntax) this-syntax #f)
(if (syntax? this-syntax) this-syntax #f))]
[pattern _ #:attr expansion this-syntax])
(define (do-$expand stx)
(syntax-parse stx
[(_ {~and form {~or trans (trans . _)}})
#:declare trans (static (disjoin procedure? set!-transformer?) "syntax transformer")
(local-apply-transformer (attribute trans.value) #'form 'expression)])))
(define-syntax-parser expand-inside
#:track-literals
[(_ form:do-expand-inside) #'form.expansion])
;; ---------------------------------------------------------------------------------------------------
(define-simple-macro (symbol-binding-pairs x:id ...)
([x 'x] ...))
(define-simple-macro (expand-expression e:expr)
#:with result (local-expand #'e 'expression '())
#:do [(println #'result)]
result)
(expand-expression
(expand-inside
(let ($expand (symbol-binding-pairs a b c))
(list a b c))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment