I am using Racket to write a Domain specific language, I have learned it from beautifulracket.com. When I try to finish my DSL's expander, I want to use macros to transform my DSL into racket code. More specifically, I want to use a macro to implement function call. Here's my code
(define-macro (r-eval PARAM ... (r-id ID))
#'((eval (read (open-input-string ID))) PARAM ...))
(provide r-eval)
but when I try to run it, there are some errors:
This chinese DSL code
一 二之【+】
is equivalent to (r-eval 1 2 (r-id "+"))
,which is equivalent to ((eval (read (open-input-string "+"))) 1 2)
, and I use macro stepper to confirm that the macro expand correctly,
but I got an error,+: unbound identifier; also, no #%top syntax transformer is bound in: +
I have (provide +)
yet in my expander.rkt, I don't know what does the error means and why does it happens.Here's my expander.rkt's all code:
#lang br/quicklang
(define-macro (r-begin (r-program EXPR ...))
#'(#%module-begin
EXPR ...
;(display 123)
;(define expr-list
; (list EXPR ...))
;(display expr-list)
;(void (run expr-list))
))
(provide (rename-out [r-begin #%module-begin]))
(define-macro (r-expr PARAM ...)
#' (PARAM ...))
(provide r-expr)
(define-macro (r-eval PARAM ... (r-id ID))
#'((eval (read (open-input-string ID))) PARAM ...))
(provide r-eval)
(define (run expr-list) 2)
(provide run)
(define (p x y) (+ x y))
(provide p)
(provide +)
(provide eval)
(provide read)
(provide open-input-string)
You should give eval
the second argument, the environment that should containt the definition for +
. That's what the error message means - that +
has no definition.
There's a built-in name for the initial environment that you can use there. Look in the documentation for the specifics.