From 87ccfb87fcdb5dba701d422d18e249f5a60afe7d Mon Sep 17 00:00:00 2001 From: Andreas Kostler Date: Thu, 14 Apr 2011 07:31:47 +1000 Subject: [PATCH] Project kick-off --- .gitignore | 4 +++ README | 13 ++++++++ project.clj | 4 +++ src/binj/core.clj | 72 +++++++++++++++++++++++++++++++++++++++++ test/binj/test/core.clj | 6 ++++ 5 files changed, 99 insertions(+) create mode 100644 .gitignore create mode 100644 README create mode 100644 project.clj create mode 100644 src/binj/core.clj create mode 100644 test/binj/test/core.clj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6eae6a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +pom.xml +*jar +lib +classes diff --git a/README b/README new file mode 100644 index 0000000..c96fe15 --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +# binj + +Erlany style Bin for Clojure + +## Usage + +ToDo + +## License + +Copyright (C) 2011 FIXME + +Distributed under the Eclipse Public License, the same as Clojure. diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..ce6b0e2 --- /dev/null +++ b/project.clj @@ -0,0 +1,4 @@ +(defproject binj "1.0.0-SNAPSHOT" + :description "FIXME: write" + :dependencies [[org.clojure/clojure "1.2.0"] + [org.clojure/clojure-contrib "1.2.0"]]) diff --git a/src/binj/core.clj b/src/binj/core.clj new file mode 100644 index 0000000..60f4f58 --- /dev/null +++ b/src/binj/core.clj @@ -0,0 +1,72 @@ +(ns binj.core) + + + +(defn << [& rest] + (let [rest + (if (and (= (count rest)) + (string? (first rest))) + (map int (first rest)) + rest)] + (flatten (map (fn [val] + (if (seq? val) + (apply decimal-to-bytelist val) + (bit-and val 0xff))) rest)))) +(defn decimal-to-bytelist + ([val] (decimal-to-bytelist val 8 1)) + ([val bits] (decimal-to-bytelist val bits 1)) + ([val bits unit] + (loop [bits (* bits unit) + val val + acc '()] + (if (<= bits 8) + (conj acc (bit-and val (dec (bit-shift-left 1 bits)))) + (recur (- bits 8) (bit-shift-right val 8) (conj acc (bit-and val 0xff))))))) + +(defn- reduce-bl [bl] + (reduce + (map #(* (bit-and %1 0xff) %2) + bl + (iterate #(bit-shift-left % 8) 1)))) + +(defn bytelist-to-decimal + ([bytelist] (reduce-bl (reverse bytelist))) + ([bytelist n] (reduce-bl (take n (reverse bytelist))))) + +(defn destructure-binvec [bin-vec] + (let [bdg-pairs (partition 2 (first bin-vec)) + bin (second bin-vec)] + (loop [bdgs (reverse bdg-pairs) + acc '() + bin (if (number? bin) bin + (bytelist-to-decimal bin))] + (if (empty? bdgs) acc + (let [bdg (first bdgs) + sym (first bdg) + val (second bdg)] + (recur (rest bdgs) + (conj (conj acc + (bit-and bin (dec (bit-shift-left 1 val)))) + sym) + (bit-shift-right bin val))))))) + +(defn foo [bindings] + (let [bdg-pair (partition 2 bindings)] + (loop [bdg bdg-pair + acc []] + (if (empty? bdg) acc + (let [b (first bdg) + bin (first b) + val (second b)] + (if (and (vector? bin) + (some number? bin)) + (recur (rest bdg) + (into acc (destructure-binvec b))) + (recur + (rest bdg) + (conj (conj acc bin) val)))))))) + + +(defmacro let-bin [bindings & body] + (let [bin (foo bindings)] + `(let [~@(destructure bin)] ~@body))) + diff --git a/test/binj/test/core.clj b/test/binj/test/core.clj new file mode 100644 index 0000000..e15a9ae --- /dev/null +++ b/test/binj/test/core.clj @@ -0,0 +1,6 @@ +(ns binj.test.core + (:use [binj.core] :reload) + (:use [clojure.test])) + +(deftest replace-me ;; FIXME: write + (is false "No tests have been written."))