Sketchy LISP
Reference
  Copyright (C) 2006
Nils M Holm

7 Interpreter API

7.1 Embedding the Interpreter

The Sketchy interpreter consists of two parts: the sketchy.h header file and the library. The header contains

The library contains the interpreter itself. To compile a C program that interfaces Sketchy, use the following invocation:

cc program.c -lsketchy

You might have to add -Iincdir and -Llibdir options, if the header or library are located in non-standard places.

A minimal program embedding the Sketchy interpreter follows. The program implements a complete interpreter shell. The only differences to the `real' Sketchy shell are that this simple application does not implement statistics, batch mode, signal handling, or command line options.

#include <stdio.h>
#include <sketchy.h>

void main(void) {
    int n;

    if (sk_init(SK_DFL_NODES, SK_DFL_VCELLS)) {
        fprintf(stderr, "sk_init failed\n");
        exit(1);
    }
    if (sk_loadImage(SK_DFL_IMAGE)) {
        fprintf(stderr, "sk_loadImage failed\n");
        exit(1);
    }
    while (1) {
        SK_errFlag = 0;
        n = sk_read();
        if (n == sk_eof()) break;
        n = sk_eval(n);
        if (SK_errFlag) {
            sk_printError();
        }
        else {
            sk_pr("=> ");
            sk_print(n);
            sk_nl();
        }
    }
    sk_bye();
}

The functions, variables, and constants used in this program will be explained in detail in the following sections.

7.2 Functions

7.2.1 sk_bye

void sk_bye(void);

Print "Bye" to the output stream and terminate the calling program using exit(0).

7.2.2 sk_count

void sk_count(struct sk_counter *c, int k);

Increment the counter c by some small amount k (k may not be larger than 1000). If the counter overflows, an error condition occurs. The counter structure is defined as follows:

struct sk_counter {
    int n,      /* ones */
        n1k,    /* thousands */
        n1m,    /* millions */
        n1g;    /* billions */
};

7.2.3 sk_display

void sk_display(int n);

Display the Sketchy node n using the display primitive.

7.2.4 sk_dumpImage

void sk_dumpImage(char *p);

Dump the workspace of the interpreter to the file p. This function sets SK_errFlag in case of an error.

7.2.5 sk_eof

int sk_eof(void);

Return the EOF object. Comparing a node with the EOF object resembles the eof-object? primitive:

int eof_object(int n) { return n == sk_eof(); }

7.2.6 sk_eval

int sk_eval(int n);

Evaluate the Sketchy node n and return a node representing the normal form of n. This function sets SK_errFlag in case of an error. In this case, the return value of sk_eval() is undefined.

7.2.7 sk_fini

void sk_fini(void);

Release the memory pools allocated by sk_init().

7.2.8 sk_gc

void sk_gc(struct sk_gcStats *stats);

Perform a garbage collection and fill the stats data structure with some statistics. stats is defined as follows:

struct sk_gcStats {
    int nodes_used,
        vcells_used,
        nodes_max,
        vcells_max;
};

The _used fields are filled with the numbers of nodes and vcells currently used, and the _max fields are filled with peak load of the memory pools since the last call to sk_gc.

sk_gc also resets the peak load indicators.

7.2.9 sk_gotError

void sk_gotError(void);

Signal the interpreter that the most recent error has been handled. Either this routine or sk_printError must be called after detecting an error condition. Otherwise the interpreter will not evaluate any further expressions.

7.2.10 sk_init

int sk_init(int nodes, int vcells);

Initialize the interpreter and allocate the memory pools. Return a value indicating success (0) or failure (<0). The arguments nodes and vcells indicate the numbers of nodes and vector cells to allocate. To allocate a default number of resources, use

sk_init(SK_DFL_NODES, SK_DFL_VCELLS);

Neither the number of nodes nor the number of vcells may be less than SK_MIN_SIZE.

The release date of the interpreter can be found in the constant SK_RELEASE and the major version number in SK_MAJOR. The release date has the format "yyyy-mm-dd", the version number is an integer.

7.2.11 sk_license

char **sk_license(void);

Return a pointer to the conditions of use as an array of strings. Each string contains one line of the license. The last line contains NULL.

7.2.12 sk_load

int sk_load(char *p);

Load a source file by temporarily redirecting the input stream to the file p. Return a value indicating success (0) or failure (<0). Failure occurs, if the source file could not be opened or contains an erroneous expression. In the latter case, some definitions contained in the file may have loaded sucessfully.

7.2.13 sk_loadImage

int sk_loadImage(char *p);

Load a workspace image from the file p. Return a value indicating success (0) or failure (<0). Possible causes for failure are:

Note: After a failed attempt to load an image, the interpreter must be shut down by calling sk_fini() and then re-initialized using sk_init().

7.2.14 sk_nil

const int sk_nil(void);

Return the node representing the empty list (aka NIL).

7.2.15 sk_nl

void sk_nl(void);

Write a newline sequence to the output stream.

7.2.16 sk_pr

void sk_pr(char *s);

Write the string s to the output stream.

7.2.17 sk_print

void sk_print(int n);

Write the external representation of the Sketchy node n to the output stream.

7.2.18 sk_printCallTrace

void sk_printCallTrace(int frame);

Print a trace of the 10 most recently called functions.

7.2.19 sk_printCounter

void sk_printCounter(struct sk_counter *c);

Write the value of a counter to the output stream. For a definition of the sk_counter structure, see sk_count(). The counter value is printed in groups of three digits separated by commas, like this:

1,234,567

7.2.20 sk_printError

void sk_printError(void);

Print an error message and reset the error condition by calling sk_gotError(). If the error flag (SK_errFlag) is clear upon entry, sk_printError() does not print any message. If it does print a message, it has the following form:

* file: line: function: message: expr
* additional information

File is the file containing the source of the error. It is taken from the variable SK_errFile. If this variable is NULL, the file part is omitted.

Line is the line number of the expression that has caused the error. It is equal to the value of SK_errLine.

Function is the name of the function in which the error occured. It is taken from the node SK_errFun. If this node is NIL, sk_printError() prints REPL instead.

Message is the error message itself (SK_errMsg).

Expr is the expression that caused the error. It is taken from the node SK_errExpr. If SK_errExpr is equal to the constant SK_NOEXPR, the error was not caused by any specific expression.

The additional information part is equal to the SK_errArg variable. It prints only, if this variable is not NULL.

If the SK_errFrame variable is not NIL, sk_printError() also prints a call trace using sk_printCallTrace().

7.2.21 sk_printStats

void sk_printStats(void);

Print some statistics of the form

nr reduction steps
nn nodes allocated
ng garbage collections

where nr = SK_reductions,
nn = SK_allocations,
and ng = SK_collections.

All the statistics variables are of the type sk_counter. For its definition, see sk_count(). Individual values are printed using sk_printCounter().

7.2.22 sk_read

int sk_read(void);

Read a Scheme datum from the input stream and convert it to internal representation. Return a Sketchy node representing the internal form. This function resembles the read primitive.

the sk_read() function may be used to pass meta commands to the interpreter.

7.2.23 sk_require

void sk_require(char *p);

Load the content of the file p using sk_load, but only if the basename of p is not bound in the interpreter. The basename of a path is the element between the last slash (if any) and the first dot (if any):

/this/is/some/path/basename.l

7.2.24 sk_resetCounter

int sk_resetCounter(struct sk_counter *c);

Reset the counter c to zero. For a definition of the sk_counter structure, see sk_count().

7.2.25 sk_stop

void sk_stop(void);

Stop the interpreter by issuing an error. The error message delivered to the interpreter is "interrupted". After stopping the interpreter using sk_stop(), the error condition must be reset by issuing sk_printError() or sk_gotError().

sk_stop() is typically called by a signal handler. The following code fragment would handle keyboard interrupts (SIGINT) under Unix:

#include <signal.h>

void catchIntr(int sig) {
	sk_stop();
}

void main(void) {
	signal(SIGINT, catchIntr);
	/*
	 * Place your Sketchy interface here.
	 */
}

7.3 Variables

7.3.1 SK_allocations

extern struct sk_counter SK_allocations;

Allocation counter. See sk_count().

7.3.2 SK_arrowMode

extern int SK_arrowMode;

Enable arrow comments. See :arrow-comments meta command.

7.3.3 SK_batch

extern int SK_batch;

Batch (silent) mode flag. Do not print informational messages, exit on first error.

7.3.4 SK_closureForm

extern int SK_closureForm;

External representation of closures (0,1,2). See :closure-form meta command.

7.3.5 SK_collections

extern struct sk_counter SK_collections;

Garbage collection counter. See sk_count().

7.3.6 SK_errArg

extern char *SK_errArg;

Additional error information. See sk_printError().

7.3.7 SK_errExpr

extern int SK_errExpr;

Expression causing last error. See sk_printError().

7.3.8 SK_errFile

extern char *SK_errFile;

File of last error. See sk_printError().

7.3.9 SK_errFlag

Error flag. See sk_eval(), sk_printError(), and sk_gotError().

extern int SK_errFlag;

7.3.10 SK_errFrame

extern int SK_errFrame;

Call frame of last error. See sk_printError() and sk_printCallTrace().

7.3.11 SK_errFun

extern int SK_errFun;

Function of last error. See sk_printError().

7.3.12 SK_errLine

extern int SK_errLine;

Line number of last error. See sk_printError().

7.3.13 SK_errMsg

extern char *SK_errMsg;

Most recent error message. See sk_printError().

7.3.14 SK_metaChar

extern int SK_metaChar;

Meta command character. Prefix for meta commands. Default: ':'.

7.3.15 SK_reductions

extern struct sk_counter SK_reductions;

Reduction counter. See sk_count().

7.3.16 SK_statFlag

extern int SK_statFlag;

Statistics flag. Start gathering statistics. See sk_printStats() function and :statistics meta command.

7.3.17 SK_strictApply

extern int SK_strictApply;

Strict (R5RS) apply flag. See :r5rs-apply meta command.

7.3.18 SK_trace

extern int SK_trace;

Function being traced. See :trace meta command.

7.3.19 SK_traceHandler

extern int (*SK_traceHandler)(int n);

Pointer to used-defined trace handler. Set to NULL to use the internal trace handler. For now, see the source code (sketchy.c)for further details.