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