Files
Nim/nim/debugids.pas
Andreas Rumpf ddaedab835 version 0.7.2
2008-12-12 14:02:27 +01:00

130 lines
2.7 KiB
ObjectPascal

//
//
// The Nimrod Compiler
// (c) Copyright 2008 Andreas Rumpf
//
// See the file "copying.txt", included in this
// distribution, for details about the copyright.
//
unit debugids;
interface
{$include 'config.inc'}
uses
nsystem, nos, strutils, ast;
const
idfile = 'debugids.txt';
// This module implements debugging facilities for the ID mechanism.
procedure registerID(s: PSym);
procedure writeIDTable();
procedure loadIDTable();
implementation
type
TIdSymTuple = record{@tuple} // keep id from sym to better detect bugs
id: int;
s: PSym;
end;
TIdSymTupleSeq = array of TIdSymTuple;
TIdSymTable = record
counter: int;
data: TIdSymTupleSeq;
end;
function TableRawGet(const t: TTable; key: PObject): int;
var
h: THash;
begin
h := hashNode(key) and high(t.data); // start with real hash value
while t.data[h].key <> nil do begin
if (t.data[h].key = key) then begin
result := h; exit
end;
h := nextTry(h, high(t.data))
end;
result := -1
end;
function TableSearch(const t: TTable; key, closure: PObject;
comparator: TCmpProc): PObject;
var
h: THash;
begin
h := hashNode(key) and high(t.data); // start with real hash value
while t.data[h].key <> nil do begin
if (t.data[h].key = key) then
if comparator(t.data[h].val, closure) then begin // BUGFIX 1
result := t.data[h].val; exit
end;
h := nextTry(h, high(t.data))
end;
result := nil
end;
function TableGet(const t: TTable; key: PObject): PObject;
var
index: int;
begin
index := TableRawGet(t, key);
if index >= 0 then result := t.data[index].val
else result := nil
end;
procedure TableRawInsert(var data: TPairSeq; key, val: PObject);
var
h: THash;
begin
h := HashNode(key) and high(data);
while data[h].key <> nil do begin
assert(data[h].key <> key);
h := nextTry(h, high(data))
end;
assert(data[h].key = nil);
data[h].key := key;
data[h].val := val;
end;
procedure TableEnlarge(var t: TTable);
var
n: TPairSeq;
i: int;
begin
{@ignore}
n := emptySeq;
setLength(n, length(t.data) * growthFactor);
fillChar(n[0], length(n)*sizeof(n[0]), 0);
{@emit
newSeq(n, length(t.data) * growthFactor); }
for i := 0 to high(t.data) do
if t.data[i].key <> nil then
TableRawInsert(n, t.data[i].key, t.data[i].val);
{@ignore}
t.data := n;
{@emit
swap(t.data, n);
}
end;
procedure TablePut(var t: TTable; key, val: PObject);
var
index: int;
begin
index := TableRawGet(t, key);
if index >= 0 then
t.data[index].val := val
else begin
if mustRehash(length(t.data), t.counter) then TableEnlarge(t);
TableRawInsert(t.data, key, val);
inc(t.counter)
end;
end;
end.