summary refs log tree commit diff stats
path: root/rod/semtempl.nim
diff options
context:
space:
mode:
Diffstat (limited to 'rod/semtempl.nim')
-rw-r--r--rod/semtempl.nim204
1 files changed, 0 insertions, 204 deletions
diff --git a/rod/semtempl.nim b/rod/semtempl.nim
deleted file mode 100644
index f866f77d2..000000000
--- a/rod/semtempl.nim
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-#
-#           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-proc isExpr(n: PNode): bool = 
-  # returns true if ``n`` looks like an expression
-  if n == nil: 
-    return false
-  case n.kind
-  of nkIdent..nkNilLit: 
-    result = true
-  of nkCall..nkPassAsOpenArray: 
-    for i in countup(0, sonsLen(n) - 1): 
-      if not isExpr(n.sons[i]): 
-        return false
-    result = true
-  else: result = false
-  
-proc isTypeDesc(n: PNode): bool = 
-  # returns true if ``n`` looks like a type desc
-  if n == nil: 
-    return false
-  case n.kind
-  of nkIdent, nkSym, nkType: 
-    result = true
-  of nkDotExpr, nkBracketExpr: 
-    for i in countup(0, sonsLen(n) - 1): 
-      if not isTypeDesc(n.sons[i]): 
-        return false
-    result = true
-  of nkTypeOfExpr..nkEnumTy: 
-    result = true
-  else: result = false
-  
-proc evalTemplateAux(c: PContext, templ, actual: PNode, sym: PSym): PNode = 
-  var p: PSym
-  if templ == nil: 
-    return nil
-  case templ.kind
-  of nkSym: 
-    p = templ.sym
-    if (p.kind == skParam) and (p.owner.id == sym.id): 
-      result = copyTree(actual.sons[p.position])
-    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(c, templ.sons[i], actual, sym)
-  
-var evalTemplateCounter: int = 0
-
-proc evalTemplateArgs(c: PContext, n: PNode, s: PSym): PNode = 
-  # to prevend endless recursion in templates
-  # instantation
-  var 
-    f, a: int
-    arg: PNode
-  f = sonsLen(s.typ) # if the template has zero arguments, it can be called without ``()``
-                     # `n` is then a nkSym or something similar
-  case n.kind
-  of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: a = sonsLen(
-      n)
-  else: a = 0
-  if a > f: liMessage(n.info, errWrongNumberOfArguments)
-  result = copyNode(n)
-  for i in countup(1, f - 1): 
-    if i < a: arg = n.sons[i]
-    else: arg = copyTree(s.typ.n.sons[i].sym.ast)
-    if arg == nil: liMessage(n.info, errWrongNumberOfArguments)
-    if not (s.typ.sons[i].kind in {tyTypeDesc, tyStmt, tyExpr}): 
-      # concrete type means semantic checking for argument:
-      arg = fitNode(c, s.typ.sons[i], semExprWithType(c, arg))
-    addSon(result, arg)
-
-proc evalTemplate(c: PContext, n: PNode, sym: PSym): PNode = 
-  var args: PNode
-  inc(evalTemplateCounter)
-  if evalTemplateCounter > 100: 
-    liMessage(n.info, errTemplateInstantiationTooNested) # replace each param by the corresponding node:
-  args = evalTemplateArgs(c, n, sym)
-  result = evalTemplateAux(c, sym.ast.sons[codePos], args, sym)
-  dec(evalTemplateCounter)
-
-proc symChoice(c: PContext, n: PNode, s: PSym): PNode = 
-  var 
-    a: PSym
-    o: TOverloadIter
-    i: int
-  i = 0
-  a = initOverloadIter(o, c, n)
-  while a != nil: 
-    a = nextOverloadIter(o, c, n)
-    inc(i)
-  if i <= 1: 
-    result = newSymNode(s)
-    result.info = n.info
-    markUsed(n, s)
-  else: 
-    # semantic checking requires a type; ``fitNode`` deals with it
-    # appropriately
-    result = newNodeIT(nkSymChoice, n.info, newTypeS(tyNone, c))
-    a = initOverloadIter(o, c, n)
-    while a != nil: 
-      addSon(result, newSymNode(a))
-      a = nextOverloadIter(o, c, n)
-
-proc resolveTemplateParams(c: PContext, n: PNode, withinBind: bool, 
-                           toBind: var TIntSet): PNode = 
-  var s: PSym
-  if n == nil: 
-    return nil
-  case n.kind
-  of nkIdent: 
-    if not withinBind and not IntSetContains(toBind, n.ident.id): 
-      s = SymTabLocalGet(c.Tab, n.ident)
-      if (s != nil): 
-        result = newSymNode(s)
-        result.info = n.info
-      else: 
-        result = n
-    else: 
-      IntSetIncl(toBind, n.ident.id)
-      result = symChoice(c, n, lookup(c, n))
-  of nkSym..nkNilLit:         # atom
-    result = n
-  of nkBind: 
-    result = resolveTemplateParams(c, n.sons[0], true, toBind)
-  else: 
-    result = n
-    for i in countup(0, sonsLen(n) - 1): 
-      result.sons[i] = resolveTemplateParams(c, n.sons[i], withinBind, toBind)
-  
-proc transformToExpr(n: PNode): PNode = 
-  var realStmt: int
-  result = n
-  case n.kind
-  of nkStmtList: 
-    realStmt = - 1
-    for i in countup(0, sonsLen(n) - 1): 
-      case n.sons[i].kind
-      of nkCommentStmt, nkEmpty, nkNilLit: 
-        nil
-      else: 
-        if realStmt == - 1: realStmt = i
-        else: realStmt = - 2
-    if realStmt >= 0: result = transformToExpr(n.sons[realStmt])
-    else: n.kind = nkStmtListExpr
-  of nkBlockStmt: 
-    n.kind = nkBlockExpr      #nkIfStmt: n.kind := nkIfExpr; // this is not correct!
-  else: 
-    nil
-
-proc semTemplateDef(c: PContext, n: PNode): PNode = 
-  var 
-    s: PSym
-    toBind: TIntSet
-  if c.p.owner.kind == skModule: 
-    s = semIdentVis(c, skTemplate, n.sons[0], {sfStar})
-    incl(s.flags, sfGlobal)
-  else: 
-    s = semIdentVis(c, skTemplate, n.sons[0], {})
-  if sfStar in s.flags: 
-    incl(s.flags, sfInInterface) # check parameter list:
-  pushOwner(s)
-  openScope(c.tab)
-  n.sons[namePos] = newSymNode(s) # check that no pragmas exist:
-  if n.sons[pragmasPos] != nil: 
-    liMessage(n.info, errNoPragmasAllowedForX, "template") # check that no generic parameters exist:
-  if n.sons[genericParamsPos] != nil: 
-    liMessage(n.info, errNoGenericParamsAllowedForX, "template")
-  if (n.sons[paramsPos] == nil): 
-    # use ``stmt`` as implicit result type
-    s.typ = newTypeS(tyProc, c)
-    s.typ.n = newNodeI(nkFormalParams, n.info)
-    addSon(s.typ, newTypeS(tyStmt, c))
-    addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0]))
-  else: 
-    semParamList(c, n.sons[ParamsPos], nil, s)
-    if n.sons[paramsPos].sons[0] == nil: 
-      # use ``stmt`` as implicit result type
-      s.typ.sons[0] = newTypeS(tyStmt, c)
-      s.typ.n.sons[0] = newNodeIT(nkType, n.info, s.typ.sons[0])
-  addParams(c, s.typ.n)       # resolve parameters:
-  IntSetInit(toBind)
-  n.sons[codePos] = resolveTemplateParams(c, n.sons[codePos], false, toBind)
-  if not (s.typ.sons[0].kind in {tyStmt, tyTypeDesc}): 
-    n.sons[codePos] = transformToExpr(n.sons[codePos]) # only parameters are resolved, no type checking is performed
-  closeScope(c.tab)
-  popOwner()
-  s.ast = n
-  result = n
-  if n.sons[codePos] == nil: 
-    liMessage(n.info, errImplOfXexpected, s.name.s) # add identifier of template as a last step to not allow
-                                                    # recursive templates
-  addInterfaceDecl(c, s)