added missing files;change config for bug #374441

This commit is contained in:
Andreas Rumpf
2009-05-10 22:35:58 +02:00
parent d54b333e7e
commit c7e144f978
11 changed files with 324 additions and 15 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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)

View File

@@ -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))

View File

@@ -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
View 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

View File

@@ -23,6 +23,7 @@ const
reallyOsDealloc = true
coalescRight = true
coalescLeft = true
overwriteFree = false
type
PPointer = ptr pointer

View File

@@ -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;

View File

@@ -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
View 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, "")

View File

@@ -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