I have a proc which I want to directly include in my code, that's why I decided templates is the way to go.
For example, in my caller proc I have:
case someVar
of 0: result = doSth()
...
(obviously doSth() also returns a value)
Now, to make this work I converted my doSth() in this template:
template Core_Print_Templ*(xl: ExpressionList): Value =
let v = xl.evaluate(forceArray=true).a
echo v[0].stringify(quoted=false)
v[0]
So, basically result (in my caller proc) gets the value of v[0] from the template.
Now, the question is: how could I solve this, while keeping the Core_Print_Templ as a template, if this function has more than one exit points - meaning: if i returns a result from different locations?
For example, the following code (currently a proc), how could I turn this into a template?
proc Core_Not*[F,X,V](f: F, xl: X): V {.inline.} =
let v0 = f.validateOne(xl.list[0],[BV,IV])
case v0.kind
of BV:
if v0.b: result = TRUE
else: result = FALSE
of IV:
result = valueFromInteger(bitnot(v0.i))
else: discard
(I know templates is about code being substituted ed directly in the caller code, but I still do not fully understand how it works - so any ideas are more than welcome)
I use dirty templates a lot but only when I need to capture 5~10 variables in the environment.
It's very easy to refactor and forget that the dirty template was capturing something, it happen to me with result. In your case the transformation is easy:
proc Core_Not*[F,X,V](f: F, xl: X): V {.inline.} =
let v0 = f.validateOne(xl.list[0],[BV,IV])
case v0.kind
of BV:
if v0.b: result = TRUE
else: result = FALSE
of IV:
result = valueFromInteger(bitnot(v0.i))
else: discard
to
template Core_Not*[F,X,V](f: F, xl: X): V =
let v0 = f.validateOne(xl.list[0],[BV,IV])
var tresult: V
case v0.kind
of BV:
if v0.b: tresult = TRUE
else: tresult = FALSE
of IV:
result = valueFromInteger(bitnot(v0.i))
else: discard
tresult