Common Lisp: Remove GNU CLISP specific implementation
authorIqbal Ansari <iqbalansari02@yahoo.com>
Fri, 18 Nov 2016 12:06:44 +0000 (17:36 +0530)
committerIqbal Ansari <iqbalansari02@yahoo.com>
Fri, 18 Nov 2016 17:19:24 +0000 (22:49 +0530)
26 files changed:
.travis.yml
Makefile
clisp/.dir-locals.el [deleted file]
clisp/Dockerfile [deleted file]
clisp/Makefile [deleted file]
clisp/README.md [deleted file]
clisp/core.lisp [deleted file]
clisp/dependencies.lisp [deleted file]
clisp/env.lisp [deleted file]
clisp/printer.lisp [deleted file]
clisp/reader.lisp [deleted file]
clisp/run [deleted file]
clisp/step0_repl.lisp [deleted file]
clisp/step1_read_print.lisp [deleted file]
clisp/step2_eval.lisp [deleted file]
clisp/step3_env.lisp [deleted file]
clisp/step4_if_fn_do.lisp [deleted file]
clisp/step5_tco.lisp [deleted file]
clisp/step6_file.lisp [deleted file]
clisp/step7_quote.lisp [deleted file]
clisp/step8_macros.lisp [deleted file]
clisp/step9_try.lisp [deleted file]
clisp/stepA_mal.lisp [deleted file]
clisp/tests/stepA_mal.mal [deleted file]
clisp/types.lisp [deleted file]
clisp/utils.lisp [deleted file]

index 94590b2..ad303b7 100644 (file)
@@ -14,7 +14,6 @@ matrix:
     - {env: IMPL=coffee,    services: [docker]}
     - {env: IMPL=cs,        services: [docker]}
     - {env: IMPL=chuck,     services: [docker]}
-    - {env: IMPL=clisp,     services: [docker]}
     - {env: IMPL=clojure,   services: [docker]}
     - {env: IMPL=common-lisp, services: [docker]}
     - {env: IMPL=crystal,   services: [docker]}
index 250b25c..a3a735a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -77,7 +77,7 @@ DOCKERIZE =
 # Settings
 #
 
-IMPLS = ada awk bash basic c d chuck clojure coffee clisp common-lisp cpp crystal cs dart \
+IMPLS = ada awk bash basic c d chuck clojure coffee common-lisp cpp crystal cs dart \
        erlang elisp elixir es6 factor forth fsharp go groovy guile haskell \
        haxe io java julia js kotlin logo lua make mal ocaml matlab miniMAL \
        nim objc objpascal perl perl6 php pil plpgsql plsql powershell ps \
@@ -153,7 +153,6 @@ d_STEP_TO_PROG =       d/$($(1))
 chuck_STEP_TO_PROG =   chuck/$($(1)).ck
 clojure_STEP_TO_PROG = clojure/target/$($(1)).jar
 coffee_STEP_TO_PROG =  coffee/$($(1)).coffee
-clisp_STEP_TO_PROG = clisp/$($(1)).fas
 common-lisp_STEP_TO_PROG =  common-lisp/$($(1))
 cpp_STEP_TO_PROG =     cpp/$($(1))
 crystal_STEP_TO_PROG = crystal/$($(1))
diff --git a/clisp/.dir-locals.el b/clisp/.dir-locals.el
deleted file mode 100644 (file)
index 96c665e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-((lisp-mode
-  (inferior-lisp-program . "clisp")))
\ No newline at end of file
diff --git a/clisp/Dockerfile b/clisp/Dockerfile
deleted file mode 100644 (file)
index 711244b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM ubuntu:vivid
-MAINTAINER Joel Martin <github@martintribe.org>
-
-##########################################################
-# General requirements for testing or common across many
-# implementations
-##########################################################
-
-RUN apt-get -y update
-
-# Required for running tests
-RUN apt-get -y install make python
-
-# Some typical implementation and test requirements
-RUN apt-get -y install curl libreadline-dev libedit-dev
-
-RUN mkdir -p /mal
-WORKDIR /mal
-
-##########################################################
-# Specific implementation requirements
-##########################################################
-
-# Install clisp
-RUN apt-get -y install clisp
diff --git a/clisp/Makefile b/clisp/Makefile
deleted file mode 100644 (file)
index 1f35911..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-SOURCES_BASE = utils.lisp types.lisp reader.lisp printer.lisp
-SOURCES_LISP = env.lisp core.lisp stepA_mal.lisp
-SOURCES = $(SOURCES_BASE) $(SOURCES_LISP)
-
-all : stepA_mal.fas
-
-.PHONY: stats
-
-step%.fas : step%.lisp dependencies.lisp utils.lisp types.lisp env.lisp printer.lisp reader.lisp core.lisp
-       clisp -q -c $<
-
-clean:
-       rm *.fas *.lib
-
-stats: $(SOURCES)
-       @wc $^
-       @printf "%5s %5s %5s %s\n" `grep -E "^[[:space:]]*;|^[[:space:]]*$$" $^ | wc` "[comments/blanks]"
-
-stats-lisp: $(SOURCES_LISP)
-       @wc $^
-       @printf "%5s %5s %5s %s\n" `grep -E "^[[:space:]]*;|^[[:space:]]*$$" $^ | wc` "[comments/blanks]"
diff --git a/clisp/README.md b/clisp/README.md
deleted file mode 100644 (file)
index 120e3d6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Implementation of MAL in Common Lisp
-
-- This implementation is not portable and works only with CLISP
diff --git a/clisp/core.lisp b/clisp/core.lisp
deleted file mode 100644 (file)
index 5ac7cfd..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-(defpackage :core
-  (:use :common-lisp :types :reader :printer)
-  (:export :ns))
-
-(in-package :core)
-
-(define-condition index-error (types:mal-runtime-exception)
-  ((size :initarg :size :reader size)
-   (index :initarg :index :reader index)
-   (sequence :initarg :sequence :reader sequence))
-  (:report (lambda (condition stream)
-             (format stream
-                     "Index out of range (~a), length is ~a but index given was ~a"
-                     (printer:pr-str (sequence condition))
-                     (size condition)
-                     (index condition)))))
-
-(defun get-file-contents (filename)
-  (with-open-file (stream filename)
-    (let ((data (make-string (file-length stream))))
-      (read-sequence data stream)
-      data)))
-
-(defmacro wrap-boolean (form)
-  `(if ,form
-       types:mal-true
-       types:mal-false))
-
-(defvar ns
-  (list
-   (cons (types:make-mal-symbol "+")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values '+ value1 value2))))
-
-   (cons (types:make-mal-symbol "-")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values '- value1 value2))))
-
-   (cons (types:make-mal-symbol "*")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values '* value1 value2))))
-
-   (cons (types:make-mal-symbol "/")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:make-mal-number (floor (/ (types:mal-data-value value1)
-                                                                       (types:mal-data-value value2)))))))
-
-   (cons (types:make-mal-symbol "prn")
-         (types:make-mal-builtin-fn (lambda (&rest strings)
-                                      (write-line (format nil
-                                                          "~{~a~^ ~}"
-                                                          (mapcar (lambda (string) (printer:pr-str string t))
-                                                                  strings)))
-                                      types:mal-nil)))
-
-   (cons (types:make-mal-symbol "println")
-         (types:make-mal-builtin-fn (lambda (&rest strings)
-                                      (write-line (format nil
-                                                          "~{~a~^ ~}"
-                                                          (mapcar (lambda (string) (printer:pr-str string nil))
-                                                                  strings)))
-                                      types:mal-nil)))
-
-   (cons (types:make-mal-symbol "pr-str")
-         (types:make-mal-builtin-fn (lambda (&rest strings)
-                                      (types:make-mal-string (format nil
-                                                                     "~{~a~^ ~}"
-                                                                     (mapcar (lambda (string) (printer:pr-str string t))
-                                                                             strings))))))
-
-   (cons (types:make-mal-symbol "str")
-         (types:make-mal-builtin-fn (lambda (&rest strings)
-                                      (types:make-mal-string (format nil
-                                                                     "~{~a~}"
-                                                                     (mapcar (lambda (string) (printer:pr-str string nil))
-                                                                             strings))))))
-
-   (cons (types:make-mal-symbol "list")
-         (types:make-mal-builtin-fn (lambda (&rest values)
-                                      (make-mal-list values))))
-
-   (cons (types:make-mal-symbol "list?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (or (types:mal-nil-p value)
-                                                        (types:mal-list-p value))))))
-
-   (cons (types:make-mal-symbol "empty?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (zerop (length (mal-data-value value)))))))
-
-   (cons (types:make-mal-symbol "count")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (types:apply-unwrapped-values 'length value))))
-
-   (cons (types:make-mal-symbol "=")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (wrap-boolean (types:mal-value= value1 value2)))))
-
-   (cons (types:make-mal-symbol "<")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values-prefer-bool '<
-                                                                                value1
-                                                                                value2))))
-
-   (cons (types:make-mal-symbol ">")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values-prefer-bool '>
-                                                                                value1
-                                                                                value2))))
-
-   (cons (types:make-mal-symbol "<=")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values-prefer-bool '<=
-                                                                                value1
-                                                                                value2))))
-
-   (cons (types:make-mal-symbol ">=")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (types:apply-unwrapped-values-prefer-bool '>=
-                                                                                value1
-                                                                                value2))))
-
-   (cons (types:make-mal-symbol "read-string")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (reader:read-str (types:mal-data-value value)))))
-
-   (cons (types:make-mal-symbol "slurp")
-         (types:make-mal-builtin-fn (lambda (filename)
-                                      (types:apply-unwrapped-values 'get-file-contents filename))))
-
-   (cons (types:make-mal-symbol "atom")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (types:make-mal-atom value))))
-
-   (cons (types:make-mal-symbol "atom?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-atom-p value)))))
-
-   (cons (types:make-mal-symbol "deref")
-         (types:make-mal-builtin-fn (lambda (atom)
-                                      (types:mal-data-value atom))))
-
-   (cons (types:make-mal-symbol "reset!")
-         (types:make-mal-builtin-fn (lambda (atom value)
-                                      (setf (types:mal-data-value atom) value))))
-
-   (cons (types:make-mal-symbol "swap!")
-         (types:make-mal-builtin-fn (lambda (atom fn &rest args)
-                                      (setf (types:mal-data-value atom)
-                                            (apply (mal-data-value fn)
-                                                   (append (list (types:mal-data-value atom))
-                                                           args))))))
-
-   (cons (types:make-mal-symbol "cons")
-         (types:make-mal-builtin-fn (lambda (element list)
-                                      (types:make-mal-list (cons element
-                                                                 (map 'list
-                                                                      #'identity
-                                                                      (mal-data-value list)))))))
-
-   (cons (types:make-mal-symbol "concat")
-         (types:make-mal-builtin-fn (lambda (&rest lists)
-                                      (types:make-mal-list (apply #'concatenate
-                                                                  'list
-                                                                  (mapcar #'types:mal-data-value lists))))))
-
-
-   (cons (types:make-mal-symbol "nth")
-         (types:make-mal-builtin-fn (lambda (sequence index)
-                                      (or (nth (mal-data-value index)
-                                               (map 'list #'identity (mal-data-value sequence)))
-                                          (error 'index-error
-                                                 :size (length (mal-data-value sequence))
-                                                 :index (mal-data-value index)
-                                                 :sequence sequence)))))
-
-   (cons (types:make-mal-symbol "first")
-         (types:make-mal-builtin-fn (lambda (sequence)
-                                      (or (first (map 'list #'identity (mal-data-value sequence)))
-                                          types:mal-nil))))
-
-   (cons (types:make-mal-symbol "rest")
-         (types:make-mal-builtin-fn (lambda (sequence)
-                                      (types:make-mal-list (rest (map 'list
-                                                                      #'identity
-                                                                      (mal-data-value sequence)))))))
-
-   (cons (types:make-mal-symbol "throw")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (error 'types:mal-user-exception
-                                             :data value))))
-
-   (cons (types:make-mal-symbol "apply")
-         (types:make-mal-builtin-fn (lambda (fn &rest values)
-                                      (let ((final-arg (map 'list
-                                                            #'identity
-                                                            (types:mal-data-value (car (last values)))))
-                                            (butlast-args (butlast values)))
-                                        (apply (types:mal-data-value fn)
-                                               (append butlast-args final-arg))))))
-
-   (cons (types:make-mal-symbol "map")
-         (types:make-mal-builtin-fn (lambda (fn sequence)
-                                      (let ((applicants (map 'list
-                                                             #'identity
-                                                             (types:mal-data-value sequence))))
-                                        (types:make-mal-list (mapcar (types:mal-data-value fn)
-                                                                     applicants))))))
-
-   (cons (types:make-mal-symbol "nil?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-nil-p value)))))
-
-   (cons (types:make-mal-symbol "true?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (and (types:mal-boolean-p value)
-                                                                   (types:mal-data-value value))))))
-
-   (cons (types:make-mal-symbol "false?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (and (types:mal-boolean-p value)
-                                                                   (not (types:mal-data-value value)))))))
-
-   (cons (types:make-mal-symbol "symbol?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-symbol-p value)))))
-
-   (cons (types:make-mal-symbol "symbol")
-         (types:make-mal-builtin-fn (lambda (string)
-                                      (types:make-mal-symbol (types:mal-data-value string)))))
-
-   (cons (types:make-mal-symbol "keyword")
-         (types:make-mal-builtin-fn (lambda (keyword)
-                                      (if (types:mal-keyword-p keyword)
-                                          keyword
-                                          (types:make-mal-keyword (format nil ":~a" (types:mal-data-value keyword)))))))
-
-   (cons (types:make-mal-symbol "keyword?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-keyword-p value)))))
-
-   (cons (types:make-mal-symbol "vector")
-         (types:make-mal-builtin-fn (lambda (&rest elements)
-                                      (types:make-mal-vector (map 'vector #'identity elements)))))
-
-   (cons (types:make-mal-symbol "vector?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-vector-p value)))))
-
-   (cons (types:make-mal-symbol "hash-map")
-         (types:make-mal-builtin-fn (lambda (&rest elements)
-                                      (let ((hash-map (make-hash-table :test 'types:mal-value=)))
-                                        (loop
-                                           for (key value) on elements
-                                           by #'cddr
-                                           do (setf (gethash key hash-map) value))
-                                        (types:make-mal-hash-map hash-map)))))
-
-   (cons (types:make-mal-symbol "map?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-hash-map-p value)))))
-
-   (cons (types:make-mal-symbol "assoc")
-         (types:make-mal-builtin-fn (lambda (hash-map &rest elements)
-                                      (let ((hash-map-value (types:mal-data-value hash-map))
-                                            (new-hash-map (make-hash-table :test 'types:mal-value=)))
-
-                                        (loop
-                                           for key being the hash-keys of hash-map-value
-                                           do (setf (gethash key new-hash-map)
-                                                    (gethash key hash-map-value)))
-
-                                        (loop
-                                           for (key value) on elements
-                                           by #'cddr
-                                           do (setf (gethash key new-hash-map) value))
-
-                                        (types:make-mal-hash-map new-hash-map)))))
-
-   (cons (types:make-mal-symbol "dissoc")
-         (types:make-mal-builtin-fn (lambda (hash-map &rest elements)
-                                      (let ((hash-map-value (types:mal-data-value hash-map))
-                                            (new-hash-map (make-hash-table :test 'types:mal-value=)))
-
-                                        (loop
-                                           for key being the hash-keys of hash-map-value
-                                           do (when (not (member key elements :test #'types:mal-value=))
-                                                (setf (gethash key new-hash-map)
-                                                      (gethash key hash-map-value))))
-
-                                        (types:make-mal-hash-map new-hash-map)))))
-
-   (cons (types:make-mal-symbol "get")
-         (types:make-mal-builtin-fn (lambda (hash-map key)
-                                      (or (and (types:mal-hash-map-p hash-map)
-                                               (gethash key (types:mal-data-value hash-map)))
-                                          types:mal-nil))))
-
-   (cons (types:make-mal-symbol "contains?")
-         (types:make-mal-builtin-fn (lambda (hash-map key)
-                                      (if (gethash key (types:mal-data-value hash-map))
-                                          types:mal-true
-                                          types:mal-false))))
-
-   (cons (types:make-mal-symbol "keys")
-         (types:make-mal-builtin-fn (lambda (hash-map)
-                                      (let ((hash-map-value (types:mal-data-value hash-map)))
-                                        (types:make-mal-list (loop
-                                                                for key being the hash-keys of hash-map-value
-                                                                collect key))))))
-
-   (cons (types:make-mal-symbol "vals")
-         (types:make-mal-builtin-fn (lambda (hash-map)
-                                      (let ((hash-map-value (types:mal-data-value hash-map)))
-                                        (types:make-mal-list (loop
-                                                                for key being the hash-keys of hash-map-value
-                                                                collect (gethash key hash-map-value)))))))
-
-   (cons (types:make-mal-symbol "sequential?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (or (types:mal-vector-p value)
-                                                        (types:mal-list-p value))))))
-
-   (cons (types:make-mal-symbol "readline")
-         (types:make-mal-builtin-fn (lambda (prompt)
-                                      (format *standard-output* (types:mal-data-value prompt))
-                                      (force-output *standard-output*)
-                                      (types:wrap-value (read-line *standard-input* nil)))))
-
-   (cons (types:make-mal-symbol "string?")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (wrap-boolean (types:mal-string-p value)))))
-
-   (cons (types:make-mal-symbol "time-ms")
-         (types:make-mal-builtin-fn (lambda ()
-
-                                      (types:make-mal-number (floor (/ (get-internal-real-time)
-                                                                       (/ internal-time-units-per-second
-                                                                          1000)))))))
-
-   (cons (types:make-mal-symbol "conj")
-         (types:make-mal-builtin-fn (lambda (value &rest elements)
-                                      (cond ((types:mal-list-p value)
-                                             (types:make-mal-list (append (nreverse elements)
-                                                                          (types:mal-data-value value))))
-                                            ((types:mal-vector-p value)
-                                             (types:make-mal-vector (concatenate 'vector
-                                                                                 (types:mal-data-value value)
-                                                                                 elements)))
-                                            (t (error 'types:mal-user-exception))))))
-   (cons (types:make-mal-symbol "seq")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (if (zerop (length (types:mal-data-value value)))
-                                          types:mal-nil
-                                          (cond ((types:mal-list-p value)
-                                                 value)
-                                                ((types:mal-vector-p value)
-                                                 (types:make-mal-list (map 'list
-                                                                           #'identity
-                                                                           (types:mal-data-value value))))
-                                                ((types:mal-string-p value)
-                                                 (types:make-mal-list  (map 'list
-                                                                            (lambda (char)
-                                                                              (types:make-mal-string (make-string 1 :initial-element char)))
-                                                                            (types:mal-data-value value))))
-                                                (t (error 'types:mal-user-exception)))))))
-
-   (cons (types:make-mal-symbol "with-meta")
-         (types:make-mal-builtin-fn (lambda (value meta)
-                                      (funcall (switch-mal-type value
-                                                 (types:string #'types:make-mal-string)
-                                                 (types:symbol #'types:make-mal-symbol)
-                                                 (types:list #'types:make-mal-list)
-                                                 (types:vector #'types:make-mal-vector)
-                                                 (types:hash-map #'types:make-mal-hash-map)
-                                                 (types:fn #'types:make-mal-fn)
-                                                 (types:builtin-fn #'types:make-mal-builtin-fn))
-                                               (types:mal-data-value value)
-                                               :meta meta
-                                               :attrs (types:mal-data-attrs value)))))
-
-   (cons (types:make-mal-symbol "meta")
-         (types:make-mal-builtin-fn (lambda (value)
-                                      (or (types:mal-data-meta value)
-                                          types:mal-nil))))
-
-   ;; Since a nil in clisp may mean an empty list or boolean false or simply nil, the
-   ;; caller can specify the preferred type while evaluating an expression
-   (cons (types:make-mal-symbol "clisp-eval")
-         (types:make-mal-builtin-fn (lambda (code &optional booleanp listp)
-                                      (types:wrap-value (eval (read-from-string (types:mal-data-value code)))
-                                                        :booleanp (and booleanp (types:mal-data-value booleanp))
-                                                        :listp (and listp (types:mal-data-value listp))))))
-
-   (cons (types:make-mal-symbol "define-builtin")
-         (types:make-mal-builtin-fn (lambda (arglist &rest body)
-                                      (let* ((func-args (types:unwrap-value arglist))
-                                             (func-body (mapcar #'types:unwrap-value body))
-                                             (func (eval `(lambda ,func-args ,@func-body))))
-                                        (types:make-mal-builtin-fn (lambda (&rest args)
-                                                                     (types:wrap-value (apply func
-                                                                                              (mapcar #'types:unwrap-value args)))))))))))
diff --git a/clisp/dependencies.lisp b/clisp/dependencies.lisp
deleted file mode 100644 (file)
index 4d82225..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-(require "utils")
-(require "types")
-(require "env")
-(require "reader")
-(require "printer")
-(require "core")
diff --git a/clisp/env.lisp b/clisp/env.lisp
deleted file mode 100644 (file)
index 74604d2..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-(defpackage :env
-  (:use :common-lisp :types)
-  (:export :undefined-symbol
-           :mal-env
-           :create-mal-env
-           :get-env
-           :find-env
-           :set-env))
-
-(in-package :env)
-
-(define-condition undefined-symbol (types:mal-runtime-exception)
-  ((symbol :initarg :symbol :reader symbol))
-  (:report (lambda (condition stream)
-             (format stream
-                     "'~a' not found"
-                     (symbol condition)))))
-
-(define-condition arity-mismatch (types:mal-runtime-exception)
-  ((required :initarg :required :reader required)
-   (provided :initarg :provided :reader provided))
-  (:report (lambda (condition stream)
-             (format stream
-                     "Unexpected number of arguments provided, expected ~a, got ~a"
-                     (required condition)
-                     (provided condition)))))
-
-(defstruct mal-env
-  (bindings (make-hash-table :test 'equal) :read-only t)
-  (parent nil :read-only t))
-
-(defun find-env (env symbol)
-  (let ((value (gethash (types:mal-data-value symbol)
-                        (mal-env-bindings env)))
-        (parent (mal-env-parent env)))
-    (cond
-      (value value)
-      (parent (find-env parent symbol))
-      (t nil))))
-
-(defun get-env (env symbol)
-  (let ((value (find-env env symbol)))
-    (if value
-        value
-        (error 'undefined-symbol
-               :symbol (format nil "~a" (types:mal-data-value symbol))))))
-
-(defun set-env (env symbol value)
-  (setf (gethash (types:mal-data-value symbol)
-                 (mal-env-bindings env))
-        value))
-
-(defun create-mal-env (&key (parent nil) (binds nil) (exprs nil))
-  (let ((varidiac-position (position (types:make-mal-symbol "&")
-                                     binds
-                                     :test #'mal-value=)))
-    (when varidiac-position
-      (setf (subseq binds varidiac-position (length binds))
-            (list (nth (1+ varidiac-position) binds)))
-      (setf binds (subseq binds 0 (1+ varidiac-position)))
-
-      (let* ((no-of-args (length exprs))
-             ;; There are enough arguments for variadic operator
-             ;; to consume
-             (rest-args (cond ((>= no-of-args (1+ varidiac-position))
-                               (make-mal-list (subseq exprs
-                                                      varidiac-position
-                                                      (length exprs))))
-                              ;; There are enough parameters to satisfy the
-                              ;; normal arguments, set rest-args to a nil value
-                              ((= no-of-args varidiac-position)
-                               types:mal-nil))))
-        (handler-case
-            (setf exprs (concatenate 'list
-                                     (subseq exprs 0 varidiac-position)
-                                     (list rest-args)))
-          (simple-type-error (condition)
-            (error 'arity-mismatch
-                   :required (length binds)
-                   :provided (length exprs))))))
-
-    (when (not (= (length binds) (length exprs)))
-      (error 'arity-mismatch
-             :required (length binds)
-             :provided (length exprs)))
-
-    (let ((arg-params (map 'list #'cons binds exprs))
-          (bindings (make-hash-table :test 'equal)))
-      (dolist (arg-param arg-params)
-        (setf (gethash (types:mal-data-value (car arg-param)) bindings)
-              (cdr arg-param)))
-      (make-mal-env :bindings bindings :parent parent))))
diff --git a/clisp/printer.lisp b/clisp/printer.lisp
deleted file mode 100644 (file)
index afc05dc..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-(defpackage :printer
-  (:use :common-lisp :utils :types)
-  (:export :pr-str))
-
-(in-package :printer)
-
-(defun pr-mal-sequence (start-delimiter sequence end-delimiter &optional (print-readably t))
-  (concatenate 'string
-               start-delimiter
-               (format nil
-                       "~{~a~^ ~}"
-                       (map 'list (lambda (value)
-                                    (pr-str value print-readably))
-                            (types:mal-data-value sequence)))
-               end-delimiter))
-
-(defun pr-mal-hash-map (hash-map &optional (print-readably t))
-  (let ((hash-map-value (types:mal-data-value hash-map)))
-    (concatenate 'string
-                 "{"
-                 (format nil
-                         "~{~a~^ ~}"
-                         (let (entries)
-                           (maphash (lambda (key value)
-                                      (push (format nil
-                                                    "~a ~a"
-                                                    (pr-str key print-readably)
-                                                    (pr-str value print-readably))
-                                            entries))
-                                    hash-map-value)
-                           (nreverse entries)))
-                 "}")))
-
-(defun pr-string (ast &optional (print-readably t))
-  (if print-readably
-      (utils:replace-all (prin1-to-string (types:mal-data-value ast))
-                         "
-"
-                         "\\n")
-      (types:mal-data-value ast)))
-
-(defun pr-str (ast &optional (print-readably t))
-  (when ast
-    (switch-mal-type ast
-      (types:number (format nil "~d" (types:mal-data-value ast)))
-      (types:boolean (if (types:mal-data-value ast) "true" "false"))
-      (types:nil "nil")
-      (types:string (pr-string ast print-readably))
-      (types:symbol (types:mal-data-value ast))
-      (types:keyword (types:mal-data-value ast))
-      (types:list (pr-mal-sequence "(" ast ")" print-readably))
-      (types:vector (pr-mal-sequence "[" ast "]" print-readably))
-      (types:hash-map (pr-mal-hash-map ast print-readably))
-      (types:atom (format nil "(atom ~a)" (pr-str (types:mal-data-value ast))))
-      (types:fn "#<function>")
-      (types:builtin-fn "#<builtin function>"))))
diff --git a/clisp/reader.lisp b/clisp/reader.lisp
deleted file mode 100644 (file)
index 5e9e7b6..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-(defpackage :reader
-  (:use :common-lisp :regexp :utils :types)
-  (:export :read-str
-           :eof))
-
-(in-package :reader)
-
-(defvar *string-re* (regexp:regexp-compile "^\"\\(\\\\\\(.\\|
-\\)\\|[^\"\\]\\)*\"$")
-  "Regular expression to match string")
-
-(defvar *digit-re* (regexp:regexp-compile "^\\(-\\|+\\)\\?[[:digit:]]\\+$")
-  "Regular expression to match digits")
-
-(defvar *tokenizer-re* (regexp:regexp-compile "[[:space:],]*\\(~@\\|[][{}()~`'^@]\\|\"\\(\\\\\\(.\\|
-\\)\\|[^\"\\]\\)*\"\\?\\|;[^
-]*\\|[^][[:space:]~{}()@^`'\";]*\\)")
-  "Regular expression to match LISP code")
-
-(define-condition eof (types:mal-error)
-  ((context :initarg :context :reader context))
-  (:report (lambda (condition stream)
-             (format stream
-                     "EOF encountered while reading ~a"
-                     (context condition)))))
-
-(defun parse-string (token)
-  (if (and (> (length token) 1)
-           (regexp:regexp-exec *string-re* token))
-      (progn
-        (read-from-string (utils:replace-all token
-                                             "\\n"
-                                             "
-")))
-      ;; A bit inaccurate
-      (error 'eof
-             :context "string")))
-
-;; Useful to debug regexps
-(defun test-re (re string)
-  (let ((match (regexp:match re string)))
-    (when match
-      (regexp:match-string string match))))
-
-(defun test-tokenizer (re string)
-  (let ((*tokenizer-re* re))
-    (tokenize string)))
-
-(defun tokenize (string)
-  (let (tokens)
-    (do* ((start 0)
-          (end (length string))
-          (match t))
-         ((not match))
-      (setf match (when (< start end)
-                    (nth-value 1
-                               (regexp:regexp-exec *tokenizer-re* string :start start))))
-      (when match
-        (setf start (regexp:match-end match))
-        (let ((token (string-trim "," (regexp:match-string string match))))
-          (unless (or (zerop (length token))
-                      (char= (char token 0) #\;))
-            (push token tokens)))))
-    (nreverse tokens)))
-
-(defstruct (token-reader)
-  (tokens nil))
-
-(defun peek (reader)
-  (car (token-reader-tokens reader)))
-
-(defun next (reader)
-  (pop (token-reader-tokens reader)))
-
-(defun consume (reader)
-  (pop (token-reader-tokens reader))
-  reader)
-
-(defun read-str (string)
-  (read-form (make-token-reader :tokens (tokenize string))))
-
-(defun read-form (reader)
-  (let ((token (peek reader)))
-    (cond
-      ((null token) nil)
-      ((string= token "(") (make-mal-list (read-mal-sequence reader
-                                                             ")"
-                                                             'list)))
-      ((string= token "[") (make-mal-vector (read-mal-sequence reader
-                                                               "]"
-                                                               'vector)))
-      ((string= token "{") (make-mal-hash-map (read-hash-map reader)))
-      ((string= token "^") (read-form-with-meta reader))
-      ((member token '("'" "`" "~" "~@" "@") :test #'string= ) (expand-quote reader))
-      (t (read-atom reader)))))
-
-(defun read-form-with-meta (reader)
-  (consume reader)
-  (let ((meta (read-form reader))
-        (value (read-form reader)))
-
-    (when (or (null meta)
-              (null value))
-      (error 'eof
-             :context "object metadata"))
-
-    (make-mal-list (list (make-mal-symbol "with-meta") value meta))))
-
-(defun expand-quote (reader)
-  (let ((quote (next reader)))
-    (make-mal-list (list (make-mal-symbol (cond
-                                            ((string= quote "'") "quote")
-                                            ((string= quote "`") "quasiquote")
-                                            ((string= quote "~") "unquote")
-                                            ((string= quote "~@") "splice-unquote")
-                                            ((string= quote "@") "deref")))
-                         (read-form reader)))))
-
-(defun read-mal-sequence (reader &optional (delimiter ")") (constructor 'list))
-  ;; Consume the opening brace
-  (consume reader)
-  (let (forms)
-    (loop
-       for token = (peek reader)
-       while (cond
-               ((null token) (error 'eof
-                                    :context (if (string= delimiter ")")
-                                                 "list"
-                                                 "vector")))
-               ((string= token delimiter) (return))
-               (t (push (read-form reader) forms))))
-    ;; Consume the closing brace
-    (consume reader)
-    (apply constructor (nreverse forms))))
-
-(defun read-hash-map (reader)
-  ;; Consume the open brace
-  (consume reader)
-  (let (forms)
-    (loop
-       for token = (peek reader)
-       while (cond
-               ((null token) (error 'eof
-                                    :context "hash-map"))
-               ((string= token "}") (return))
-               (t (let ((key (read-form reader))
-                        (value (read-form reader)))
-                    (if (null value)
-                        (error 'eof
-                               :context "hash-map")
-                        (push (cons key value) forms))))))
-    ;; Consume the closing brace
-    (consume reader)
-    (make-hash-table :test 'types:mal-value=
-                     :initial-contents (nreverse forms))))
-
-(defun read-atom (reader)
-  (let ((token (next reader)))
-    (cond
-      ((string= token "false")
-       types:mal-false)
-      ((string= token "true")
-       types:mal-true)
-      ((string= token "nil")
-       types:mal-nil)
-      ((char= (char token 0) #\")
-       (make-mal-string (parse-string token)))
-      ((char= (char token 0) #\:)
-       (make-mal-keyword token))
-      ((regexp:regexp-exec *digit-re* token)
-       (make-mal-number (read-from-string token)))
-      (t (make-mal-symbol token)))))
diff --git a/clisp/run b/clisp/run
deleted file mode 100755 (executable)
index 9522020..0000000
--- a/clisp/run
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-exec clisp $(dirname $0)/${STEP:-stepA_mal}.fas "${@}"
diff --git a/clisp/step0_repl.lisp b/clisp/step0_repl.lisp
deleted file mode 100644 (file)
index 960ed2e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-(defpackage :mal
-  (:use :common-lisp
-        :readline))
-
-(in-package :mal)
-
-(defun mal-read (string)
-  string)
-
-(defun mal-eval (ast env)
-  ast)
-
-(defun mal-print (expression)
-  expression)
-
-(defun rep (string)
-  (mal-print (mal-eval (mal-read string)
-                       (make-hash-table :test #'equal))))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step1_read_print.lisp b/clisp/step1_read_print.lisp
deleted file mode 100644 (file)
index f1d2bb9..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :reader
-        :printer))
-
-(in-package :mal)
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  ast)
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           nil))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step2_eval.lisp b/clisp/step2_eval.lisp
deleted file mode 100644 (file)
index 148b566..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer))
-
-(in-package :mal)
-
-;; Environment
-
-(defvar *repl-env* (make-hash-table :test 'types:mal-value=))
-
-(setf (gethash (types:make-mal-symbol "+") *repl-env*)
-      (types:make-mal-builtin-fn (lambda (value1 value2)
-                                   (apply-unwrapped-values '+
-                                                           value1
-                                                           value2))))
-
-(setf (gethash (types:make-mal-symbol "-") *repl-env*)
-      (types:make-mal-builtin-fn (lambda (value1 value2)
-                                   (apply-unwrapped-values '-
-                                                           value1
-                                                           value2))))
-
-(setf (gethash (types:make-mal-symbol "*") *repl-env*)
-      (types:make-mal-builtin-fn (lambda (value1 value2)
-                                   (apply-unwrapped-values '*
-                                                           value1
-                                                           value2))))
-
-(setf (gethash (types:make-mal-symbol "/") *repl-env*)
-      (types:make-mal-builtin-fn (lambda (value1 value2)
-                                   (apply-unwrapped-values '/
-                                                           value1
-                                                           value2))))
-
-(defun lookup-env (symbol env)
-  (let ((value (gethash symbol env)))
-    (if value
-        value
-        (error 'env:undefined-symbol
-               :symbol (format nil "~a" (types:mal-data-value symbol))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (cond
-    ((not (types:mal-list-p ast)) (eval-ast ast env))
-    ((zerop (length (mal-data-value ast))) ast)
-    (t (progn
-         (let ((evaluated-list (eval-ast ast env)))
-           (apply (mal-data-value (car evaluated-list))
-                  (cdr evaluated-list)))))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash key new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (lookup-env ast env))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env ))
-    (types:any ast)))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step3_env.lisp b/clisp/step3_env.lisp
deleted file mode 100644 (file)
index a3aed4a..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer))
-
-(in-package :mal)
-
-(defvar *repl-env* (env:create-mal-env))
-
-(set-env *repl-env*
-         (types:make-mal-symbol "+")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (apply-unwrapped-values '+ value1 value2))))
-
-(set-env *repl-env*
-         (types:make-mal-symbol "-")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (apply-unwrapped-values '- value1 value2))))
-
-(set-env *repl-env*
-         (types:make-mal-symbol "*")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (apply-unwrapped-values '* value1 value2))))
-
-(set-env *repl-env*
-         (types:make-mal-symbol "/")
-         (types:make-mal-builtin-fn (lambda (value1 value2)
-                                      (apply-unwrapped-values '/ value1 value2))))
-
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash key new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env ))
-    (types:any ast)))
-
-(defun eval-let* (forms env)
-  (let ((new-env (env:create-mal-env :parent env))
-        ;; Convert a potential vector to a list
-        (bindings (map 'list
-                       #'identity
-                       (types:mal-data-value (second forms)))))
-
-    (mapcar (lambda (binding)
-              (env:set-env new-env
-                           (car binding)
-                           (mal-eval (or (cdr binding)
-                                         types:mal-nil)
-                                     new-env)))
-            (loop
-               for (symbol value) on bindings
-               by #'cddr
-               collect (cons symbol value)))
-
-    (mal-eval (third forms) new-env)))
-
-(defun eval-list (ast env)
-  (let ((forms (mal-data-value ast)))
-    (cond
-      ((mal-value= mal-def! (first forms))
-       (env:set-env env (second forms) (mal-eval (third forms) env)))
-      ((mal-value= mal-let* (first forms))
-       (eval-let* forms env))
-      (t (let ((evaluated-list (eval-ast ast env)))
-           (apply (types:mal-data-value (car evaluated-list))
-                  (cdr evaluated-list)))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (cond
-    ((null ast) types:mal-nil)
-    ((not (types:mal-list-p ast)) (eval-ast ast env))
-    ((zerop (length (mal-data-value ast))) ast)
-    (t (eval-list ast env))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step4_if_fn_do.lisp b/clisp/step4_if_fn_do.lisp
deleted file mode 100644 (file)
index 0d96571..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash key new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun eval-let* (forms env)
-  (let ((new-env (env:create-mal-env :parent env))
-        ;; Convert a potential vector to a list
-        (bindings (map 'list
-                       #'identity
-                       (mal-data-value (second forms)))))
-
-    (mapcar (lambda (binding)
-              (env:set-env new-env
-                           (car binding)
-                           (mal-eval (or (cdr binding)
-                                         types:mal-nil)
-                                     new-env)))
-            (loop
-               for (symbol value) on bindings
-               by #'cddr
-               collect (cons symbol value)))
-
-    (mal-eval (third forms) new-env)))
-
-(defun eval-list (ast env)
-  (let ((forms (mal-data-value ast)))
-    (cond
-      ((mal-value= mal-def! (first forms))
-       (env:set-env env (second forms) (mal-eval (third forms) env)))
-      ((mal-value= mal-let* (first forms))
-       (eval-let* forms env))
-      ((mal-value= mal-do (first forms))
-       (car (last (mapcar (lambda (form) (mal-eval form env))
-                          (cdr forms)))))
-      ((mal-value= mal-if (first forms))
-       (let ((predicate (mal-eval (second forms) env)))
-         (mal-eval (if (or (mal-value= predicate types:mal-nil)
-                           (mal-value= predicate types:mal-false))
-                       (fourth forms)
-                       (third forms))
-                   env)))
-      ((mal-value= mal-fn* (first forms))
-       (types:make-mal-fn (let ((arglist (second forms))
-                                (body (third forms)))
-                            (lambda (&rest args)
-                              (mal-eval body (env:create-mal-env :parent env
-                                                                 :binds (map 'list
-                                                                             #'identity
-                                                                             (mal-data-value arglist))
-                                                                 :exprs args))))))
-      (t (let* ((evaluated-list (eval-ast ast env))
-               (function (car evaluated-list)))
-         ;; If first element is a mal function unwrap it
-         (apply (mal-data-value function)
-                (cdr evaluated-list)))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (cond
-    ((null ast) types:mal-nil)
-    ((not (types:mal-list-p ast)) (eval-ast ast env))
-    ((zerop (length (mal-data-value ast))) ast)
-    (t (eval-list ast env))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))
-    (error (condition)
-      (format nil
-              "~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step5_tco.lisp b/clisp/step5_tco.lisp
deleted file mode 100644 (file)
index d25e1d0..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash key new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (loop
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env))))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (if (not (types:mal-fn-p function))
-                          (return (apply (mal-data-value function)
-                                         (cdr evaluated-list)))
-                          (let* ((attrs (types:mal-data-attrs function)))
-                            (setf ast (cdr (assoc 'ast attrs))
-                                  env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                          :binds (map 'list
-                                                                      #'identity
-                                                                      (mal-data-value (cdr (assoc 'params attrs))))
-                                                          :exprs (cdr evaluated-list)))))))))))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))
-    (error (condition)
-      (format nil
-              "~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun main ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-;; Do not start REPL inside Emacs
-(unless (member :swank *features*)
-  (main))
diff --git a/clisp/step6_file.lisp b/clisp/step6_file.lisp
deleted file mode 100644 (file)
index 095f664..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "eval")
-             (types:make-mal-builtin-fn (lambda (ast)
-                                          (mal-eval ast *repl-env*))))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash (mal-eval key env) new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (loop
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env))))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (if (not (types:mal-fn-p function))
-                          (return (apply (mal-data-value function)
-                                         (cdr evaluated-list)))
-                          (let* ((attrs (types:mal-data-attrs function)))
-                            (setf ast (cdr (assoc 'ast attrs))
-                                  env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                          :binds (map 'list
-                                                                      #'identity
-                                                                      (mal-data-value (cdr (assoc 'params attrs))))
-                                                          :exprs (cdr evaluated-list)))))))))))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))
-    (error (condition)
-      (format nil
-              "~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
-(rep "(def! *ARGV* (list))")
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "*ARGV*")
-             (types:wrap-value (cdr common-lisp-user::*args*)
-                               :listp t))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun repl ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-(defun main ()
-  (if (null common-lisp-user::*args*)
-      ;; Do not start REPL inside Emacs
-      (unless (member :swank *features*)
-        (repl))
-      (rep (format nil
-                   "(load-file \"~a\")"
-                   (car common-lisp-user::*args*)))))
-
-(main)
diff --git a/clisp/step7_quote.lisp b/clisp/step7_quote.lisp
deleted file mode 100644 (file)
index d73e4f0..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-quote (make-mal-symbol "quote"))
-(defvar mal-quasiquote (make-mal-symbol "quasiquote"))
-(defvar mal-unquote (make-mal-symbol "unquote"))
-(defvar mal-splice-unquote (make-mal-symbol "splice-unquote"))
-(defvar mal-cons (make-mal-symbol "cons"))
-(defvar mal-concat (make-mal-symbol "concat"))
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "eval")
-             (types:make-mal-builtin-fn (lambda (ast)
-                                          (mal-eval ast *repl-env*))))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash (mal-eval key env) new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-
-(defun is-pair (value)
-  (and (or (mal-list-p value)
-           (mal-vector-p value))
-       (not (zerop (length (mal-data-value value))))))
-
-(defun quasiquote (ast)
-  (if (not (is-pair ast))
-      (types:make-mal-list (list mal-quote
-                                 ast))
-      (let ((forms (map 'list #'identity (mal-data-value ast))))
-        (cond
-          ((mal-value= mal-unquote (first forms))
-           (second forms))
-
-          ((and (is-pair (first forms))
-                (mal-value= mal-splice-unquote
-                            (first (mal-data-value (first forms)))))
-           (types:make-mal-list (list mal-concat
-                                      (second (mal-data-value (first forms)))
-                                      (quasiquote (make-mal-list (cdr forms))))))
-
-          (t (types:make-mal-list (list mal-cons
-                                        (quasiquote (first forms))
-                                        (quasiquote (make-mal-list (cdr forms))))))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-eval (ast env)
-  (loop
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-quote (first forms))
-                  (return (second forms)))
-
-                 ((mal-value= mal-quasiquote (first forms))
-                  (setf ast (quasiquote (second forms))))
-
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env))))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (if (not (types:mal-fn-p function))
-                          (return (apply (mal-data-value function)
-                                         (cdr evaluated-list)))
-                          (let* ((attrs (types:mal-data-attrs function)))
-                            (setf ast (cdr (assoc 'ast attrs))
-                                  env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                          :binds (map 'list
-                                                                      #'identity
-                                                                      (mal-data-value (cdr (assoc 'params attrs))))
-                                                          :exprs (cdr evaluated-list)))))))))))))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (reader:eof (condition)
-      (format nil
-              "~a"
-              condition))
-    (env:undefined-symbol (condition)
-      (format nil
-              "~a"
-              condition))
-    (error (condition)
-      (format nil
-              "~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
-(rep "(def! *ARGV* (list))")
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "*ARGV*")
-             (types:wrap-value (cdr common-lisp-user::*args*)
-                               :listp t))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun repl ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-(defun main ()
-  (if (null common-lisp-user::*args*)
-      ;; Do not start REPL inside Emacs
-      (unless (member :swank *features*)
-        (repl))
-      (rep (format nil
-                   "(load-file \"~a\")"
-                   (car common-lisp-user::*args*)))))
-
-(main)
diff --git a/clisp/step8_macros.lisp b/clisp/step8_macros.lisp
deleted file mode 100644 (file)
index 6264e30..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(define-condition invalid-function (types:mal-error)
-  ((form :initarg :form :reader form)
-   (context :initarg :context :reader context))
-  (:report (lambda (condition stream)
-             (format stream
-                     "Invalid function '~a' provided while ~a"
-                     (printer:pr-str (form condition))
-                     (if (string= (context condition) "apply")
-                         "applying"
-                         "defining macro")))))
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-quote (make-mal-symbol "quote"))
-(defvar mal-quasiquote (make-mal-symbol "quasiquote"))
-(defvar mal-unquote (make-mal-symbol "unquote"))
-(defvar mal-splice-unquote (make-mal-symbol "splice-unquote"))
-(defvar mal-cons (make-mal-symbol "cons"))
-(defvar mal-concat (make-mal-symbol "concat"))
-(defvar mal-macroexpand (make-mal-symbol "macroexpand"))
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-defmacro! (make-mal-symbol "defmacro!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "eval")
-             (types:make-mal-builtin-fn (lambda (ast)
-                                          (mal-eval ast *repl-env*))))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash (mal-eval key env) new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun is-pair (value)
-  (and (or (mal-list-p value)
-           (mal-vector-p value))
-       (not (zerop (length (mal-data-value value))))))
-
-(defun quasiquote (ast)
-  (if (not (is-pair ast))
-      (types:make-mal-list (list mal-quote
-                                 ast))
-      (let ((forms (map 'list #'identity (mal-data-value ast))))
-        (cond
-          ((mal-value= mal-unquote (first forms))
-           (second forms))
-
-          ((and (is-pair (first forms))
-                (mal-value= mal-splice-unquote
-                            (first (mal-data-value (first forms)))))
-           (types:make-mal-list (list mal-concat
-                                      (second (mal-data-value (first forms)))
-                                      (quasiquote (make-mal-list (cdr forms))))))
-
-          (t (types:make-mal-list (list mal-cons
-                                        (quasiquote (first forms))
-                                        (quasiquote (make-mal-list (cdr forms))))))))))
-
-(defun is-macro-call (ast env)
-  (when (and (types:mal-list-p ast)
-             (not (zerop (length (mal-data-value ast)))))
-    (let* ((func-symbol (first (mal-data-value ast)))
-           (func (when (types:mal-symbol-p func-symbol)
-                   (env:find-env env func-symbol))))
-      (and func
-           (types:mal-fn-p func)
-           (cdr (assoc 'is-macro (types:mal-data-attrs func)))))))
-
-(defun mal-macroexpand (ast env)
-  (loop
-     while (is-macro-call ast env)
-     do (let* ((forms (types:mal-data-value ast))
-               (func (env:get-env env (first forms))))
-          (setf ast (apply (mal-data-value func)
-                           (cdr forms)))))
-  ast)
-
-(defun mal-eval (ast env)
-  (loop
-     do (setf ast (mal-macroexpand ast env))
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-quote (first forms))
-                  (return (second forms)))
-
-                 ((mal-value= mal-quasiquote (first forms))
-                  (setf ast (quasiquote (second forms))))
-
-                 ((mal-value= mal-macroexpand (first forms))
-                  (return (mal-macroexpand (second forms) env)))
-
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-defmacro! (first forms))
-                  (let ((value (mal-eval (third forms) env)))
-                    (return (if (types:mal-fn-p value)
-                                (env:set-env env
-                                             (second forms)
-                                             (progn
-                                               (setf (cdr (assoc 'is-macro (types:mal-data-attrs value))) t)
-                                               value))
-                                (error 'invalid-function
-                                       :form value
-                                       :context "macro")))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env)
-                                                            (cons 'is-macro nil))))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (cond ((types:mal-fn-p function)
-                             (let* ((attrs (types:mal-data-attrs function)))
-                               (setf ast (cdr (assoc 'ast attrs))
-                                     env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                             :binds (map 'list
-                                                                         #'identity
-                                                                         (mal-data-value (cdr (assoc 'params attrs))))
-                                                             :exprs (cdr evaluated-list)))))
-                            ((types:mal-builtin-fn-p function)
-                             (return (apply (mal-data-value function)
-                                            (cdr evaluated-list))))
-                            (t (error 'invalid-function
-                                      :form function
-                                      :context "apply")))))))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (types:mal-error (condition)
-      (format nil
-              "~a"
-              condition))
-    (error (condition)
-      (format nil
-              "Internal error: ~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
-(rep "(def! *ARGV* (list))")
-(rep "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))")
-(rep "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))")
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "*ARGV*")
-             (types:wrap-value (cdr common-lisp-user::*args*)
-                               :listp t))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun repl ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-(defun main ()
-  (if (null common-lisp-user::*args*)
-      ;; Do not start REPL inside Emacs
-      (unless (member :swank *features*)
-        (repl))
-      (rep (format nil
-                   "(load-file \"~a\")"
-                   (car common-lisp-user::*args*)))))
-
-(main)
diff --git a/clisp/step9_try.lisp b/clisp/step9_try.lisp
deleted file mode 100644 (file)
index 2066e95..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(define-condition invalid-function (types:mal-runtime-exception)
-  ((form :initarg :form :reader form)
-   (context :initarg :context :reader context))
-  (:report (lambda (condition stream)
-             (format stream
-                     "Invalid function '~a' provided while ~a"
-                     (printer:pr-str (form condition))
-                     (if (string= (context condition) "apply")
-                         "applying"
-                         "defining macro")))))
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "eval")
-             (types:make-mal-builtin-fn (lambda (ast)
-                                          (mal-eval ast *repl-env*))))
-
-(defvar mal-quote (make-mal-symbol "quote"))
-(defvar mal-quasiquote (make-mal-symbol "quasiquote"))
-(defvar mal-unquote (make-mal-symbol "unquote"))
-(defvar mal-splice-unquote (make-mal-symbol "splice-unquote"))
-(defvar mal-cons (make-mal-symbol "cons"))
-(defvar mal-concat (make-mal-symbol "concat"))
-(defvar mal-macroexpand (make-mal-symbol "macroexpand"))
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-defmacro! (make-mal-symbol "defmacro!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-(defvar mal-try* (make-mal-symbol "try*"))
-(defvar mal-catch* (make-mal-symbol "catch*"))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash (mal-eval key env) new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun is-pair (value)
-  (and (or (mal-list-p value)
-           (mal-vector-p value))
-       (not (zerop (length (mal-data-value value))))))
-
-(defun quasiquote (ast)
-  (if (not (is-pair ast))
-      (types:make-mal-list (list mal-quote
-                                 ast))
-      (let ((forms (map 'list #'identity (mal-data-value ast))))
-        (cond
-          ((mal-value= mal-unquote (first forms))
-           (second forms))
-
-          ((and (is-pair (first forms))
-                (mal-value= mal-splice-unquote
-                            (first (mal-data-value (first forms)))))
-           (types:make-mal-list (list mal-concat
-                                      (second (mal-data-value (first forms)))
-                                      (quasiquote (make-mal-list (cdr forms))))))
-
-          (t (types:make-mal-list (list mal-cons
-                                        (quasiquote (first forms))
-                                        (quasiquote (make-mal-list (cdr forms))))))))))
-
-(defun is-macro-call (ast env)
-  (when (and (types:mal-list-p ast)
-             (not (zerop (length (mal-data-value ast)))))
-    (let* ((func-symbol (first (mal-data-value ast)))
-           (func (when (types:mal-symbol-p func-symbol)
-                   (env:find-env env func-symbol))))
-      (and func
-           (types:mal-fn-p func)
-           (cdr (assoc 'is-macro (types:mal-data-attrs func)))))))
-
-(defun mal-macroexpand (ast env)
-  (loop
-     while (is-macro-call ast env)
-     do (let* ((forms (types:mal-data-value ast))
-               (func (env:get-env env (first forms))))
-          (setf ast (apply (mal-data-value func)
-                           (cdr forms)))))
-  ast)
-
-(defun mal-eval (ast env)
-  (loop
-     do (setf ast (mal-macroexpand ast env))
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-quote (first forms))
-                  (return (second forms)))
-
-                 ((mal-value= mal-quasiquote (first forms))
-                  (setf ast (quasiquote (second forms))))
-
-                 ((mal-value= mal-macroexpand (first forms))
-                  (return (mal-macroexpand (second forms) env)))
-
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-defmacro! (first forms))
-                  (let ((value (mal-eval (third forms) env)))
-                    (return (if (types:mal-fn-p value)
-                                (env:set-env env
-                                             (second forms)
-                                             (progn
-                                               (setf (cdr (assoc 'is-macro (types:mal-data-attrs value))) t)
-                                               value))
-                                (error 'invalid-function
-                                       :form value
-                                       :context "macro")))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env)
-                                                            (cons 'is-macro nil))))))
-
-                 ((mal-value= mal-try* (first forms))
-                  (handler-case
-                      (return (mal-eval (second forms) env))
-                    (types:mal-exception (condition)
-                      (when (third forms)
-                        (let ((catch-forms (types:mal-data-value (third forms))))
-                          (when (mal-value= mal-catch*
-                                            (first catch-forms))
-                            (return (mal-eval (third catch-forms)
-                                              (env:create-mal-env :parent env
-                                                                  :binds (list (second catch-forms))
-                                                                  :exprs (list (if (typep condition 'types:mal-runtime-exception)
-                                                                                   (types:make-mal-string (format nil "~a" condition))
-                                                                                   (types::mal-exception-data condition)))))))))
-                      (error condition))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (cond ((types:mal-fn-p function)
-                             (let* ((attrs (types:mal-data-attrs function)))
-                               (setf ast (cdr (assoc 'ast attrs))
-                                     env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                             :binds (map 'list
-                                                                         #'identity
-                                                                         (mal-data-value (cdr (assoc 'params attrs))))
-                                                             :exprs (cdr evaluated-list)))))
-                            ((types:mal-builtin-fn-p function)
-                             (return (apply (mal-data-value function)
-                                            (cdr evaluated-list))))
-                            (t (error 'invalid-function
-                                      :form function
-                                      :context "apply")))))))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (types:mal-error (condition)
-      (format nil
-              "Error: ~a"
-              condition))
-    (types:mal-runtime-exception (condition)
-      (format nil
-              "Exception: ~a"
-              condition))
-    (types:mal-user-exception (condition)
-      (format nil
-              "Exception: ~a"
-              (pr-str (types::mal-exception-data condition))))
-    (error (condition)
-      (format nil
-              "Internal error: ~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
-(rep "(def! *ARGV* (list))")
-(rep "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))")
-(rep "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))")
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "*ARGV*")
-             (types:wrap-value (cdr common-lisp-user::*args*)
-                               :listp t))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                         ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun repl ()
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-(defun main ()
-  (if (null common-lisp-user::*args*)
-      ;; Do not start REPL inside Emacs
-      (unless (member :swank *features*)
-        (repl))
-      (rep (format nil
-                   "(load-file \"~a\")"
-                   (car common-lisp-user::*args*)))))
-
-(main)
diff --git a/clisp/stepA_mal.lisp b/clisp/stepA_mal.lisp
deleted file mode 100644 (file)
index 3c7135e..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-(require "dependencies")
-
-(defpackage :mal
-  (:use :common-lisp
-        :readline
-        :types
-        :env
-        :reader
-        :printer
-        :core))
-
-(in-package :mal)
-
-(define-condition invalid-function (types:mal-runtime-exception)
-  ((form :initarg :form :reader form)
-   (context :initarg :context :reader context))
-  (:report (lambda (condition stream)
-             (format stream
-                     "Invalid function '~a' provided while ~a"
-                     (printer:pr-str (form condition))
-                     (if (string= (context condition) "apply")
-                         "applying"
-                         "defining macro")))))
-
-(defvar *repl-env* (env:create-mal-env))
-
-(dolist (binding core:ns)
-  (env:set-env *repl-env*
-               (car binding)
-               (cdr binding)))
-
-(defvar mal-quote (make-mal-symbol "quote"))
-(defvar mal-quasiquote (make-mal-symbol "quasiquote"))
-(defvar mal-unquote (make-mal-symbol "unquote"))
-(defvar mal-splice-unquote (make-mal-symbol "splice-unquote"))
-(defvar mal-cons (make-mal-symbol "cons"))
-(defvar mal-concat (make-mal-symbol "concat"))
-(defvar mal-macroexpand (make-mal-symbol "macroexpand"))
-(defvar mal-def! (make-mal-symbol "def!"))
-(defvar mal-defmacro! (make-mal-symbol "defmacro!"))
-(defvar mal-let* (make-mal-symbol "let*"))
-(defvar mal-do (make-mal-symbol "do"))
-(defvar mal-if (make-mal-symbol "if"))
-(defvar mal-fn* (make-mal-symbol "fn*"))
-(defvar mal-try* (make-mal-symbol "try*"))
-(defvar mal-catch* (make-mal-symbol "catch*"))
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "eval")
-             (types:make-mal-builtin-fn (lambda (ast)
-                                          (mal-eval ast *repl-env*))))
-
-(defun eval-sequence (sequence env)
-  (map 'list
-       (lambda (ast) (mal-eval ast env))
-       (mal-data-value sequence)))
-
-(defun eval-hash-map (hash-map env)
-  (let ((hash-map-value (mal-data-value hash-map))
-        (new-hash-table (make-hash-table :test 'types:mal-value=)))
-    (loop
-       for key being the hash-keys of hash-map-value
-       do (setf (gethash (mal-eval key env) new-hash-table)
-                (mal-eval (gethash key hash-map-value) env)))
-    (make-mal-hash-map new-hash-table)))
-
-(defun eval-ast (ast env)
-  (switch-mal-type ast
-    (types:symbol (env:get-env env ast))
-    (types:list (eval-sequence ast env))
-    (types:vector (make-mal-vector (apply 'vector (eval-sequence ast env))))
-    (types:hash-map (eval-hash-map ast env))
-    (types:any ast)))
-
-(defun is-pair (value)
-  (and (or (mal-list-p value)
-           (mal-vector-p value))
-       (not (zerop (length (mal-data-value value))))))
-
-(defun quasiquote (ast)
-  (if (not (is-pair ast))
-      (types:make-mal-list (list mal-quote ast))
-      (let ((forms (map 'list #'identity (mal-data-value ast))))
-        (cond
-          ((mal-value= mal-unquote (first forms))
-           (second forms))
-
-          ((and (is-pair (first forms))
-                (mal-value= mal-splice-unquote
-                            (first (mal-data-value (first forms)))))
-           (types:make-mal-list (list mal-concat
-                                      (second (mal-data-value (first forms)))
-                                      (quasiquote (make-mal-list (cdr forms))))))
-
-          (t (types:make-mal-list (list mal-cons
-                                        (quasiquote (first forms))
-                                        (quasiquote (make-mal-list (cdr forms))))))))))
-
-(defun is-macro-call (ast env)
-  (when (and (types:mal-list-p ast)
-             (not (zerop (length (mal-data-value ast)))))
-    (let* ((func-symbol (first (mal-data-value ast)))
-           (func (when (types:mal-symbol-p func-symbol)
-                   (env:find-env env func-symbol))))
-      (and func
-           (types:mal-fn-p func)
-           (cdr (assoc 'is-macro (types:mal-data-attrs func)))))))
-
-(defun mal-macroexpand (ast env)
-  (loop
-     while (is-macro-call ast env)
-     do (let* ((forms (types:mal-data-value ast))
-               (func (env:get-env env (first forms))))
-          (setf ast (apply (mal-data-value func)
-                           (cdr forms)))))
-  ast)
-
-(defun mal-eval (ast env)
-  (loop
-     do (setf ast (mal-macroexpand ast env))
-     do (cond
-          ((null ast) (return types:mal-nil))
-          ((not (types:mal-list-p ast)) (return (eval-ast ast env)))
-          ((zerop (length (mal-data-value ast))) (return ast))
-          (t (let ((forms (mal-data-value ast)))
-               (cond
-                 ((mal-value= mal-quote (first forms))
-                  (return (second forms)))
-
-                 ((mal-value= mal-quasiquote (first forms))
-                  (setf ast (quasiquote (second forms))))
-
-                 ((mal-value= mal-macroexpand (first forms))
-                  (return (mal-macroexpand (second forms) env)))
-
-                 ((mal-value= mal-def! (first forms))
-                  (return (env:set-env env (second forms) (mal-eval (third forms) env))))
-
-                 ((mal-value= mal-defmacro! (first forms))
-                  (let ((value (mal-eval (third forms) env)))
-                    (return (if (types:mal-fn-p value)
-                                (env:set-env env
-                                             (second forms)
-                                             (progn
-                                               (setf (cdr (assoc 'is-macro (types:mal-data-attrs value))) t)
-                                               value))
-                                (error 'invalid-function
-                                       :form value
-                                       :context "macro")))))
-
-                 ((mal-value= mal-let* (first forms))
-                  (let ((new-env (env:create-mal-env :parent env))
-                        ;; Convert a potential vector to a list
-                        (bindings (map 'list
-                                       #'identity
-                                       (mal-data-value (second forms)))))
-
-                    (mapcar (lambda (binding)
-                              (env:set-env new-env
-                                           (car binding)
-                                           (mal-eval (or (cdr binding)
-                                                         types:mal-nil)
-                                                     new-env)))
-                            (loop
-                               for (symbol value) on bindings
-                               by #'cddr
-                               collect (cons symbol value)))
-                    (setf ast (third forms)
-                          env new-env)))
-
-                 ((mal-value= mal-do (first forms))
-                  (mapc (lambda (form) (mal-eval form env))
-                        (butlast (cdr forms)))
-                  (setf ast (car (last forms))))
-
-                 ((mal-value= mal-if (first forms))
-                  (let ((predicate (mal-eval (second forms) env)))
-                    (setf ast (if (or (mal-value= predicate types:mal-nil)
-                                      (mal-value= predicate types:mal-false))
-                                  (fourth forms)
-                                  (third forms)))))
-
-                 ((mal-value= mal-fn* (first forms))
-                  (return (let ((arglist (second forms))
-                                (body (third forms)))
-                            (types:make-mal-fn (lambda (&rest args)
-                                                 (mal-eval body (env:create-mal-env :parent env
-                                                                                    :binds (map 'list
-                                                                                                #'identity
-                                                                                                (mal-data-value arglist))
-                                                                                    :exprs args)))
-                                               :attrs (list (cons 'params arglist)
-                                                            (cons 'ast body)
-                                                            (cons 'env env)
-                                                            (cons 'is-macro nil))))))
-
-                 ((mal-value= mal-try* (first forms))
-                  (handler-case
-                      (return (mal-eval (second forms) env))
-                    ((or types:mal-exception types:mal-error) (condition)
-                      (when (third forms)
-                        (let ((catch-forms (types:mal-data-value (third forms))))
-                          (when (mal-value= mal-catch*
-                                            (first catch-forms))
-                            (return (mal-eval (third catch-forms)
-                                              (env:create-mal-env :parent env
-                                                                  :binds (list (second catch-forms))
-                                                                  :exprs (list (if (or (typep condition 'types:mal-runtime-exception)
-                                                                                       (typep condition 'types:mal-error))
-                                                                                   (types:make-mal-string (format nil "~a" condition))
-                                                                                   (types::mal-exception-data condition)))))))))
-                     (error condition))))
-
-                 (t (let* ((evaluated-list (eval-ast ast env))
-                           (function (car evaluated-list)))
-                      ;; If first element is a mal function unwrap it
-                      (cond ((types:mal-fn-p function)
-                             (let* ((attrs (types:mal-data-attrs function)))
-                               (setf ast (cdr (assoc 'ast attrs))
-                                     env (env:create-mal-env :parent (cdr (assoc 'env attrs))
-                                                             :binds (map 'list
-                                                                         #'identity
-                                                                         (mal-data-value (cdr (assoc 'params attrs))))
-                                                             :exprs (cdr evaluated-list)))))
-                            ((types:mal-builtin-fn-p function)
-                             (return (apply (mal-data-value function)
-                                            (cdr evaluated-list))))
-                            (t (error 'invalid-function
-                                      :form function
-                                      :context "apply")))))))))))
-
-(defun mal-read (string)
-  (reader:read-str string))
-
-(defun mal-print (expression)
-  (printer:pr-str expression))
-
-(defun rep (string)
-  (handler-case
-      (mal-print (mal-eval (mal-read string)
-                           *repl-env*))
-    (types:mal-error (condition)
-      (format nil
-              "Error: ~a"
-              condition))
-    (types:mal-runtime-exception (condition)
-      (format nil
-              "Exception: ~a"
-              condition))
-    (types:mal-user-exception (condition)
-      (format nil
-              "Exception: ~a"
-              (pr-str (types::mal-exception-data condition))))
-    (error (condition)
-      (format nil
-              "Internal error: ~a"
-              condition))))
-
-(rep "(def! not (fn* (a) (if a false true)))")
-(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
-(rep "(def! *ARGV* (list))")
-(rep "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))")
-(rep "(def! *host-language* \"clisp\")")
-(rep "(def! *gensym-counter* (atom 0))")
-(rep "(def! gensym (fn* [] (symbol (str \"G__\" (swap! *gensym-counter* (fn* [x] (+ 1 x)))))))")
-(rep "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) (let* (condvar (gensym)) `(let* (~condvar ~(first xs)) (if ~condvar ~condvar (or ~@(rest xs)))))))))")
-(rep "(defmacro! defbuiltin! (fn* (arglist & forms) `(define-builtin '~arglist '~@forms)))")
-
-(env:set-env *repl-env*
-             (types:make-mal-symbol "*ARGV*")
-             (types:wrap-value (cdr common-lisp-user::*args*)
-                               :listp t))
-
-;; Readline setup
-;;; The test runner sets this environment variable, in which case we do
-;;; use readline since tests do not work with the readline interface
-(defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
-
-(defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
-                                                    ".mal-clisp-history")))
-
-(defun load-history ()
-  (readline:read-history *history-file*))
-
-(defun save-history ()
-  (readline:write-history *history-file*))
-
-;; Setup history
-(when use-readline-p
-  (load-history))
-
-(defun raw-input (prompt)
-  (format *standard-output* prompt)
-  (force-output *standard-output*)
-  (read-line *standard-input* nil))
-
-(defun mal-readline (prompt)
-  (let ((input (if use-readline-p
-                   (readline:readline prompt)
-                   (raw-input prompt))))
-    (when (and use-readline-p
-               input
-               (not (zerop (length input))))
-      (readline:add-history input))
-    input))
-
-(defun mal-writeline (string)
-  (when string
-    (write-line string)))
-
-(defun repl ()
-  (rep "(println (str \"Mal [\" *host-language* \"]\"))");
-  (loop do (let ((line (mal-readline "user> ")))
-             (if line
-                 (mal-writeline (rep line))
-                 (return))))
-  (when use-readline-p
-    (save-history)))
-
-(defun main ()
-  (if (null common-lisp-user::*args*)
-      ;; Do not start REPL inside Emacs
-      (unless (member :swank *features*)
-        (repl))
-      (rep (format nil
-                   "(load-file \"~a\")"
-                   (car common-lisp-user::*args*)))))
-
-(main)
diff --git a/clisp/tests/stepA_mal.mal b/clisp/tests/stepA_mal.mal
deleted file mode 100644 (file)
index 2bb5d54..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-;; Testing clisp interop
-
-(clisp-eval "42")
-;=>42
-
-(clisp-eval "(+ 1 1)")
-;=>2
-
-(clisp-eval "(setq foo 1 bar 2 baz 3)")
-
-(clisp-eval "(list foo bar baz)")
-;=>(1 2 3)
-
-(clisp-eval "7")
-;=>7
-
-;;
-;; Testing boolean flag
-(clisp-eval "(= 123 123)" true)
-;=>true
-
-(clisp-eval "(= 123 456)")
-;=>nil
-
-(clisp-eval "(= 123 456)" true)
-;=>false
-
-;;
-;; Testing list flag
-(clisp-eval "(last nil)" false true)
-;=>()
-
-(clisp-eval "nil" false true)
-;=>()
-
-(clisp-eval "nil")
-;=>nil
-
-;;
-;; Testing creation of Common Lisp Objects
-(clisp-eval "#(1 2)")
-;=>[1 2]
-
-;;; Not testing with elements since order in hashtable cannot be guaranteed
-(clisp-eval "(make-hash-table)")
-;=>{}
-
-(clisp-eval "(defun redundant-identity (x) x)"))
-;=>REDUNDANT-IDENTITY
-
-(clisp-eval "(redundant-identity 2)"))
-;=>2
-
-(clisp-eval "(defun range (max &key (min 0) (step 1)) (loop for n from min below max by step collect n))")
-;=>RANGE
-
-(clisp-eval "(range 10 :min 0 :step 1)")
-;=>(0 1 2 3 4 5 6 7 8 9)
-
-(clisp-eval "(mapcar #'1+ (range 10 :min 0 :step 1))")
-;=>(1 2 3 4 5 6 7 8 9 10)
-
-;;
-;; Testing defbuiltin!
-(def! make-native-hash-map (defbuiltin! (&REST args) (MAKE-HASH-TABLE :initial-contents (LOOP FOR (KEY VALUE) ON args BY (FUNCTION CDDR) COLLECT (CONS KEY VALUE)))))
-;=>#<builtin function>
-
-(make-native-hash-map 1 2)
-;=>{1 2}
-
-(def! native-range (defbuiltin! (max &KEY (MIN 0) (STEP 1)) (LOOP FOR n FROM MIN BELOW max BY STEP COLLECT n)))
-;=>#<builtin function>
-
-(native-range 10 :MIN 2 :STEP 2)
-;=>(2 4 6 8)
\ No newline at end of file
diff --git a/clisp/types.lisp b/clisp/types.lisp
deleted file mode 100644 (file)
index fa1f0e1..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-;; Dummy package where MAL variables are interned
-(defpackage :mal-user
-  (:use :common-lisp))
-
-(defpackage :types
-  (:use :common-lisp)
-  (:export :mal-value=
-
-           ;; Accessors
-           :mal-data-value
-           :mal-data-type
-           :mal-data-meta
-           :mal-data-attrs
-
-           ;; Mal values
-           :number
-           :make-mal-number
-           :mal-number-p
-
-           :boolean
-           :mal-boolean-p
-
-           :nil
-           :mal-nil-p
-
-           :string
-           :make-mal-string
-           :mal-string-p
-
-           :symbol
-           :make-mal-symbol
-           :mal-symbol-p
-
-           :keyword
-           :make-mal-keyword
-           :mal-keyword-p
-
-           :list
-           :make-mal-list
-           :mal-list-p
-
-           :vector
-           :make-mal-vector
-           :mal-vector-p
-
-           :hash-map
-           :make-mal-hash-map
-           :mal-hash-map-p
-
-           :atom
-           :make-mal-atom
-           :mal-atom-p
-
-           :fn
-           :make-mal-fn
-           :mal-fn-p
-
-           :builtin-fn
-           :make-mal-builtin-fn
-           :mal-builtin-fn-p
-
-           :any
-
-           ;; Singleton values
-           :mal-nil
-           :mal-true
-           :mal-false
-
-           :mal-exception
-
-           ;; User exceptions
-           :mal-user-exception
-
-           ;; Exceptions raised by the runtime itself
-           :mal-runtime-exception
-
-           ;; Error
-           :mal-error
-
-           ;; Helpers
-           :wrap-value
-           :unwrap-value
-           :apply-unwrapped-values
-           :apply-unwrapped-values-prefer-bool
-           :switch-mal-type))
-
-(in-package :types)
-
-(define-condition mal-error (error)
-  nil)
-
-(define-condition mal-exception (error)
-  nil)
-
-(define-condition mal-runtime-exception (mal-exception)
-  nil)
-
-(define-condition mal-user-exception (mal-exception)
-  ((data :accessor mal-exception-data :initarg :data)))
-
-(defstruct mal-data
-  (type nil :read-only t)
-  (value nil)
-  meta
-  attrs)
-
-(defmacro define-mal-type (type)
-  ;; Create a class for given type and a convenience constructor and also export
-  ;; them
-  (let ((constructor (intern (string-upcase (concatenate 'string
-                                                         "make-mal-"
-                                                         (symbol-name type)))))
-        (predicate (intern (string-upcase (concatenate 'string
-                                                         "mal-"
-                                                         (symbol-name type)
-                                                         "-p")))))
-    `(progn (defun ,constructor (value &key meta attrs)
-              (make-mal-data :type ',type
-                             :value value
-                             :meta meta
-                             :attrs attrs))
-
-            (defun ,predicate (value)
-              (when (typep value 'mal-data)
-                (equal (mal-data-type value) ',type))))))
-
-(define-mal-type number)
-(define-mal-type symbol)
-(define-mal-type keyword)
-(define-mal-type string)
-;; TODO true, false and nil should ideally be singleton
-(define-mal-type boolean)
-(define-mal-type nil)
-
-(define-mal-type list)
-(define-mal-type vector)
-(define-mal-type hash-map)
-
-(define-mal-type atom)
-
-(define-mal-type fn)
-(define-mal-type builtin-fn)
-
-(defvar mal-nil (make-mal-nil nil))
-(defvar mal-true (make-mal-boolean t))
-(defvar mal-false (make-mal-boolean nil))
-
-;; Generic type
-(defvar any)
-
-(defmacro switch-mal-type (ast &body forms)
-  `(let ((type (types:mal-data-type ,ast)))
-     (cond
-       ,@(mapcar (lambda (form)
-                   (list (if (or (equal (car form) t)
-                                 (equal (car form) 'any))
-                             t
-                             (list 'equal (list 'quote (car form)) 'type))
-                         (cadr form)))
-                 forms))))
-
-(defun mal-symbol= (value1 value2)
-  (string= (mal-data-value value1)
-           (mal-data-value value2)))
-
-(defun mal-sequence= (value1 value2)
-  (let ((sequence1 (map 'list #'identity (mal-data-value value1)))
-        (sequence2 (map 'list #'identity (mal-data-value value2))))
-    (when (= (length sequence1) (length sequence2))
-      (every #'identity
-             (loop
-                for x in sequence1
-                for y in sequence2
-                collect (mal-value= x y))))))
-
-(defun mal-hash-map= (value1 value2)
-  (let ((map1 (mal-data-value value1))
-        (map2 (mal-data-value value2)))
-    (when (= (hash-table-count map1) (hash-table-count map2))
-      (every #'identity
-             (loop
-                for key being the hash-keys of map1
-                collect (mal-value= (gethash key map1)
-                                    (gethash key map2)))))))
-
-(defun mal-value= (value1 value2)
-  (when (and (typep value1 'mal-data)
-             (typep value2 'mal-data))
-    (if (equal (mal-data-type value1) (mal-data-type value2))
-        (switch-mal-type value1
-          (list (mal-sequence= value1 value2))
-          (vector (mal-sequence= value1 value2))
-          (hash-map (mal-hash-map= value1 value2))
-          (any (equal (mal-data-value value1) (mal-data-value value2))))
-        (when (or (and (mal-list-p value1) (mal-vector-p value2))
-                  (and (mal-list-p value2) (mal-vector-p value1)))
-          (mal-sequence= value1 value2)))))
-
-(defun hash-mal-value (value)
-  (sxhash (mal-data-value value)))
-
-(ext:define-hash-table-test mal-value= mal-value= hash-mal-value)
-
-(defun wrap-hash-value (value)
-  (let ((new-hash-table (make-hash-table :test 'mal-value=)))
-    (loop
-       for key being the hash-keys of value
-       do (setf (gethash (wrap-value key) new-hash-table)
-                (wrap-value (gethash key value))))
-    new-hash-table))
-
-(defun wrap-value (value &key booleanp listp)
-  "Convert a Common Lisp value to MAL value"
-  (typecase value
-    (number (make-mal-number value))
-    ;; This needs to before symbol since nil is a symbol
-    (null (cond
-            (booleanp mal-false)
-            (listp (make-mal-list nil))
-            (t mal-nil)))
-    ;; This needs to before symbol since t, nil are symbols
-    (boolean (if value mal-true mal-false))
-    (symbol (make-mal-symbol (symbol-name value)))
-    (keyword (make-mal-keyword value))
-    (string (make-mal-string value))
-    (list (make-mal-list (map 'list #'wrap-value value)))
-    (vector (make-mal-vector (map 'vector #'wrap-value value)))
-    (hash-table (make-mal-hash-map (wrap-hash-value value)))
-    (null mal-nil)))
-
-(defun unwrap-value (value)
-  "Convert a MAL value to native Common Lisp value"
-  (switch-mal-type value
-    (list (mapcar #'unwrap-value (mal-data-value value)))
-    (vector (map 'vector #'unwrap-value (mal-data-value value)))
-    (hash-map (let ((hash-table (make-hash-table))
-                    (hash-map-value (mal-data-value value)))
-                (loop
-                   for key being the hash-keys of hash-map-value
-                   do (setf (gethash (mal-data-value key) hash-table)
-                            (mal-data-value (gethash key hash-map-value))))
-                hash-table))
-    ;; Unfortunately below means even symbols that user indented to use
-    ;; from the common lisp are interned in lowercase thus runtime
-    ;; will not find them as such users need to explicitly upcase the
-    ;; symbols from common lisp
-    (symbol (intern (mal-data-value value) :mal-user))
-    ;; In case of a keyword strip the first colon, and intern the symbol in
-    ;; keyword package
-    (keyword (intern (string-upcase (subseq (mal-data-value value) 1))
-                     :keyword))
-    (any (mal-data-value value))))
-
-(defun apply-unwrapped-values (op &rest values)
-  (wrap-value (apply op (mapcar #'unwrap-value values))))
-
-(defun apply-unwrapped-values-prefer-bool (op &rest values)
-  (wrap-value (apply op (mapcar #'unwrap-value values)) :booleanp t))
diff --git a/clisp/utils.lisp b/clisp/utils.lisp
deleted file mode 100644 (file)
index 0ba81e7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-(defpackage :utils
-  (:use :common-lisp)
-  (:export :replace-all))
-
-(in-package :utils)
-
-(defun replace-all (string part replacement &key (test #'char=))
-  "Returns a new string in which all the occurences of the part
-is replaced with replacement."
-  (with-output-to-string (out)
-    (loop with part-length = (length part)
-       for old-pos = 0 then (+ pos part-length)
-       for pos = (search part string
-                         :start2 old-pos
-                         :test test)
-       do (write-string string out
-                        :start old-pos
-                        :end (or pos (length string)))
-       when pos do (write-string replacement out)
-       while pos)))