aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cljcc/analyze/resolve.clj4
-rw-r--r--src/cljcc/cljcc.clj8
-rw-r--r--src/cljcc/driver.clj8
-rw-r--r--src/cljcc/lexer.clj24
-rw-r--r--src/cljcc/parser.clj6
-rw-r--r--src/cljcc/tacky.clj23
-rw-r--r--src/cljcc/token.clj4
-rw-r--r--src/cljcc/util.clj1
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.