[racket] Define several procedures in a macro

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

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



Posted on the users mailing list.