comparison svk/generate.nim @ 1489:e6bd1f553c1b default tip main

add: quite a bit more wrapper
author sam <sam@basx.dev>
date Sun, 18 May 2025 23:47:16 +0700
parents 3ce7c132fdac
children
comparison
equal deleted inserted replaced
1488:3ce7c132fdac 1489:e6bd1f553c1b
53 53
54 EnumDef = object 54 EnumDef = object
55 name: string 55 name: string
56 values: seq[EnumEntry] 56 values: seq[EnumEntry]
57 isBitmask: bool 57 isBitmask: bool
58 nBytes: int = 4
58 59
59 ConstantDef = object 60 ConstantDef = object
60 name: string 61 name: string
61 datatype: string 62 datatype: string
62 value: string 63 value: string
201 var edef = EnumDef(name: e.attr("name"), isBitmask: false) 202 var edef = EnumDef(name: e.attr("name"), isBitmask: false)
202 for ee in e.findAll("enum"): 203 for ee in e.findAll("enum"):
203 edef.addValue(ee) 204 edef.addValue(ee)
204 enums[edef.name] = edef 205 enums[edef.name] = edef
205 elif e.attr("type") == "bitmask": 206 elif e.attr("type") == "bitmask":
206 var edef = EnumDef(name: e.attr("name"), isBitmask: true) 207 let nBytes = if e.attr("bitwidth") == "": 4 else: parseInt(e.attr("bitwidth")) div 8
208 var edef = EnumDef(name: e.attr("name"), isBitmask: true, nBytes: nBytes)
207 for ee in e.findAll("enum"): 209 for ee in e.findAll("enum"):
208 edef.addValue(ee) 210 edef.addValue(ee)
209 enums[edef.name] = edef 211 enums[edef.name] = edef
210 212
211 for f in features: 213 for f in features:
234 # generate core types =============================================================================== 236 # generate core types ===============================================================================
235 # preamble, much easier to hardcode than to generate from xml 237 # preamble, much easier to hardcode than to generate from xml
236 outFile.writeLine """ 238 outFile.writeLine """
237 239
238 import std/dynlib 240 import std/dynlib
239 import std/strutils
240 import std/tables
241 import std/macros 241 import std/macros
242 import std/typetraits 242 import std/typetraits
243 243
244 import ../semicongine/thirdparty/winim/winim/inc/winbase 244 import ../semicongine/thirdparty/winim/winim/inc/winbase
245 import ../semicongine/thirdparty/winim/winim/inc/windef 245 import ../semicongine/thirdparty/winim/winim/inc/windef
253 (variant shl 29) or (major shl 22) or (minor shl 12) or patch 253 (variant shl 29) or (major shl 22) or (minor shl 12) or patch
254 254
255 macro enumFullRange(a: typed): untyped = 255 macro enumFullRange(a: typed): untyped =
256 newNimNode(nnkBracket).add(a.getType[1][1 ..^ 1]) 256 newNimNode(nnkBracket).add(a.getType[1][1 ..^ 1])
257 257
258 func asBits[T, S](flags: openArray[T]): S =
259 for flag in flags:
260 let a = distinctBase(S)(result)
261 let b = distinctBase(S)(flag)
262 result = S(a or b)
263
264 func toEnums*[T, S](number: T): seq[S] =
265 for value in enumFullRange(S):
266 if (value.ord and cint(number)) > 0:
267 result.add value
268 """ 258 """
269 259
270 outFile.writeLine "type" 260 outFile.writeLine "type"
271 outFile.writeLine """ 261 outFile.writeLine """
272 262
350 "VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT", 340 "VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT",
351 ] 341 ]
352 342
353 for edef in enums.values(): 343 for edef in enums.values():
354 if edef.values.len > 0: 344 if edef.values.len > 0:
355 outFile.writeLine &"type {edef.name}* {{.size: 4.}} = enum" 345 outFile.writeLine &"type {edef.name}* {{.size: {edef.nBytes}.}} = enum"
356 for ee in edef.values: 346 for ee in edef.values:
357 # due to the nim identifier-system, there might be collisions between typenames and enum-member names 347 # due to the nim identifier-system, there might be collisions between typenames and enum-member names
358 if ee.name in nameCollisions: 348 if ee.name in nameCollisions:
359 outFile.writeLine &" {ee.name}_VALUE = {ee.value}" 349 outFile.writeLine &" {ee.name}_VALUE = {ee.value}"
360 else: 350 else:
430 outFile.writeLine "" 420 outFile.writeLine ""
431 421
432 for edef in enums.values(): 422 for edef in enums.values():
433 if edef.values.len > 0: 423 if edef.values.len > 0:
434 if edef.isBitmask: 424 if edef.isBitmask:
435 let bitsName = edef.name 425 let enumName = edef.name
436 let p = bitsName.rfind("FlagBits") 426 let p = enumName.rfind("FlagBits")
437 let flagsName = bitsName[0 ..< p] & "Flags" & bitsName[p + 8 .. ^1] 427 let flagSetType = enumName[0 ..< p] & "Flags" & enumName[p + 8 .. ^1]
438 428
439 outFile.writeLine &"converter {bitsName}ToBits*(flags: openArray[{bitsName}]): {flagsName} =" 429 outFile.writeLine &"""
440 outFile.writeLine &" asBits[{bitsName}, {flagsName}](flags)" 430 func `or`(a: {flagSetType}, b: {enumName}): {flagSetType} {{.hint[XDeclaredButNotUsed]: off.}} =
441 outFile.writeLine &"func `$`*(bits: {flagsName}): string =" 431 {flagSetType}(distinctBase({flagSetType})(a) or distinctBase({flagSetType})(b))
442 outFile.writeLine &" $toEnums[{flagsName}, {bitsName}](bits)" 432 func `or`(a, b: {enumName}): {flagSetType} {{.hint[XDeclaredButNotUsed]: off.}} =
433 {flagSetType}(distinctBase({flagSetType})(a) or distinctBase({flagSetType})(b))
434 func contains(flags: {flagSetType}, flag: {enumName}): bool {{.hint[XDeclaredButNotUsed]: off.}} =
435 (distinctBase({flagSetType})(flags) and distinctBase({flagSetType})(flag)) > 0
436 """
437 outFile.writeLine &"func `$`*(bits: {flagSetType}): string ="
438 outFile.writeLine &"""
439 for value in enumFullRange({enumName}):
440 if (value.ord and cint(bits)) > 0:
441 result &= $value & "|"
442 result.setLen(max(0, result.len - 1))
443 """
443 outFile.writeLine "" 444 outFile.writeLine ""
444 445
445 for command in commands: 446 for command in commands:
446 if command.attr("api") == "vulkansc": 447 if command.attr("api") == "vulkansc":
447 continue 448 continue