changed integer promotion rules; added math.fmod
This commit is contained in:
parent
b5d34242ca
commit
2900ceae35
13 changed files with 83 additions and 71 deletions
|
|
@ -334,12 +334,10 @@ type
|
||||||
tfEnumHasHoles, # enum cannot be mapped into a range
|
tfEnumHasHoles, # enum cannot be mapped into a range
|
||||||
tfShallow, # type can be shallow copied on assignment
|
tfShallow, # type can be shallow copied on assignment
|
||||||
tfThread, # proc type is marked as ``thread``
|
tfThread, # proc type is marked as ``thread``
|
||||||
tfUniIntLit # type represents literal value that could be either
|
tfFromGeneric, # type is an instantiation of a generic; this is needed
|
||||||
# singed or unsigned integer (e.g. 100)
|
|
||||||
tfFromGeneric # type is an instantiation of a generic; this is needed
|
|
||||||
# because for instantiations of objects, structural
|
# because for instantiations of objects, structural
|
||||||
# type equality has to be used
|
# 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
|
tfAny # type class requires any constraint to be met
|
||||||
|
|
||||||
TTypeFlags* = set[TTypeFlag]
|
TTypeFlags* = set[TTypeFlag]
|
||||||
|
|
@ -587,6 +585,7 @@ type
|
||||||
# for range types a nkRange node
|
# for range types a nkRange node
|
||||||
# for record types a nkRecord node
|
# for record types a nkRecord node
|
||||||
# for enum types a list of symbols
|
# for enum types a list of symbols
|
||||||
|
# for tyInt it can be the int literal
|
||||||
# else: unused
|
# else: unused
|
||||||
destructor*: PSym # destructor. warning: nil here may not necessary
|
destructor*: PSym # destructor. warning: nil here may not necessary
|
||||||
# mean that there is no destructor.
|
# mean that there is no destructor.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ proc FinishSystem*(tab: TStrTable)
|
||||||
proc getSysSym*(name: string): PSym
|
proc getSysSym*(name: string): PSym
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
var
|
var
|
||||||
gSysTypes: array[TTypeKind, PType]
|
gSysTypes: array[TTypeKind, PType]
|
||||||
compilerprocs: TStrTable
|
compilerprocs: TStrTable
|
||||||
|
|
||||||
|
|
@ -73,7 +73,26 @@ proc getSysType(kind: TTypeKind): PType =
|
||||||
if result.kind != kind:
|
if result.kind != kind:
|
||||||
InternalError("wanted: " & $kind & " got: " & $result.kind)
|
InternalError("wanted: " & $kind & " got: " & $result.kind)
|
||||||
if result == nil: InternalError("type not found: " & $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 =
|
proc getCompilerProc(name: string): PSym =
|
||||||
var ident = getIdent(name, hashIgnoreStyle(name))
|
var ident = getIdent(name, hashIgnoreStyle(name))
|
||||||
result = StrTableGet(compilerprocs, ident)
|
result = StrTableGet(compilerprocs, ident)
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ type
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
||||||
warnXisPassedToProcVar, warnAnalysisLoophole,
|
warnXisPassedToProcVar, warnAnalysisLoophole,
|
||||||
warnDifferentHeaps, warnWriteToForeignHeap,
|
warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitNarrowing,
|
||||||
warnUser,
|
warnUser,
|
||||||
hintSuccess, hintSuccessX,
|
hintSuccess, hintSuccessX,
|
||||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||||
|
|
@ -345,6 +345,7 @@ const
|
||||||
warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
|
warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
|
||||||
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
||||||
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
||||||
|
warnImplicitNarrowing: "implicit narrowing conversion: '$1'",
|
||||||
warnUser: "$1 [User]",
|
warnUser: "$1 [User]",
|
||||||
hintSuccess: "operation successful [Success]",
|
hintSuccess: "operation successful [Success]",
|
||||||
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]",
|
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]",
|
||||||
|
|
@ -362,13 +363,14 @@ const
|
||||||
hintUser: "$1 [User]"]
|
hintUser: "$1 [User]"]
|
||||||
|
|
||||||
const
|
const
|
||||||
WarningsToStr*: array[0..16, string] = ["CannotOpenFile", "OctalEscape",
|
WarningsToStr*: array[0..17, string] = ["CannotOpenFile", "OctalEscape",
|
||||||
"XIsNeverRead", "XmightNotBeenInit",
|
"XIsNeverRead", "XmightNotBeenInit",
|
||||||
"Deprecated", "ConfigDeprecated",
|
"Deprecated", "ConfigDeprecated",
|
||||||
"SmallLshouldNotBeUsed", "UnknownMagic",
|
"SmallLshouldNotBeUsed", "UnknownMagic",
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
||||||
"CommentXIgnored", "XisPassedToProcVar",
|
"CommentXIgnored", "XisPassedToProcVar",
|
||||||
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "User"]
|
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
|
||||||
|
"ImplicitNarrowing,", "User"]
|
||||||
|
|
||||||
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
||||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||||
|
|
|
||||||
|
|
@ -1285,20 +1285,6 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
GlobalError(n.info, errInvalidExpressionX,
|
GlobalError(n.info, errInvalidExpressionX,
|
||||||
renderTree(a, {renderNoComments}))
|
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 =
|
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
result = n
|
result = n
|
||||||
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
||||||
|
|
@ -1319,15 +1305,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if result.typ == nil:
|
if result.typ == nil:
|
||||||
let i = result.intVal
|
let i = result.intVal
|
||||||
if i >= low(int32) and i <= high(int32):
|
if i >= low(int32) and i <= high(int32):
|
||||||
if i >= 0:
|
result.typ = getSysType(tyInt)
|
||||||
result.typ = uniIntType(tyInt).memoize
|
|
||||||
else:
|
|
||||||
result.typ = getSysType(tyInt)
|
|
||||||
else:
|
else:
|
||||||
if i >= 0:
|
result.typ = getSysType(tyInt64)
|
||||||
result.typ = uniIntType(tyInt64).memoize
|
|
||||||
else:
|
|
||||||
result.typ = getSysType(tyInt64)
|
|
||||||
of nkInt8Lit:
|
of nkInt8Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(tyInt8)
|
if result.typ == nil: result.typ = getSysType(tyInt8)
|
||||||
of nkInt16Lit:
|
of nkInt16Lit:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
|
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
|
||||||
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
||||||
commands
|
commands, magicsys
|
||||||
|
|
||||||
proc getConstExpr*(m: PSym, n: PNode): PNode
|
proc getConstExpr*(m: PSym, n: PNode): PNode
|
||||||
# evaluates the constant expression or returns nil if it is no constant
|
# evaluates the constant expression or returns nil if it is no constant
|
||||||
|
|
|
||||||
|
|
@ -159,16 +159,29 @@ proc concreteType(mapping: TIdTable, t: PType): PType =
|
||||||
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
else:
|
else:
|
||||||
var k = skipTypes(a, {tyRange}).kind
|
var k = skipTypes(a, {tyRange}).kind
|
||||||
if k == f.kind: result = isSubtype
|
if k == f.kind: result = isSubtype
|
||||||
elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv
|
elif k == tyInt:
|
||||||
elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv
|
# and a.n != nil and a.n.intVal >= firstOrd(f) and
|
||||||
elif f.kind in {tyUInt..tyUInt64} and k == tyInt and tfUniIntLit in a.flags:
|
# 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
|
result = isIntConv
|
||||||
elif k >= min and k <= max: result = isConvertible
|
elif k >= min and k <= max: result = isConvertible
|
||||||
else: result = isNone
|
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 =
|
proc handleFloatRange(f, a: PType): TTypeRelation =
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
|
|
@ -227,10 +240,10 @@ proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
if tfAny in f.flags:
|
if tfAny in f.flags:
|
||||||
if match == true:
|
if match:
|
||||||
return isGeneric
|
return isGeneric
|
||||||
else:
|
else:
|
||||||
if match == false:
|
if not match:
|
||||||
return isNone
|
return isNone
|
||||||
|
|
||||||
# if the loop finished without returning, either all constraints matched
|
# 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
|
if a.kind == tyGenericInst and
|
||||||
skipTypes(f, {tyVar}).kind notin {
|
skipTypes(f, {tyVar}).kind notin {
|
||||||
tyGenericBody, tyGenericInvokation,
|
tyGenericBody, tyGenericInvokation,
|
||||||
tyGenericParam, tyTypeClass }:
|
tyGenericParam, tyTypeClass}:
|
||||||
return typeRel(mapping, f, lastSon(a))
|
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])
|
return typeRel(mapping, f, a.sons[0])
|
||||||
case f.kind
|
case f.kind
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
|
|
@ -302,18 +315,20 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = typeRel(mapping, base(a), base(f))
|
result = typeRel(mapping, base(a), base(f))
|
||||||
if result < isGeneric: result = isNone
|
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
|
result = isConvertible # a convertible to f
|
||||||
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
|
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
|
||||||
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
|
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
|
||||||
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
|
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 tyInt64: result = handleRange(f, a, tyInt, tyInt64)
|
||||||
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
|
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
|
||||||
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
|
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
|
||||||
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
|
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
|
||||||
of tyUInt32: result = handleRange(f, a, tyUInt, tyUInt32)
|
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
|
||||||
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
|
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
|
||||||
of tyFloat: result = handleFloatRange(f, a)
|
of tyFloat: result = handleFloatRange(f, a)
|
||||||
of tyFloat32: result = handleFloatRange(f, a)
|
of tyFloat32: result = handleFloatRange(f, a)
|
||||||
of tyFloat64: 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:
|
# use default value:
|
||||||
setSon(m.call, formal.position + 1, copyTree(formal.ast))
|
setSon(m.call, formal.position + 1, copyTree(formal.ast))
|
||||||
inc(f)
|
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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
#
|
#
|
||||||
# * inlines iterators
|
# * inlines iterators
|
||||||
# * inlines constants
|
# * inlines constants
|
||||||
# * performes contant folding
|
# * performes constant folding
|
||||||
# * converts "continue" to "break"
|
# * converts "continue" to "break"
|
||||||
# * introduces method dispatchers
|
# * introduces method dispatchers
|
||||||
# * performs lambda lifting for closure support
|
# * performs lambda lifting for closure support
|
||||||
|
|
@ -401,7 +401,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
|
||||||
result = transformSons(c, n)
|
result = transformSons(c, n)
|
||||||
else:
|
else:
|
||||||
# generate a range check:
|
# 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)
|
result = newTransNode(nkChckRange64, n, 3)
|
||||||
else:
|
else:
|
||||||
result = newTransNode(nkChckRange, n, 3)
|
result = newTransNode(nkChckRange, n, 3)
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ type
|
||||||
Tid* {.importc: "id_t", header: "<sys/types.h>".} = int
|
Tid* {.importc: "id_t", header: "<sys/types.h>".} = int
|
||||||
Tino* {.importc: "ino_t", header: "<sys/types.h>".} = int
|
Tino* {.importc: "ino_t", header: "<sys/types.h>".} = int
|
||||||
TKey* {.importc: "key_t", header: "<sys/types.h>".} = int
|
TKey* {.importc: "key_t", header: "<sys/types.h>".} = int
|
||||||
TMode* {.importc: "mode_t", header: "<sys/types.h>".} = int
|
TMode* {.importc: "mode_t", header: "<sys/types.h>".} = cint
|
||||||
TNlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int
|
TNlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int
|
||||||
TOff* {.importc: "off_t", header: "<sys/types.h>".} = int64
|
TOff* {.importc: "off_t", header: "<sys/types.h>".} = int64
|
||||||
TPid* {.importc: "pid_t", header: "<sys/types.h>".} = int
|
TPid* {.importc: "pid_t", header: "<sys/types.h>".} = int
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,8 @@ when not defined(ECMAScript):
|
||||||
proc floor*(x: float): float {.importc: "floor", nodecl.}
|
proc floor*(x: float): float {.importc: "floor", nodecl.}
|
||||||
proc ceil*(x: float): float {.importc: "ceil", nodecl.}
|
proc ceil*(x: float): float {.importc: "ceil", nodecl.}
|
||||||
|
|
||||||
|
proc fmod*(x, y: float): float {.importc: "fmod", header: "<math.h>".}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
||||||
proc floor*(x: float): float {.importc: "Math.floor", nodecl.}
|
proc floor*(x: float): float {.importc: "Math.floor", nodecl.}
|
||||||
|
|
@ -230,10 +232,13 @@ else:
|
||||||
var y = exp(2.0*x)
|
var y = exp(2.0*x)
|
||||||
return (y-1.0)/(y+1.0)
|
return (y-1.0)/(y+1.0)
|
||||||
|
|
||||||
|
proc `mod`*(x, y: float): float =
|
||||||
|
result = if y == 0.0: x else: x - y * (x/y).floor
|
||||||
|
|
||||||
type
|
type
|
||||||
TRunningStat* = object ## an accumulator for statistical data
|
TRunningStat* {.pure,final.} = object ## an accumulator for statistical data
|
||||||
n*: int ## number of pushed data
|
n*: int ## number of pushed data
|
||||||
sum*, min*, max*, mean*: float ## self-explaining
|
sum*, min*, max*, mean*: float ## self-explaining
|
||||||
oldM, oldS, newS: float
|
oldM, oldS, newS: float
|
||||||
|
|
||||||
proc push*(s: var TRunningStat, x: float) =
|
proc push*(s: var TRunningStat, x: float) =
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ when defined(posix):
|
||||||
const
|
const
|
||||||
PROT_READ = 1 # page can be read
|
PROT_READ = 1 # page can be read
|
||||||
PROT_WRITE = 2 # page can be written
|
PROT_WRITE = 2 # page can be written
|
||||||
MAP_PRIVATE = 2 # Changes are private
|
MAP_PRIVATE = 2'i32 # Changes are private
|
||||||
|
|
||||||
when defined(macosx) or defined(bsd):
|
when defined(macosx) or defined(bsd):
|
||||||
const MAP_ANONYMOUS = 0x1000
|
const MAP_ANONYMOUS = 0x1000
|
||||||
|
|
@ -40,7 +40,7 @@ when defined(posix):
|
||||||
|
|
||||||
proc osAllocPages(size: int): pointer {.inline.} =
|
proc osAllocPages(size: int): pointer {.inline.} =
|
||||||
result = mmap(nil, size, PROT_READ or PROT_WRITE,
|
result = mmap(nil, size, PROT_READ or PROT_WRITE,
|
||||||
MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
|
MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
|
||||||
if result == nil or result == cast[pointer](-1):
|
if result == nil or result == cast[pointer](-1):
|
||||||
raiseOutOfMem()
|
raiseOutOfMem()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
{.push hints:off}
|
{.push hints:off}
|
||||||
|
|
||||||
proc c_strcmp(a, b: CString): cint {.nodecl, noSideEffect, importc: "strcmp".}
|
proc c_strcmp(a, b: CString): cint {.nodecl, noSideEffect, importc: "strcmp".}
|
||||||
proc c_memcmp(a, b: CString, size: cint): cint {.
|
proc c_memcmp(a, b: CString, size: int): cint {.
|
||||||
nodecl, noSideEffect, importc: "memcmp".}
|
nodecl, noSideEffect, importc: "memcmp".}
|
||||||
proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
|
proc c_memcpy(a, b: CString, size: int) {.nodecl, importc: "memcpy".}
|
||||||
proc c_strlen(a: CString): int {.nodecl, noSideEffect, importc: "strlen".}
|
proc c_strlen(a: CString): int {.nodecl, noSideEffect, importc: "strlen".}
|
||||||
proc c_memset(p: pointer, value: cint, size: int) {.nodecl, importc: "memset".}
|
proc c_memset(p: pointer, value: cint, size: int) {.nodecl, importc: "memset".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,8 +199,8 @@ proc Open(f: var TFile, filename: string,
|
||||||
var p: pointer = fopen(filename, FormatOpen[mode])
|
var p: pointer = fopen(filename, FormatOpen[mode])
|
||||||
result = (p != nil)
|
result = (p != nil)
|
||||||
f = cast[TFile](p)
|
f = cast[TFile](p)
|
||||||
if bufSize > 0:
|
if bufSize > 0 and bufSize <= high(cint):
|
||||||
if setvbuf(f, nil, IOFBF, bufSize) != 0'i32:
|
if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32:
|
||||||
raise newException(EOutOfMemory, "out of memory")
|
raise newException(EOutOfMemory, "out of memory")
|
||||||
elif bufSize == 0:
|
elif bufSize == 0:
|
||||||
discard setvbuf(f, nil, IONBF, 0)
|
discard setvbuf(f, nil, IONBF, 0)
|
||||||
|
|
|
||||||
5
todo.txt
5
todo.txt
|
|
@ -11,6 +11,7 @@ New pragmas:
|
||||||
- ``borrow`` needs to take type classes into account
|
- ``borrow`` needs to take type classes into account
|
||||||
- make templates hygienic by default: try to gensym() everything in the 'block'
|
- make templates hygienic by default: try to gensym() everything in the 'block'
|
||||||
of a template; find a better solution for gensym instead of `*ident`
|
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
|
- make use of ``tyIter`` to fix the implicit items/pairs issue
|
||||||
- ``=`` should be overloadable; requires specialization for ``=``
|
- ``=`` should be overloadable; requires specialization for ``=``
|
||||||
- optimize genericAssign in the code generator
|
- optimize genericAssign in the code generator
|
||||||
|
|
@ -21,8 +22,7 @@ New pragmas:
|
||||||
- implement "closure tuple consists of a single 'ref'" optimization
|
- implement "closure tuple consists of a single 'ref'" optimization
|
||||||
|
|
||||||
- document 'do' notation
|
- document 'do' notation
|
||||||
- unsigned ints and bignums; requires abstract integer literal type:
|
- finish support for unsigned ints
|
||||||
use tyInt+node for that
|
|
||||||
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
||||||
indentation handling is quite complex too; problem with exception handling
|
indentation handling is quite complex too; problem with exception handling
|
||||||
is that often the scope of ``try`` is wrong and apart from that ``try`` is
|
is that often the scope of ``try`` is wrong and apart from that ``try`` is
|
||||||
|
|
@ -100,6 +100,7 @@ Library
|
||||||
Low priority
|
Low priority
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
- bignums
|
||||||
- change how comments are part of the AST
|
- change how comments are part of the AST
|
||||||
- ``with proc `+`(x, y: T): T`` for generic code
|
- ``with proc `+`(x, y: T): T`` for generic code
|
||||||
- new feature: ``distinct T with operations``
|
- new feature: ``distinct T with operations``
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue