Skip to content

Commit c0f5f0b

Browse files
committed
Replace identifiers within maybeCase just block
with reference to the inner value in the maybe object. Fixes #6
1 parent 9ce9596 commit c0f5f0b

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,7 @@ <h1><a class="toc-backref" href="#16">Macros</a></h1>
13351335
</dl>
13361336
<p>converts to ---&gt;</p>
13371337
<dl class="docutils"><dt>if m.isValid:</dt>
1338-
<dd>var x = m.value eval expr using x</dd>
1338+
<dd>eval expr using x where x is replaced with m.value</dd>
13391339
<dt>else:</dt>
13401340
<dd>eval expr2</dd>
13411341
</dl>

src/maybe/maybe.nim

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ proc just*[T](val: T) : Maybe[T] =
3333
## Construct a maybe instance in the valid state.
3434
Maybe[T](valid: true, value: val)
3535

36+
proc replaceIdents(before: NimNode, after: NimNode, ast: var NimNode) =
37+
for i in 0 .. <ast.len:
38+
var child = ast[i]
39+
case child.kind:
40+
of nnkIdent:
41+
if child == before:
42+
copyChildrenTo(child, after)
43+
ast[i] = after
44+
else:
45+
discard
46+
47+
replaceIdents(before, after, child)
48+
3649
macro maybeCase*[T](m : Maybe[T], body : untyped) : untyped =
3750
## A macro which provides a safe access pattern to
3851
## the maybe type. This avoids the need to have a get function
@@ -50,8 +63,7 @@ macro maybeCase*[T](m : Maybe[T], body : untyped) : untyped =
5063
## converts to --->
5164
##
5265
## if m.isValid:
53-
## var x = m.value
54-
## eval expr using x
66+
## eval expr using x where x is replaced with m.value
5567
## else:
5668
## eval expr2
5769
##
@@ -72,10 +84,13 @@ macro maybeCase*[T](m : Maybe[T], body : untyped) : untyped =
7284
var valueExpr = newDotExpr(m, ident("value"))
7385

7486
var justClause = newNimNode(nnkStmtList)
75-
justClause.add(newNimNode(nnkVarSection).add(
76-
newIdentDefs(unboxedIdent, newEmptyNode(), valueExpr)))
77-
for i in 2..body[0].len-1:
78-
justClause.add(body[0][i])
87+
for i in 2 .. <body[0].len:
88+
# We must go through each expression in the just clause
89+
# and replace our identifier named in the declaration of
90+
# the macro (the 'x' in just x:) with m.value
91+
var current = body[0][i]
92+
replaceIdents(unboxedIdent, valueExpr, current)
93+
justClause.add(current)
7994

8095
var nothingClause = newNimNode(nnkStmtList)
8196
for i in 1..body[1].len-1:
@@ -86,6 +101,7 @@ macro maybeCase*[T](m : Maybe[T], body : untyped) : untyped =
86101
ifExpr.add(newNimNode(nnkElseExpr).add(nothingClause))
87102

88103
result = ifExpr
104+
echo treeRepr(result)
89105

90106
proc `$`*[T](m: Maybe[T]) : string =
91107
## Convert a maybe instance to a string.

0 commit comments

Comments
 (0)