>From the following piece of code it should be evident what I am trying
to do.
(defmacro macro1 (param)
`(let ((,(intern "var1") 777))
,param))
(macro1 var1)
I tried also
(defmacro macro1 (param)
`(let ((,(make-symbol "var1") 777))
,param))
(macro1 var1)
Is it possible at all?
Thanks in advance.
Anton V. Belyaev wrote:
> >From the following piece of code it should be evident what I am trying
> to do.
>
> (defmacro macro1 (param)
> `(let ((,(intern "var1") 777))
> ,param))
> (macro1 var1)
>
> I tried also
>
> (defmacro macro1 (param)
> `(let ((,(make-symbol "var1") 777))
> ,param))
> (macro1 var1)
>
> Is it possible at all?
> Thanks in advance.
Do you expect (macro1 var1) to return 777?
It looks like you're trying to do this:
(defmacro macro1 (param)
`(let ((var1 777))
,param))
"Anton V. Belyaev" <·············@gmail.com> writes:
>>From the following piece of code it should be evident what I am trying
> to do.
>
> (defmacro macro1 (param)
> `(let ((,(intern "var1") 777))
> ,param))
> (macro1 var1)
>
> Is it possible at all?
> Thanks in advance.
You might want to explain your overall goal, as what you want to do is not
terribly common, but in the spirit of enough rope...
The problem with (intern "var1") is that the reader ordinarily upcases
everything it sees, but you're short circuiting that behavior. So what
your (macro1 var1) actually expands to is
CL-USER> (macroexpand-1 '(macro1 var1))
(LET ((|var1| 777))
VAR1)
but VAR1 and |var1| are different symbols (technically the pipes aren't
part of the symbol name, but we're close enough). You can solve your
problem by uppercasing the string before you call intern.
(defmacro macro3 (param)
`(let ((,(intern (string-upcase "var1")) 777))
,param))
But I still don't know what you actually hope to accomplish. My version
macroexpands as follows.
CL-USER> (macroexpand-1 '(macro3 var1))
(LET ((VAR1 777))
VAR1)
which is all well, but only works for argument "var1"
CL-USER> (macroexpand-1 '(macro3 var2))
(LET ((VAR1 777))
VAR2)
and of course, VAR2 is unbound. Which leads me to believe you might have
intended something like
(defmacro macro4 (param)
`(let ((,param 777))
,param))
which at least works for any argument. If you explain your problem,
someone here will almost certainly provide you with better advice than you
can get from the likes of me. :)
--
Deon Garrett
Department of Computer Science
Institute for Intelligent Systems
The University of Memphis
·····@acm.org
Thank Deon!
My problem explanation was fuzzy, but you guessed in one of you
solutions
what was really needed :)
This is what I needed:
(defmacro macro3 (param)
`(let ((,(intern (string-upcase "var1")) 777))
,param))
"Anton V. Belyaev" <·············@gmail.com> writes:
>>From the following piece of code it should be evident what I am trying
> to do.
>
> (defmacro macro1 (param)
> `(let ((,(intern "var1") 777))
> ,param))
> (macro1 var1)
[2]> (macroexpand '(macro1 var1))
(LET ((|var1| 777)) VAR1) ;
T
> I tried also
>
> (defmacro macro1 (param)
> `(let ((,(make-symbol "var1") 777))
> ,param))
> (macro1 var1)
>
> Is it possible at all?
Yes.
Read about READTABLE-CASE in CLHS.
A generic solution could be (it really depends on what you want):
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun string-invert (string &key (start 0) (end nil))
(map 'string (lambda (ch)
(cond ((char= (char-upcase ch) ch) (char-downcase ch))
((char= (char-downcase ch) ch) (char-upcase ch))
(t ch))) (subseq string start end))))
[12]> (defmacro macro1 (param)
`(let ((,(intern
(funcall
(ecase (readtable-case *readtable*)
(:upcase (function string-upcase))
(:downcase (function string-downcase))
(:invert (function string-invert))
(:preserve (function identity)))
"var1")) 777))
,param))
MACRO1
[13]> (macroexpand '(macro1 var1))
(LET ((VAR1 777)) VAR1) ;
T
[14]> (|SETF| (|READTABLE-CASE| |*READTABLE*|) :|DOWNCASE|)
:|DOWNCASE|
[15]> (|MACROEXPAND| '(|MACRO1| VAR1))
(|LET| ((VAR1 777)) VAR1) ;
|T|
[16]> (|SETF| (|READTABLE-CASE| |*READTABLE*|) :|INVERT|)
:invert
[17]> (|MACROEXPAND| '(|MACRO1| var1))
(let ((var1 777)) var1) ;
t
[18]> (|SETF| (|READTABLE-CASE| |*READTABLE*|) :|PRESERVE|)
:PRESERVE
[19]> (|MACROEXPAND| '(|MACRO1| var1))
(LET ((var1 777)) var1) ;
T
[20]>
This is for interactive use, but on the other hand, when you use the
macro in the sources of a program, the symbol given to the macro will
be read by the same readtable as the macro itself, so it may be better
to write:
(defmacro macro1 (param)
`(let ((,(intern
#.(funcall
(ecase (readtable-case *readtable*)
(:upcase (function string-upcase))
(:downcase (function string-downcase))
(:invert (function string-invert))
(:preserve (function identity)))
"var1")) 777))
,param))
Or you could just consider that your sources will use the :UPCASE
(which is the default) readtable-case, and just write:
(defmacro macro1 (param)
`(let ((,(intern (string-upcase "var1")) 777))
,param))
Or just:
(defmacro macro1 (param)
`(let ((,(intern (string-upcase "VAR1")) 777))
,param))
But then of course, people who like to use a :modern or :invert
readtable-case will have difficulty using it. You can't make
everybody happy all the time.
--
__Pascal Bourguignon__ http://www.informatimago.com/
HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.