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
79 lines
1.3 KiB
Nim
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
|
|
|