changed integer promotion rules; breaks bootstrapping and lots of code

This commit is contained in:
Araq 2012-07-08 21:03:47 +02:00
commit 4fbba0a65a
42 changed files with 643 additions and 261 deletions

View file

@ -224,7 +224,8 @@ type
sfMainModule, # module is the main module
sfSystemModule, # module is the system module
sfNoReturn, # proc never returns (an exit proc)
sfAddrTaken, # the variable's address is taken (ex- or implicitely)
sfAddrTaken, # the variable's address is taken (ex- or implicitely);
# *OR*: a proc is indirectly called (used as first class)
sfCompilerProc, # proc is a compiler proc, that is a C proc that is
# needed for the code generator
sfProcvar, # proc can be passed to a proc var

View file

@ -1037,8 +1037,9 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
InitLocExpr(p, e.sons[1], a)
var t = skipTypes(e.sons[1].typ, abstractVarRange)
case t.kind
of tyInt..tyInt64:
putIntoDest(p, d, e.typ, ropecg(p.module, "#reprInt($1)", [rdLoc(a)]))
of tyInt..tyInt64, tyUInt..tyUInt64:
putIntoDest(p, d, e.typ,
ropecg(p.module, "#reprInt((NI64)$1)", [rdLoc(a)]))
of tyFloat..tyFloat128:
putIntoDest(p, d, e.typ, ropecg(p.module, "#reprFloat($1)", [rdLoc(a)]))
of tyBool:

View file

@ -1066,7 +1066,8 @@ proc createVar(p: var TProc, typ: PType, indirect: bool): PRope =
result = nil
proc isIndirect(v: PSym): bool =
result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject)
result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject) and
v.kind notin {skProc, skConverter, skMethod, skIterator}
proc genVarInit(p: var TProc, v: PSym, n: PNode, r: var TCompRes) =
var

View file

@ -74,24 +74,51 @@ proc getSysType(kind: TTypeKind): PType =
InternalError("wanted: " & $kind & " got: " & $result.kind)
if result == nil: InternalError("type not found: " & $kind)
when false:
var
intTypeCache: array[-5..64, PType]
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:
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 setIntLitType*(result: PNode) =
let i = result.intVal
case platform.IntSize
of 8: result.typ = getIntLitType(result)
of 4:
if i >= low(int32) and i <= high(int32):
result.typ = getIntLitType(result)
else:
result.typ = getSysType(tyInt64)
of 2:
if i >= low(int16) and i <= high(int16):
result.typ = getIntLitType(result)
elif i >= low(int32) and i <= high(int32):
result.typ = getSysType(tyInt32)
else:
result.typ = getSysType(tyInt64)
of 1:
# 8 bit CPUs are insane ...
if i >= low(int8) and i <= high(int8):
result.typ = getIntLitType(result)
elif i >= low(int16) and i <= high(int16):
result.typ = getSysType(tyInt16)
elif i >= low(int32) and i <= high(int32):
result.typ = getSysType(tyInt32)
else:
result.typ = getSysType(tyInt64)
else: InternalError(result.info, "invalid int size")
proc getCompilerProc(name: string): PSym =
var ident = getIdent(name, hashIgnoreStyle(name))

79
compiler/saturate.nim Normal file
View file

@ -0,0 +1,79 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Saturated arithmetic routines. XXX Make part of the stdlib?
proc `|+|`*(a, b: biggestInt): biggestInt =
## saturated addition.
result = a +% b
if (result xor a) >= 0'i64 or (result xor b) >= 0'i64:
return result
if a < 0 or b < 0:
result = low(result)
else:
result = high(result)
proc `|-|`*(a, b: biggestInt): biggestInt =
result = a -% b
if (result xor a) >= 0'i64 or (result xor not b) >= 0'i64:
return result
if b > 0:
result = low(result)
else:
result = high(result)
proc `|abs|`*(a: biggestInt): biggestInt =
if a != low(a):
if a >= 0: result = a
else: result = -a
else:
result = low(a)
proc `|div|`*(a, b: biggestInt): biggestInt =
# (0..5) div (0..4) == (0..5) div (1..4) == (0 div 4) .. (5 div 1)
if b == 0'i64:
# make the same as ``div 1``:
result = a
elif a == low(a) and b == -1'i64:
result = high(result)
else:
result = a div b
proc `|mod|`*(a, b: biggestInt): biggestInt =
if b == 0'i64:
result = a
else:
result = a mod b
proc `|*|`*(a, b: biggestInt): biggestInt =
var
resAsFloat, floatProd: float64
result = a *% b
floatProd = toBiggestFloat(a) # conversion
floatProd = floatProd * toBiggestFloat(b)
resAsFloat = toBiggestFloat(result)
# Fast path for normal case: small multiplicands, and no info
# is lost in either method.
if resAsFloat == floatProd: return result
# Somebody somewhere lost info. Close enough, or way off? Note
# that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
# The difference either is or isn't significant compared to the
# true value (of which floatProd is a good approximation).
# abs(diff)/abs(prod) <= 1/32 iff
# 32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
return result
if floatProd >= 0.0:
result = high(result)
else:
result = low(result)

View file

@ -18,8 +18,8 @@ proc sameMethodDispatcher(a, b: PSym): bool =
if aa.kind == nkSym and bb.kind == nkSym and aa.sym == bb.sym:
result = true
proc resolveOverloads(c: PContext, n, orig: PNode,
filter: TSymKinds): TCandidate =
proc resolveOverloads(c: PContext, n, orig: PNode,
filter: TSymKinds): TCandidate =
var initialBinding: PNode
var f = n.sons[0]
if f.kind == nkBracketExpr:
@ -67,9 +67,17 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
not sameMethodDispatcher(best.calleeSym, alt.calleeSym):
if best.state != csMatch:
InternalError(n.info, "x.state is not csMatch")
#writeMatches(best)
#writeMatches(alt)
var args = "("
for i in countup(1, sonsLen(n) - 1):
if i > 1: add(args, ", ")
add(args, typeToString(n.sons[i].typ))
add(args, ")")
LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [
getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
best.calleeSym.Name.s])
args])
proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
assert x.state == csMatch

View file

@ -213,6 +213,11 @@ proc markUsed*(n: PNode, s: PSym) =
if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s)
if sfError in s.flags: LocalError(n.info, errWrongSymbolX, s.name.s)
proc markIndirect*(c: PContext, s: PSym) =
if s.kind in {skProc, skConverter, skMethod, skIterator}:
incl(s.flags, sfAddrTaken)
# XXX add to 'c' for global analysis
proc useSym*(sym: PSym): PNode =
result = newSymNode(sym)
markUsed(result, sym)

View file

@ -74,8 +74,10 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
smoduleId != c.module.id and smoduleId != c.friendModule.id:
LocalError(n.info, errXCannotBePassedToProcVar, s.name.s)
result = symChoice(c, n, s)
if result.kind == nkSym and isGenericRoutine(result.sym):
LocalError(n.info, errInstantiateXExplicitely, s.name.s)
if result.kind == nkSym:
markIndirect(c, result.sym)
if isGenericRoutine(result.sym):
LocalError(n.info, errInstantiateXExplicitely, s.name.s)
of skConst:
markUsed(n, s)
case skipTypes(s.typ, abstractInst).kind
@ -129,10 +131,11 @@ proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
if diff == high(int):
GlobalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [
src.typeToString, castDest.typeToString])
const
IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
proc checkConvertible(info: TLineInfo, castDest, src: PType) =
const
IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
if sameType(castDest, src) and castDest.sym == src.sym:
# don't annoy conversions that may be needed on another processor:
if castDest.kind notin {tyInt..tyUInt64, tyNil}:
@ -177,8 +180,8 @@ proc isCastable(dst, src: PType): bool =
result = false
else:
result = (ds >= ss) or
(skipTypes(dst, abstractInst).kind in {tyInt..tyFloat128}) or
(skipTypes(src, abstractInst).kind in {tyInt..tyFloat128})
(skipTypes(dst, abstractInst).kind in IntegralTypes) or
(skipTypes(src, abstractInst).kind in IntegralTypes)
proc semConv(c: PContext, n: PNode, s: PSym): PNode =
if sonsLen(n) != 2: GlobalError(n.info, errConvNeedsOneArg)
@ -190,10 +193,12 @@ proc semConv(c: PContext, n: PNode, s: PSym): PNode =
if op.kind != nkSymChoice:
checkConvertible(result.info, result.typ, op.typ)
else:
for i in countup(0, sonsLen(op) - 1):
if sameType(result.typ, op.sons[i].typ):
markUsed(n, op.sons[i].sym)
return op.sons[i]
for i in countup(0, sonsLen(op) - 1):
let it = op.sons[i]
if sameType(result.typ, it.typ):
markUsed(n, it.sym)
markIndirect(c, it.sym)
return it
localError(n.info, errUseQualifier, op.sons[0].sym.name.s)
proc semCast(c: PContext, n: PNode): PNode =
@ -222,7 +227,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
n.typ = getSysType(tyInt)
of tyArrayConstr, tyArray:
n.typ = n.sons[1].typ.sons[0] # indextype
of tyInt..tyInt64, tyChar, tyBool, tyEnum:
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
n.typ = n.sons[1].typ
else: GlobalError(n.info, errInvalidArgForX, opToStr[m])
result = n
@ -498,6 +503,24 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
if n.kind notin nkCallKinds or n.sons[0].kind != nkSym: return
var callee = n.sons[0].sym
# constant folding that is necessary for correctness of semantic pass:
if callee.magic != mNone and callee.magic in ctfeWhitelist and n.typ != nil:
var call = newNodeIT(nkCall, n.info, n.typ)
call.add(n.sons[0])
var allConst = true
for i in 1 .. < n.len:
let a = getConstExpr(c.module, n.sons[i])
if a != nil: call.add(a)
else:
allConst = false
call.add(n.sons[i])
if allConst:
result = semfold.getConstExpr(c.module, call)
if result.isNil: result = n
else: return result
result.typ = semfold.getIntervalType(callee.magic, call)
# optimization pass: not necessary for correctness of the semantic pass
if {sfNoSideEffect, sfCompileTime} * callee.flags != {} and
{sfForward, sfImportc} * callee.flags == {}:
if sfCompileTime notin callee.flags and
@ -901,7 +924,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal}).kind in
{tyInt..tyInt64}:
var idx = getOrdValue(n.sons[1])
if (idx >= 0) and (idx < sonsLen(arr)): n.typ = arr.sons[int(idx)]
if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
else: GlobalError(n.info, errInvalidIndexValueForTuple)
else:
GlobalError(n.info, errIndexTypesDoNotMatch)
@ -1301,15 +1324,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
nil
of nkNilLit:
result.typ = getSysType(tyNil)
of nkIntLit:
# XXX this is stupid:
if result.typ == nil:
let i = result.intVal
if i >= low(int32) and i <= high(int32):
result.typ = getSysType(tyInt)
else:
result.typ = getSysType(tyInt64)
of nkInt8Lit:
of nkIntLit:
if result.typ == nil: setIntLitType(result)
of nkInt8Lit:
if result.typ == nil: result.typ = getSysType(tyInt8)
of nkInt16Lit:
if result.typ == nil: result.typ = getSysType(tyInt16)

View file

@ -13,7 +13,7 @@
import
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
commands, magicsys
commands, magicsys, saturate
proc getConstExpr*(m: PSym, n: PNode): PNode
# evaluates the constant expression or returns nil if it is no constant
@ -26,12 +26,19 @@ proc newStrNodeT*(strVal: string, n: PNode): PNode
# implementation
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
if skipTypes(n.typ, abstractVarRange).kind == tyChar:
result = newIntNode(nkCharLit, intVal)
else:
proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
case skipTypes(n.typ, abstractVarRange).kind
of tyInt:
result = newIntNode(nkIntLit, intVal)
result.typ = n.typ
result.typ = getIntLitType(result)
# hrm, this is not correct: 1 + high(int) shouldn't produce tyInt64 ...
#setIntLitType(result)
of tyChar:
result = newIntNode(nkCharLit, intVal)
result.typ = n.typ
else:
result = newIntNode(nkIntLit, intVal)
result.typ = n.typ
result.info = n.info
proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode =
@ -67,6 +74,150 @@ proc ordinalValToString(a: PNode): string =
else:
result = $x
proc isFloatRange(t: PType): bool {.inline.} =
result = t.kind == tyRange and t.sons[0].kind in {tyFloat..tyFloat128}
proc isIntRange(t: PType): bool {.inline.} =
result = t.kind == tyRange and t.sons[0].kind in {
tyInt..tyInt64, tyUInt8..tyUInt32}
proc pickIntRange(a, b: PType): PType =
if isIntRange(a): result = a
elif isIntRange(b): result = b
else: result = a
proc isIntRangeOrLit(t: PType): bool =
result = isIntRange(t) or isIntLit(t)
proc pickMinInt(n: PNode): biggestInt =
if n.kind in {nkIntLit..nkUInt64Lit}:
result = n.intVal
elif isIntLit(n.typ):
result = n.typ.n.intVal
elif isIntRange(n.typ):
result = firstOrd(n.typ)
else:
InternalError(n.info, "pickMinInt")
proc pickMaxInt(n: PNode): biggestInt =
if n.kind in {nkIntLit..nkUInt64Lit}:
result = n.intVal
elif isIntLit(n.typ):
result = n.typ.n.intVal
elif isIntRange(n.typ):
result = lastOrd(n.typ)
else:
InternalError(n.info, "pickMaxInt")
proc makeRange(typ: PType, first, last: biggestInt): PType =
var n = newNode(nkRange)
addSon(n, newIntNode(nkIntLit, min(first, last)))
addSon(n, newIntNode(nkIntLit, max(first, last)))
result = newType(tyRange, typ.owner)
result.n = n
addSon(result, skipTypes(typ, {tyRange}))
proc makeRangeF(typ: PType, first, last: biggestFloat): PType =
var n = newNode(nkRange)
addSon(n, newFloatNode(nkFloatLit, min(first.float, last.float)))
addSon(n, newFloatNode(nkFloatLit, max(first.float, last.float)))
result = newType(tyRange, typ.owner)
result.n = n
addSon(result, skipTypes(typ, {tyRange}))
proc getIntervalType*(m: TMagic, n: PNode): PType =
# Nimrod requires interval arithmetic for ``range`` types. Lots of tedious
# work but the feature is very nice for reducing explicit conversions.
result = n.typ
template commutativeOp(opr: expr) {.immediate.} =
let a = n.sons[1]
let b = n.sons[2]
if isIntRangeOrLit(a.typ) and isIntRangeOrLit(b.typ):
result = makeRange(pickIntRange(a.typ, b.typ),
opr(pickMinInt(a), pickMinInt(b)),
opr(pickMaxInt(a), pickMaxInt(b)))
template binaryOp(opr: expr) {.immediate.} =
let a = n.sons[1]
let b = n.sons[2]
if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}:
result = makeRange(a.typ,
opr(pickMinInt(a), pickMinInt(b)),
opr(pickMaxInt(a), pickMaxInt(b)))
case m
of mUnaryMinusI, mUnaryMinusI64:
let a = n.sons[1].typ
if isIntRange(a):
# (1..3) * (-1) == (-3.. -1)
result = makeRange(a, 0|-|lastOrd(a), 0|-|firstOrd(a))
of mUnaryMinusF64:
let a = n.sons[1].typ
if isFloatRange(a):
result = makeRangeF(a, -getFloat(a.n.sons[1]),
-getFloat(a.n.sons[0]))
of mAbsF64:
let a = n.sons[1].typ
if isFloatRange(a):
# abs(-5.. 1) == (1..5)
result = makeRangeF(a, abs(getFloat(a.n.sons[1])),
abs(getFloat(a.n.sons[0])))
of mAbsI, mAbsI64:
let a = n.sons[1].typ
if isIntRange(a):
result = makeRange(a, `|abs|`(getInt(a.n.sons[1])),
`|abs|`(getInt(a.n.sons[0])))
of mSucc:
let a = n.sons[1].typ
let b = n.sons[2].typ
if isIntRange(a) and isIntLit(b):
# (-5.. 1) + 6 == (-5 + 6)..(-1 + 6)
result = makeRange(a, pickMinInt(n.sons[1]) |+| pickMinInt(n.sons[2]),
pickMaxInt(n.sons[1]) |+| pickMaxInt(n.sons[2]))
of mPred:
let a = n.sons[1].typ
let b = n.sons[2].typ
if isIntRange(a) and isIntLit(b):
result = makeRange(a, pickMinInt(n.sons[1]) |-| pickMinInt(n.sons[2]),
pickMaxInt(n.sons[1]) |-| pickMaxInt(n.sons[2]))
of mAddI, mAddI64, mAddU, mAddU64:
commutativeOp(`|+|`)
of mMulI, mMulI64, mMulU, mMulU64:
commutativeOp(`|*|`)
of mSubI, mSubI64, mSubU, mSubU64:
binaryOp(`|-|`)
of mBitandI, mBitandI64:
var a = n.sons[1]
var b = n.sons[2]
# symmetrical:
if b.kind notin {nkIntLit..nkUInt64Lit}: swap(a, b)
if b.kind in {nkIntLit..nkUInt64Lit}:
let x = b.intVal|+|1
if (x and -x) == x and x >= 0:
result = makeRange(a.typ, 0, b.intVal)
of mModI, mModI64, mModU, mModU64:
# so ... if you ever wondered about modulo's signedness; this defines it:
let a = n.sons[1]
let b = n.sons[2]
if b.kind in {nkIntLit..nkUInt64Lit}:
if b.intVal >= 0:
result = makeRange(a.typ, 0, b.intVal-1)
else:
result = makeRange(a.typ, b.intVal+1, 0)
of mDivI, mDivI64, mDivU, mDivU64:
binaryOp(`|div|`)
of mMinI, mMinI64:
commutativeOp(min)
of mMaxI, mMaxI64:
commutativeOp(max)
else: nil
discard """
mShlI, mShlI64,
mShrI, mShrI64, mAddF64, mSubF64, mMulF64, mDivF64, mMaxF64, mMinF64
"""
proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
# b and c may be nil
result = nil

View file

@ -40,6 +40,11 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
# pass unmodified to evals
result = n
proc semOrd(c: PContext, n: PNode): PNode =
result = n
result.typ = makeRangeType(c, firstOrd(n.sons[1].typ),
lastOrd(n.sons[1].typ), n.info)
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
flags: TExprFlags): PNode =
case n[0].sym.magic
@ -49,5 +54,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n)
result.typ = getSysType(tyString)
of mInstantiationInfo: result = semInstantiationInfo(c, n)
of mOrd: result = semOrd(c, n)
else: result = n

View file

@ -132,7 +132,8 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
var a = semConstExpr(c, n[1])
var b = semConstExpr(c, n[2])
if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128}:
if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128,
tyUInt8..tyUInt32}:
GlobalError(n.info, errOrdinalTypeExpected)
if enumHasHoles(a.typ):
GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)

View file

@ -34,8 +34,13 @@ type
# for example
TTypeRelation* = enum # order is important!
isNone, isConvertible, isIntConv, isSubtype,
isGeneric
isNone, isConvertible,
isIntConv,
isSubtype,
isSubrange, # subrange of the wanted type; no type conversion
# but apart from that counts as ``isSubtype``
isGeneric,
isFromIntLit, # conversion *from* int literal; proven safe
isEqual
proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} =
@ -56,10 +61,6 @@ proc initCandidate*(c: var TCandidate, callee: PType) =
proc put(t: var TIdTable, key, val: PType) {.inline.} =
IdTablePut(t, key, val)
when false:
if val.kind == tyObject and isDefined"testme" and
IdentEq(val.sym.name, "TTable"):
assert false
proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, calleeScope = -1) =
initCandidateAux(c, callee.typ)
@ -100,7 +101,7 @@ proc cmpCandidates*(a, b: TCandidate): int =
if (a.calleeScope != -1) and (b.calleeScope != -1):
result = a.calleeScope - b.calleeScope
proc writeMatches(c: TCandidate) =
proc writeMatches*(c: TCandidate) =
Writeln(stdout, "exact matches: " & $c.exactMatches)
Writeln(stdout, "subtype matches: " & $c.subtypeMatches)
Writeln(stdout, "conv matches: " & $c.convMatches)
@ -160,15 +161,25 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
if a.kind == f.kind:
result = isEqual
else:
var k = skipTypes(a, {tyRange}).kind
if k == f.kind: result = isSubtype
elif k == tyInt and f.kind in {tyRange, tyInt8..tyUInt64}:
# and a.n != nil and a.n.intVal >= firstOrd(f) and
# a.n.intVal <= lastOrd(f):
let ab = skipTypes(a, {tyRange})
let k = ab.kind
if k == f.kind: result = isSubrange
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
tyUInt..tyUInt64} and
isIntLit(ab) and ab.n.intVal >= firstOrd(f) and
ab.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 = isFromIntLit
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
result = isIntConv
elif k >= min and k <= max: result = isConvertible
elif k >= min and k <= max:
result = isConvertible
elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64,
tyUInt8..tyUInt32} and
a.n[0].intVal >= firstOrd(f) and
a.n[1].intVal <= lastOrd(f):
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
@ -186,10 +197,10 @@ proc handleFloatRange(f, a: PType): TTypeRelation =
if a.kind == f.kind:
result = isEqual
else:
var k = skipTypes(a, {tyRange}).kind
if k == f.kind: result = isSubtype
elif k == tyInt and f.kind >= tyFloat and f.kind <= tyFloat128:
result = isIntConv
let ab = skipTypes(a, {tyRange})
var k = ab.kind
if k == f.kind: result = isSubrange
elif isIntLit(ab): result = isConvertible
elif k >= tyFloat and k <= tyFloat128: result = isConvertible
else: result = isNone
@ -229,7 +240,7 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation =
for i in countup(0, f.sonsLen - 1):
let son = f.sons[i]
var match = son.kind == a.kind
var match = son.kind == skipTypes(a, {tyRange}).kind
if not match:
case son.kind
@ -584,12 +595,17 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
of isConvertible:
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isIntConv:
of isIntConv:
# too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here:
inc(m.intConvMatches)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isSubtype:
inc(m.subtypeMatches)
result = implicitConv(nkHiddenSubConv, f, copyTree(arg), m, c)
of isSubrange:
inc(m.subtypeMatches)
result = copyTree(arg)
of isGeneric:
inc(m.genericMatches)
if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}:
@ -601,6 +617,11 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
if skipTypes(result.typ, abstractVar).kind in {tyTuple}:
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
# BUGFIX: use ``result.typ`` and not `f` here
of isFromIntLit:
# too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here:
inc(m.intConvMatches, 256)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isEqual:
inc(m.exactMatches)
result = copyTree(arg)

View file

@ -734,7 +734,6 @@ proc transform(c: PTransf, n: PNode): PTransNode =
# we inline constants if they are not complex constants:
if cnst != nil and not dontInlineConstant(n, cnst):
result = PTransNode(cnst) # do not miss an optimization
warnNarrowingConversion(result.pnode)
proc processTransf(context: PPassContext, n: PNode): PNode =
# Note: For interactive mode we cannot call 'passes.skipCodegen' and skip

View file

@ -102,6 +102,9 @@ proc getOrdValue(n: PNode): biggestInt =
LocalError(n.info, errOrdinalTypeExpected)
result = 0
proc isIntLit*(t: PType): bool {.inline.} =
result = t.n != nil and t.n.kind == nkIntLit
proc isCompatibleToCString(a: PType): bool =
if a.kind == tyArray:
if (firstOrd(a.sons[0]) == 0) and
@ -400,8 +403,15 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
result = ""
if t == nil: return
if prefer == preferName and t.sym != nil and sfAnon notin t.sym.flags:
if t.kind == tyInt and isIntLit(t):
return t.sym.Name.s & "(" & $t.n.intVal & ")"
return t.sym.Name.s
case t.Kind
of tyInt:
if not isIntLit(t):
result = typeToStr[t.kind]
else:
result = "intLit(" & $t.n.intVal & ")"
of tyGenericBody, tyGenericInst, tyGenericInvokation:
result = typeToString(t.sons[0]) & '['
for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)):
@ -536,7 +546,7 @@ proc lastOrd(t: PType): biggestInt =
of tyUInt8: result = 0xFF
of tyUInt16: result = 0xFFFF
of tyUInt32: result = 0xFFFFFFFF
of tyUInt64: result = -1
of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64
of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position

View file

@ -570,9 +570,67 @@ operation meaning
`Automatic type conversion`:idx: is performed in expressions where different
kinds of integer types are used: the smaller type is converted to the larger.
A `narrowing type conversion`:idx: converts a larger to a smaller type (for
example ``int32 -> int16``. A `widening type conversion`:idx: converts a
smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only
widening type conversion are *implicit*:
.. code-block:: nimrod
var myInt16 = 5i16
var myInt: int
myInt16 + 34 # of type ``int16``
myInt16 + myInt # of type ``int``
myInt16 + 2i32 # of type ``int32``
However, ``int`` literals are implicitely convertible to a smaller integer type
if the literal's value fits this smaller type and such a conversion is less
expensive than other implicit conversions, so ``myInt16 + 34`` produces
an ``int16`` result.
For further details, see `Convertible relation`_.
Subrange types
~~~~~~~~~~~~~~
A `subrange`:idx: type is a range of values from an ordinal type (the base
type). To define a subrange type, one must specify it's limiting values: the
lowest and highest value of the type:
.. code-block:: nimrod
type
TSubrange = range[0..5]
``TSubrange`` is a subrange of an integer which can only hold the values 0
to 5. Assigning any other value to a variable of type ``TSubrange`` is a
checked runtime error (or static error if it can be statically
determined). Assignments from the base type to one of its subrange types
(and vice versa) are allowed.
A subrange type has the same size as its base type (``int`` in the example).
Nimrod requires `interval arithmetic`:idx: for subrange types over a set
of built-in operators that involve constants: ``x mod 3`` is of
type ``range[0..2]``. The following built-in operators for integers are
affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``,
``pred``, ``mod``, ``div``, ``and`` (bitwise and).
Bitwise and only produces a ``range`` if one of its operands is a
constant *x* so that (x+1) is a number of two.
(Bitwise and then behaves as a ``mod`` operation.)
This means that the following code is accepted:
.. code-block:: nimrod
case (x and 3) + 7
of 7: echo "A"
of 8: echo "B"
of 9: echo "C"
of 10: echo "D"
# note: no ``else`` required as (x and 3) + 7 has the type: range[7..10]
Pre-defined floating point types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -729,26 +787,6 @@ ordinal value and its string value by using a tuple. It is also
possible to only specify one of them.
Subrange types
~~~~~~~~~~~~~~
A `subrange`:idx: type is a range of values from an ordinal type (the base
type). To define a subrange type, one must specify it's limiting values: the
lowest and highest value of the type:
.. code-block:: nimrod
type
TSubrange = range[0..5]
``TSubrange`` is a subrange of an integer which can only hold the values 0
to 5. Assigning any other value to a variable of type ``TSubrange`` is a
checked runtime error (or static error if it can be statically
determined). Assignments from the base type to one of its subrange types
(and vice versa) are allowed.
A subrange type has the same size as its base type (``int`` in the example).
String type
~~~~~~~~~~~
All string literals are of the type `string`:idx:. A string in Nimrod is very
@ -1798,7 +1836,9 @@ evaluated and if its value is in a *slicelist* the corresponding statements
given *slicelist* the ``else`` part is executed. If there is no ``else``
part and not all possible values that ``expr`` can hold occur in a
``slicelist``, a static error occurs. This holds only for expressions of
ordinal types.
ordinal types. "All possible values" of ``expr`` are determined by ``expr``'s
type.
If the expression is not of an ordinal type, and no ``else`` part is
given, control passes after the ``case`` statement.

View file

@ -59,7 +59,7 @@ type
rawType: PNimType
ppointer = ptr pointer
pbyteArray = ptr array[0.. 0xffff, byte]
pbyteArray = ptr array[0.. 0xffff, int8]
TGenSeq {.pure.} = object
len, space: int

View file

@ -84,7 +84,7 @@ proc setupQuery(db: TDbConn, query: TSqlQuery,
result = PQExec(db, q)
if PQresultStatus(result) != PGRES_TUPLES_OK: dbError(db)
proc setRow(res: PPGresult, r: var TRow, line, cols: int) =
proc setRow(res: PPGresult, r: var TRow, line, cols: int32) =
for col in 0..cols-1:
setLen(r[col], 0)
var x = PQgetvalue(res, line, col)
@ -96,7 +96,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
## fast, but potenially dangerous: If the for-loop-body executes another
## query, the results can be undefined. For Postgres it is safe though.
var res = setupQuery(db, query, args)
var L = int(PQnfields(res))
var L = PQnfields(res)
var result = newRow(L)
for i in 0..PQntuples(res)-1:
setRow(res, result, i, L)
@ -107,7 +107,7 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): TRow =
## retrieves a single row.
var res = setupQuery(db, query, args)
var L = int(PQnfields(res))
var L = PQnfields(res)
result = newRow(L)
setRow(res, result, 0, L)
PQclear(res)

View file

@ -64,7 +64,7 @@ proc TryExec*(db: TDbConn, query: TSqlQuery,
## tries to execute the query and returns true if successful, false otherwise.
var q = dbFormat(query, args)
var stmt: sqlite3.PStmt
if prepare_v2(db, q, q.len, stmt, nil) == SQLITE_OK:
if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK:
if step(stmt) == SQLITE_DONE:
result = finalize(stmt) == SQLITE_OK
@ -79,9 +79,9 @@ proc newRow(L: int): TRow =
proc setupQuery(db: TDbConn, query: TSqlQuery,
args: openarray[string]): PStmt =
var q = dbFormat(query, args)
if prepare_v2(db, q, q.len, result, nil) != SQLITE_OK: dbError(db)
if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db)
proc setRow(stmt: PStmt, r: var TRow, cols: int) =
proc setRow(stmt: PStmt, r: var TRow, cols: cint) =
for col in 0..cols-1:
setLen(r[col], column_bytes(stmt, col)) # set capacity
setLen(r[col], 0)
@ -94,7 +94,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
## fast, but potenially dangerous: If the for-loop-body executes another
## query, the results can be undefined. For Sqlite it is safe though.
var stmt = setupQuery(db, query, args)
var L = int(columnCount(stmt))
var L = (columnCount(stmt))
var result = newRow(L)
while step(stmt) == SQLITE_ROW:
setRow(stmt, result, L)
@ -105,7 +105,7 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): TRow =
## retrieves a single row.
var stmt = setupQuery(db, query, args)
var L = int(columnCount(stmt))
var L = (columnCount(stmt))
result = newRow(L)
if step(stmt) == SQLITE_ROW:
setRow(stmt, result, L)

View file

@ -35,14 +35,15 @@ type
proc toSdlColor*(c: TColor): Sdl.TColor =
## Convert colors.TColor to SDL.TColor
var x = c.extractRGB
result.r = toU8(x.r)
result.g = toU8(x.g)
result.b = toU8(x.b)
result.r = x.r and 0xff
result.g = x.g and 0xff
result.b = x.b and 0xff
proc createSdlColor*(sur: PSurface, c: TColor, alpha: int = 0): int32 =
## Creates a color using ``sdl.MapRGBA``.
var x = c.extractRGB
return sdl.MapRGBA(sur.s.format, toU8(x.r), toU8(x.g), toU8(x.b), toU8(alpha))
return sdl.MapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff,
x.b and 0xff, alpha and 0xff)
proc toSdlRect*(r: TRect): sdl.TRect =
## Convert ``graphics.TRect`` to ``sdl.TRect``.

View file

@ -82,7 +82,7 @@ proc matchOrFind(s: string, pattern: TRegEx, matches: var openarray[string],
start, flags: cint): cint =
var
rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, flags,
res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if res < 0'i32: return res
for i in 1..int(res)-1:
@ -100,7 +100,7 @@ proc findBounds*(s: string, pattern: TRegEx, matches: var openarray[string],
## is written into `matches` and ``(-1,0)`` is returned.
var
rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if res < 0'i32: return (-1, 0)
for i in 1..int(res)-1:
@ -119,7 +119,7 @@ proc findBounds*(s: string, pattern: TRegEx,
## ``(-1,0)`` is returned.
var
rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if res < 0'i32: return (-1, 0)
for i in 1..int(res)-1:
@ -135,14 +135,14 @@ proc findBounds*(s: string, pattern: TRegEx,
## match, ``(-1,0)`` is returned.
var
rawMatches: array[0..3 - 1, cint]
res = pcre.Exec(pattern.h, nil, s, len(s), start, 0'i32,
res = pcre.Exec(pattern.h, nil, s, len(s).cint, start, 0'i32,
cast[ptr cint](addr(rawMatches)), 3)
if res < 0'i32: return (int(res), 0)
return (int(rawMatches[0]), int(rawMatches[1]-1))
proc matchOrFind(s: string, pattern: TRegEx, start, flags: cint): cint =
var rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
result = pcre.Exec(pattern.h, pattern.e, s, len(s), start, flags,
result = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if result >= 0'i32:
result = rawMatches[1] - rawMatches[0]
@ -180,7 +180,7 @@ proc find*(s: string, pattern: TRegEx, matches: var openarray[string],
## is written into ``matches`` and -1 is returned.
var
rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
res = pcre.Exec(pattern.h, pattern.e, s, len(s), start, 0'i32,
res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, 0'i32,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if res < 0'i32: return res
for i in 1..int(res)-1:
@ -195,7 +195,7 @@ proc find*(s: string, pattern: TRegEx, start = 0): int =
## match, -1 is returned.
var
rawMatches: array[0..3 - 1, cint]
res = pcre.Exec(pattern.h, nil, s, len(s), start, 0'i32,
res = pcre.Exec(pattern.h, nil, s, len(s).cint, start, 0'i32,
cast[ptr cint](addr(rawMatches)), 3)
if res < 0'i32: return res
return rawMatches[0]
@ -205,7 +205,7 @@ iterator findAll*(s: string, pattern: TRegEx, start = 0): string =
var i = int32(start)
var rawMatches: array[0..maxSubpatterns * 3 - 1, cint]
while true:
let res = pcre.Exec(pattern.h, pattern.e, s, len(s), i, 0'i32,
let res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32,
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
if res < 0'i32: break
let a = rawMatches[0]

View file

@ -53,7 +53,8 @@ proc oidToString*(oid: TOid, str: cstring) =
str[24] = '\0'
var
incr, fuzz: int
incr: int
fuzz: int32
proc genOid*(): TOid =
## generates a new OID.

View file

@ -244,7 +244,7 @@ when defined(Windows) and not defined(useNimRtl):
var s = PFileHandleStream(s)
if s.atTheEnd: return 0
var br: int32
var a = winlean.ReadFile(s.handle, buffer, bufLen, br, nil)
var a = winlean.ReadFile(s.handle, buffer, bufLen.cint, br, nil)
# TRUE and zero bytes returned (EOF).
# TRUE and n (>0) bytes returned (good data).
# FALSE and bytes returned undefined (system error).
@ -255,7 +255,7 @@ when defined(Windows) and not defined(useNimRtl):
proc hsWriteData(s: PStream, buffer: pointer, bufLen: int) =
var s = PFileHandleStream(s)
var bytesWritten: int32
var a = winlean.writeFile(s.handle, buffer, bufLen, bytesWritten, nil)
var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil)
if a == 0: OSError()
proc newFileHandleStream(handle: THandle): PFileHandleStream =
@ -293,7 +293,7 @@ when defined(Windows) and not defined(useNimRtl):
proc CreatePipeHandles(Rdhandle, WrHandle: var THandle) =
var piInheritablePipe: TSecurityAttributes
piInheritablePipe.nlength = SizeOF(TSecurityAttributes)
piInheritablePipe.nlength = SizeOF(TSecurityAttributes).cint
piInheritablePipe.lpSecurityDescriptor = nil
piInheritablePipe.Binherithandle = 1
if CreatePipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32:
@ -313,7 +313,7 @@ when defined(Windows) and not defined(useNimRtl):
success: int
hi, ho, he: THandle
new(result)
SI.cb = SizeOf(SI)
SI.cb = SizeOf(SI).cint
if poParentStreams notin options:
SI.dwFlags = STARTF_USESTDHANDLES # STARTF_USESHOWWINDOW or
CreatePipeHandles(SI.hStdInput, HI)
@ -323,16 +323,16 @@ when defined(Windows) and not defined(useNimRtl):
HE = HO
else:
CreatePipeHandles(HE, Si.hStdError)
result.inputHandle = hi
result.outputHandle = ho
result.errorHandle = he
result.inputHandle = TFileHandle(hi)
result.outputHandle = TFileHandle(ho)
result.errorHandle = TFileHandle(he)
else:
SI.hStdError = GetStdHandle(STD_ERROR_HANDLE)
SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE)
SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)
result.inputHandle = si.hStdInput
result.outputHandle = si.hStdOutput
result.errorHandle = si.hStdError
result.inputHandle = TFileHandle(si.hStdInput)
result.outputHandle = TFileHandle(si.hStdOutput)
result.errorHandle = TFileHandle(si.hStdError)
var cmdl: cstring
when false: # poUseShell in options:
@ -394,7 +394,7 @@ when defined(Windows) and not defined(useNimRtl):
discard TerminateProcess(p.FProcessHandle, 0)
proc waitForExit(p: PProcess, timeout: int = -1): int =
discard WaitForSingleObject(p.FProcessHandle, timeout)
discard WaitForSingleObject(p.FProcessHandle, timeout.int32)
var res: int32
discard GetExitCodeProcess(p.FProcessHandle, res)
@ -424,7 +424,7 @@ when defined(Windows) and not defined(useNimRtl):
ProcInfo: TProcessInformation
process: THandle
L: int32
SI.cb = SizeOf(SI)
SI.cb = SizeOf(SI).cint
SI.hStdError = GetStdHandle(STD_ERROR_HANDLE)
SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE)
SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)
@ -454,7 +454,7 @@ when defined(Windows) and not defined(useNimRtl):
for i in 0..readfds.len()-1:
rfds[i] = readfds[i].FProcessHandle
var ret = waitForMultipleObjects(readfds.len,
var ret = waitForMultipleObjects(readfds.len.int32,
addr(rfds), 0'i32, timeout)
case ret
of WAIT_TIMEOUT:

View file

@ -343,7 +343,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") =
name.sin_port = sockets.htons(int16(port))
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)),
sizeof(name)) < 0'i32:
sizeof(name).TSockLen) < 0'i32:
OSError()
else:
var hints: TAddrInfo
@ -366,7 +366,7 @@ when false:
name.sin_port = sockets.htons(int16(port))
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)),
sizeof(name)) < 0'i32:
sizeof(name).TSockLen) < 0'i32:
OSError()
proc getSockName*(socket: TSocket): TPort =
@ -378,7 +378,7 @@ proc getSockName*(socket: TSocket): TPort =
name.sin_family = posix.AF_INET
#name.sin_port = htons(cint16(port))
#name.sin_addr.s_addr = htonl(INADDR_ANY)
var namelen: cint = sizeof(name)
var namelen = sizeof(name).TSockLen
if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)),
addr(namelen)) == -1'i32:
OSError()
@ -398,7 +398,7 @@ proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] =
## **Warning:** This function might block even if socket is non-blocking
## when using SSL.
var sockAddress: Tsockaddr_in
var addrLen: cint = sizeof(sockAddress)
var addrLen = sizeof(sockAddress).TSockLen
var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)),
addr(addrLen))
@ -477,9 +477,9 @@ proc getServByName*(name, proto: string): TServent =
proc getServByPort*(port: TPort, proto: string): TServent =
## well-known getservbyport proc.
when defined(Windows):
var s = winlean.getservbyport(ze(int16(port)), proto)
var s = winlean.getservbyport(ze(int16(port)).cint, proto)
else:
var s = posix.getservbyport(ze(int16(port)), proto)
var s = posix.getservbyport(ze(int16(port)).cint, proto)
if s == nil: OSError()
result.name = $s.s_name
result.aliases = cstringArrayToSeq(s.s_aliases)
@ -492,11 +492,11 @@ proc getHostByAddr*(ip: string): THostEnt =
myaddr.s_addr = inet_addr(ip)
when defined(windows):
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr),
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cint,
cint(sockets.AF_INET))
if s == nil: OSError()
else:
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr),
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).cint,
cint(posix.AF_INET))
if s == nil:
raise newException(EOS, $hStrError(h_errno))
@ -539,7 +539,7 @@ proc getHostByName*(name: string): THostEnt =
proc getSockOptInt*(socket: TSocket, level, optname: int): int =
## getsockopt for integer options.
var res: cint
var size: cint = sizeof(res)
var size = sizeof(res).cint
if getsockopt(socket.fd, cint(level), cint(optname),
addr(res), addr(size)) < 0'i32:
OSError()
@ -549,7 +549,7 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) =
## setsockopt for integer options.
var value = cint(optval)
if setsockopt(socket.fd, cint(level), cint(optname), addr(value),
sizeof(value)) < 0'i32:
sizeof(value).cint) < 0'i32:
OSError()
proc connect*(socket: TSocket, name: string, port = TPort(0),
@ -608,7 +608,7 @@ proc connect*(socket: TSocket, name: string, port = TPort(0),
of AF_INET: s.sin_family = posix.AF_INET
of AF_INET6: s.sin_family = posix.AF_INET6
else: nil
if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s).cint) < 0'i32:
OSError()
proc connectAsync*(socket: TSocket, name: string, port = TPort(0),

View file

@ -111,7 +111,7 @@ type
## in the range 0 to 23.
monthday*: range[1..31] ## The day of the month, in the range 1 to 31.
month*: TMonth ## The current month.
year*: int ## The current year.
year*: range[-10_000..10_000] ## The current year.
weekday*: TWeekDay ## The current day of the week.
yearday*: range[0..365] ## The number of days since January 1,
## in the range 0 to 365.
@ -122,7 +122,7 @@ type
timezone*: int ## The offset of the (non-DST) timezone in seconds
## west of UTC.
TTimeInterval* = object
TTimeInterval* {.pure.} = object ## a time interval
miliseconds*: int ## The number of miliseconds
seconds*: int ## The number of seconds
minutes*: int ## The number of minutes
@ -150,11 +150,11 @@ proc `$` *(timeInfo: TTimeInfo): string
proc `$` *(time: TTime): string
## converts a calendar time to a string representation.
proc `-` *(a, b: TTime): int64{.
proc `-`*(a, b: TTime): int64 {.
rtl, extern: "ntDiffTime".}
## computes the difference of two calendar times. Result is in seconds.
proc `<` * (a, b: TTime): bool {.
proc `<`*(a, b: TTime): bool {.
rtl, extern: "ntLtTime".} =
## returns true iff ``a < b``, that is iff a happened before b.
result = a - b < 0
@ -175,8 +175,8 @@ proc getStartMilsecs*(): int {.deprecated.}
## get the miliseconds from the start of the program. **Deprecated since
## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
proc newInterval*(miliseconds, seconds, minutes, hours, days, months,
years: int = 0): TTimeInterval =
proc initInterval*(miliseconds, seconds, minutes, hours, days, months,
years: int = 0): TTimeInterval =
## creates a new ``TTimeInterval``.
result.miliseconds = miliseconds
result.seconds = seconds
@ -188,23 +188,20 @@ proc newInterval*(miliseconds, seconds, minutes, hours, days, months,
proc isLeapYear(year: int): bool =
if year mod 400 == 0:
return true
return true
elif year mod 100 == 0:
return false
return false
elif year mod 4 == 0:
return true
return true
else:
return false
return false
proc getDaysInMonth(month: TMonth, year: int): int =
# http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month
if month == mFeb: # Feb
if isLeapYear(year):
result = 29
else:
result = 28
elif month in [mApr, mJun, mSep, mNov]: result = 30
else: result = 31
case month
of mFeb: result = if isLeapYear(year): 29 else: 28
of mApr, mJun, mSep, mNov: result = 30
else: result = 31
proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
var anew = a
@ -228,9 +225,10 @@ proc calculateSeconds(a: TTimeInfo, interval: TTimeInterval): float =
proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
## adds ``interval`` time.
##
## **Note:** This has been only briefly tested and it may not be very accurate.
## **Note:** This has been only briefly tested and it may not be
## very accurate.
let t = timeInfoToTime(a)
var secs = calculateSeconds(a, interval)
let secs = calculateSeconds(a, interval)
if a.tzname == "UTC":
result = getGMTime(TTime(float(t) + secs))
else:
@ -242,7 +240,7 @@ proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo =
## **Note:** This has been only briefly tested, it is inaccurate especially
## when you subtract so much that you reach the Julian calendar.
let t = timeInfoToTime(a)
var secs = calculateSeconds(a, interval)
let secs = calculateSeconds(a, interval)
if a.tzname == "UTC":
result = getGMTime(TTime(float(t) - secs))
else:
@ -329,7 +327,7 @@ when not defined(ECMAScript):
proc timeInfoToTM(t: TTimeInfo): structTM =
const
weekDays: array [TWeekDay, int] = [1, 2, 3, 4, 5, 6, 0]
weekDays: array [TWeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8]
result.second = t.second
result.minute = t.minute
result.hour = t.hour
@ -362,13 +360,13 @@ when not defined(ECMAScript):
var a = t
result = tmToTimeInfo(localtime(addr(a))[], true)
# copying is needed anyway to provide reentrancity; thus
# the convertion is not expensive
# the conversion is not expensive
proc getGMTime(t: TTime): TTimeInfo =
var a = t
result = tmToTimeInfo(gmtime(addr(a))[], false)
# copying is needed anyway to provide reentrancity; thus
# the convertion is not expensive
# the conversion is not expensive
proc TimeInfoToTime(timeInfo: TTimeInfo): TTime =
var cTimeInfo = timeInfo # for C++ we have to make a copy,

View file

@ -182,8 +182,8 @@ when not defined(EcmaScript) and not defined(NimrodVM):
include "system/hti"
type
Byte* = Int8 ## this is an alias for ``int8``, that is a signed
## int 8 bits wide.
Byte* = uInt8 ## this is an alias for ``uint8``, that is an unsigned
## int 8 bits wide.
Natural* = range[0..high(int)]
## is an int type ranging from zero to the maximum value
@ -967,7 +967,7 @@ type
type # these work for most platforms:
cchar* {.importc: "char", nodecl.} = char
## This is the same as the type ``char`` in *C*.
cschar* {.importc: "signed char", nodecl.} = byte
cschar* {.importc: "signed char", nodecl.} = int8
## This is the same as the type ``signed char`` in *C*.
cshort* {.importc: "short", nodecl.} = int16
## This is the same as the type ``short`` in *C*.
@ -1156,6 +1156,10 @@ proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
## The stingify operator for an integer argument. Returns `x`
## converted to a decimal string.
proc `$` *(x: uint64): string {.noSideEffect.}
## The stingify operator for an unsigned integer argument. Returns `x`
## converted to a decimal string.
proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
## The stingify operator for a float argument. Returns `x`
## converted to a decimal string.
@ -1177,7 +1181,7 @@ proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
## as it is. This operator is useful for generic code, so
## that ``$expr`` also works if ``expr`` is already a string.
proc `$` *[T](x: ordinal[T]): string {.magic: "EnumToStr", noSideEffect.}
proc `$` *[TEnum: enum](x: TEnum): string {.magic: "EnumToStr", noSideEffect.}
## The stingify operator for an enumeration argument. This works for
## any enumeration type thanks to compiler magic. If
## a ``$`` operator for a concrete enumeration is provided, this is
@ -1850,7 +1854,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
proc getFileSize*(f: TFile): int64
## retrieves the file size (in bytes) of `f`.
proc ReadBytes*(f: TFile, a: var openarray[byte], start, len: int): int
proc ReadBytes*(f: TFile, a: var openarray[int8], start, len: int): int
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
## the actual number of bytes that have been read which may be less than
## `len` (if not as many bytes are remaining), but not greater.
@ -1865,7 +1869,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
## the actual number of bytes that have been read which may be less than
## `len` (if not as many bytes are remaining), but not greater.
proc writeBytes*(f: TFile, a: openarray[byte], start, len: int): int
proc writeBytes*(f: TFile, a: openarray[int8], start, len: int): int
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
## the number of actual written bytes, which may be less than `len` in case
## of an error.

View file

@ -71,7 +71,8 @@ proc c_fopen(filename, mode: cstring): C_TextFileStar {.
importc: "fopen", nodecl.}
proc c_fclose(f: C_TextFileStar) {.importc: "fclose", nodecl.}
proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs.}
proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs,
noSideEffect.}
# we use it only in a way that cannot lead to security issues
proc c_fread(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {.

View file

@ -20,6 +20,11 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
c_sprintf(buf, "%p", x)
return $buf
proc `$`(x: uint64): string =
var buf: array [0..59, char]
c_sprintf(buf, "%llu", x)
return $buf
proc reprStrAux(result: var string, s: string) =
if cast[pointer](s) == nil:
add result, "nil"
@ -67,7 +72,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
result = $e & " (invalid data!)"
type
pbyteArray = ptr array[0.. 0xffff, byte]
pbyteArray = ptr array[0.. 0xffff, int8]
proc addSetElem(result: var string, elem: int, typ: PNimType) =
case typ.kind

View file

@ -222,17 +222,17 @@ proc fwrite(buf: Pointer, size, n: int, f: TFile): int {.
proc readBuffer(f: TFile, buffer: pointer, len: int): int =
result = fread(buffer, 1, len, f)
proc ReadBytes(f: TFile, a: var openarray[byte], start, len: int): int =
proc ReadBytes(f: TFile, a: var openarray[int8], start, len: int): int =
result = readBuffer(f, addr(a[start]), len)
proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int =
result = readBuffer(f, addr(a[start]), len)
proc writeBytes(f: TFile, a: openarray[byte], start, len: int): int =
var x = cast[ptr array[0..1000_000_000, byte]](a)
proc writeBytes(f: TFile, a: openarray[int8], start, len: int): int =
var x = cast[ptr array[0..1000_000_000, int8]](a)
result = writeBuffer(f, addr(x[start]), len)
proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
var x = cast[ptr array[0..1000_000_000, byte]](a)
var x = cast[ptr array[0..1000_000_000, int8]](a)
result = writeBuffer(f, addr(x[start]), len)
proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
result = fwrite(buffer, 1, len, f)

View file

@ -13,8 +13,8 @@
{.deadCodeElim: on.}
type
WideChar* = int16
PWideChar* = ptr int16
WideChar* = uint16
PWideChar* = ptr uint16
type # WinNT.h -- Defines the 32-Bit Windows types and constants
SHORT* = int16
@ -72,7 +72,6 @@ type # WinDef.h -- Basic Windows Type Definitions
DWORD* = int32
WINBOOL* = int32
BYTE* = char
WORD* = int16
# FLOAT* = float
PFLOAT* = ptr FLOAT
@ -296,13 +295,13 @@ type
when defined(winUnicode):
type
PTBYTE* = ptr int16
PTBYTE* = ptr uint16
PTCH* = PWideChar
PTCHAR* = PWideChar
PTSTR* = PWideChar
else:
type
PTBYTE* = ptr int8
PTBYTE* = ptr byte
PTCH* = cstring
PTCHAR* = cstring
PTSTR* = cstring
@ -316,12 +315,12 @@ type
when defined(winUnicode):
type
TBYTE* = int16
TBYTE* = uint16
TCHAR* = widechar
BCHAR* = int16
else:
type
TBYTE* = int8
TBYTE* = uint8
TCHAR* = char
BCHAR* = int8
type
@ -7432,34 +7431,34 @@ type
PDCB* = ptr DCB
const
bm_DCB_fBinary* = 0x00000001
bp_DCB_fBinary* = 0
bm_DCB_fBinary* = 1
bp_DCB_fBinary* = 0'i32
bm_DCB_fParity* = 0x00000002
bp_DCB_fParity* = 1
bp_DCB_fParity* = 1'i32
bm_DCB_fOutxCtsFlow* = 0x00000004
bp_DCB_fOutxCtsFlow* = 2
bp_DCB_fOutxCtsFlow* = 2'i32
bm_DCB_fOutxDsrFlow* = 0x00000008
bp_DCB_fOutxDsrFlow* = 3
bp_DCB_fOutxDsrFlow* = 3'i32
bm_DCB_fDtrControl* = 0x00000030
bp_DCB_fDtrControl* = 4
bp_DCB_fDtrControl* = 4'i32
bm_DCB_fDsrSensitivity* = 0x00000040
bp_DCB_fDsrSensitivity* = 6
bp_DCB_fDsrSensitivity* = 6'i32
bm_DCB_fTXContinueOnXoff* = 0x00000080
bp_DCB_fTXContinueOnXoff* = 7
bp_DCB_fTXContinueOnXoff* = 7'i32
bm_DCB_fOutX* = 0x00000100
bp_DCB_fOutX* = 8
bp_DCB_fOutX* = 8'i32
bm_DCB_fInX* = 0x00000200
bp_DCB_fInX* = 9
bp_DCB_fInX* = 9'i32
bm_DCB_fErrorChar* = 0x00000400
bp_DCB_fErrorChar* = 10
bp_DCB_fErrorChar* = 10'i32
bm_DCB_fNull* = 0x00000800
bp_DCB_fNull* = 11
bp_DCB_fNull* = 11'i32
bm_DCB_fRtsControl* = 0x00003000
bp_DCB_fRtsControl* = 12
bp_DCB_fRtsControl* = 12'i32
bm_DCB_fAbortOnError* = 0x00004000
bp_DCB_fAbortOnError* = 14
bp_DCB_fAbortOnError* = 14'i32
bm_DCB_fDummy2* = 0xFFFF8000'i32
bp_DCB_fDummy2* = 15
bp_DCB_fDummy2* = 15'i32
proc fBinary*(a: var DCB): DWORD
proc set_fBinary*(a: var DCB, fBinary: DWORD)
@ -7575,21 +7574,21 @@ type
const
bm_COMSTAT_fCtsHold* = 0x00000001
bp_COMSTAT_fCtsHold* = 0
bp_COMSTAT_fCtsHold* = 0'i32
bm_COMSTAT_fDsrHold* = 0x00000002
bp_COMSTAT_fDsrHold* = 1
bp_COMSTAT_fDsrHold* = 1'i32
bm_COMSTAT_fRlsdHold* = 0x00000004
bp_COMSTAT_fRlsdHold* = 2
bp_COMSTAT_fRlsdHold* = 2'i32
bm_COMSTAT_fXoffHold* = 0x00000008
bp_COMSTAT_fXoffHold* = 3
bp_COMSTAT_fXoffHold* = 3'i32
bm_COMSTAT_fXoffSent* = 0x00000010
bp_COMSTAT_fXoffSent* = 4
bp_COMSTAT_fXoffSent* = 4'i32
bm_COMSTAT_fEof* = 0x00000020
bp_COMSTAT_fEof* = 5
bp_COMSTAT_fEof* = 5'i32
bm_COMSTAT_fTxim* = 0x00000040
bp_COMSTAT_fTxim* = 6
bp_COMSTAT_fTxim* = 6'i32
bm_COMSTAT_fReserved* = 0xFFFFFF80'i32
bp_COMSTAT_fReserved* = 7
bp_COMSTAT_fReserved* = 7'i32
proc fCtsHold*(a: var COMSTAT): DWORD
# should be renamed to get_<x>?
@ -9984,25 +9983,25 @@ type
const
bm_LDT_ENTRY_BaseMid* = 0x000000FF
bp_LDT_ENTRY_BaseMid* = 0
bp_LDT_ENTRY_BaseMid* = 0'i32
bm_LDT_ENTRY_Type* = 0x00001F00
bp_LDT_ENTRY_Type* = 8
bp_LDT_ENTRY_Type* = 8'i32
bm_LDT_ENTRY_Dpl* = 0x00006000
bp_LDT_ENTRY_Dpl* = 13
bp_LDT_ENTRY_Dpl* = 13'i32
bm_LDT_ENTRY_Pres* = 0x00008000
bp_LDT_ENTRY_Pres* = 15
bp_LDT_ENTRY_Pres* = 15'i32
bm_LDT_ENTRY_LimitHi* = 0x000F0000
bp_LDT_ENTRY_LimitHi* = 16
bp_LDT_ENTRY_LimitHi* = 16'i32
bm_LDT_ENTRY_Sys* = 0x00100000
bp_LDT_ENTRY_Sys* = 20
bp_LDT_ENTRY_Sys* = 20'i32
bm_LDT_ENTRY_Reserved_0* = 0x00200000
bp_LDT_ENTRY_Reserved_0* = 21
bp_LDT_ENTRY_Reserved_0* = 21'i32
bm_LDT_ENTRY_Default_Big* = 0x00400000
bp_LDT_ENTRY_Default_Big* = 22
bp_LDT_ENTRY_Default_Big* = 22'i32
bm_LDT_ENTRY_Granularity* = 0x00800000
bp_LDT_ENTRY_Granularity* = 23
bp_LDT_ENTRY_Granularity* = 23'i32
bm_LDT_ENTRY_BaseHi* = 0xFF000000
bp_LDT_ENTRY_BaseHi* = 24
bp_LDT_ENTRY_BaseHi* = 24'i32
type
LOCALESIGNATURE* {.final, pure.} = object
@ -22820,7 +22819,7 @@ proc SEXT_HIWORD*(L: int32): int32 =
proc ZEXT_HIWORD*(L: int32): int32 =
# return type might be wrong
result = ze(HIWORD(L))
result = HIWORD(L) and 0xffff'i32
proc SEXT_LOWORD*(L: int32): int32 =
result = LOWORD(L)
@ -22869,13 +22868,13 @@ proc MAKEWPARAM*(L, h: int32): WPARAM =
result = WPARAM(MAKELONG(L, h))
proc GET_X_LPARAM*(lp: Windows.LParam): int32 =
result = int16(LOWORD(lp))
result = LOWORD(lp.int32)
proc GET_Y_LPARAM*(lp: Windows.LParam): int32 =
result = int16(HIWORD(lp))
result = HIWORD(lp.int32)
proc UNICODE_NULL*(): WCHAR =
result = 0'i16
result = 0'u16
@ -23500,7 +23499,8 @@ proc ListView_EnsureVisible(hwndLV: HWND, i, fPartialOK: int32): LRESULT =
MAKELPARAM(fPartialOK, 0))
proc ListView_FindItem(wnd: HWND, iStart: int32, lvfi: var LV_FINDINFO): int32 =
result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart), cast[LPARAM](addr(lvfi)))
result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart),
cast[LPARAM](addr(lvfi))).int32
proc ListView_GetBkColor(wnd: HWND): LRESULT =
result = SendMessage(wnd, LVM_GETBKCOLOR, 0, 0)
@ -23534,7 +23534,7 @@ proc ListView_GetItemCount(wnd: HWND): LRESULT =
proc ListView_GetItemPosition(hwndLV: HWND, i: int32, pt: var POINT): int32 =
result = SendMessage(hwndLV, LVM_GETITEMPOSITION, WPARAM(int32(i)),
cast[LPARAM](addr(pt)))
cast[LPARAM](addr(pt))).int32
proc ListView_GetItemSpacing(hwndLV: HWND, fSmall: int32): LRESULT =
result = SendMessage(hwndLV, LVM_GETITEMSPACING, fSmall, 0)
@ -23878,10 +23878,10 @@ proc GetLargestConsoleWindowSize(hConsoleOutput: HANDLE): COORD =
result.x = toU16(res shr 16)
proc Succeeded(Status: HRESULT): WINBOOL =
result = (Status and 0x80000000'i32)
result = (Status and 0x80000000).WinBool
proc Failed(Status: HRESULT): WINBOOL =
result = (Status and 0x80000000'i32)
result = (Status and 0x80000000).WinBool
proc IsError(Status: HRESULT): WINBOOL =
result = ord((int(Status) shr 31) == SEVERITY_ERROR)
@ -23920,7 +23920,7 @@ proc MAKELCID(LangId, SortId: int16): DWORD =
result = toU32((ze(SortId) shl 16) or ze(LangId))
proc MAKESORTLCID(LangId, SortId, SortVersion: int16): DWORD =
result = MAKELCID(LangId, SortId) or int(SortVersion shl 20'i32)
result = MAKELCID(LangId, SortId) or (SortVersion shl 20'i32)
proc LANGIDFROMLCID(LocaleId: LCID): int16 =
result = toU16(LocaleId)

View file

@ -16257,7 +16257,7 @@ proc COLUMN_REQUESTED_WIDTH*(column: PTreeViewColumn): int32 =
MaxWidth = column.max_width
else:
MaxWidth = column.requested_width
result = CLAMP(column.requested_width, MinWidth, MaxWidth)
result = CLAMP(column.requested_width, MinWidth, MaxWidth).int32
proc DRAW_EXPANDERS*(tree_view: PTreeView): bool =
result = (not (FLAG_SET(tree_view, TREE_VIEW_IS_LIST))) and

View file

@ -878,10 +878,10 @@ proc get_tab*(tab_array: PTabArray, tab_index: gint,
proc get_positions_in_pixels*(tab_array: PTabArray): gboolean{.cdecl,
dynlib: lib, importc: "pango_tab_array_get_positions_in_pixels".}
proc ASCENT*(rect: TRectangle): int32 =
result = - int(rect.y)
result = -rect.y
proc DESCENT*(rect: TRectangle): int32 =
result = int(rect.y) + int(rect.height)
result = (rect.y) + (rect.height)
proc LBEARING*(rect: TRectangle): int32 =
result = rect.x

View file

@ -280,9 +280,9 @@ else:
const
LibName = "libSDL.so(|.1|.0)"
const
MAJOR_VERSION* = 1'i8
MINOR_VERSION* = 2'i8
PATCHLEVEL* = 11'i8 # SDL.h constants
MAJOR_VERSION* = 1
MINOR_VERSION* = 2
PATCHLEVEL* = 11 # SDL.h constants
INIT_TIMER* = 0x00000001
INIT_AUDIO* = 0x00000010
INIT_VIDEO* = 0x00000020
@ -2523,8 +2523,8 @@ proc AllocSurface(flags: int32, width, height, depth: int,
AMask)
proc MustLock(Surface: PSurface): bool =
Result = ((surface[] .offset != 0) or
((surface[] .flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0))
Result = ((surface[].offset != 0) or
((surface[].flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0))
proc LockMutex(mutex: Pmutex): int =
Result = mutexP(mutex)

View file

@ -141,9 +141,9 @@ else:
const
ImageLibName = "libSDL_image.so"
const
IMAGE_MAJOR_VERSION* = 1'i8
IMAGE_MINOR_VERSION* = 2'i8
IMAGE_PATCHLEVEL* = 5'i8
IMAGE_MAJOR_VERSION* = 1
IMAGE_MINOR_VERSION* = 2
IMAGE_PATCHLEVEL* = 5
# This macro can be used to fill a version structure with the compile-time
# version of the SDL_image library.

View file

@ -161,9 +161,9 @@ else:
const
MixerLibName = "libSDL_mixer.so"
const
MAJOR_VERSION* = 1'i8
MINOR_VERSION* = 2'i8
PATCHLEVEL* = 7'i8 # Backwards compatibility
MAJOR_VERSION* = 1
MINOR_VERSION* = 2
PATCHLEVEL* = 7 # Backwards compatibility
CHANNELS* = 8 # Good default values for a PC soundcard
DEFAULT_FREQUENCY* = 22050

View file

@ -15,9 +15,9 @@ else:
const
MixerLibName = "libSDL_mixer.so"
const
MAJOR_VERSION* = 1'i8
MINOR_VERSION* = 2'i8
PATCHLEVEL* = 7'i8 # Backwards compatibility
MAJOR_VERSION* = 1
MINOR_VERSION* = 2
PATCHLEVEL* = 7 # Backwards compatibility
CHANNELS* = 8 # Good default values for a PC soundcard
DEFAULT_FREQUENCY* = 22050

View file

@ -122,9 +122,9 @@ else:
const
NetLibName = "libSDL_net.so"
const #* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *
MAJOR_VERSION* = 1'i8
MINOR_VERSION* = 2'i8
PATCHLEVEL* = 5'i8 # SDL_Net.h constants
MAJOR_VERSION* = 1
MINOR_VERSION* = 2
PATCHLEVEL* = 5 # SDL_Net.h constants
#* Resolve a host name and port to an IP address in network form.
# If the function succeeds, it will return 0.
# If the host couldn't be resolved, the host portion of the returned

View file

@ -165,9 +165,9 @@ else:
const
ttfLibName = "libSDL_ttf.so(|.1|.0)"
const
MAJOR_VERSION* = 2'i8
MINOR_VERSION* = 0'i8
PATCHLEVEL* = 8'i8 # Backwards compatibility
MAJOR_VERSION* = 2
MINOR_VERSION* = 0
PATCHLEVEL* = 8 # Backwards compatibility
STYLE_NORMAL* = 0x00000000
STYLE_BOLD* = 0x00000001

View file

@ -171,9 +171,9 @@ proc filter_deblocking*(): PFilter{.cdecl,
# SMPEG.h
#------------------------------------------------------------------------------
const
MAJOR_VERSION* = 0'i8
MINOR_VERSION* = 4'i8
PATCHLEVEL* = 2'i8
MAJOR_VERSION* = 0
MINOR_VERSION* = 4
PATCHLEVEL* = 2
type
TVersion*{.final.} = object

View file

@ -160,19 +160,20 @@ proc inflateSyncPoint*(z: PZstream): int32{.cdecl, dynlib: libz,
proc get_crc_table*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".}
proc deflateInit(strm: var TZStream, level: int32): int32 =
result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream))
result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream).cint)
proc inflateInit(strm: var TZStream): int32 =
result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream))
result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream).cint)
proc deflateInit2(strm: var TZStream,
level, `method`, windowBits, memLevel,
strategy: int32): int32 =
result = deflateInit2u(strm, level, `method`, windowBits, memLevel,
strategy, ZLIB_VERSION(), sizeof(TZStream))
strategy, ZLIB_VERSION(), sizeof(TZStream).cint)
proc inflateInit2(strm: var TZStream, windowBits: int32): int32 =
result = inflateInit2u(strm, windowBits, ZLIB_VERSION(), sizeof(TZStream))
result = inflateInit2u(strm, windowBits, ZLIB_VERSION(),
sizeof(TZStream).cint)
proc zlibAllocMem*(AppData: Pointer, Items, Size: int): Pointer {.cdecl.} =
result = Alloc(Items * Size)

View file

@ -10,7 +10,7 @@ import
osproc,
cairowin32, cairoxlib,
gl, glut, glu, glx, glext, wingl,
lua, lualib, lauxlib, mysql, sqlite3,
lua, lualib, lauxlib, mysql, sqlite3, db_mongo
writeln(stdout, "test compilation of binding modules")

View file

@ -1,12 +1,11 @@
version 0.9.0
=============
- deprecate ``var x, y = 0`` as it's confusing for tuple consistency
- finish support for unsigned ints:
- document new type conversion rules
- support more unsigned operations
- test codegen
- provide ``$`` for unsigned ints
Debug GC session:
- test sequence of closures; especially that the GC does not leak for those!
New pragmas:
@ -15,8 +14,6 @@ New pragmas:
- document destructors
- ``borrow`` needs to take type classes into account
- make templates hygienic by default: try to gensym() everything in the 'block'
of a template; find a better solution for gensym instead of `*ident`
- introduce ``;`` to the parser
- make use of ``tyIter`` to fix the implicit items/pairs issue
- ``=`` should be overloadable; requires specialization for ``=``
@ -50,7 +47,10 @@ version 0.9.XX
- document it
- fix exception handling
- make templates hygienic by default: try to gensym() everything in the 'block'
of a template; find a better solution for gensym instead of `*ident`
- document nimdoc properly finally
- make 'clamp' a magic for the range stuff
- implement a warning message for shadowed 'result' variable
- implement the high level optimizer
- change overloading resolution
@ -101,7 +101,7 @@ Library
newSeq(result, a.len)
for i in 0..a.len-1: result[i] = a[i]
--> ensure @[] calls the array version!
--> ensure @[] still calls the array version!
Low priority
@ -147,7 +147,6 @@ Further optimization ideas
Version 2 and beyond
====================
- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
"stop the world". However, it may be worthwhile to generate explicit
(or implicit) syncGC() calls in loops. Automatic loop injection seems

View file

@ -87,7 +87,11 @@ Changes affecting backwards compatibility
- Deprecated the ``ssl`` module.
- Deprecated ``nimrod pretty`` as it never worked good enough and has some
inherent problems.
- The integer promotion rules changed.
- The integer promotion rules changed; the compiler is now less picky in some
situations and more picky in other situations: In particular implicit
conversions from ``int`` to ``int32`` are now forbidden.
- ``system.byte`` is now an alias for ``uint8``; it used to be an alias
to ``int8``.
Compiler Additions
@ -123,6 +127,7 @@ Language Additions
- The apostrophe in type suffixes for numerical literal is now optional.
- Unsigned integer types have been added.
- The integer promotion rules changed.
- Nimrod now tracks proper intervals for ``range`` over some built-in operators.
2012-02-09 Version 0.8.14 released