diff options
Diffstat (limited to 'compiler/evaltempl.nim')
-rw-r--r-- | compiler/evaltempl.nim | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index d7006d34d..265fe3fe1 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -19,14 +19,17 @@ type mapping: TIdTable # every gensym'ed symbol needs to be mapped to some # new symbol -proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx): PNode = - #inc genSymBaseId +proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = case templ.kind of nkSym: var s = templ.sym if s.owner.id == c.owner.id: if s.kind == skParam: - result = copyTree(actual.sons[s.position]) + let x = actual.sons[s.position] + if x.kind == nkArgList: + for y in items(x): result.add(y) + else: + result.add copyTree(x) else: InternalAssert sfGenSym in s.flags var x = PSym(IdTableGet(c.mapping, s)) @@ -34,16 +37,42 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx): PNode = x = copySym(s, false) x.owner = c.genSymOwner IdTablePut(c.mapping, s, x) - result = newSymNode(x, templ.info) + result.add newSymNode(x, templ.info) else: - result = copyNode(templ) + result.add copyNode(templ) of nkNone..nkIdent, nkType..nkNilLit: # atom - result = copyNode(templ) + result.add copyNode(templ) else: - result = copyNode(templ) - newSons(result, sonsLen(templ)) + var res = copyNode(templ) for i in countup(0, sonsLen(templ) - 1): - result.sons[i] = evalTemplateAux(templ.sons[i], actual, c) + evalTemplateAux(templ.sons[i], actual, c, res) + result.add res + +when false: + proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx): PNode = + case templ.kind + of nkSym: + var s = templ.sym + if s.owner.id == c.owner.id: + if s.kind == skParam: + result = copyTree(actual.sons[s.position]) + else: + InternalAssert sfGenSym in s.flags + var x = PSym(IdTableGet(c.mapping, s)) + if x == nil: + x = copySym(s, false) + x.owner = c.genSymOwner + IdTablePut(c.mapping, s, x) + result = newSymNode(x, templ.info) + else: + result = copyNode(templ) + of nkNone..nkIdent, nkType..nkNilLit: # atom + result = copyNode(templ) + else: + result = copyNode(templ) + newSons(result, sonsLen(templ)) + for i in countup(0, sonsLen(templ) - 1): + result.sons[i] = evalTemplateAux(templ.sons[i], actual, c) proc evalTemplateArgs(n: PNode, s: PSym): PNode = # if the template has zero arguments, it can be called without ``()`` @@ -78,6 +107,19 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym): PNode = ctx.owner = tmpl ctx.genSymOwner = genSymOwner initIdTable(ctx.mapping) - result = evalTemplateAux(tmpl.getBody, args, ctx) + + let body = tmpl.getBody + if isAtom(body): + result = newNodeI(nkPar, body.info) + evalTemplateAux(body, args, ctx, result) + if result.len == 1: result = result.sons[0] + else: + GlobalError(result.info, errIllFormedAstX, + renderTree(result, {renderNoComments})) + else: + result = copyNode(body) + #evalTemplateAux(body, args, ctx, result) + for i in countup(0, safeLen(body) - 1): + evalTemplateAux(body.sons[i], args, ctx, result) dec(evalTemplateCounter) |