mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
added missing files;change config for bug #374441
This commit is contained in:
@@ -522,7 +522,7 @@ Result variable
|
||||
---------------
|
||||
A procedure that returns a value has an implicit ``result`` variable that
|
||||
represents the return value. A ``return`` statement with no expression is a
|
||||
shorthand for ``return result``. So all tree code snippets are equivalent:
|
||||
shorthand for ``return result``. So all three code snippets are equivalent:
|
||||
|
||||
.. code-block:: nimrod
|
||||
return 42
|
||||
@@ -556,7 +556,7 @@ caller, a ``var`` parameter can be used:
|
||||
|
||||
In the example, ``res`` and ``remainder`` are `var parameters`.
|
||||
Var parameters can be modified by the procedure and the changes are
|
||||
visible to the caller.
|
||||
visible to the caller.
|
||||
|
||||
|
||||
Discard statement
|
||||
@@ -952,8 +952,8 @@ Operation Comment
|
||||
``dec(x, n)`` decrements `x` by `n`; `n` is an integer
|
||||
``succ(x)`` returns the successor of `x`
|
||||
``succ(x, n)`` returns the `n`'th successor of `x`
|
||||
``succ(x)`` returns the predecessor of `x`
|
||||
``succ(x, n)`` returns the `n`'th predecessor of `x`
|
||||
``prec(x)`` returns the predecessor of `x`
|
||||
``pred(x, n)`` returns the `n`'th predecessor of `x`
|
||||
----------------- --------------------------------------------------------
|
||||
|
||||
The ``inc dec succ pred`` operations can fail by raising an `EOutOfRange` or
|
||||
|
||||
@@ -34,7 +34,7 @@ While Nimrod's support for object oriented programming (OOP) is minimalistic,
|
||||
powerful OOP technics can be used. OOP is seen as *one* way to design a
|
||||
program, not *the only* way. Often a procedural approach leads to simpler
|
||||
and more efficient code. In particular, prefering aggregation over inheritance
|
||||
often yields to a better design.
|
||||
often results in a better design.
|
||||
|
||||
|
||||
Objects
|
||||
@@ -422,7 +422,7 @@ containers:
|
||||
else:
|
||||
var it = root
|
||||
while it != nil:
|
||||
# compare the data items; uses the generic ``cmd`` proc
|
||||
# compare the data items; uses the generic ``cmp`` proc
|
||||
# that works for any type that has a ``==`` and ``<`` operator
|
||||
var c = cmp(it.data, n.data)
|
||||
if c < 0:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import os, streams, parsecsv, strutils, math
|
||||
|
||||
if paramCount() < 1:
|
||||
quit("Usage: sumcsv filename[.csv]")
|
||||
quit("Usage: statcsv filename[.csv]")
|
||||
|
||||
var filename = appendFileExt(ParamStr(1), "csv")
|
||||
var s = newFileStream(filename, fmRead)
|
||||
|
||||
@@ -493,6 +493,10 @@ proc rawDealloc(a: var TAllocator, p: pointer) =
|
||||
f.zeroField = 0
|
||||
f.next = c.freeList
|
||||
c.freeList = f
|
||||
when overwriteFree:
|
||||
# set to 0xff to check for usage after free bugs:
|
||||
c_memset(cast[pointer](cast[int](p) +% sizeof(TFreeCell)), -1'i32,
|
||||
s -% sizeof(TFreeCell))
|
||||
# check if it is not in the freeSmallChunks[s] list:
|
||||
if c.free < s:
|
||||
assert c notin a.freeSmallChunks[s div memAlign]
|
||||
@@ -506,6 +510,8 @@ proc rawDealloc(a: var TAllocator, p: pointer) =
|
||||
c.size = SmallChunkSize
|
||||
freeBigChunk(a, cast[PBigChunk](c))
|
||||
else:
|
||||
# set to 0xff to check for usage after free bugs:
|
||||
when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead())
|
||||
# free big chunk
|
||||
freeBigChunk(a, cast[PBigChunk](c))
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ proc c_strcmp(a, b: CString): cint {.nodecl, importc: "strcmp".}
|
||||
proc c_memcmp(a, b: CString, size: cint): cint {.nodecl, importc: "memcmp".}
|
||||
proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
|
||||
proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
|
||||
proc c_memset(p: pointer, value: cint, size: int) {.nodecl, importc: "memset".}
|
||||
|
||||
type
|
||||
C_TextFile {.importc: "FILE", nodecl, final.} = object # empty record for
|
||||
|
||||
196
lib/cellsets.nim
Normal file
196
lib/cellsets.nim
Normal file
@@ -0,0 +1,196 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2009 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# Efficient set of pointers for the GC (and repr)
|
||||
|
||||
type
|
||||
TCell {.pure.} = object
|
||||
refcount: int # the refcount and some flags
|
||||
typ: PNimType
|
||||
when debugGC:
|
||||
filename: cstring
|
||||
line: int
|
||||
|
||||
PCell = ptr TCell
|
||||
|
||||
PPageDesc = ptr TPageDesc
|
||||
TBitIndex = range[0..UnitsPerPage-1]
|
||||
TPageDesc {.final, pure.} = object
|
||||
next: PPageDesc # all nodes are connected with this pointer
|
||||
key: TAddress # start address at bit 0
|
||||
bits: array[TBitIndex, int] # a bit vector
|
||||
|
||||
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
||||
TCellSet {.final, pure.} = object
|
||||
counter, max: int
|
||||
head: PPageDesc
|
||||
data: PPageDescArray
|
||||
|
||||
PCellArray = ptr array[0..100_000_000, PCell]
|
||||
TCellSeq {.final, pure.} = object
|
||||
len, cap: int
|
||||
d: PCellArray
|
||||
|
||||
# ------------------- cell set handling ---------------------------------------
|
||||
|
||||
proc contains(s: TCellSeq, c: PCell): bool {.inline.} =
|
||||
for i in 0 .. s.len-1:
|
||||
if s.d[i] == c: return True
|
||||
return False
|
||||
|
||||
proc add(s: var TCellSeq, c: PCell) {.inline.} =
|
||||
if s.len >= s.cap:
|
||||
s.cap = s.cap * 3 div 2
|
||||
var d = cast[PCellArray](alloc(s.cap * sizeof(PCell)))
|
||||
copyMem(d, s.d, s.len * sizeof(PCell))
|
||||
dealloc(s.d)
|
||||
s.d = d
|
||||
# XXX: realloc?
|
||||
s.d[s.len] = c
|
||||
inc(s.len)
|
||||
|
||||
proc init(s: var TCellSeq, cap: int = 1024) =
|
||||
s.len = 0
|
||||
s.cap = cap
|
||||
s.d = cast[PCellArray](alloc0(cap * sizeof(PCell)))
|
||||
|
||||
proc deinit(s: var TCellSeq) =
|
||||
dealloc(s.d)
|
||||
s.d = nil
|
||||
s.len = 0
|
||||
s.cap = 0
|
||||
|
||||
const
|
||||
InitCellSetSize = 1024 # must be a power of two!
|
||||
|
||||
proc Init(s: var TCellSet) =
|
||||
s.data = cast[PPageDescArray](alloc0(InitCellSetSize * sizeof(PPageDesc)))
|
||||
s.max = InitCellSetSize-1
|
||||
s.counter = 0
|
||||
s.head = nil
|
||||
|
||||
proc Deinit(s: var TCellSet) =
|
||||
var it = s.head
|
||||
while it != nil:
|
||||
var n = it.next
|
||||
dealloc(it)
|
||||
it = n
|
||||
s.head = nil # play it safe here
|
||||
dealloc(s.data)
|
||||
s.data = nil
|
||||
s.counter = 0
|
||||
|
||||
proc nextTry(h, maxHash: int): int {.inline.} =
|
||||
result = ((5*h) + 1) and maxHash
|
||||
# For any initial h in range(maxHash), repeating that maxHash times
|
||||
# generates each int in range(maxHash) exactly once (see any text on
|
||||
# random-number generation for proof).
|
||||
|
||||
proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while t.data[h] != nil:
|
||||
if t.data[h].key == key: return t.data[h]
|
||||
h = nextTry(h, t.max)
|
||||
return nil
|
||||
|
||||
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
|
||||
var h = cast[int](desc.key) and t.max
|
||||
while data[h] != nil:
|
||||
assert(data[h] != desc)
|
||||
h = nextTry(h, t.max)
|
||||
assert(data[h] == nil)
|
||||
data[h] = desc
|
||||
|
||||
proc CellSetEnlarge(t: var TCellSet) =
|
||||
var oldMax = t.max
|
||||
t.max = ((t.max+1)*2)-1
|
||||
var n = cast[PPageDescArray](alloc0((t.max + 1) * sizeof(PPageDesc)))
|
||||
for i in 0 .. oldmax:
|
||||
if t.data[i] != nil:
|
||||
CellSetRawInsert(t, n, t.data[i])
|
||||
dealloc(t.data)
|
||||
t.data = n
|
||||
|
||||
proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while true:
|
||||
var x = t.data[h]
|
||||
if x == nil: break
|
||||
if x.key == key: return x
|
||||
h = nextTry(h, t.max)
|
||||
|
||||
if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4):
|
||||
CellSetEnlarge(t)
|
||||
inc(t.counter)
|
||||
h = cast[int](key) and t.max
|
||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||
assert(t.data[h] == nil)
|
||||
# the new page descriptor goes into result
|
||||
result = cast[PPageDesc](alloc0(sizeof(TPageDesc)))
|
||||
result.next = t.head
|
||||
result.key = key
|
||||
t.head = result
|
||||
t.data[h] = result
|
||||
|
||||
# ---------- slightly higher level procs --------------------------------------
|
||||
|
||||
proc contains(s: TCellSet, cell: PCell): bool =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc incl(s: var TCellSet, cell: PCell) {.noinline.} =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetPut(s, u shr PageShift)
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask))
|
||||
|
||||
proc excl(s: var TCellSet, cell: PCell) =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
t.bits[u shr IntShift] = (t.bits[u shr IntShift] and
|
||||
not (1 shl (u and IntMask)))
|
||||
|
||||
proc containsOrIncl(s: var TCellSet, cell: PCell): bool =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
|
||||
if not result:
|
||||
t.bits[u shr IntShift] = t.bits[u shr IntShift] or
|
||||
(1 shl (u and IntMask))
|
||||
else:
|
||||
Incl(s, cell)
|
||||
result = false
|
||||
|
||||
iterator elements(t: TCellSet): PCell {.inline.} =
|
||||
# while traversing it is forbidden to add pointers to the tree!
|
||||
var r = t.head
|
||||
while r != nil:
|
||||
var i = 0
|
||||
while i <= high(r.bits):
|
||||
var w = r.bits[i] # taking a copy of r.bits[i] here is correct, because
|
||||
# modifying operations are not allowed during traversation
|
||||
var j = 0
|
||||
while w != 0: # test all remaining bits for zero
|
||||
if (w and 1) != 0: # the bit is set!
|
||||
yield cast[PCell]((r.key shl PageShift) or
|
||||
(i shl IntShift +% j) *% MemAlign)
|
||||
inc(j)
|
||||
w = w shr 1
|
||||
inc(i)
|
||||
r = r.next
|
||||
|
||||
@@ -23,6 +23,7 @@ const
|
||||
reallyOsDealloc = true
|
||||
coalescRight = true
|
||||
coalescLeft = true
|
||||
overwriteFree = false
|
||||
|
||||
type
|
||||
PPointer = ptr pointer
|
||||
|
||||
@@ -358,7 +358,8 @@ begin
|
||||
end
|
||||
end;
|
||||
g.len := pos - g.pos;
|
||||
if (g.kind <> gtEof) and (g.len <= 0) then InternalError('nimNextToken');
|
||||
if (g.kind <> gtEof) and (g.len <= 0) then
|
||||
InternalError('nimNextToken: ' + toString(g.buf));
|
||||
g.pos := pos;
|
||||
end;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
//
|
||||
// The Nimrod Compiler
|
||||
// (c) Copyright 2008 Andreas Rumpf
|
||||
// (c) Copyright 2009 Andreas Rumpf
|
||||
//
|
||||
// See the file "copying.txt", included in this
|
||||
// distribution, for details about the copyright.
|
||||
@@ -45,6 +45,7 @@ function toString(i: BiggestInt): string; overload;
|
||||
//function toString(i: int): string; overload;
|
||||
function ToStringF(const r: Real): string; overload;
|
||||
function ToString(b: Boolean): string; overload;
|
||||
function ToString(b: PChar): string; overload;
|
||||
|
||||
function IntToStr(i: BiggestInt; minChars: int): string;
|
||||
|
||||
@@ -415,6 +416,11 @@ begin
|
||||
result := sysUtils.intToStr(i);
|
||||
end;
|
||||
|
||||
function ToString(b: PChar): string; overload;
|
||||
begin
|
||||
result := string(b);
|
||||
end;
|
||||
|
||||
function normalize(const s: string): string;
|
||||
var
|
||||
i: int;
|
||||
|
||||
103
pycompab.py
Normal file
103
pycompab.py
Normal file
@@ -0,0 +1,103 @@
|
||||
""" Python compability library
|
||||
|
||||
With careful and painful coding, compability from Python 1.5.2 up to 3.0
|
||||
is achieved. Don't try this at home.
|
||||
|
||||
Copyright 2009, Andreas Rumpf
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
python3 = sys.version[0] >= "3"
|
||||
python26 = sys.version[:3] == "2.6"
|
||||
|
||||
true, false = 0==0, 0==1
|
||||
|
||||
if python3:
|
||||
sys.exit("This script does not yet work with Python 3.0")
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
if python3:
|
||||
def replace(s, a, b): return s.replace(a, b)
|
||||
def lower(s): return s.lower()
|
||||
def join(a, s=""): return s.join(a)
|
||||
def find(s, a): return s.find(a)
|
||||
def split(s, a=None): return s.split(a)
|
||||
def strip(s): return s.strip()
|
||||
|
||||
def has_key(dic, key): return key in dic
|
||||
else:
|
||||
from string import replace, lower, join, find, split, strip
|
||||
|
||||
def has_key(dic, key): return dic.has_key(key)
|
||||
|
||||
if not python3 and not python26:
|
||||
import md5
|
||||
def newMD5(): return md5.new()
|
||||
def MD5update(obj, x):
|
||||
return obj.update(x)
|
||||
else:
|
||||
import hashlib
|
||||
def newMD5(): return hashlib.md5()
|
||||
def MD5update(obj, x):
|
||||
if python26:
|
||||
return obj.update(x)
|
||||
else:
|
||||
return obj.update(bytes(x, "utf-8"))
|
||||
|
||||
def mydigest(hasher):
|
||||
result = ""
|
||||
for c in hasher.digest():
|
||||
if python3:
|
||||
x = hex(c)[2:]
|
||||
else:
|
||||
x = hex(ord(c))[2:]
|
||||
if len(x) == 1: x = "0" + x
|
||||
result = result + x
|
||||
return result
|
||||
|
||||
def Subs(frmt, *args, **substitution):
|
||||
DIGITS = "0123456789"
|
||||
LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
chars = DIGITS+LETTERS+"_"
|
||||
d = substitution
|
||||
a = args
|
||||
result = []
|
||||
i = 0
|
||||
L = len(frmt)
|
||||
while i < L:
|
||||
if frmt[i] == '$':
|
||||
i = i+1
|
||||
if frmt[i] == '$':
|
||||
result.append('$')
|
||||
i = i+1
|
||||
elif frmt[i] == '{':
|
||||
i = i+1
|
||||
j = i
|
||||
while frmt[i] != '}': i = i+1
|
||||
i = i+1 # skip }
|
||||
x = frmt[j:i-1]
|
||||
if x[0] in DIGITS:
|
||||
result.append(str(a[int(x)-1]))
|
||||
else:
|
||||
result.append(str(d[x]))
|
||||
elif frmt[i] in chars:
|
||||
j = i
|
||||
i = i+1
|
||||
while i < len(frmt) and frmt[i] in chars: i = i + 1
|
||||
x = frmt[j:i]
|
||||
if x[0] in DIGITS:
|
||||
result.append(str(a[int(x)-1]))
|
||||
else:
|
||||
result.append(str(d[x]))
|
||||
else:
|
||||
assert(false)
|
||||
else:
|
||||
result.append(frmt[i])
|
||||
i = i+1
|
||||
return join(result, "")
|
||||
|
||||
@@ -5,12 +5,7 @@
|
||||
@if llvm_gcc or gcc:
|
||||
# GCC, LLVM and Visual C++ have a problem to optimize some modules.
|
||||
# This is really strange.
|
||||
@if windows or macosX:
|
||||
cgen.speed = "-O0"
|
||||
@else:
|
||||
cgen.speed = "-O1 -fno-strict-aliasing"
|
||||
@end
|
||||
cgen.speed = "-O0"
|
||||
@elif vcc:
|
||||
cgen.speed = ""
|
||||
@end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user