commit f25090d64f44c1349a200acff7648ff1676a64ff
Author: Andres Navarro <canavarro82@gmail.com>
Date: Tue, 15 Feb 2011 10:47:43 -0300
Initial commit. COPYRIGHT, README and Makefile. Object layout definitions and some tests.
Diffstat:
A | COPYRIGHT | | | 33 | +++++++++++++++++++++++++++++++++ |
A | README | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
A | src/Makefile | | | 34 | ++++++++++++++++++++++++++++++++++ |
A | src/klisp.c | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/klisp.h | | | 29 | +++++++++++++++++++++++++++++ |
A | src/kobject.h | | | 260 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 447 insertions(+), 0 deletions(-)
diff --git a/COPYRIGHT b/COPYRIGHT
@@ -0,0 +1,33 @@
+klisp License
+--------------
+
+klisp is licensed under the terms of the MIT license reproduced below.
+This means that klisp is free software and can be used for both academic
+and commercial purposes at absolutely no cost.
+
+===============================================================================
+
+Copyright (C) 2011 Andres Navarro
+Lua Parts: Copyright (C) 1994-2010 Lua.org, PUC-Rio.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+===============================================================================
+
+(end of COPYRIGHT)
diff --git a/README b/README
@@ -0,0 +1,41 @@
+README for klisp 0.1
+
+* What is klisp?
+ --------------
+ klisp is an open source interpreter for the Kernel Programming
+ Language. It aims at being comprehensive and robust as specified in
+ the "Revised(-1) Report on the Kernel Programming Language", but
+ that probably won't happen for some time. It is written in C99 under
+ the MIT license. It draws heavily from the Lua interpreter source
+ code & file structure.
+
+* What is the Kernel Programming Language?
+ ----------------------------------------
+ Kernel is a conservative, Scheme-like dialect of Lisp in which
+ everything is a first-class object. It was created by John N. Shutt.
+ You can read all about it at
+ http://web.cs.wpi.edu/~jshutt/kernel.html
+
+* Availability
+ ------------
+ klisp is freely available for both academic and commercial purposes.
+ See COPYRIGHT for details.
+ klisp can be downloaded at
+ http://www.bitbucket.org/AndresNavarro/klisp
+
+
+* Installation
+ ------------
+ klisp is implemented in C99, with some gcc extensions for packing
+ and alignment. It was developed and tested in x86 under Linux. In
+ time it will be written so as to be compiled under many different
+ platforms, but right now the author's efforts are directed towards
+ implementing functionality.
+
+* Origin
+ ------
+ klisp is developed by Andres Navarro, a Computer Science
+ undergraduate at Buenos Aires University (UBA). You can reach him at
+ <canavarro82@gmail.com>.
+
+(end of README)
diff --git a/src/Makefile b/src/Makefile
@@ -0,0 +1,34 @@
+CC=gcc
+CFLAGS=-O2 -std=c99 -Wall -m32 $(MYCFLAGS)
+RM=rm -f
+LIBS=-lm $(MYLIBS)
+
+MYCFLAGS=
+MYLDFLAGS=
+MYLIBS=
+
+CORE_O=
+
+KRN_T= klisp
+KRN_O= klisp.o
+
+ALL_T= $(KRN_T)
+ALL_O= $(CORE_O) $(KRN_O)
+
+default:
+ $(MAKE) all MYCFLAGS= MYLIBS=""
+
+all: $(ALL_T)
+
+o: $(ALL_O)
+
+$(KRN_T): $(ALL_O)
+ $(CC) -o $@ $(MYLDFLAGS) $(KRN_O) $(LIBS)
+
+clean:
+ $(RM) $(ALL_T) $(ALL_O)
+
+# list targets that do not create files (but not all makes understand .PHONY)
+.PHONY: all default o clean
+
+klisp.o: klisp.c klisp.h kobject.h
diff --git a/src/klisp.c b/src/klisp.c
@@ -0,0 +1,50 @@
+/*
+** klisp.c
+** Kernel stand-alone interpreter
+** See Copyright Notice in klisp.h
+*/
+
+#include <stdio.h>
+
+#include "kobject.h"
+
+int main(int argc, char *argv[])
+{
+ printf("Tests\n");
+
+ printf("\nVariables: \n");
+ printf("nil: %d\n", ttisnil(knil));
+ printf("ignore: %d\n", ttisignore(kignore));
+ printf("inert: %d\n", ttisinert(kinert));
+ printf("eof: %d\n", ttiseof(keof));
+ printf("true: %d\n", ttisboolean(ktrue));
+ printf("false: %d\n", ttisboolean(kfalse));
+
+
+ printf("\nConstants: \n");
+
+ printf("nil: %d\n", ttisnil(KNIL));
+ printf("ignore: %d\n", ttisignore(KIGNORE));
+ printf("inert: %d\n", ttisinert(KINERT));
+ printf("eof: %d\n", ttiseof(KEOF));
+ printf("true: %d\n", ttisboolean(KTRUE));
+ printf("false: %d\n", ttisboolean(KFALSE));
+
+ printf("int: %d\n",
+ ttisfixint(((TValue) {.tv = {.t = K_TAG_FIXINT, .v = { .i = 3}}})));
+ printf("double: %d\n", ttisdouble((TValue){.d = 1.0}));
+
+ printf("\nSwitch: \n");
+
+ printf("nil: %d\n", ttype(KNIL));
+ printf("ignore: %d\n", ttype(KIGNORE));
+ printf("inert: %d\n", ttype(KINERT));
+ printf("eof: %d\n", ttype(KEOF));
+ printf("true: %d\n", ttype(KTRUE));
+ printf("false: %d\n", ttype(KFALSE));
+ printf("int: %d\n",
+ ttype(((TValue) {.tv = {.t = K_TAG_FIXINT, .v = { .i = 3}}})));
+ printf("double: %d\n", ttype((TValue){.d = 1.0}));
+
+ return 0;
+}
diff --git a/src/klisp.h b/src/klisp.h
@@ -0,0 +1,29 @@
+/*
+** klisp.h
+** klisp - An interpreter for the Kernel Programming Language.
+** See Copyright Notice at the end of this file
+*/
+
+/******************************************************************************
+* Copyright (C) 2011 Andres Navarro. All rights reserved.
+* Lua parts: Copyright (C) 1994-2010 Lua.org, PUC-Rio. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
diff --git a/src/kobject.h b/src/kobject.h
@@ -0,0 +1,260 @@
+/*
+** kobject.h
+** Type definitions for Kernel Objects
+** See Copyright Notice in klisp.h
+*/
+
+/*
+** SOURCE NOTE: While the tagging system comes from Mozilla TraceMonkey,
+** o code from TraceMonkey was used.
+** The general structure, names and comments of this file follow the
+** scheme of Lua.
+*/
+
+/*
+** TODO:
+**
+** - #ifdef for little/big endian (for now, only little endian)
+** Should be careful with endianness of floating point numbers too,
+** as they don't necessarily match the endianness of other values
+** - #ifdef of 32/64 bits (for now, only 32 bits)
+** See TraceMonkey and _funderscore comments on reddit
+** for 64 bits implementation ideas
+** 47 bits should be enough for pointers (see Canonical Form Addresses)
+** - #ifdef for alignment/packing info (for now, only gcc)
+**
+*/
+
+#ifndef kobject_h
+#define kobject_h
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/*
+** Union of all collectible objects
+*/
+typedef union GCObject GCObject;
+
+/*
+** Common Header for all collectible objects (in macro form, to be
+** included in other objects)
+*/
+#define CommonHeader GCObject *next; uint16_t tt; uint16_t gct;
+
+
+/*
+** Common header in struct form
+*/
+typedef struct __attribute__ ((__packed__)) GCheader {
+ CommonHeader;
+} GCheader;
+
+/*
+** Tags: Types & Flags
+*/
+
+/*
+** Tagged values in 64 bits (for 32 bit systems)
+** NaN boxing: Values are encoded as double precision NaNs
+** There is one canonical NaN that is used through the interpreter
+** and all remaining NaNs are used to encode the rest of the types
+** (other than double)
+** Canonical NaN: (0)(111 1111 1111) 1000 0000 0000 0000 0000 32(0)
+** Infinities: s(111 1111 1111) 0000 0000 0000 0000 0000 32(0)
+** Tagged values: (0)(111 1111 1111) 1111 tttt tttt tttt tttt 32(v)
+** So all tags start with 0x7fff which leaves us 16 bits for the
+** tag proper.
+** The tag consist of an 8 bit flag part and an 8 bit type part
+** so tttt tttt tttt tttt is actually ffff ffff tttt tttt
+** This gives us 256 types and as many as 8 flags per type.
+*/
+
+/*
+** Macros for manipulating tags directly
+*/
+#define K_TAG_TAGGED 0x7fff0000
+#define K_TAG_BASE_MASK 0x7fff0000
+#define K_TAG_BASE_TYPE_MASK 0x7fff00ff
+
+#define K_TAG_FLAG(t) (((t) >> 8) & 0xff)
+#define K_TAG_TYPE(t) ((t) & 0xff)
+#define K_TAG_BASE(t) ((t) & K_TAG_BASE_MASK)
+#define K_TAG_BASE_TYPE(t) ((t) & K_TAG_BASE_TYPE_MASK)
+
+/*
+** Number types are first and ordered to allow easy switch statements
+** in arithmetic operators. The ones marked with (?) are still in
+** consideration for separate type tags.
+** They are in order: fixed width integers, arbitrary integers,
+** fixed width rationals, arbitrary rationals, exact infinities,
+** inexact reals (doubles) and infinities(?) and real with no primary
+** values(NaN)(?), bounded reals (heap allocated), inexact infinities(?),
+** real with no primary value (?),
+** complex numbers (heap allocated)
+*/
+
+/* LUA NOTE: In Lua the corresponding defines are in lua.h */
+#define K_TFIXINT 0
+#define K_TBIGINT 1
+#define K_TFIXRAT 2
+#define K_TBIGRAT 3
+#define K_TEINF 4
+#define K_TDOUBLE 5
+#define K_TBDOUBLE 6
+#define K_TIINF 7
+#define K_TRWNPN 8
+#define K_TCOMPLEX 9
+
+#define K_TNIL 20
+#define K_TIGNORE 21
+#define K_TINERT 22
+#define K_TEOF 23
+#define K_TBOOLEAN 24
+#define K_TCHAR 25
+
+#define K_TPAIR 30
+#define K_TSTRING 31
+#define K_TSYMBOL 32
+
+#define K_MAKE_VTAG(t) (K_TAG_TAGGED | t)
+
+/* TODO: For now we will only use fixints */
+#define K_TAG_FIXINT K_MAKE_VTAG(K_TFIXINT)
+
+#define K_TAG_NIL K_MAKE_VTAG(K_TNIL)
+#define K_TAG_IGNORE K_MAKE_VTAG(K_TIGNORE)
+#define K_TAG_INERT K_MAKE_VTAG(K_TINERT)
+#define K_TAG_EOF K_MAKE_VTAG(K_TEOF)
+#define K_TAG_BOOLEAN K_MAKE_VTAG(K_TBOOLEAN)
+#define K_TAG_CHAR K_MAKE_VTAG(K_TCHAR)
+
+#define K_TAG_PAIR K_MAKE_VTAG(K_TPAIR)
+#define K_TAG_STRING K_MAKE_VTAG(K_TSTRING)
+#define K_TAG_SYMBOL K_MAKE_VTAG(K_TSYMBOL)
+
+/*
+** Macros to test types
+*/
+
+/*
+** This is intended for use in switch statements
+** TODO: decide if inexact infinities and reals with no
+** primary values are included in K_TDOUBLE
+*/
+#define ttype(o) ({ TValue o_ = o; \
+ ttisdouble(o_)? K_TDOUBLE : ttype_(o_); })
+
+/*
+** This is intended for internal use below. DON'T USE OUTSIDE THIS FILE
+*/
+#define ttag(o) ((o).tv.t)
+#define ttype_(o) (K_TAG_TYPE(ttag(o)))
+#define tflag_(o) (K_TAG_FLAG(ttag(o)))
+#define tbasetype_(o) (K_TAG_BASE_TYPE(ttag(o)))
+
+/* Simple types (value in TValue struct) */
+#define ttisfixint(o) (tbasetype_(o) == K_TAG_FIXINT)
+#define ttisnil(o) (tbasetype_(o) == K_TAG_NIL)
+#define ttisignore(o) (tbasetype_(o) == K_TAG_IGNORE)
+#define ttisinert(o) (tbasetype_(o) == K_TAG_INERT)
+#define ttiseof(o) (tbasetype_(o) == K_TAG_EOF)
+#define ttisboolean(o) (tbasetype_(o) == K_TAG_BOOLEAN)
+#define ttischar(o) (tbasetype_(o) == K_TAG_CHAR)
+#define ttisdouble(o) ((ttag(o) & K_TAG_BASE_MASK) != K_TAG_TAGGED)
+
+/* Complex types (value in heap) */
+#define ttisstring(o) (tbasetype_(o) == K_TAG_STRING)
+#define ttissymbol(o) (tbasetype_(o) == K_TAG_SYMBOL)
+#define ttispair(o) (tbasetype_(o) == K_TAG_PAIR)
+
+
+/*
+** Union of all Kernel non heap-allocated values (except doubles)
+*/
+typedef union {
+ bool b;
+ int32_t i;
+ unsigned char ch;
+ GCObject *gc;
+ void *p;
+ /* ... */
+} Value;
+
+/*
+** All Kernel non heap-allocated values (except doubles) tagged
+*/
+typedef struct __attribute__ ((__packed__)) InnerTV {
+ uint32_t t;
+ Value v;
+} InnerTV;
+
+/*
+** Union of all Kernel non heap-allocated values
+*/
+typedef __attribute__((aligned (8))) union {
+ double d;
+ InnerTV tv;
+} TValue;
+
+/*
+** Individual heap-allocated values
+*/
+typedef struct __attribute__ ((__packed__)) {
+ CommonHeader;
+ TValue car;
+ TValue cdr;
+} Pair;
+
+typedef struct __attribute__ ((__packed__)) {
+ CommonHeader;
+ unsigned char b[]; // buffer
+} Symbol;
+
+typedef struct __attribute__ ((__packed__)) {
+ CommonHeader;
+ uint32_t size; // to allow embedded '\0'
+ unsigned char b[]; // buffer
+} String;
+
+/*
+** Union of all Kernel heap-allocated values
+*/
+
+/* LUA NOTE: In Lua the corresponding union is in lstate.h */
+union GCObject {
+ GCheader gch;
+ Pair pair;
+ Symbol sym;
+ String str;
+};
+
+
+/*
+** Some constants
+*/
+#define KNIL_ {.tv = {.t = K_TAG_NIL, .v = { .i = 0 }}}
+#define KINERT_ {.tv = {.t = K_TAG_INERT, .v = { .i = 0 }}}
+#define KIGNORE_ {.tv = {.t = K_TAG_IGNORE, .v = { .i = 0 }}}
+#define KEOF_ {.tv = {.t = K_TAG_EOF, .v = { .i = 0 }}}
+#define KTRUE_ {.tv = {.t = K_TAG_BOOLEAN, .v = { .b = true }}}
+#define KFALSE_ {.tv = {.t = K_TAG_BOOLEAN, .v = { .b = false }}}
+
+#define KNIL ((TValue) KNIL_)
+#define KINERT ((TValue) KINERT_)
+#define KIGNORE ((TValue) KIGNORE_)
+#define KEOF ((TValue) KEOF_)
+#define KTRUE ((TValue) KTRUE_)
+#define KFALSE ((TValue) KFALSE_)
+
+/*
+** The same constants as global const variables
+*/
+const TValue knil = KNIL_;
+const TValue kignore = KIGNORE_;
+const TValue kinert = KINERT_;
+const TValue keof = KEOF_;
+const TValue ktrue = KTRUE_;
+const TValue kfalse = KFALSE_;
+
+#endif