001 (ns beowulf.reader.macros
002 "Can I implement reader macros? let's see!
003
004 We don't need (at least, in the Clojure reader) to rewrite forms like
005 `'FOO`, because that's handled by the parser. But we do need to rewrite
006 things which don't evaluate their arguments, like `SETQ`, because (unless
007 LABEL does it, which I'm not yet sure of) we're not yet able to implement
008 things which don't evaluate arguments.
009
010 TODO: at this stage, the following should probably also be read macros:
011 DEFINE"
012 (:require [beowulf.cons-cell :refer [make-beowulf-list]]
013 [beowulf.host :refer [CONS LIST]]
014 [clojure.string :refer [join]]))
015
016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
017 ;;;
018 ;;; We don't need (at least, in the Clojure reader) to rewrite forms like
019 ;;; "'FOO", because that's handled by the parser. But we do need to rewrite
020 ;;; things which don't evaluate their arguments, like `SETQ`, because (unless
021 ;;; LABEL does it, which I'm not yet sure of) we're not yet able to implement
022 ;;; things which don't evaluate arguments.
023 ;;;
024 ;;; TODO: at this stage, the following should probably also be read macros:
025 ;;; DEFINE
026 ;;;
027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
028 ;;;
029 ;;; Copyright (C) 2022-2023 Simon Brooke
030 ;;;
031 ;;; This program is free software; you can redistribute it and/or
032 ;;; modify it under the terms of the GNU General Public License
033 ;;; as published by the Free Software Foundation; either version 2
034 ;;; of the License, or (at your option) any later version.
035 ;;;
036 ;;; This program is distributed in the hope that it will be useful,
037 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
038 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
039 ;;; GNU General Public License for more details.
040 ;;;
041 ;;; You should have received a copy of the GNU General Public License
042 ;;; along with this program; if not, write to the Free Software
043 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
044 ;;;
045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
046
047 (def ^:dynamic *readmacros*
048 {:car {'DEFUN (fn [f]
049 (LIST 'SET (LIST 'QUOTE (second f))
050 (LIST 'QUOTE (CONS 'LAMBDA (rest (rest f))))))
051 'SETQ (fn [f] (LIST 'SET (LIST 'QUOTE (second f)) (nth f 2)))}})
052
053 (defn expand-macros
054 [form]
055 (try
056 (if-let [car (when (and (coll? form) (symbol? (first form)))
057 (first form))]
058 (if-let [macro (-> *readmacros* :car car)]
059 (make-beowulf-list (apply macro (list form)))
060 form)
061 form)
062 (catch Exception any
063 (println (join "\n"
064 ["# ERROR while expanding macro:"
065 (str "# Form: " form)
066 (str "# Error class: " (.getName (.getClass any)))
067 (str "# Message: " (.getMessage any))]))
068 form)))