diff options
author | Araq <rumpf_a@web.de> | 2012-06-28 08:33:25 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-06-28 08:33:25 +0200 |
commit | 2900ceae3580a9f1e83b500cf1abcdfe77762cad (patch) | |
tree | 1279b1199dcd7f1af2949355e692b1857960a0ee /compiler | |
parent | b5d34242ca7156ec702f8e63a01c9cd059d28e5f (diff) | |
download | Nim-2900ceae3580a9f1e83b500cf1abcdfe77762cad.tar.gz |
changed integer promotion rules; added math.fmod
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 7 | ||||
-rwxr-xr-x | compiler/magicsys.nim | 23 | ||||
-rwxr-xr-x | compiler/msgs.nim | 8 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 24 | ||||
-rwxr-xr-x | compiler/semfold.nim | 2 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 56 | ||||
-rwxr-xr-x | compiler/transf.nim | 4 |
7 files changed, 65 insertions, 59 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index d14bef9f7..511d6f116 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -334,12 +334,10 @@ type tfEnumHasHoles, # enum cannot be mapped into a range tfShallow, # type can be shallow copied on assignment tfThread, # proc type is marked as ``thread`` - tfUniIntLit # type represents literal value that could be either - # singed or unsigned integer (e.g. 100) - tfFromGeneric # type is an instantiation of a generic; this is needed + tfFromGeneric, # type is an instantiation of a generic; this is needed # because for instantiations of objects, structural # type equality has to be used - tfAll # type class requires all constraints to be met (default) + tfAll, # type class requires all constraints to be met (default) tfAny # type class requires any constraint to be met TTypeFlags* = set[TTypeFlag] @@ -587,6 +585,7 @@ type # for range types a nkRange node # for record types a nkRecord node # for enum types a list of symbols + # for tyInt it can be the int literal # else: unused destructor*: PSym # destructor. warning: nil here may not necessary # mean that there is no destructor. diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index a69b40fbf..09c99c027 100755 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -24,7 +24,7 @@ proc FinishSystem*(tab: TStrTable) proc getSysSym*(name: string): PSym # implementation -var +var gSysTypes: array[TTypeKind, PType] compilerprocs: TStrTable @@ -73,7 +73,26 @@ proc getSysType(kind: TTypeKind): PType = if result.kind != kind: InternalError("wanted: " & $kind & " got: " & $result.kind) if result == nil: InternalError("type not found: " & $kind) - + +when false: + var + intTypeCache: array[-5..64, PType] + + proc getIntLitType*(literal: PNode): PType = + # we cache some common integer literal types for performance: + let value = literal.intVal + if value >= low(intTypeCache) and value <= high(intTypeCache): + result = intTypeCache[value.int] + if result == nil: + let ti = getSysType(tyInt) + result = copyType(ti, ti.owner, false) + result.n = literal + intTypeCache[value.int] = result + else: + let ti = getSysType(tyInt) + result = copyType(ti, ti.owner, false) + result.n = literal + proc getCompilerProc(name: string): PSym = var ident = getIdent(name, hashIgnoreStyle(name)) result = StrTableGet(compilerprocs, ident) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 0b79a68a2..53438c722 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -102,7 +102,7 @@ type warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored, warnXisPassedToProcVar, warnAnalysisLoophole, - warnDifferentHeaps, warnWriteToForeignHeap, + warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitNarrowing, warnUser, hintSuccess, hintSuccessX, hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, @@ -345,6 +345,7 @@ const warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]", warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]", warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]", + warnImplicitNarrowing: "implicit narrowing conversion: '$1'", warnUser: "$1 [User]", hintSuccess: "operation successful [Success]", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", @@ -362,13 +363,14 @@ const hintUser: "$1 [User]"] const - WarningsToStr*: array[0..16, string] = ["CannotOpenFile", "OctalEscape", + WarningsToStr*: array[0..17, string] = ["CannotOpenFile", "OctalEscape", "XIsNeverRead", "XmightNotBeenInit", "Deprecated", "ConfigDeprecated", "SmallLshouldNotBeUsed", "UnknownMagic", "RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported", "CommentXIgnored", "XisPassedToProcVar", - "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "User"] + "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", + "ImplicitNarrowing,", "User"] HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 00acbbe65..501b7ed72 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1285,20 +1285,6 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = GlobalError(n.info, errInvalidExpressionX, renderTree(a, {renderNoComments})) -proc uniIntType(kind: TTypeKind): PType = - result = getSysType(kind).copyType(getCurrOwner(), true) - result.flags.incl(tfUniIntLit) - -template memoize(e: expr): expr = - var `*guard` {.global.} = false - var `*memo` {.global.} : type(e) - - if not `*guard`: - `*memo` = e - `*guard` = true - - `*memo` - proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = n if gCmd == cmdIdeTools: suggestExpr(c, n) @@ -1319,15 +1305,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ == nil: let i = result.intVal if i >= low(int32) and i <= high(int32): - if i >= 0: - result.typ = uniIntType(tyInt).memoize - else: - result.typ = getSysType(tyInt) + result.typ = getSysType(tyInt) else: - if i >= 0: - result.typ = uniIntType(tyInt64).memoize - else: - result.typ = getSysType(tyInt64) + result.typ = getSysType(tyInt64) of nkInt8Lit: if result.typ == nil: result.typ = getSysType(tyInt8) of nkInt16Lit: diff --git a/compiler/semfold.nim b/compiler/semfold.nim index f67e58e2f..66d7e98fc 100755 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -13,7 +13,7 @@ import strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times, nversion, platform, math, msgs, os, condsyms, idents, renderer, types, - commands + commands, magicsys proc getConstExpr*(m: PSym, n: PNode): PNode # evaluates the constant expression or returns nil if it is no constant diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 7e985e981..7a5d959df 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -159,16 +159,29 @@ proc concreteType(mapping: TIdTable, t: PType): PType = proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = if a.kind == f.kind: result = isEqual - else: + else: var k = skipTypes(a, {tyRange}).kind if k == f.kind: result = isSubtype - elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv - elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv - elif f.kind in {tyUInt..tyUInt64} and k == tyInt and tfUniIntLit in a.flags: + elif k == tyInt: + # and a.n != nil and a.n.intVal >= firstOrd(f) and + # a.n.intVal <= lastOrd(f): + # integer literal in the proper range; we want ``i16 + 4`` to stay an + # ``int16`` operation so we declare the ``4`` pseudo-equal to int16 result = isIntConv elif k >= min and k <= max: result = isConvertible else: result = isNone - + #elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv + #elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv + +proc isConvertibleToRange(f, a: PType): bool = + # be less picky for tyRange, as that it is used for array indexing: + if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and + a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}: + result = true + elif f.kind in {tyFloat..tyFloat128} and + a.kind in {tyFloat..tyFloat128}: + result = true + proc handleFloatRange(f, a: PType): TTypeRelation = if a.kind == f.kind: result = isEqual @@ -227,10 +240,10 @@ proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation = else: nil if tfAny in f.flags: - if match == true: + if match: return isGeneric else: - if match == false: + if not match: return isNone # if the loop finished without returning, either all constraints matched @@ -287,9 +300,9 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = if a.kind == tyGenericInst and skipTypes(f, {tyVar}).kind notin { tyGenericBody, tyGenericInvokation, - tyGenericParam, tyTypeClass }: + tyGenericParam, tyTypeClass}: return typeRel(mapping, f, lastSon(a)) - if a.kind == tyVar and f.kind != tyVar: + if a.kind == tyVar and f.kind != tyVar: return typeRel(mapping, f, a.sons[0]) case f.kind of tyEnum: @@ -302,18 +315,20 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = if a.kind == f.kind: result = typeRel(mapping, base(a), base(f)) if result < isGeneric: result = isNone - elif skipTypes(f, {tyRange}).kind == a.kind: + elif skipTypes(f, {tyRange}).kind == a.kind: + result = isIntConv + elif isConvertibleToRange(skipTypes(f, {tyRange}), a): result = isConvertible # a convertible to f of tyInt: result = handleRange(f, a, tyInt8, tyInt32) of tyInt8: result = handleRange(f, a, tyInt8, tyInt8) of tyInt16: result = handleRange(f, a, tyInt8, tyInt16) - of tyInt32: result = handleRange(f, a, tyInt, tyInt32) + of tyInt32: result = handleRange(f, a, tyInt8, tyInt32) of tyInt64: result = handleRange(f, a, tyInt, tyInt64) - of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32) - of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8) - of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16) - of tyUInt32: result = handleRange(f, a, tyUInt, tyUInt32) - of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64) + of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32) + of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8) + of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16) + of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32) + of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64) of tyFloat: result = handleFloatRange(f, a) of tyFloat32: result = handleFloatRange(f, a) of tyFloat64: result = handleFloatRange(f, a) @@ -789,12 +804,3 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = # use default value: setSon(m.call, formal.position + 1, copyTree(formal.ast)) inc(f) - - when false: - if sfSystemModule notin c.module.flags: - if fileInfoIdx("temp.nim") == c.module.info.fileIndex: - echo "########################" - echo m.call.renderTree - for i in 1..m.call.len-1: - debug m.call[i].typ - diff --git a/compiler/transf.nim b/compiler/transf.nim index f6e87e828..7c2353c54 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -12,7 +12,7 @@ # # * inlines iterators # * inlines constants -# * performes contant folding +# * performes constant folding # * converts "continue" to "break" # * introduces method dispatchers # * performs lambda lifting for closure support @@ -401,7 +401,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode = result = transformSons(c, n) else: # generate a range check: - if (dest.kind == tyInt64) or (source.kind == tyInt64): + if dest.kind == tyInt64 or source.kind == tyInt64: result = newTransNode(nkChckRange64, n, 3) else: result = newTransNode(nkChckRange, n, 3) |