aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <agrawalshagun07@gmail.com>2025-03-16 02:00:40 +0530
committerYour Name <agrawalshagun07@gmail.com>2025-03-16 02:00:40 +0530
commit0321df3708cfa4d1440faf3f407611df85484b4b (patch)
tree8c23154afaf1afd78363eb0fa639edd5d8a32821
parente458b2fadee1eaf0a6cf4ed4881da6f3f25acc21 (diff)
Refactor files to cljcc-compiler and cli tool.
-rw-r--r--cli/deps.edn4
-rw-r--r--cli/src/cli/cli.clj51
-rw-r--r--cli/src/cli/core/log.clj28
-rw-r--r--cli/src/cli/core/shell.clj31
-rw-r--r--cli/src/cli/driver.clj3
-rw-r--r--cli/src/cli/log.clj28
-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.edn5
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
diff --git a/deps.edn b/deps.edn
index e965a53..2dc0b92 100644
--- a/deps.edn
+++ b/deps.edn
@@ -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"]