The Jisp Engine

The Jisp engine provides a miniature Lisp implementation using a Java applet or a command-line application. You can see Jisp running in a Java applet near the bottom of this page.

Jisp is intended to provide a subset of Common Lisp but I'm not too sure how precisely this is achieved. The program uses language features and classes from JDK1.1 and doesn't work with older compilers or runtime systems. Comments welcome. And yes it is a mildly silly name for a program, though I gather a good one for a village in Holland.

Jisp is Copyright 1998 Richard W.E. Furse. All rights reserved.

Links to this page and applet are welcome, but please let me know. Please do not make modifications to Jisp without checking with me first. I'd probably be fairly open with the code anyway as most of it was written over a weekend. And I will not be held responsible for loss or damage resulting from use of this software. It's only a toy, there's nothing deliberately wrong with it, but you never know. If you don't like this caveat, don't use the software.


What is Jisp For?

Jisp is a simple Lisp interpreter written in Java. I'm vaguely curious about compiler techniques and this would provide a good vehicle.

Jisp is `light-weight' (45k at last count) and has an open design. It could be useful for teaching, particularly with web-based CBT systems.


Constructs Available:

The following constructs can be used with the system. I'm afraid I assume here that readers know their way around Lisp so I'm not giving detailed descriptions.

Basic Types:

Conses And Lists:

A cons is a pairing of objects, known as car and cdr.

A list is a collection of `cons' statements chained together using `cdr' and terminated with a nil.

Maths:

Maths functions operate using the Java arbitrary precision maths library. Floating-point numbers and fractions are not supported at this time.

Logic:

Functions And Evaluation:

Basic Evaluation:

A list in Jisp is evaluated by evaluating all elements within the list and then applying the first item to the others as a function. Note that although there are many constructs of form (...), many are not function applications.

A typical function application is (+ 1 2). Here the atom `+' is evaluated to the addition function. Numbers are already evaluated so nothing happens to these. The addition function is then applied to 1 and 2, returning 3.

If we have defined a function addone which adds one to a number, then the call (addone (+ 1 1)) would first evaluate the atom `addone' to return the function itself and then evaluate the (+ 1 1) expression to produce 2. The addone function code will then be applied to 2 to produce 3. That was a poor explanation: for a better one see any good book on Common Lisp.

Function And Evaluation Constructs:

Scope:

The scope is a binding of atom symbols to Jisp objects. It has a `memory' so that values can be bound `locally' to a symbol and then unbound in a way that does not lose any previous value. Scope also supports `global' bindings. The global binding only provides the value for a symbol when no local binding is present. No memory is kept of previous global bindings.

Scopes are Serializable in Java terms, meaning that it will be easy to read and write the contents of a scope (including function definitions etc) from and to disc.

Bindings happen under the following conditions:

  1. A function is applied. In this case the formal parameters of the function are bound locally to the actual parameters passed to the function.
  2. `defun' is called. This explicitly binds a function to a particular symbol globally.
  3. `let' is used. This explicitly binds a number of atoms locally to Jisp objects.

A Warning Concerning Recursive Functions:

The current implementation has behaviour that I'm not 100% sure about: when declaring a function using defun or using let and lambda, it is possible to declare recursive functions. Within this recursive function, the reference back to the function itself will remain an atom rather than a reference to the function itself. For most purposes this is irrelevant as the atom will be evaluated to produce the function later. However there are possible problems if the symbol in use is redefined, as a call to the old function will call the new function after one iteration.

To avoid this problem, do not redefine named functions at runtime unless you're going to be extremely careful.


The Jisp Prompt:

Jisp can be run on the command line using java Jisp.Prompt. Run on its own this will provide a conventional read-eval-print loop to the user. This program has two optional parameters, input file and output file. Thus java Jisp.Prompt in.jisp will run the Jisp script in.jisp and output results to the screen. java Jisp.Prompt in.jisp out.txt will route the output to file.


The Jisp Applet:

The applet should be visible at the end of this section. Click on the bottom box and you should be able to enter items to evaluated. This program has a somewhat ropey approach to working out when you want to evaluate the string in the box--essentially the system will attempt to evaluate the string any time you press enter and there is an equal number of open and close brackets in the box. Still, it's only intended as a toy for the moment.

The Jisp applet accepts a `context' parameter from the HTML page describing it: this page invokes the applet which may contain a number of Jisp expressions to be evaluated before the user prompt becomes active. This page enclosing the applet loads it using the following form:

<APPLET CODE="Jisp.JispApplet" ARCHIVE="Jisp.jar" WIDTH=600 HEIGHT=500>
<PARAM name="context" value="
    (defun factorial (n) (if (eq n 0) 1 (* n (factorial (- n 1)))))
    (defun church3 (f) (lambda (x) (f (f (f x)))))
">
</APPLET>

The applet presented on this page is available as a `jar' archive as well as ordinary class files. Running on older browsers the class will be picked up without use of the ARCHIVE parameter. This is slower and requires the program to be stored twice on the server.

You may have some problems running this applet though I don't know why. It runs fine in my Internet Explorer 4 browser and the HotJava browser provided with Sun's JavaPC demo package, but seems to have trouble with Internet Explorer 3 and my (old) version of appletviewer. I thought this might be due to private inner classes, but I've given them all package visibility and the problem remains. Two problems manifest themselves: the first is an access violation. The second occurs when the applet appears to be working but then refuses to evaluate expressions when enter is pressed. If you've got this far however, then it will be possible to run the program using the Jisp Prompt (above).


The author Richard Furse can be emailed as richard@muse.demon.co.uk.

Return to index Counter