2

Intention:

I am trying to generate macros using the macro form:

(make-type "int32" 32)

which would produce:

(defmacro make-int32t (name)
  `(quote (:type 'int32t :bit-length 32 :name ,name)))

This generated macro produces something like:

(make-int32t "myvar")

(:TYPE 'INT32T :BIT-LENGTH 32 :NAME "myvar")

Problem:

I am struggling with how to make the macro produce the leading backquote and the commas.

Here is what I have:

(defmacro make-type (type-name bit-length)
  (let*
      ((make-name  (concatenate 'string "make-" type-name))
       (mac-name (intern make-name)))
       `(defmacro ,mac-name (name)
     '(quote (:type ,type-name :bit-length ,bit-length :name "substitued")))))
 ; "substituted" ideally is something like ,name

If I macroexpand I get:

 (macroexpand-1 '(make-type "int32" 32))

(DEFMACRO |make-int32| (NAME)
  ''(:TYPE "int32" :BIT-LENGTH 32 :NAME "substitued"))

If I try to use the macro, I get:

(make-type "int44" 44)
; in: MAKE-TYPE "int44"
;     (SB-INT:NAMED-DS-BIND (:MACRO |make-int44| . DEFMACRO)
;         (NAME)
;         (CDR #:EXPR)
;       (BLOCK |make-int44| ''(:TYPE "int44" :BIT-LENGTH 44 :NAME "substitued")))
; --> SB-INT:BINDING* 
; ==>
;   (LET* ((#:G0 (SB-C::CHECK-DS-LIST (CDR #:EXPR) 1 1 '(# NAME)))
;          (NAME (POP #:G0)))
;     (BLOCK |make-int44| ''(:TYPE "int44" :BIT-LENGTH 44 :NAME "substitued")))
; 
; caught STYLE-WARNING:
;   The variable NAME is defined but never used.
; 
; compilation unit finished
;   caught 1 STYLE-WARNING condition
WARNING: redefining COMMON-LISP-USER::|make-int44| in DEFMACRO

|make-int44|

But if I try to use the macro, it is not defined.

(make-int44 "myvar")
The function COMMON-LISP-USER::MAKE-INT44 is undefined.

Questions

1) How to replace the "substituted" by ,name

2) How to properly do this?

EDIT: I had a typo: MARCO --> Macro, so I changed the question accordingly

9
  • 2
    what is DEFMARCO ? Seems not to be a Common Lisp operator. Commented Mar 27, 2018 at 21:18
  • 1
    This might be helpful: stackoverflow.com/questions/17429521/… Commented Mar 27, 2018 at 21:42
  • 1
    I don't have time to answer now, but google "common lisp double backquote" and "common lisp nested backquote" Commented Mar 27, 2018 at 21:45
  • 1
    A little hint, the macro should probably include something that looks like ','name in place of "substituted" Commented Mar 27, 2018 at 21:48
  • 1
    Alternatively, rather than thinking in terms of backquotes and splicing, how would you construct the form that you need? After after all, ``(defmacro ,mac-name (name) ,@body)` is equivalent (enough) to (list* 'defmacro mac-name (list 'name) body). If you construct the forms that way, you can probably get a working version sooner, and then can try to turn it into a backquote based implementation (if that's still important). Commented Mar 27, 2018 at 21:59

1 Answer 1

2

Thank you all for your input. To close this, I will post an answer to the question based on your comments:

(defmacro make-type (type-name bit-length)
  (let* ((make-name (concatenate 'string "DEFINE-" (string-upcase type-name)))
         (mac-name  (intern make-name)))
      `(defmacro ,mac-name (name)
         `(quote (:type       ,,type-name
                  :bit-length ,,bit-length
                  :name       ,name)))))

It can be used as:

* (define-type "int16" 16)

DEFINE-INT16
* (DEFINE-int16 "myvar")

(:TYPE "int16" :BIT-LENGTH 16 :NAME "myvar")
Sign up to request clarification or add additional context in comments.

2 Comments

style: I would not use MAKE- in MAKE-TYPE. Use something like DEF- or DEFINE- . MAKE- usually would be a function which makes something. What you have is a macro, which defines something.
@Rainer, what would we do without you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.