Skip to content

Instantly share code, notes, and snippets.

@hiredman
Created October 31, 2009 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiredman/222974 to your computer and use it in GitHub Desktop.
Save hiredman/222974 to your computer and use it in GitHub Desktop.
(defn shell [cmd]
(-> (Runtime/getRuntime) (.exec cmd)))
(defn is->string [is]
(let [sb (StringBuilder.)]
(loop [ch (.read is)]
(if (= (int ch) -1)
(.toString sb)
(do (.append sb (char ch))
(recur (.read is)))))))
(defmulti clojurec (comp :tag meta))
(defmethod clojurec :proc [p]
(let [[name- args & body] p
args (pr-str (into () args))
return (name (:tag (meta name-)))
body (apply str (map clojurec body))]
(format "\n%s %s %s\n{\n%s\n}\n" return name- args body)))
(defmethod clojurec := [assn]
(let [type (name (:tag (meta (first assn))))
name- (name (first assn))
value (second assn)]
(format "%s %s = %s;\n" type name- value)))
(defmethod clojurec :call [call]
(let [name (first call)
args (rest call)]
(format "%s%s;" name args)))
(defmethod clojurec :c-program [prog]
(let [body (apply str (map clojurec prog))
m (meta prog)
cmd (format "%s %s -o %s" (:compiler m) (:file-name m) (:binary-file m))]
(with-open [o (-> m :file-name java.io.File. java.io.FileWriter.)]
(.write o body))
(shell cmd)
`(fn [] (shell (format "./%s" ~(:binary-file m))))))
(defmacro cc [x]
(clojurec x))
;; example
(cc
#^{:tag :c-program :compiler "gcc" :file-name "test.c" :binary-file "test"}
[#^:proc (#^:int main []
#^:= (#^int x 1)
#^:call (printf "foo\n"))])
;; at repl
user=>
(cc
#^{:tag :c-program :compiler "gcc" :file-name "test.c" :binary-file "test"}
[#^:proc (#^:int main []
#^:= (#^int x 1)
#^:call (printf "foo\n"))])
#<user$eval__759$fn__761 user$eval__759$fn__761@1b17d49>
user=> (-> *1 (apply nil) .getInputStream is->string)
"foo\n"
user=>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment