Permalink
Browse files

Initial commit.

  • Loading branch information...
0 parents commit 3fd11643d6aabdeea7dc1ce3a7e43b24845477f8 @technomancy committed Apr 24, 2011
Showing with 129 additions and 0 deletions.
  1. +6 −0 .gitignore
  2. +36 −0 README.md
  3. +4 −0 project.clj
  4. +54 −0 src/slam/hound.clj
  5. +29 −0 test/slamhound/test_reconstruct.clj
@@ -0,0 +1,6 @@
+pom.xml
+*jar
+/lib/
+/classes/
+.lein-failures
+.lein-deps-sum
@@ -0,0 +1,36 @@
+# Slamhound
+
+ They sent a slamhound on Turner's trail in New Delhi, slotted it
+ to his pheromones and the color of his hair. It caught up with him
+ on a street called Chandni Chauk and came scrambling for his
+ rented BMW through a forest of bare brown legs and pedicab
+ tires. Its core was a kilogram of recrystallized hexogene and
+ flaked TNT. He didn't see it coming. The last he saw of India was
+ the pink stucco facade of a place called the Khush-Oil Hotel.
+
+ Because he had a good agent, he had a good contract. Because he
+ had a good contract, he was in Singapore an hour after the
+ explosion. Most of him, anyway. The Dutch surgeon liked to joke
+ about that, how an unspecified percentage of Turner hadn't made it
+ out of Palam International on that first flight and had to spend
+ the night there in a shed, in a support vat.
+
+ It took the Dutchman and his team three months to put Turner
+ together again. They cloned a square meter of skin for him, grew
+ it on slabs of collagen and shark-cartilage polysaccharides. They
+ bought eyes and genitals on the open market. The eyes were green.
+
+ -- Count Zero, page 1. By William Gibson
+
+Slamhound rips your ns form apart and reconstructs it. No Dutch
+surgeon required.
+
+## Usage
+
+ $ lein slamhound my.namespace
+
+## License
+
+Copyright (C) 2011 Phil Hagelberg
+
+Distributed under the Eclipse Public License, the same as Clojure.
@@ -0,0 +1,4 @@
+(defproject slamhound "1.0.0-SNAPSHOT"
+ :description
+ "Rips your ns form apart and reconstructs it. We have the technology."
+ :eval-in-leiningen true)
@@ -0,0 +1,54 @@
+(ns slam.hound
+ (:use [clojure.java.io :only [reader]])
+ (:import (java.io PushbackReader)))
+
+(def ns-clauses [:refer-clojure :use :require :import])
+
+(defn ns-to-map [ns-form]
+ (let [[_ ns-name doco & clauses] ns-form
+ ns-meta (meta ns-name)
+ [ns-meta clauses] (if (string? doco)
+ [(assoc ns-meta :doc doco) clauses]
+ [ns-meta (cons doco clauses)])]
+ (into {:meta ns-meta :name ns-name}
+ (map (juxt first rest) clauses))))
+
+(defn ns-from-map [ns-map]
+ `(~'ns ~(:name ns-map)
+ ~(:doc (:meta ns-map))
+ ~@(for [clause-type ns-clauses
+ :when (clause-type ns-map)]
+ (cons clause-type (clause-type ns-map)))))
+
+(defn missing-var [e]
+ (->> (.getMessage e)
+ (re-seq #"Unable to resolve symbol: (\w+) in this context")
+ (second)
+ (symbol)))
+
+(defn check-for-failure [ns-map body]
+ (try (eval `(do ~(ns-from-map ns-map) ~@body))
+ nil
+ (catch Exception e
+ (missing-var e))))
+
+(defn resolve-failure [failure ns-map]
+ ;; tricky bits
+ )
+
+(defn reconstruct-ns-form [ns-map body]
+ (if-let [failure (check-for-failure ns-map body)]
+ (recur (resolve-failure failure ns-map) body)))
+
+(defn write-new-ns [filename ns-map]
+ ;; very tricky bits
+ )
+
+(defn reconstruct
+ ([filename]
+ (let [rdr (PushbackReader. (reader filename))
+ ns-map (ns-to-map (read rdr))
+ stripped-ns (apply dissoc ns-map (rest ns-clauses))
+ body (take-while #(not= ::done %)
+ (repeatedly #(read rdr false ::done)))]
+ (write-new-ns filename (reconstruct-ns-form stripped-ns body)))))
@@ -0,0 +1,29 @@
+(ns slamhound.test-reconstruct
+ "Testing some things going on here."
+ (:use [clojure.test]
+ [slam.hound]))
+
+(def sample-ns-form '(ns slamhound.test-reconstruct
+ "Testing some things going on here."
+ (:refer-clojure :exclude [compile test])
+ (:use [clojure.test]
+ [clojure.zip :only [zipper up]]
+ [slam.hound])
+ (:require [clojure.java.io :as io]
+ [clojure.set :as set])
+ (:import (java.io File ByteArrayInputStream)
+ (java.util UUID))))
+
+(def sample-ns-map
+ {:name 'slamhound.test-reconstruct
+ :meta {:doc "Testing some things going on here."}
+ :use '([clojure.test] [clojure.zip :only [zipper up]] [slam.hound])
+ :require '([clojure.java.io :as io] [clojure.set :as set])
+ :import '((java.io File ByteArrayInputStream) (java.util UUID))
+ :refer-clojure '(:exclude [compile test])})
+
+(deftest test-ns-to-map
+ (is (= sample-ns-map (ns-to-map sample-ns-form))))
+
+(deftest test-ns-from-map
+ (is (= sample-ns-form (ns-from-map sample-ns-map))))

0 comments on commit 3fd1164

Please sign in to comment.