<div dir="ltr"><div class="gmail_extra" style>I've written three little examples, extracted from the macro you pointed us to. The first just reproduces the problem you're seeing, I expect. Note that if you reverse the "a ..." and the "x" line, you don't get an error anymore, but you do get strange output. This is because of the interaction between Redex's typesetting and macro transformations. Macros preserve the source locations of the input so, by the time Redex gets ahold of the program, the "a ..." part is gone and in its place is the "+ - *" but with the original source locations. That's why things seem to go "backwards" from Redex's perspective in the example you got and in the example as written below: it happens when it sees the "x" production and gets confused about why the "+ - *" seems to actually be later in the source file.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Okay, onto the second example below: here I just punt entirely. If you put the "+ - *" into its own non-terminal and then don't render that one, then you can use some other technique to render these (like in the running text or language extension or something). This idea doesn't generalize well, but if you can get by with it, then it is easiest.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>The third definition below shows how you can munge the source locations at compile time so as to achieve something with sane looking source locations by the time Redex gets it. Here it adjusts the "+ - *"'s source locations so they all appear on one line (important because "HERE" takes only one line but you can leave a blank line there if you plan to insert code that takes two lines, etc) and they have reasonable looking space between them.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Hope this helps.</div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>Robby</div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>
<div class="gmail_extra">#lang racket</div><div class="gmail_extra">(require redex/reduction-semantics</div><div class="gmail_extra"> redex/pict)</div><div class="gmail_extra">(define-syntax-rule </div><div class="gmail_extra">
(mk-L L a ...)</div><div class="gmail_extra"> (define-language L</div><div class="gmail_extra"> (e (λ (x) e)</div><div class="gmail_extra"> (e e)</div><div class="gmail_extra"> a ...</div><div class="gmail_extra">
x)</div><div class="gmail_extra"> (x variable-not-otherwise-mentioned)))</div><div class="gmail_extra"><br></div><div class="gmail_extra">(mk-L L + - *)</div><div class="gmail_extra">(with-handlers ((exn:fail? exn-message))</div>
<div class="gmail_extra"> (render-language L))</div><div class="gmail_extra"><br></div><div class="gmail_extra">(define-syntax-rule </div><div class="gmail_extra"> (mk-L2 L a ...)</div><div class="gmail_extra"> (define-language L</div>
<div class="gmail_extra"> (e (λ (x) e)</div><div class="gmail_extra"> (e e)</div><div class="gmail_extra"> prims</div><div class="gmail_extra"> x)</div><div class="gmail_extra"> (prims a ...)</div>
<div class="gmail_extra"> (x variable-not-otherwise-mentioned)))</div><div class="gmail_extra"><br></div><div class="gmail_extra">(mk-L2 L2 + - *)</div><div class="gmail_extra">(render-language L2 #:nts '(e x))</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">(define-syntax (mk-L3 stx)</div><div class="gmail_extra"> (syntax-case stx ()</div><div class="gmail_extra"> [(_ L a ...)</div><div class="gmail_extra"> (let ()</div>
<div class="gmail_extra"> (define template</div><div class="gmail_extra"> #'(define-language L</div><div class="gmail_extra"> (e (λ (x) e)</div><div class="gmail_extra"> (e e)</div>
<div class="gmail_extra"> HERE</div><div class="gmail_extra"> x)</div><div class="gmail_extra"> (x variable-not-otherwise-mentioned)))</div><div class="gmail_extra"> (car</div>
<div class="gmail_extra"> (let loop ([stx template])</div><div class="gmail_extra"> (syntax-case stx (HERE)</div><div class="gmail_extra"> [HERE </div><div class="gmail_extra"> (let loop ([as (syntax->list #'(a ...))]</div>
<div class="gmail_extra"> [pos (syntax-position stx)]</div><div class="gmail_extra"> [col (syntax-column stx)])</div><div class="gmail_extra"> (cond</div><div class="gmail_extra">
[(null? as) '()]</div><div class="gmail_extra"> [else </div><div class="gmail_extra"> (define a (car as))</div><div class="gmail_extra"> (define span (string-length (symbol->string (syntax-e a))))</div>
<div class="gmail_extra"> (cons</div><div class="gmail_extra"> (datum->syntax a </div><div class="gmail_extra"> (syntax-e a)</div><div class="gmail_extra">
(vector (syntax-source stx)</div><div class="gmail_extra"> (syntax-line stx)</div><div class="gmail_extra"> col</div>
<div class="gmail_extra"> pos</div><div class="gmail_extra"> span)</div><div class="gmail_extra"> a)</div>
<div class="gmail_extra"> (loop (cdr as)</div><div class="gmail_extra"> (+ pos span 1)</div><div class="gmail_extra"> (+ col span 1)))]))]</div><div class="gmail_extra">
[(a ...)</div><div class="gmail_extra"> (list</div><div class="gmail_extra"> (datum->syntax</div><div class="gmail_extra"> stx</div><div class="gmail_extra"> (apply append (map loop (syntax->list #'(a ...))))</div>
<div class="gmail_extra"> stx</div><div class="gmail_extra"> stx))]</div><div class="gmail_extra"> [a</div><div class="gmail_extra"> (list stx)]))))]))</div><div class="gmail_extra">
<br></div><div class="gmail_extra">(mk-L3 L3 + - *)</div><div class="gmail_extra">(render-language L3)</div></div></div>