diff options
Diffstat (limited to 'rod/semtempl.nim')
-rw-r--r-- | rod/semtempl.nim | 204 |
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) |