File: tswizzle.nim

package info (click to toggle)
nim 0.19.4-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 462,356 kB
  • sloc: sh: 11,089; ansic: 4,699; makefile: 706; python: 309; sql: 297; asm: 141; xml: 13
file content (80 lines) | stat: -rw-r--r-- 1,379 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
discard """
  output: '''3
[1, 3]
[2, 1, 2]
'''
  disabled: "true"
"""

import macros, strutils

template accept(e: expr) =
  static: assert(compiles(e))

template reject(e: expr) =
  static: assert(not compiles(e))

proc swizzleIdx(c: char): int =
  return case c
    of 'x': 0
    of 'y': 1
    of 'z': 2
    of 'w': 3
    of 'r': 0
    of 'g': 1
    of 'b': 2
    of 'a': 3
    else: 0

proc isSwizzle(s: string): bool {.compileTime.} =
  template trySet(name, set) =
    block search:
      for c in s:
        if c notin set:
          break search
      return true

  trySet coords, {'x', 'y', 'z', 'w'}
  trySet colors, {'r', 'g', 'b', 'a'}

  return false

type
  StringIsSwizzle = concept value
    value.isSwizzle

  SwizzleStr = static[string] and StringIsSwizzle

proc foo(x: SwizzleStr) =
  echo "sw"

#foo("xx")
reject foo("xe")

type
  Vec[N: static[int]; T] = array[N, T]

when false:
  proc card(x: Vec): int = x.N
  proc `$`(x: Vec): string = x.repr.strip

  macro `.`(x: Vec, swizzle: SwizzleStr): expr =
    var
      cardinality = swizzle.len
      values = newNimNode(nnkBracket)
      v = genSym()

    for c in swizzle:
      values.add newNimNode(nnkBracketExpr).add(
        v, c.swizzleIdx.newIntLitNode)

    return quote do:
      let `v` = `x`
      Vec[`cardinality`, `v`.T](`values`)

var z = Vec([1, 2, 3])

#echo z.card
#echo z.xz
#echo z.yxy