summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-06 08:45:18 +0100
committerAraq <rumpf_a@web.de>2012-12-06 08:45:18 +0100
commita1f677980270d668b9b22e75a9892e100cc2a6d8 (patch)
tree6340cc0694ad6acbce83153612af3cb7ad2f82fe /compiler
parent1d842e8b75aa95670386b2ac4613932d2e01b9a3 (diff)
downloadNim-a1f677980270d668b9b22e75a9892e100cc2a6d8.tar.gz
implemented AST based overloading
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/procfind.nim4
-rwxr-xr-xcompiler/sigmatch.nim19
-rwxr-xr-xcompiler/types.nim3
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: