The script interpreter

Author(s): Daniel Cabeza, Manuel Hermenegildo.

ciao-shell is the Ciao script interpreter. It can be used to write Prolog shell scripts (see [Her96,CHV96b]), that is, executable files containing source code, which are compiled on demand.

Writing Prolog scripts can sometimes be advantageous with respect to creating binary executables for small- to medium-sized programs that are modified often and perform relatively simple tasks. The advantage is that no explicit compilation is necessary, and thus changes and updates to the program imply only editing the source file. The disadvantage is that startup of the script (the first time after it is modified) is slower than for an application that has been compiled previously.

An area of application is, for example, writing CGI executables: the slow speed of the network connection in comparison with that of executing a program makes program execution speed less important and has made scripting languages very popular for writing these applications. Logic languages are, a priori, excellent candidates to be used as scripting languages. For example, the built-in grammars and databases can sometimes greatly simplify many typical script-based applications.

How it works

Essentially, ciao-shell is a smaller version of the Ciao top-level, which starts by loading the file given to it as the first argument and then starts execution at main/1 (the argument is instantiated to a list containing the command line options, in the usual way). Note that the Prolog script cannot have a module declaration for this to work. While loading the file, ciao-shell changes the prolog flag quiet so that no informational or warning messages are printed (error messages will be reported to user_error, however). The operation of ciao-shell in Unix-like systems is based in a special compiler feature: when the first character of a file is '#', the compiler skips the first lines until an empty line is found. In Windows, its use is as easy as naming the file with a .pls extension, which will launch ciao-shell appropriately.

For example, in a Linux/Unix system, assume a file called hello contains the following program:

#!/bin/sh 
exec ciao-shell $0 "$@" # -*- mode: ciao; -*-

main(_) :-
     write('Hello world'), nl.

Then, the file hello can be run by simply making it executable and invoking it from the command line:

/herme@clip:/tmp
[86]> chmod +x hello

/herme@clip:/tmp
[87]> hello
Hello world

The line:

#!/bin/sh 
invokes the /bin/sh shell which will interpret the following line:
exec ciao-shell $0 "$@" # -*- mode: ciao; -*-

and invoke ciao-shell, instructing it to read this same file ($0), passing it the rest of the arguments to hello as arguments to the prolog program. The second part of the line # -*- mode: ciao; -*- is simply a comment which is seen by emacs and instructs it to edit this file in Ciao mode (this is needed because these script files typically do not have a .pl ending). When ciao-shell starts, if it is the first time, it compiles the program (skipping the first lines, as explained above), or else at successive runs loads the .po object file, and then calls main/1.

Note that the process of creating Prolog scripts is made very simple by the Ciao emacs mode, which automatically inserts the header and makes the file executable (See Using Ciao inside GNU emacs).

Command line arguments in scripts

The following example illustrates the use of command-line arguments in scripts. Assume that a file called say contains the following lines:

#!/bin/sh 
exec ciao-shell $0 "$@" # -*- mode: ciao; -*-

main(Argv) :-
     write_list(Argv), nl.

write_list([]).
write_list([Arg|Args]) :- 
     write(Arg),
     write(' '),
     write_list(Args).

An example of use is:

/herme@clip:/tmp
[91]> say hello dolly
hello dolly