[plt-scheme] defining a lisp dialect via mzscheme extensions that provides define-macro

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Wed Feb 6 13:20:12 EST 2008

I've implemented most of a certain Lisp dialect as a DrScheme/MrEd 
Language by extensive use of MzScheme "define-syntax", custom "#%app", 
and reader tweaks.

The only thing I'm stuck on is how to get the language's "defmacro" to 
work using "defmacro.ss", given MzScheme's respect for phase separation.

The toy code below illustrates my current approach.

Any thoughts on how to get the body of "toy-macro" to be in language 
"toylang"?

;;-----------------------------------------------------------------------------

(module toylang-except-macro mzscheme
 
  (define (toy-write x) (display "toy-write says ") (write x) (newline))
 
  (provide #%module-begin #%app #%datum #%top
           toy-write
           (rename begin      toy-begin)
           (rename list       toy-list)
           (rename quote      toy-quote)
           (rename quasiquote toy-quasiquote)
           (rename unquote    toy-unquote)))

(module toylang mzscheme
 
  (require toylang-except-macro
           (lib "defmacro.ss"))
 
  (define-syntax toy-macro
    ;; Note: Everything here inside "define-syntax" is in the transformer
    ;; environment, so it's MzScheme language, even were the language of 
this
    ;; "toylang" module "toylang-except-macro" rather than "mzscheme".
    (syntax-rules ()
      ((_ N A B ...) (define-macro N (lambda A B ...)))))
 
  (provide toy-macro
           (all-from toylang-except-macro)
           (rename require-for-syntax %require-for-syntax)))

(module myprog toylang
 
  (%require-for-syntax toylang-except-macro)

  ;; GOOD: This definition of "foo" has the "toylang-except-macro" bindings,
  ;; as desired.
  (toy-macro foo (str)
             (toy-list (toy-quote toy-begin)
                       (toy-list (toy-quote toy-write)
                                 str)))
  (foo "yeah!")

  ;; BAD: This definition of "bar" is letting me use Scheme syntax, which is
  ;; not what I want.  That also suggests that the body of "bar" 
wouldn't obey
  ;; "mzscheme" bindings such as "if" that I might want to override in
  ;; "toylang".
  (toy-macro bar (str)
             (begin (display "scheme says ")
                    (write str)
                    (newline)))
  (bar "shucks"))

(require myprog)

;; OUTPUT:
;; | scheme says "shucks"
;; | toy-write says "yeah!"

;;-----------------------------------------------------------------------------



Posted on the users mailing list.