nil은 :scm/unresolved를 대신함
This commit is contained in:
1 parent
5359bc1c0a
commit
18e4fd09d5
2 files changed
+26
-19
No files matched your search
+19
-17
@@ -1,13 +1,11 @@
|
||||
(ns scm
|
||||
(:refer-clojure :exclude [read])
|
||||
(:require
|
||||
[clojure.core.match :refer [match]]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.pprint]
|
||||
[instaparse.core :as insta]
|
||||
[clojure.spec.alpha :as s])
|
||||
(:import
|
||||
(clojure.lang ILookup)))
|
||||
(:require [clojure.core.match :refer [match]]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.pprint]
|
||||
[instaparse.core :as insta]
|
||||
[clojure.spec.alpha :as s])
|
||||
(:import (clojure.lang ILookup)))
|
||||
|
||||
|
||||
;;; syntax objects
|
||||
@@ -20,13 +18,14 @@
|
||||
(satisfies? ISyntax x))
|
||||
|
||||
(deftype Syntax [datum ctx]
|
||||
:load-ns true ; 왜?
|
||||
Object
|
||||
(equals [x y]
|
||||
(or (identical? x y)
|
||||
(and (satisfies? ISyntax y)
|
||||
(.equals datum (syntax-e y))
|
||||
(.equals ctx (syntax-context y)))))
|
||||
ISyntax
|
||||
scm/ISyntax
|
||||
(syntax-e [this] datum)
|
||||
(syntax-context [this] ctx))
|
||||
|
||||
@@ -42,7 +41,8 @@
|
||||
;; 더 좋은 방법은 생각하고 있다. 모든 라이브러리나 프로그램은
|
||||
;; top-level scope를 짓겠는다. 그때 nil/#{}는 `::unresolved`를
|
||||
;; 대신하고 하나의 scope를 이루어진 집합은 #{}를 대신하겠는다.
|
||||
(= (syntax-context stx) ::unresolved))
|
||||
#_(= (syntax-context stx) ::unresolved)
|
||||
(empty? (syntax-context stx)))
|
||||
|
||||
(defn resolved? [stx]
|
||||
(not (unresolved? stx)))
|
||||
@@ -69,11 +69,11 @@
|
||||
(defn stx-reader [x]
|
||||
(if-let [[datum ctx] (and (vector? x) x)]
|
||||
(->Syntax datum ctx)
|
||||
(->Syntax x ::unresolved)))
|
||||
(->Syntax x nil)))
|
||||
|
||||
(defn datum->syntax
|
||||
([datum]
|
||||
(->Syntax datum ::unresolved))
|
||||
(->Syntax datum nil))
|
||||
([datum ctxt-donor]
|
||||
(->Syntax datum (syntax-context ctxt-donor))))
|
||||
|
||||
@@ -143,7 +143,9 @@
|
||||
instaparse {}}}]
|
||||
(let [r (insta/parse r7rs-parser text
|
||||
:start (if library? :library-start :datum-start)
|
||||
instaparse)]
|
||||
instaparse)
|
||||
#_#_scopeholder (when syntax?
|
||||
(->Syntax nil #{(new-scope "toplevel_")}))]
|
||||
(if (insta/failure? r)
|
||||
(if throw?
|
||||
(throw (ex-info "reader error" {:err r}))
|
||||
@@ -165,10 +167,10 @@
|
||||
;; 그라머에 datum을 감추지 않은 고러서 대신 여기 모든 datum을
|
||||
;; 과정할 수 있었더다. 작업 한 개만으로 syntax object들 다
|
||||
;; 만들 수 있어서 이럼은 더 좋다.
|
||||
:datum (fn [x]
|
||||
(if syntax?
|
||||
(datum->syntax x)
|
||||
x))
|
||||
:datum #(if syntax?
|
||||
#_(datum->syntax % scopeholder)
|
||||
(datum->syntax %)
|
||||
%)
|
||||
:number identity
|
||||
:symbol symbol
|
||||
:string (fn [& els]
|
||||
|
||||
+7
-2
@@ -1,6 +1,7 @@
|
||||
(ns scm-test
|
||||
(:require [scm :as sut]
|
||||
[clojure.test :as t]))
|
||||
[clojure.test :as t])
|
||||
(:import scm.ISyntax scm.Syntax))
|
||||
|
||||
(t/deftest read-test
|
||||
(t/testing "boolean"
|
||||
@@ -61,5 +62,9 @@
|
||||
(t/is (sut/syntax? #scm/stx [123 #{}]))
|
||||
(t/is (= 123 (sut/syntax-e #scm/stx [123 #{}]))))
|
||||
|
||||
(t/deftest resolved?-test
|
||||
(t/deftest unresolved?-test
|
||||
(t/is (sut/unresolved? (scm/->Syntax 123 nil)))
|
||||
(t/is (sut/unresolved? #scm/stx 123)))
|
||||
|
||||
(t/deftest resolved?-test
|
||||
(t/is (sut/resolved? (scm/->Syntax 123 '#{a}))))
|
||||
Reference in new issue
Block a user