Skip to content

Instantly share code, notes, and snippets.

Created November 25, 2017 11:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/3ab832df094b0629ec337afb84218770 to your computer and use it in GitHub Desktop.
Save anonymous/3ab832df094b0629ec337afb84218770 to your computer and use it in GitHub Desktop.
import macros,options
type C = ref object
c: int
macro until(cond,node,body:untyped):untyped =
# Example implementation, just to prove it's possible
# Generates:
# for raw in b:
# if cond(raw): break
# when declared Option:
# when raw is Option:
# let a = raw.get
# else:
# let a = raw
# else:
# let a = raw
# body
#
let
el = node[1]
list = node[2]
rawel = newIdentNode("rawel")
var
brk = newNimNode(nnkBreakStmt)
cnd = newIfStmt((newCall(cond, rawel), brk))
wnstmt = newTree(nnkWhenStmt,
newNimNode(nnkElifBranch).add(
newCall("declared", newIdentNode("Option")),
newTree(nnkWhenStmt,
newNimNode(nnkElifBranch).add(
newCall("is",rawel, newIdentNode("Option")),
newLetStmt(el, newCall("get", rawel))
),
newNimNode(nnkElse).add(newLetStmt(el, rawel))
),
),
newNimNode(nnkElse).add(newLetStmt(el, rawel))
)
brk.add(newEmptyNode())
result = newTree( nnkForStmt,
rawel,
list,
newStmtList(cnd, wnstmt, body)
)
var b = @[C(c: 0), nil, C(c: 2)]
until isnil, a in b:
echo a.c
# 0
var c = @[some(2), none(int), some(8), some(10)]
until isNone, a in c:
echo a
# 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment