Skip to content

Instantly share code, notes, and snippets.

@carl-eastlund
Created January 26, 2014 01:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carl-eastlund/8626893 to your computer and use it in GitHub Desktop.
Save carl-eastlund/8626893 to your computer and use it in GitHub Desktop.
Simple DSL expansion
#lang racket
(require (for-syntax racket syntax/parse racket/syntax syntax/id-table))
(begin-for-syntax
(define macro-table (make-free-id-table))
(define (expand-macro id stx)
(define transformer (syntax-local-value id))
(define mark (make-syntax-introducer))
(mark (transformer (mark stx))))
(define (recursive-expand stx)
(syntax-parse stx
[(macro:id . _)
#:when (dict-has-key? macro-table #'macro)
(recursive-expand (expand-macro #'macro stx))]
[(_ ...)
(define elems (map recursive-expand (syntax->list stx)))
(datum->syntax stx elems stx)]
[_ stx])))
(define-syntax (define-dsl-syntax stx)
(syntax-parse stx
[(_ (name:id . args) body:expr)
#'(begin
(define-syntax-rule (name . args) body)
(begin-for-syntax
(dict-set! macro-table (quote-syntax name) #t)))]))
(module+ test
(require rackunit)
(define-syntax (test stx)
(syntax-parse stx
[(_ e:expr)
(define/syntax-parse expanded
(recursive-expand #'e))
#'(quote expanded)]))
(define-dsl-syntax (pred? x) (> 3 x))
(check-equal?
(test (or (< 10 x) (pred? y)))
'(or (< 10 x) (> 3 y)))
(define-dsl-syntax (other? x) (or (= 2 x) (= 3 x)))
(check-equal?
(test (or (other? x) (other? y)))
'(or (or (= 2 x) (= 3 x))
(or (= 2 y) (= 3 y)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment