reddit / emacs

how to create an argument list out of a list given to a macro

rese2020 · 2022-01-30 10:38
i have a macro definition like this: `(defmacro test-macro (name args)` `\`(progn` `(defun ,(intern (format "my-test-function%s" name) (,(intern (string-join args " "))))` i want the args given to the macro to be the list of the argument of the function im creating
Illiamen · 2022-01-30 15:24
Something like this would work: (defmacro test (name args) `(defun ,name ,args (+ ,@args)) (test adder (a b c)) Macro arguments are treated literally, so you can just pass in a list of symbols (no quoting). Depending on your needs, you could also use `&rest` if you can't pass the symbols as a list. (defmacro test (name &rest args) `(defun ,name ,args (+ ,@args)) (test adder a b c) See also the manual if you haven't already: https://www.gnu.org/software/emacs/manual/html_node/elisp/Macros.html Does this answer your question?
rese2020 · 2022-01-30 19:25
thanks for your time, that worked well, could you provide a code for an interactive list for the function as well: for example i want to prompt for all the argument list i tried this but wont work: (interactive ,(intern (format "(list (read-string (\"%s: \" )) (read-string (\"%s: \" )))" (nth 0 args) (nth 1 args))))
Illiamen · 2022-02-01 23:31
`intern` is used to get a symbol named by the string. You can't use it to produce a list, just symbols. In the previous example, you are already passing symbols to the macro when you use the macro. See here: https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html As you know, you pass `interactive` a list of expressions that will return a value for each argument in `args`. Therefore, you can iterate over the elements in `args` to produce the code that you wrap with `(list ...)`. Both `cl-loop` and `mapcar` work well for this. (cl-loop for sym in args collect `(read-string ,(format "%s: " sym))) or (mapcar (lambda (sym) `(read-string ,(format "%s: " sym))) args) These produce a list of function calls to `read-string` that can you can splice into the code your macro produces using `,@`. See here: https://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote.html You can see the output of macros using `pp-macroexpand-last-sexp`. It can be used by placing the cursor after the `(test adder a b c)` in the previous example.