Sorry, I think I need to elaborate a bit more!

I've written code as follows

(define-syntax-class my-id
  (pattern id
    #:do (if (identifier? #'id) (values) 
             (raise-user-error (~a "Expected id: " (syntax->datum #'id))))))

(define-syntax (my-let stx)
  (syntax-parse stx
    [(_ ([id:my-id binding] ...) body ... last-body)
     #'(let ([id binding] ...) body ... last-body)]))

(define-syntax (reassign stx)
  (syntax-parse stx
    [(_ id:my-id new-value)
      #'(set! id new-value)]))

... other syntax rules using my-id as a syntax class

I enjoy using syntax classes to check that my arguments are id's, but what I 
don't enjoy is how limited my error message is. (I don't want to use Rackets. 
The end users for this are students using very simple self-defined languages, 
and the error messages should be very intuitive, so my-id
is just id but with my own error.)

What I'd like to do is format my errors more like
"let: Expected an identifier to bind but got 3"
"reassign: Expected an identifier to reassign but got 3."

The way I planned to do this was to pass arguments into my syntax class. In the 
racket documentation, it states this is possible. The forms of 
define-syntax-class are as follows.

(define-syntax-class name-id stxclass-option ...
  stxclass-variant ...+)
(define-syntax-class (name-id . kw-formals) stxclass-option ...
  stxclass-variant ...+)

I'm hoping to use the second form to write something like the following

(define-syntax-class (my-id name description)
  (pattern id
    #:do (if (identifier? #'id) (values) 
             (raise-syntax-error name 
                 (~a " expected " description but got (syntax->datum #'id))))))

This way I could write my let as

(define-syntax (my-let stx)
  (syntax-parse stx
    [(_ ([id:(my-id 'let "an identifier to bind") binding] ...) body ... 
last-body)
     #'(let ([id binding] ...) body ... last-body)]))

(or to make this look cleaner, I could have a line of code before this that 
says (define let-id (my-id 'let "an identifier to bind")) I don't think that 
would exactly work, but I'm sure it's doable in some way)

The only thing I'm having problems with is that apparently that isn't the right 
way to use the formals. When I try writing it the original way but with the 
updated my-id version, I get 

id:my-id: expected 1 positional argument; got 0 positional arguments in: 
id:my-id

and when I write it with the parentheses like I did in the last example I get 

my-let: expected more terms at: () within: (my-let ([x 2]) 1) in: (my-let ([x 
2]) 1)

On Monday, July 24, 2017 at 1:19:06 PM UTC-4, Alex Knauth wrote:
> On Jul 24, 2017, at 1:06 PM, Sam Waxman <samw...@gmail.com> wrote:
> 
> 
> Probably a silly question but I can't figure out how to get this working.
> 
> I want to have a syntax class that I can pass arguments into. So,
> 
> (define-syntax-class (my-syn-class argument)
>   ...
> )
> 
> (syntax-parse #'some-syntax
>   [(_ x:*????*)])
> 
> 
> In place of *????* what do I write to pass the argument into my syntax class?
> I tried 
> 
> (syntax-parse #'some-syntax
>   [(_ x:(my-id *my-argument*)])
> 
> but this doesn't appear to work.
> 
> Thanks in advance!
> 
> 
> You have to use either ~var [1] or #:declare [2].
> 
> 
>   [1]: 
> http://docs.racket-lang.org/syntax/stxparse-patterns.html#%28elem._%28pattern-link._%28~7evar._s%2B%29%29%29
>   [2]: 
> http://docs.racket-lang.org/syntax/stxparse-specifying.html#%28part._.Pattern_.Directives%29

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to