Re: clines-from-file - The argument to CLINES, LINE, is not a string
- From: Pascal Bourguignon <spam@xxxxxxxxxxxxxxxx>
- Date: Sun, 30 Oct 2005 23:44:36 +0100
xbunny <xbunny@xxxxxxxxxxxxxx> writes:
> There is a great macro in ECL called Clines which allows me to paste C
> code into the ECL C output file and then other parts of ECL allow me
> to access and call that code once its compiled. What Im trying to do
> is write a function which allows me to read a file and puts its
> contents into Clines rather than having the C embedded as strings in
> the Lisp source. However I am a clueless newbie :-( I have the
> following function :
>
> (defun clines-from-file (filename)
> (with-open-file (stream filename :direction :input)
> (loop for line = (read-line stream nil stream)
> until (eql line stream) do
> (Clines line))))
>
> which I would think does what I want, however it generates an error
> when I load the file. ECL says:
>
> The argument to CLINES, LINE, is not a string.
>
> which is confusing because it 'looks' like a string if I change
> (Clines line) to (print line).
>
> Can anyone help? I have a feeling that clines-from-file needs to be a
> macro like Clines but Im still learning macros.
The problem is that clines is not a function. It's a macro. It
doesn't evaluate its arguments, and therefore expects a string literal
at macro-expansion time (compilation time), not a variable bound at
run-time to a string value.
You could somewhat code calling eval:
(eval `(clines ,line))
but this would be meaningless if you called clines-form-file at run-time.
You'll have to ensure that it's called at macroexpansion time:
(eval-when (:compile-toplevel)
(defun clines-from-file ...
... (eval `(clines ,line)) ...))
....
(eval-when (:compile-toplevel)
(clines-from-file "some-file.c"))
Perhaps a cleaner way to do this would be to define clines-from-file
as macro itself:
(defmacro clines-from-file (filename)
"Reads the filename at macroexpansion time, and generates a clines
with the contents of the file."
`(clines ,@(with-open-file (stream filename :direction :input)
(loop :for line = (read-line stream nil nil)
:while line :collect line))))
Note that the with-open-file is executed at macroexpansion time, for
the comma. If clines doesn't put each string on a different line,
you'll have to append a newline to each line:
... :collect (format nil "~A~%" line)
--
__Pascal Bourguignon__ http://www.informatimago.com/
Grace personified,
I leap into the window.
I meant to do that.
.
- References:
- Prev by Date: Re: Bug hunting/lexical confusion
- Next by Date: Re: newbie question on making executables in Lisp.
- Previous by thread: clines-from-file - The argument to CLINES, LINE, is not a string
- Next by thread: Re: clines-from-file - The argument to CLINES, LINE, is not a string
- Index(es):
Relevant Pages
|