Reader now reads from file, and ignores (some) comments

This commit is contained in:
Simon Brooke 2021-02-05 18:01:48 +00:00
parent 78f2cc39f0
commit d049c7ec40
2 changed files with 106 additions and 83 deletions

View file

@ -0,0 +1,11 @@
;; Test comment
(DEFINE
(APPEND
(LAMBDA
(X Y)
(COND ((NULL X) Y) (T (CONS (CAR X) (APPEND (CDR X Y)))))))
(CONC
(LAMBDA
(X Y)
(COND ((NULL (CDR X)) (RPLACD X Y)) (T (CONC (CDR X) Y)))
X)))

View file

@ -14,11 +14,14 @@
Both these extensions can be disabled by using the `--strict` command line Both these extensions can be disabled by using the `--strict` command line
switch." switch."
(:require [beowulf.bootstrap :refer [*options*]] (:require [beowulf.bootstrap :refer [*options*]]
[clojure.java.io :refer [file reader]]
[clojure.math.numeric-tower :refer [expt]] [clojure.math.numeric-tower :refer [expt]]
[clojure.string :refer [starts-with? upper-case]] [clojure.string :refer [starts-with? upper-case]]
[instaparse.core :as i] [instaparse.core :as i]
[instaparse.failure :as f] [instaparse.failure :as f]
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]])) [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]])
(:import [java.io InputStream PushbackReader]
[instaparse.gll Failure]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
@ -35,6 +38,8 @@
be operated upon further." be operated upon further."
(i/parser (i/parser
(str (str
;; we tolerate whitespace and comments around legitimate input
"raw := expr | opt-comment expr opt-comment;"
;; top level: we accept mexprs as well as sexprs. ;; top level: we accept mexprs as well as sexprs.
"expr := mexpr | sexpr ;" "expr := mexpr | sexpr ;"
@ -58,7 +63,8 @@
semi-colon := ';';" semi-colon := ';';"
;; comments. I'm pretty confident Lisp 1.5 did NOT have these. ;; comments. I'm pretty confident Lisp 1.5 did NOT have these.
"comment := opt-space <';;'> #'[^\\n\\r]*';" "opt-comment := opt-space | comment;"
"comment := opt-space <';;'> #'[^\\n\\r]*' opt-space;"
;; sexprs. Note it's not clear to me whether Lisp 1.5 had the quote macro, ;; sexprs. Note it's not clear to me whether Lisp 1.5 had the quote macro,
;; but I've included it on the basis that it can do little harm. ;; but I've included it on the basis that it can do little harm.
@ -93,8 +99,9 @@
an `ex-info`, with `p` as the value of its `:failure` key." an `ex-info`, with `p` as the value of its `:failure` key."
([p] ([p]
(if (if
(instance? instaparse.gll.Failure p) (instance? Failure p)
(throw (ex-info (str "Ic ne behæfd: " (f/pprint-failure p)) {:cause :parse-failure :failure p})) (throw (ex-info (str "Ic ne behæfd: " (f/pprint-failure p)) {:cause :parse-failure
:failure p}))
(simplify p :sexpr))) (simplify p :sexpr)))
([p context] ([p context]
(if (if
@ -114,7 +121,7 @@
(= context :mexpr) (= context :mexpr)
[:quoted-expr p] [:quoted-expr p]
p) p)
:comment (if (:comment :opt-comment) (if
(:strict *options*) (:strict *options*)
(throw (throw
(ex-info "Cannot parse comments in strict mode" (ex-info "Cannot parse comments in strict mode"
@ -139,6 +146,7 @@
[:mvar "list"] [:mvar "list"]
[:args (apply vector (map simplify (rest p)))]] [:args (apply vector (map simplify (rest p)))]]
(map #(simplify % context) p)) (map #(simplify % context) p))
:raw (first (remove empty? (map simplify (rest p))))
;;default ;;default
p))) p)))
p))) p)))
@ -311,6 +319,10 @@
(defn READ (defn READ
"An implementation of a Lisp reader sufficient for bootstrapping; not necessarily "An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
the final Lisp reader." the final Lisp reader. `input` should be either a string representation of a LISP
expression, or else an input stream. A single form will be read."
[input] [input]
(gsp (or input (read-line)))) (cond
(string? input) (gsp (or input (read-line)))
(instance? InputStream input) (READ (slurp input))
:else (throw (ex-info "READ: `input` should be a string or an input stream" {}))))