Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns main)
- (require '[clojure.string :as string])
- (defprotocol llvm_Code
- "A protocol for all types that map to llvm"
- (genCode [this] "llvm code version of the type"))
- (defrecord llvm_Integer [precision]
- llvm_Code
- (genCode [this]
- (str "i" precision)))
- (defrecord llvm_Struct [types]
- llvm_Code
- (genCode [this]
- (str "{" (string/join "," (map genCode types)) "}")))
- (defrecord llvm_Vector [elements type]
- llvm_Code
- (genCode [this]
- (str "<" elements 'x (genCode type) ">")))
- (defrecord llvm_Double []
- llvm_Code
- (genCode [this]
- (str "double")))
- (defrecord llvm_Void []
- llvm_Code
- (genCode [this]
- (str "void")))
- (defn mangle [x]
- (-> x
- (string/replace "_" "__")
- (string/replace ":" "_colon_")))
- (defn argPairGen [x]
- (str (genCode (x 0)) " %" (mangle (x 1))))
- (defn argListGenCode [x]
- (string/join ", " (map argPairGen x)))
- (defrecord llvm_Define [ret funcName args body]
- llvm_Code
- (genCode [this]
- (str "define " (genCode ret) " @" funcName "(" (argListGenCode args) "){ }")))
- (defrecord llvm_Pointer [toType]
- llvm_Code
- (genCode [this]
- (str (genCode toType) "*")))
- (defrecord llvm_Block [blocks]
- llvm_Code
- (genCode [this]
- (string/join "\n" (map genCode blocks))))
- (defrecord llvm_RetValue [retType value]
- llvm_Code
- (genCode [this]
- (str (genCode retType) " " (genCode value))))
- (defrecord llvm_RetVoid [a]
- llvm_Code
- (genCode [this] "ret void"))
- (defrecord llvm_Let [bindName statement]
- llvm_Code
- (genCode [this]
- (str '% (mangle bindName) " = " (genCode statement))))
- ;;; USABLE STUFF BELOW
- (defn lint
- "An specific precisiti on integer."
- [n]
- (assert (integer? n))
- (llvm_Integer. n))
- (defn lstruct [& types]
- (assert true) ; TODO if types is a map
- ; (apply print (map #(extends? llvm_Type %) types))
- (llvm_Struct. types))
- (defn lret
- ([] (llvm_RetVoid. nil))
- ([t v] (llvm_RetValue. t v)))
- (defn lp
- "llvm pointer"
- [t] (llvm_Pointer. t))
- (defn llet
- ([bindName value] (llvm_Let. bindName value)))
- (defn ldef [ret fname argList body]
- (llvm_Define. ret fname argList body))
- (defn lvoid llvm_Void.)
- ;; User-defined code
- (def lint32 (lint 32))
- (def lchar (lint8))
- (print (genCode (ldef lvoid :main [[lin32 :argc]
- [(lp (lp lchar)) :argv]]
- :body)))
- ;; wanna be code
- ;(ldecl printf ((lp li8), lvarargs))
- ;
- ;(ldefn lint32 main [[lint32 argc]
- ; [(lp (lp lchar)) argv]]
- ; (llet v (printf "Hello World!"))
- ; (lret v))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement