[racket] Define several procedures in a macro

From: Alexander D. Knauth (alexander at knauth.org)
Date: Wed Jan 21 18:18:55 EST 2015

And the syntax-case way if you’re interested:
(define-syntax define-instruction
  (lambda (stx)
    (syntax-case stx (sim)
      [(_ (name . args) (sim body-r ...))
       (with-syntax ([simulator-name (format-id #'name "~a-simulation" #'name)])
         #'(define (simulator-name . args)
             body-r ...))])))


On Jan 21, 2015, at 6:12 PM, Alexander D. Knauth <alexander at knauth.org> wrote:

> You’d be surprised at how much I had tried to do stuff like that before I had heard about syntax-case, syntax-parse, etc. (and read fear of macros)
> 
> Here’s how I would do that (this could also be done with syntax-case)
> 
> #lang racket
> 
> (require (for-syntax racket/base
>                     syntax/parse
>                     racket/syntax))
> 
> (define-syntax define-instruction
>  (syntax-parser #:datum-literals (sim)
>    [(_ (name . args) (sim body-r ...))
>     #:with simulator-name (format-id #'name "~a-simulation" #'name)
>     #'(define (simulator-name . args)
>         body-r ...)]))
> 
> (define-instruction (hello a b c)
> (sim
>  (+ a b c)))
> 
> (hello-simulation 1 2 3)
> ;; > 6
> 
> On Jan 21, 2015, at 4:21 PM, Peter Samarin <petrsamarin at gmail.com> wrote:
> 
>> Hi all,
>> 
>> I have yet another macro that uses eval!
>> And it is obvious from the previous discussion that it can be done without.
>> 
>> By the way, thanks for your answers, they were all very helpful!
>> (I think by mistake, I sent my thanks to Eli only and not to the whole mailing list).
>> 
>> The macro is used to define three procedures with provided name and fixed suffixes: "-simulation" "-mc" (for microcontroller) and "-vhdl".
>> It assembles three symbols that combine the provided name with the suffixes, then constructs procedure bodies in a list and finally uses eval-define combination to define the three procedures.
>> I suspect that instead of symbols I should construct identifiers and then they can be defined without eval, but have not been able to figure out a way to do that.
>> 
>> Here is the construction of the simulator procedure:
>> 
>> (define-syntax define-instruction
>> (syntax-rules (sim)
>>   [(_ (name . args) (sim body-r ...))
>>    (begin
>>      (define name-string (symbol->string 'name))
>>      (define simulator-name
>>        (string->symbol
>>         (string-append
>>          name-string "-simulation")))
>>      (eval `(define (,simulator-name . args)
>>               body-r ...)))]))
>> 
>> (define-instruction (hello a b c)
>> (sim
>>  (+ a b c)))
>> 
>> (hello simulation 1 2 3)
>> ;; > 6
>> 
>> Peter
>> 
>> 
>> ;;; Some context for the interested
>> The macro is used in a larger system for writing custom processors with custom instructions (appication specific instruction processors (ASIPs)).
>> And the purpose for the macro is to define three procedures that represent processor instructions that can be used either to simulate instructions in a Racket REPL, to embed the instruction in a custom processor in VHDL, and to convert the actual sequence of instructions into machine code that can be executed on that processor in hardware.
>> The last two will be eventually combined
>> 
>> As an alternative, I am also working on an interpreter-like version that uses no macros.
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
> 
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



Posted on the users mailing list.