Add comments to clarify chaining code

This commit is contained in:
Mark Spanbroek 2021-03-13 10:54:16 +01:00
parent e266870dfa
commit b8e52b6acf

View File

@ -1,33 +1,39 @@
import std/macros
template `?.`*(option: typed, identifier: untyped{nkIdent}): untyped =
# chain is of shape: option?.identifier
option ->? option.unsafeGet.identifier
macro `?.`*(option: typed, infix: untyped{nkInfix}): untyped =
# chain is of shape: option?.left `operator` right
let left = infix[1]
infix[1] = quote do: `option`?.`left`
infix
macro `?.`*(option: typed, bracket: untyped{nkBracketExpr}): untyped =
# chain is of shape: option?.left[right]
let left = bracket[0]
bracket[0] = quote do: `option`?.`left`
bracket
macro `?.`*(option: typed, dot: untyped{nkDotExpr}): untyped =
# chain is of shape: option?.left.right
let left = dot[0]
dot[0] = quote do: `option`?.`left`
dot
macro `?.`*(option: typed, call: untyped{nkCall}): untyped =
let procedure = call[0]
if call.len > 1:
if procedure.kind == nnkDotExpr:
let (inner, outer) = (procedure[0], procedure[1])
call[0] = outer
call.insert(1, quote do: `option`?.`inner`)
call
else:
call.insert(1, quote do: `option`.unsafeGet)
quote do: `option` ->? `call`
if call.len == 1:
# chain is of shape: option?.procedure()
quote do: `option`?.`procedure`
elif procedure.kind == nnkDotExpr:
# chain is of shape: option?.left.right(arguments)
let (left, right) = (procedure[0], procedure[1])
call[0] = right
call.insert(1, quote do: `option`?.`left`)
call
else:
quote do: `option`?.`procedure`
# chain is of shape: option?.procedure(arguments)
call.insert(1, quote do: `option`.unsafeGet)
quote do: `option` ->? `call`