@@ -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,19 @@ extension UnsafePointer {
20
28
struct ASTGenVisitor : SyntaxTransformVisitor {
21
29
let ctx : UnsafeMutableRawPointer
22
30
let base : UnsafePointer < CChar >
23
-
31
+
32
+ // TOOD: we need to be up updating this.
33
+ var declContext : UnsafeMutableRawPointer
34
+
24
35
public func visit( _ node: FunctionCallExprSyntax ) -> [ UnsafeMutableRawPointer ] {
25
- let args = visit ( node. argumentList) . first!
36
+ let args = visit ( node. argumentList) . only
26
37
// TODO: hack
27
- let callee = visit ( node. calledExpression. as ( IdentifierExprSyntax . self ) ! ) . first!
38
+ let callee = visit ( node. calledExpression) . only
28
39
let call = SwiftFunctionCallExpr_create ( self . ctx, callee, args)
29
40
30
41
return [ call]
31
42
}
32
-
43
+
33
44
public func visit( _ node: IdentifierExprSyntax ) -> [ UnsafeMutableRawPointer ] {
34
45
let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
35
46
@@ -40,9 +51,31 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
40
51
41
52
return [ SwiftIdentifierExpr_create ( ctx, id, loc) ]
42
53
}
43
-
54
+
55
+ public func visit( _ node: SimpleTypeIdentifierSyntax ) -> [ UnsafeMutableRawPointer ] {
56
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
57
+
58
+ var text = node. name. text
59
+ let id = text. withUTF8 { buf in
60
+ return SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
61
+ }
62
+
63
+ return [ SimpleIdentTypeRepr_create ( ctx, loc, id) ]
64
+ }
65
+
66
+ public func visit( _ node: IdentifierPatternSyntax ) -> [ UnsafeMutableRawPointer ] {
67
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
68
+
69
+ var text = node. identifier. text
70
+ let id = text. withUTF8 { buf in
71
+ return SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
72
+ }
73
+
74
+ return [ SwiftIdentifierExpr_create ( ctx, id, loc) ]
75
+ }
76
+
44
77
public func visit( _ node: TupleExprElementListSyntax ) -> [ UnsafeMutableRawPointer ] {
45
- let elements = node. map { visit ( $0) . first! }
78
+ let elements = node. map { visit ( $0) . only }
46
79
47
80
// TODO: find correct paren locs.
48
81
let lParenLoc = self . base. advanced ( by: node. position. utf8Offset) . raw
@@ -52,22 +85,135 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
52
85
SwiftTupleExpr_create ( self . ctx, lParenLoc, elementsRef, rParenLoc)
53
86
} ]
54
87
}
88
+
89
+ public func visit( _ node: PatternBindingSyntax ) -> [ UnsafeMutableRawPointer ] {
90
+ let pattern = visit ( node. pattern)
91
+ let initializer = visit ( node. initializer!)
92
+
93
+ return [ pattern. only, initializer. only]
94
+ }
95
+
96
+ public func visit( _ node: VariableDeclSyntax ) -> [ UnsafeMutableRawPointer ] {
97
+ let components = visit ( node. bindings)
98
+ assert ( components. count == 2 )
99
+ let pattern = components. first!
100
+ let initializer = components. last!
55
101
102
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
103
+ let isStateic = false // TODO: compute this
104
+ let isLet = node. letOrVarKeyword. tokenKind == . letKeyword
105
+
106
+ // TODO: don't drop "initializer" on the floor.
107
+ return [ SwiftVarDecl_create ( ctx, pattern, loc, isStateic, isLet, declContext) ]
108
+ }
109
+
110
+ public func visit( _ node: CodeBlockSyntax ) -> [ UnsafeMutableRawPointer ] {
111
+ let statements = visit ( node. statements)
112
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
113
+
114
+ return [ statements. withBridgedArrayRef { ref in
115
+ BraceStmt_create ( ctx, loc, ref, loc)
116
+ } ]
117
+ }
118
+
119
+ public func visit( _ node: FunctionParameterSyntax ) -> [ UnsafeMutableRawPointer ] {
120
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
121
+
122
+ let firstName : UnsafeMutableRawPointer ?
123
+ let secondName : UnsafeMutableRawPointer ?
124
+
125
+ if let nodeFirstName = node. firstName {
126
+ var text = nodeFirstName. text
127
+ firstName = text. withUTF8 { buf in
128
+ SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count) . raw
129
+ }
130
+ } else {
131
+ firstName = nil
132
+ }
133
+
134
+ if let nodeSecondName = node. secondName {
135
+ var text = nodeSecondName. text
136
+ secondName = text. withUTF8 { buf in
137
+ SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count) . raw
138
+ }
139
+ } else {
140
+ secondName = nil
141
+ }
142
+
143
+ return [ ParamDecl_create ( ctx, loc, loc, firstName, loc, secondName, declContext) ]
144
+ }
145
+
146
+ public func visit( _ node: FunctionDeclSyntax ) -> [ UnsafeMutableRawPointer ] {
147
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
148
+
149
+ var nameText = node. identifier. text
150
+ let name = nameText. withUTF8 { buf in
151
+ return SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
152
+ }
153
+
154
+ let body : UnsafeMutableRawPointer ?
155
+ if let nodeBody = node. body {
156
+ body = visit ( nodeBody) . only
157
+ } else {
158
+ body = nil
159
+ }
160
+
161
+ let returnType : UnsafeMutableRawPointer ?
162
+ if let output = node. signature. output {
163
+ returnType = visit ( output. returnType) . only
164
+ } else {
165
+ returnType = nil
166
+ }
167
+
168
+ let params = node. signature. input. parameterList. map { visit ( $0) . only }
169
+ return [ params. withBridgedArrayRef { ref in
170
+ FuncDecl_create ( ctx, loc, false , loc, name, loc, false , nil , false , nil , loc, ref, loc, body, returnType, declContext)
171
+ } ]
172
+ }
173
+
174
+ public func visit( _ node: IfStmtSyntax ) -> [ UnsafeMutableRawPointer ] {
175
+ let conditions = node. conditions. map { self . visit ( $0) . only }
176
+ assert ( conditions. count == 1 ) // TODO: handle multiple conditions.
177
+
178
+ let body = visit ( node. body) . only
179
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
180
+
181
+ if let elseBody = node. elseBody, node. elseKeyword != nil {
182
+ let elseStmt = visit ( elseBody. data) . only // TODO: don't use SyntaxData
183
+ return [ IfStmt_create ( ctx, loc, conditions. only, body, loc,
184
+ elseStmt) ]
185
+ }
186
+
187
+ return [ IfStmt_create ( ctx, loc, conditions. only, body, nil , nil ) ]
188
+ }
189
+
56
190
public func visit( _ node: StringLiteralExprSyntax ) -> [ UnsafeMutableRawPointer ] {
57
191
let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
58
- var segment = node. segments. first! . as ( StringSegmentSyntax . self) !. content. text
192
+ var segment = node. segments. only . as ( StringSegmentSyntax . self) !. content. text
59
193
return segment. withUTF8 { buf in
60
194
let id = SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
61
195
return [ SwiftStringLiteralExpr_create ( ctx, id, buf. count, loc) ]
62
196
}
63
197
}
198
+
199
+ public func visit( _ node: IntegerLiteralExprSyntax ) -> [ UnsafeMutableRawPointer ] {
200
+ let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
201
+ var segment = node. digits. text
202
+ return segment. withUTF8 { buf in
203
+ let id = SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
204
+ return [ SwiftIntegerLiteralExpr_create ( ctx, id, buf. count, loc) ]
205
+ }
206
+ }
64
207
}
65
208
66
209
@_cdecl ( " parseTopLevelSwift " )
67
210
public func parseTopLevelSwift(
68
- buffer: UnsafePointer < CChar > , ctx: UnsafeMutableRawPointer
211
+ buffer: UnsafePointer < CChar > , declContext: UnsafeMutableRawPointer ,
212
+ ctx: UnsafeMutableRawPointer
69
213
) -> 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!
214
+ let syntax = try ! Parser . parse ( source: String ( cString: buffer) )
215
+ // dump(syntax)
216
+ let count = ASTGenVisitor ( ctx: ctx, base: buffer, declContext: declContext)
217
+ . visit ( syntax)
218
+ return count. first!
73
219
}
0 commit comments