diff options
| author | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-07-28 22:02:14 +0530 |
|---|---|---|
| committer | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-07-28 22:02:14 +0530 |
| commit | 30f2e3d8008d52cdccd6dcc5ba5c602079469f49 (patch) | |
| tree | 18aaa5282dcfa0c7a4ce8ec8d584206615f4aaff /src/cljcc | |
| parent | b6de8db464151fa1300c5a47e508e9e792d034d0 (diff) | |
Refactor compiler driver, add running individual stages from cli
Diffstat (limited to 'src/cljcc')
| -rw-r--r-- | src/cljcc/cljcc.clj | 8 | ||||
| -rw-r--r-- | src/cljcc/driver.clj | 94 | ||||
| -rw-r--r-- | src/cljcc/util.clj | 8 |
3 files changed, 60 insertions, 50 deletions
diff --git a/src/cljcc/cljcc.clj b/src/cljcc/cljcc.clj index 6708173..8c8211d 100644 --- a/src/cljcc/cljcc.clj +++ b/src/cljcc/cljcc.clj @@ -2,7 +2,6 @@ (:require [clojure.tools.cli :refer [parse-opts]] [clojure.string :as string] - [cljcc.log :as log] [cljcc.util :refer [exit]] [cljcc.driver :as d]) (:gen-class)) @@ -37,6 +36,7 @@ (if exit-message (exit (if ok? 0 1) exit-message) (try - (d/run file-path options) - (catch Exception e (exit 1 (.getMessage e))) - (finally (exit 0 "Succesfully ran compiler.")))))) + (d/run file-path options) + (exit 0 "Successfully executed.") + (catch Exception e + (exit 1 (ex-message e))))))) diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj index a06c9a3..ad9c3a4 100644 --- a/src/cljcc/driver.clj +++ b/src/cljcc/driver.clj @@ -1,23 +1,18 @@ (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?]] - [cljcc.parser :as p])) + (:require + [clojure.java.io :as io] + [cljcc.compiler :as c] + [cljcc.log :as log] + [cljcc.util :refer [get-os handle-sh mac-aarch64? make-file-name]] + [cljcc.parser :as p])) -(defn make-file-name - ([filename ext] - (str filename "." ext)) - ([directory filename ext] - (str directory "/" filename "." ext))) - -(defn handle-os [] +(defn validate-os [] (let [os (get-os)] (condp = os - :linux (println "running on linux") + :linux (log/info "Running on Linux.") :mac (if (mac-aarch64?) - (println "running on mac arch 64") - (println "running on mac")) + (log/info "Running on Mac ARM64.") + (log/info "Running on Mac x86_64.")) :unsupported (throw (Exception. (str os " is not currently supported.")))))) (defn remove-extension [^String filename] @@ -25,41 +20,64 @@ (.substring filename 0 (.lastIndexOf filename ".")) filename)) -(defn preprocess [directory filename] +(defn preprocessor-step [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. ^String (:out output))) - (println (str "Successfully preprocessed file: " preprocessed-file-path))))) + (throw (Exception. ^String (:err output))) + (log/info (str "Successfully preprocessed file: " preprocessed-file-path))))) -(defn assemble [directory filename] +(defn assemble-step [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. ^String (:out output))) - (println (str "Successfully created executable at: " output-file output))))) + (throw (Exception. ^String (:err output))) + (log/info (str "Successfully created executable at: " output-file))))) -(defn run-compile [directory filename] +(defn parser-step [directory filename] + (let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i") + file (io/file preprocessed-file-path) + source (slurp file)] + (if (p/parseable? (p/parse source)) + (log/info "Input file is succesfully parsed.") + (throw (Exception. "Failed during parsing"))))) + +(defn compiler-step [directory filename] (let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i") file (io/file preprocessed-file-path) source (slurp file) - _ (if (p/parseable? (p/parse source)) - (println "Parsing successfull.") - (throw (Exception. "Failed during parsing"))) 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))) + (log/info (str "Succesfully generated assembly file.\n" assembled-source)))) -(defn cleanup [directory filename] +(defn cleanup-step [directory filename] (let [file-without-ext (remove-extension filename)] (io/delete-file (make-file-name directory file-without-ext "i") true) (io/delete-file (make-file-name directory file-without-ext "s") true))) +(defn create-steps [options directory filename] + (let [base-steps [(partial validate-os) + (partial preprocessor-step directory filename)] + parser-step-fn (partial parser-step directory filename) + compiler-step-fn (partial compiler-step directory filename) + assemble-step-fn (partial assemble-step directory filename) + cleanup-step-fn (partial cleanup-step directory filename)] + (cond + (:parse options) (concat base-steps + [parser-step-fn cleanup-step-fn]) + (:codegen options) (concat base-steps + [parser-step-fn compiler-step-fn cleanup-step-fn]) + :else (concat base-steps + [parser-step-fn compiler-step-fn assemble-step-fn cleanup-step-fn])))) + +(defn run-steps [options directory filename] + (let [steps (create-steps options directory filename)] + (run! #(apply % []) steps))) + (defn run "Runs the compiler driver with the given input source file." [^String file-path options] @@ -67,26 +85,12 @@ filename (.getName file) directory (.getParent file)] (try - (handle-os) - (preprocess directory filename) - (run-compile directory filename) - (assemble directory filename) - (println "Successfully created executable at " directory " for filename " filename) - (catch Exception e - (println "Caught exception: " (.getMessage e)) - (cleanup directory filename) - (throw (Exception. "Failed to run compiler."))) + (run-steps options directory filename) (finally - (cleanup directory filename))))) + (cleanup-step directory filename))))) (comment - (run "/Users/shagunagrawal/Development/c_tests/ex3.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") + (run "/Users/shagunagrawal/Development/c_tests/ex3.c" {}) ,) diff --git a/src/cljcc/util.clj b/src/cljcc/util.clj index 81419e4..6c6c88e 100644 --- a/src/cljcc/util.clj +++ b/src/cljcc/util.clj @@ -2,6 +2,12 @@ (:require [clojure.java.shell :refer [sh]] [cljcc.log :as log])) +(defn make-file-name + ([^String filename ^String ext] + (str filename "." ext)) + ([directory filename ext] + (str directory "/" filename "." ext))) + (defn get-os [] (let [os-name (.toLowerCase (System/getProperty "os.name"))] (cond @@ -10,7 +16,7 @@ :else :unsupported))) (defn mac-aarch64? [] - (and (= :mac (get-os)) (= (System/getProperty "os.arch" "aarch64")))) + (and (= :mac (get-os)) (= (System/getProperty "os.arch") "aarch64"))) (defn handle-sh "Preprends arch -x86_64 if running under Mac M chips." |
