I have finally run out of excuses to delay publishing Kea Common
Lisp, the compiler for Parrot I've been hacking on for years now.
Attached please find a draft of the release announcement and the
README.text file it mentions; these should be enough to download it and
try it out.  For those who are curious enough to do so, I would be
grateful for any reports of success or failure (especially failure!)
before I annouce Kea-CL to the Lisp community.

   Thanks in advance -- and many thanks to the Parrot community in
general for making dynamic language implementation (almost) easy!

                                        -- Bob Rogers
                                           http://rgrjr.dyndns.org/

Subject: [ANNOUNCE] Kea Common Lisp:  A Lisp compiler for Parrot

   Kea Common Lisp is an implementation of ANSI Common Lisp that is
based on CMU Common Lisp (see http://www.cons.org/cmucl/) and is
targeted to the Parrot bytecode virtual machine (see
http://www.parrotcode.org/).  Parrot is a VM designed specifically for
running dynamic languages in general, and Perl 6 in particular.  The
chief goal of the Kea Common Lisp project is to provide easy
interoperability between Lisp and the other dynamic languages hosted on
Parrot.

   The runtime is incomplete, being at the level of a simple desk
calculator with an eccentric syntax, but the cross-compiler already
supports most of the core semantic repertoire.  The cross-compiler is
almost capable of compiling itself; when that happens, EVAL will become
suddenly much more powerful, and Kea will be able to grow rapidly.

   Kea Common Lisp is free sofware, and is licenced under the same terms
as Parrot (approximately).  See the README.text file (contents appended
below) for license details, and for download instructions.
                     Kea Common Lisp version 0.4.15

Copyright (C) 2005, 2006, 2007, Bob Rogers <[EMAIL PROTECTED]>.
All Rights Reserved.

Kea Common Lisp is an implementation of ANSI Common Lisp that is based
on CMU Common Lisp (see http://www.cons.org/cmucl/) and is targeted to
the Parrot bytecode virtual machine (see http://www.parrotcode.org/).

LICENSE INFORMATION
-------------------

This code is distributed under the same license as Perl 5; you can
redistribute it and/or modify it under the terms of either:

    a) the GNU General Public License as found in the directory
       "LICENSES", or any later version; or

    b) the "Artistic License" as be found in the directory "LICENSES",
       or any later version.

So far, this is identical to the Parrot license.  However, some source
files are derived directly from CMU Common Lisp sources that are in the
public domain; these files have headers that clearly mark them as such,
and, taken individually, each of these files is still in the public
domain.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
the GNU General Public License or the Artistic License for more details.

PREREQUISITES
-------------

Kea Common Lisp works with the current development version of Parrot.
See http://www.parrotcode.org/ to find out how to get the current
development sources using Subversion.  Alternatively, download the
Parrot release from CPAN that has the same version number.  Parrot, in
turn, requires Perl 5.8.x (for some "x" greater than 1), and an ANSI C
compiler; both are also used by Kea-CL.

Kea Common Lisp has only been tested on Linux/x86, but should in principal run
on any platform supported by Parrot.  However, makefile tweaks will be
necessary to build dynclasses/character.pmc on some non-Linux systems.
(Patches welcome.)

BUILDING
--------

The release tarball is available at:

        http://rgrjr.dyndns.org/lisp/kea-cl/kea-cl-0.4.15.tgz

Building Kea Common Lisp from the tarball is straightforward:

    1.  Untar and cd into the build directory (kea-cl-0.x.x).
    2.  Edit the PARROT-HOME macro at the top of the makefile to reflect
        the location of the Parrot build directory.
    3.  "make"
    4.  "make test"

There is no "make install" as Kea Common Lisp (like Parrot) can only be
run from its build directory.

Note that "make" just compiles prepackaged *.imc and *.pir files to
*.pbc (i.e. from Parrot assembler to Parrot bytecode).
This is because there is not enough runtime support yet for the
compiler to run natively on Parrot, so compiling *.lisp files to *.imc
requires cross-compilation from a full-blown Common Lisp implementation.
For details, see the "REBUILDING FROM SCRATCH" section below.

RUNNING
-------

After compiling, do

        parrot kea.pbc

to run the Lisp interpreter.  The prompt is a "* ".  To exit, type an
EOF.  See below for a summary of implemented functions.  Note that there
is no DEFUN or even LET; the interpreter is really just a simple desk
calculator with an eccentric syntax.

REBUILDING FROM SCRATCH
-----------------------

Kea Common Lisp consists of five categories of source files (ignoring
test scaffolding):

    1.  Hand-written Parrot Intermediate Representation (PIR) sources;

    2.  dynclasses/character.pmc, a PMC class definition, which is
        preprocessed into C and then compiled to a shared object file;

    3.  A cross-compiler, written in Common Lisp, which compiles a
        subset of Common Lisp to PIR;

    4.  Lisp sources compiled by the cross-compiler (listed in the
        COMPILED-LISP-FILES macro in the makefile); and

    5.  A few other *.lisp files that are not actually used yet.

Categories 1 and 2 are compiled by/with Parrot, and require only a
working copy of Parrot and the C compiler you used to compile Parrot.
Recompiling the *.lisp files in categories 3
and 4 requires CMU Common Lisp
(CMUCL), which only works on flavors of Unix.  This release of Kea CL was 
tested with 19d, but any recent CMUCL version should 
work just fine.   (It used to work with Steel Bank Common Lisp (SBCL)
version 0.8.18, but the lexical
variable support in r158 broke it, since the lexvar stuff uses more
CMUCL internals, and I haven't been able to fix it since.)

To recompile the *.lisp files, assuming the Parrot config is still
correct, do the following:

    1.  Adjust the macros in "Lisp config" section of the makefile.
        They are set up correctly for the default CMUCL install (at
        least on an x86 machine).
    2.  "make realclean" (or "make imc-clean").
    3.  "make"
    4.  "make test"
    5.  "make test-compiler"

Typing "make clean" removes all PMC-derived and *.pbc files, restoring
the state to that of the distribution tarball; this is sufficient to
rebuild after updating Parrot.  Typing "make imc-clean" also removes ALL
*.imc files that were compiled from *.lisp; in that case, a subsequent
"make" will recompile the necessary *.lisp sources.  Finally, "make
realclean" also gets rid of the cross-compiler binaries.

REBUILDING FROM SUBVERSION
--------------------------

The Kea-CL Subversion repository (see http://subversion.tigris.org/) is
at https://rgrjr.dyndns.org/svn/kea-cl/, and does not require login
credentials for read access.  To check it out, do

        svn checkout https://rgrjr.dyndns.org/svn/kea-cl/trunk/ kea-cl
        cd kea-cl

Unlike the release tarball, a fresh working copy does not have the *.imc
files produced by the cross-compiler, so you will need to follow the
instructions in the "REBUILDING FROM SCRATCH" section above.

WHAT'S CURRENTLY IMPLEMENTED
----------------------------

For details on the state of the implementation, see the kea-cl.pod
document.  See also the TODO.text file for a task list of missing
functionality.

Here's a summary of the Lisp functions implemented in Kea Common Lisp
version 0.4.15.  For the most part, full ANSI semantics are supported for
these functions, the chief exceptions being the arithmetic functions,
FORMAT, multidimensional arrays, readtables, and error handling.
(For reference, this represents a bit over a quarter of the symbols
defined by the language.)  For documentation of individual Lisp
functions, please see the Common Lisp HyperSpec at (e.g.)
http://www.lispworks.com/documentation/HyperSpec/Front/ .

        * (&rest args)
        + (&rest args)
        - (number &rest more-numbers)
        / (number &rest more-numbers)
        /= (number &rest more-numbers)
        1+ (number)
        1- (number)
        < (number &rest more-numbers)
        <= (number &rest more-numbers)
        = (number &rest more-numbers)
        > (number &rest more-numbers)
        >= (number &rest more-numbers)
        abs (number)
        adjoin (item list &key key (test #'eql) (test-not nil notp))
        alpha-char-p (char)
        alphanumericp (char)
        append (&rest lists)
        apply (function arg &rest args)
        aref (array &rest subscripts)
        ash (integer count)
        assoc (item alist &key key test test-not)
        atom (object)
        both-case-p (char)
        boundp (variable)
        butlast (list &optional (n 1))
        caaaar (list)
        caaadr (list)
        caaar (list)
        caadar (list)
        caaddr (list)
        caadr (list)
        caar (list)
        cadaar (list)
        cadadr (list)
        cadar (list)
        caddar (list)
        cadddr (list)
        caddr (list)
        cadr (list)
        car (list)
        cdaaar (list)
        cdaadr (list)
        cdaar (list)
        cdadar (list)
        cdaddr (list)
        cdadr (list)
        cdar (list)
        cddaar (list)
        cddadr (list)
        cddar (list)
        cdddar (list)
        cddddr (list)
        cdddr (list)
        cddr (list)
        cdr (list)
        ceiling (number &optional (divisor 1))
        cerror (continue-string datum &rest arguments)
        char (string index)
        char-code (char)
        char-downcase (char)
        char-equal (character &rest more-characters)
        char-int (char)
        char-name (char)
        char-upcase (char)
        char= (character &rest more-characters)
        character (object)
        characterp (object)
        close (stream &key abort)
        code-char (code)
        complexp (object)
        concatenate (output-type-spec &rest sequences)
        cons (se1 se2)
        consp (object)
        copy-alist (alist)
        copy-list (list)
        copy-seq (sequence)
        copy-symbol (symbol &optional (copy-props nil))
        copy-tree (object)
        count (item sequence &key from-end (test #'eql)
                    (test-not nil) (start 0) end key)
        count-if (test sequence &key from-end (start 0) end key)
        count-if-not (test sequence &key from-end (start 0) end key)
        digit-char (weight &optional (radix 10))
        digit-char-p (char &optional (radix 10))
        eighth (list)
        elt (sequence index)
        endp (object)
        eq (obj1 obj2)
        eql (obj1 obj2)
        equal (x y)
        equalp (x y)
        error (datum &rest arguments)
        eval (original-exp)
        evenp (number)
        export (symbols &optional (package *package*))
        expt (base power)
        fboundp (name)
        fceiling (number &optional (divisor 1))
        fdefinition (function-name)
        ffloor (number &optional (divisor 1))
        fifth (list)
        find (item sequence
                   &key from-end (test #'eql) test-not (start 0) end key)
        find-if (test sequence &key from-end (start 0) end key)
        find-if-not (test sequence &key from-end (start 0) end key)
        find-package (name)
        find-symbol (name &optional package)
        first (list)
        floatp (object)
        floor (number &optional (divisor 1))
        fmakunbound (name)
        format (destination control-string &rest format-arguments)
        fourth (list)
        funcall (function &rest arguments)
        function (object)
        functionp (object)
        gensym (&optional (thing g))
        gentemp (&optional (prefix t) (package *package*))
        get (symbol indicator &optional (default nil))
        get-dispatch-macro-character (disp-char sub-char &optional
                                                (rt *readtable*))
        get-macro-character (char &optional (rt *readtable*))
        get-output-stream-string (stream)
        getf (place indicator &optional (default nil))
        gethash (key hash-table &optional default)
        graphic-char-p (char)
        hash-table-count (hash-table)
        hash-table-p (object)
        hash-table-rehash-size (structure)
        hash-table-rehash-threshold (object)
        hash-table-test (structure)
        identity (thing)
        input-stream-p (stream)
        integerp (object)
        interactive-stream-p (stream)
        intern (name &optional package)
        intersection (list1 list2 &key key (test #'eql) (test-not nil))
        keywordp (object)
        last (list &optional (n 1))
        length (sequence)
        list (&rest args)
        list* (arg &rest others)
        list-length (list)
        listp (object)
        load (filename)
        lower-case-p (char)
        make-array (dimensions &key (element-type t)
                               (initial-element nil)
                               (initial-contents nil)
                               adjustable fill-pointer
                               displaced-to displaced-index-offset)
        make-dispatch-macro-character (char &optional
                                            (non-terminating-p nil)
                                            (rt *readtable*))
        make-hash-table (&key (test 'eql) (size 65) (rehash-size 1.5)
                              (rehash-threshold 1.0) (weak-p nil))
        make-list (size &key initial-element)
        make-package (name &key (use *default-package-use-list*) nicknames
                           (internal-symbols 10) (external-symbols 10))
        make-sequence (type length &key (initial-element nil iep))
        make-string (count &key element-type initial-element)
        make-string-output-stream (&key (element-type 'character))
        make-symbol (string)
        makunbound (variable)
        mapc (function list &rest more-lists)
        mapcan (function list &rest more-lists)
        mapcar (function list &rest more-lists)
        mapcon (function list &rest more-lists)
        maphash (map-function hash-table)
        mapl (function list &rest more-lists)
        maplist (function list &rest more-lists)
        max (number &rest more-numbers)
        member (item list &key key (test #'eql) (test-not nil))
        member-if (test list &key key)
        member-if-not (test list &key key)
        min (number &rest more-numbers)
        minusp (number)
        mod (number divisor)
        name-char (name)
        nconc (&rest lists)
        nintersection (list1 list2 &key key (test #'eql) (test-not nil))
        ninth (list)
        nreconc (x y)
        nreverse (sequence)
        nset-difference (list1 list2 &key key (test #'eql) (test-not nil))
        nset-exclusive-or (list1 list2 &key key (test #'eql) (test-not #'eql))
        nth (n list)
        nthcdr (n list)
        null (object)
        numberp (object)
        nunion (list1 list2 &key key (test #'eql) (test-not nil))
        oddp (number)
        open-stream-p (stream)
        output-stream-p (stream)
        package-name (x)
        package-nicknames (x)
        package-shadowing-symbols (x)
        package-use-list (x)
        package-used-by-list (x)
        packagep (object)
        plusp (number)
        position (item sequence
                       &key from-end (test #'eql) test-not (start 0) end key)
        position-if (test sequence &key from-end (start 0) key end)
        position-if-not (test sequence &key from-end (start 0) key end)
        prin1 (object &optional stream)
        prin1-to-string (object)
        princ (object &optional stream)
        princ-to-string (object)
        print (object &optional stream)
        print-object (mc stream)
        progn (&rest stuff)
        rassoc (item alist &key key test test-not)
        rationalp (object)
        read (&optional (stream *standard-input*) (eof-errorp t) (eof-value nil)
                        (recursivep nil))
        read-char (&optional (stream *standard-input*) (eof-errorp t) eof-value
                             recursive-p)
        read-delimited-list (endchar &optional (input-stream *standard-input*)
                      recursive-p)
        read-preserving-whitespace (&optional (stream *standard-input*)
                                              (eof-errorp t) (eof-value nil)
                                              (recursivep nil))
        readtable-case (structure)
        readtablep (object)
        realp (object)
        reduce (function sequence &key key from-end (start 0) end
                         (initial-value nil ivp))
        rem (number divisor)
        remhash (key hash-table)
        remove (item sequence
                     &key from-end (test #'eql) test-not (start 0) end count 
key)
        remove-if (predicate sequence &key from-end (start 0) end count key)
        remove-if-not (predicate sequence &key from-end (start 0) end count key)
        remprop (symbol indicator)
        rename-package (package name &optional (nicknames nil))
        replace (target-sequence source-sequence
                                 &key (start1 0) end1 (start2 0) end2)
        rest (list)
        revappend (x y)
        reverse (sequence)
        round (number &optional (divisor 1))
        row-major-aref (array index)
        rplaca (x y)
        rplacd (x y)
        schar (string index)
        second (list)
        set (variable new-value)
        set-difference (list1 list2 &key key (test #'eql) (test-not nil))
        set-dispatch-macro-character (disp-char sub-char function
                                                &optional (rt *readtable*))
        set-exclusive-or (list1 list2 &key key (test #'eql) (test-not nil))
        set-macro-character (char function
                                  &optional
                                  (non-terminatingp nil)
                                  (rt *readtable*))
        setq (&rest stuff)
        seventh (list)
        sixth (list)
        special-operator-p (symbol)
        standard-char-p (char)
        stream-element-type (stream)
        streamp (stream)
        string (x)
        string-downcase (string &key (start 0) end)
        string-equal (string1 string2 &key (start1 0) end1 (start2 0) end2)
        string-upcase (string &key (start 0) end)
        string= (string1 string2 &key (start1 0) end1 (start2 0) end2)
        stringp (object)
        subseq (sequence start &optional end)
        subsetp (list1 list2 &key key (test #'eql) (test-not nil))
        sxhash (s-expr)
        symbol-function (variable)
        symbol-name (variable)
        symbol-package (variable)
        symbol-plist (variable)
        symbol-value (variable)
        symbolp (object)
        tailp (object list)
        tenth (list)
        terpri (&optional (stream *standard-output*))
        third (list)
        truncate (number &optional (divisor 1))
        type-of (object)
        union (list1 list2 &key key (test #'eql) (test-not nil))
        unread-char (character &optional (stream *standard-input*))
        upper-case-p (char)
        use-package (packages-to-use &optional (package *package*))
        values (&rest values)
        values-list (list)
        vector (&rest objects)
        vectorp (object)
        warn (datum &rest arguments)
        write-char (character &optional (stream *standard-output*))
        write-string (string &optional (stream *standard-output*)
                             &key (start 0) end)
        zerop (number)

Other operations supported by the compiler but not by the runtime
system:

        and (&rest forms)       macroexpands into if
        block (block-name &rest body-forms)
        cond (&rest clauses)    macroexpands into if
        decf
        defmacro
        defstruct
        do              macroexpands into let/block/tagbody
        do*             macroexpands into let*/block/tagbody
        dolist          macroexpands into let/block/tagbody
        dotimes         macroexpands into let/block/tagbody
        eval-when (situations &rest forms)
        flet (function-bindings &rest body-forms)
        go (tag)
        if (test eval-if-true eval-if-false)
        labels (function-bindings &rest body-forms)
        let (bindings &rest body-forms)
        let* (bindings &rest body-forms)
        multiple-value-bind (varlist value-form &body body)
        multiple-value-call (&rest stuff)
        multiple-value-list     macroexpands into multiple-value-call
        multiple-value-prog1 (&rest stuff)
        multiple-value-setq (varlist value-form)
        not (thing)
        nth-value (&rest args)
        or (&rest forms)        macroexpands into if
        prog            macroexpands into let/block/tagbody
        prog*           macroexpands into let*/block/tagbody
        prog1           macroexpands into let
        prog2           macroexpands into let
        return (values)
        return-from (tag values)
        svref (simple-vector index)
        tagbody (&rest stuff)
        the (&rest stuff)
        throw (&rest stuff)
        typep (object type &optional environment)
        unless          macroexpands into if
        unwind-protect (&rest stuff)
        when            macroexpands into if

These are mostly special forms and macros that require ad-hoc evaluation
and/or extra lexical analysis.  They could be implemented as part of the
hand-written evaluator, but that would involve some duplication of code;
better to wait until the compiler lexical analyzer can be ported, and
use that (if not the full compiler).

Reply via email to