Rearrange tuple binding code

Introduce separate proc for creation of unpacking
statement.

Use `quote do` to make code as similar as possible
to the `bindLet` and `bindVar` templates.
This commit is contained in:
Mark Spanbroek 2023-02-13 12:05:57 +01:00
parent 8b210f3f67
commit 935535a76e

View File

@ -30,38 +30,35 @@ template bindVar(name, expression): bool =
placeholder(T) placeholder(T)
option.isSome option.isSome
macro bindTuple(name, expression): bool = proc newUnpackTupleNode(names: NimNode, value: NimNode): NimNode =
let stmtList = newStmtList() # builds tuple unpacking statement, eg: let (a, b) = value
let opt = genSym(nskLet, "option") let vartuple = nnkVarTuple.newTree()
let T = genSym(nskType, "T") for i in 0..<names.len:
vartuple.add names[i]
vartuple.add newEmptyNode()
vartuple.add value
nnkLetSection.newTree(vartuple)
stmtList.add quote do: macro bindTuple(names, expression): bool =
let evaluated = `expression` let opt = ident("option")
let `opt` = evaluated.option let evaluated = ident("evaluated")
type `T` = typeof(`opt`.unsafeGet()) let T = ident("T")
let valueNode = quote do: let value = quote do:
if `opt`.isSome: if `opt`.isSome:
`opt`.unsafeGet() `opt`.unsafeGet()
else: else:
bindFailed(evaluated) bindFailed(`evaluated`)
placeholder(`T`) placeholder(`T`)
# build tuple unpacking statement, eg: let letsection = newUnpackTupleNode(names, value)
# let (a, b) = `valueNode`
let tplNode = nnkVarTuple.newTree()
for i in 0..<name.len:
tplNode.add name[i]
tplNode.add newEmptyNode()
tplNode.add valueNode
stmtList.add nnkStmtList.newTree( quote do:
nnkLetSection.newTree( let `evaluated` = `expression`
tplNode let `opt` = `evaluated`.option
) type `T` = typeof(`opt`.unsafeGet())
) `letsection`
stmtList.add quote do: `opt`.isSome `opt`.isSome
return stmtList
macro `=?`*(name, expression): bool = macro `=?`*(name, expression): bool =
## The `=?` operator lets you bind the value inside an Option or Result to a ## The `=?` operator lets you bind the value inside an Option or Result to a