1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
extension WorldSyntax {
static func parse(lexer: inout Lexer, documents: DocumentsSyntax) throws -> SyntaxNode<WorldSyntax> {
try lexer.expect(.world)
let name = try Identifier.parse(lexer: &lexer)
let items = try parseItems(lexer: &lexer)
return .init(syntax: WorldSyntax(documents: documents, name: name, items: items))
}
static func parseItems(lexer: inout Lexer) throws -> [WorldItemSyntax] {
try lexer.expect(.leftBrace)
var items: [WorldItemSyntax] = []
while true {
let docs = try DocumentsSyntax.parse(lexer: &lexer)
if lexer.eat(.rightBrace) {
break
}
items.append(try WorldItemSyntax.parse(lexer: &lexer, documents: docs))
}
return items
}
}
extension WorldItemSyntax {
static func parse(lexer: inout Lexer, documents: DocumentsSyntax) throws -> WorldItemSyntax {
switch lexer.peek()?.kind {
case .import:
return try .import(.parse(lexer: &lexer, documents: documents))
case .export:
return try .export(.parse(lexer: &lexer, documents: documents))
case .use:
return try .use(UseSyntax.parse(lexer: &lexer))
case .type:
return try .type(.init(syntax: .parse(lexer: &lexer, documents: documents)))
case .flags:
return try .type(.init(syntax: .parseFlags(lexer: &lexer, documents: documents)))
case .enum:
return try .type(.init(syntax: .parseEnum(lexer: &lexer, documents: documents)))
case .variant:
return try .type(.init(syntax: .parseVariant(lexer: &lexer, documents: documents)))
case .resource:
return try .type(TypeDefSyntax.parseResource(lexer: &lexer, documents: documents))
case .record:
return try .type(.init(syntax: .parseRecord(lexer: &lexer, documents: documents)))
case .union:
return try .type(.init(syntax: .parseUnion(lexer: &lexer, documents: documents)))
case .include:
return try .include(.parse(lexer: &lexer))
default:
throw ParseError(description: "`type`, `resource` or `func` expected")
}
}
}
extension ImportSyntax {
static func parse(lexer: inout Lexer, documents: DocumentsSyntax) throws -> ImportSyntax {
try lexer.expect(.import)
let kind = try ExternKindSyntax.parse(lexer: &lexer)
return ImportSyntax(documents: documents, kind: kind)
}
}
extension ExportSyntax {
static func parse(lexer: inout Lexer, documents: DocumentsSyntax) throws -> ExportSyntax {
try lexer.expect(.export)
let kind = try ExternKindSyntax.parse(lexer: &lexer)
return ExportSyntax(documents: documents, kind: kind)
}
}
extension ExternKindSyntax {
static func parse(lexer: inout Lexer) throws -> ExternKindSyntax {
var clone = lexer
let id = try Identifier.parse(lexer: &clone)
if clone.eat(.colon) {
switch clone.peek()?.kind {
case .func:
// import foo: func(...)
lexer = clone
return try .function(id, .parse(lexer: &lexer))
case .interface:
// import foo: interface { ... }
try clone.expect(.interface)
lexer = clone
return try .interface(id, InterfaceSyntax.parseItems(lexer: &lexer))
default: break
}
}
// import foo:bar/baz
return try .path(.parse(lexer: &lexer))
}
}
extension IncludeSyntax {
static func parse(lexer: inout Lexer) throws -> IncludeSyntax {
try lexer.expect(.include)
let from = try UsePathSyntax.parse(lexer: &lexer)
var names: [IncludeNameSyntax] = []
if lexer.eat(.with) {
names = try Parser.parseList(lexer: &lexer, start: .leftBrace, end: .rightBrace) { _, lexer in
let name = try Identifier.parse(lexer: &lexer)
try lexer.expect(.as)
let asName = try Identifier.parse(lexer: &lexer)
return IncludeNameSyntax(name: name, asName: asName)
}
}
return IncludeSyntax(from: from, names: names)
}
}
|