 
 (defn generate-vhdl [& entities]
   (do
-    (println "library ieee;")
-    (println "use ieee.std_logic_1164.all;")
+    (println "LIBRARY ieee;")
+    (println "USE ieee.std_logic_1164.all;")
     (println (to-vhdl (first entities)))))

  (:use clojure.contrib.str-utils))


(def std-logic "std_logic")

(defn std-logic-vector [start end]
  (str "std_logic_vector(" start " downto " end ")"))


(defn indented-lines [strings] (map (partial str "  ") strings))


(defmethod to-vhdl :process [[type ports & definition]]
  (list
    (str "PROCESS(" (str-join "," (map keyword-to-str ports)) ")")
    "BEGIN"
    (with-meta (map to-vhdl definition) {:noindent true})
    "END PROCESS;"))

(defmethod to-vhdl :case [[type target & cases]]
  (list
    (spaces "CASE" (keyword-to-str target) "IS")
    (map #(str (spaces "WHEN" (quoted-str (first %)) "=>" (to-vhdl (second %))) \;)
         (partition 2 cases))
    "END CASE;"))

; does not generate lines like block-level methods do
(defmethod to-vhdl :<= [[type target expression]]
  (spaces (keyword-to-str target) "<=" (keyword-to-str expression)))

(defmethod to-vhdl :signal [[type sig type]]
  (str "SIGNAL " (name sig) " : " type ";"))

(defmethod to-vhdl :deftype [[type name values]]
  (let [valuelist (str-join ", " values)]
    (spaces "TYPE" name "IS" "(" valuelist ");")))

(defmethod to-vhdl :if [[type condition & body]]
  (list
    (spaces "IF" (to-vhdl condition) "THEN")
    (with-meta (map to-vhdl body) {:noindent true})
    "END IF;"))

(defmethod to-vhdl :and [[type condA condB]]
  (spaces (to-vhdl condA) "AND" (to-vhdl condB)))

(defmethod to-vhdl :event [[type target]]
  (str (keyword-to-str target) "'EVENT"))
