tswizzle.nim 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. discard """
  2. output: '''3
  3. [1, 3]
  4. [2, 1, 2]
  5. '''
  6. disabled: "true"
  7. """
  8. import macros, strutils
  9. template accept(e: expr) =
  10. static: assert(compiles(e))
  11. template reject(e: expr) =
  12. static: assert(not compiles(e))
  13. proc swizzleIdx(c: char): int =
  14. return case c
  15. of 'x': 0
  16. of 'y': 1
  17. of 'z': 2
  18. of 'w': 3
  19. of 'r': 0
  20. of 'g': 1
  21. of 'b': 2
  22. of 'a': 3
  23. else: 0
  24. proc isSwizzle(s: string): bool {.compileTime.} =
  25. template trySet(name, set) =
  26. block search:
  27. for c in s:
  28. if c notin set:
  29. break search
  30. return true
  31. trySet coords, {'x', 'y', 'z', 'w'}
  32. trySet colors, {'r', 'g', 'b', 'a'}
  33. return false
  34. type
  35. StringIsSwizzle = concept value
  36. value.isSwizzle
  37. SwizzleStr = static[string] and StringIsSwizzle
  38. proc foo(x: SwizzleStr) =
  39. echo "sw"
  40. #foo("xx")
  41. reject foo("xe")
  42. type
  43. Vec[N: static[int]; T] = array[N, T]
  44. when false:
  45. proc card(x: Vec): int = x.N
  46. proc `$`(x: Vec): string = x.repr.strip
  47. macro `.`(x: Vec, swizzle: SwizzleStr): expr =
  48. var
  49. cardinality = swizzle.len
  50. values = newNimNode(nnkBracket)
  51. v = genSym()
  52. for c in swizzle:
  53. values.add newNimNode(nnkBracketExpr).add(
  54. v, c.swizzleIdx.newIntLitNode)
  55. return quote do:
  56. let `v` = `x`
  57. Vec[`cardinality`, `v`.T](`values`)
  58. var z = Vec([1, 2, 3])
  59. #echo z.card
  60. #echo z.xz
  61. #echo z.yxy