diff options
| author | Your Name <agrawalshagun07@gmail.com> | 2025-03-16 02:00:40 +0530 |
|---|---|---|
| committer | Your Name <agrawalshagun07@gmail.com> | 2025-03-16 02:00:40 +0530 |
| commit | 0321df3708cfa4d1440faf3f407611df85484b4b (patch) | |
| tree | 8c23154afaf1afd78363eb0fa639edd5d8a32821 /cli/src | |
| parent | e458b2fadee1eaf0a6cf4ed4881da6f3f25acc21 (diff) | |
Refactor files to cljcc-compiler and cli tool.
Diffstat (limited to 'cli/src')
| -rw-r--r-- | cli/src/cli/cli.clj | 51 | ||||
| -rw-r--r-- | cli/src/cli/core/log.clj | 28 | ||||
| -rw-r--r-- | cli/src/cli/core/shell.clj | 31 | ||||
| -rw-r--r-- | cli/src/cli/driver.clj | 3 | ||||
| -rw-r--r-- | cli/src/cli/log.clj | 28 |
5 files changed, 141 insertions, 0 deletions
diff --git a/cli/src/cli/cli.clj b/cli/src/cli/cli.clj new file mode 100644 index 0000000..f7aba04 --- /dev/null +++ b/cli/src/cli/cli.clj @@ -0,0 +1,51 @@ +(ns cli.cli + (:require + [clojure.tools.cli :refer [parse-opts]] + [clojure.string :as string] + [cljcc.util :refer [exit]] + [cli.driver :as driver]) + (:gen-class)) + +(set! *warn-on-reflection* true) + +(defn usage [options-summary] + (->> + ["Usage: ./cljcc path/to/file.c [options]" + "" + "Options:" + options-summary] + (string/join \newline))) + +(def cli-options + [[nil "--lex" "Runs lexer. Does not emit any files."] + [nil "--parse" "Runs parser. Does not emit any files."] + [nil "--validate" "Runs semantic analyzer. Does not emit any files."] + [nil "--tacky" "Runs tacky generation. Does not emit any files."] + [nil "--codegen" "Runs compiler. Does not emit any files."] + ["-c" nil "Generate object file." + :id :generate-object-file] + ["-h" "--help"]]) + +(defn validate-args [args] + (let [{:keys [options arguments summary]} (parse-opts args cli-options)] + (cond + (:help options) {:exit-message (usage summary) :ok? true} + (= 1 (count arguments)) {:file-path (first arguments) + :options options} + :else {:exit-message (usage summary)}))) + +(defn -main + "Main entrypoint for cljcc compiler." + [& args] + (let [{:keys [file-path exit-message ok? options]} (validate-args args) + libs (filterv (fn [v] (and + (string? v) + (re-matches #"-l.+" v))) + args)] + (if exit-message + (exit (if ok? 0 1) exit-message) + (try + (driver/run file-path (assoc options :libs libs)) + (exit 0 "Successfully executed.") + (catch Exception e + (exit 1 (ex-message e) e)))))) diff --git a/cli/src/cli/core/log.clj b/cli/src/cli/core/log.clj new file mode 100644 index 0000000..1b279fc --- /dev/null +++ b/cli/src/cli/core/log.clj @@ -0,0 +1,28 @@ +(ns cli.core.log + (:require [clojure.string :as str])) + +(def ^:private log-colors + {:debug "\u001b[36m" ; Cyan + :info "\u001b[32m" ; Green + :warn "\u001b[33m" ; Yellow + :error "\u001b[31m" ; Red + :reset "\u001b[0m"}) ; Reset color + +(def reset-color (get log-colors :reset)) + +(defn- log-message [level message] + (let [color (get log-colors level) + formatted-message (str color "[" (str/upper-case (name level)) "] " message reset-color)] + (println formatted-message))) + +(defn debug [msg] + (log-message :debug msg)) + +(defn info [msg] + (log-message :info msg)) + +(defn warn [msg] + (log-message :warn msg)) + +(defn error [msg] + (log-message :error msg)) diff --git a/cli/src/cli/core/shell.clj b/cli/src/cli/core/shell.clj new file mode 100644 index 0000000..c17dbaa --- /dev/null +++ b/cli/src/cli/core/shell.clj @@ -0,0 +1,31 @@ +(ns cli.core.shell + (:require [cli.core.log :as log] + [clojure.java.shell :refer [sh]])) + +(defn get-os [] + (let [os-name (.toLowerCase (System/getProperty "os.name"))] + (cond + (.contains os-name "mac") :mac + (.contains os-name "linux") :linux + :else :unsupported))) + +(defn mac-aarch64? [] + (and (= :mac (get-os)) (= (System/getProperty "os.arch") "aarch64"))) + +(defn handle-sh + "Preprends arch -x86_64 if running under Mac M chips." + [command & args] + (let [args (filterv (comp not empty?) args)] + (if (mac-aarch64?) + (apply sh "arch" "-x86_64" command args) + (apply sh command args)))) + +(defn exit + ([status msg] + (if (= status 0) + (log/info msg) + (log/error msg)) + (System/exit status)) + ([status msg e] + (log/error (ex-data e)) + (exit status msg))) diff --git a/cli/src/cli/driver.clj b/cli/src/cli/driver.clj new file mode 100644 index 0000000..41a916f --- /dev/null +++ b/cli/src/cli/driver.clj @@ -0,0 +1,3 @@ +(ns cli.driver) + +(defn run [& args]) diff --git a/cli/src/cli/log.clj b/cli/src/cli/log.clj new file mode 100644 index 0000000..3f207d7 --- /dev/null +++ b/cli/src/cli/log.clj @@ -0,0 +1,28 @@ +(ns cli.log + (:require [clojure.string :as str])) + +(def ^:private log-colors + {:debug "\u001b[36m" ; Cyan + :info "\u001b[32m" ; Green + :warn "\u001b[33m" ; Yellow + :error "\u001b[31m" ; Red + :reset "\u001b[0m"}) ; Reset color + +(def reset-color (get log-colors :reset)) + +(defn- log-message [level message] + (let [color (get log-colors level) + formatted-message (str color "[" (str/upper-case (name level)) "] " message reset-color)] + (println formatted-message))) + +(defn debug [msg] + (log-message :debug msg)) + +(defn info [msg] + (log-message :info msg)) + +(defn warn [msg] + (log-message :warn msg)) + +(defn error [msg] + (log-message :error msg)) |
