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
|
import WIT
struct HostWorldGenerator: ASTVisitor {
let printer: SourcePrinter
let context: SemanticsContext
let world: SyntaxNode<WorldSyntax>
let sourceFile: SyntaxNode<SourceFileSyntax>
let packageUnit: PackageUnit
let signatureTranslation: SignatureTranslation
let definitionMapping: DefinitionMapping
mutating func generate() throws {
try walk(world)
}
func visit<T>(_: T) throws {}
func visitPost<T>(_: T) throws {}
func visit(_ world: SyntaxNode<WorldSyntax>) throws {
try printer.write(
line: """
struct \(ConvertCase.pascalCase(world.name)) {
let moduleInstance: ModuleInstance
static func link(_ hostModules: inout [String: HostModule]) {
}
""")
// Enter world struct body
printer.indent()
for item in world.items {
switch item {
case .export(let export):
switch export.kind {
case .function(let name, let function):
let exportFunction = HostExportFunction(
function: function, name: .world(name.text),
signatureTranslation: signatureTranslation,
definitionMapping: definitionMapping
)
try exportFunction.print(typeResolver: resolveType(_:), printer: printer)
case .path(.id(let interfaceIdent)):
let (interface, sourceFile) = try context.lookupInterface(
name: interfaceIdent.text, contextPackage: packageUnit
)
var generator = HostExportInterface(
printer: printer,
context: context,
sourceFile: sourceFile,
packageUnit: packageUnit,
interface: interface,
signatureTranslation: SignatureTranslation(interfaceContext: (interface, packageUnit)),
definitionMapping: definitionMapping
)
try generator.generate()
default: break
}
case .type(let typeDef):
try TypeDefinition(accessLevel: .internal)
.print(printer: printer, signatureTranslation: signatureTranslation, typeDef: typeDef)
case .use(let use):
try TypeDefinition(accessLevel: .public)
.printUse(printer: printer, use: use, contextPackageName: packageUnit.packageName)
default: break
}
}
// Leave world struct body
printer.unindent()
printer.write(line: "}")
}
func resolveType(_ type: TypeReprSyntax) throws -> WITType {
try context.resolveType(type, in: world, sourceFile: sourceFile, contextPackage: packageUnit)
}
}
|