127 79 22MB
English Pages [584] Year 2023
✠❨ ✍ ❘ ❆ ✌❙ ✟ ☞ ☛ ✡
❇✞■✆☎ ✂ ✁✝✂✆ ▲✁ ●✁✂▼▼■◆● ✆✂◆●✞✂●✝ ❊✁ ▼ ✄❈✁✂❚❈❍ ◆ ✁✂ ✄✂◆☎✆✝✁
➤
✤✣ ✛✚ ✙✘✗ ✁✙ ✕ ✕ ✚ ✙ ✔✓ ✚ ✘ ✘ ✕ ✁ ✙ ✣ ✒ ✙ ✚ ✑✏ ✎✕✕✂✌✚✘☞ ☛✕✔✘✣✑✕✡
❚❤❡ ✄❛r❧② ☎❝❝❡ss ✆r✝❣r❛♠ ❧❡ts ②✝✉ r❡❛❞ s✐❣♥✐✞❝❛♥t ✆✝rt✐✝♥s ✝❢ ❛♥ ✉✆❝✝♠✐♥❣ ❜✝✝❦ ✟❤✐❧❡ ✐t➆s st✐❧❧ ✐♥ t❤❡ ❡❞✐t✐♥❣ ❛♥❞ ✆r✝❞✉❝t✐✝♥ ✆❤❛s❡s✱ s✝ ②✝✉ ♠❛② ❝✝♠❡ ❛❝r✝ss ❡rr✝rs ✝r ✝t❤❡r ✐ss✉❡s ②✝✉ ✟❛♥t t✝ ❝✝♠♠❡♥t ✝♥✳ ✠✉t ✟❤✐❧❡ ✟❡ s✐♥❝❡r❡❧② ❛✆✆r❡❝✐❛t❡ ②✝✉r ❢❡❡❞❜❛❝❦ ❞✉r✐♥❣ ❛ ❜✝✝❦➆s ✄☎ ✆❤❛s❡✱ ✆❧❡❛s❡ ✉s❡ ②✝✉r ❜❡st ❞✐s✲ ❝r❡t✐✝♥ ✟❤❡♥ ❞❡❝✐❞✐♥❣ ✟❤❛t t✝ r❡✆✝rt✳ ☎t t❤❡ ✄☎ st❛❣❡✱ ✟❡➆r❡ ♠✝st ✐♥t❡r❡st❡❞ ✐♥ ❢❡❡❞❜❛❝❦ r❡❧❛t❡❞ t✝ ❝✝♥t❡♥t➋ ❣❡♥❡r❛❧ ❝✝♠♠❡♥ts t✝ t❤❡ ✟r✐t❡r✱ t❡❝❤♥✐❝❛❧ ❡rr✝rs✱ ✍❡rs✐✝♥✐♥❣ ❝✝♥❝❡r♥s✱ ✝r ✝t❤❡r ❤✐❣❤✲❧❡✍❡❧ ✐ss✉❡s ❛♥❞ ✝❜s❡r✍❛t✐✝♥s✳ ☎s t❤❡s❡ t✐t❧❡s ❛r❡ st✐❧❧ ✐♥ ❞r❛❢t ❢✝r♠✱ ✟❡ ❛❧r❡❛❞② ❦♥✝✟ t❤❡r❡ ♠❛② ❜❡ t②✆✝s✱ ❣r❛♠♠❛t✐❝❛❧ ♠✐st❛❦❡s✱ ♠✐ss✲ ✐♥❣ ✐♠❛❣❡s ✝r ❝❛✆t✐✝♥s✱ ❧❛②✝✉t ✐ss✉❡s✱ ❛♥❞ ✐♥st❛♥❝❡s ✝❢ ✆❧❛❝❡❤✝❧❞❡r t❡①t✳ ✖✝ ♥❡❡❞ t✝ r❡✆✝rt t❤❡s❡➋t❤❡② ✟✐❧❧ ❛❧❧ ❜❡ ❝✝rr❡❝t❡❞ ❧❛t❡r✱ ❞✉r✐♥❣ t❤❡ ❝✝✆②❡❞✐t✲ ✐♥❣✱ ✆r✝✝❢r❡❛❞✐♥❣✱ ❛♥❞ t②✆❡s❡tt✐♥❣ ✆r✝❝❡ss❡s✳ ■❢ ②✝✉ ❡♥❝✝✉♥t❡r ❛♥② ❡rr✝rs ✜➇❡rr❛t❛➈✮ ②✝✉➆❞ ❧✐❦❡ t✝ r❡✆✝rt✱ ✆❧❡❛s❡ ✞❧❧ ✝✉t ✢✥✦✧ ★♦♦✩✪✫ ✬♦✭✯ s✝ ✟❡ ❝❛♥ r❡✍✐❡✟ ②✝✉r ❝✝♠♠❡♥ts✳
✁✂✄☎ ✆✝✝✞✟✟ ✞✠✡☛✡☞✌✍ ✎✏✑✎✒✑✓✔ ✕✖✗✘✙✚✛✜✢ ✣ ✤✥✤✦ ✧✘ ★✖✙✩ ✪✩✫✬✭✮✙✯ ✰✪✱★ ✲✳✴ ✵✶✷✸✲✸✶✲✷✹✸✺✺✻✼✸✽ ✾✗✙✚✫✢✿ ✰✪✱★ ✲✳✴ ✵✶✷✸✲✸✶✲✷✹✸✺✺✻✳✸✳ ✾✮✧✖✖❀✿ ❁❂✧✭✚❃✜✮✙✴ ❄✚✭✭✚✩❅ ❁✖✭✭✖❆❀ ❇✩✫✩✛✚✫✛ ❈✬✚✢✖✙✴ ❉✚✭✭ ❊✙✩✫❀✭✚✫ ❁✙✖✬❂❆✢✚✖✫ ❇✩✫✩✛✮✙✴ ✪✩✧✙✚✫✩ ❁✭✖❅✚✢✩✭✭✖✸❋✖✫●❍✭✮● ◆■ ❏❑▲▼❖P ◗▼❘❙❙ ▲❚❯ ❑P❘ ◆■ ❏❑▲▼❖P ◗▼❘❙❙ ❱■❲■ ▲▼❘ ▼❘❲❳❙❑❘▼❘❯ ❑▼▲❯❘❨▲▼❩❙ ■❬ ◆■ ❏❑▲▼❖P ◗▼❘❙❙❭ ❪❚❖❫ ❴❑P❘▼ ❵▼■❯❛❖❑ ▲❚❯ ❖■❨❵▲❚❜ ❚▲❨❘❙ ❨❘❚❑❳■❚❘❯ P❘▼❘❳❚ ❨▲❜ ❝❘ ❑P❘ ❑▼▲❯❘❨▲▼❩❙ ■❬ ❑P❘❳▼ ▼❘❙❵❘❖❑❳r❘ ■❞❚❘▼❙❫ ❡▲❑P❘▼ ❑P▲❚ ❛❙❘ ▲ ❑▼▲❯❘❨▲▼❩ ❙❜❨❝■❱ ❞❳❑P ❘r❘▼❜ ■❖❖❛▼▼❘❚❖❘ ■❬ ▲ ❑▼▲❯❘❢ ❨▲▼❩❘❯ ❚▲❨❘❭ ❞❘ ▲▼❘ ❛❙❳❚❲ ❑P❘ ❚▲❨❘❙ ■❚❱❜ ❳❚ ▲❚ ❘❯❳❑■▼❳▲❱ ❬▲❙P❳■❚ ▲❚❯ ❑■ ❑P❘ ❝❘❚❘❬❳❑ ■❬ ❑P❘ ❑▼▲❯❘❨▲▼❩ ■❞❚❘▼❭ ❞❳❑P ❚■ ❳❚❑❘❚❑❳■❚ ■❬ ❳❚❬▼❳❚❲❘❨❘❚❑ ■❬ ❑P❘ ❑▼▲❯❘❨▲▼❩❫ ❣❱❱ ▼❳❲P❑❙ ▼❘❙❘▼r❘❯❫ ◆■ ❵▲▼❑ ■❬ ❑P❳❙ ❞■▼❩ ❨▲❜ ❝❘ ▼❘❵▼■❯❛❖❘❯ ■▼ ❑▼▲❚❙❨❳❑❑❘❯ ❳❚ ▲❚❜ ❬■▼❨ ■▼ ❝❜ ▲❚❜ ❨❘▲❚❙❭ ❘❱❘❖❑▼■❚❳❖ ■▼ ❨❘❖P▲❚❳❖▲❱❭ ❳❚❖❱❛❯❳❚❲ ❵P■❑■❖■❵❜❳❚❲❭ ▼❘❖■▼❯❳❚❲❭ ■▼ ❝❜ ▲❚❜ ❳❚❬■▼❨▲❢ ❑❳■❚ ❙❑■▼▲❲❘ ■▼ ▼❘❑▼❳❘r▲❱ ❙❜❙❑❘❨❭ ❞❳❑P■❛❑ ❑P❘ ❵▼❳■▼ ❞▼❳❑❑❘❚ ❵❘▼❨❳❙❙❳■❚ ■❬ ❑P❘ ❖■❵❜▼❳❲P❑ ■❞❚❘▼ ▲❚❯ ❑P❘ ❵❛❝❱❳❙P❘▼❫ ❤P❘ ❳❚❬■▼❨▲❑❳■❚ ❳❚ ❑P❳❙ ❝■■❩ ❳❙ ❯❳❙❑▼❳❝❛❑❘❯ ■❚ ▲❚ ✐❣❙ ❪❙❥ ❝▲❙❳❙❭ ❞❳❑P■❛❑ ❞▲▼▼▲❚❑❜❫ ❦P❳❱❘ ❘r❘▼❜ ❵▼❘❖▲❛❑❳■❚ P▲❙ ❝❘❘❚ ❑▲❩❘❚ ❳❚ ❑P❘ ❵▼❘❵▲▼▲❑❳■❚ ■❬ ❑P❳❙ ❞■▼❩❭ ❚❘❳❑P❘▼ ❑P❘ ▲❛❑P■▼ ❚■▼ ◆■ ❏❑▲▼❖P ◗▼❘❙❙❭ ❪❚❖❫ ❙P▲❱❱ P▲r❘ ▲❚❜ ❱❳▲❝❳❱❳❑❜ ❑■ ▲❚❜ ❵❘▼❙■❚ ■▼ ❘❚❑❳❑❜ ❞❳❑P ▼❘❙❵❘❖❑ ❑■ ▲❚❜ ❱■❙❙ ■▼ ❯▲❨▲❲❘ ❖▲❛❙❘❯ ■▼ ▲❱❱❘❲❘❯ ❑■ ❝❘ ❖▲❛❙❘❯ ❯❳▼❘❖❑❱❜ ■▼ ❳❚❯❳▼❘❖❑❱❜ ❝❜ ❑P❘ ❳❚❬■▼❨▲❑❳■❚ ❖■❚❑▲❳❚❘❯ ❳❚ ❳❑❫
✘✣✤ ✁✤ ✜
✂✄☎✆✝✞✟✠☎✡✝✄ ☛☞✆☎ ✂✌ ✍✎✏ ✑☞✒✡✠✒ ✓✎☞✔☎✏✆ ✕✌ ✖ ✗✡✄✡✙☞✚ ✓✝✙✔✡✚✏✆ ✓✎☞✔☎✏✆ ✛✌ ✢✄☞✆✥ ✦✔✏✆☞☎✝✆✒ ✓✎☞✔☎✏✆ ✧✌ ✑✡✄☞✆✥ ✦✔✏✆☞☎✝✆✒ ✓✎☞✔☎✏✆ ★✌ ✩✝✪✡✠☞✚ ☞✄✞ ✫✏✚☞☎✡✝✄☞✚ ✦✔✏✆☞☎✝✆✒ ✓✎☞✔☎✏✆ ✬✌ ✩✝✠☞✚ ✭☞✆✡☞✮✚✏✒ ✓✎☞✔☎✏✆ ✯✌ ✂✰ ✱☎☞☎✏✙✏✄☎✒ ☞✄✞ ✓✝✄✞✡☎✡✝✄☞✚ ✲✳✔✆✏✒✒✡✝✄✒ ✓✎☞✔☎✏✆ ✴✌ ✓✝✙✔✝✟✄✞ ✱☎☞☎✏✙✏✄☎✒ ✓✎☞✔☎✏✆ ✵✌ ✩✝✝✔✒ ✓✎☞✔☎✏✆ ✶✌ ✷✟✄✠☎✡✝✄✒ ✓✎☞✔☎✏✆ ✕✸✌ ✷✡✚✏✹✒✠✝✔✏ ✭☞✆✡☞✮✚✏✒ ☞✄✞ ✱☎✝✆☞✪✏✹✠✚☞✒✒ ✱✔✏✠✡✰✡✏✆✒ ☛☞✆☎ ✂✂✌ ✍✥✔✏✒ ✑✏✥✝✄✞ ✡✄☎ ✓✎☞✔☎✏✆ ✕✕✌ ✩✝✄✪ ✂✄☎✏✪✏✆✒ ✓✎☞✔☎✏✆ ✕✛✌ ✢✄✒✡✪✄✏✞ ✂✄☎✏✪✏✆✒ ✓✎☞✔☎✏✆ ✕✧✌ ✷✚✝☞☎✡✄✪✹✔✝✡✄☎ ✺✟✙✮✏✆✒ ✓✎☞✔☎✏✆ ✕★✌ ☛✝✡✄☎✏✆✒ ✓✎☞✔☎✏✆ ✕✬✌ ✖✆✆☞✥✒ ☞✄✞ ☛✝✡✄☎✏✆ ✖✆✡☎✎✙✏☎✡✠ ✓✎☞✔☎✏✆ ✕✯✌ ✓✎☞✆☞✠☎✏✆✒ ☞✄✞ ✱☎✆✡✄✪✒ ✓✎☞✔☎✏✆ ✕✴✌ ✱✟✔✔✝✆☎✡✄✪ ✻✥✄☞✙✡✠ ✗✏✙✝✆✥ ✖✚✚✝✠☞☎✡✝✄ ✓✎☞✔☎✏✆ ✕✵✌ ✱☎✆✟✠☎✟✆✏✒ ☛☞✆☎ ✂✂✂✌ ✦✔☎✡✙✡✼☞☎✡✝✄✒ ✓✎☞✔☎✏✆ ✕✶✌ ✦✔☎✡✙✡✼✡✄✪ ✍☞✠✽✥ ☛✆✝✪✆☞✙✒ ✓✎☞✔☎✏✆ ✛✸✌ ✫✏✪✡✒☎✏✆ ✖✚✚✝✠☞☎✡✝✄ ✺✏✳☎ ✱☎✏✔✒ ✖✔✔✏✄✞✡✳ ✖ ✌✻✏✮✟✪✪✡✄✪ ✖✒✒✏✙✮✚✥ ✓✝✞✏ ✾✡☎✎ ✿✻✑ ✝✆ ✩✩✻✑ ✫✏✰✏✆✏✄✠✏✒ ✓✎☞✔☎✏✆✒ ✡✄ ✆✏✞ ☞✆✏ ✡✄✠✚✟✞✏✞ ✡✄ ☎✎✡✒ ✲☞✆✚✥ ✖✠✠✏✒✒ ☛✻✷❀
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
!"#$%&'(#!%"
!"#$%%'()*%(+,-'%",&%./,0/(112$0%)($0-(0#3%&,/*4%%'#$5%',%+,//,&% 1#'(.",/3%6/,1%6($'(37%$,8#)39%:,1.2)#/3%(/#%1(02:4%($5%'"#%.#,.)#%&",% &,/*%,$%'"#1%(/#%&2;(/5321,$./'
"#$!5+2''2+!)0!H)1/)05!IJ[!)1!)0!"#%"(8"8.H+-'9)IJ+9$.D&$5.0KHJL4.0&/2/)&09!E2%#!*)0$!&4!/#)1! 5+2''2+!)1!2!*$&89-%7&(.$9!"!/#2/!3$4)0$1!#&.!2!*205-25$!%&01/+-%/!%20!7$!4&+'$3!4+&'!2!1$F-$0%$!&4! &/#$+!*205-25$!%&01/+-%/1!203!/&8$019!E?NH9! Q&-A**!+$4$+!/&!/#)1!4&+'2*!5+2''2+!.#)*$!.+)/)05!/#$!(2+1$+:!7-/!,&-!.&0A/!$@(*)%)/*,!3$4)0$!/#$1$! 5+2''2+!+-*$1!20,.#$+$!)0!,&-+!%&'()*$+9!
:*/;.,6# b&.!/#2/!,&-!#2?"!3$4)0)/)&0!203!2!4&+'2*!5+2''2+:!*$/A1!/2*8!27&-/!#&.!/&!2%/-2**,!.+)/$! /#$!(2+1$+9!O$A**!-1$!2!1/+2)5#/4&+.2+3!/$%#0)F-$!%2**$3!$"-9$)7=".8")-"(%.*+$)7(6:!.#)%#!-1$1!2!3)44$+$0/! 4-0%/)&0!/&!(2+1$!$2%#!0&0J/$+')02*!1,'7&*!203!+$/-+0!/#$!%&++$1(&03)05!>?"!0&3$9!]&+!$@2'(*$:!.#$0! /#$!(2+1$+!$@($%/1!/&!$0%&-0/$+!/#$!!1,'7&*!3$4)0$3!)0!H)1/)05!IJ[:!)/!%2**1!2!4-0%/)&0!/&! (2+1$!/#2/!1,'7&*!203!+$/-+0!/#$!statement!>?"!0&3$!4+&'!H)1/)05!IJf9!"#$!'2)0!(2+1)05!4-0%/)&0! (2+1$1!/#$!!1,'7&*:!.#)%#!%&++$1(&031!/&!/#$!$0/)+$!(+&5+2'9!O)/#!$2%#!4-0%/)&0!%2**!/&! #203*$!2!0$.!1,'7&*:!/#$!(2+1$+!3$1%$031!/&!2!*&.$+!*$?"!0&3$9!?)0%$!/#)1!)1!2!3)44$+$0/!0&0J/$+')02*!1,'7&*:!)/!1#&-*3!7$!#203*$3!7,!2!1$(2+2/$!4-0%/)&0:! parse_exp:!.#)%#!;!#2?"!0&3$!+$(+$1$0/)05!/#$! +$/-+0!?"!.#$0!,&-!.+&/$!/#$!(2+1$+9!Q&-A+$!233)05!,$/!20&/#$+!32/2!1/+-%/-+$:! )01/$23!&4!.+)/)05!211$'7*,!/&!2!4)*$!+)5#/!2.2,:!1&!/#2/!,&-!%20!'&3)4,!/#$!211$'7*,!%&3$!24/$+!,&-A?"!0&3$9! !"#$%&'(/&
01!&2)3%,&"+3&45678"$%+9&0,,%:#$;&
72!&8"9$&
700$:;*$93&-87$C!-%#!B$)'('$,!&6-&!'&!5)+#39$,!&6$!)'?6&!$>'&! 9+#$@!"&!-7,+!B-7'#-&$,!&6-&!/+3)!9+;5'7$)!)$G$9&,!$-96!'%B-7'#!&$,&!5)+?)-;C!-,!'&!#'#!(+)!$-)7'$)!,&-?$,@!
@'**/(5$ ;0!/#)1!%#2(/$+:!,&-!.+&/$!2!%&'()*$+!/#2/!/+2014&+'1!2!%&'(*$/$!G!(+&5+2'!)0/&!20!$@$%-/27*$!/#2/! +-01!&0!,&-+!%&'(-/$+9!Q&-!*$2+0$3!#&.!/&!)0/$+(+$/!2!(+&5+2'!.+)//$0!)0!@[\!211$'7*,:!2!4&+'2*! 5+2''2+!)0!$@/$03$3!D2%8-1Jb2-+!4&+':!203!20!>?"!3$4)0)/)&0!)0!>?NH9!"#$!18)**1!203!%&0%$(/1!,&-! *$2+0$3!)0!/#)1!%#2(/$+K203!/#$!4&-+!%&'()*$+!1/25$1!,&-!)'(*$'$0/$3K2+$!/#$!4&-032/)&0!4&+! $$93&-87$!,&-9.,!-%#!#$,9)'8$,!6+0! I'%3>!,/,&$;,!('?3)$!+3&!06$&6$)!-!5)+?)-;=,!,&-9.!,6+37#!8$!$>$93&-87$!O&!!(#4$$5552',)#2%8:$;/89$')%&,."#$M+=P@!!
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
!
!" !"#$%&'()$#*'$+&
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
!"#$%"%&'&($)"!"#$%&'()$#*'$+*"+#,-#"./&($0&".1"$"%,12)&"'$)3&4"51"0#,%" -#$/0&(*"6.37))"&80&19"6.3("-.:/,)&("0."#$19)&"0+."31$(6"./&($0.(%;" 1&2$0,.1"$19"93&!E(,2%:C! U%@&+!6%!5(4*,%!&5%!#2&%)!93&63'%!8#10,%1%4&!%@0)%''3#4:!V%!'&()&!97!8#0734$!&5%!'#2)8%!E(,2%+! ')%*!34!-4(%rbp)+!!&5%!*%'&34(&3#4!(**)%''!(&!-8(%rbp):!V%!8(4-&!*#!&53'!34!(!'34$,%!34'&)28&3#4+! 9%8(2'%!mov!8(4-&!5(E%!1%1#)7!(**)%''%'!('!9#&5!'#2)8%!(4*!*%'&34(&3#4!#0%)(4*':!J&!,%('&!#4%!#0%)(4*! !mov!4%%*'!!9%!(!)%$3'&%)!#)!(4!311%*3(&%!E(,2%:!V%!$%&!()#24*!&53'!97!8#0734$!-2!A)#1!1%1#)7!34! (!'8)(&85!)%$3'&%)+!G?WX!3+!(4*!A)#1!&5%)%!!&5%!*%'&34(&3#4!1%1#)7!(**)%''!4:!V%!&5%4!&(.%!&5%!93&63'%! 8#10,%1%4&!#A!-2!63&5!&5%!not!34'&)28&3#4!5+!'#!1%1#)7!(**)%''!-8(%rbp)!4#6!8#4&(34'!&5%!E(,2%!6%! 6(4&!!)%&2)4Y!~(-2)+!65385!8#1%'!#2&!!1:!"#!)%&2)4!&53'!E(,2%+!6%!1#E%!3&!34!ZJ[:!"5%!A34(,!&5)%%! 34'&)28&3#4'!()%!&5%!12!,%&'!+".&/'#2"+!65385!&%()'!*#64!&5%!'&(8.!A)(1%!(4*!)%&2)4'!A)#1!&5%!A248&3#4:! !"#$!
;A!7#2!8#103,%!=Y!65(&!&5%!A248&3#4!0)#,#$2%!(4*!%03,#$2%! *#+!(4*!657!6%!)%A%)!!'&(8.!(**)%''%'!)%,(&3E%!!(!E(,2%!34!&5%!GPN!)%$3'&%):!"#!(4'6%)!&5%'%+!6%!4%%*! !&(,.!(9#2&!&5%!'%$1%4&!#A!0)#$)(1!1%1#)7!8(,,%*!&5%!*%$,4:!"5%!G^N!)%$3'&%)+!(,'#!8(,,%*!&5%!*%$,4+ .'&!%"3+!(,6(7'!5#,*'!&5%!(**)%''!#A!&5%!!#A!&5%!'&(8.:!BG^N!0#34&'!!&5%!,('&!2'%*!'&(8.!',#&+!)(&5%)!&5(4! &5%!A3)'&!A)%%!#4%:C!J'!63&5!(47!'&(8.!*(&(!'&)28&2)%+!7#2!8(4!02'5!E(,2%'!#4!&5%!'&(8.!(4*!0#0!E(,2%'!#AA! #A!3&I!&5%!push!(4*!pop!(''%19,7!34'&)28&3#4'!*#!%@(8&,7!&5(&:! "5%!'&(8.!$)#6'!()*!,#6%)!1%1#)7!(**)%''%':!V5%4!7#2!02'5!'#1%&534$!#4!&5%!'&(8.+!7#2! *%8)%1%4&+G^N:!"5(&!1%(4'!&5%!O!#A!&5%!'&(8.RD&5%!(**)%''!')%*!34!G^ND3'!&5%!/')"*%!(**)%''!#4! &5%!'&(8.:!"5%!'&(8.!*3($)(1'!34!&53'!9##.!()%!#)3%4&%*!63&5!,#6%)!1%1#)7!(**)%''%'!(&!&5%!+!'#!&5%!! #A!&5%!'&(8.!3'!(&!&5%!!#A!&5%!*3($)(1:!"534.!#A!&5%!1%1#)7!(**)%''%'!34!&5%'%!*3($)(1'!,3.%!,34%! 4219%)'!34!(!8#*%!,3'&34$:!"5%!!#A!(!8#*%!,3'&34$!3'!,34%!?+!(4*!,34%!4219%)'!348)%('%!('!7#2!$#!*#64I! '313,(),7+!&5%!(**)%''%'!34!&5%'%!*3($)(1'!348)%('%!('!7#2!$#!*#64!&5%!0($%!#)!'8)%%4:!U#&%!&5(&!1#'&! '&(8.!*3($)(1'!34!#&5%)!9##.'!(4*!()&38,%'!2'%!&5%!#00#'3&%!#)3%4&(&3#4D&5%7!02&!&5%!!#A!&5%!'&(8.!(&!&5%! 9#&!#A!&5%!*3($)(1+!'#!,#6%)!1%1#)7!(**)%''%'!(00%()!,#6%)!#4!&5%!0($%:!;!A34*!&5(&!,(7#2&!)%(,,7! 8#4A2'34$+!92&!3A!7#2!0)%A%)!3&+!_2'&!&2)4!7#2)!9##.!20'3*%!*#64:! J4!34'&)28&3#4!,3.%!push $3!*#%'!&6#!&534$'Y! ?:! V)3&%'!&5%!E(,2%!9%34$!02'5%*!B34!&53'!%@(10,%+!3C!!&5%!4%@&!%10&7!'0#&!#4!&5%!'&(8.:!"5%!push!(4*! pop!34'&)28&3#4'!(*_2'&!&5%!'&(8.!0#34&%)!34!`>97&%!348)%1%4&'+!(4*!&5%!!E(,2%!#4!&5%!'&(8.!3'! 82))%4&,7!(&!&5%!(**)%''!')%*!34!G^N+!'#!&5%!4%@&!%10&7!'0#&!3'!G^N!K!`:! =:! X%8)%1%4&'!G^N!97!%3$5&:!"5%!4%6!(**)%''!34!G^N!3'!4#6!&5%!!#A!&5%!'&(8.+!(4*!&5%!E(,2%!(&!&5(&! (**)%''!3'!3:!! F3$2)%!=>?!3,,2'&)(&%'!&5%!%AA%8&!#A!(!push!34'&)28&3#4!#4!&5%!'&(8.!(4*!G^N!)%$3'&%):!
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
! ?D()%!#4,7!A#2)!97&%':!H#2!8(4-&!02'5!#4,7!A#2)!97&%'!#4!&5%!'&(8.+!92&! 7#2!8(4!2'%!movl!!8#07!(!Q>97&%!E(,2%!34!'&(8.!'0(8%!7#2-E%!(,)%(*7!(,,#8(&%*:!J!8#20,%!#A! 34'&)28&3#4'!*#!&53'!34!97&%!E(,2%':!;4!%3&5%)!8('%+!3&-'!(,'#!0#''39,%!!02'5! (4*!0#0!=>97&%!E(,2%'+!92&!7#2!&7038(,,7!*#4-&!4%%*!:C!c%1#)7!(**)%''%'!#4!@dQ!'7'&%1'!()%!%3$5&! 97&%'+!'#!7#2!8(4!2'%!push!(4*!pop!!02&!&5%1!#4!(4*!&(.%!&5%1!#AA!&5%!'&(8.D&53'!63,,!8#1%!34!5(4*7! 34!(!1#1%4&:! "5%!'&(8.!3'4-&!_2'&!(4!24*3AA%)%4&3(&%*!8524.!#A!1%1#)7I!3&-'!*3E3*%*!34!'%8&3#4'!8(,,%*!*%$,4+ 13$-"*:!V5%4%E%)!(!A248&3#4!3'!8(,,%*+!3&!(,,#8(&%'!'#1%!1%1#)7!(&!&5%!!#A!&5%!'&(8.!97!*%8)%('34$!&5%! '&(8.!0#34&%):!"53'!1%1#)7!3'!&5%!A248&3#4-'!'&(8.!A)(1%+!65%)%!3&!')%'!,#8(,!E()3(9,%'!(4*!&%10#)()7! E(,2%':!S2'&!9%A#)%!&5%!A248&3#4!)%&2)4'+!3&!*%(,,#8(&%'!3&'!'&(8.!A)(1%+!)%')34$!&5%!'&(8.!0#34&%)!!3&'! 0)%E3#2'!E(,2%:!P7!8#4E%4&3#4+!&5%!GPN!)%$3'&%)!0#34&'!!&5%!9('%!#A!&5%!82))%4&!'&(8.!A)(1%:!V%!)%A%)!! *(&(!34!&5%!82))%4&!'&(8.!A)(1%!)%,(&3E%!!&5%!(**)%''!')%*!34!GPN:!"53'!1%(4'!6%!*#4-&!4%%*!(9'#,2&%! (**)%''%'+!65385!6%!8(4-&!.4#6!34!(*E(48%:!^348%!&5%!'&(8.!$)#6'!()*!,#6%)!1%1#)7!(**)%''%'+!%E%)7! (**)%''!34!&5%!82))%4&!'&(8.!A)(1%!3'!,#6%)!&5(4!&5%!(**)%''!')%*!34!GPNI!&53'!3'!657!&5%!(**)%''%'!#A! ,#8(,!E()3(9,%'+!,3.%!-4(%rbp)+!(,,!5(E%!4%$(&3E%!#AA'%&'!A)#1!GPN:!;4!,(&%)!85(0&%)'+!6%-,,!(,'#!)%A%)!! *(&(!34!&5%!8(,,%)-'!'&(8.!A)(1%+!,3.%!A248&3#4!0()(1%&%)'+!)%,(&3E%!!GPN:!!B;&-'!(,'#!0#''39,%!!)%A%)!! ,#8(,!E()3(9,%'!(4*!0()(1%&%)'!)%,(&3E%!!G^N+!(4*!4#&!9#&5%)!63&5!GPN!(&!(,,I!'#1%!8#103,%)'!*#!&53'!('! (4!#0&313M(&3#4:C! =Y! ?:! pushq %rbp!'(E%'!&5%!82))%4&!E(,2%!#A!GPN+!&5%!(**)%''!#A!&5%!9('%!#A!&5%!8(,,%)-'!'&(8.!A)(1%+! #4!&5%!'&(8.:!V%-,,!4%%*!&53'!E(,2%!65%4!6%!)%')%!&5%!8(,,%)-'!'&(8.!A)(1%!,(&%):!"53'!E(,2%!63,,!9%! (&!&5%!9#&!#A!&5%!4%6!'&(8.!A)(1%!%'&(9,3'5%*!97!&5%!4%@&!34'&)28&3#4:! =:! movq %rsp, %rbp!1(.%'!&5%!!#A!&5%!'&(8.!&5%!9('%!#A!&5%!4%6!'&(8.!A)(1%:!J&!&53'!0#34&+!&5%! !(4*!9#&!#A!&5%!82))%4&!'&(8.!A)(1%!()%!&5%!'(1%:!"5%!82))%4&!'&(8.!A)(1%!5#,*'!%@(8&,7!#4%!
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
E(,2%+!65385!9#&5!G^N!(4*!GPN!0#34&!Y!&5%!9('%!#A!&5%!8(,,%)-'!'&(8.!A)(1%+!65385!6%!'(E%*!34!&5%! 0)%E3#2'!34'&)28&3#4:! T:! subq $n, %rsp!*%8)%1%4&'!&5%!'&(8.!0#34&%)!97!!!97&%':!"5%!'&(8.!A)(1%!4#6!5('!!!97&%'! (E(3,(9,%!!')%!,#8(,!(4*!&%10#)()7!E()3(9,%':!;4!F3$2)%!=>=+!&53'!34'&)28&3#4!(,,#8(&%'!=Q!97&%'+! %4#2$5!'0(8%!A#)!'3@!Q>97&%!34&%$%)':!!
! T:! int main(void) { return --2; }
!"#$"%&'()B!
+%'"%C08"5','-./&.01'=#"%&'$34'547.414%$'/-4.0$/.'
"53'!'5#2,*4-&!8#103,%+!9%8(2'%!7#2!8(4-&!*%8)%1%4&!(!8#4'&(4&:!P2&!3A!7#2)!8#103,%)!*#%'4-&!.4#6! &5(&!--!3'!(!*3'&348&!.%4+!3&!63,,!&534.!+!,$%+!0#$%!*+1+%!&25!,3)**!-25.*+!3-+'8!
Writing a C Compiler (Early Access) © 2023 by Nora Sandler
56")=$e!'5#6'!&5%!20*(&%*!J^"!*%A343&3#4+!63&5! 4%6!0()&'!9#,*%*:! program = Program(function_definition) function_definition = Function(identifier name, statement body) statement = Return(exp) exp = Constant(int) | Unary(unary_operator, exp) unary_operator = Complement | Negate
!"#$"%&'()E!
934'06#$.07$'#:%$0F'$.44'2"$3'=%0.:'/-4.0$"/%#'
"5%!20*(&%*!)2,%!A#)!exp!34*38(&%'!&5(&!(4!%@0)%''3#4!8(4!9%!%3&5%)!(!8#4'&(4&!34&%$%)!#)!(!24()7! #0%)(&3#4:!J!24()7!#0%)(&3#4!8#4'3'&'!#A!#4%!#A!&5%!&6#!24()7!#0%)()'+!Complement!#)!Negate+! (00,3%*!!(4!344%)!%@0)%''3#4:!U#&38%!&5(&!&5%!*%A343&3#4!#A!exp!3'!)%82)'3E%Y!&5%!Unary!8#4'&)28)!A#)! (4!exp!4#*%!8#4&(34'!(4#&5%)!exp!4#*%:!"53'!,%&'!2'!8#4'&)28&!()93&)()3,7!*%%0,7!4%'&%*!%@0)%''3#4'+!,3.%! -(~(-~-(-4))):! V%!(,'#!4%%*!!1(.%!&5%!8#))%'0#4*34$!85(4$%'!!&5%!$)(11()+!'5#64!34!(**)%''!8#*%!34'&%(*!#A!8#4E%)&34$!(4!J^"!*3)%8&,7!! (''%19,7:!F3)'&+!3&!,%&'!2'!5(4*,%!1(_#)!'&)28&2)(,!&)(4'A#)1(&3#4'D,3.%!)%1#E34$!4%'&%*!%@0)%''3#4'D '%0()(&%,7!A)#1!&5%!*%&(3,'!#A!(''%19,7!,(4$2($%+!,3.%!A3$2)34$!#2&!65385!#0%)(4*'!()%!E(,3*!A#)!65385! 34'&)28&3#4':!V%!8(4!6)3&%!'%E%)(,!'1(,,%)+!'310,%)!8#103,%)!0(''%'+!34'&%(*!#A!5(E34$!#4%!52$%+! 8#10,38(&%*!(''%19,7!$%4%)(&3#4!0('':!^%8#4*+!&5)%%>(**)%''!8#*%!3'!6%,,>'23&%*!!'%E%)(,!#0&313M(&3#4'! 6%-,,!310,%1%4&!34!N()&!;;;:!;&!5('!(!'310,%+!243A#)1!'&)28&2)%+!65385!1(.%'!3&!%('7!!(4'6%)!L2%'&3#4'! ,3.%+!O3'!&5%!)%'2,&!#A!&53'!%@0)%''3#4!%E%)!2'%*gR!#)!O63,,!&53'!E()3(9,%!(,6(7'!&5%!5(E%!'(1%!E(,2%gR!"5%! (4'6%)'!!&5#'%!L2%'&3#4'!*%&%)134%!65(&!#0&313M(&3#4'!()%!'(A%!!0%)A#)1:! !"#$ +,&!-)&"$&*./,*/"#0$+,&!-)&"$!*(/"!#$ @53+%'+.)23+!%+(%+,+5323)#5,!*)>+!3-%++A2..%+,,!.+!2%+!$,+/$*!/#%!25#3-+%!%+2,#54!2*3-#$6-!)3!),5B3!%+*+7253!3#!3-),!(%#C+&38!D5! )53+%'+.)23+!%+(%+,+5323)#5!&25!(%#7).+!2!''#5!32%6+3!/#%!'$*3)(*+!,#$%&+!*256$26+,!25.!2!''#5!,32%3)56!(#)53!/#%!2,,+'?*0! 6+5+%23)#5!/#%!'$*3)(*+!32%6+3!2%&-)3+&3$%+,8!9-+!EEFG!'()*+%!/%2'+;#%>!H&!!(#1$$--,234)5I!),!2!6%+23!+12'(*+!#/!3-),:!)3!,$((#%3,! ,+7+%2*!/%#53+5.,!25.!?2&>+5.,!$,)56!2!,)56*+!)53+%'+.)23+!%+(%+,+5323)#58!@/!0#$!;253!3#!'()*+!2!5+;!(%#6%2'')56!*256$26+4! 0#$!&25!C$,3!'()*+!)3!3#!3-+!EEFG!@J4!25.!3-+5!EEFG!32>+,!&2%+!#/!#(3)')K)56!3-23!@J!25.!(%#.$&)56!'2&-)5+!.+!/#%!.)//+%+53! +!250!*256$26+!;)3-!25!EEFG!/%#53+5.!25.!'()*+!)3! /#%!3-23!2%&-)3+&3$%+8!
c#'&!8#103,%)'!2'%!'#1%!A#)1!#A!&5)%%>(**)%''!8#*%!34&%)4(,,7+!92&!&5%!*%&(3,'!E()7:!;-E%!*%83*%*!! 4(1%!&5%!34&%)1%*3(&%!)%0)%'%4&(&3#4!34!&53'!9##.!9:;=>:!BU(134$!7#2)!34&%)1%*3(&%!)%0)%'%4&(&3#4'!3'+! 34!17!#0343#4+!#4%!#A!&5%!9%'&!0()&'!#A!8#103,%)!*%'3$4:C!;!1(*%!20!"J/hH!A#)!&53'!9##.+!92&!3&-'!'313,()! !&5)%%>(**)%''!8#*%!34!#&5%)!8#103,%)':!
!"#$%$%&'()*+,' V%!*%A34%!"J/hH!34!J^XQ:! program = Program(function_definition) function_definition = Function(identifier, 1 instruction* body) instruction = Return(val) | Unary(unary_operator, val src, val dst) val = Constant(int) | Var(identifier) unary_operator = Complement | Negate
!"#$"%&'()J!
934'9+,KL'M>'
;4!"J/hH+!(!A248&3#4!9#*7!8#4'3'&'!#A!(!,3'&!#A!34'&)28&3#4'!1+!)(&5%)!&5(4!(!'34$,%!'&(&%1%4&:!;4!&53'! )%'0%8&+!3&-'!'313,()!!&5%!(''%19,7!J^"!6%!*%A34%*!34!&5%!0)%E3#2'!85(0&%):!F#)!4#6+!"J/hH!5('!&6#! 34'&)28&3#4'Y!Return!(4*!Unary:!Return!)%&2)4'!(!E(,2%I!Unary!0%)A#)1'!'#1%!24()7!#0%)(&3#4!#4! src+!&5%!'#2)8%!E(,2%!A#)!&5%!%@0)%''3#4+!(4*!')%'!&5%!)%'2,&!34!dst+!&5%!*%'&34(&3#4:!P#&5!34'&)28&3#4'! #0%)(&%!#4!val'+!65385!8(4!9%!%3&5%)!8#4'&(4&!34&%$%)'!BConstantC!#)!&%10#)()7!E()3(9,%'!BVarC:!"5%! "J/hH!6%!$%4%)(&%!12'&!1%%&!#4%!)%L23)%1%4&!&5(&!3'4-&!%@0,383&!34!i:!"5%!&)38.7!0()&!3'!&2)434$!(4!exp!4#*%!34!(!,3'&!#A! 34'&)28&3#4'I!#48%!7#2!5(E%!&5(&!A3$2)%*!#2&+!5(4*,34$!&5%!#&5%)!J^"!4#*%'!3'!%('7:!"(9,%!=>?!,3'&'!(!A%6! %@(10,%'!#A!J^"'!(4*!&5%!)%'2,&34$!"J/hH:! %&'()$*+,$
%-./0$1)23)4)56&67"54$"8$95&3:$;#23)447"54$
*#!$
!*123$
Return(Constant(3)) Return(Unary(Complement, Constant(2)))
Return(Constant(3)) Unary(Complement, Constant(2), Var("tmp.0")) Return(Var("tmp.0"))! Unary(Negate, Constant(8), Var("tmp.0")) Unary(Complement, Var("tmp.0"), Var("tmp.1")) Unary(Negate, Var("tmp.1"), Var("tmp.2")) Return(Var("tmp.2"))!
Return(Unary(Negate, Unary(Complement, Unary(Negate, Constant(8)))))!
;4!&5%'%!%@(10,%'+!6%!8#4E%)&!%(85!24()7!#0%)(&3#4!34!(!Unary!"J/hH!34'&)28&3#4+!'&()&34$!63&5! &5%!344%)1#'&!%@0)%''3#4!(4*!6#).34$!#2)!6(7!#2&:!V%!')%!&5%!)%'2,&!#A!%(85!Unary!34'&)28&3#4!34!(! &%10#)()7!E()3(9,%+!65385!6%!&5%4!2'%!34!&5%!#2&%)!%@0)%''3#4!#)!return!'&(&%1%4&:!*%A34%*!3*%4&3A3%)'!9%8(2'%!34&%$%)'!()%4-&!E(,3*!3*%4&3A3%)'!34!/:!;4!"(9,%!=>?+!6%!2'%!(!E()3(&3#4! #4!&53'!(00)#(85I!6%!8#48(&%4(&%!(!*%'8)30&3E%!'&)34$+!(!0%)3#*+!(4*!&5%!$,#9(,!8#24&%)!!0)#*28%!243L2%! 3*%4&3A3%)'!,3.%!tmp.0:!"5%'%!6#4-&!8#4A,38&!63&5!2'%)>*%A34%*!3*%4&3A3%)'!9%8(2'%!/!3*%4&3A3%)'!8(4-&! 8#4&(34!0%)3#*':!V3&5!&53'!4(134$!'85%1%+!7#2!8(4!%48#*%!2'%A2,!34A#)1(&3#4!34!(2$%4%)(&%*!4(1%'+! ,3.%!&5%!4(1%!#A!&5%!A248&3#4!65%)%!&5%7-)%!2'%*:!B;&-'!,%''!2'%A2,!3A!7#2!4(1%!%E%)7!E()3(9,%!tmp+!,3.%! ;-E%!*#4%!5%)%:C!
:5;/0$%&'0??+!348,2*%'!(!8#4'&)28&!8#))%'0#4*34$!!&5%!sub!34'&)28&3#4!B&5%!&53)*! 34'&)28&3#4!34!&5%!A248&3#4!0)#,#$2%C:!"53'!8#4'&)28&!'0%83A3%'!5#6!1(47!97&%'!6%!4%%*!!'29&)(8&!A)#1! &5%!'&(8.!0#34&%):!"5%!(''%19,7!J^"!*#%'4-&!348,2*%!&5%!#&5%)!34'&)28&3#4'!A)#1!&5%!0)#,#$2%!(4*! %03,#$2%I!&5%'%!34'&)28&3#4'!()%!(,6(7'!&5%!'(1%+!'#!6%!8(4!(**!&5%1!*2)34$!8#*%!%13''3#4:!"5(&!'(3*+!&5%! #&5%)!(00)#(85%'!!)%0)%'%4&34$!&5%!A248&3#4!0)#,#$2%!(4*!%03,#$2%!(,'#!6#).+!'#!85##'%!65385%E%)!7#2! ,3.%!9%'&:! V%-,,!(,'#!34&)#*28%!.*"27'3"#&*%"3*!!)%0)%'%4&!&%10#)()7!E()3(9,%':!V%!2'%!0'%2*#)%$3'&%)'!('! #0%)(4*'!34!(''%19,7!34'&)28&3#4'+!,3.%!)%(,!)%$3'&%)'I!&5%!#4,7!*3AA%)%48%!3'!&5(&!6%!5(E%!(4!24,313&%*! '200,7!#A!&5%1:!P%8(2'%!&5%7!()%4-&!)%(,!)%$3'&%)'+!&5%7!8(4-&!(00%()!34!&5%!A34(,!(''%19,7!0)#$)(1D &5%7-,,!4%%*!!9%!)%0,(8%*!97!)%(,!)%$3'&%)'!#)!1%1#)7!(**)%''%'!34!(!,(&%)!8#103,%)!0('':!F#)!4#6+!6%-,,! (''3$4!%E%)7!0'%2*#)%$3'&%)!!(!*3'&348&!(**)%''!34!1%1#)7:!;4!N()&!;;;+!6%-,,!6)3&%!(!3"#&*%"3+$//',$%'3+! 65385!(''3$4'!('!1(47!0'%2*#)%$3'&%)'!('!0#''39,%!!5()*6()%!)%$3'&%)'!34'&%(*!#A!1%1#)7!(**)%''%':! 93&!G?W! )%$3'&%):!"5%!4(1%'!J"5463?>64$
*556789:$
Program(function_definition) Function(name, instructions)
Program(function_definition) Function(name, instructions)
@5463?>67"54$ Return(val) Unary(unary_operator, src, dst)
Mov(val, Reg(AX)) Ret Mov(src, dst) Unary(unary_operator, dst)
A2)3&6"34$ Complement Negate
Not Neg
A2)3&5B4$ Constant(int) Var(identifier)
Imm(int) Pseudo(identifier)
^348%!#2)!4%6!(''%19,7!34'&)28&3#4'!2'%!&5%!'(1%!#0%)(&3#4!A#)!&5%!'#2)8%!(4*!*%'&34(&3#4+!6%!8#07! &5%!'#2)8%!E(,2%!34!&5%!*%'&34(&3#4!9%A#)%!3''234$!&5%!neg!#)!not!34'&)28&3#4:!U#&%!&5(&!6%-)%!4#&!2'34$! &5%!AllocateStack!34'&)28&3#4!7%&I!6%-,,!(**!3&!34!&5%!E%)7!,('&!0(''!9%A#)%!8#*%!%13''3#4+!#48%!6%! .4#6!5#6!1(47!97&%'!6%!4%%*!!(,,#8(&%:!V%-)%!(,'#!4#&!2'34$!(47!Stack!#0%)(4*'I!6%-,,!)%0,(8%! %E%)7!Pseudo!#0%)(4*!63&5!(!Stack!#0%)(4*!34!&5%!4%@&!8#103,%)!0('':!J4*!6%-)%!4#&!2'34$!&5%!G?WX! )%$3'&%)I!6%-,,!34&)#*28%!3&!65%4!6%!)%6)3&%!34E(,3*!34'&)28&3#4':!!
>"59/?$%&'@3"A;4."&$30".3' U%@&+!6%!6)3&%!(!8#103,%)!0(''!!)%0,(8%!%(85!Pseudo!#0%)(4*!63&5!(!Stack!#0%)(4*+!,%(E34$!&5%! )%'&!#A!&5%!(''%19,7!J^"!2485(4$%*:!;4!$ %"2+()"5463?>64$
4@>B@>$
Program(function_definition)
L%)53!#$3!3-+!/$5&3)#5!.+/)5)3)#5! N5!E)5$14!2..!23!+5.!#/!/)*+:! .section .note.GNU-stack,"",@progbits! .globl : pushq %rbp movq %rsp, %rbp
Function(name, instructions)
@5463?>67"54$ Mov(src, dst) Ret
Unary(unary_operator, operand) AllocateStack(int)
movl , ! movq %rbp, %rsp popq %rbp ret
subq $, %rsp
4B6?C>