aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc/driver.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/cljcc/driver.clj')
-rw-r--r--src/cljcc/driver.clj82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj
new file mode 100644
index 0000000..960bd1f
--- /dev/null
+++ b/src/cljcc/driver.clj
@@ -0,0 +1,82 @@
+(ns cljcc.driver
+ (:require [clojure.java.shell :refer [sh]]
+ [clojure.java.io :as io]
+ [cljcc.compiler :as c]
+ [cljcc.util :refer [get-os handle-sh mac-aarch64?]]))
+
+(defn make-file-name
+ ([filename ext]
+ (str filename "." ext))
+ ([directory filename ext]
+ (str directory "/" filename "." ext)))
+
+(defn handle-os []
+ (let [os (get-os)]
+ (condp = os
+ :linux (println "running on linux")
+ :mac (if (mac-aarch64?)
+ (println "running on mac arch 64")
+ (println "running on mac"))
+ :unsupported (throw (Exception. (str os " is not currently supported."))))))
+
+(defn remove-extension [filename]
+ (if (.contains filename ".")
+ (.substring filename 0 (.lastIndexOf filename "."))
+ filename))
+
+(defn preprocess [directory filename]
+ (let [input-file-path (make-file-name directory (remove-extension filename) "c")
+ preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
+ output (handle-sh "gcc" "-E" "-P" input-file-path "-o" preprocessed-file-path)]
+ (if (= 1 (:exit output))
+ (throw (Exception. (:out output)))
+ (println (str "Successfully preprocessed file: " preprocessed-file-path)))))
+
+(defn assemble [directory filename]
+ (let [file-without-ext (remove-extension filename)
+ assembly-file (make-file-name directory file-without-ext "s")
+ output-file (str directory "/" file-without-ext)
+ output (handle-sh "gcc" assembly-file "-o" output-file)]
+ (println file-without-ext assembly-file output-file output)
+ (if (= 1 (:exit output))
+ (throw (Exception. (:out output)))
+ (println (str "Successfully created executable at: " output-file output)))))
+
+(defn run-compile [directory filename]
+ (let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
+ file (io/file preprocessed-file-path)
+ source (slurp file)
+ assembled-source (c/run-compile source)
+ out-file-path (make-file-name directory (remove-extension filename) "s")]
+ (spit out-file-path assembled-source)
+ (println "succesfully generated .s file" assembled-source)))
+
+(defn cleanup [directory filename]
+ (let [file-without-ext (remove-extension filename)]
+ (sh "rm" (make-file-name directory file-without-ext "i"))
+ (sh "rm" (make-file-name directory file-without-ext "s"))))
+
+(defn run
+ "Runs the compiler driver with the given input source file."
+ [file-path]
+ (let [file (io/file file-path)
+ filename (.getName file)
+ directory (.getParent file)]
+ (handle-os)
+ (preprocess directory filename)
+ (run-compile directory filename)
+ (assemble directory filename)
+ (cleanup directory filename)
+ (println "Successfully created executable at " directory " for filename " filename)))
+
+(comment
+
+ (run "/Users/shagunagrawal/Development/c_tests/ex2.c")
+
+ (assemble "/Users/shagunagrawal/Development/c_tests" "ex2.c")
+
+ (handle-sh "gcc" "-E" "-P" "/Users/shagunagrawal/Development/c_tests/ex2.c" "-o" "/Users/shagunagrawal/Development/c_tests/out.i")
+
+ (sh "gcc" "-E" "-P" "/Users/shagunagrawal/Development/c_tests/ex1.c" "-o" "/Users/shagunagrawal/Development/c_tests/out.i")
+
+ ,)