Hello:
Is it possible to convert string to a macro?
for example :
(with-open-file (s "test-lisp" :direction :output :if-exists
:supersede)
(format s "Here are a couple~%of test data lines~%"))
as
((intern "with-open-file") (s "test-lisp" :direction :output :if-exists
:supersede)
(format s "Here are a couple~%of test data lines~%")))
Thanks...
·············@gmail.com" <············@gmail.com> writes:
> Hello:
>
> Is it possible to convert string to a macro?
> for example :
>
> (with-open-file (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%"))
>
> as
>
> ((intern "with-open-file") (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%")))
You are probably looking mostly for READ and EVAL.
·············@gmail.com" <············@gmail.com> writes:
> Hello:
>
> Is it possible to convert string to a macro?
> for example :
>
> (with-open-file (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%"))
>
> as
>
> ((intern "with-open-file") (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%")))
>
> Thanks...
(let ((macro-name "WITH-OPEN-FILE"))
;; There is no macro named "with-open-file" in CL!
(eval `(,(intern macro-name)
(s "test-lisp" :direction :output :if-exists:supersede)
(format s "Here are a couple~%of test data lines~%"))))
--
__Pascal Bourguignon__ http://www.informatimago.com/
This universe shipped by weight, not volume. Some expansion may have
occurred during shipment.
············@gmail.com wrote:
> Hello:
>
> Is it possible to convert string to a macro?
> for example :
>
> (with-open-file (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%"))
>
> as
>
> ((intern "with-open-file") (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%")))
>
If i do understand what you mean ... like this ?
(defmacro x2 (v)
`(list ',v ',v))
; > (x2 a) => (A A)
(defmacro x3 (v)
`(list ',v ',v ',v))
; > (x3 a) => (A A A)
;; Calling the macros with their string-name 'str'
(defmacro call-mac (str v)
`(,(read-from-string str) ,v))
; > (call-mac "x2" a) => (A A)
; > (call-mac "x3" a) => (A A A)
; > (macroexpand-1 '(call-mac "x2" a)) => (X2 A)
; > (macroexpand '(call-mac "x2" a)) => (LIST 'A 'A)
············@gmail.com wrote:
> Hello:
>
> Is it possible to convert string to a macro?
> for example :
>
> (with-open-file (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%"))
>
> as
>
> ((intern "with-open-file") (s "test-lisp" :direction :output :if-exists
> :supersede)
> (format s "Here are a couple~%of test data lines~%")))
I think the only meaningful answer here is... why on earth do you want
to do this?
It's not a rethorical question: if you tell us what your problem is,
we'll be able to show you the *real* solution.
Alberto
My purpose is to practice writing a macro.
I would like to write the macro mentioned in the form previously. That
is:
To make multiple with-xxx into a single with macro
(with (("file-open" ...) ("file-open" ...) )
...
)
·············@gmail.com" <············@gmail.com> writes:
> My purpose is to practice writing a macro.
>
> I would like to write the macro mentioned in the form previously. That
> is:
>
> To make multiple with-xxx into a single with macro
>
> (with (("file-open" ...) ("file-open" ...) )
> ...
> )
You don't need strings here...
(defmacro with (clauses &body body)
(if (null clauses)
`(locally ,@body) ; locally instead of progn to allow declarations
`(,(intern (format nil ···@(WITH-~A~)" (caar clauses))) ,@(cdar clauses)
(with ,(cdr clauses) ,@body))))
Note the recursive macro! Unfortunately, macroexpand only expands the
outer macro. If you want to see how everything expands, you can
either use an implementation specific device, such as #+clisp
ext:expand-form, but it will expand also the other macros, not only
the one you wrote, or you can macroexpand the internal macro call yourself:
(defmacro with (clauses &body body)
(if (null clauses)
`(locally ,@body) ; locally instead of progn to allow declarations
`(,(intern (format nil ···@(WITH-~A~)" (caar clauses))) ,@(cdar clauses)
,(macroexpand (list* 'with (cdr clauses) body)))))
(macroexpand '(with ((output-to-string (so))
(open-file (o "out"))
(open-stream (i (run-program "ls")))
(slots (name salary) owner))
(format so "~S" (do-something i o name salary))))
-->
(LET ((SO (MAKE-STRING-OUTPUT-STREAM :ELEMENT-TYPE 'CHARACTER)))
(DECLARE (SYSTEM::READ-ONLY SO))
(UNWIND-PROTECT
(PROGN
(LET ((O (OPEN "out"))) (DECLARE (SYSTEM::READ-ONLY O))
(UNWIND-PROTECT
(MULTIPLE-VALUE-PROG1
(PROGN
(LET ((I (RUN-PROGRAM "ls"))) (DECLARE (SYSTEM::READ-ONLY I))
(UNWIND-PROTECT
(MULTIPLE-VALUE-PROG1
(PROGN
(LET ((#1=#:G16442 OWNER))
(SYMBOL-MACROLET
((NAME (SLOT-VALUE #1# 'NAME)) (SALARY (SLOT-VALUE #1# 'SALARY)))
(LET NIL (FORMAT SO "~S" (DO-SOMETHING I O NAME SALARY))))))
(WHEN I (CLOSE I)))
(WHEN I (CLOSE I :ABORT T)))))
(WHEN O (CLOSE O)))
(WHEN O (CLOSE O :ABORT T))))
(GET-OUTPUT-STREAM-STRING SO))
(CLOSE SO))) ;
T
--
__Pascal Bourguignon__