Skip to content

pve1/load-lisp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rationale:

Sometimes you need to build stuff from the shell, or start servers on
remote machines.  You want to tell your lisp compiler "here's my code,
here are my libraries, now load my application" without having to
create elaborate init scripts or makefiles for every program.

----

Load-lisp provides a convenient command line interface for these
common operations (and some not so common operations).  Hopefully, it
allows you to easily build your software with one shell command,
without complicated --eval '(...)' incantations.

Currently SBCL is supported, but adding support for other
implementations is easy.  All processes are started with --no-userinit
(or --script).

The scripts load-lisp and compile-lisp should be symlinked to ~/bin.

Both scripts accept the same options, but compile-lisp will invoke
sbcl with --script, and quit after the last option has been processed,
whereas load-lisp will call sbcl with --no-userinit and --noinform and
enter the REPL normally after all options have been processed.


Usage:

load-lisp [--core CORE] [OPTION] ...

Options are processed and executed in the order they appear on the
command line.

Supported options:

-I DIR                   Add DIR to asdf registry
-T DIR                   Add TREE to asdf registry (asdf2 only)
-S SYSTEM                Load SYSTEM
-R SYSTEM                Require SYSTEM
--eval SEXP              Eval SEXP
--load FILE              Load FILE
--compile FILE           Compile FILE
--clean SYSTEM           Delete FASL files associated with SYSTEM
--load-compile FILE      First compile FILE (if needed), then load the
                         resulting FASL
--deps SYSTEM            Load dependencies of SYSTEM, but not SYSTEM
--swank [PORT]           Start swank on the given port, or default port
--quit                   Quit (only meaningful for load-lisp)
--batch                  Process arguments normally, then quit
                         (default behaviour for compile-lisp).

--main FUNCTION          Set FUNCTION to be the toplevel function when
                         saving a core (use with --save option)

--save CORE              Save current lisp to CORE (and die)

--save-exe CORE          Save an executable core to CORE
                          - The user init-file is not loaded by this
                            core at startup
                          - The debugger is disabled

                         Tip: combine this option with
                         "--install --main quit"

                         NOTE: Any options given *after* either --save
                         or --save-exe are saved and processed in the
                         newly created core's init hook instead.


--install                Install the load-lisp argument handler code
                         into a core being saved.  The core will be
                         able to process all the flags documented
                         here on its own.

---ANYLISPSYMBOL [ARG]   Funcall the lisp symbol ANYLISPSYMBOL with
                         the string argument ARG (note the three
                         dashes).  If ARG starts with "-" then it is
                         ignored.  (use a backslash, like '\-...' to
                         prevent this)


So called 'apply-flags' are also supported.  Each flag contains one or
more spec characters followed by a lisp function name.

Valid spec characters are:

- r: read-from-string
- f: funcall the function with the flag argument
- a: apply the function to the flag argument
     (use like --rap-foo '(arg1 arg2 arg3)')
- p: print the result

They can be used as follows:

--f-FOO ARG       funcall FOO with string argument ARG
--rf-FOO ARG      read-from-string ARG, then funcall FOO with the
                  result
--rfp-FOO ARG     read-from-string ARG, then funcall FOO, then print
                  the result
--fp-FOO ARG      funcall FOO with string argument ARG, then print the
                  result
--ra-FOO ARG      read-from-string ARG, then apply FOO
                  (use like --ra-foo '(arg1 arg2 arg3)')
--rap-FOO ARG     read-from-string ARG, then apply FOO, then print the
                  result

Mirrored specs are also recognized (fr, pf, pfr, ar, par).  Other spec
combinations are not allowed.

--------------

Usage examples:

$ load-lisp --eval '(print "hello world")'
$ load-lisp ---print "hello world"

- both commands print "hello world" then enter the REPL


$ compile-lisp -I systems/my-systems/ -I systems/third-party/ -S my-library

- adds systems/my-systems/ and systems/third-party/ to the asdf registry
- loads the system "my-library", then quits.


$ compile-lisp -I systems/my-systems/ -I systems/third-party/ -S my-library --save my-library.core

- adds systems/my-systems/ and systems/third-party/ to the asdf registry
- loads the system "my-library"
- saves the core to "my-library.core".


$ compile-lisp -I systems/my-systems/ -I systems/third-party/ -S some-system --load some-script.lisp --main my-package:my-main-function --save my-program

- adds systems/my-systems/ and systems/third-party/ to the asdf registry
- loads the system "some-system"
- loads the lisp file "some-script.lisp"
- saves an executable core to "my-program" with the toplevel function
  my-package:my-main-function.  The "--main" switch must precede the
  "--save" switch.


$ load-lisp -I systems/my-systems/ -I systems/third-party/ -S util

- adds systems/my-systems/ and systems/third-party/ to the asdf registry
- loads the system "util"
- then enters the repl


$ load-lisp -I systems/my-systems/ -I systems/third-party/ -S my-library -S my-web-app --swank

- adds systems/my-systems/ and systems/third-party/ to the asdf registry
- loads the systems "my-library" and "my-web-app"
- creates a swank server and enters the repl


$ load-lisp -T systems/ --deps my-web-app --save base.core

- adds the systems/ tree to the asdf registry (asdf2 only)
- loads all dependencies of system "my-web-app" (but not my-web-app itself)
- saves the core to "base.core"


$ load-lisp --core base.core -S my-web-app ---set-server-port 10000 ---start-server

- starts the core "base.core"
  - the --core flag, if given, must be the first flag of the command,
- loads the systems "my-web-app"
- funcalls CL-USER::SET-SERVER-PORT with the string argument "10000"
- funcalls CL-USER::START-SERVER with no arguments


$ load-lisp --load ~/quicklisp/setup.lisp ---ql:quickload alexandria

- loads the file ~/quicklisp/setup.lisp
- funcalls the function QL:QUICKLOAD with the argument "alexandria"
  (note the three dashes to indicate arbitrary funcalling of functions
  that take at most one string argument)


$ compile-lisp --install --main quit --save-exe mycore

- installs the arg handler code
- sets the top-level function to QUIT
- saves an executable core to "mycore"
  - note: this core will just quit when executed with no arguments,
    use ---foo options to make it do things (or any other options
    documented here)


$ compile-lisp --install --save-exe mycore -S alexandria ---print hello

- installs the arg handler code
- saves an executable core to "mycore"
- on startup, the core "mycore" will load the system "alexandria" and print "hello"
  - i.e. running "./mycore ---print world" will load alexandria, print
    "hello" and print "world" in that order.