From 277319fa392f5ee9f21eedf2c4d224739f045690 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 16 Mar 2025 14:53:45 +0530 Subject: Add common functions for handling cljcc compiler --- cljcc-compiler/src/cljcc/cljcc.cljc | 89 +++++++++++++++---------------------- 1 file changed, 36 insertions(+), 53 deletions(-) (limited to 'cljcc-compiler/src/cljcc/cljcc.cljc') 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))) - ()) -- cgit v1.2.3