diff options
Diffstat (limited to 'src/cljcc')
| -rw-r--r-- | src/cljcc/driver.clj | 1 | ||||
| -rw-r--r-- | src/cljcc/emit.clj | 5 | ||||
| -rw-r--r-- | src/cljcc/parser.clj | 31 | ||||
| -rw-r--r-- | src/cljcc/tacky.clj | 16 |
4 files changed, 48 insertions, 5 deletions
diff --git a/src/cljcc/driver.clj b/src/cljcc/driver.clj index 2869561..9f81bb0 100644 --- a/src/cljcc/driver.clj +++ b/src/cljcc/driver.clj @@ -40,6 +40,7 @@ assembly-ast (c/generate-assembly source) assembly-output (e/emit assembly-ast) assembly-out-file-path (make-file-name directory (remove-extension filename) "s") + _ (println assembly-output) _ (spit assembly-out-file-path assembly-output) output-file (str directory "/" file-without-ext) output (handle-sh "gcc" assembly-file "-o" output-file)] diff --git a/src/cljcc/emit.clj b/src/cljcc/emit.clj index 080886e..d326c55 100644 --- a/src/cljcc/emit.clj +++ b/src/cljcc/emit.clj @@ -60,6 +60,11 @@ :add "addl" :sub "subl" :mul "imull" + :bit-and "andl" + :bit-xor "xorl" + :bit-or "orl" + :bit-left-shift "sall" + :bit-right-shift "sarl" (throw (AssertionError. (str "Invalid binary operator: " instruction))))] [(format " %s %s, %s" binop-operator src dst)])) diff --git a/src/cljcc/parser.clj b/src/cljcc/parser.clj index bee6d32..0d95ac8 100644 --- a/src/cljcc/parser.clj +++ b/src/cljcc/parser.clj @@ -44,11 +44,38 @@ keyword = #'int\\b' | #'return\\b' | #'void\\b'" :auto-whitespace whitespace)) +(def bitwise-parser + (insta/parser + "<program> = function+ + function = #'int\\b' identifier <'('> #'void\\b' <')'> <'{'> statement <'}'> + statement = #'return\\b' exp <';'> + exp = exp-prime + <exp-prime> = mul-div-mod | add-exp | sub-exp + add-exp = exp-prime <'+'> mul-div-mod + sub-exp = exp-prime <'-'> mul-div-mod + <mul-div-mod> = bitwise-exp-prime | mul-exp | div-exp | mod-exp + mul-exp = mul-div-mod <'*'> bitwise-exp-prime + div-exp = mul-div-mod <'/'> bitwise-exp-prime + mod-exp = mul-div-mod <'%'> bitwise-exp-prime + <bitwise-exp-prime> = bit-and-exp | bit-or-exp | bit-xor-exp | bit-left-shift-exp | bit-right-shift-exp | term + bit-and-exp = bitwise-exp-prime <'&'> term + bit-or-exp = bitwise-exp-prime <'|'> term + bit-xor-exp = bitwise-exp-prime <'^'> term + bit-left-shift-exp = bitwise-exp-prime <'<<'> term + bit-right-shift-exp = bitwise-exp-prime <'>>'> term + <term> = constant-exp | unary-exp | <'('> exp-prime <')'> + unary-exp = unary-operator term + unary-operator = #'-' | #'~' + identifier = #'[a-zA-Z_]\\w*\\b' + constant-exp = #'[0-9]+\\b' + keyword = #'int\\b' | #'return\\b' | #'void\\b'" + :auto-whitespace whitespace)) + (defn parseable? [result] (not (insta/failure? result))) (defn parse [source] - (binop-parser source)) + (bitwise-parser source)) (comment @@ -64,7 +91,7 @@ }") (pp/pprint (parse "int main(void) { - return -(((((10))))); + return 1 & 2 + 6 & 6; }")) (pp/pprint diff --git a/src/cljcc/tacky.clj b/src/cljcc/tacky.clj index d87a909..533cb3e 100644 --- a/src/cljcc/tacky.clj +++ b/src/cljcc/tacky.clj @@ -38,7 +38,12 @@ :sub-exp :sub :mul-exp :mul :div-exp :div - :mod-exp :mod)) + :mod-exp :mod + :bit-and-exp :bit-and + :bit-or-exp :bit-or + :bit-xor-exp :bit-xor + :bit-right-shift-exp :bit-right-shift + :bit-left-shift-exp :bit-left-shift)) (defn- unary-instruction [unary-operator src dst] {:type :unary @@ -62,7 +67,12 @@ :sub-exp :mul-exp :mod-exp - :div-exp}) + :div-exp + :bit-and-exp + :bit-or-exp + :bit-xor-exp + :bit-right-shift-exp + :bit-left-shift-exp}) (defn- binary-expr? [v] (contains? binary-exprs v)) @@ -121,7 +131,7 @@ (pp/pprint (tacky-generate - (p/parse "int main(void) {return 1 * 2 - 3 * (4 + 5);}"))) + (p/parse "int main(void) {return 1 * 2 & 3 * (4 + 5);}"))) (pp/pprint (p/parse "int main(void) {return 1 * 2 - 3 * (4 + 5);}")) |
