Skip to content

Commit 2df25fc

Browse files
committed
Move ASTGen into Swift from swift-syntax.
1 parent 7bc67c9 commit 2df25fc

File tree

4 files changed

+285
-3
lines changed

4 files changed

+285
-3
lines changed

lib/ASTGen/ASTGen.swift

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
import SwiftParser
2+
import SwiftSyntax
3+
4+
import CASTBridging
5+
6+
extension Array {
7+
public func withBridgedArrayRef<T>(_ c: (BridgedArrayRef) -> T) -> T {
8+
withUnsafeBytes { buf in
9+
c(BridgedArrayRef(data: buf.baseAddress!, numElements: count))
10+
}
11+
}
12+
}
13+
14+
extension UnsafePointer {
15+
public var raw: UnsafeMutableRawPointer {
16+
UnsafeMutableRawPointer(mutating: self)
17+
}
18+
}
19+
20+
struct ASTGenVisitor: SyntaxTransformVisitor {
21+
let ctx: UnsafeMutableRawPointer
22+
let base: UnsafePointer<CChar>
23+
24+
// TOOD: we need to be up updating this.
25+
var declContext: UnsafeMutableRawPointer
26+
27+
// TODO: this some how messes up the witness table when I uncomment it locally :/
28+
// public func visit<T>(_ node: T?) -> [UnsafeMutableRawPointer]? {
29+
// if let node = node { return visit(node) }
30+
// return nil
31+
// }
32+
33+
@_disfavoredOverload
34+
public func visit(_ node: SourceFileSyntax) -> UnsafeMutableRawPointer {
35+
fatalError("Use other overload.")
36+
}
37+
38+
public func visitAny(_ node: Syntax) -> ResultType {
39+
fatalError("Not implemented.")
40+
}
41+
42+
public func visit(_ node: SourceFileSyntax) -> [UnsafeMutableRawPointer] {
43+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
44+
var out = [UnsafeMutableRawPointer]()
45+
46+
for element in node.statements {
47+
let swiftASTNodes = visit(element)
48+
if element.item.is(StmtSyntax.self) {
49+
out.append(SwiftTopLevelCodeDecl_createStmt(ctx, declContext, loc, swiftASTNodes, loc))
50+
} else if element.item.is(ExprSyntax.self) {
51+
out.append(SwiftTopLevelCodeDecl_createExpr(ctx, declContext, loc, swiftASTNodes, loc))
52+
} else {
53+
assert(element.item.is(DeclSyntax.self))
54+
out.append(swiftASTNodes)
55+
}
56+
}
57+
58+
return out
59+
}
60+
61+
public func visit(_ node: FunctionCallExprSyntax) -> UnsafeMutableRawPointer {
62+
let args = visit(node.argumentList)
63+
// TODO: hack
64+
let callee = visit(node.calledExpression)
65+
return SwiftFunctionCallExpr_create(self.ctx, callee, args)
66+
}
67+
68+
public func visit(_ node: IdentifierExprSyntax) -> UnsafeMutableRawPointer {
69+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
70+
71+
var text = node.identifier.text
72+
let id = text.withUTF8 { buf in
73+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
74+
}
75+
76+
return SwiftIdentifierExpr_create(ctx, id, loc)
77+
}
78+
79+
public func visit(_ node: SimpleTypeIdentifierSyntax) -> UnsafeMutableRawPointer {
80+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
81+
82+
var text = node.name.text
83+
let id = text.withUTF8 { buf in
84+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
85+
}
86+
87+
return SimpleIdentTypeRepr_create(ctx, loc, id)
88+
}
89+
90+
public func visit(_ node: IdentifierPatternSyntax) -> UnsafeMutableRawPointer {
91+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
92+
93+
var text = node.identifier.text
94+
let id = text.withUTF8 { buf in
95+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
96+
}
97+
98+
return SwiftIdentifierExpr_create(ctx, id, loc)
99+
}
100+
101+
public func visit(_ node: MemberAccessExprSyntax) -> UnsafeMutableRawPointer {
102+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
103+
let base = visit(node.base!)
104+
var nameText = node.name.text
105+
let name = nameText.withUTF8 { buf in
106+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
107+
}
108+
109+
return UnresolvedDotExpr_create(ctx, base, loc, name, loc)
110+
}
111+
112+
public func visit(_ node: TupleExprElementSyntax) -> UnsafeMutableRawPointer {
113+
visit(node.expression)
114+
}
115+
116+
public func visit(_ node: TupleExprElementListSyntax) -> UnsafeMutableRawPointer {
117+
let elements = node.map(self.visit)
118+
119+
// TODO: find correct paren locs.
120+
let lParenLoc = self.base.advanced(by: node.position.utf8Offset).raw
121+
let rParenLoc = self.base.advanced(by: node.position.utf8Offset).raw
122+
123+
return elements.withBridgedArrayRef { elementsRef in
124+
SwiftTupleExpr_create(self.ctx, lParenLoc, elementsRef, rParenLoc)
125+
}
126+
}
127+
128+
public func visit(_ node: VariableDeclSyntax) -> UnsafeMutableRawPointer {
129+
let pattern = visit(node.bindings.first!.pattern)
130+
let initializer = visit(node.bindings.first!.initializer!)
131+
132+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
133+
let isStateic = false // TODO: compute this
134+
let isLet = node.letOrVarKeyword.tokenKind == .letKeyword
135+
136+
// TODO: don't drop "initializer" on the floor.
137+
return SwiftVarDecl_create(ctx, pattern, loc, isStateic, isLet, declContext)
138+
}
139+
140+
public func visit(_ node: ConditionElementSyntax) -> UnsafeMutableRawPointer {
141+
visit(node.condition)
142+
}
143+
144+
public func visit(_ node: CodeBlockItemSyntax) -> UnsafeMutableRawPointer {
145+
visit(node.item)
146+
}
147+
148+
public func visit(_ node: CodeBlockSyntax) -> UnsafeMutableRawPointer {
149+
let statements = node.statements.map(self.visit)
150+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
151+
152+
return statements.withBridgedArrayRef { ref in
153+
BraceStmt_create(ctx, loc, ref, loc)
154+
}
155+
}
156+
157+
public func visit(_ node: FunctionParameterSyntax) -> UnsafeMutableRawPointer {
158+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
159+
160+
let firstName: UnsafeMutableRawPointer?
161+
let secondName: UnsafeMutableRawPointer?
162+
163+
if let nodeFirstName = node.firstName {
164+
var text = nodeFirstName.text
165+
firstName = text.withUTF8 { buf in
166+
SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count).raw
167+
}
168+
} else {
169+
firstName = nil
170+
}
171+
172+
if let nodeSecondName = node.secondName {
173+
var text = nodeSecondName.text
174+
secondName = text.withUTF8 { buf in
175+
SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count).raw
176+
}
177+
} else {
178+
secondName = nil
179+
}
180+
181+
return ParamDecl_create(ctx, loc, loc, firstName, loc, secondName, declContext)
182+
}
183+
184+
public func visit(_ node: FunctionDeclSyntax) -> UnsafeMutableRawPointer {
185+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
186+
187+
var nameText = node.identifier.text
188+
let name = nameText.withUTF8 { buf in
189+
return SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
190+
}
191+
192+
let body: UnsafeMutableRawPointer?
193+
if let nodeBody = node.body {
194+
body = visit(nodeBody)
195+
} else {
196+
body = nil
197+
}
198+
199+
let returnType: UnsafeMutableRawPointer?
200+
if let output = node.signature.output {
201+
returnType = visit(output.returnType)
202+
} else {
203+
returnType = nil
204+
}
205+
206+
let params = node.signature.input.parameterList.map { visit($0) }
207+
return params.withBridgedArrayRef { ref in
208+
FuncDecl_create(ctx, loc, false, loc, name, loc, false, nil, false, nil, loc, ref, loc, body, returnType, declContext)
209+
}
210+
}
211+
212+
public func visit(_ node: IfStmtSyntax) -> UnsafeMutableRawPointer {
213+
let conditions = node.conditions.map(self.visit)
214+
assert(conditions.count == 1) // TODO: handle multiple conditions.
215+
216+
let body = visit(node.body)
217+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
218+
219+
if let elseBody = node.elseBody, node.elseKeyword != nil {
220+
return IfStmt_create(ctx, loc, conditions.first!, body, loc, visit(elseBody))
221+
}
222+
223+
return IfStmt_create(ctx, loc, conditions.first!, body, nil, nil)
224+
}
225+
226+
public func visit(_ node: StringLiteralExprSyntax) -> UnsafeMutableRawPointer {
227+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
228+
var segment = node.segments.first!.as(StringSegmentSyntax.self)!.content.text
229+
return segment.withUTF8 { buf in
230+
let id = SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
231+
return SwiftStringLiteralExpr_create(ctx, id, buf.count, loc)
232+
}
233+
}
234+
235+
public func visit(_ node: IntegerLiteralExprSyntax) -> UnsafeMutableRawPointer {
236+
let loc = self.base.advanced(by: node.position.utf8Offset).raw
237+
var segment = node.digits.text
238+
return segment.withUTF8 { buf in
239+
let id = SwiftASTContext_getIdentifier(ctx, buf.baseAddress, buf.count)
240+
return SwiftIntegerLiteralExpr_create(ctx, id, buf.count, loc)
241+
}
242+
}
243+
}
244+
245+
@_cdecl("parseTopLevelSwift")
246+
public func parseTopLevelSwift(
247+
buffer: UnsafePointer<CChar>, declContext: UnsafeMutableRawPointer,
248+
ctx: UnsafeMutableRawPointer,
249+
outputContext: UnsafeMutableRawPointer,
250+
callback: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void
251+
) {
252+
let syntax = try! Parser.parse(source: String(cString: buffer))
253+
dump(syntax)
254+
ASTGenVisitor(ctx: ctx, base: buffer, declContext: declContext)
255+
.visit(syntax)
256+
.forEach { callback($0, outputContext) }
257+
}

lib/ASTGen/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
add_subdirectory(${SWIFT_SOURCE_DIR}/../swift-syntax ${CMAKE_CURRENT_BINARY_DIR}/swift-syntax)
2+
3+
add_library(ASTGen
4+
ASTGen.swift)
5+
6+
target_compile_options(ASTGen PUBLIC
7+
"-emit-module-interface")
8+
9+
target_link_libraries(ASTGen PUBLIC
10+
SwiftSyntax
11+
SwiftParser
12+
SwiftDiagnostics)
13+
14+
target_include_directories(SwiftParser PUBLIC
15+
"${CMAKE_CURRENT_BINARY_DIR}/../Parser/swift-syntax/SwiftSyntax"
16+
"${CMAKE_CURRENT_BINARY_DIR}/../Parser/swift-syntax/SwiftDiagnostics"
17+
"${CMAKE_CURRENT_BINARY_DIR}/../Parser/swift-syntax/SwiftParser")
18+
19+
set_property(GLOBAL APPEND PROPERTY SWIFTSYNTAX_EXPORTS ASTGen)
20+
21+
install(TARGETS ASTGen
22+
EXPORT SwiftSyntaxTargets
23+
ARCHIVE DESTINATION lib
24+
LIBRARY DESTINATION lib
25+
RUNTIME DESTINATION bin)
26+
27+
add_dependencies(ASTGen swiftAST)

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ list(APPEND LLVM_COMMON_DEPENDS swift-parse-syntax-generated-headers)
1717

1818
add_subdirectory(APIDigester)
1919
add_subdirectory(AST)
20+
add_subdirectory(ASTGen) # Must come before Parse
2021
add_subdirectory(ASTSectionImporter)
2122
add_subdirectory(Basic)
2223
add_subdirectory(ConstExtract)

lib/Parse/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ else()
66
set(SWIFT_GYB_FLAGS --line-directive "\'#line" "%(line)d" "\"%(file)s\"\'")
77
endif()
88

9-
add_subdirectory(${SWIFT_SOURCE_DIR}/../swift-syntax ${CMAKE_CURRENT_BINARY_DIR}/swift-syntax)
10-
add_dependencies(ASTGen swiftAST)
11-
129
add_swift_host_library(swiftParse STATIC
1310
Confusables.cpp
1411
Lexer.cpp

0 commit comments

Comments
 (0)