Tarun Maganti
Tarun Maganti

Reputation: 3076

Cannot work out how to run .scm (using guile or scm) files

I have created a abc.scm file and tried to compile it to a binary (or whatever guile scheme compiles to) using "guild compile", "scm" and "guile" commands in terminal in Ubuntu.

For "guild compile abc.scm", I get the output "wrote `/home/tarunmaganti/.cache/guile/ccache/2.0-LE-8-2.0/home/tarunmaganti/abc.scm.go'" I find the file and run like this - "./abc.scm.go" which says permission denied.
When I give the necessary permissions using "chmod 755" or "chmod 777", I get an error like - "bash: ./abc.scm.go: cannot execute binary file: Exec format error".

The "scm whatever-file-name.scm" just opens up the scm interpreter.

The "guile whatever-file-name.scm does nothing.

The link of official GNU/Guile Scheme isn't very helpful.

Please, help me. I would like to create a guile scheme script file. Compile it and run it as C/C++ program. Is it possible? If compilation isn't possible, I would like to know, how to at least run the script file of GNU/guile scheme or MIT-Scheme.

{Step-by-step is highly appreciated, I'm still a beginner in using Ubuntu and also in Scheme.}

Thanks in advance.

Upvotes: 6

Views: 3665

Answers (3)

Lassi
Lassi

Reputation: 3940

Apparently guile foo assumes that foo is a Scheme source file. If foo is a precompiled binary .go file it tries to treat it as a text file anyway and compile it a second time, which fails. I could not find any equivalent command line syntax for executing a pre-compiled .go file.

However, you can get almost the same effect as follows:

  • Write a source file foo.scm that exports a main procedure:
(define-module (foo)
  #:export (main))

(define (main)
  (display "Hello world!")
  (newline))
  • Pre-compile it with guild compile -o foo.go foo.scm
  • Write a shell script that runs guile -C "$PWD" -c "(use-modules (foo)) (main)". The -C dir flag (capital C) tells it to load pre-compiled files from the directory dir. The -c expr flag (lowercase c) tells it to evaluate the Scheme code expr which in this case just does use-module to load the pre-compiled module and then calls our main procedure.

Upvotes: 3

Jeff Spaulding
Jeff Spaulding

Reputation: 223

Guile's compiler is like Java's compiler: it produces bytecode that is then run in Guile's VM. I don't know of any way to go straight from Guile Scheme code to native code. Guile is really meant to be an extension language that allows you to add Scheme scripting to your C/C++ program.

I don't know much about MIT Scheme, but from what I can tell it also does not compile to a standalone executable. Feel free to correct me on that.

There's a way around all this, though. As long as you don't mind a dependency on libguile, you can write a wrapper in C/C++ and hand libguile a string containing your Scheme code. There's a basic example given in the Guile manual for Dia here. Create your script in a header file and wrap it in a null-terminated C string, then (after a bit of boilerplate and whatnot) evaluate it with scm_eval_string().

If you want to write Scheme and output native binaries, I've heard good things about Chicken.

Upvotes: 2

C. K. Young
C. K. Young

Reputation: 222973

You can use the shebang notation to create a Guile script (the -s is optional in newer versions of Guile):

#!/usr/bin/guile -s
!#
(display "Hello, world!\n")

Notice the !# on the second line. Guile treats the #! as the start of a block comment (similar to what #| is in standard Scheme), which has to be terminated using !# (similar to |# in standard Scheme).

If you want your script to pass any command-line options to Guile itself, then read about the meta switch. Here's an example of such:

#!/usr/bin/guile \
-e main -s
!#
(define (main args)
  (if (null? (cdr args))
      (format #t "Hello, world!~%")
      (for-each (lambda (name)
                  (format #t "Hello, ~a!~%" name))
                (cdr args))))

Upvotes: 5

Related Questions