[Openmcl-devel] Using ccl as a #! scripting language

John McAleely john at mcaleely.com
Sun Oct 26 05:07:06 PDT 2008


Hi,

I've been learning lisp recently, and I've wanted to use it for  
'casual' scripting in order to become more familiar with it.

As such, I wanted to find a way to use it on my mac as a scripting  
language from the terminal in #! scripts.

The script below is my attempt at making this practical, that I've  
used on 10.5 with a recent version (just before 1.2) of ccl

Presented here in the hope others find it useful.

John

---/usr/local/bin/ccl-script---
#!/bin/bash
# ccl-script
#
# Placed in the public domain by the author John McAleely <john at mcaleely.com 
 >
#
# A front end for ccl to be used to create #! executable text scripts on
# unix like operating systems.
# Start your text script with:
# #!/usr/bin/env /path/to/ccl-script *command-line*
#
# *command-line* is defined in the script as a list of the
#                command line arguments used to invoke the script
# #! causes the remainder of the line to be ignored.
#
# eg
#
##!/usr/bin/env /path/to/ccl-script *command-line*
#(format t "Hello World called as: ~a" (pop *command-line*))
#(quit)
#
##!/usr/bin/env /path/to/ccl-script *command-line*
#(loop for line = (read-line *standard-input* nil nil)
#  while line do (format t "~a~%" line))
#(quit)

# edit this to be your ccl start script of choice (ccl64, openmcl,  
etc...)
CCL=ccl

# stash away the name for the global variable that will hold the  
command line
VAR=$1

# Store the name of the script we will load later
SCRIPT=$2

# get rid of the script's paramaters
shift 2

# now prepare the command line typed by the user as the
# lisp global *command-line*. This will follow the unix convention
# of starting with the calling script name.
CMDLINE="(progn
            (defvar $VAR nil)
            (push \"$SCRIPT\" $VAR)"

# loop over the remaining command line parameters, pushing
# each onto *command-line*. Done this way to preserve spaces,
# etc in names, and save lisp users the trouble of doing
# parsing work the shell has already done.
while (($#)); do
   CMDLINE="$CMDLINE
            (push \"$1\" $VAR)"
   shift
done

# finally order the list in the least surprising way
CMDLINE="$CMDLINE
            (setf $VAR (reverse $VAR)))"

# pass a little bit of read-macro magic in first,
# so that the line #!/usr... in your script is ignored.
# declares #! as a read macro that ignores the remainder of the line.
$CCL \
  -e "(set-dispatch-macro-character #\\# #\\!
       #'(lambda (s c1 c2)
           (declare (ignore c1 c2))
           (read-line s t nil t)))" \
  -e "$CMDLINE" \
  -l "$SCRIPT"
--eof--



More information about the Openmcl-devel mailing list