added missing files;change config for bug #374441

This commit is contained in:
Andreas Rumpf 2009-05-10 22:35:58 +02:00
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 A procedure that returns a value has an implicit ``result`` variable that
represents the return value. A ``return`` statement with no expression is a 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 .. code-block:: nimrod
return 42 return 42
@ -556,7 +556,7 @@ caller, a ``var`` parameter can be used:
In the example, ``res`` and ``remainder`` are `var parameters`. In the example, ``res`` and ``remainder`` are `var parameters`.
Var parameters can be modified by the procedure and the changes are Var parameters can be modified by the procedure and the changes are
visible to the caller. visible to the caller.
Discard statement Discard statement
@ -952,8 +952,8 @@ Operation Comment
``dec(x, n)`` decrements `x` by `n`; `n` is an integer ``dec(x, n)`` decrements `x` by `n`; `n` is an integer
``succ(x)`` returns the successor of `x` ``succ(x)`` returns the successor of `x`
``succ(x, n)`` returns the `n`'th successor of `x` ``succ(x, n)`` returns the `n`'th successor of `x`
``succ(x)`` returns the predecessor of `x` ``prec(x)`` returns the predecessor of `x`
``succ(x, n)`` returns the `n`'th 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 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 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 program, not *the only* way. Often a procedural approach leads to simpler
and more efficient code. In particular, prefering aggregation over inheritance and more efficient code. In particular, prefering aggregation over inheritance
often yields to a better design. often results in a better design.
Objects Objects
@ -422,7 +422,7 @@ containers:
else: else:
var it = root var it = root
while it != nil: 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 # that works for any type that has a ``==`` and ``<`` operator
var c = cmp(it.data, n.data) var c = cmp(it.data, n.data)
if c < 0: if c < 0:

View file

@ -6,7 +6,7 @@
import os, streams, parsecsv, strutils, math import os, streams, parsecsv, strutils, math
if paramCount() < 1: if paramCount() < 1:
quit("Usage: sumcsv filename[.csv]") quit("Usage: statcsv filename[.csv]")
var filename = appendFileExt(ParamStr(1), "csv") var filename = appendFileExt(ParamStr(1), "csv")
var s = newFileStream(filename, fmRead) var s = newFileStream(filename, fmRead)

View file

@ -493,6 +493,10 @@ proc rawDealloc(a: var TAllocator, p: pointer) =
f.zeroField = 0 f.zeroField = 0
f.next = c.freeList f.next = c.freeList
c.freeList = f 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: # check if it is not in the freeSmallChunks[s] list:
if c.free < s: if c.free < s:
assert c notin a.freeSmallChunks[s div memAlign] assert c notin a.freeSmallChunks[s div memAlign]
@ -506,6 +510,8 @@ proc rawDealloc(a: var TAllocator, p: pointer) =
c.size = SmallChunkSize c.size = SmallChunkSize
freeBigChunk(a, cast[PBigChunk](c)) freeBigChunk(a, cast[PBigChunk](c))
else: else:
# set to 0xff to check for usage after free bugs:
when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead())
# free big chunk # free big chunk
freeBigChunk(a, cast[PBigChunk](c)) 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_memcmp(a, b: CString, size: cint): cint {.nodecl, importc: "memcmp".}
proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".} proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".} proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
proc c_memset(p: pointer, value: cint, size: int) {.nodecl, importc: "memset".}
type type
C_TextFile {.importc: "FILE", nodecl, final.} = object # empty record for 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 reallyOsDealloc = true
coalescRight = true coalescRight = true
coalescLeft = true coalescLeft = true
overwriteFree = false
type type
PPointer = ptr pointer PPointer = ptr pointer

View file

@ -358,7 +358,8 @@ begin
end end
end; end;
g.len := pos - g.pos; 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; g.pos := pos;
end; end;

View file

@ -1,7 +1,7 @@
// //
// //
// The Nimrod Compiler // The Nimrod Compiler
// (c) Copyright 2008 Andreas Rumpf // (c) Copyright 2009 Andreas Rumpf
// //
// See the file "copying.txt", included in this // See the file "copying.txt", included in this
// distribution, for details about the copyright. // distribution, for details about the copyright.
@ -45,6 +45,7 @@ function toString(i: BiggestInt): string; overload;
//function toString(i: int): string; overload; //function toString(i: int): string; overload;
function ToStringF(const r: Real): string; overload; function ToStringF(const r: Real): string; overload;
function ToString(b: Boolean): string; overload; function ToString(b: Boolean): string; overload;
function ToString(b: PChar): string; overload;
function IntToStr(i: BiggestInt; minChars: int): string; function IntToStr(i: BiggestInt; minChars: int): string;
@ -415,6 +416,11 @@ begin
result := sysUtils.intToStr(i); result := sysUtils.intToStr(i);
end; end;
function ToString(b: PChar): string; overload;
begin
result := string(b);
end;
function normalize(const s: string): string; function normalize(const s: string): string;
var var
i: int; 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: @if llvm_gcc or gcc:
# GCC, LLVM and Visual C++ have a problem to optimize some modules. # GCC, LLVM and Visual C++ have a problem to optimize some modules.
# This is really strange. # This is really strange.
@if windows or macosX: cgen.speed = "-O0"
cgen.speed = "-O0"
@else:
cgen.speed = "-O1 -fno-strict-aliasing"
@end
@elif vcc: @elif vcc:
cgen.speed = "" cgen.speed = ""
@end @end