[racket] Define several procedures in a macro
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