> On Dec 26, 2023, at 3:07 PM, Al <frm...@mailgw.com> wrote:
> 
> Hi, suppose I need to reference data from "file.txt" in my Scheme program. I 
> could use read-char / read / open-input-file etc (or other (chicken io) 
> procedures) to read the the contents of the file into a variable.
> 
> However, such deserialization happens at run-time. If I compile my program 
> into an executable, it will try to open "file.txt" at run-time. How can I 
> arrange for "file.txt" to be read at compile-time, and inlined into the 
> executable, so that the executable doesn't require access to the original 
> file?
> 
> The only way I can think of is to convert "file.txt" to a scheme string 
> definition in a separate file:
> 
> ; file.scm
> (define file-contents " ... ")
> 
> and include it via (include "file.scm"). Then the definition would occur at 
> compile-time.
> 
> But of course this requires encoding (possibly binary) files as scheme 
> strings, and probably an extra Makefile step to convert file.txt into 
> file.scm. This is not attractive -- are there other options?
> 
> 

Hello. This is something that can be achieved through macros. The execution of 
the body of the macro definition is something that happens at compilation time, 
so it is as simple as reading the content of the file at that moment and 
transforming it into a constant:

$ cat embed-file.scm
;;;------------------------ file: embed-file.scm

(import (chicken syntax))

(define-syntax embed-file-as-constant
   (er-macro-transformer
    (lambda (x r c)
      (import (chicken io))
      (with-input-from-file (cadr x) (lambda () (read-string #f))))))

;;; sample use of embed-file-as-constant:

(define file-contents (embed-file-as-constant "file.txt"))

(display "file contents:\n")
(display file-contents)
$ cat file.txt
first line
second line
last line
$ csc embed-file.scm
$ ./embed-file
file contents:
first line
second line
last line

Marc



Reply via email to