Mercurial > games > semicongine
comparison svk/generate.nim @ 1489:e6bd1f553c1b
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 |
