diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-04-06 18:14:12 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-04-06 18:14:12 +0300 |
commit | e941a147670442e706d1777f4a1bc368d0cbcdba (patch) | |
tree | 26a5ebae52db73c297b40b560ab61d21ae0e4fb9 /compiler | |
parent | efb53233cb3434b94b28060f0a642c51049cb09d (diff) | |
download | Nim-e941a147670442e706d1777f4a1bc368d0cbcdba.tar.gz |
completing the "types as first class values" reform
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/msgs.nim | 3 | ||||
-rwxr-xr-x | compiler/sem.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 83 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 2 |
4 files changed, 50 insertions, 40 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 87f5e5650..a0058ebe3 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -72,7 +72,7 @@ type errNoPragmasAllowedForX, errNoGenericParamsAllowedForX, errInvalidParamKindX, errDefaultArgumentInvalid, errNamedParamHasToBeIdent, errNoReturnTypeForX, errConvNeedsOneArg, errInvalidPragmaX, - errXNotAllowedHere, errInvalidControlFlowX, errATypeHasNoValue, + errXNotAllowedHere, errInvalidControlFlowX, errXisNoType, errCircumNeedsPointer, errInvalidExpression, errInvalidExpressionX, errEnumHasNoValueX, errNamedExprExpected, errNamedExprNotAllowed, errXExpectsOneTypeParam, @@ -275,7 +275,6 @@ const errInvalidPragmaX: "invalid pragma: $1", errXNotAllowedHere: "$1 not allowed here", errInvalidControlFlowX: "invalid control flow: $1", - errATypeHasNoValue: "a type has no value", errXisNoType: "invalid type: \'$1\'", errCircumNeedsPointer: "'[]' needs a pointer or reference type", errInvalidExpression: "invalid expression", diff --git a/compiler/sem.nim b/compiler/sem.nim index e27f20503..8afbe3c51 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -21,7 +21,7 @@ proc semPass*(): TPass type TExprFlag = enum - efAllowType, efLValue, efWantIterator, efInTypeof + efLValue, efWantIterator, efInTypeof TExprFlags = set[TExprFlag] proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index bca27a43d..d2a19cb86 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -10,7 +10,16 @@ # this module does the semantic checking for expressions # included from sem.nim -proc semExprOrTypedesc(c: PContext, n: PNode): PNode +proc restoreOldStyleType(n: PNode) = + # XXX: semExprWithType used to return the same type + # for nodes such as (100) or (int). + # This is inappropriate. The type of the first expression + # should be "int", while the type of the second one should + # be typedesc(int). + # + # This is strictly for backward compatibility until + # the transition to types as first-class values is complete. + n.typ = n.typ.skipTypes({tyTypeDesc}) proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode = markUsed(n, s) @@ -108,10 +117,9 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = if s.ast == nil: InternalError(n.info, "no default for") result = semExpr(c, s.ast) of skType: - if efAllowType notin flags: - GlobalError(n.info, errATypeHasNoValue) markUsed(n, s) result = newSymNode(s, n.info) + result.typ = makeTypeDesc(c, s.typ) else: markUsed(n, s) result = newSymNode(s, n.info) @@ -206,7 +214,8 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = if sonsLen(n) != 2: GlobalError(n.info, errXExpectsTypeOrValue, opToStr[m]) else: - n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) + n.sons[1] = semExprWithType(c, n.sons[1]) + restoreOldStyleType(n.sons[1]) var typ = skipTypes(n.sons[1].typ, abstractVarRange) case typ.Kind of tySequence, tyString, tyOpenArray: @@ -219,15 +228,21 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = result = n proc semSizeof(c: PContext, n: PNode): PNode = - if sonsLen(n) != 2: GlobalError(n.info, errXExpectsTypeOrValue, "sizeof") - else: n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) + if sonsLen(n) != 2: + GlobalError(n.info, errXExpectsTypeOrValue, "sizeof") + else: + n.sons[1] = semExprWithType(c, n.sons[1]) + restoreOldStyleType(n.sons[1]) + n.typ = getSysType(tyInt) result = n proc semOf(c: PContext, n: PNode): PNode = if sonsLen(n) == 3: - n.sons[1] = semExprWithType(c, n.sons[1], {efAllowType}) - n.sons[2] = semExprWithType(c, n.sons[2], {efAllowType}) + n.sons[1] = semExprWithType(c, n.sons[1]) + n.sons[2] = semExprWithType(c, n.sons[2]) + restoreOldStyleType(n.sons[1]) + restoreOldStyleType(n.sons[2]) var a = skipTypes(n.sons[1].typ, abstractPtrs) var b = skipTypes(n.sons[2].typ, abstractPtrs) if b.kind != tyObject or a.kind != tyObject: @@ -251,31 +266,16 @@ proc semIs(c: PContext, n: PNode): PNode = else: GlobalError(n.info, errXExpectsTwoArguments, "is") -proc semExprOrTypedesc(c: PContext, n: PNode): PNode = - # XXX: Currently, semExprWithType will return the same type - # for nodes such as (100) or (int). - # This is inappropriate. The type of the first expression - # should be "int", while the type of the second one should - # be typeDesc(int). - # Ideally, this should be fixed in semExpr, but right now - # there are probably users that depend on the present behavior. - # XXX: Investigate current uses of efAllowType and fix them to - # work with tyTypeDesc. - result = semExprWithType(c, n, {efAllowType}) - if result.kind == nkSym and result.sym.kind == skType and - result.typ.kind != tyTypeDesc: - result.typ = makeTypeDesc(c, result.typ) - proc semOpAux(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkExprEqExpr and sonsLen(a) == 2: var info = a.sons[0].info a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info) - a.sons[1] = semExprOrTypedesc(c, a.sons[1]) + a.sons[1] = semExprWithType(c, a.sons[1]) a.typ = a.sons[1].typ else: - n.sons[i] = semExprOrTypedesc(c, a) + n.sons[i] = semExprWithType(c, a) proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: @@ -754,13 +754,15 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = return semSym(c, n, s, flags) checkSonsLen(n, 2) - n.sons[0] = semExprWithType(c, n.sons[0], {efAllowType} + flags) + n.sons[0] = semExprWithType(c, n.sons[0], flags) + restoreOldStyleType(n.sons[0]) var i = considerAcc(n.sons[1]) - var ty = n.sons[0].Typ + var ty = n.sons[0].typ var f: PSym = nil result = nil if isTypeExpr(n.sons[0]): - if ty.kind == tyEnum: + case ty.kind + of tyEnum: # look up if the identifier belongs to the enum: while ty != nil: f = getSymFromList(ty.n, i) @@ -771,10 +773,22 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result.info = n.info result.typ = ty markUsed(n, f) - return - elif efAllowType notin flags: - GlobalError(n.sons[0].info, errATypeHasNoValue) + return + of tyGenericInst: + assert ty.sons[0].kind == tyGenericBody + let tbody = ty.sons[0] + for s in countup(0, tbody.len-2): + let tParam = tbody.sons[s] + assert tParam.kind == tyGenericParam + if tParam.sym.name == i: + let foundTyp = makeTypeDesc(c, ty.sons[s + 1]) + return newSymNode(copySym(tParam.sym).linkTo(foundTyp), n.info) return + else: + # echo "TYPE FIELD ACCESS" + # debug ty + return + # XXX: This is probably not relevant any more # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": ty = n.sons[0].Typ @@ -854,14 +868,14 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result.add(x[0]) return checkMinSonsLen(n, 2) - n.sons[0] = semExprOrTypedesc(c, n.sons[0]) + n.sons[0] = semExprWithType(c, n.sons[0]) var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) case arr.kind of tyArray, tyOpenArray, tyArrayConstr, tySequence, tyString, tyCString: checkSonsLen(n, 2) n.sons[0] = makeDeref(n.sons[0]) for i in countup(1, sonsLen(n) - 1): - n.sons[i] = semExprWithType(c, n.sons[i], flags - {efAllowType}) + n.sons[i] = semExprWithType(c, n.sons[i], flags) var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(tyInt) var arg = IndexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) if arg != nil: @@ -1282,9 +1296,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = nil of nkNilLit: result.typ = getSysType(tyNil) - of nkType: - if not (efAllowType in flags): GlobalError(n.info, errATypeHasNoValue) - n.typ = semTypeNode(c, n, nil) of nkIntLit: if result.typ == nil: result.typ = getSysType(tyInt) of nkInt8Lit: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 8479810d2..be5bd95d9 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -693,7 +693,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkTypeOfExpr: # for ``type(countup(1,3))``, see ``tests/ttoseq``. checkSonsLen(n, 1) - result = semExprWithType(c, n.sons[0], {efInTypeof, efAllowType}).typ + result = semExprWithType(c, n.sons[0], {efInTypeof}).typ of nkPar: if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: GlobalError(n.info, errTypeExpected) |