From b6de8db464151fa1300c5a47e508e9e792d034d0 Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Fri, 26 Jul 2024 00:03:57 +0530 Subject: Add cli options for pasing and codegen Add cli options specific for only parsing and codegen add logger for help in debugging --- deps.edn | 1 + src/cljcc/cljcc.clj | 40 ++++++++++++++++++++++++++++++++-------- src/cljcc/driver.clj | 2 +- src/cljcc/log.clj | 29 +++++++++++++++++++++++++++++ src/cljcc/parser.clj | 3 ++- src/cljcc/util.clj | 9 ++++++++- 6 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 src/cljcc/log.clj diff --git a/deps.edn b/deps.edn index e6b7e08..c0a34f4 100644 --- a/deps.edn +++ b/deps.edn @@ -1,5 +1,6 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.11.1"} + org.clojure/tools.cli {:mvn/version "1.1.230"} instaparse/instaparse {:mvn/version "1.5.0"} com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"}} :aliases diff --git a/src/cljcc/cljcc.clj b/src/cljcc/cljcc.clj index e687ae9..6708173 100644 --- a/src/cljcc/cljcc.clj +++ b/src/cljcc/cljcc.clj @@ -1,18 +1,42 @@ (ns cljcc.cljcc (: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)) (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 "--parse" "Runs parser. Does not emit any files."] + [nil "--codegen" "Runs compiler. Does not emit any files."] + ["-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 [input-file-path (first args)] - (try - (d/run input-file-path) - (catch Exception e - (println "Error: " (.getMessage e)) - (System/exit 1)) - (finally - (System/exit 0))))) + (let [{:keys [file-path exit-message ok? options]} (validate-args args)] + (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.")))))) diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj index dede930..a06c9a3 100644 --- a/src/cljcc/driver.clj +++ b/src/cljcc/driver.clj @@ -62,7 +62,7 @@ (defn run "Runs the compiler driver with the given input source file." - [^String file-path] + [^String file-path options] (let [file (io/file ^String file-path) filename (.getName file) directory (.getParent file)] diff --git a/src/cljcc/log.clj b/src/cljcc/log.clj new file mode 100644 index 0000000..394e4a4 --- /dev/null +++ b/src/cljcc/log.clj @@ -0,0 +1,29 @@ +(ns cljcc.log + (:require [clojure.string :as str] + [cljcc.log :as log])) + +(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/src/cljcc/parser.clj b/src/cljcc/parser.clj index 860fcd5..a4d7492 100644 --- a/src/cljcc/parser.clj +++ b/src/cljcc/parser.clj @@ -11,7 +11,8 @@ " = function+ function = #'int\\b' identifier <'('> #'void\\b' <')'> <'{'> statement <'}'> statement = #'return\\b' exp <';'> - exp = constant + exp = constant | unop exp | <'('> exp <')'> + unop = #'-\\b' | #'~\\b' identifier = #'[a-zA-Z_]\\w*\\b' constant = #'[0-9]+\\b' keyword = #'int\\b' | #'return\\b' | #'void\\b'" diff --git a/src/cljcc/util.clj b/src/cljcc/util.clj index 1087029..81419e4 100644 --- a/src/cljcc/util.clj +++ b/src/cljcc/util.clj @@ -1,5 +1,6 @@ (ns cljcc.util - (:require [clojure.java.shell :refer [sh]])) + (:require [clojure.java.shell :refer [sh]] + [cljcc.log :as log])) (defn get-os [] (let [os-name (.toLowerCase (System/getProperty "os.name"))] @@ -17,3 +18,9 @@ (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)) -- cgit v1.2.3