@@ -11,6 +11,14 @@ extension Array {
1111 }
1212}
1313
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+
1422extension UnsafePointer {
1523 public var raw : UnsafeMutableRawPointer {
1624 UnsafeMutableRawPointer ( mutating: self )
@@ -20,16 +28,19 @@ extension UnsafePointer {
2028struct ASTGenVisitor : SyntaxTransformVisitor {
2129 let ctx : UnsafeMutableRawPointer
2230 let base : UnsafePointer < CChar >
23-
31+
32+ // TOOD: we need to be up updating this.
33+ var declContext : UnsafeMutableRawPointer
34+
2435 public func visit( _ node: FunctionCallExprSyntax ) -> [ UnsafeMutableRawPointer ] {
25- let args = visit ( node. argumentList) . first!
36+ let args = visit ( node. argumentList) . only
2637 // TODO: hack
27- let callee = visit ( node. calledExpression. as ( IdentifierExprSyntax . self ) ! ) . first!
38+ let callee = visit ( node. calledExpression) . only
2839 let call = SwiftFunctionCallExpr_create ( self . ctx, callee, args)
2940
3041 return [ call]
3142 }
32-
43+
3344 public func visit( _ node: IdentifierExprSyntax ) -> [ UnsafeMutableRawPointer ] {
3445 let loc = self . base. advanced ( by: node. position. utf8Offset) . raw
3546
@@ -40,9 +51,31 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
4051
4152 return [ SwiftIdentifierExpr_create ( ctx, id, loc) ]
4253 }
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+
4477 public func visit( _ node: TupleExprElementListSyntax ) -> [ UnsafeMutableRawPointer ] {
45- let elements = node. map { visit ( $0) . first! }
78+ let elements = node. map { visit ( $0) . only }
4679
4780 // TODO: find correct paren locs.
4881 let lParenLoc = self . base. advanced ( by: node. position. utf8Offset) . raw
@@ -52,22 +85,135 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
5285 SwiftTupleExpr_create ( self . ctx, lParenLoc, elementsRef, rParenLoc)
5386 } ]
5487 }
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!
55101
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+
56190 public func visit( _ node: StringLiteralExprSyntax ) -> [ UnsafeMutableRawPointer ] {
57191 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
59193 return segment. withUTF8 { buf in
60194 let id = SwiftASTContext_getIdentifier ( ctx, buf. baseAddress, buf. count)
61195 return [ SwiftStringLiteralExpr_create ( ctx, id, buf. count, loc) ]
62196 }
63197 }
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+ }
64207}
65208
66209@_cdecl ( " parseTopLevelSwift " )
67210public func parseTopLevelSwift(
68- buffer: UnsafePointer < CChar > , ctx: UnsafeMutableRawPointer
211+ buffer: UnsafePointer < CChar > , declContext: UnsafeMutableRawPointer ,
212+ ctx: UnsafeMutableRawPointer
69213) -> 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!
73219}
0 commit comments