From e88635d6d32055cc7d3a4ccf16c1a74cb5b88d1c Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Thu, 22 Aug 2024 00:51:56 +0530 Subject: Add analyzer for validating program semantics Add validator for semantic analysis Pass ch5 test cases for validate flag --- src/cljcc/driver.clj | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src/cljcc/driver.clj') 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))) -- cgit v1.2.3