Mercurial > games > semicongine
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 |