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:
parent
a66d059acc
commit
4b7655fd10
12 changed files with 225 additions and 58 deletions
|
|
@ -1,5 +1,5 @@
|
|||
discard """
|
||||
line: 11
|
||||
line: 10
|
||||
errormsg: "type mismatch: got (typedesc[float], string)"
|
||||
"""
|
||||
|
||||
|
|
|
|||
79
tests/metatype/swizzle.nim
Normal file
79
tests/metatype/swizzle.nim
Normal 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
|
||||
|
||||
10
tests/metatype/typeclassinference.nim
Normal file
10
tests/metatype/typeclassinference.nim
Normal 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]"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue