Slide 1

Slide 1 text

*NQSPWJOH4XJGU5PPMTXJUIMJC4ZOUBY )BSMBO)BTLJOT !IBSMBOIBTLJOT

Slide 2

Slide 2 text

"HFOEB ↟ (PPWFSDPNQJMFSCBTJDT ↟ *OUSPEVDFMJC4ZOUBY ↟ -FBSOUIFEFTJHOPGMJC4ZOUBY ↟ -FBSOUIFMJC4ZOUBY"1*T ↟ 8SJUFB4XJGUGPSNBUUFS

Slide 3

Slide 3 text

4FNBOUJD"OBMZTJT 1BSTFS -FYFS $PNQJMFS#BTJDT Lexers, Parsers, Code Gen, Oh My! struct Cat {} [kw_struct, ident("Cat"), l_brace, r_brace] $BU 'SPOUFOE #BDLFOE

Slide 4

Slide 4 text

.BDIJOF-PXFSJOH 4FNBOUJD"OBMZTJT 1BSTFS -FYFS $PNQJMFS#BTJDT Lexers, Parsers, Code Gen, Oh My! struct Cat {} [kw_struct, ident("Cat"), l_brace, r_brace] $BU $BU 0QUJNJ[FS 4*-(FO 0101001010100… "OBMZTJT --7.*3(FO 'SPOUFOE #BDLFOE

Slide 5

Slide 5 text

4XJGU"CTUSBDU4ZOUBY5SFF struct Cat { let name: String }

Slide 6

Slide 6 text

4XJGU"CTUSBDU4ZOUBY5SFF struct Cat { let name: String } 4USVDU $BU .FNCFST 1SPQFSUZ OBNF 4USJOH MFU

Slide 7

Slide 7 text

MJC4ZOUBY ↟ 'VMMTPVSDFQSFTFSWJOH4ZOUBYUSFF ↟ 4XJGUBOE$ "1*T ↟ ,FFQTUSBDLPGBMMUPLFOTBOE5SJWJB ↟ 4QBDFT OFXMJOFT DPNNFOUT ↟ &WFSZUIJOHOFDFTTBSZUPQSJOUUIFGJMFCBDLPVU Why throw it all away?

Slide 8

Slide 8 text

MJC4ZOUBY5SFF struct Cat {}

Slide 9

Slide 9 text

MJC4ZOUBY5SFF struct Cat {} struct Cat { }

Slide 10

Slide 10 text

MJC4ZOUBY5SFF struct Cat {} struct Cat { }

Slide 11

Slide 11 text

MJC4ZOUBY5SFF struct Cat {} struct Cat { }

Slide 12

Slide 12 text

5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {}

Slide 13

Slide 13 text

5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {} struct Cat {} struct Cat { }

Slide 14

Slide 14 text

struct Cat {} struct Cat { } struct Feline {} struct { } Feline 5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {}

Slide 15

Slide 15 text

struct Cat {} struct Cat { } struct Feline {} struct { } Feline 5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {}

Slide 16

Slide 16 text

struct Cat {} struct Cat { } struct Feline {} struct { } Feline 5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {}

Slide 17

Slide 17 text

struct Cat {} struct Cat { } struct Feline {} struct { } Feline 5SBOTGPSNJOH4ZOUBY struct Feline {} struct Cat {}

Slide 18

Slide 18 text

(SJUUZ%FUBJMT ↟ 3BX4ZOUBY ↟ 4ZOUBY%BUB ↟ 4ZOUBY/PEFT

Slide 19

Slide 19 text

3BX4ZOUBY indirect enum RawSyntax { }

Slide 20

Slide 20 text

3BX4ZOUBY indirect enum RawSyntax { case node(SyntaxKind, [RawSyntax], SourcePresence) }

Slide 21

Slide 21 text

3BX4ZOUBY indirect enum RawSyntax { case node(SyntaxKind, [RawSyntax], SourcePresence) case token(TokenKind, Trivia, Trivia, SourcePresence) }

Slide 22

Slide 22 text

5SJWJB3VMFT ↟ 5SBJMJOH5SJWJB ↟ "UPLFOPXOTUIFUSJWJBBGUFSJUVQUPUIFGJSTUOFXMJOF ↟ -FBEJOH5SJWJB ↟ "UPLFOPXOTUIFUSJWJBCFGPSFJUTUBSUJOHXJUIUIFGJSTUOFXMJOF Two Simple Rules for Lexing my Beautiful Code

Slide 23

Slide 23 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 24

Slide 24 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 25

Slide 25 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 26

Slide 26 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 27

Slide 27 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 28

Slide 28 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code } if x == 6 {

Slide 29

Slide 29 text

5SJWJB3VMFT Two Simple Rules for Lexing my Beautiful Code if x == 6 { }

Slide 30

Slide 30 text

4ZOUBY%BUB ↟ (JWFTJEFOUJUZUPB3BX4ZOUBY ↟ $BOOPUCFTIBSFECFUXFFOOPEFT ↟ $BDIFTDIJMESFOMB[JMZ ↟ 1PJOUTCBDLUPUIFQBSFOUOPEF Finding My Identity

Slide 31

Slide 31 text

4ZOUBY/PEFT ↟ "TUSVDUGPSFBDILJOEPGOPEF ↟ 5ZQFTBGF"1* ↟ "DDFTTPSTGPSFBDIDIJME ↟ 5SBOTGPSNBUJPONFUIPET public class IfStmtSyntax: StmtSyntax { var ifKeyword: TokenSyntax { … } func withIfKeyword(_ node: TokenSyntax) -> IfStmtSyntax { … } // … more methods }

Slide 32

Slide 32 text

4ZOUBY$SFBUJPO"1*T • make"1*T • with"1*T • 4ZOUBY#VJMEFST

Slide 33

Slide 33 text

make"1*T let returnKeyword = SyntaxFactory.makeReturnKeyword(trailingTrivia: .spaces(1)) let three = SyntaxFactory.makeIntegerLiteralExpr(3) let returnStmt = SyntaxFactory.makeReturnStmt(returnKeyword: returnKeyword, expression: three) Fully Formed and Ready to Go return 3

Slide 34

Slide 34 text

with"1*T Fully Formed and Ready to Go let returnHello = returnStmt.withExpression( SyntaxFactory.makeStringLiteralExpr("Hello")) return "Hello" return 3

Slide 35

Slide 35 text

4ZOUBY#VJMEFST let structKeyword = SyntaxFactory.makeStructKeyword( trailingTrivia: .spaces(1)) struct Cat {}

Slide 36

Slide 36 text

4ZOUBY#VJMEFST let structKeyword = SyntaxFactory.makeStructKeyword( trailingTrivia: .spaces(1)) let catID = SyntaxFactory.makeIdentifier("Cat", trailingTrivia: .spaces(1)) struct Cat {}

Slide 37

Slide 37 text

4ZOUBY#VJMEFST let structKeyword = SyntaxFactory.makeStructKeyword( trailingTrivia: .spaces(1)) let catID = SyntaxFactory.makeIdentifier("Cat", trailingTrivia: .spaces(1)) let struct = StructDeclSyntax { builder in builder.useStructKeyword(structKeyword) builder.useName(catID) builder.useLeftBrace(SyntaxFactory.makeLeftBraceToken()) builder.useRightBrace(SyntaxFactory.makeRightBraceToken()) } struct Cat {}

Slide 38

Slide 38 text

(VJEJOH1SJODJQMFTPGMJC4ZOUBY"1*%FTJHO ↟ 6TFSTTIPVMEOUIBWFUPCF4XJGUFYQFSUT ↟ "1*TXJMMBMXBZTHFOFSBUFTUSVDUVSBMMZWBMJEDPEF ↟ /PUBMXBZTTZOUBDUJDBMMZWBMJE ↟ &WFSZ"1*JTTJNJMBSMZOBNFEBOEFBTZUPEJTDPWFS ↟ "VUPDPNQMFUFGSJFOEMZ ↟ 4UBSUUZQJOHSyntaxFactory.makeUPTFFBMMUIF"1*T Always Know What to Do

Slide 39

Slide 39 text

%FNP Building a Swift formatter in Swift

Slide 40

Slide 40 text

5IFSFT4UJMM8PSLUPCF%POF ↟ MJC4ZOUBYJTTUJMMIFBWJMZJOEFWFMPQNFOU ↟ 7FSZCBSFCPOFTnMJUUMFTUSVDUVSFBWBJMBCMF ↟ .PTUMZUPLFOT ↟ -PUTPGUnknownSyntaxOPEFT ↟ /FFETVQEBUFTUPUIF4XJGUQBSTFSUPXPSLGVMMZ

Slide 41

Slide 41 text

.PSF*OGPSNBUJPO MJC4ZOUBY%PDVNFOUBUJPO CJUMZMJCTZOUBY IUUQTHJUIVCDPNBQQMFTXJGU 4XJGU(JU)VC3FQPTJUPSZ

Slide 42

Slide 42 text

5IBOL:PV