comparison src/vulkan_api/vulkan_api_generator.nim @ 80:637da715b604

add: fix name clashes
author Sam <sam@basx.dev>
date Wed, 22 Feb 2023 18:22:20 +0700
parents 031f241de6ca
children fa1b6107deae
comparison
equal deleted inserted replaced
79:031f241de6ca 80:637da715b604
77 func tableSorted(table: Table[int, string]): seq[(int, string)] = 77 func tableSorted(table: Table[int, string]): seq[(int, string)] =
78 result = toSeq(table.pairs) 78 result = toSeq(table.pairs)
79 result.sort((a, b) => cmp(a[0], b[0])) 79 result.sort((a, b) => cmp(a[0], b[0]))
80 80
81 # serializers 81 # serializers
82 func serializeEnum(node: XmlNode, root: XmlNode): seq[string] = 82 func serializeEnum(node: XmlNode, api: XmlNode): seq[string] =
83 let name = node.attr("name") 83 let name = node.attr("name")
84 if name == "": 84 if name == "":
85 return result 85 return result
86 86
87 var reservedNames: seq[string]
88 for t in api.findAll("type"):
89 reservedNames.add t.attr("name").replace("_", "").toLower()
90
87 # find additional enum defintion in feature definitions 91 # find additional enum defintion in feature definitions
88 var values: Table[int, string] 92 var values: Table[int, string]
89 for feature in root.findAll("feature"): 93 for feature in api.findAll("feature"):
90 for require in feature.findAll("require"): 94 for require in feature.findAll("require"):
91 for theenum in require.findAll("enum"): 95 for theenum in require.findAll("enum"):
92 if theenum.attr("extends") == name: 96 if theenum.attr("extends") == name:
93 if theenum.hasAttr("offset"): 97 if theenum.hasAttr("offset"):
94 let enumBase = 1000000000 + (smartParseInt(theenum.attr("extnumber")) - 1) * 1000 98 let enumBase = 1000000000 + (smartParseInt(theenum.attr("extnumber")) - 1) * 1000
109 elif theenum.hasAttr("alias"): 113 elif theenum.hasAttr("alias"):
110 discard 114 discard
111 else: 115 else:
112 raise newException(Exception, &"Unknown extension value: {feature}\nvalue:{theenum}") 116 raise newException(Exception, &"Unknown extension value: {feature}\nvalue:{theenum}")
113 # find additional enum defintion in extension definitions 117 # find additional enum defintion in extension definitions
114 for extension in root.findAll("extension"): 118 for extension in api.findAll("extension"):
115 let extensionNumber = parseInt(extension.attr("number")) 119 let extensionNumber = parseInt(extension.attr("number"))
116 let enumBase = 1000000000 + (extensionNumber - 1) * 1000 120 let enumBase = 1000000000 + (extensionNumber - 1) * 1000
117 for require in extension.findAll("require"): 121 for require in extension.findAll("require"):
118 for theenum in require.findAll("enum"): 122 for theenum in require.findAll("enum"):
119 if theenum.attr("extends") == name: 123 if theenum.attr("extends") == name:
154 else: 158 else:
155 values[smartParseInt(value.attr("value"))] = value.attr("name") 159 values[smartParseInt(value.attr("value"))] = value.attr("name")
156 if values.len > 0: 160 if values.len > 0:
157 result.add " " & name & "* {.size: sizeof(cint).} = enum" 161 result.add " " & name & "* {.size: sizeof(cint).} = enum"
158 for (value, name) in tableSorted(values): 162 for (value, name) in tableSorted(values):
159 let enumEntry = &" {name} = {value}" 163 var thename = name
164 if name.replace("_", "").toLower() in reservedNames:
165 thename = thename & "_ENUM"
166 let enumEntry = &" {thename} = {value}"
160 result.add enumEntry 167 result.add enumEntry
161 168
162 # generate bitsets (normal enums in the C API, but bitfield-enums in Nim) 169 # generate bitsets (normal enums in the C API, but bitfield-enums in Nim)
163 elif node.attr("type") == "bitmask": 170 elif node.attr("type") == "bitmask":
164 for value in node.findAll("enum"): 171 for value in node.findAll("enum"):
191 result.add &"""converter BitsetToNumber*(flags: openArray[{name}]): {cApiName} = 198 result.add &"""converter BitsetToNumber*(flags: openArray[{name}]): {cApiName} =
192 for flag in flags: 199 for flag in flags:
193 result = {cApiName}(uint(result) or uint(flag))""" 200 result = {cApiName}(uint(result) or uint(flag))"""
194 result.add "type" 201 result.add "type"
195 202
196 func serializeStruct(node: XmlNode, root: XmlNode): seq[string] = 203 func serializeStruct(node: XmlNode): seq[string] =
197 let name = node.attr("name") 204 let name = node.attr("name")
198 var union = "" 205 var union = ""
199 if node.attr("category") == "union": 206 if node.attr("category") == "union":
200 union = "{.union.} " 207 union = "{.union.} "
201 result.add &" {name}* {union}= object" 208 result.add &" {name}* {union}= object"
340 " let vulkanLib* = loadLib(\"libvulkan.so.1\")", 347 " let vulkanLib* = loadLib(\"libvulkan.so.1\")",
341 "when defined(windows):", 348 "when defined(windows):",
342 " let vulkanLib* = loadLib(\"vulkan-1.dll\")", 349 " let vulkanLib* = loadLib(\"vulkan-1.dll\")",
343 "if vulkanLib == nil:", 350 "if vulkanLib == nil:",
344 " raise newException(Exception, \"Unable to load vulkan library\")", 351 " raise newException(Exception, \"Unable to load vulkan library\")",
352 "func VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} =",
353 " (variant shl 29) or (major shl 22) or (minor shl 12) or patch",
354 "",
345 "type", 355 "type",
346 ], 356 ],
347 "structs": @["type"], 357 "structs": @["type"],
348 "enums": @["type"], 358 "enums": @["type"],
349 "commands": @[], 359 "commands": @[],
364 var outfile = "structs" 374 var outfile = "structs"
365 if thetype.attr("name") in platformTypes: 375 if thetype.attr("name") in platformTypes:
366 outfile = "platform/" & platformTypes[thetype.attr("name")] 376 outfile = "platform/" & platformTypes[thetype.attr("name")]
367 if not (outfile in outputFiles): 377 if not (outfile in outputFiles):
368 outputFiles[outfile] = @[] 378 outputFiles[outfile] = @[]
369 outputFiles[outfile].add serializeStruct(thetype, api) 379 outputFiles[outfile].add serializeStruct(thetype)
370 380
371 # types 381 # types
372 var headerTypes: Table[string, string] 382 var headerTypes: Table[string, string]
373 for types in api.findAll("types"): 383 for types in api.findAll("types"):
374 for thetype in types.findAll("type"): 384 for thetype in types.findAll("type"):
411 featureloads.add &"load{name}" 421 featureloads.add &"load{name}"
412 outputFiles["commands"].add &"proc load{name}*() =" 422 outputFiles["commands"].add &"proc load{name}*() ="
413 for command in feature.findAll("command"): 423 for command in feature.findAll("command"):
414 outputFiles["commands"].add procLoads[command.attr("name")] 424 outputFiles["commands"].add procLoads[command.attr("name")]
415 outputFiles["commands"].add "" 425 outputFiles["commands"].add ""
416 outputFiles["commands"].add ["proc loadAll*() ="] 426 outputFiles["commands"].add ["proc initVulkan*() ="]
417 for l in featureloads: 427 for l in featureloads:
418 outputFiles["commands"].add [&" {l}()"] 428 outputFiles["commands"].add [&" {l}()"]
419 outputFiles["commands"].add "" 429 outputFiles["commands"].add ""
420 430
421 # for promoted extensions, dependants need to call the load-function of the promoted feature/extension 431 # for promoted extensions, dependants need to call the load-function of the promoted feature/extension
490 outputFiles[file].add "" 500 outputFiles[file].add ""
491 501
492 var mainout: seq[string] 502 var mainout: seq[string]
493 for section in ["basetypes", "enums", "structs", "commands"]: 503 for section in ["basetypes", "enums", "structs", "commands"]:
494 mainout.add outputFiles[section] 504 mainout.add outputFiles[section]
505 for platform in api.findAll("platform"):
506 mainout.add &"when defined({platform.attr(\"protect\")}):"
507 mainout.add &" include platform/{platform.attr(\"name\")}"
495 writeFile outdir / &"types.nim", mainout.join("\n") 508 writeFile outdir / &"types.nim", mainout.join("\n")
496 509
497 for filename, filecontent in outputFiles.pairs: 510 for filename, filecontent in outputFiles.pairs:
498 if filename.startsWith("platform/"): 511 if filename.startsWith("platform/"):
499 writeFile outdir / &"{filename}.nim", (@[ 512 writeFile outdir / &"{filename}.nim", (@[
500 "import std/dynlib",
501 "import ../types",
502 "type" 513 "type"
503 ] & filecontent).join("\n") 514 ] & filecontent).join("\n")
504 515
505 when isMainModule: 516 when isMainModule:
506 main() 517 main()