summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-08-19 01:34:40 +0300
committerZahary Karadjov <zahary@gmail.com>2013-08-19 01:35:33 +0300
commitc6d06111122f4519bc5a03319aa0ff89a6a60184 (patch)
tree739464b7841d0ca6f42a75037a4f9756400fa205
parenta453d8d64d3d50c32eae630b5764fae50138bc08 (diff)
downloadNim-c6d06111122f4519bc5a03319aa0ff89a6a60184.tar.gz
Revert "Revert "made some tests green""
-rw-r--r--compiler/ast.nim3
-rw-r--r--compiler/lambdalifting.nim2
-rw-r--r--compiler/seminst.nim37
-rw-r--r--compiler/semtypes.nim2
-rw-r--r--tests/compile/tobjects.nim86
-rw-r--r--tests/compile/toverprc.nim54
6 files changed, 95 insertions, 89 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 5f6b658cf..25c66e117 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1359,7 +1359,8 @@ proc getStrOrChar*(a: PNode): string =
 proc isGenericRoutine*(s: PSym): bool = 
   case s.kind
   of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter:
-    result = sfFromGeneric in s.flags
+    result = sfFromGeneric in s.flags or
+             (s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty)
   else: nil
 
 proc isRoutine*(s: PSym): bool {.inline.} =
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 163ea4136..9a40b350e 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -220,7 +220,7 @@ proc getHiddenParam(routine: PSym): PSym =
 
 proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
   result = s.kind in {skProc, skMethod, skConverter} and
-    s.owner == outerProc and not isGenericRoutine(s)
+    s.owner == outerProc
   #s.typ.callConv == ccClosure
 
 proc addClosureParam(i: PInnerContext, e: PEnv) =
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index ed842d98e..15be33261 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -91,17 +91,8 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
     addDecl(c, result)
     pushProcCon(c, result)
     # add params to scope
-    let origFormalParams = result.typ.n
-    result.typ.n = newNodeI(nkFormalParams,
-                            origFormalParams.info,
-                            origFormalParams.len)
-    result.typ.n.sons[0] = copyNode(origFormalParams.sons[0])
-    for i in 1 .. <result.typ.len:
-      let origParam = origFormalParams[i].sym
-      var param = copySym(origParam)
-      result.typ.n.sons[i] = newSymNode(param)
-      param.typ = result.typ.sons[i]
-      param.ast = origParam.ast
+    for i in 1 .. <result.typ.n.len:
+      var param = result.typ.n.sons[i].sym
       param.owner = result
       addParamOrResult(c, param, result.kind)
     # debug result.typ.n
@@ -150,6 +141,15 @@ proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
 
 proc fixupProcType(c: PContext, genericType: PType,
                    inst: TInstantiation): PType =
+  # XXX: This is starting to look suspiciously like ReplaceTypeVarsT
+  # there are few apparent differences, but maybe the code could be
+  # moved over.
+  # * the code here uses the new genericSym.position property when
+  #   doing lookups. 
+  # * the handling of tyTypeDesc seems suspicious in ReplaceTypeVarsT
+  #   typedesc params were previously handled in the second pass of
+  #   semParamList
+  # * void (nkEmpty) params doesn't seem to be stripped in ReplaceTypeVarsT
   result = genericType
   if result == nil: return
 
@@ -167,7 +167,8 @@ proc fixupProcType(c: PContext, genericType: PType,
     if genericType.sons == nil: return
     var head = 0
     for i in 0 .. <genericType.sons.len:
-      var changed = fixupProcType(c, genericType.sons[i], inst)
+      let origType = genericType.sons[i]
+      var changed = fixupProcType(c, origType, inst)
       if changed != genericType.sons[i]:
         var changed = changed.skipIntLit
         if result == genericType:
@@ -194,7 +195,11 @@ proc fixupProcType(c: PContext, genericType: PType,
         
         if result.n != nil:
           if result.n.kind == nkRecList:
-            result.n.sons[head].typ = changed
+            for son in result.n.sons:
+              if son.typ == origType:
+                son.typ = changed
+                son.sym = copySym(son.sym, true)
+                son.sym.typ = changed
           if result.n.kind == nkFormalParams:
             if i != 0:
               let origParam = result.n.sons[head].sym
@@ -205,14 +210,14 @@ proc fixupProcType(c: PContext, genericType: PType,
 
       # won't be advanced on empty (void) nodes
       inc head
-        
+  
   of tyGenericInvokation:
     result = newTypeWithSons(c, tyGenericInvokation, genericType.sons)
     for i in 1 .. <genericType.sons.len:
       result.sons[i] = fixupProcType(c, result.sons[i], inst)
     result = instGenericContainer(c, getInfoContext(-1), result)
-  else:
-    nil
+  
+  else: nil
 
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
                       info: TLineInfo): PSym =
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index bb6c646f2..2c6fc4738 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -384,7 +384,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
       # for ``{}`` we want to trigger the type mismatch in ``fitNode``:
       if r.kind != nkCurly or len(r) == 0:
         checkMinSonsLen(t, 1)
-        branch.sons[i] = fitNode(c, t.sons[0].typ, r)
+        branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r))
         inc(covered)
       else:
         # constant sets have special rules
diff --git a/tests/compile/tobjects.nim b/tests/compile/tobjects.nim
index 68705d944..06fa15583 100644
--- a/tests/compile/tobjects.nim
+++ b/tests/compile/tobjects.nim
@@ -1,52 +1,52 @@
-type

-  TBase = object of TObject

-    x, y: int

-

-  TSubclassKind = enum ka, kb, kc, kd, ke, kf

-  TSubclass = object of TBase

-    case c: TSubclassKind

-    of ka, kb, kc, kd:

-      a, b: int

-    of ke:

-      d, e, f: char

-    else: nil

-    n: bool

+type
+  TBase = object of TObject
+    x, y: int
+
+  TSubclassKind = enum ka, kb, kc, kd, ke, kf
+  TSubclass = object of TBase
+    case c: TSubclassKind
+    of ka, kb, kc, kd:
+      a, b: int
+    of ke:
+      d, e, f: char
+    else: nil
+    n: bool
 
 type
   TMyObject = object of TObject
-    case disp: range[0..4]:
+    case disp: range[0..4]
       of 0: arg: char
       of 1: s: string
       else: wtf: bool
       
 var
   x: TMyObject
-

-var

-  global: int

-

-var

-  s: string

-  r: float = 0.0

-  i: int = 500 + 400

-

-case i

-of 500..999: write(stdout, "ha!\n")

-of 1000..3000, 12: write(stdout, "ganz schön groß\n")

-of 1, 2, 3: write(stdout, "1 2 oder 3\n")

-else: write(stdout, "sollte nicht passieren\n")

-

-case readLine(stdin)

-of "Rumpf": write(stdout, "Hallo Meister!\n")

-of "Andreas": write(stdout, "Hallo Meister!\n")

-else: write(stdout, "Nicht mein Meister!\n")

-

-global = global + 1

-write(stdout, "Hallo wie heißt du? \n")

-s = readLine(stdin)

-i = 0

-while i < len(s):

-  if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n")

-  i = i + 1

-

-write(stdout, "Du heißt " & s)

+
+var
+  global: int
+
+var
+  s: string
+  r: float = 0.0
+  i: int = 500 + 400
+
+case i
+of 500..999: write(stdout, "ha!\n")
+of 1000..3000, 12: write(stdout, "ganz schön groß\n")
+of 1, 2, 3: write(stdout, "1 2 oder 3\n")
+else: write(stdout, "sollte nicht passieren\n")
+
+case readLine(stdin)
+of "Rumpf": write(stdout, "Hallo Meister!\n")
+of "Andreas": write(stdout, "Hallo Meister!\n")
+else: write(stdout, "Nicht mein Meister!\n")
+
+global = global + 1
+write(stdout, "Hallo wie heißt du? \n")
+s = readLine(stdin)
+i = 0
+while i < len(s):
+  if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n")
+  i = i + 1
+
+write(stdout, "Du heißt " & s)
diff --git a/tests/compile/toverprc.nim b/tests/compile/toverprc.nim
index 96b851fc1..22b64ed48 100644
--- a/tests/compile/toverprc.nim
+++ b/tests/compile/toverprc.nim
@@ -1,32 +1,32 @@
-# Test overloading of procs when used as function pointers

-

-import strutils

-

-proc parseInt(x: float): int {.noSideEffect.} = nil

-proc parseInt(x: bool): int {.noSideEffect.} = nil

-proc parseInt(x: float32): int {.noSideEffect.} = nil

-proc parseInt(x: int8): int {.noSideEffect.} = nil

-proc parseInt(x: TFile): int {.noSideEffect.} = nil

-proc parseInt(x: char): int {.noSideEffect.} = nil

-proc parseInt(x: int16): int {.noSideEffect.} = nil

+# Test overloading of procs when used as function pointers
+
+import strutils
+
+proc parseInt(x: float): int {.noSideEffect.} = nil
+proc parseInt(x: bool): int {.noSideEffect.} = nil
+proc parseInt(x: float32): int {.noSideEffect.} = nil
+proc parseInt(x: int8): int {.noSideEffect.} = nil
+proc parseInt(x: TFile): int {.noSideEffect.} = nil
+proc parseInt(x: char): int {.noSideEffect.} = nil
+proc parseInt(x: int16): int {.noSideEffect.} = nil
 
 proc parseInt[T](x: T): int = echo x; 34
-

-type

-  TParseInt = proc (x: string): int {.noSideEffect.}

-

-var

-  q = TParseInt(parseInt)

-  p: TParseInt = parseInt

-

-proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = 

-  result = x("123")

-  

-echo "Give a list of numbers (separated by spaces): "

-var x = stdin.readline.split.map(parseInt).max

-echo x, " is the maximum!"

-echo "another number: ", takeParseInt(parseInt)

-

+
+type
+  TParseInt = proc (x: string): int {.noSideEffect.}
+
+var
+  q = TParseInt(parseInt)
+  p: TParseInt = parseInt
+
+proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = 
+  result = x("123")
+  
+echo "Give a list of numbers (separated by spaces): "
+var x = stdin.readline.split.map(parseInt).max
+echo x, " is the maximum!"
+echo "another number: ", takeParseInt(parseInt)
+
 
 type
   TFoo[a,b] = object