+;;; lispstrack.lisp ---
+
+;; Copyright (C) 2012 David Vazquez
+;; Copyright (C) 2012 Raimon Grau
+
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; 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 the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; This code is executed when lispstrack compiles this file
+;;; itself. The compiler provides compilation of some special forms,
+;;; as well as funcalls and macroexpansion, but no functions. So, we
+;;; define the Lisp world from scratch. This code has to define enough
+;;; language to the compiler to be able to run.
+#+lispstrack
+(progn
+ (eval-when-compile
+ (%compile-defmacro 'defmacro
+ '(lambda (name args &rest body)
+ `(eval-when-compile
+ (%compile-defmacro ',name '(lambda ,args ,@body))))))
+
+ (defmacro %defvar (name value)
+ `(progn
+ (eval-when-compile
+ (%compile-defvar ',name))
+ (setq ,name ,value)))
+
+ (defmacro defvar (name value)
+ `(%defvar ,name ,value))
+
+ (defmacro %defun (name args &rest body)
+ `(progn
+ (eval-when-compile
+ (%compile-defun ',name))
+ (fsetq ,name (lambda ,args ,@body))))
+
+ (defmacro defun (name args &rest body)
+ `(%defun ,name ,args ,@body))
+
+ (defvar *package* (new))
+
+ (defvar nil (make-symbol "NIL"))
+ (set *package* "NIL" nil)
+
+ (defvar t (make-symbol "T"))
+ (set *package* "T" t)
+
+ (defun internp (name)
+ (in name *package*))
+
+ (defun intern (name)
+ (if (internp name)
+ (get *package* name)
+ (set *package* name (make-symbol name))))
+
+ (defun find-symbol (name)
+ (get *package* name))
+
+ (defmacro when (condition &rest body)
+ `(if ,condition (progn ,@body) nil))
+
+ (defmacro unless (condition &rest body)
+ `(if ,condition nil (progn ,@body)))
+
+ (defmacro dolist (iter &rest body)
+ (let ((var (first iter))
+ (g!list (make-symbol "LIST")))
+ `(let ((,g!list ,(second iter))
+ (,var nil))
+ (while ,g!list
+ (setq ,var (car ,g!list))
+ ,@body
+ (setq ,g!list (cdr ,g!list))))))
+
+ (defun = (x y) (= x y))
+ (defun + (x y) (+ x y))
+ (defun - (x y) (- x y))
+ (defun * (x y) (* x y))
+ (defun / (x y) (/ x y))
+ (defun 1+ (x) (+ x 1))
+ (defun 1- (x) (- x 1))
+ (defun zerop (x) (= x 0))
+ (defun not (x) (if x nil t))
+
+ (defun truncate (x y) (floor (/ x y)))
+
+ (defun cons (x y ) (cons x y))
+ (defun consp (x) (consp x))
+
+ (defun car (x) (car x))
+ (defun cdr (x) (cdr x))
+
+ (defun caar (x) (car (car x)))
+ (defun cadr (x) (car (cdr x)))
+ (defun cdar (x) (cdr (car x)))
+ (defun cddr (x) (cdr (cdr x)))
+ (defun caddr (x) (car (cdr (cdr x))))
+ (defun cdddr (x) (cdr (cdr (cdr x))))
+ (defun cadddr (x) (car (cdr (cdr (cdr x)))))
+
+ (defun first (x) (car x))
+ (defun second (x) (cadr x))
+ (defun third (x) (caddr x))
+ (defun fourth (x) (cadddr x))
+
+ (defun list (&rest args)
+ args)
+
+ (defun atom (x)
+ (not (consp x))))
+
+(defun ensure-list (x)
+ (if (listp x)
+ x
+ (list x)))
+