diff options
author | Araq <rumpf_a@web.de> | 2012-12-06 08:45:18 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-12-06 08:45:18 +0100 |
commit | a1f677980270d668b9b22e75a9892e100cc2a6d8 (patch) | |
tree | 6340cc0694ad6acbce83153612af3cb7ad2f82fe /compiler | |
parent | 1d842e8b75aa95670386b2ac4613932d2e01b9a3 (diff) | |
download | Nim-a1f677980270d668b9b22e75a9892e100cc2a6d8.tar.gz |
implemented AST based overloading
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/procfind.nim | 4 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 19 | ||||
-rwxr-xr-x | compiler/types.nim | 3 |
3 files changed, 19 insertions, 7 deletions
diff --git a/compiler/procfind.nim b/compiler/procfind.nim index fde4d22ea..4a1fb5ac8 100755 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -29,7 +29,7 @@ proc equalGenericParams(procA, procB: PNode): bool = a = procA.sons[i].sym b = procB.sons[i].sym if (a.name.id != b.name.id) or - not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return + not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return if (a.ast != nil) and (b.ast != nil): if not ExprStructuralEquivalent(a.ast, b.ast): return result = true @@ -44,7 +44,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = if equalGenericParams(result.ast.sons[genericParamsPos], fn.ast.sons[genericParamsPos]): case equalParams(result.typ.n, fn.typ.n) - of paramsEqual: + of paramsEqual: return of paramsIncompatible: LocalError(fn.info, errNotOverloadable, fn.name.s) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index c48434eb7..1f2511694 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -12,18 +12,18 @@ import intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, - magicsys, condsyms, idents, lexer, options + magicsys, condsyms, idents, lexer, options, parampatterns type TCandidateState* = enum csEmpty, csMatch, csNoMatch TCandidate* {.final.} = object - exactMatches*: int + exactMatches*: int # also misused to prefer iters over procs + genericMatches: int # also misused to prefer constraints subtypeMatches: int intConvMatches: int # conversions to int are not as expensive convMatches: int - genericMatches: int state*: TCandidateState callee*: PType # may not be nil! calleeSym*: PSym # may be nil @@ -773,6 +773,15 @@ proc setSon(father: PNode, at: int, son: PNode) = proc matchesAux*(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var TIntSet) = + template checkConstraint(n: expr) {.immediate, dirty.} = + if not formal.constraint.isNil: + if matchNodeKinds(formal.constraint, n): + # better match over other routines with no such restriction: + inc(m.genericMatches, 100) + else: + m.state = csNoMatch + return + var f = 1 # iterates over formal parameters var a = 1 # iterates over the actual given arguments m.state = csMatch # until proven otherwise @@ -805,7 +814,8 @@ proc matchesAux*(c: PContext, n, nOrig: PNode, n.sons[a].sons[1], nOrig.sons[a].sons[1]) if arg == nil: m.state = csNoMatch - return + return + checkConstraint(n.sons[a].sons[1]) if m.baseTypeMatch: assert(container == nil) container = newNodeI(nkBracket, n.sons[a].info) @@ -862,6 +872,7 @@ proc matchesAux*(c: PContext, n, nOrig: PNode, if f != formalLen - 1: container = nil else: setSon(m.call, formal.position + 1, arg) + checkConstraint(n.sons[a]) inc(a) inc(f) diff --git a/compiler/types.nim b/compiler/types.nim index 825b1027a..23d202fdf 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -632,7 +632,8 @@ proc SameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool = result = SameTypeAux(a, b, c) proc equalParam(a, b: PSym): TParamsEquality = - if SameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): + if SameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}) and + ExprStructuralEquivalent(a.constraint, b.constraint): if a.ast == b.ast: result = paramsEqual elif a.ast != nil and b.ast != nil: |