aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShagun Agrawal <agrawalshagun07@gmail.com>2024-07-28 22:02:14 +0530
committerShagun Agrawal <agrawalshagun07@gmail.com>2024-07-28 22:02:14 +0530
commit30f2e3d8008d52cdccd6dcc5ba5c602079469f49 (patch)
tree18aaa5282dcfa0c7a4ce8ec8d584206615f4aaff
parentb6de8db464151fa1300c5a47e508e9e792d034d0 (diff)
Refactor compiler driver, add running individual stages from cli
-rw-r--r--src/cljcc/cljcc.clj8
-rw-r--r--src/cljcc/driver.clj94
-rw-r--r--src/cljcc/util.clj8
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."