Nim/tests/metatype/swizzle.nim
Zahary Karadjov 4b7655fd10 reference implementation of a vector swizzle library
This also provides the initial steps towards support for type class "filtered" type inference
fixes an "ordinal type expected" ICE, related to the use of static params
2014-03-20 01:16:50 +02:00

79 lines
1.3 KiB
Nim

discard """
output: '''3
[1, 3]
[2, 1, 2]
'''
"""
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 =
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 = generic value
value.isSwizzle
SwizzleStr = static[string] and StringIsSwizzle
proc foo(x: SwizzleStr) =
echo "sw"
accept foo("xx")
reject foo("xe")
type
Vec[N: static[int]; T] = array[N, T]
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