aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc
diff options
context:
space:
mode:
authorShagun Agrawal <agrawalshagun07@gmail.com>2024-08-11 00:22:05 +0530
committerShagun Agrawal <agrawalshagun07@gmail.com>2024-08-11 00:22:05 +0530
commit0f4b96b2b02822abf6f84903366709b1336905a2 (patch)
treeae43a57952f8dd3a3fd063aaf130db38dfe5a692 /src/cljcc
parent399bb5ab8bce44f5aeb43909dd10ad4ef5c93de1 (diff)
Add bitwise operators
Diffstat (limited to 'src/cljcc')
-rw-r--r--src/cljcc/driver.clj1
-rw-r--r--src/cljcc/emit.clj5
-rw-r--r--src/cljcc/parser.clj31
-rw-r--r--src/cljcc/tacky.clj16
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);}"))