Permalink
Browse files

Redesigned the emitter

The emitter should now be easier to comprehend. The trick is that parent
expressions adds a :db/id key to it's child expressions. As before, the
emitter returns transaction data, but now in the form of maps.

Another substantial change is that I now derive 'child' (again) instead
of explicitly recording it in the database as :ast/child
  • Loading branch information...
1 parent 1be7108 commit c6dc541cbee8c00218798d98c1a873113c2bce12 @jonase committed Aug 8, 2012
Showing with 183 additions and 214 deletions.
  1. +1 −1 project.clj
  2. +88 −144 src/scape/core.clj
  3. +31 −19 src/scape/emitter.clj
  4. +48 −48 src/scape/rules.clj
  5. +15 −2 src/scape/schema.clj
View
@@ -7,4 +7,4 @@
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/clojurescript "0.0-1443"]
[domina "1.0.0-SNAPSHOT"]
- [com.datomic/datomic-free "0.8.3372"]])
+ [com.datomic/datomic-free "0.8.3397"]])
View
@@ -40,65 +40,46 @@
(println "AST transaction complete.")
(db conn)))))
- (def child-rule
- '[
- #_[[child ?parent ?child]
- [?parent :ast.if/test ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.if/then ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.if/else ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.def/init ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.fn/method ?method]
- [?method :ast.fn.method/statement ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.fn/method ?method]
- [?method :ast.fn.method/return ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.do/statement ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.do/return ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.let/binding ?binding]
- [?binding :ast.let.binding/init ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.let/statement ?child]]
- #_[[child ?parent ?child]
- [?parent :ast.let/return ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.invoke/f ?child]
- [?parent :ast.invoke/arg ?child]]
-
- #_[[child ?parent ?child]
- [?parent :ast.recur/arg ?child]]
-
- [[child ?a ?d]
- [?a :ast.default/child ?d]]])
+ ;; How many top-level forms?
+ (count (q '[:find ?e
+ :where
+ [?e :ast/top-level true]]
+ ast-db))
- (def ancestor
- '[[[ancestor ?ancestor ?descendant]
- [child ?ancestor ?descendant]]
- [[ancestor ?ancestor ?descendant]
- [?ancestor :ast.default/child ?middle-man]
- ;[child ?ancestor ?middle-man]
- [ancestor ?middle-man ?descendant]]])
+ ;; How many ast nodes are there in core.cljs?
+ (count (q '[:find ?e
+ :where
+ [?e :ast/ns :cljs.core]
+ [?e :ast/op]]
+ ast-db))
- (q '[:find ?descendant
- :in $ %
+ ;; What namespaces have been analyzed?
+ (q '[:find ?ns
:where
- [?map :ast.def/name :cljs.core/map]
- [?map :ast.def/init ?init]
- [ancestor ?init ?descendant]]
- ast-db
- (concat ancestor child-rule))
+ [_ :ast/ns ?ns]]
+ ast-db)
+
+ ;; What ops are in use?
+ (q '[:find ?op
+ :where [_ :ast/op ?op]]
+ ast-db)
+
+ ;; Where are no-ops?
+ (q '[:find ?line
+ :where
+ [?e :ast/op :no-op]
+ [?e :ast/line ?line]]
+ ast-db)
+ ;; What forms are on line 288?
+ (q '[:find ?form
+ :where
+ [?op :ast/op]
+ [?op :ast/line 288]
+ [?op :ast/form ?form]
+ [?op :ast/ns :domina]]
+ ast-db)
+
;; Find documentation and line number
(q '[:find ?line ?doc
:in $ ?name
@@ -112,18 +93,18 @@
(q '[:find ?line
:in $ ?sym
:where
- [?var :ast/op :var]
- [?var :ast.var/local false]
- [?var :ast/name ?sym]
+ [?var :ast.var/ns-qualified-name ?sym]
[?var :ast/line ?line]
[?var :ast/ns :domina]]
ast-db :cljs.core/map)
- ;; What are the most used local/var names?
- (->> (q '[:find ?var ?name
+ ;; What are the most used var names?
+ (->> (q '[:find ?var ?sym
+ :in $ ?local ?ns
:where
- [?var :ast.var/name ?name]]
- ast-db)
+ [?var :ast.var/name ?sym]
+ [?var :ast/ns ?ns]]
+ ast-db false :domina.events)
(map second)
frequencies
(sort-by second)
@@ -162,14 +143,13 @@
[?kw* :ast/form ?kw]]
ast-db)
- ;; Any local functions used?
+ ;; Any local functions invoked?
(sort-by second
(q '[:find ?name ?line
:where
- [?e :ast.invoke/f ?var]
- [?var :ast.var/local true]
- [?var :ast/line ?line]
- [?var :ast/name ?name]]
+ [_ :ast.invoke/f ?local]
+ [?local :ast/line ?line]
+ [?local :ast.local/name ?name]]
ast-db))
;;What op's are parents to recur?
@@ -209,10 +189,8 @@
;; What namespaces are used, and how many times?
(->> (q '[:find ?ns ?var
:where
- [?var :ast/op :var]
- [?var :ast/name ?name]
- [?var :ast.var/local false]
- [(namespace ?name) ?ns]]
+ [?var :ast.var/name]
+ [?var :ast.var/ns ?ns]]
ast-db)
(map first)
frequencies
@@ -221,13 +199,12 @@
;; What vars from namespace x are used in namespace y?
(q '[:find ?var-name
- :in $ % ?x ?y
+ :in $ ?x ?y
:where
- [?var :ast/op :var]
- [?var :ast/name ?var-name]
+ [?var :ast.var/ns ?x]
[?var :ast/ns ?y]
- [namespace ?var ?x]]
- ast-db rules/namespace :cljs.core :domina.events)
+ [?var :ast.var/name ?var-name]]
+ ast-db :cljs.core :domina.events)
;; Who's calling my namespace?
(q '[:find ?ns
@@ -241,105 +218,72 @@
;; Who's using my fn (and on what line)?
(q '[:find ?ns ?line
- :in $ % ?my-var
+ :in $ ?my-var
:where
- [?var :ast/name ?my-var]
+ [?var :ast.var/ns-qualified-name ?my-var]
[?var :ast/line ?line]
[?var :ast/ns ?ns]
- [namespace ?var ?my-ns]
+ [?var :ast.var/ns ?my-ns]
[(not= ?ns ?my-ns)]]
- ast-db rules/namespace :cljs.core/filter)
+ ast-db :cljs.core/filter)
;; What vars (from other namespaces) are used from my ns?
(q '[:find ?var-name
- :in $ % ?my-ns
+ :in $ ?my-ns
:where
- [?var :ast/name ?var-name]
[?var :ast/ns ?my-ns]
- [namespace ?var ?ns]
- [(not= ?ns ?my-ns)]
- [(not= ?ns nil)]]
- ast-db rules/namespace :domina.css)
+ [?var :ast.var/name ?var-name]
+ [?var :ast.var/ns ?ns]
+ [(not= ?ns ?my-ns)]]
+ ast-db :domina.css)
;; Which function in core is used most (outside core itself)
(->> (q '[:find ?var ?var-name
- :in $ %
:where
- [?var :ast/op :var]
- [?var :ast/name ?var-name]
+ [?var :ast.var/ns :cljs.core]
+ [?var :ast.var/name ?var-name]
[?var :ast/ns ?var-ns]
- [namespace ?var :cljs.core]
[(not= ?var-ns :cljs.core)]]
- ast-db
- rules/namespace)
+ ast-db)
(map second)
frequencies
(sort-by second)
reverse)
- ;; What op's can we figure out the type of?
- (q '[:find ?op
- :in $ %
- :where
- [?e :ast/op ?op]
- [type ?e _]]
- ast-db rules/type)
-
- ;; Enumerate type/op/line/ns of known types
- (seq (q '[:find ?type ?op ?line ?ns
- :in $ %
- :where
- [?e :ast/op ?op]
- [?e :ast/line ?line]
- [?e :ast/ns ?ns]
- [type ?e ?type]]
- ast-db rules/type))
-
;; What functions does ?my-fn invoke?
(q '[:find ?fn-name
:in $ % ?my-fn
:where
- [?def :db/ident ?my-fn]
- [descendant ?def ?invoke]
- [?invoke :ast/op :invoke]
+ [?def :ast.def/name ?my-fn]
+ [ancestor ?def ?invoke]
[?invoke :ast.invoke/f ?f]
- [?f :ast.var/local false]
- [?f :ast/name ?fn-name]]
- ast-db rules/descendant :cljs.core/map)
+ [?f :ast.var/name ?fn-name]]
+ ast-db
+ (concat rules/ancestor rules/child)
+ :cljs.core/map)
+
+ (def transitive-var
+ '[[[transitive-var ?e ?v]
+ [ancestor ?e ?v]
+ [?v :ast.var/name]]
+ [[transitive-var ?e ?v]
+ [ancestor ?e ?v*]
+ [?v* :ast.var/ns-qualified-name ?name]
+ [?ve :ast.def/name ?name]
+ [transitive-var ?ve ?v]]])
;; Transitive var dependency
;; Could be used for tree shaking?
(q '[:find ?var-name
- :in $ % ?my-fn
+ :in $ % ?my-def
:where
- [?def :db/ident ?my-fn]
- [transitive-var-dep ?def ?var]
- [?var :ast/name ?var-name]
- ]
+ [?def :ast.def/name ?my-def]
+ [transitive-var ?def ?var]
+ [?var :ast.var/name ?var-name]]
ast-db
- (concat rules/descendant
- rules/transitive-var-dep)
+ (concat transitive-var
+ rules/ancestor
+ rules/child)
:cljs.core/map)
- ;;=>
- ;; #<HashSet [[:cljs.core/chunk-append],
- ;; [:cljs.core/seq],
- ;; [:cljs.core/rest],
- ;; [:cljs.core/chunk],
- ;; [:cljs.core/every?],
- ;; [:cljs.core/conj],
- ;; [:cljs.core/chunk-buffer],
- ;; [:cljs.core/first],
- ;; [:cljs.core/cons],
- ;; [:cljs.core/chunk-cons],
- ;; [:cljs.core/apply],
- ;; [:cljs.core/count],
- ;; [:cljs.core/-nth],
- ;; [:cljs.core/chunk-rest],
- ;; [:cljs.core/chunked-seq?],
- ;; [:cljs.core/chunk-first],
- ;; [:cljs.core/identity],
- ;; [:cljs.core/LazySeq]]>
-
-
)
Oops, something went wrong.

0 comments on commit c6dc541

Please sign in to comment.