Hello,

I am writing a Racket library which will make it possible to control the
Neovim text editor using Racket. People will be able to use Racket to
control Neovim, as well as write plugins for Neovim in Racket.
https://gitlab.com/HiPhish/neovim.rkt

So far it looks good, but I am stuck on macros. There is a hash table
which serves as a specification for which functions to generate, it is
stored in the file 'nvim/api/specification.rkt'. This table has the key
"functions" which contains a vector of more hash tables.

I need this information to generate function definitions for users to be
able to call Neovim procedures from Racket. So instead of writing
something like

  (api-call "nvim_command" '#("echo 'hello world'"))

users should be able to write

  (require nvim/api)
  (command "echo 'hello world'")

For this I need to loop over the functions vector like this:

  (define functions (hash-ref api-info "functions"))
  (for ([function (in-vector functions)])
    (define name   (hash-ref function       "name"))
    (defien params (hash-ref function "parameters"))
    `(define (,(string->symbol name) ,@params)
       (api-call ,name (vector ,@params))))

Reality is a bit more complicated because the parameters are not a list
but a vector of vectors, but that's besides the point. The question is:
how do I do this? A regular for-loop at runtime will not work, and
wrapping this in begin-for-syntax doesn't produce actual module-level
definitions.

I tried doing it with a macro:

  (define-syntax (api->func-def stx)
    (syntax-case stx ()
      [(_ api-name api-params)
       (with-syntax ([name
                       (datum->syntax stx
                         (string->symbol
                           (function-name (eval (syntax->datum #'api-name)))))]
                     [arg-list
                       (datum->syntax stx
                         (vector->list
                           (vector-map string->symbol (eval (syntax->datum 
#'api-params)))))])
         #`(define (name #,@#'arg-list)
             (api-call api-name (vector #,@#'arg-list))))]))

This *seems* to generate the proper definition, although I'm not really
sure. But how can I write the loop now so that it covers all function
definitions? I don't need to re-use the macro, I only need it once, so
if there was an easier solution like my for-loop above that does it in
place it would be even better.

-- 
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