aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc/driver.clj
diff options
context:
space:
mode:
authorShagun Agrawal <agrawalshagun07@gmail.com>2024-08-22 00:51:56 +0530
committerShagun Agrawal <agrawalshagun07@gmail.com>2024-08-22 00:51:56 +0530
commite88635d6d32055cc7d3a4ccf16c1a74cb5b88d1c (patch)
tree103ed07e89ae47cc723382ee712a0ca61b869844 /src/cljcc/driver.clj
parent502a23ce2966d4ad96ad65735718fcaaebc8d4e1 (diff)
Add analyzer for validating program semantics
Add validator for semantic analysis Pass ch5 test cases for validate flag
Diffstat (limited to 'src/cljcc/driver.clj')
-rw-r--r--src/cljcc/driver.clj37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj
index 65bc96a..4ad0051 100644
--- a/src/cljcc/driver.clj
+++ b/src/cljcc/driver.clj
@@ -5,12 +5,13 @@
[cljcc.tacky :as t]
[cljcc.lexer :as l]
[cljcc.emit :as e]
+ [cljcc.analyzer :as a]
[clojure.pprint :as pp]
[cljcc.log :as log]
[cljcc.util :refer [get-os handle-sh mac-aarch64? make-file-name]]
[cljcc.parser :as p]))
-(defn validate-os []
+(defn- validate-os []
(let [os (get-os)]
(condp = os
:linux (log/info "Running on Linux.")
@@ -19,12 +20,12 @@
(log/info "Running on Mac x86_64."))
:unsupported (throw (Exception. (str os " is not currently supported."))))))
-(defn remove-extension [^String filename]
+(defn- remove-extension [^String filename]
(if (.contains filename ".")
(.substring filename 0 (.lastIndexOf filename "."))
filename))
-(defn preprocessor-step [directory filename]
+(defn- preprocessor-step [directory filename]
(let [input-file-path (make-file-name directory (remove-extension filename) "c")
preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
output (handle-sh "gcc" "-E" "-P" input-file-path "-o" preprocessed-file-path)]
@@ -32,7 +33,7 @@
(throw (Exception. ^String (:err output)))
(log/info (str "Successfully preprocessed file: " preprocessed-file-path)))))
-(defn assemble-step [directory filename]
+(defn- assemble-step [directory filename]
(let [file-without-ext (remove-extension filename)
assembly-file (make-file-name directory file-without-ext "s")
preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
@@ -49,7 +50,7 @@
(throw (Exception. ^String (:err output)))
(log/info (str "Successfully created executable at: " output-file)))))
-(defn parser-step [directory filename]
+(defn- parser-step [directory filename]
(let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
file (io/file preprocessed-file-path)
source (slurp file)
@@ -57,7 +58,15 @@
(log/info "Input file is succesfully parsed.")
(pp/pprint ast)))
-(defn lexer-step [directory filename]
+(defn- semantic-analyzer-step [directory filename]
+ (let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
+ file (io/file preprocessed-file-path)
+ source (slurp file)
+ ast (a/validate (p/parse (l/lex source)))]
+ (log/info "Input file is succesfully validated.")
+ (pp/pprint ast)))
+
+(defn- lexer-step [directory filename]
(let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
file (io/file preprocessed-file-path)
source (slurp file)
@@ -65,7 +74,7 @@
(log/info "Input file is succesfully lexed.")
(pp/pprint output)))
-(defn tacky-step [directory filename]
+(defn- tacky-step [directory filename]
(let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
file (io/file preprocessed-file-path)
source (slurp file)
@@ -74,34 +83,36 @@
"Successfully generated Tacky IR.\n"
(with-out-str (pp/pprint output))))))
-(defn compiler-step [directory filename]
+(defn- compiler-step [directory filename]
(let [preprocessed-file-path (make-file-name directory (remove-extension filename) "i")
file (io/file preprocessed-file-path)
source (slurp file)
assembly-ast (c/generate-assembly source)]
(log/info (str "Succesfully generated assembly ast.\n" assembly-ast))))
-(defn cleanup-step [directory filename]
+(defn- cleanup-step [directory filename]
(let [file-without-ext (remove-extension filename)]
(io/delete-file (make-file-name directory file-without-ext "i") true)
(io/delete-file (make-file-name directory file-without-ext "s") true)))
-(defn create-steps [options directory filename]
+(defn- create-steps [options directory filename]
(let [steps [(partial validate-os)
(partial preprocessor-step directory filename)
(partial lexer-step directory filename)
(partial parser-step directory filename)
+ (partial semantic-analyzer-step directory filename)
(partial tacky-step directory filename)
(partial compiler-step directory filename)
(partial assemble-step directory filename)]]
(cond
(:lex options) (subvec steps 0 3)
(:parse options) (subvec steps 0 4)
- (:tacky options) (subvec steps 0 5)
- (:codegen options) (subvec steps 0 6)
+ (:validate options) (subvec steps 0 5)
+ (:tacky options) (subvec steps 0 6)
+ (:codegen options) (subvec steps 0 7)
:else steps)))
-(defn run-steps [options directory filename]
+(defn- run-steps [options directory filename]
(let [steps (create-steps options directory filename)]
(run! #(apply % []) steps)))