Interop now working. Not all tests pass.
This commit is contained in:
parent
d6801ee443
commit
971a86e384
|
@ -10,7 +10,7 @@
|
||||||
therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
|
therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
|
||||||
objects."
|
objects."
|
||||||
(:require [clojure.string :as s]
|
(:require [clojure.string :as s]
|
||||||
[clojure.tools.trace :refer :all]
|
[clojure.tools.trace :refer [deftrace]]
|
||||||
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL T F]]))
|
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL T F]]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
`(if (= ~x NIL) T F))
|
`(if (= ~x NIL) T F))
|
||||||
|
|
||||||
(defmacro ATOM
|
(defmacro ATOM
|
||||||
"Returns `T` if and only is the argument `x` is bound to and atom; else `F`.
|
"Returns `T` if and only if the argument `x` is bound to an atom; else `F`.
|
||||||
It is not clear to me from the documentation whether `(ATOM 7)` should return
|
It is not clear to me from the documentation whether `(ATOM 7)` should return
|
||||||
`T` or `F`. I'm going to assume `T`."
|
`T` or `F`. I'm going to assume `T`."
|
||||||
[x]
|
[x]
|
||||||
|
@ -52,6 +52,12 @@
|
||||||
[x]
|
[x]
|
||||||
`(if (or (symbol? ~x) (number? ~x)) T NIL))
|
`(if (or (symbol? ~x) (number? ~x)) T NIL))
|
||||||
|
|
||||||
|
(defmacro NUMBERP
|
||||||
|
"Returns `T` if and only if the argument `x` is bound to an number; else `F`.
|
||||||
|
TODO: check whether floating point numbers, rationals, etc were numbers in Lisp 1.5"
|
||||||
|
[x]
|
||||||
|
`(if (number? ~x) T F))
|
||||||
|
|
||||||
(defn CAR
|
(defn CAR
|
||||||
"Return the item indicated by the first pointer of a pair. NIL is treated
|
"Return the item indicated by the first pointer of a pair. NIL is treated
|
||||||
specially: the CAR of NIL is NIL."
|
specially: the CAR of NIL is NIL."
|
||||||
|
@ -159,7 +165,6 @@
|
||||||
:else
|
:else
|
||||||
(make-cons-cell (CAR x) (APPEND (CDR x) y))))
|
(make-cons-cell (CAR x) (APPEND (CDR x) y))))
|
||||||
|
|
||||||
|
|
||||||
(defn MEMBER
|
(defn MEMBER
|
||||||
"This predicate is true if the S-expression `x` occurs among the elements
|
"This predicate is true if the S-expression `x` occurs among the elements
|
||||||
of the list `y`.
|
of the list `y`.
|
||||||
|
@ -192,6 +197,11 @@
|
||||||
(make-cons-cell (CAR x) (CAR y))
|
(make-cons-cell (CAR x) (CAR y))
|
||||||
(PAIRLIS (CDR x) (CDR y) a))))
|
(PAIRLIS (CDR x) (CDR y) a))))
|
||||||
|
|
||||||
|
(defmacro QUOTE
|
||||||
|
"Quote, but in upper case for LISP 1.5"
|
||||||
|
[f]
|
||||||
|
`(quote ~f))
|
||||||
|
|
||||||
(defn ASSOC
|
(defn ASSOC
|
||||||
"If a is an association list such as the one formed by PAIRLIS in the above
|
"If a is an association list such as the one formed by PAIRLIS in the above
|
||||||
example, then assoc will produce the first pair whose first term is x. Thus
|
example, then assoc will produce the first pair whose first term is x. Thus
|
||||||
|
@ -253,6 +263,18 @@
|
||||||
"/")))
|
"/")))
|
||||||
l))
|
l))
|
||||||
|
|
||||||
|
(defn to-clojure
|
||||||
|
"If l is a `beowulf.cons_cell.ConsCell`, return a Clojure list having the
|
||||||
|
same members in the same order."
|
||||||
|
[l]
|
||||||
|
(cond
|
||||||
|
(not (instance? beowulf.cons_cell.ConsCell l))
|
||||||
|
l
|
||||||
|
(= (CDR l) NIL)
|
||||||
|
(list (to-clojure (CAR l)))
|
||||||
|
:else
|
||||||
|
(conj (to-clojure (CDR l)) (to-clojure (CAR l)))))
|
||||||
|
|
||||||
(deftrace INTEROP
|
(deftrace INTEROP
|
||||||
"Clojure (or other host environment) interoperation API. `fn-symbol` is expected
|
"Clojure (or other host environment) interoperation API. `fn-symbol` is expected
|
||||||
to be either
|
to be either
|
||||||
|
@ -294,10 +316,11 @@
|
||||||
{:cause :interop
|
{:cause :interop
|
||||||
:detail :not-found
|
:detail :not-found
|
||||||
:name fn-symbol
|
:name fn-symbol
|
||||||
:also-tried l-name})))]
|
:also-tried l-name})))
|
||||||
(print (str "INTEROP: evaluating `" (cons f args) "`"))
|
args' (to-clojure args)]
|
||||||
|
(print (str "INTEROP: evaluating `" (cons f args') "`"))
|
||||||
(flush)
|
(flush)
|
||||||
(let [result (eval (read-string (str "(cons " f " " args ")")))] ;; this has the potential to blow up the world
|
(let [result (eval (conj args' f))] ;; this has the potential to blow up the world
|
||||||
(println (str "; returning `" result "`"))
|
(println (str "; returning `" result "`"))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
|
@ -373,6 +396,7 @@
|
||||||
"Essentially, identical to EVAL except traced."
|
"Essentially, identical to EVAL except traced."
|
||||||
[expr env]
|
[expr env]
|
||||||
(cond
|
(cond
|
||||||
|
(NUMBERP expr) expr
|
||||||
(=
|
(=
|
||||||
(ATOM? expr) T)
|
(ATOM? expr) T)
|
||||||
(CDR (ASSOC expr env))
|
(CDR (ASSOC expr env))
|
||||||
|
@ -398,12 +422,13 @@
|
||||||
(cond
|
(cond
|
||||||
(true? (:trace *options*))
|
(true? (:trace *options*))
|
||||||
(traced-eval expr env)
|
(traced-eval expr env)
|
||||||
|
(NUMBERP expr) expr
|
||||||
(=
|
(=
|
||||||
(ATOM? expr) T)
|
(ATOM? expr) T)
|
||||||
(CDR (ASSOC expr env))
|
(CDR (ASSOC expr env))
|
||||||
(=
|
(=
|
||||||
(ATOM? (CAR expr))
|
(ATOM? (CAR expr))
|
||||||
T)(cond
|
T) (cond
|
||||||
(= (CAR expr) 'QUOTE) (CADR expr)
|
(= (CAR expr) 'QUOTE) (CADR expr)
|
||||||
(= (CAR expr) 'COND) (EVCON (CDR expr) env)
|
(= (CAR expr) 'COND) (EVCON (CDR expr) env)
|
||||||
:else (APPLY
|
:else (APPLY
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
(rplacd
|
(rplacd
|
||||||
[this value]
|
[this value]
|
||||||
"replace the rest (but-first; cdr) of this sequence with this value")
|
"replace the rest (but-first; cdr) of this sequence with this value")
|
||||||
|
(getCar
|
||||||
|
[this]
|
||||||
|
"Return the first element of this sequence.")
|
||||||
(getCdr
|
(getCdr
|
||||||
[this]
|
[this]
|
||||||
"like `more`, q.v., but returns List `NIL` not Clojure `nil` when empty." ))
|
"like `more`, q.v., but returns List `NIL` not Clojure `nil` when empty." ))
|
||||||
|
@ -66,6 +69,8 @@
|
||||||
(str "Invalid value in RPLACD: `" value "` (" (type value) ")")
|
(str "Invalid value in RPLACD: `" value "` (" (type value) ")")
|
||||||
{:cause :bad-value
|
{:cause :bad-value
|
||||||
:detail :rplaca}))))
|
:detail :rplaca}))))
|
||||||
|
(getCar [this]
|
||||||
|
(. this CAR))
|
||||||
(getCdr [this]
|
(getCdr [this]
|
||||||
(. this CDR))
|
(. this CDR))
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
[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]
|
||||||
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]]))
|
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -93,7 +94,7 @@
|
||||||
([p]
|
([p]
|
||||||
(if
|
(if
|
||||||
(instance? instaparse.gll.Failure p)
|
(instance? instaparse.gll.Failure p)
|
||||||
(throw (ex-info "Ic ne behæfd" {: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
|
||||||
|
|
|
@ -51,6 +51,21 @@
|
||||||
actual (ATOM? (gsp "(A B C D)"))]
|
actual (ATOM? (gsp "(A B C D)"))]
|
||||||
(is (= actual expected) "A list is explicitly not an atom"))))
|
(is (= actual expected) "A list is explicitly not an atom"))))
|
||||||
|
|
||||||
|
(deftest numberp-tests
|
||||||
|
(testing "NUMBERP"
|
||||||
|
(let [expected T
|
||||||
|
actual (NUMBERP 7)]
|
||||||
|
(is (= actual expected) "7 is a number"))
|
||||||
|
(let [expected T
|
||||||
|
actual (NUMBERP 3.14)]
|
||||||
|
(is (= actual expected) "3.14 is a number"))
|
||||||
|
(let [expected F
|
||||||
|
actual (NUMBERP NIL)]
|
||||||
|
(is (= actual expected) "NIL is not a number"))
|
||||||
|
(let [expected F
|
||||||
|
actual (NUMBERP (gsp "HELLO"))]
|
||||||
|
(is (= actual expected) "HELLO is not a number"))))
|
||||||
|
|
||||||
(deftest access-function-tests
|
(deftest access-function-tests
|
||||||
(testing "CAR"
|
(testing "CAR"
|
||||||
(let [expected 'A
|
(let [expected 'A
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
(deftest interop-test
|
(deftest interop-test
|
||||||
(testing "INTEROP called from Clojure"
|
(testing "INTEROP called from Clojure"
|
||||||
(let [expected '123
|
(let [expected (symbol "123")
|
||||||
actual (INTEROP (gsp "(CLOJURE CORE STR)") (gsp "(1 2 3)"))]
|
actual (INTEROP (gsp "(CLOJURE CORE STR)") (gsp "(1 2 3)"))]
|
||||||
(is (= actual expected))))
|
(is (= actual expected))))
|
||||||
(testing "INTEROP called from Lisp"
|
(testing "INTEROP called from Lisp"
|
||||||
(let [expected 'ABC
|
(let [expected 'ABC
|
||||||
actual (EVAL (gsp "(INTEROP '(CLOJURE CORE STR) '('A 'B 'C)"))]
|
actual (EVAL (INTEROP '(CLOJURE CORE STR) '('A 'B 'C)) '())]
|
||||||
(is (= actual expected))))
|
(is (= actual expected))))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue