333 lines
22 KiB
HTML
333 lines
22 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/read.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns beowulf.read
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002 "This provides the reader required for boostrapping. It's not a bad
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003 reader - it provides feedback on errors found in the input - but it isn't
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 the real Lisp reader.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
005
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006 Intended deviations from the behaviour of the real Lisp reader are as follows:
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
007
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008 1. It reads the meta-expression language `MEXPR` in addition to the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 symbolic expression language `SEXPR`, which I do not believe the Lisp 1.5
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
010 reader ever did;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
011 2. It treats everything between a double semi-colon and an end of line as a comment,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
012 as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
013
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
014 Both these extensions can be disabled by using the `--strict` command line
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
015 switch."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 (:require ;; [beowulf.reader.char-reader :refer [read-chars]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
017 [beowulf.reader.generate :refer [generate]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
018 [beowulf.reader.parser :refer [parse]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
019 [beowulf.reader.simplify :refer [simplify]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
020 [clojure.string :refer [join split starts-with? trim]])
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
021 (:import [java.io InputStream]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
022 [instaparse.gll Failure]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
023
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
025 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
026 ;;; This file provides the reader required for boostrapping. It's not a bad
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 ;;; reader - it provides feedback on errors found in the input - but it isn't
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
028 ;;; the real Lisp reader.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
029 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
031 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
032 ;;; Copyright (C) 2022-2023 Simon Brooke
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
033 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 ;;; This program is free software; you can redistribute it and/or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
035 ;;; modify it under the terms of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 ;;; as published by the Free Software Foundation; either version 2
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
037 ;;; of the License, or (at your option) any later version.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
038 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
039 ;;; This program is distributed in the hope that it will be useful,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
040 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
041 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
042 ;;; GNU General Public License for more details.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
043 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
044 ;;; You should have received a copy of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
045 ;;; along with this program; if not, write to the Free Software
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
046 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
047 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
049
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
050 (defn strip-line-comments
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
051 "Strip blank lines and comment lines from this string `s`, expected to
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
052 be Lisp source."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
053 [^String s]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
054 (join "\n"
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
055 (remove
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
056 #(or (empty? %)
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
057 (starts-with? (trim %) ";;"))
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
058 (split s #"\n"))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
059
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
060 (defn number-lines
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
061 ([^String s]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
062 (number-lines s nil))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
063 ([^String s ^Failure e]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
064 (let [l (-> e :line)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
065 c (-> e :column)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
066 (join "\n"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 11 forms covered">
|
|
067 (map #(str (format "%5d %s" (inc %1) %2)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
068 (when (= l (inc %1))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 11 forms covered">
|
|
069 (str "\n" (apply str (repeat c " ")) "^")))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
070 (range)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
071 (split s #"\n"))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
072
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
073 (defn gsp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
074 "Shortcut macro - the internals of read; or, if you like, read-string.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
075 Argument `s` should be a string representation of a valid Lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
076 expression."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
077 [s]
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
078 (let [source (strip-line-comments s)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
079 parse-tree (parse source)]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
080 (if (instance? Failure parse-tree)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 8 forms covered">
|
|
081 (doall (println (number-lines source parse-tree))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 9 forms covered">
|
|
082 (throw (ex-info "Ne can forstande " (assoc parse-tree :source source))))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
083 (generate (simplify parse-tree)))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
084
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
085 (defn read-from-console
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
086 "Attempt to read a complete lisp expression from the console. NOTE that this
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
087 will only really work for S-Expressions, not M-Expressions."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
088 []
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
089 (loop [r (read-line)]
|
|
</span><br/>
|
|
<span class="partial" title="11 out of 12 forms covered">
|
|
090 (if (and (= (count (re-seq #"\(" r))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
091 (count (re-seq #"\)" r)))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
092 (= (count (re-seq #"\[" r))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
093 (count (re-seq #"\]" r))))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
094 r
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
095 (recur (str r "\n" (read-line))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
096
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
097 (defn READ
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
098 "An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
099 the final Lisp reader. `input` should be either a string representation of a LISP
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
100 expression, or else an input stream. A single form will be read."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
101 ([]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
102 (gsp (read-from-console)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
103 ([input]
|
|
</span><br/>
|
|
<span class="partial" title="2 out of 4 forms covered">
|
|
104 (cond
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 5 forms covered">
|
|
105 (empty? input) (READ)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
106 (string? input) (gsp input)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 9 forms covered">
|
|
107 (instance? InputStream input) (READ (slurp input))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
108 :else (throw (ex-info "READ: `input` should be a string or an input stream" {})))))
|
|
</span><br/>
|
|
</body>
|
|
</html>
|