From: xbunny
Subject: clines-from-file - The argument to CLINES, LINE, is not a string
Date: 
Message-ID: <4y69f.37358$iD.35316@fe2.news.blueyonder.co.uk>
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.

Best regards, Bunny

From: Pascal Bourguignon
Subject: Re: clines-from-file - The argument to CLINES, LINE, is not a string
Date: 
Message-ID: <87d5lmr5ez.fsf@thalassa.informatimago.com>
xbunny <······@eidosnet.co.uk> 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.
From: xbunny
Subject: Re: clines-from-file - The argument to CLINES, LINE, is not a string
Date: 
Message-ID: <M5t9f.105537$Ih5.65492@fe1.news.blueyonder.co.uk>
Pascal Bourguignon wrote:
> (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) 
>   

Hey thats great, needed the second bit but it works fine, thank you very 
much. Bunny
From: Johan Bockgård
Subject: Re: clines-from-file - The argument to CLINES, LINE, is not a string
Date: 
Message-ID: <yoijhdaybepk.fsf@linus003.dd.chalmers.se>
xbunny <······@eidosnet.co.uk> 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 :

Too complicated. Try

    (clines "#include \"some-file.c\"")

-- 
Johan Bockgård
From: xbunny
Subject: Re: clines-from-file - The argument to CLINES, LINE, is not a string
Date: 
Message-ID: <w6t9f.105538$Ih5.8177@fe1.news.blueyonder.co.uk>
Johan Bockgård wrote:

> xbunny <······@eidosnet.co.uk> 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 :
> 
> 
> Too complicated. Try
> 
>     (clines "#include \"some-file.c\"")
> 

thats just cheating ;-) slapping myself for not thinking of it. Bunny