[racket] Metaprogramming with scheme

From: Valeriya Pudova (valery at digitalchile.net)
Date: Sat Jun 19 05:00:27 EDT 2010

Hello Good People

I have the task to make the translator from metalanguage A to the
metalanguage B.
My app should open file "a.ss", parse and translate to the file "b.ss".
At the translation time the app should:

1) Expand all macro definitions of the file "a.ss" and evaluate all
definitions witch are just a
scheme.
2) Generate the s-record structure witch represent the content of "b.ss"
3) In case if the "a.ss" have a syntax errors - printout error message with
the line number
at the file "a.ss" and the expression where  happen the error.

For example:
File: <a.ss>
---------------------------------------------------------------------

(define-syntax foo
   ;; This is macro definition in the 'a' file
)

(define (bar ...)
   ;; This is a function definition of the 'a' file
)

;; meta language expression
(define-fsm
   :name "trigger"
   (define-state
      :name "zero"
       (on-event "switch"
          (foo ...)   ;; use macro definition
          (go "one")))
   (define-state
      :name "one" ;;; N.B. the scheme expression can be used anywhere there
can be (string-append "on" "e")
       (on-event "switch"
          (foo ...)   ;; call the function
          (go "one")))))

Eof File <a.ss>
---------------------------------------------------------------------

In case if was used not valid keyword "define-fsmZ" the error message should
be:

a.ss:L:C: unknown symbol "define-fsmM" in:   (define-fsmZ :name "trigger"
(define-state ....

Where L and C are line and column numbers.

The easiest way to do this task can be: Just evaluate the file "a.ss" in the
name space
where are defined methods "define-fsm", "define-state", "on-event" and "go"

But this case each of those methods will not have the syntax object of the
evaluated expression.
And in case if it will find and error it could not message about error's
location.

Alternative way is to use syntax-case instead methods for the "define-fsm",
"define-state", "on-event"
and "go" definitions. The body of macro will have the syntax object for an
expression.

(define-syntax (define-fsm stx)
  (syntax-case stx ()
    [(_ params ...)
       (let ([name (get-name stx)])  ;;; the method 'get-name' will return
extracted name from the syntax
         #'('fsm name))]))  ;;; this is expression of language B

This code will not work because macro expansion could not have access to
variable 'name'
And I do not know how resolve this issue.

Another alternative is: to use the patterns like a:

(define-syntax (define-fsm stx)
  (syntax-case stx (:name)
    [(_ :name name  params ...)
       #'('fsm name)]))

But in case if there are will be bunch of parameters in random order:

:name ... :param1 ... :param2 ... etc
or
:param2 ... :name ... :param1 ... etc

As result the body of the macro can be awkward.

I spent already allot of time to make this task. And I have several variants
of translator. None of them is good.
I am not a good scheme programmer and have no any friend who can help. That
is why I address my question
to the Racket community:

   "What is the best way to make this task with scheme?"

-- Valeriya
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100619/49c99619/attachment.html>

Posted on the users mailing list.