mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-02 03:02:31 +00:00
130 lines
2.7 KiB
ObjectPascal
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.
|