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
This commit is contained in:
Zahary Karadjov 2014-03-19 02:52:48 +02:00
commit 4b7655fd10
12 changed files with 225 additions and 58 deletions

View file

@ -1,5 +1,5 @@
discard """
line: 11
line: 10
errormsg: "type mismatch: got (typedesc[float], string)"
"""

View file

@ -0,0 +1,79 @@
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

View file

@ -0,0 +1,10 @@
import typetraits
type
Vec[N: static[int]; T] = distinct array[N, T]
var x = Vec([1, 2, 3])
static:
assert x.type.name == "Vec[static[int](3), int]"