diff options
| author | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-08-30 18:49:17 +0530 |
|---|---|---|
| committer | Shagun Agrawal <agrawalshagun07@gmail.com> | 2024-08-30 18:49:17 +0530 |
| commit | 276b0c200e5159b1d099ff85aab544480c2ac757 (patch) | |
| tree | 8cb86289809936901b2a49344818528799fa81da /src/cljcc/tacky.clj | |
| parent | 7a3e7151ea7e05952ec58648d71d9ed33168109d (diff) | |
Add compound assignment operators
Added compound assignment operators ( >>==, += etc )
Pass chapter 5 extra credit tests
Diffstat (limited to 'src/cljcc/tacky.clj')
| -rw-r--r-- | src/cljcc/tacky.clj | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/src/cljcc/tacky.clj b/src/cljcc/tacky.clj index ffa85b1..6046045 100644 --- a/src/cljcc/tacky.clj +++ b/src/cljcc/tacky.clj @@ -34,6 +34,38 @@ :logical-not :logical-not (throw (ex-info "Tacky Error. Invalid unary operator." {op op})))) +(defn- assignment-operator + "Converts parser assignment operator to tacky representation." + [op] + (condp = op + :assignemnt :assignemnt + :assignment-plus :assignment-add + :assignment-multiply :assignment-mul + :assignment-minus :assignment-minus + :assignment-divide :assignment-div + :assignment-mod :assignment-mod + :assignment-bitwise-and :assignemnt-bit-and + :assignment-bitwise-or :assignemnt-bit-or + :assignment-bitwise-xor :assignemnt-bit-xor + :assignment-bitwise-left-shift :assignment-bit-left-shift + :assignment-bitwise-right-shift :assignment-bit-right-shift)) + +(defn- assignment-operator->binary-operator + "Converts parser assignment operator to binary operator keyword." + [op] + (condp = op + :assignemnt :assignemnt + :assignment-plus :plus + :assignment-multiply :multiply + :assignment-minus :hyphen + :assignment-divide :divide + :assignment-mod :remainder + :assignment-bitwise-and :ampersand + :assignment-bitwise-or :bitwise-or + :assignment-bitwise-xor :bitwise-xor + :assignment-bitwise-left-shift :bitwise-left-shift + :assignment-bitwise-right-shift :bitwise-right-shift)) + (defn- binary-operator "Converts parser's binary operator to tacky representation." [binop] @@ -164,11 +196,20 @@ (label-instruction false-label)])})) (defn- assignment-exp-handler [e] - (let [var (parsed-var->tacky-var (:left e)) ; guaranteed to be parsed variable - rhs (expression-handler (:right e))] - {:val var - :instructions (flatten [(:instructions rhs) - (copy-instruction (:val rhs) var)])})) + (let [asop (:assignment-operator e) + direct-assignment? (= asop :assignment) + var (parsed-var->tacky-var (:left e))] ; guaranteed to be parsed variable + (if direct-assignment? + (let [rhs (expression-handler (:right e))] + {:val var + :instructions (flatten [(:instructions rhs) + (copy-instruction (:val rhs) var)])}) + (let [bin-op (assignment-operator->binary-operator (:assignment-operator e)) + bin-exp (p/binary-exp-node (:left e) (:right e) bin-op) + rhs (expression-handler bin-exp)] + {:val var + :instructions (flatten [(:instructions rhs) + (copy-instruction (:val rhs) var)])})))) (defn- expression-handler [e] (when-let [exp-type (:exp-type e)] @@ -236,7 +277,20 @@ (pp/pprint (tacky-from-src "int main(void) { -2 + 2; +int a = 11; + int b = 12; + a &= 0 || b; + b ^= a || 1; + + int c = 14; + c |= a || b; + + int d = 16; + d >>= c || d; + + int e = 18; + e <<= c || d; + return (a == 1 && b == 13 && c == 15 && d == 8 && e == 36); }")) (pp/pprint |
