aboutsummaryrefslogtreecommitdiff
path: root/cljcc-compiler/src/cljcc/cljcc.cljc
diff options
context:
space:
mode:
authorYour Name <agrawalshagun07@gmail.com>2025-03-16 14:53:45 +0530
committerYour Name <agrawalshagun07@gmail.com>2025-03-16 14:53:45 +0530
commit277319fa392f5ee9f21eedf2c4d224739f045690 (patch)
treef2e3a89de7946647d7560db242e7ce22fda25a5c /cljcc-compiler/src/cljcc/cljcc.cljc
parent39b6930e14cfda58fd066805f5da447c685ab67f (diff)
Add common functions for handling cljcc compiler
Diffstat (limited to 'cljcc-compiler/src/cljcc/cljcc.cljc')
-rw-r--r--cljcc-compiler/src/cljcc/cljcc.cljc89
1 files changed, 36 insertions, 53 deletions
diff --git a/cljcc-compiler/src/cljcc/cljcc.cljc b/cljcc-compiler/src/cljcc/cljcc.cljc
index c067b75..742c1c2 100644
--- a/cljcc-compiler/src/cljcc/cljcc.cljc
+++ b/cljcc-compiler/src/cljcc/cljcc.cljc
@@ -1,11 +1,18 @@
(ns cljcc.cljcc
(:require
- [clojure.tools.cli :refer [parse-opts]]
- [clojure.string :as string]
- [cljcc.util :refer [exit]]
- [cljcc.driver :as d])
+ [cljcc.lexer :as lexer]
+ [cljcc.parser :as parser]
+ [cljcc.tacky :as tacky]
+ [cljcc.analyze.core :as analyzer]
+ [cljcc.compiler :as codegen]
+ [cljcc.emit :as emit])
(:gen-class))
+#?(:clj (set! *warn-on-reflection* true))
+
+(def valid-os-targets #{:mac :linux})
+(def valid-stages #{:lex :parse :validate :tacky :codegen :emit})
+
(defn run
"Compiles source input using specified compiler options.
@@ -13,54 +20,30 @@
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]
- (->>
- ["Usage: ./cljcc path/to/file.c [options]"
- ""
- "Options:"
- options-summary]
- (string/join \newline)))
+ Options map:
+ :target - Map of target platform settings
+ :os - Target OS #{:linux :mac}
+ :stage - Which stage to generate #{:lex :parse :validate :tacky :codegen :emit}
-(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
- (d/run file-path (assoc options :libs libs))
- (exit 0 "Successfully executed.")
- (catch Exception e
- (exit 1 (ex-message e) e))))))
-
-(comment
+ Returns generated AST for specified stage."
+ [source & {:keys [options] :or {options {}}}]
+ (let [default-options {:target {:os :linux}
+ :stage :emit}
+ merged-options (merge default-options options)
+ stage (:stage merged-options)
+ target-os (:os (:target merged-options))
+ _ (assert (stage valid-stages) "Invalid stage for compilation.")
+ _ (assert (target-os valid-os-targets) "Invalid operating system.")
+ stages [lexer/lex parser/parse
+ analyzer/validate tacky/tacky-generate
+ codegen/assembly emit/emit]
+ stage-idx (condp = stage
+ :lex 1
+ :parse 2
+ :validate 3
+ :tacky 4
+ :codegen 5
+ :emit 6)
+ stages-to-run (vec (take stage-idx stages))]
+ (reduce (fn [acc f] (f acc)) source stages-to-run)))
- ())