diff options
| author | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-12-24 00:05:11 +0530 |
|---|---|---|
| committer | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-12-24 00:05:11 +0530 |
| commit | 382c19861608e9ab9903c78f1e5c02bc061cc7c8 (patch) | |
| tree | cbf2d16132a71b21e0f0e81f6b724685dcb242aa | |
| parent | b50b3552de7e0e6bf71d78e59adec5e305d7618b (diff) | |
Add driver changes and float regex
| -rw-r--r-- | src/cljcc/analyze/resolve.clj | 4 | ||||
| -rw-r--r-- | src/cljcc/cljcc.clj | 8 | ||||
| -rw-r--r-- | src/cljcc/driver.clj | 8 | ||||
| -rw-r--r-- | src/cljcc/lexer.clj | 24 | ||||
| -rw-r--r-- | src/cljcc/parser.clj | 6 | ||||
| -rw-r--r-- | src/cljcc/tacky.clj | 23 | ||||
| -rw-r--r-- | src/cljcc/token.clj | 4 | ||||
| -rw-r--r-- | src/cljcc/util.clj | 1 |
8 files changed, 47 insertions, 31 deletions
diff --git a/src/cljcc/analyze/resolve.clj b/src/cljcc/analyze/resolve.clj index 9250e49..5982312 100644 --- a/src/cljcc/analyze/resolve.clj +++ b/src/cljcc/analyze/resolve.clj @@ -56,7 +56,7 @@ (if (contains? ident->symbol fn-name) (p/function-call-exp-node (:new-name (get ident->symbol fn-name)) (mapv #(resolve-exp % ident->symbol) args)) - (throw (ex-info "Undeclared function !" {:function-name fn-name})))) + (exc/analyzer-error "Undeclared function." {:function-name fn-name}))) (exc/analyzer-error "Invalid expression." {:exp e}))) (defn- resolve-optional-exp [e ident->symbol] @@ -166,7 +166,7 @@ (condp = declaration-type :variable (resolve-variable-declaration d ident->symbol) :function (resolve-function-declaration d ident->symbol) - (throw (ex-info "Analyzer Error. Invalid declaration type." {:declaration d})))) + (exc/analyzer-error "Invalid declaration type" {:declaration d}))) (defn- resolve-for-init [for-init ident->symbol] (if (= (:type for-init) :declaration) diff --git a/src/cljcc/cljcc.clj b/src/cljcc/cljcc.clj index e36658e..c03301d 100644 --- a/src/cljcc/cljcc.clj +++ b/src/cljcc/cljcc.clj @@ -37,11 +37,15 @@ (defn -main "Main entrypoint for cljcc compiler." [& args] - (let [{:keys [file-path exit-message ok? options]} (validate-args 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 options) + (d/run file-path (assoc options :libs libs)) (exit 0 "Successfully executed.") (catch Exception e (exit 1 (ex-message e) e)))))) diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj index 2db8c0b..20d2d22 100644 --- a/src/cljcc/driver.clj +++ b/src/cljcc/driver.clj @@ -41,18 +41,16 @@ file (io/file preprocessed-file-path) source (slurp file) assembly-ast (c/assembly-from-src source) - _ (log/info (str "Generated assembly output: " (with-out-str (pp/pprint assembly-ast)))) assembly-output (e/emit assembly-ast) - _ (log/info (str "Generated ASM output: " (with-out-str (pp/pprint assembly-output)))) assembly-out-file-path (make-file-name directory (remove-extension filename) "s") - _ (println assembly-output) _ (spit assembly-out-file-path assembly-output) output-file (if (:generate-object-file options) (str directory "/" (str file-without-ext ".o")) (str directory "/" file-without-ext)) + libs (str/join " " (:libs options)) output (if (:generate-object-file options) - (handle-sh "gcc" "-c" assembly-file "-o" output-file) - (handle-sh "gcc" assembly-file "-o" output-file))] + (handle-sh "gcc" "-c" assembly-file "-o" output-file libs) + (handle-sh "gcc" assembly-file "-o" output-file libs))] (if (= 1 (:exit output)) (throw (Exception. ^String (:err output))) (log/info (str "Successfully created executable at: " output-file))))) diff --git a/src/cljcc/lexer.clj b/src/cljcc/lexer.clj index 61022d9..3651d16 100644 --- a/src/cljcc/lexer.clj +++ b/src/cljcc/lexer.clj @@ -11,44 +11,37 @@ (defn lex ([source] - (lex source 0 (lexer-ctx))) - ([[ch pk th :as source] pos {:keys [line col] :as ctx}] + (lex source (lexer-ctx))) + ([[ch pk th :as source] {:keys [line col] :as ctx}] (cond (empty? source) (update ctx :tokens #(conj % (t/create :eof line col))) (newline? ch) (recur (next source) - (+ pos 1) (-> ctx (update :line inc) (update :col (fn [_] 1)))) (contains? t/chrs-kind-map (str ch pk th)) (recur (next (next (next source))) - (+ pos 3) (-> ctx (update :col #(+ % 3)) (update :tokens #(conj % (t/create (get t/chrs-kind-map (str ch pk th)) line col))))) (contains? t/chrs-kind-map (str ch pk)) (recur (next (next source)) - (+ pos 2) (-> ctx (update :col #(+ % 2)) (update :tokens #(conj % (t/create (get t/chrs-kind-map (str ch pk)) line col))))) (contains? t/chrs-kind-map ch) (recur (next source) - (+ pos 1) (-> ctx (update :col inc) (update :tokens #(conj % (t/create (get t/chrs-kind-map ch) line col))))) (whitespace? ch) (recur (next source) - (+ pos 1) (-> ctx (update :col inc))) (digit? ch) (let [[chrs rst] (split-with letter-digit? source) number (read-number (apply str chrs) line col) cnt (count chrs) - npos (+ pos cnt) token (t/create :number line col number)] (recur (apply str rst) - npos (-> ctx (update :col #(+ % cnt)) (update :tokens #(conj % token))))) @@ -58,19 +51,18 @@ kind (t/identifier->kind lexeme) token (if (= :identifier kind) (t/create kind line col lexeme) - (t/create kind line col)) - npos (+ pos cnt)] - (recur (apply str rst) npos (-> ctx - (update :col #(+ % cnt)) - (update :tokens #(conj % token))))) + (t/create kind line col))] + (recur (apply str rst) (-> ctx + (update :col #(+ % cnt)) + (update :tokens #(conj % token))))) :else (exc/lex-error {:line line :col col})))) (comment (lex " -int main() { - long unsigned a = 110lu; +int main(void) { + return 42; } ") diff --git a/src/cljcc/parser.clj b/src/cljcc/parser.clj index 6ab3373..7837ce3 100644 --- a/src/cljcc/parser.clj +++ b/src/cljcc/parser.clj @@ -43,8 +43,8 @@ [kind [token & rst]] (if (= kind (:kind token)) [token rst] - (throw (ex-info "Parser Error." {:expected kind - :actual (:kind token)})))) + (exc/parser-error "Actual and expected token differ." {:expected kind + :actual (:kind token)}))) (defn constant-exp-node [v] {:type :exp @@ -519,7 +519,7 @@ (defn- parse-program [tokens] (let [[declarations tokens] (parse-repeatedly tokens parse-declaration :eof) _ (expect :eof tokens) - ;_ (m/coerce #'s/Program declarations) + ;_ (m/coerce #'s/Program declarations) ] declarations)) diff --git a/src/cljcc/tacky.clj b/src/cljcc/tacky.clj index b88411e..9e1961a 100644 --- a/src/cljcc/tacky.clj +++ b/src/cljcc/tacky.clj @@ -526,8 +526,9 @@ symbols (atom ident->symbol) function-instructions (tacky-function-instructions ast symbols) program (vec (concat variable-instructions function-instructions)) - _ (m/coerce s/TackyProgram program) - _ (m/coerce s/SymbolMap @symbols)] + ;_ (m/coerce s/TackyProgram program) + ;_ (m/coerce s/SymbolMap @symbols) + ] {:program program :ident->symbol @symbols})) @@ -631,6 +632,24 @@ int foo; tacky-generate :program)) + (def x (-> file-path + slurp + p/parse-from-src + a/validate)) + + (pretty/explain + s/SymbolMap + (:ident->symbol (tacky-generate x))) + + (pretty/explain + s/SymbolMap + (-> file-path + slurp + p/parse-from-src + a/validate + tacky-generate + :ident->symbol)) + (-> file-path slurp p/parse-from-src diff --git a/src/cljcc/token.clj b/src/cljcc/token.clj index 3d08010..213588c 100644 --- a/src/cljcc/token.clj +++ b/src/cljcc/token.clj @@ -53,6 +53,7 @@ :kw-return :kw-int :kw-long + :kw-double :kw-void :kw-signed :kw-unsigned}) @@ -194,6 +195,7 @@ "void" :kw-void "int" :kw-int "long" :kw-long + "double" :kw-double "if" :kw-if "else" :kw-else "do" :kw-do @@ -208,7 +210,7 @@ :identifier)) (def type-specifier-keywords - #{:kw-int :kw-long :kw-signed :kw-unsigned}) + #{:kw-int :kw-long :kw-double :kw-signed :kw-unsigned}) (def storage-specifier-keywords #{:kw-static :kw-extern}) diff --git a/src/cljcc/util.clj b/src/cljcc/util.clj index c9fc208..0a24eef 100644 --- a/src/cljcc/util.clj +++ b/src/cljcc/util.clj @@ -83,6 +83,7 @@ (def signed-long-re #"[0-9]+[lL]") (def unsigned-int-re #"[0-9]+[uU]") (def signed-int-re #"[0-9]+") +(def fractional-constant #"([0-9]*\.[0-9]+|[0-9]+\.?)[Ee][+-]?[0-9]+|[0-9]*\.[0-9]+|[0-9]+\.") (defn read-number "Returns number in string form. |
