Hello Good People<br><br>I have the task to make the translator from metalanguage A to the metalanguage B.<br>My app should open file "a.ss", parse and translate to the file "b.ss".<br>At the translation time the app should:<br>
<br>1) Expand all macro definitions of the file "a.ss" and evaluate all definitions witch are just a<br>scheme.<br>2) Generate the s-record structure witch represent the content of "b.ss"<br>3) In case if the "a.ss" have a syntax errors - printout error message with the line number <br>
at the file "a.ss" and the expression where happen the error.<br><br>For example:<br>File: <a.ss> ---------------------------------------------------------------------<br><br>(define-syntax foo <br> ;; This is macro definition in the 'a' file<br>
)<br><br>(define (bar ...) <br> ;; This is a function definition of the 'a' file<br>)<br><br>;; meta language expression<br>(define-fsm <br> :name "trigger"<br> (define-state <br> :name "zero"<br>
(on-event "switch"<br> (foo ...) ;; use macro definition<br> (go "one")))<br> (define-state<br> :name "one" ;;; N.B. the scheme expression can be used anywhere there can be (string-append "on" "e") <br>
(on-event "switch"<br>
(foo ...) ;; call the function <br> (go "one")))))<br><br>Eof File <a.ss> ---------------------------------------------------------------------<br><br>In case if was used not valid keyword "define-fsmZ" the error message should be:<br>
<br>a.ss:L:C: unknown symbol "define-fsmM" in: (define-fsmZ :name "trigger" (define-state ....<br><br>Where L and C are line and column numbers.<br><br>The easiest way to do this task can be: Just evaluate the file "a.ss" in the name space <br>
where are defined methods "define-fsm", "define-state", "on-event" and "go"<br><br>But this case each of those methods will not have the syntax object of the evaluated expression.<br>
And in case if it will find and error it could not message about error's location. <br><br>Alternative way is to use syntax-case instead methods for the "define-fsm", "define-state", "on-event" <br>
and "go" definitions. The body of macro will have the syntax object for an expression. <br><br>(define-syntax (define-fsm stx)<br> (syntax-case stx ()<br> [(_ params ...) <br> (let ([name (get-name stx)]) ;;; the method 'get-name' will return extracted name from the syntax<br>
#'('fsm name))])) ;;; this is expression of language B<br><br>This code will not work because macro expansion could not have access to variable 'name'<br>And I do not know how resolve this issue.<br>
<br>Another alternative is: to use the patterns like a:<br><br>(define-syntax (define-fsm stx)<br> (syntax-case stx (:name)<br> [(_ :name name
params ...) <br> #'('fsm name)]))<br><br>But in case if there are will be bunch of parameters in random order:<br><br>:name ... :param1 ... :param2 ... etc<br>or <br>:param2 ... :name ... :param1 ... etc<br>
<br>As result the body of the macro can be awkward.<br><br>I spent already allot of time to make this task. And I have several variants of translator. None of them is good.<br>I am not a good scheme programmer and have no any friend who can help. That is why I address my question <br>
to the Racket community:<br><br> "What is the best way to make this task with scheme?"<br><br clear="all">-- Valeriya<br>