From ce23b814a0255a1a20eefff5e9b3679d52b8aa43 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 6 Aug 2012 18:11:03 +0200 Subject: [PATCH] borrow works with generics --- compiler/procfind.nim | 70 ++++++++++++++++++------------------------- compiler/semcall.nim | 14 +++++++++ compiler/types.nim | 14 +++++++++ tests/run/tborrow.nim | 21 +++++++++++++ todo.txt | 1 - web/news.txt | 1 + 6 files changed, 79 insertions(+), 42 deletions(-) create mode 100644 tests/run/tborrow.nim diff --git a/compiler/procfind.nim b/compiler/procfind.nim index 34a3482f8..eefe734b3 100755 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -13,14 +13,6 @@ import ast, astalgo, msgs, semdata, types, trees -proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym - # Searchs for the fn in the symbol table. If the parameter lists are exactly - # the same the sym in the symbol table is returned, else nil. -proc SearchForBorrowProc*(c: PContext, fn: PSym, tos: int): PSym - # Searchs for the fn in the symbol table. If the parameter lists are suitable - # for borrowing the sym in the symbol table is returned, else nil. -# implementation - proc equalGenericParams(procA, procB: PNode): bool = var a, b: PSym result = procA == procB @@ -41,7 +33,9 @@ proc equalGenericParams(procA, procB: PNode): bool = if not ExprStructuralEquivalent(a.ast, b.ast): return result = true -proc SearchForProc(c: PContext, fn: PSym, tos: int): PSym = +proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = + # Searchs for the fn in the symbol table. If the parameter lists are exactly + # the same the sym in the symbol table is returned, else nil. var it: TIdentIter result = initIdentIter(it, c.tab.stack[tos], fn.Name) while result != nil: @@ -58,36 +52,30 @@ proc SearchForProc(c: PContext, fn: PSym, tos: int): PSym = nil result = NextIdentIter(it, c.tab.stack[tos]) -proc paramsFitBorrow(child, parent: PNode): bool = - var length = sonsLen(child) - result = false - if length == sonsLen(parent): - for i in countup(1, length - 1): - var m = child.sons[i].sym - var n = parent.sons[i].sym - assert((m.kind == skParam) and (n.kind == skParam)) - if not compareTypes(m.typ, n.typ, dcEqOrDistinctOf): return - if not compareTypes(child.sons[0].typ, parent.sons[0].typ, - dcEqOrDistinctOf): return - result = true +when false: + proc paramsFitBorrow(child, parent: PNode): bool = + var length = sonsLen(child) + result = false + if length == sonsLen(parent): + for i in countup(1, length - 1): + var m = child.sons[i].sym + var n = parent.sons[i].sym + assert((m.kind == skParam) and (n.kind == skParam)) + if not compareTypes(m.typ, n.typ, dcEqOrDistinctOf): return + if not compareTypes(child.sons[0].typ, parent.sons[0].typ, + dcEqOrDistinctOf): return + result = true -proc SearchForBorrowProc(c: PContext, fn: PSym, tos: int): PSym = - # Searchs for the fn in the symbol table. If the parameter lists are suitable - # for borrowing the sym in the symbol table is returned, else nil. - var it: TIdentIter - for scope in countdown(tos, 0): - result = initIdentIter(it, c.tab.stack[scope], fn.Name) - while result != nil: - # watchout! result must not be the same as fn! - if (result.Kind == fn.kind) and (result.id != fn.id): - if equalGenericParams(result.ast.sons[genericParamsPos], - fn.ast.sons[genericParamsPos]): - if paramsFitBorrow(fn.typ.n, result.typ.n): return - result = NextIdentIter(it, c.tab.stack[scope]) - -proc SearchForBorrowProc2(c: PContext, fn: PSym, tos: int): PSym = - # Searchs for the fn in the symbol table. If the parameter lists are suitable - # for borrowing the sym in the symbol table is returned, else nil. - # New approach: generate fn(x, y, z) where x, y, z have the proper types - # and use the overloading resolution mechanism: - nil + proc SearchForBorrowProc*(c: PContext, fn: PSym, tos: int): PSym = + # Searchs for the fn in the symbol table. If the parameter lists are suitable + # for borrowing the sym in the symbol table is returned, else nil. + var it: TIdentIter + for scope in countdown(tos, 0): + result = initIdentIter(it, c.tab.stack[scope], fn.Name) + while result != nil: + # watchout! result must not be the same as fn! + if (result.Kind == fn.kind) and (result.id != fn.id): + if equalGenericParams(result.ast.sons[genericParamsPos], + fn.ast.sons[genericParamsPos]): + if paramsFitBorrow(fn.typ.n, result.typ.n): return + result = NextIdentIter(it, c.tab.stack[scope]) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index eca8d75f0..e4655c5ba 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -150,3 +150,17 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = else: result = explicitGenericInstError(n) +proc SearchForBorrowProc(c: PContext, fn: PSym, tos: int): PSym = + # Searchs for the fn in the symbol table. If the parameter lists are suitable + # for borrowing the sym in the symbol table is returned, else nil. + # New approach: generate fn(x, y, z) where x, y, z have the proper types + # and use the overloading resolution mechanism: + var call = newNode(nkCall) + call.add(newIdentNode(fn.name, fn.info)) + for i in 1..