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