local-expand supports the stop-list argument, so I think you can put all
core forms there.

#lang racket

(require syntax/parse/define)

(define-syntax (A-core stx)
  (syntax-parse stx #:literals (b-core)
    [(A-core (b-core x)) #'(printf "A-core got value ~a.~n" x)]))

(define-syntax (b-core stx) (raise-syntax-error #f "b-core out of context"))

(define-simple-macro (b-surface x) (b-core x))

(define-syntax (A-surface stx)
  (syntax-parse stx
    [(A-surface expr)
     #:with sub-stx (local-expand #'expr 'expression (list #'b-core))
     #`(A-core sub-stx)]))

(A-surface (b-surface "hello"))

Note that I switch define-syntax-rule to define-simple-macro because
define-syntax-rule will use syntax-protect, resulting in errors like cannot
use identifier tainted by macro transformation.

On Thu, Jul 23, 2020 at 10:00 AM Thomas Del Vecchio <
[email protected]> wrote:

> Hi all,
>
> I'm working on a family of languages in Racket, and I'm running into a
> conceptual issue with the information flow of the project. I have a
> standard core language whose syntax is s-expressions, with some macros in
> the expander. Then, there is a surface language (compiled into
> s-expressions with brag) which directly translates into the core language.
> There will also be other surface languages in the future, forming a
> tower/tree of languages that compile into simpler ones, so I want to make
> sure I get this pattern right.
>
> Conceptually, I would want the surface language to fully "compile" into
> the core language before the core language tries to do anything. As I
> develop the surface language, I don't think I should have to concern myself
> with the inner workings of the core language; I should be able to just
> produce core language code, and then have the core language handle it from
> there. I find myself running into an issue, however, where the core
> language starts to do computations before the translation is
> fully complete. This is an issue because the macros of the core language
> are taking in the syntax of the surface language which hasn't been
> translated yet, and so the core language doesn't recognize this syntax and
> breaks.
>
> As a small example, consider the following:
> core-language-expander.rkt
> (define-syntax (A-core stx)
>   (syntax-parse stx #:datum-literals (b-core)
>     [(A-core (b-core x)) #'(printf "A-core got value ~a.~n" x)]))
>
> surface-language-expander.rkt
> (define-syntax-rule (b-surface x) (b-core x))
> (define-syntax (A-surface stx)
>   (syntax-parse stx
>     [(A-surface expr) #'(A-core expr)]))
>
> Here, if we call `(A-surface (b-surface "hello"))`, we would want it to
> take the `A-surface`, and convert it into `A-core`, and then expand 
> `(b-surface
> "hello")`. Since `A-core` is implemented as a macro, though, it takes 
> `(b-surface
> "hello")` unexpanded, and so tries to evaluate `(A-core (b-surface
> "hello"))`, which fails.
>
> Since `b-core` isn't defined as a function/macro in the core language (it
> is just a piece of syntax used in `A-core`), we can't just evaluate 
> `(b-surface
> "hello")` as a value before passing it in. If we try using `local-expand`
> or something similar to handle the expansion as syntax, there isn't an
> obvious way to make it only expand macros defined in the surface language
> expander (and not those defined in the core language expander), which turns
> out to be an issue in my case.
>
> Do any of you recommend a resource for understanding the strategy of
> taking a stack of languages and compiling down one layer at a time? It
> seems like the notion of a tower of languages would be fairly natural, yet
> the only success I have had is with some hacks with recursive local-expand
> that feel extremely unnatural, and also require further hacks to get around
> things like syntax-tainting.
>
> Thanks so much!
> Thomas Del Vecchio
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/26f44e6d-f1f8-465e-9639-6cd6afeffa31n%40googlegroups.com
> <https://groups.google.com/d/msgid/racket-users/26f44e6d-f1f8-465e-9639-6cd6afeffa31n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CADcuegvACr%2Bs%3DHwGbmhtPqyYOC8UahK47Rf22wJkdJ6X5Yabiw%40mail.gmail.com.

Reply via email to