Chicken » Using the interpreter

## Using the interpreter

CHICKEN provides an interpreter named `csi` for evaluating Scheme programs and expressions interactively.

### Interpreter command line format

`csi {FILENAME|OPTION`}

where `FILENAME` specifies a file with Scheme source-code. If the extension of the source file is `.scm`, it may be omitted. The runtime options described in Compiler command line format are also available for the interpreter. If the environment variable `CSI_OPTIONS` is set to a list of options, then these options are additionally passed to every direct or indirect invocation of `csi`. Please note that runtime options (like `-:...`) can not be passed using this method. The options recognized by the interpreter are:

--
  Ignore everything on the command-line following this marker. Runtime options (`-:...`) are still recognized.
-i -case-insensitive
  Enables the reader to read symbols case insensitive. The default is to read case sensitive (in violation of R5RS). This option registers the `case-insensitive` feature identifier.
-b -batch
  Quit the interpreter after processing all command line options.
-e -eval EXPRESSIONS
  Evaluate `EXPRESSIONS`. This option implies `-batch`, `-no-init` and `-quiet`, so no startup message will be printed and the interpreter exits after processing all `-eval` options and/or loading files given on the command-line.
-p -print EXPRESSIONS
  Evaluate `EXPRESSIONS` and print the results of each expression using `print`. Implies `-batch`, `-no-init` and `-quiet`.
-P -pretty-print EXPRESSIONS
  Evaluate `EXPRESSIONS` and print the results of each expression using `pretty-print`. Implies `-batch`, `-no-init` and `-quiet`.
-D -feature SYMBOL
  Registers `SYMBOL` to be a valid feature identifier for `cond-expand` and `feature?`.
-h -help
  Write a summary of the available command line options to standard output and exit.
-I -include-path PATHNAME
  Specifies an alternative search-path for files included via the `include` special form. This option may be given multiple times. If the environment variable `CHICKEN_INCLUDE_PATH` is set, it should contain a list of alternative include pathnames separated by `;`.
-K -keyword-style STYLE
  Enables alternative keyword syntax, where `STYLE` may be either `prefix` (as in Common Lisp) or `suffix` (as in DSSSL). Any other value is ignored.
-n -no-init
  Do not load initialization-file. If this option is not given and the file `$HOME/.csirc` exists, then it is loaded before the read-eval-print loop commences.
-no-parentheses-synonyms
  Disables list delimiter synonyms, [..] and {...} for (...).
-no-symbol-escape
  Disables support for escaped symbols, the |...| form.
-w -no-warnings
  Disables any warnings that might be issued by the reader or evaluated code.
-q -quiet
  Do not print a startup message. Also disables generation of call-trace information for interpreted code.
-r5rs-syntax
  Disables the CHICKEN extensions to R5RS syntax. Does not disable non-standard read syntax.
-s -script PATHNAME
  This is equivalent to `-batch -quiet -no-init PATHNAME`. Arguments following `PATHNAME` are available by using `command-line-arguments` and are not processed as interpreter options. Extra options in the environment variable `CSI_OPTIONS` are ignored.
-sx PATHNAME
  The same as `-s PATHNAME` but prints each expression to `(current-error-port)` before it is evaluated.
-ss PATHNAME
  The same as `-s PATHNAME` but invokes the procedure `main` with the value of `(command-line-arguments)` as its single argument. If the main procedure returns an integer result, then the interpreter is terminated, returning the integer as the status code back to the invoking process. Any other result terminates the interpreter with a zero exit status.
-setup-mode
  When locating extensions, search the current directory first. By default, extensions are located first in the extension repository, where `chicken-install` stores compiled extensions and their associated metadata.
-R -require-extension NAME
  Equivalent to evaluating `(require-extension NAME)`.
-v -version
  Write the banner with version information to standard output and exit.

### Writing Scheme scripts

Since UNIX shells use the `#!` notation for starting scripts, anything following the characters `#!` is ignored, with the exception of the special symbols `#!optional, #!key, #!rest` and `#!eof`.

The easiest way is to use the `-script` option like this:

    % cat foo
    #! /usr/local/bin/csi -script
    (print (eval (with-input-from-string
                    (car (command-line-arguments))
                     read)))

    % chmod +x foo
    % ./foo "(+ 3 4)"
    7

The parameter `command-line-arguments` is set to a list of the parameters that were passed to the Scheme script. Scripts can be compiled to standalone executables (don't forget to declare used library units).

CHICKEN supports writing shell scripts in Scheme for other platforms as well, using a slightly different approach. The first example would look like this on Windows:

    C:>type foo.bat
    @;csibatch %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
    (print (eval (with-input-from-string
                    (car (command-line-arguments))
                    read)))

    C:>foo "(+ 3 4)"
    7

Like UNIX scripts, batch files can be compiled. Windows batch scripts do not accept more than 8 arguments.

Since it is sometimes useful to run a script in the interpreter without actually executing it (for example to test specific parts of it), the option `-ss` can be used as an alternative to `-script`. `-ss PATHNAME` is equivalent to `-script PATHNAME` but invokes `(main (command-line-arguments))` after loading all top-level forms of the script file. The result of `main` is returned as the exit status to the shell. Any non-numeric result exits with status zero:

    % cat hi.scm
    (define (main args)
      (print "Hi, " (car args))
      0)
    % csi -ss hi.scm you
    Hi, you
    % csi -q
    #;1> ,l hi.scm
    #;2> (main (list "ye all"))
    Hi, ye all
    0
    #;3>

When `csi` is started with the `-script` option, the feature identifier `chicken-script` is defined, so can conditionally execute code depending on wether the file is executed as a script or normally loaded into the interpreter, say for debugging purposes:

    #!/bin/sh
    #| demonstrates a slightly different way to run a script on UNIX systems
    exec csi -s "$0" "$@"
    |#

    (define (main args) ...)

    (cond-expand
      (chicken-script
        (main (command-line-arguments)))
      (else))

See also the documentation for the `-ss` option above.

You can also have a look at /writing portable scripts.

### Toplevel commands

The toplevel loop understands a number of special commands:

,?
  Show summary of available toplevel commands.
,c
  Show call-trace items of the most recent error
,ch
  Clears stored expression results of previously evaluated expressions.
,d EXP
  Describe result of evaluated expression `EXP`.
,du EXP
  Dump contents of the result of evaluated expression `EXP`.
,dur EXP N
  Dump `N` bytes of the result of evaluated expression `EXP`.
,e FILENAME
  Runs an external editor to edit the given `FILENAME` (see below for more information).
,exn
  Describes the last exception that occurred and adds it to the result history (it can be accessed using the `#` notation).
,f N
  Select call-trace item with the given number, where the number `0` indicates the last item in the trace
,g NAME
  Returns the value of the local variable with the given name (which may be a symbol or string); you don't have to give the complete name - `,g` will return the first variable that matches the prefix given
,h
  Shows all previously evaluated expression results.
,l FILENAME ...
  Load files with given `FILENAME`s
,ln FILENAME ...
  Load files and print result(s) of each top-level expression.
,m MODULENAME
  switches the "current module" to `MODULENAME`, so expressions will be evaluated in the context of the given module. To switch back to toplevel, use `#f` as a MODULENAME. In compiled modules, only exported bindings will be visible to interactively entered code. In interpreted modules all bindings are visible.
,p EXP
  Pretty-print evaluated expression `EXP`.
,q
  Quit the interpreter.
,r
  Show system information.
,s TEXT ...
  Execute shell-command.
,t EXP
  Evaluate form and print elapsed time.
,x EXP
  Pretty-print macroexpanded expression `EXP` (the expression is not evaluated).

You can define your own toplevel commands using the `toplevel-command` procedure:

### toplevel-command

`(toplevel-command SYMBOL PROC [HELPSTRING])` procedure

  Defines or redefines a toplevel interpreter command which can be invoked by entering `,SYMBOL`. `PROC` will be invoked when the command is entered and may read any required argument via `read` (or `read-line`). If the optional argument `HELPSTRING` is given, it will be listed by the `,?` command.

### Getting error information

Interpreted code has some extended debugging information available that can be used to locate errors and obtaining information about the lexical environment that was effective at the point of error. When an error occurs in an evaluated expression, a "call trace" is printed - the list of calls up to the error location. Note that this does not follow a stack model: it is merely a list of recently made procedure calls where the last one in the list is (probably) the call of whatever procedure was executing before the error happened. You can use the `,c` command to show the call-trace of the last error. Depending on whether compiled or interpreted code was executing and how much debugging information is available, the call trace shows trace-buffer entries of the following shape:

     <frame-number>:<environment?> <mode> <procedure-name> <form>

`<frame-number>` gives the number of the call-trace entry, counting from zero and beginning with the most recent entry. If a `[]` follows the frame-number, then this frame contains the lexical environment in effect when that procedure call took place. `<mode>` is optional and is either `<syntax>` or `<eval>` indicating whether this trace-buffer entry represents a syntax-expansion or an evaluation and is not given for compiled code. `<form>` is also only available for interpreted code and shows the procedure call expression, possibly following the name of the procedure containing the call expression.

If the trace-buffer entry contains lexical environment information than the complete environment of the call site is shown.

Use `,f` to select a frame by number, if you want to inspect the lexical environment of an earlier frame. The `,g` command lets you retrieve the value of a local or lexical variable from the currently selected frame. Note that the variables are renamed to simplify the variable lookup done internally by the interpreter.

### Running an external editor

The `,e` command runs the editor given by:

- The parameter `editor-command` which should return a string naming an external editor and defaults to `#f`, which means no editor is currently selected (so the following alternatives are tried).
- The contents of the environment variables `EDITOR` or `VISUAL`.
- If the environment variable `EMACS` is set, the editor chosen is `emacsclient`.
- As a truly last resort, `vi` is used.

### History access

The interpreter toplevel accepts the special object `#[INDEX]` which returns the result of entry number `INDEX` in the history list. If the expression for that entry resulted in multiple values, the first result (or an unspecified value for no values) is returned. If no `INDEX` is given (and if a whitespace or closing paranthesis character follows the `#`, then the result of the last expression is returned. Note that the value returned is implicitly quoted.

### set-describer!

`(set-describer! TAG PROC)` procedure

  Sets a custom description handler that invokes `PROC` when the `,d` command is invoked with a record-type object that has the type `TAG` (a symbol). `PROC` is called with two arguments: the object to be described and an output-port. It should write a possibly useful textual description of the object to the passed output-port. For example:

      #;1> (define-record-type point (make-point x y) point?
             (x point-x)
             (y point-y))
      #;2> (set-describer! 'point
             (lambda (pt o)
               (with-output-to-port o
                 (lambda ()
                   (print "a point with x=" (point-x pt) " and y=" (point-y pt))))))
      #;3> ,d (make-point 1 2)
      a point with x=1 and y=2

### Auto-completion and edition

On platforms that support it, it is possible to get auto-completion of symbols, history (over different `csi` sessions) and a more feature-full editor for the expressions you type using the readline egg by Tony Garnock Jones. It is very useful for interactive use of csi. See the egg's documentation on how to set it up. If readline is not available on your system consider using the self-contained linenoise egg instead. It should work on almost any system but is not as feature-rich as readline (e.g. it lacks reverse-i-search and auto-completion).

The interpreter `csi` internally requires some routines from the `ports` and `extras` library units and loads them automatically on startup. These libraries are not automatically loaded in compiled code, so there is an inconsistency between code that is executed in `csi` versus code that is compiled and executed.

Previous: Using the compiler

Next: Supported language