SlideShare a Scribd company logo
1 of 85
Download to read offline
Integrating libSyntax into
the compiler pipeline
1 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Hi, I'm Yusuke
@kitasuke
2 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Swift Compiler
3 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
4 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Overview of Parser
5 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
6 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
TokenKind
SYNTAX_TOKENS = [
# Keywords that start decls
DeclKeyword('Associatedtype', 'associatedtype', serialization_code=1),
DeclKeyword('Class', 'class', serialization_code=2),
DeclKeyword('Deinit', 'deinit', serialization_code=3),
DeclKeyword('Enum', 'enum', serialization_code=4),
DeclKeyword('Extension', 'extension', serialization_code=5),
DeclKeyword('Func', 'func', serialization_code=6),
...
]
7 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
8 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Syntax tree
9 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
SyntaxKind
enum class SyntaxKind {
TypealiasDecl,
AssociatedtypeDecl,
ClassDecl,
StructDecl,
ProtocolDecl,
FunctionDecl,
...
};
10 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
11 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
AST
12 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
AST base objects
/// Stmt - Base class for all statements in swift.
class alignas(8) Stmt {...}
/// Decl - Base class for all declarations in Swift.
class alignas(1 << DeclAlignInBits) Decl {...}
/// Expr - Base class for all expressions in swift.
class alignas(8) Expr {...}
/// Pattern - Base class for all patterns in Swift.
class alignas(8) Pattern {...}
13 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
AST objects
/// Integer literal with a '+' or '-' sign, like '+4' or '- 2'.
///
/// After semantic analysis assigns types, this is guaranteed to have
/// a BuiltinIntegerType or be a normal type and implicitly be
/// AnyBuiltinIntegerType.
class IntegerLiteralExpr : public NumberLiteralExpr {
public:
/// Returns the value of the literal, appropriately constructed in the
/// target type.
APInt getValue() const;
/// Returns the raw value of the literal without any truncation.
APInt getRawValue() const;
...
};
14 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Integrating libSyntax into
the compiler pipeline
15 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
16 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Goal
To have the Swift parser fully embrace libSyntax and
stop emitting the semantic AST
17 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Problem
Semantic AST is completely ignored and wasted
when SwiftSyntax invokes the Swift parser to get the
libSyntax tree
18 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Existing pipeline
19 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Existing pipeline + SwiftSyntax
20 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
How's Swift parsed in
existing pipeline?
21 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseTopLevel
// ParseDecl.cpp
bool Parser::parseTopLevel() {
parseBraceItems(Items,
allowTopLevelCode() ? BraceItemListKind::TopLevelCode
: BraceItemListKind::TopLevelLibrary);
....
}
22 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseBraceItems
// ParseStmt.cpp
ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
BraceItemListKind Kind,
BraceItemListKind ConditionalBlockKind) {
ASTNode Result;
ParserStatus Status = parseExprOrStmt(Result);
...
}
23 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExpr
// ParseStmt.cpp
ParserStatus Parser::parseExprOrStmt(ASTNode &Result) {
ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr);
...
}
24 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExpr
// ParseStmt.cpp
ParserStatus Parser::parseExprOrStmt(ASTNode &Result) {
ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr);
...
}
// ParseExpr.cpp
ParserResult<Expr> parseExpr(Diag<> ID) {
return parseExprImpl(ID, /*isExprBasic=*/false);
}
25 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExpr
// ParseStmt.cpp
ParserStatus Parser::parseExprOrStmt(ASTNode &Result) {
ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr);
...
}
// ParseExpr.cpp
ParserResult<Expr> parseExpr(Diag<> ID) {
return parseExprImpl(ID, /*isExprBasic=*/false);
}
ParserResult<Expr> Parser::parseExprImpl(Diag<> Message,
bool isExprBasic) {
auto expr = parseExprSequence(Message, isExprBasic,
/*forConditionalDirective*/false);
...
}
26 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprSequence
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
bool isExprBasic,
bool isForConditionalDirective) {
// Parse a unary expression.
ParserResult<Expr> Primary =
parseExprSequenceElement(Message, isExprBasic);
...
}
27 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprSequence
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
bool isExprBasic,
bool isForConditionalDirective) {
// Parse a unary expression.
ParserResult<Expr> Primary =
parseExprSequenceElement(Message, isExprBasic);
...
}
ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
bool isExprBasic) {
return parseExprUnary(message, isExprBasic);
}
28 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprElement
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) {
return parseExprPostfix(Message, isExprBasic);
}
29 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprElement
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) {
return parseExprPostfix(Message, isExprBasic);
}
ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
return parseExprPrimary(ID, isExprBasic);
}
30 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseIntegerLiteralExpr
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
// Syntax
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
switch (Tok.getKind()) {
case tok::integer_literal: {
StringRef Text = copyAndStripUnderscores(Tok.getText());
SourceLoc Loc = consumeToken(tok::integer_literal);
// Syntax
ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr);
// AST object
return makeParserResult(new (Context)
IntegerLiteralExpr(Text, Loc,
/*Implicit=*/false));
}
}
}
31 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseIntegerLiteralExpr
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
// Syntax
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
switch (Tok.getKind()) {
case tok::integer_literal: {
StringRef Text = copyAndStripUnderscores(Tok.getText());
SourceLoc Loc = consumeToken(tok::integer_literal);
// Syntax
ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr);
// AST object
return makeParserResult(new (Context)
IntegerLiteralExpr(Text, Loc,
/*Implicit=*/false));
}
}
}
32 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseIntegerLiteralExpr
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
// Syntax
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
switch (Tok.getKind()) {
case tok::integer_literal: {
StringRef Text = copyAndStripUnderscores(Tok.getText());
SourceLoc Loc = consumeToken(tok::integer_literal);
// Syntax
ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr);
// AST object
return makeParserResult(new (Context)
IntegerLiteralExpr(Text, Loc,
/*Implicit=*/false));
}
}
}
33 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseIntegerLiteralExpr
// ParseExpr.cpp
ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
// Syntax
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
switch (Tok.getKind()) {
case tok::integer_literal: {
StringRef Text = copyAndStripUnderscores(Tok.getText());
SourceLoc Loc = consumeToken(tok::integer_literal);
// Syntax
ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr);
// AST object
return makeParserResult(new (Context)
IntegerLiteralExpr(Text, Loc,
/*Implicit=*/false));
}
}
}
34 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseBraceItems
// ParseStmt.cpp
ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
BraceItemListKind Kind,
BraceItemListKind ConditionalBlockKind) {
SyntaxParsingContext ItemListContext(SyntaxContext,
SyntaxKind::CodeBlockItemList);
auto *TLCD = new (Context) TopLevelCodeDecl(CurDeclContext);
ASTNode Result;
ParserStatus Status = parseExprOrStmt(Result);
auto Brace = BraceStmt::create(Context, Result.getStartLoc(),
Result, Result.getEndLoc());
TLCD->setBody(Brace);
Entries.push_back(TLCD);
return Status;
}
35 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseBraceItems
// ParseStmt.cpp
ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
BraceItemListKind Kind,
BraceItemListKind ConditionalBlockKind) {
SyntaxParsingContext ItemListContext(SyntaxContext,
SyntaxKind::CodeBlockItemList);
auto *TLCD = new (Context) TopLevelCodeDecl(CurDeclContext);
ASTNode Result;
ParserStatus Status = parseExprOrStmt(Result);
auto Brace = BraceStmt::create(Context, Result.getStartLoc(),
Result, Result.getEndLoc());
TLCD->setBody(Brace);
Entries.push_back(TLCD);
return Status;
}
36 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseTopLevel
// ParseDecl.cpp
bool Parser::parseTopLevel() {
SF.ASTStage = SourceFile::Parsing;
parseBraceItems(Items,
allowTopLevelCode() ? BraceItemListKind::TopLevelCode
: BraceItemListKind::TopLevelLibrary);
// Add newly parsed decls to the module.
SmallVector<ASTNode, 128> Items;
for (auto Item : Items)
if (auto *D = Item.dyn_cast<Decl*>())
SF.Decls.push_back(D);
// Note that the source file is fully parsed and verify it.
SF.ASTStage = SourceFile::Parsed;
verify(SF);
// If we are done parsing the whole file, finalize the token receiver.
if (Tok.is(tok::eof)) {
SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
TokReceiver->finalize();
}
}
37 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseTopLevel
// ParseDecl.cpp
bool Parser::parseTopLevel() {
SF.ASTStage = SourceFile::Parsing;
parseBraceItems(Items,
allowTopLevelCode() ? BraceItemListKind::TopLevelCode
: BraceItemListKind::TopLevelLibrary);
// Add newly parsed decls to the module.
SmallVector<ASTNode, 128> Items;
for (auto Item : Items)
if (auto *D = Item.dyn_cast<Decl*>())
SF.Decls.push_back(D);
// Note that the source file is fully parsed and verify it.
SF.ASTStage = SourceFile::Parsed;
verify(SF);
// If we are done parsing the whole file, finalize the token receiver.
if (Tok.is(tok::eof)) {
SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
TokReceiver->finalize();
}
}
38 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseTopLevel
// ParseDecl.cpp
bool Parser::parseTopLevel() {
SF.ASTStage = SourceFile::Parsing;
parseBraceItems(Items,
allowTopLevelCode() ? BraceItemListKind::TopLevelCode
: BraceItemListKind::TopLevelLibrary);
// Add newly parsed decls to the module.
SmallVector<ASTNode, 128> Items;
for (auto Item : Items)
if (auto *D = Item.dyn_cast<Decl*>())
SF.Decls.push_back(D);
// Note that the source file is fully parsed and verify it.
SF.ASTStage = SourceFile::Parsed;
verify(SF);
// If we are done parsing the whole file, finalize the token receiver.
if (Tok.is(tok::eof)) {
SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
TokReceiver->finalize();
}
}
39 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseTopLevel
// ParseDecl.cpp
bool Parser::parseTopLevel() {
SF.ASTStage = SourceFile::Parsing;
parseBraceItems(Items,
allowTopLevelCode() ? BraceItemListKind::TopLevelCode
: BraceItemListKind::TopLevelLibrary);
// Add newly parsed decls to the module.
SmallVector<ASTNode, 128> Items;
for (auto Item : Items)
if (auto *D = Item.dyn_cast<Decl*>())
SF.Decls.push_back(D);
// Note that the source file is fully parsed and verify it.
SF.ASTStage = SourceFile::Parsed;
verify(SF);
// If we are done parsing the whole file, finalize the token receiver.
if (Tok.is(tok::eof)) {
SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia);
TokReceiver->finalize();
}
}
40 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Syntax tree creation &
AST generation
41 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprParen
ParserResult<Expr> Parser::parseExprParen() {
SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext);
// In consumeToken(), a RawTokenSyntax is added to the context.
consumeToken(tok::l_paren)
// On returning from parseExpr(), a Expr Syntax node is created and added to the context.
ParserResult<Expr> Result = parseExpr();
consumeToken(tok::r_paren)
// Now the context holds { '(' Expr ')' }.
// From these parts, it creates ParenExpr node and add it to the parent.
return makeParserResult(new (Context) ParenExpr(Result.get()));
}
42 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Syntax tree
ParserResult<Expr> Parser::parseExprParen() {
SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext);
// In consumeToken(), a RawTokenSyntax is added to the context.
consumeToken(tok::l_paren)
// On returning from parseExpr(), a Expr Syntax node is created and added to the context.
ParserResult<Expr> Result = parseExpr();
consumeToken(tok::r_paren)
// Now the context holds { '(' Expr ')' }.
// From these parts, it creates ParenExpr node and add it to the parent.
return makeParserResult(new (Context) ParenExpr(Result.get()));
}
43 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
AST
ParserResult<Expr> Parser::parseExprParen() {
SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext);
// In consumeToken(), a RawTokenSyntax is added to the context.
consumeToken(tok::l_paren)
// On returning from parseExpr(), a Expr Syntax node is created and added to the context.
ParserResult<Expr> Result = parseExpr();
consumeToken(tok::r_paren)
// Now the context holds { '(' Expr ')' }.
// From these parts, it creates ParenExpr node and add it to the parent.
return makeParserResult(new (Context) ParenExpr(Result.get()));
}
44 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
parseExprParen
ParserResult<Expr> Parser::parseExprParen() {
SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext);
// In consumeToken(), a RawTokenSyntax is added to the context.
consumeToken(tok::l_paren)
// On returning from parseExpr(), a Expr Syntax node is created and added to the context.
ParserResult<Expr> Result = parseExpr();
consumeToken(tok::r_paren)
// Now the context holds { '(' Expr ')' }.
// From these parts, it creates ParenExpr node and add it to the parent.
return makeParserResult(new (Context) ParenExpr(Result.get()));
}
45 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
How optionally creating
syntax tree?
46 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
LangOptions
/// A collection of options that affect the language dialect and
/// provide compiler debugging facilities.
class LangOptions {
/// Whether to parse syntax tree. If the syntax tree is built, the generated
/// AST may not be correct when syntax nodes are reused as part of
/// incrementals parsing.
bool BuildSyntaxTree = false;
}
47 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
SyntaxParsingContext
class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
// If false, context does nothing.
bool Enabled;
...
}
/// Add Token with Trivia to the parts.
void SyntaxParsingContext::addToken(Token &Tok,
const ParsedTrivia &LeadingTrivia,
const ParsedTrivia &TrailingTrivia) {
if (!Enabled)
return;
...
}
/// Add Syntax to the parts.
void SyntaxParsingContext::addSyntax(ParsedSyntax Node) {
if (!Enabled)
return;
...
}
48 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
SyntaxParsingContext
class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
// If false, context does nothing.
bool Enabled;
...
}
/// Add Token with Trivia to the parts.
void SyntaxParsingContext::addToken(Token &Tok,
const ParsedTrivia &LeadingTrivia,
const ParsedTrivia &TrailingTrivia) {
if (!Enabled)
return;
...
}
/// Add Syntax to the parts.
void SyntaxParsingContext::addSyntax(ParsedSyntax Node) {
if (!Enabled)
return;
...
}
49 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Existing pipeline + SwiftSyntax
50 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Recap
51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Recap
→ Syntax tree is created by SyntaxParsingContext
51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Recap
→ Syntax tree is created by SyntaxParsingContext
→ AST is generated while syntax tree is created
51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Recap
→ Syntax tree is created by SyntaxParsingContext
→ AST is generated while syntax tree is created
→ if Enabled, parser creates syntax tree AND
generates AST
51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Goal
To have the Swift parser fully embrace libSyntax and
stop emitting the semantic AST
52 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
New pipeline
53 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
How's Swift pared in new
pipeline?
54 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
55 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
ParsedSyntaxBuilders
class ParsedParenExprSyntaxBuilder {
public:
explicit ParsedParenExprSyntaxBuilder(SyntaxParsingContext &SPCtx)
: SPCtx(SPCtx) {}
ParsedParenExprSyntaxBuilder &useLeftParen(ParsedTokenSyntax LeftParen);
ParsedParenExprSyntaxBuilder &useExpression(ParsedExprSyntax Expression);
ParsedParenExprSyntaxBuilder &useRightParen(ParsedTokenSyntax RightParen);
ParsedParenExprSyntax build();
...
};
56 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() {
ParsedParenExprSyntaxBuilder builder(*SyntaxContext);
// (
auto leftParen = consumeTokenSyntax(tok::l_paren);
builder.useLeftParen(std::move(leftParen));
// Expr
auto expression = parseExpressionSyntax();
builder.useExpression(expression);
// )
auto rightParen = consumeTokenSyntax(tok::r_paren);
builder.useRightParen(std::move(rightParen));
return makeParsedResult(builder.build());
}
57 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() {
ParsedParenExprSyntaxBuilder builder(*SyntaxContext);
// (
auto leftParen = consumeTokenSyntax(tok::l_paren);
builder.useLeftParen(std::move(leftParen));
// Expr
auto expression = parseExpressionSyntax();
builder.useExpression(expression);
// )
auto rightParen = consumeTokenSyntax(tok::r_paren);
builder.useRightParen(std::move(rightParen));
return makeParsedResult(builder.build());
}
58 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
ParserResult<Expr> Parser::parseExprParen() {
auto parsed = parseExprParenSyntax();
SyntaxContext->addSyntax(parsed.get());
...
}
59 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
ASTGen
60 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
ASTGen
/// Generates AST nodes from Syntax nodes.
class Parser;
class ASTGen {
public:
Expr *generate(const syntax::ExprSyntax &Expr, const SourceLoc Loc);
Expr *generate(const syntax::ParenExprSyntax &Expr, const SourceLoc Loc);
...
}
61 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
ASTGen
ParserResult<Expr> ASTGen::parseExprParen() {
auto syntax = SyntaxContext->topNode<ParenExprSyntax>();
auto result = generate(syntax, leadingLoc);
return makeParserResult(result);
}
62 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
ASTGen
ParserResult<Expr> ASTGen::parseExprParen() {
auto syntax = SyntaxContext->topNode<ParenExprSyntax>();
auto result = generate(syntax, leadingLoc);
return makeParserResult(result);
}
63 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser + ASTGen
64 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Benefits
65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Benefits
→ Robust architecture
65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Benefits
→ Robust architecture
→ SwiftSyntax parsing performance improvements
65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Benefits
→ Robust architecture
→ SwiftSyntax parsing performance improvements
→ Enable future work for making the compiler
pipeline more suitable for interactive contexts
65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Pipeline + SwiftSyntax
66 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Current scope
Parser should be fully converted first to have layered
architecture for syntax tree and AST
67 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Current scope
68 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() {
ParsedParenExprSyntaxBuilder builder(*SyntaxContext);
// (
auto leftParen = consumeTokenSyntax(tok::l_paren);
builder.useLeftParen(std::move(leftParen));
// Expr
auto expression = parseExpressionSyntax();
builder.useExpression(expression);
// )
auto rightParen = consumeTokenSyntax(tok::r_paren);
builder.useRightParen(std::move(rightParen));
return makeParsedResult(builder.build());
}
69 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Parser
ParserResult<Expr> Parser::parseExprParen() {
auto parsed = parseExprParenSyntax();
SyntaxContext->addSyntax(parsed.get());
auto syntax = SyntaxContext->topNode<ParenExprSyntax>();
auto result = Generator.generate(syntax, leadingLoc);
return makeParserResult(result);
}
70 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
TODOs
71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
TODOs
→ Performance issue
71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
TODOs
→ Performance issue
→ Module separation
71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
TODOs
→ Performance issue
→ Module separation
→ SwiftSyntax hookup
71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
syntax-parse branch
https://github.com/apple/swift/tree/
syntax-parse
72 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Summary
73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Summary
→ libSyntax integration is still WIP
73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Summary
→ libSyntax integration is still WIP
→ Definitely better change for many reasons
73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
Summary
→ libSyntax integration is still WIP
→ Definitely better change for many reasons
→ Huge performance improvements for SwiftSyntax
73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)

More Related Content

What's hot

FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...
FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...
FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...Alexey Smirnov
 
Python coroutine
Python coroutinePython coroutine
Python coroutine경섭 심
 
Re-engineering Eclipse MDT/OCL for Xtext
Re-engineering Eclipse MDT/OCL for XtextRe-engineering Eclipse MDT/OCL for Xtext
Re-engineering Eclipse MDT/OCL for XtextEdward Willink
 
(1) cpp introducing the_cpp_programming_language
(1) cpp introducing the_cpp_programming_language(1) cpp introducing the_cpp_programming_language
(1) cpp introducing the_cpp_programming_languageNico Ludwig
 
Netty: asynchronous data transfer
Netty: asynchronous data transferNetty: asynchronous data transfer
Netty: asynchronous data transferVictor Cherkassky
 
Unit 1
Unit 1Unit 1
Unit 1siddr
 
Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475Max Kleiner
 
Virtual platform
Virtual platformVirtual platform
Virtual platformsean chen
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJavaJobaer Chowdhury
 
Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Max Kleiner
 
EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4Max Kleiner
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined FunctionsChristoph Bauer
 
Reversing the dropbox client on windows
Reversing the dropbox client on windowsReversing the dropbox client on windows
Reversing the dropbox client on windowsextremecoders
 
Linker and loader upload
Linker and loader   uploadLinker and loader   upload
Linker and loader uploadBin Yang
 
GEM - GNU C Compiler Extensions Framework
GEM - GNU C Compiler Extensions FrameworkGEM - GNU C Compiler Extensions Framework
GEM - GNU C Compiler Extensions FrameworkAlexey Smirnov
 

What's hot (20)

FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...
FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...
FORECAST: Fast Generation of Accurate Context-Aware Signatures of Control-Hij...
 
Python coroutine
Python coroutinePython coroutine
Python coroutine
 
Re-engineering Eclipse MDT/OCL for Xtext
Re-engineering Eclipse MDT/OCL for XtextRe-engineering Eclipse MDT/OCL for Xtext
Re-engineering Eclipse MDT/OCL for Xtext
 
(1) cpp introducing the_cpp_programming_language
(1) cpp introducing the_cpp_programming_language(1) cpp introducing the_cpp_programming_language
(1) cpp introducing the_cpp_programming_language
 
Netty: asynchronous data transfer
Netty: asynchronous data transferNetty: asynchronous data transfer
Netty: asynchronous data transfer
 
Unit 1
Unit 1Unit 1
Unit 1
 
Biopython
BiopythonBiopython
Biopython
 
Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475
 
Intro to Pig UDF
Intro to Pig UDFIntro to Pig UDF
Intro to Pig UDF
 
Virtual platform
Virtual platformVirtual platform
Virtual platform
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 
Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33Use of an Oscilloscope - maXbox Starter33
Use of an Oscilloscope - maXbox Starter33
 
EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined Functions
 
Calico docker+ipam
Calico docker+ipamCalico docker+ipam
Calico docker+ipam
 
Reversing the dropbox client on windows
Reversing the dropbox client on windowsReversing the dropbox client on windows
Reversing the dropbox client on windows
 
Linker and loader upload
Linker and loader   uploadLinker and loader   upload
Linker and loader upload
 
Calico and container
Calico and containerCalico and container
Calico and container
 
GEM - GNU C Compiler Extensions Framework
GEM - GNU C Compiler Extensions FrameworkGEM - GNU C Compiler Extensions Framework
GEM - GNU C Compiler Extensions Framework
 
Computer Science Assignment Help
Computer Science Assignment HelpComputer Science Assignment Help
Computer Science Assignment Help
 

Similar to Integrating libSyntax into the compiler pipeline

[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipelineYusuke Kita
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 KotlinVMware Tanzu
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxbradburgess22840
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherencearagozin
 
Introduction to Python.Net
Introduction to Python.NetIntroduction to Python.Net
Introduction to Python.NetStefan Schukat
 
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...HostedbyConfluent
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConfJaroslaw Palka
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
Python help- You will be writing an encryption program for an IT compa.pdf
Python help- You will be writing an encryption program for an IT compa.pdfPython help- You will be writing an encryption program for an IT compa.pdf
Python help- You will be writing an encryption program for an IT compa.pdfChristopherkUzHunter
 
Cambio de bases
Cambio de basesCambio de bases
Cambio de basesalcon2015
 
import java-io-IOException- import java-nio-file-Files- import java-ni.docx
import java-io-IOException- import java-nio-file-Files- import java-ni.docximport java-io-IOException- import java-nio-file-Files- import java-ni.docx
import java-io-IOException- import java-nio-file-Files- import java-ni.docxhendriciraida
 
Drilling the Async Library
Drilling the Async LibraryDrilling the Async Library
Drilling the Async LibraryKnoldus Inc.
 
The use of the code analysis library OpenC++: modifications, improvements, er...
The use of the code analysis library OpenC++: modifications, improvements, er...The use of the code analysis library OpenC++: modifications, improvements, er...
The use of the code analysis library OpenC++: modifications, improvements, er...PVS-Studio
 
Programming Languages Implementation and Design. .docx
  Programming Languages Implementation and Design. .docx  Programming Languages Implementation and Design. .docx
Programming Languages Implementation and Design. .docxaryan532920
 
Testing Kafka components with Kafka for JUnit
Testing Kafka components with Kafka for JUnitTesting Kafka components with Kafka for JUnit
Testing Kafka components with Kafka for JUnitMarkus Günther
 
Python Evolution
Python EvolutionPython Evolution
Python EvolutionQuintagroup
 
Psycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptPsycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptSurvey Department
 
Spring data ii
Spring data iiSpring data ii
Spring data ii명철 강
 

Similar to Integrating libSyntax into the compiler pipeline (20)

[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Coherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherenceCoherence SIG: Advanced usage of indexes in coherence
Coherence SIG: Advanced usage of indexes in coherence
 
Introduction to Python.Net
Introduction to Python.NetIntroduction to Python.Net
Introduction to Python.Net
 
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
Python help- You will be writing an encryption program for an IT compa.pdf
Python help- You will be writing an encryption program for an IT compa.pdfPython help- You will be writing an encryption program for an IT compa.pdf
Python help- You will be writing an encryption program for an IT compa.pdf
 
Cambio de bases
Cambio de basesCambio de bases
Cambio de bases
 
import java-io-IOException- import java-nio-file-Files- import java-ni.docx
import java-io-IOException- import java-nio-file-Files- import java-ni.docximport java-io-IOException- import java-nio-file-Files- import java-ni.docx
import java-io-IOException- import java-nio-file-Files- import java-ni.docx
 
Drilling the Async Library
Drilling the Async LibraryDrilling the Async Library
Drilling the Async Library
 
The use of the code analysis library OpenC++: modifications, improvements, er...
The use of the code analysis library OpenC++: modifications, improvements, er...The use of the code analysis library OpenC++: modifications, improvements, er...
The use of the code analysis library OpenC++: modifications, improvements, er...
 
Programming Languages Implementation and Design. .docx
  Programming Languages Implementation and Design. .docx  Programming Languages Implementation and Design. .docx
Programming Languages Implementation and Design. .docx
 
Testing Kafka components with Kafka for JUnit
Testing Kafka components with Kafka for JUnitTesting Kafka components with Kafka for JUnit
Testing Kafka components with Kafka for JUnit
 
Python Evolution
Python EvolutionPython Evolution
Python Evolution
 
Psycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptPsycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python Script
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Qt for beginners
Qt for beginnersQt for beginners
Qt for beginners
 
Spring data ii
Spring data iiSpring data ii
Spring data ii
 

More from Yusuke Kita

Making your own tool using SwiftSyntax
Making your own tool using SwiftSyntaxMaking your own tool using SwiftSyntax
Making your own tool using SwiftSyntaxYusuke Kita
 
Creating your own Bitrise step
Creating your own Bitrise stepCreating your own Bitrise step
Creating your own Bitrise stepYusuke Kita
 
Introducing swift-format
Introducing swift-formatIntroducing swift-format
Introducing swift-formatYusuke Kita
 
Unidirectional Data Flow Through SwiftUI
Unidirectional Data Flow Through SwiftUIUnidirectional Data Flow Through SwiftUI
Unidirectional Data Flow Through SwiftUIYusuke Kita
 
Open Source Swift Workshop
Open Source Swift WorkshopOpen Source Swift Workshop
Open Source Swift WorkshopYusuke Kita
 
Contributing to Swift Compiler
Contributing to Swift CompilerContributing to Swift Compiler
Contributing to Swift CompilerYusuke Kita
 
Writing a compiler in go
Writing a compiler in goWriting a compiler in go
Writing a compiler in goYusuke Kita
 
Writing an interpreter in swift
Writing an interpreter in swiftWriting an interpreter in swift
Writing an interpreter in swiftYusuke Kita
 
SIL Optimizations - AllocBoxToStack
SIL Optimizations - AllocBoxToStackSIL Optimizations - AllocBoxToStack
SIL Optimizations - AllocBoxToStackYusuke Kita
 
SIL for First Time Learners
SIL for First Time LearnersSIL for First Time Learners
SIL for First Time LearnersYusuke Kita
 
SIL for First Time Leaners LT
SIL for First Time Leaners LTSIL for First Time Leaners LT
SIL for First Time Leaners LTYusuke Kita
 
How to try! Swift
How to try! SwiftHow to try! Swift
How to try! SwiftYusuke Kita
 
SIL for the first time
SIL for the first timeSIL for the first time
SIL for the first timeYusuke Kita
 
Introducing protobuf in Swift
Introducing protobuf in SwiftIntroducing protobuf in Swift
Introducing protobuf in SwiftYusuke Kita
 
Type-safe Web APIs with Protocol Buffers in Swift at AltConf
Type-safe Web APIs with Protocol Buffers in Swift at AltConfType-safe Web APIs with Protocol Buffers in Swift at AltConf
Type-safe Web APIs with Protocol Buffers in Swift at AltConfYusuke Kita
 
Type-safe Web APIs with Protocol Buffers in Swift at iOSCon
Type-safe Web APIs with Protocol Buffers in Swift at iOSConType-safe Web APIs with Protocol Buffers in Swift at iOSCon
Type-safe Web APIs with Protocol Buffers in Swift at iOSConYusuke Kita
 
SwiftCoreとFoundationを読んでみた
SwiftCoreとFoundationを読んでみたSwiftCoreとFoundationを読んでみた
SwiftCoreとFoundationを読んでみたYusuke Kita
 
Search APIs & Universal Links
Search APIs & Universal LinksSearch APIs & Universal Links
Search APIs & Universal LinksYusuke Kita
 

More from Yusuke Kita (20)

Making your own tool using SwiftSyntax
Making your own tool using SwiftSyntaxMaking your own tool using SwiftSyntax
Making your own tool using SwiftSyntax
 
Creating your own Bitrise step
Creating your own Bitrise stepCreating your own Bitrise step
Creating your own Bitrise step
 
Introducing swift-format
Introducing swift-formatIntroducing swift-format
Introducing swift-format
 
Unidirectional Data Flow Through SwiftUI
Unidirectional Data Flow Through SwiftUIUnidirectional Data Flow Through SwiftUI
Unidirectional Data Flow Through SwiftUI
 
Open Source Swift Workshop
Open Source Swift WorkshopOpen Source Swift Workshop
Open Source Swift Workshop
 
Contributing to Swift Compiler
Contributing to Swift CompilerContributing to Swift Compiler
Contributing to Swift Compiler
 
Writing a compiler in go
Writing a compiler in goWriting a compiler in go
Writing a compiler in go
 
Writing an interpreter in swift
Writing an interpreter in swiftWriting an interpreter in swift
Writing an interpreter in swift
 
SIL Optimizations - AllocBoxToStack
SIL Optimizations - AllocBoxToStackSIL Optimizations - AllocBoxToStack
SIL Optimizations - AllocBoxToStack
 
SIL for First Time Learners
SIL for First Time LearnersSIL for First Time Learners
SIL for First Time Learners
 
var, let in SIL
var, let in SILvar, let in SIL
var, let in SIL
 
SIL for First Time Leaners LT
SIL for First Time Leaners LTSIL for First Time Leaners LT
SIL for First Time Leaners LT
 
How to try! Swift
How to try! SwiftHow to try! Swift
How to try! Swift
 
SIL for the first time
SIL for the first timeSIL for the first time
SIL for the first time
 
Introducing protobuf in Swift
Introducing protobuf in SwiftIntroducing protobuf in Swift
Introducing protobuf in Swift
 
Type-safe Web APIs with Protocol Buffers in Swift at AltConf
Type-safe Web APIs with Protocol Buffers in Swift at AltConfType-safe Web APIs with Protocol Buffers in Swift at AltConf
Type-safe Web APIs with Protocol Buffers in Swift at AltConf
 
Type-safe Web APIs with Protocol Buffers in Swift at iOSCon
Type-safe Web APIs with Protocol Buffers in Swift at iOSConType-safe Web APIs with Protocol Buffers in Swift at iOSCon
Type-safe Web APIs with Protocol Buffers in Swift at iOSCon
 
Swift core
Swift coreSwift core
Swift core
 
SwiftCoreとFoundationを読んでみた
SwiftCoreとFoundationを読んでみたSwiftCoreとFoundationを読んでみた
SwiftCoreとFoundationを読んでみた
 
Search APIs & Universal Links
Search APIs & Universal LinksSearch APIs & Universal Links
Search APIs & Universal Links
 

Recently uploaded

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 

Recently uploaded (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 

Integrating libSyntax into the compiler pipeline

  • 1. Integrating libSyntax into the compiler pipeline 1 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 2. Hi, I'm Yusuke @kitasuke 2 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 3. Swift Compiler 3 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 4. Parser 4 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 5. Overview of Parser 5 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 6. Parser 6 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 7. TokenKind SYNTAX_TOKENS = [ # Keywords that start decls DeclKeyword('Associatedtype', 'associatedtype', serialization_code=1), DeclKeyword('Class', 'class', serialization_code=2), DeclKeyword('Deinit', 'deinit', serialization_code=3), DeclKeyword('Enum', 'enum', serialization_code=4), DeclKeyword('Extension', 'extension', serialization_code=5), DeclKeyword('Func', 'func', serialization_code=6), ... ] 7 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 8. Parser 8 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 9. Syntax tree 9 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 10. SyntaxKind enum class SyntaxKind { TypealiasDecl, AssociatedtypeDecl, ClassDecl, StructDecl, ProtocolDecl, FunctionDecl, ... }; 10 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 11. Parser 11 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 12. AST 12 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 13. AST base objects /// Stmt - Base class for all statements in swift. class alignas(8) Stmt {...} /// Decl - Base class for all declarations in Swift. class alignas(1 << DeclAlignInBits) Decl {...} /// Expr - Base class for all expressions in swift. class alignas(8) Expr {...} /// Pattern - Base class for all patterns in Swift. class alignas(8) Pattern {...} 13 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 14. AST objects /// Integer literal with a '+' or '-' sign, like '+4' or '- 2'. /// /// After semantic analysis assigns types, this is guaranteed to have /// a BuiltinIntegerType or be a normal type and implicitly be /// AnyBuiltinIntegerType. class IntegerLiteralExpr : public NumberLiteralExpr { public: /// Returns the value of the literal, appropriately constructed in the /// target type. APInt getValue() const; /// Returns the raw value of the literal without any truncation. APInt getRawValue() const; ... }; 14 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 15. Integrating libSyntax into the compiler pipeline 15 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 16. 16 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 17. Goal To have the Swift parser fully embrace libSyntax and stop emitting the semantic AST 17 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 18. Problem Semantic AST is completely ignored and wasted when SwiftSyntax invokes the Swift parser to get the libSyntax tree 18 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 19. Existing pipeline 19 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 20. Existing pipeline + SwiftSyntax 20 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 21. How's Swift parsed in existing pipeline? 21 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 22. parseTopLevel // ParseDecl.cpp bool Parser::parseTopLevel() { parseBraceItems(Items, allowTopLevelCode() ? BraceItemListKind::TopLevelCode : BraceItemListKind::TopLevelLibrary); .... } 22 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 23. parseBraceItems // ParseStmt.cpp ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries, BraceItemListKind Kind, BraceItemListKind ConditionalBlockKind) { ASTNode Result; ParserStatus Status = parseExprOrStmt(Result); ... } 23 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 24. parseExpr // ParseStmt.cpp ParserStatus Parser::parseExprOrStmt(ASTNode &Result) { ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr); ... } 24 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 25. parseExpr // ParseStmt.cpp ParserStatus Parser::parseExprOrStmt(ASTNode &Result) { ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr); ... } // ParseExpr.cpp ParserResult<Expr> parseExpr(Diag<> ID) { return parseExprImpl(ID, /*isExprBasic=*/false); } 25 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 26. parseExpr // ParseStmt.cpp ParserStatus Parser::parseExprOrStmt(ASTNode &Result) { ParserResult<Expr> ResultExpr = parseExpr(diag::expected_expr); ... } // ParseExpr.cpp ParserResult<Expr> parseExpr(Diag<> ID) { return parseExprImpl(ID, /*isExprBasic=*/false); } ParserResult<Expr> Parser::parseExprImpl(Diag<> Message, bool isExprBasic) { auto expr = parseExprSequence(Message, isExprBasic, /*forConditionalDirective*/false); ... } 26 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 27. parseExprSequence // ParseExpr.cpp ParserResult<Expr> Parser::parseExprSequence(Diag<> Message, bool isExprBasic, bool isForConditionalDirective) { // Parse a unary expression. ParserResult<Expr> Primary = parseExprSequenceElement(Message, isExprBasic); ... } 27 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 28. parseExprSequence // ParseExpr.cpp ParserResult<Expr> Parser::parseExprSequence(Diag<> Message, bool isExprBasic, bool isForConditionalDirective) { // Parse a unary expression. ParserResult<Expr> Primary = parseExprSequenceElement(Message, isExprBasic); ... } ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message, bool isExprBasic) { return parseExprUnary(message, isExprBasic); } 28 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 29. parseExprElement // ParseExpr.cpp ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) { return parseExprPostfix(Message, isExprBasic); } 29 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 30. parseExprElement // ParseExpr.cpp ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) { return parseExprPostfix(Message, isExprBasic); } ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) { return parseExprPrimary(ID, isExprBasic); } 30 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 31. parseIntegerLiteralExpr // ParseExpr.cpp ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { // Syntax SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr); switch (Tok.getKind()) { case tok::integer_literal: { StringRef Text = copyAndStripUnderscores(Tok.getText()); SourceLoc Loc = consumeToken(tok::integer_literal); // Syntax ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr); // AST object return makeParserResult(new (Context) IntegerLiteralExpr(Text, Loc, /*Implicit=*/false)); } } } 31 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 32. parseIntegerLiteralExpr // ParseExpr.cpp ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { // Syntax SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr); switch (Tok.getKind()) { case tok::integer_literal: { StringRef Text = copyAndStripUnderscores(Tok.getText()); SourceLoc Loc = consumeToken(tok::integer_literal); // Syntax ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr); // AST object return makeParserResult(new (Context) IntegerLiteralExpr(Text, Loc, /*Implicit=*/false)); } } } 32 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 33. parseIntegerLiteralExpr // ParseExpr.cpp ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { // Syntax SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr); switch (Tok.getKind()) { case tok::integer_literal: { StringRef Text = copyAndStripUnderscores(Tok.getText()); SourceLoc Loc = consumeToken(tok::integer_literal); // Syntax ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr); // AST object return makeParserResult(new (Context) IntegerLiteralExpr(Text, Loc, /*Implicit=*/false)); } } } 33 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 34. parseIntegerLiteralExpr // ParseExpr.cpp ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { // Syntax SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr); switch (Tok.getKind()) { case tok::integer_literal: { StringRef Text = copyAndStripUnderscores(Tok.getText()); SourceLoc Loc = consumeToken(tok::integer_literal); // Syntax ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr); // AST object return makeParserResult(new (Context) IntegerLiteralExpr(Text, Loc, /*Implicit=*/false)); } } } 34 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 35. parseBraceItems // ParseStmt.cpp ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries, BraceItemListKind Kind, BraceItemListKind ConditionalBlockKind) { SyntaxParsingContext ItemListContext(SyntaxContext, SyntaxKind::CodeBlockItemList); auto *TLCD = new (Context) TopLevelCodeDecl(CurDeclContext); ASTNode Result; ParserStatus Status = parseExprOrStmt(Result); auto Brace = BraceStmt::create(Context, Result.getStartLoc(), Result, Result.getEndLoc()); TLCD->setBody(Brace); Entries.push_back(TLCD); return Status; } 35 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 36. parseBraceItems // ParseStmt.cpp ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries, BraceItemListKind Kind, BraceItemListKind ConditionalBlockKind) { SyntaxParsingContext ItemListContext(SyntaxContext, SyntaxKind::CodeBlockItemList); auto *TLCD = new (Context) TopLevelCodeDecl(CurDeclContext); ASTNode Result; ParserStatus Status = parseExprOrStmt(Result); auto Brace = BraceStmt::create(Context, Result.getStartLoc(), Result, Result.getEndLoc()); TLCD->setBody(Brace); Entries.push_back(TLCD); return Status; } 36 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 37. parseTopLevel // ParseDecl.cpp bool Parser::parseTopLevel() { SF.ASTStage = SourceFile::Parsing; parseBraceItems(Items, allowTopLevelCode() ? BraceItemListKind::TopLevelCode : BraceItemListKind::TopLevelLibrary); // Add newly parsed decls to the module. SmallVector<ASTNode, 128> Items; for (auto Item : Items) if (auto *D = Item.dyn_cast<Decl*>()) SF.Decls.push_back(D); // Note that the source file is fully parsed and verify it. SF.ASTStage = SourceFile::Parsed; verify(SF); // If we are done parsing the whole file, finalize the token receiver. if (Tok.is(tok::eof)) { SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia); TokReceiver->finalize(); } } 37 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 38. parseTopLevel // ParseDecl.cpp bool Parser::parseTopLevel() { SF.ASTStage = SourceFile::Parsing; parseBraceItems(Items, allowTopLevelCode() ? BraceItemListKind::TopLevelCode : BraceItemListKind::TopLevelLibrary); // Add newly parsed decls to the module. SmallVector<ASTNode, 128> Items; for (auto Item : Items) if (auto *D = Item.dyn_cast<Decl*>()) SF.Decls.push_back(D); // Note that the source file is fully parsed and verify it. SF.ASTStage = SourceFile::Parsed; verify(SF); // If we are done parsing the whole file, finalize the token receiver. if (Tok.is(tok::eof)) { SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia); TokReceiver->finalize(); } } 38 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 39. parseTopLevel // ParseDecl.cpp bool Parser::parseTopLevel() { SF.ASTStage = SourceFile::Parsing; parseBraceItems(Items, allowTopLevelCode() ? BraceItemListKind::TopLevelCode : BraceItemListKind::TopLevelLibrary); // Add newly parsed decls to the module. SmallVector<ASTNode, 128> Items; for (auto Item : Items) if (auto *D = Item.dyn_cast<Decl*>()) SF.Decls.push_back(D); // Note that the source file is fully parsed and verify it. SF.ASTStage = SourceFile::Parsed; verify(SF); // If we are done parsing the whole file, finalize the token receiver. if (Tok.is(tok::eof)) { SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia); TokReceiver->finalize(); } } 39 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 40. parseTopLevel // ParseDecl.cpp bool Parser::parseTopLevel() { SF.ASTStage = SourceFile::Parsing; parseBraceItems(Items, allowTopLevelCode() ? BraceItemListKind::TopLevelCode : BraceItemListKind::TopLevelLibrary); // Add newly parsed decls to the module. SmallVector<ASTNode, 128> Items; for (auto Item : Items) if (auto *D = Item.dyn_cast<Decl*>()) SF.Decls.push_back(D); // Note that the source file is fully parsed and verify it. SF.ASTStage = SourceFile::Parsed; verify(SF); // If we are done parsing the whole file, finalize the token receiver. if (Tok.is(tok::eof)) { SyntaxContext->addToken(Tok, LeadingTrivia, TrailingTrivia); TokReceiver->finalize(); } } 40 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 41. Syntax tree creation & AST generation 41 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 42. parseExprParen ParserResult<Expr> Parser::parseExprParen() { SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext); // In consumeToken(), a RawTokenSyntax is added to the context. consumeToken(tok::l_paren) // On returning from parseExpr(), a Expr Syntax node is created and added to the context. ParserResult<Expr> Result = parseExpr(); consumeToken(tok::r_paren) // Now the context holds { '(' Expr ')' }. // From these parts, it creates ParenExpr node and add it to the parent. return makeParserResult(new (Context) ParenExpr(Result.get())); } 42 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 43. Syntax tree ParserResult<Expr> Parser::parseExprParen() { SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext); // In consumeToken(), a RawTokenSyntax is added to the context. consumeToken(tok::l_paren) // On returning from parseExpr(), a Expr Syntax node is created and added to the context. ParserResult<Expr> Result = parseExpr(); consumeToken(tok::r_paren) // Now the context holds { '(' Expr ')' }. // From these parts, it creates ParenExpr node and add it to the parent. return makeParserResult(new (Context) ParenExpr(Result.get())); } 43 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 44. AST ParserResult<Expr> Parser::parseExprParen() { SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext); // In consumeToken(), a RawTokenSyntax is added to the context. consumeToken(tok::l_paren) // On returning from parseExpr(), a Expr Syntax node is created and added to the context. ParserResult<Expr> Result = parseExpr(); consumeToken(tok::r_paren) // Now the context holds { '(' Expr ')' }. // From these parts, it creates ParenExpr node and add it to the parent. return makeParserResult(new (Context) ParenExpr(Result.get())); } 44 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 45. parseExprParen ParserResult<Expr> Parser::parseExprParen() { SyntaxParsingContext ParenCtxt(SyntaxKind::ParenExpr, SyntaxContext); // In consumeToken(), a RawTokenSyntax is added to the context. consumeToken(tok::l_paren) // On returning from parseExpr(), a Expr Syntax node is created and added to the context. ParserResult<Expr> Result = parseExpr(); consumeToken(tok::r_paren) // Now the context holds { '(' Expr ')' }. // From these parts, it creates ParenExpr node and add it to the parent. return makeParserResult(new (Context) ParenExpr(Result.get())); } 45 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 46. How optionally creating syntax tree? 46 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 47. LangOptions /// A collection of options that affect the language dialect and /// provide compiler debugging facilities. class LangOptions { /// Whether to parse syntax tree. If the syntax tree is built, the generated /// AST may not be correct when syntax nodes are reused as part of /// incrementals parsing. bool BuildSyntaxTree = false; } 47 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 48. SyntaxParsingContext class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext { // If false, context does nothing. bool Enabled; ... } /// Add Token with Trivia to the parts. void SyntaxParsingContext::addToken(Token &Tok, const ParsedTrivia &LeadingTrivia, const ParsedTrivia &TrailingTrivia) { if (!Enabled) return; ... } /// Add Syntax to the parts. void SyntaxParsingContext::addSyntax(ParsedSyntax Node) { if (!Enabled) return; ... } 48 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 49. SyntaxParsingContext class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext { // If false, context does nothing. bool Enabled; ... } /// Add Token with Trivia to the parts. void SyntaxParsingContext::addToken(Token &Tok, const ParsedTrivia &LeadingTrivia, const ParsedTrivia &TrailingTrivia) { if (!Enabled) return; ... } /// Add Syntax to the parts. void SyntaxParsingContext::addSyntax(ParsedSyntax Node) { if (!Enabled) return; ... } 49 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 50. Existing pipeline + SwiftSyntax 50 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 51. Recap 51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 52. Recap → Syntax tree is created by SyntaxParsingContext 51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 53. Recap → Syntax tree is created by SyntaxParsingContext → AST is generated while syntax tree is created 51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 54. Recap → Syntax tree is created by SyntaxParsingContext → AST is generated while syntax tree is created → if Enabled, parser creates syntax tree AND generates AST 51 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 55. Goal To have the Swift parser fully embrace libSyntax and stop emitting the semantic AST 52 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 56. New pipeline 53 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 57. How's Swift pared in new pipeline? 54 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 58. Parser 55 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 59. ParsedSyntaxBuilders class ParsedParenExprSyntaxBuilder { public: explicit ParsedParenExprSyntaxBuilder(SyntaxParsingContext &SPCtx) : SPCtx(SPCtx) {} ParsedParenExprSyntaxBuilder &useLeftParen(ParsedTokenSyntax LeftParen); ParsedParenExprSyntaxBuilder &useExpression(ParsedExprSyntax Expression); ParsedParenExprSyntaxBuilder &useRightParen(ParsedTokenSyntax RightParen); ParsedParenExprSyntax build(); ... }; 56 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 60. Parser ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() { ParsedParenExprSyntaxBuilder builder(*SyntaxContext); // ( auto leftParen = consumeTokenSyntax(tok::l_paren); builder.useLeftParen(std::move(leftParen)); // Expr auto expression = parseExpressionSyntax(); builder.useExpression(expression); // ) auto rightParen = consumeTokenSyntax(tok::r_paren); builder.useRightParen(std::move(rightParen)); return makeParsedResult(builder.build()); } 57 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 61. Parser ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() { ParsedParenExprSyntaxBuilder builder(*SyntaxContext); // ( auto leftParen = consumeTokenSyntax(tok::l_paren); builder.useLeftParen(std::move(leftParen)); // Expr auto expression = parseExpressionSyntax(); builder.useExpression(expression); // ) auto rightParen = consumeTokenSyntax(tok::r_paren); builder.useRightParen(std::move(rightParen)); return makeParsedResult(builder.build()); } 58 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 62. Parser ParserResult<Expr> Parser::parseExprParen() { auto parsed = parseExprParenSyntax(); SyntaxContext->addSyntax(parsed.get()); ... } 59 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 63. ASTGen 60 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 64. ASTGen /// Generates AST nodes from Syntax nodes. class Parser; class ASTGen { public: Expr *generate(const syntax::ExprSyntax &Expr, const SourceLoc Loc); Expr *generate(const syntax::ParenExprSyntax &Expr, const SourceLoc Loc); ... } 61 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 65. ASTGen ParserResult<Expr> ASTGen::parseExprParen() { auto syntax = SyntaxContext->topNode<ParenExprSyntax>(); auto result = generate(syntax, leadingLoc); return makeParserResult(result); } 62 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 66. ASTGen ParserResult<Expr> ASTGen::parseExprParen() { auto syntax = SyntaxContext->topNode<ParenExprSyntax>(); auto result = generate(syntax, leadingLoc); return makeParserResult(result); } 63 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 67. Parser + ASTGen 64 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 68. Benefits 65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 69. Benefits → Robust architecture 65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 70. Benefits → Robust architecture → SwiftSyntax parsing performance improvements 65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 71. Benefits → Robust architecture → SwiftSyntax parsing performance improvements → Enable future work for making the compiler pipeline more suitable for interactive contexts 65 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 72. Pipeline + SwiftSyntax 66 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 73. Current scope Parser should be fully converted first to have layered architecture for syntax tree and AST 67 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 74. Current scope 68 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 75. Parser ParsedSyntaxResult<Expr> Parser::parseExprParenSyntax() { ParsedParenExprSyntaxBuilder builder(*SyntaxContext); // ( auto leftParen = consumeTokenSyntax(tok::l_paren); builder.useLeftParen(std::move(leftParen)); // Expr auto expression = parseExpressionSyntax(); builder.useExpression(expression); // ) auto rightParen = consumeTokenSyntax(tok::r_paren); builder.useRightParen(std::move(rightParen)); return makeParsedResult(builder.build()); } 69 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 76. Parser ParserResult<Expr> Parser::parseExprParen() { auto parsed = parseExprParenSyntax(); SyntaxContext->addSyntax(parsed.get()); auto syntax = SyntaxContext->topNode<ParenExprSyntax>(); auto result = Generator.generate(syntax, leadingLoc); return makeParserResult(result); } 70 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 77. TODOs 71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 78. TODOs → Performance issue 71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 79. TODOs → Performance issue → Module separation 71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 80. TODOs → Performance issue → Module separation → SwiftSyntax hookup 71 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 81. syntax-parse branch https://github.com/apple/swift/tree/ syntax-parse 72 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 82. Summary 73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 83. Summary → libSyntax integration is still WIP 73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 84. Summary → libSyntax integration is still WIP → Definitely better change for many reasons 73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)
  • 85. Summary → libSyntax integration is still WIP → Definitely better change for many reasons → Huge performance improvements for SwiftSyntax 73 — Integrating libSyntax into the compiler pipeline, Yusuke Kita (@kitasuke)