summary refs log tree commit diff stats
path: root/compiler/evaltempl.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/evaltempl.nim')
-rw-r--r--compiler/evaltempl.nim62
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)