From 9f669d2d5040ef42ebdd381258046eb468093af1 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 14 Aug 2019 17:46:58 +0100 Subject: [PATCH] Now homoiconic for SEXPRS. --- src/beowulf/print.clj | 28 ++++++++++++++++++++-------- src/beowulf/read.clj | 22 +++++++++++++++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/beowulf/print.clj b/src/beowulf/print.clj index c0078df..b9563bd 100644 --- a/src/beowulf/print.clj +++ b/src/beowulf/print.clj @@ -26,14 +26,26 @@ beowulf.cons_cell.ConsCell (prin [x] - (let [car (.CAR x) - cdr (.CDR x)] - (str - "(" - (prin (.CAR x)) - " . " - (prin (.CDR x)) - ")"))) + (loop [c x + n 0 + s "("] + (let [car (.CAR c) + cdr (.CDR c) + cons? (instance? beowulf.cons_cell.ConsCell cdr) + ss (str + s + (prin car) + (cond + cons? + " " + (or (nil? cdr) (= cdr 'NIL)) + ")" + :else + (str " . " (prin cdr) ")")))] + (if + cons? + (recur cdr (inc n) ss) + ss)))) java.lang.Object (prin diff --git a/src/beowulf/read.clj b/src/beowulf/read.clj index bcdc061..49ce3fa 100644 --- a/src/beowulf/read.clj +++ b/src/beowulf/read.clj @@ -57,7 +57,6 @@ 'p'. Note that the function acts recursively and progressively decapitates its argument, so that the argument will not always be a valid parse tree." [p] - (println p) (cond (empty? p) NIL @@ -72,6 +71,8 @@ (gen-dot-terminated-list (rest p))))) (defn gen-cond-clause + "Generate a cond clause from this simplified parse tree fragment `p`; + returns `nil` if `p` does not represent a cond clause." [p] (if (and (coll? p)(= :cond-clause (first p))) @@ -79,9 +80,9 @@ (list (generate (nth p 1)) (generate (nth p 2)))))) - - (defn gen-cond + "Generate a cond statement from this simplified parse tree fragment `p`; + returns `nil` if `p` does not represent a (MEXPR) cond statement." [p] (if (and (coll? p)(= :cond (first p))) @@ -92,7 +93,17 @@ gen-cond-clause (rest p)))))) - +(defn gen-fn-call + "Generate a function call from this simplified parse tree fragment `p`; + returns `nil` if `p` does not represent a (MEXPR) function call. + TODO: I'm not yet certain but it appears that args in mexprs are + implicitly quoted; this function does not (yet) do that." + [p] + (if + (and (coll? p)(= :fncall (first p))(= :fn-name (first (second p)))) + (make-cons-cell + (second (second p)) + (generate (nth p 2))))) (defn generate "Generate lisp structure from this parse tree `p`. It is assumed that @@ -106,7 +117,8 @@ :dotted-pair (make-cons-cell (generate (nth p 1)) (generate (nth p 2))) - :list (gen-dot-terminated-list (rest p)) + :fncall (gen-fn-call p) + (:args :list) (gen-dot-terminated-list (rest p)) :number (clojure.core/read-string (second p)) ;; default (throw (Exception. (str "Cannot yet generate " (first p)))))