Strict mode now works...
This commit is contained in:
parent
75bf19e38e
commit
fe6fba87e0
|
@ -19,8 +19,8 @@
|
|||
be Lisp 1.5's EQuivalent of `SETQ`), possibly by other things."
|
||||
(atom NIL))
|
||||
|
||||
(def ^:dynamic *trace?*
|
||||
"Whether or not to trace `EVAL`."
|
||||
(def ^:dynamic *options*
|
||||
"Command line options from invocation."
|
||||
false)
|
||||
|
||||
(defn NULL
|
||||
|
@ -304,7 +304,8 @@
|
|||
See page 13 of the Lisp 1.5 Programmers Manual."
|
||||
[expr env]
|
||||
(cond
|
||||
*trace?* (traced-eval expr env)
|
||||
(true? (:trace *options*))
|
||||
(traced-eval expr env)
|
||||
(=
|
||||
(ATOM? expr) 'T)
|
||||
(CDR (ASSOC expr env))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(ns beowulf.core
|
||||
(:require [beowulf.bootstrap :refer [EVAL oblist *trace?*]]
|
||||
(:require [beowulf.bootstrap :refer [EVAL oblist *options*]]
|
||||
[beowulf.read :refer [READ]]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.pprint :refer [pprint]]
|
||||
|
@ -40,6 +40,7 @@
|
|||
data
|
||||
(case (:cause data)
|
||||
:parse-failure (println (:failure data))
|
||||
:strict nil ;; the message, which has already been printed, is enough.
|
||||
:quit (throw e)
|
||||
;; default
|
||||
(pprint data))))))
|
||||
|
@ -60,7 +61,7 @@
|
|||
(if (:errors args)
|
||||
(apply str (interpose "; " (:errors args))))
|
||||
"\nSprecan 'quit' tó laéfan\n"))
|
||||
(binding [*trace?* (true? (:trace (:options args)))]
|
||||
(binding [*options* (:options args)]
|
||||
(try
|
||||
(repl (str (:prompt (:options args)) " "))
|
||||
(catch
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns beowulf.read
|
||||
(:require [clojure.math.numeric-tower :refer [expt]]
|
||||
(:require [beowulf.bootstrap :refer [*options*]]
|
||||
[clojure.math.numeric-tower :refer [expt]]
|
||||
[clojure.string :refer [starts-with? upper-case]]
|
||||
[instaparse.core :as i]
|
||||
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]]))
|
||||
|
@ -24,7 +25,7 @@
|
|||
|
||||
;; mexprs. I'm pretty clear that Lisp 1.5 could never read these,
|
||||
;; but it's a convenience.
|
||||
"mexpr := λexpr | fncall | defn | cond | mvar;
|
||||
"mexpr := λexpr | fncall | defn | cond | mvar | mexpr comment;
|
||||
λexpr := λ lsqb bindings semi-colon body rsqb;
|
||||
λ := 'λ';
|
||||
bindings := lsqb args rsqb;
|
||||
|
@ -41,9 +42,12 @@
|
|||
mvar := #'[a-z]+';
|
||||
semi-colon := ';';"
|
||||
|
||||
;; comments. I'm pretty confident Lisp 1.5 did NOT have these.
|
||||
"comment := opt-space <';;'> #'[^\\n\\r]*';"
|
||||
|
||||
;; 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.
|
||||
"sexpr := quoted-expr | atom | number | dotted-pair | list;
|
||||
"sexpr := quoted-expr | atom | number | dotted-pair | list | sexpr comment;
|
||||
list := lpar sexpr rpar | lpar (sexpr sep)* rpar | lpar (sexpr sep)* dot-terminal;
|
||||
dotted-pair := lpar dot-terminal ;
|
||||
dot := '.';
|
||||
|
@ -95,6 +99,11 @@
|
|||
(= context :mexpr)
|
||||
[:quoted-expr p]
|
||||
p)
|
||||
:comment (if
|
||||
(:strict *options*)
|
||||
(throw
|
||||
(ex-info "Cannot parse comments in strict mode"
|
||||
{:cause :strict})))
|
||||
:dotted-pair (if
|
||||
(= context :mexpr)
|
||||
[:fncall
|
||||
|
@ -103,7 +112,12 @@
|
|||
(simplify (nth p 1) context)
|
||||
(simplify (nth p 2) context)]]
|
||||
(map simplify p))
|
||||
:mexpr (simplify (second p) :mexpr)
|
||||
:mexpr (if
|
||||
(:strict *options*)
|
||||
(throw
|
||||
(ex-info "Cannot parse meta expressions in strict mode"
|
||||
{:cause :strict}))
|
||||
(simplify (second p) :mexpr))
|
||||
:list (if
|
||||
(= context :mexpr)
|
||||
[:fncall
|
||||
|
@ -115,7 +129,6 @@
|
|||
p)))
|
||||
|
||||
|
||||
|
||||
;; # From Lisp 1.5 Programmers Manual, page 10
|
||||
;; Note that I've retyped much of this, since copy/pasting out of PDF is less
|
||||
;; than reliable. Any typos are mine. Quote starts [[
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns beowulf.mexpr-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[beowulf.read :refer [parse simplify generate]]))
|
||||
[beowulf.bootstrap :refer [*options*]]
|
||||
[beowulf.read :refer [parse simplify generate gsp]]))
|
||||
|
||||
;; These tests are taken generally from the examples on page 10 of
|
||||
;; Lisp 1.5 Programmers Manual:
|
||||
|
@ -64,3 +65,10 @@
|
|||
(parse "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest strict-tests
|
||||
(testing "Strict feature"
|
||||
(binding [*options* {:strict true}]
|
||||
(is (thrown-with-msg?
|
||||
Exception
|
||||
#"Cannot parse meta expressions in strict mode"
|
||||
(gsp "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))))
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(:require [clojure.math.numeric-tower :refer [abs]]
|
||||
[clojure.test :refer :all]
|
||||
[beowulf.cons-cell :refer :all]
|
||||
[beowulf.read :refer [parse simplify generate]]))
|
||||
[beowulf.bootstrap :refer [*options*]]
|
||||
[beowulf.read :refer [parse simplify generate gsp]]))
|
||||
|
||||
;; broadly, sexprs should be homoiconic
|
||||
|
||||
|
@ -24,6 +25,32 @@
|
|||
actual (generate (simplify (parse (str expected))))]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest comment-tests
|
||||
(testing "Reading comments"
|
||||
(let [expected 'A
|
||||
actual (gsp "A ;; comment")]
|
||||
(is (= actual expected)))
|
||||
(let [expected 10
|
||||
actual (gsp "10 ;; comment")]
|
||||
(is (= actual expected)))
|
||||
(let [expected 2/5
|
||||
actual (gsp "4E-1 ;; comment")]
|
||||
(is (= actual expected)))
|
||||
(let [expected "(A B C)"
|
||||
actual (print-str (gsp "(A ;; comment
|
||||
B C)"))]
|
||||
(is (= actual expected)
|
||||
"Really important that comments work inside lists"))
|
||||
;; ;; TODO: Currently failing and I'm not sure why
|
||||
;; (binding [*options* {:strict true}]
|
||||
;; (is (thrown-with-msg?
|
||||
;; Exception
|
||||
;; #"Cannot parse comments in strict mode"
|
||||
;; (gsp "(A ;; comment
|
||||
;; B C)"))))
|
||||
))
|
||||
|
||||
|
||||
(deftest number-tests
|
||||
(testing "Reading octal numbers"
|
||||
(let [expected 1
|
||||
|
|
Loading…
Reference in a new issue