Nested templated data: Difference between revisions

Line 721:
</pre >
=={{header|Nim}}==
<lang nim>import strutils,strformatmacros,sugar,strformat
#macro to take a nested tuple and return a type
type
#e.g. (int,(int,int))=>(string,(string,string))
PayKind = enum pkStr, pkTup
proc intstr(n: NimNode): NimNode =
Payload = object
if n.kind == nnkSym:
case kind: PayKind
return ident("string")
of pkStr:
result = nnkPar.newNimNode()
strval: string
for i ofin pkTup1..<n.len:
result.add(intstr(n[i]))
kids: seq[Payload]
 
macro tuptype(t: typed): untyped = intstr(t.getType)
proc initPayload(tplt: array | seq | tuple | int,
payload: openArray[string]): Payload =
when tplt is int:
Payload(
kind: pkStr,
strval:
if tplt in {0..payload.len-1}:
payload[tplt]
else:
"nil"
)
else:
result = Payload(kind: pkTup)
for fld in (when tplt is tuple: tplt.fields else: tplt):
result.kids.add(initPayload(fld, payload))
 
proc `$`(p: Payload): string =
case p.kind
of pkStr:
p.strval
of pkTup:
&"[{p.kids.join(\",\")}]"
 
proc replace(t: tuple | int, p: openArray[string]): auto =
when t is int: (if t in 0..<p.len: p[t] else: "nil")
else:
var res: tuptype(t)
for k, v in t.fieldpairs:
#k will be 'Field0', so we convert to an integer index
res[k[^1].int - '0'.int] = replace(v, p)
return res
when isMainModule:
#construct payload sequence
let p = collect(for i in 0..5: &"payload{i}")
 
let tplt1 = ((1, 2),(3,4,1),5)
let tplt2 = ((1,2),(3, 4, 1),6)
echo initPayloadreplace(tplt1, p)
5)
echo initPayloadreplace(tplt2, p)</lang>
let tplt2 = (99, #index out of range prints 'nil'
@[3, 4, 4],#seqs and arrays work as well as tuples
(5, [5, 5]))
echo initPayload(tplt1, p)
echo initPayload(tplt2, p)</lang>
{{out}}
<pre>[[(("payload1", "payload2]"),[ ("payload3", "payload4", "payload1]"), "payload5]")
[nil(("payload1",[ "payload2"), ("payload3", "payload4",payload4] "payload1"),[payload5,[payload5,payload5]]] "nil")</pre>
 
=={{header|Perl}}==