Skip to content

Instantly share code, notes, and snippets.

@timotheecour
Created February 12, 2021 20:07
Show Gist options
  • Save timotheecour/f7a847b0f0e9909efd6f7ee85420c4be to your computer and use it in GitHub Desktop.
Save timotheecour/f7a847b0f0e9909efd6f7ee85420c4be to your computer and use it in GitHub Desktop.
when true:
import macros
from typetraits import distinctBase
{.experimental: "caseStmtMacros".}
type CustomCase1[T]= distinct T
template customCase1[T](a: T): CustomCase1[T] = CustomCase1[T](a)
proc `==`[T](a: CustomCase1[T], b: T): bool = a.distinctBase == b
type CustomCase2[T]= distinct T
template customCase2[T](a: T): CustomCase2[T] = CustomCase2[T](a)
proc `==`[T](a: CustomCase2[T], b: T): bool = a.distinctBase == b
macro `case`(n: CustomCase1): untyped =
result = newTree(nnkIfStmt)
let selector = n[0]
for i in 1 ..< n.len:
let it = n[i]
case it.kind
of nnkElse, nnkElifBranch, nnkElifExpr, nnkElseExpr:
result.add it
of nnkOfBranch:
for j in 0..it.len-2:
let cond = newCall("==", selector, it[j])
result.add newTree(nnkElifBranch, cond, it[^1])
else:
error "custom 'case' for tuple cannot handle this node", it
result = quote do:
echo "v1"
`result`
macro `case`(n: CustomCase2): untyped =
result = newTree(nnkIfStmt)
let selector = n[0]
for i in 1 ..< n.len:
let it = n[i]
case it.kind
of nnkElse, nnkElifBranch, nnkElifExpr, nnkElseExpr:
result.add it
of nnkOfBranch:
for j in 0..it.len-2:
let cond = newCall("==", selector, it[j])
result.add newTree(nnkElifBranch, cond, it[^1])
else:
error "custom 'case' for tuple cannot handle this node", it
result = quote do:
echo "v2"
`result`
case (("foo", 78)).customCase1
of ("foo", 78): echo "yes"
of ("bar", 88): echo "no"
else: discard
case (("foo", 78)).customCase2
of ("foo", 78): echo "yes"
of ("bar", 88): echo "no"
else: discard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment