diff options
author | Zahary Karadjov <zahary@gmail.com> | 2014-01-04 12:28:25 +0200 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2014-01-04 13:10:52 +0200 |
commit | 789ba107cf3bcc1a87d896fc7cbfa11e151898c2 (patch) | |
tree | a912096f7e5133f3dd08528d1499d6cd1ecec305 /compiler | |
parent | 02533c260b16ce7b16a47781d104b46b36544749 (diff) | |
download | Nim-789ba107cf3bcc1a87d896fc7cbfa11e151898c2.tar.gz |
introduce tyFromExpr; fixes #618
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 28 | ||||
-rw-r--r-- | compiler/ccgutils.nim | 5 | ||||
-rw-r--r-- | compiler/jsgen.nim | 5 | ||||
-rw-r--r-- | compiler/sem.nim | 8 | ||||
-rw-r--r-- | compiler/semdata.nim | 4 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 7 | ||||
-rw-r--r-- | compiler/semtypes.nim | 6 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 4 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 10 | ||||
-rw-r--r-- | compiler/types.nim | 11 |
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 |