summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-01-04 12:28:25 +0200
committerZahary Karadjov <zahary@gmail.com>2014-01-04 13:10:52 +0200
commit789ba107cf3bcc1a87d896fc7cbfa11e151898c2 (patch)
treea912096f7e5133f3dd08528d1499d6cd1ecec305 /compiler
parent02533c260b16ce7b16a47781d104b46b36544749 (diff)
downloadNim-789ba107cf3bcc1a87d896fc7cbfa11e151898c2.tar.gz
introduce tyFromExpr; fixes #618
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim28
-rw-r--r--compiler/ccgutils.nim5
-rw-r--r--compiler/jsgen.nim5
-rw-r--r--compiler/sem.nim8
-rw-r--r--compiler/semdata.nim4
-rw-r--r--compiler/semgnrc.nim7
-rw-r--r--compiler/semtypes.nim6
-rw-r--r--compiler/semtypinst.nim4
-rw-r--r--compiler/sigmatch.nim10
-rw-r--r--compiler/types.nim11
10 files changed, 61 insertions, 27 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index e25f10a66..2f6b6fc9f 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -339,19 +339,31 @@ type
     tyTypeClass
     tyParametricTypeClass # structured similarly to tyGenericInst
                           # lastSon is the body of the type class
-    tyBuiltInTypeClass
-    tyCompositeTypeClass
-    tyAnd
-    tyOr
-    tyNot
-    tyAnything
-    tyStatic
+    
+    tyBuiltInTypeClass # Type such as the catch-all object, tuple, seq, etc
+    
+    tyCompositeTypeClass # 
+    
+    tyAnd, tyOr, tyNot # boolean type classes such as `string|int`,`not seq`,
+                       # `Sortable and Enumable`, etc
+    
+    tyAnything # a type class matching any type
+    
+    tyStatic   # a value known at compile type (the underlying type is .base)
+    
+    tyFromExpr # This is a type representing an expression that depends
+               # on generic parameters (the exprsesion is stored in t.n)
+               # It will be converted to a real type only during generic
+               # instantiation and prior to this it has the potential to
+               # be any type.
 
 const
   tyPureObject* = tyTuple
   GcTypeKinds* = {tyRef, tySequence, tyString}
   tyError* = tyProxy # as an errornous node should match everything
-  
+
+  tyUnknownTypes* = {tyError, tyFromExpr}
+
   tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass,
                     tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything}
 
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index b07047ec4..fe349174f 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -86,9 +86,8 @@ proc getUniqueType*(key: PType): PType =
     if result == nil:
       gCanonicalTypes[k] = key
       result = key
-  of tyTypeDesc, tyTypeClasses:
-    internalError("value expected, but got a type")
-  of tyGenericParam, tyStatic:
+  of tyTypeDesc, tyTypeClasses, tyGenericParam,
+     tyFromExpr, tyStatic:
     internalError("GetUniqueType")
   of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter:
     result = getUniqueType(lastSon(key))
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index ddfc189dd..b4e696d0a 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -129,8 +129,9 @@ proc mapType(typ: PType): TJSTypeKind =
      tyVarargs:
     result = etyObject
   of tyNil: result = etyNull
-  of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone, 
-     tyForward, tyEmpty, tyExpr, tyStmt, tyStatic, tyTypeDesc, tyTypeClasses: 
+  of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation,
+     tyNone, tyFromExpr, tyForward, tyEmpty,
+     tyExpr, tyStmt, tyStatic, tyTypeDesc, tyTypeClasses:
     result = etyNone
   of tyProc: result = etyProc
   of tyCString: result = etyString
diff --git a/compiler/sem.nim b/compiler/sem.nim
index e9c2de657..b53e7335c 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -293,6 +293,14 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
     localError(n.info, errConstExprExpected)
     result = nn
 
+type
+  TSemGenericFlag = enum
+    withinBind, withinTypeDesc, withinMixin
+  TSemGenericFlags = set[TSemGenericFlag]
+
+proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags,
+                    ctx: var TIntSet): PNode
+
 include semtypes, semtempl, semgnrc, semstmts, semexprs
 
 proc addCodeForGenerics(c: PContext, n: PNode) =
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 3020a6af1..2e920d9cf 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -214,6 +214,10 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
   let sym = newSym(skType, idAnon, getCurrOwner(), info).linkTo(typedesc)
   return newSymNode(sym, info)
 
+proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
+  result = newTypeS(tyFromExpr, c)
+  result.n = n
+
 proc makeAndType*(c: PContext, t1, t2: PType): PType =
   result = newTypeS(tyAnd, c)
   result.sons = @[t1, t2]
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index 9f477492c..b40e86cbf 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -17,11 +17,6 @@
 
 # included from sem.nim
 
-type
-  TSemGenericFlag = enum
-    withinBind, withinTypeDesc, withinMixin
-  TSemGenericFlags = set[TSemGenericFlag]
-
 proc getIdentNode(n: PNode): PNode =
   case n.kind
   of nkPostfix: result = getIdentNode(n.sons[1])
@@ -31,8 +26,6 @@ proc getIdentNode(n: PNode): PNode =
     illFormedAst(n)
     result = n
   
-proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags,
-                    ctx: var TIntSet): PNode
 proc semGenericStmtScope(c: PContext, n: PNode, 
                          flags: TSemGenericFlags,
                          ctx: var TIntSet): PNode = 
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 3ce504d2c..79147ab82 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -988,6 +988,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
           result.rawAddSon(semTypeNode(c, n.sons[i], nil))
     else: result = semGeneric(c, n, s, prev)
   of nkIdent, nkDotExpr, nkAccQuoted: 
+    if n.kind == nkDotExpr:
+      let head = qualifiedLookUp(c, n[0], {checkAmbiguity, checkUndeclared})
+      if head.kind in {skType}:
+        var toBind = initIntSet()
+        var preprocessed = semGenericStmt(c, n, {}, toBind)
+        return makeTypeFromExpr(c, preprocessed)
     var s = semTypeIdent(c, n)
     if s.typ == nil: 
       if s.kind != skError: localError(n.info, errTypeExpected)
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index ec56f75e4..75d266679 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -287,6 +287,10 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
   of tyGenericBody:
     internalError(cl.info, "ReplaceTypeVarsT: tyGenericBody" )
     result = replaceTypeVarsT(cl, lastSon(t))
+  of tyFromExpr:
+    var n = prepareNode(cl, t.n)
+    n = cl.c.semExpr(cl.c, n, {})
+    result = n.typ.skipTypes({tyTypeDesc})
   of tyInt:
     result = skipIntLit(t)
     # XXX now there are also float literals
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 2e314d115..43f1cded9 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -665,10 +665,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   of tyGenericInst:
     let roota = a.skipGenericAlias
     let rootf = f.skipGenericAlias
-    if a.kind == tyGenericInst and roota.base == rootf.base:
+    if a.kind == tyGenericInst and roota.base == rootf.base :
       for i in 1 .. rootf.sonsLen-2:
-        result = typeRel(c, rootf.sons[i], roota.sons[i])
-        if result == isNone: return
+        let ff = rootf.sons[i]
+        let aa = roota.sons[i]
+        result = typeRel(c, ff, aa)
+        if result == isNone: return        
+        if ff.kind == tyRange and result != isEqual: return isNone
+
       result = isGeneric
     else:
       result = typeRel(c, lastSon(f), a)
diff --git a/compiler/types.nim b/compiler/types.nim
index 68e816c13..dd808915e 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -10,7 +10,7 @@
 # this module contains routines for accessing and iterating over types
 
 import 
-  intsets, ast, astalgo, trees, msgs, strutils, platform
+  intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
 
 proc firstOrd*(t: PType): BiggestInt
 proc lastOrd*(t: PType): BiggestInt
@@ -406,7 +406,7 @@ const
     "bignum", "const ",
     "!", "varargs[$1]", "iter[$1]", "Error Type", "TypeClass",
     "ParametricTypeClass", "BuiltInTypeClass", "CompositeTypeClass",
-    "and", "or", "not", "any", "static"]
+    "and", "or", "not", "any", "static", "TypeFromExpr"]
 
 proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
   var t = typ
@@ -448,6 +448,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
   of tyExpr:
     InternalAssert t.len == 0
     result = "expr"
+  of tyFromExpr:
+    result = renderTree(t.n)
   of tyArray: 
     if t.sons[0].kind == tyRange: 
       result = "array[" & rangeToStr(t.sons[0].n) & ", " &
@@ -837,7 +839,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
   of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
      tyInt..tyBigNum, tyStmt, tyExpr:
     result = sameFlags(a, b)
-  of tyStatic:
+  of tyStatic, tyFromExpr:
     result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b)
   of tyObject:
     ifFastObjectTypeCheckFailed(a, b):
@@ -1018,7 +1020,8 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
     result = taField in flags
   of tyTypeClasses:
     result = true
-  of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation:
+  of tyGenericBody, tyGenericParam, tyGenericInvokation,
+     tyNone, tyForward, tyFromExpr:
     result = false
   of tyNil:
     result = kind == skConst