diff options
| -rw-r--r-- | cli/deps.edn | 4 | ||||
| -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 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/analyze/core.clj (renamed from src/cljcc/analyze/core.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/analyze/label_loops.clj (renamed from src/cljcc/analyze/label_loops.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/analyze/resolve.clj (renamed from src/cljcc/analyze/resolve.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/analyze/typecheck.clj (renamed from src/cljcc/analyze/typecheck.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/cljcc.clj (renamed from src/cljcc/cljcc.clj) | 23 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/compiler.clj (renamed from src/cljcc/compiler.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/driver.clj (renamed from src/cljcc/driver.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/emit.clj (renamed from src/cljcc/emit.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/exception.clj (renamed from src/cljcc/exception.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/lexer.clj (renamed from src/cljcc/lexer.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/log.clj (renamed from src/cljcc/log.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/parser.clj (renamed from src/cljcc/parser.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/schema.clj (renamed from src/cljcc/schema.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/symbol.clj (renamed from src/cljcc/symbol.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/tacky.clj (renamed from src/cljcc/tacky.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/token.clj (renamed from src/cljcc/token.clj) | 0 | ||||
| -rw-r--r-- | cljcc-compiler/src/cljcc/util.clj (renamed from src/cljcc/util.clj) | 0 | ||||
| -rw-r--r-- | deps.edn | 5 |
24 files changed, 160 insertions, 13 deletions
diff --git a/cli/deps.edn b/cli/deps.edn new file mode 100644 index 0000000..8d06ce6 --- /dev/null +++ b/cli/deps.edn @@ -0,0 +1,4 @@ +{:paths ["src"] + :aliases + {:run + {:main-opts ["-m" "cli.cli"]}}} 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)) diff --git a/src/cljcc/analyze/core.clj b/cljcc-compiler/src/cljcc/analyze/core.clj index 793b667..793b667 100644 --- a/src/cljcc/analyze/core.clj +++ b/cljcc-compiler/src/cljcc/analyze/core.clj diff --git a/src/cljcc/analyze/label_loops.clj b/cljcc-compiler/src/cljcc/analyze/label_loops.clj index 56fffc9..56fffc9 100644 --- a/src/cljcc/analyze/label_loops.clj +++ b/cljcc-compiler/src/cljcc/analyze/label_loops.clj diff --git a/src/cljcc/analyze/resolve.clj b/cljcc-compiler/src/cljcc/analyze/resolve.clj index 9f09333..9f09333 100644 --- a/src/cljcc/analyze/resolve.clj +++ b/cljcc-compiler/src/cljcc/analyze/resolve.clj diff --git a/src/cljcc/analyze/typecheck.clj b/cljcc-compiler/src/cljcc/analyze/typecheck.clj index d1e79dc..d1e79dc 100644 --- a/src/cljcc/analyze/typecheck.clj +++ b/cljcc-compiler/src/cljcc/analyze/typecheck.clj diff --git a/src/cljcc/cljcc.clj b/cljcc-compiler/src/cljcc/cljcc.clj index c03301d..c067b75 100644 --- a/src/cljcc/cljcc.clj +++ b/cljcc-compiler/src/cljcc/cljcc.clj @@ -6,6 +6,17 @@ [cljcc.driver :as d]) (:gen-class)) +(defn run + "Compiles source input using specified compiler options. + + Parameters: + source - Source C file. + options - Map of compiler configuration options. + + Returns generated AST for specified stage." + [source & {:keys [config] :or {config {}}}] + (let [default-config {:target {:os :linux}}])) + (set! *warn-on-reflection* true) (defn usage [options-summary] @@ -52,16 +63,4 @@ (comment - (require '[io.github.humbleui.ui :as ui]) - - (ui/defcomp app [] - [ui/center - [ui/label "Hello, world"]]) - - (defn -main [& args] - (ui/start-app! - (ui/window #'app))) - - (-main) - ()) diff --git a/src/cljcc/compiler.clj b/cljcc-compiler/src/cljcc/compiler.clj index 39b3506..39b3506 100644 --- a/src/cljcc/compiler.clj +++ b/cljcc-compiler/src/cljcc/compiler.clj diff --git a/src/cljcc/driver.clj b/cljcc-compiler/src/cljcc/driver.clj index 20d2d22..20d2d22 100644 --- a/src/cljcc/driver.clj +++ b/cljcc-compiler/src/cljcc/driver.clj diff --git a/src/cljcc/emit.clj b/cljcc-compiler/src/cljcc/emit.clj index 0686b31..0686b31 100644 --- a/src/cljcc/emit.clj +++ b/cljcc-compiler/src/cljcc/emit.clj diff --git a/src/cljcc/exception.clj b/cljcc-compiler/src/cljcc/exception.clj index 40ea930..40ea930 100644 --- a/src/cljcc/exception.clj +++ b/cljcc-compiler/src/cljcc/exception.clj diff --git a/src/cljcc/lexer.clj b/cljcc-compiler/src/cljcc/lexer.clj index ef4235f..ef4235f 100644 --- a/src/cljcc/lexer.clj +++ b/cljcc-compiler/src/cljcc/lexer.clj diff --git a/src/cljcc/log.clj b/cljcc-compiler/src/cljcc/log.clj index 3dbc4fb..3dbc4fb 100644 --- a/src/cljcc/log.clj +++ b/cljcc-compiler/src/cljcc/log.clj diff --git a/src/cljcc/parser.clj b/cljcc-compiler/src/cljcc/parser.clj index f8d039d..f8d039d 100644 --- a/src/cljcc/parser.clj +++ b/cljcc-compiler/src/cljcc/parser.clj diff --git a/src/cljcc/schema.clj b/cljcc-compiler/src/cljcc/schema.clj index bf216f9..bf216f9 100644 --- a/src/cljcc/schema.clj +++ b/cljcc-compiler/src/cljcc/schema.clj diff --git a/src/cljcc/symbol.clj b/cljcc-compiler/src/cljcc/symbol.clj index c410dac..c410dac 100644 --- a/src/cljcc/symbol.clj +++ b/cljcc-compiler/src/cljcc/symbol.clj diff --git a/src/cljcc/tacky.clj b/cljcc-compiler/src/cljcc/tacky.clj index be60841..be60841 100644 --- a/src/cljcc/tacky.clj +++ b/cljcc-compiler/src/cljcc/tacky.clj diff --git a/src/cljcc/token.clj b/cljcc-compiler/src/cljcc/token.clj index 213588c..213588c 100644 --- a/src/cljcc/token.clj +++ b/cljcc-compiler/src/cljcc/token.clj diff --git a/src/cljcc/util.clj b/cljcc-compiler/src/cljcc/util.clj index 4c56ab9..4c56ab9 100644 --- a/src/cljcc/util.clj +++ b/cljcc-compiler/src/cljcc/util.clj @@ -6,7 +6,10 @@ metosin/malli {:mvn/version "0.16.4"} com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"}} :aliases - {:run-m {:main-opts ["-m" "cljcc.cljcc"]} + {:cli + {:extra-paths ["cli/src"] + :main-opts ["-m" "cli.cli"]} + :run-m {:main-opts ["-m" "cljcc.cljcc"]} :build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.3"}} :jvm-opts ["-Dclojure.compiler.direct-linking=true"] |
