      
% Symbol table primitives

% $Id: symtab.pl,v 1.2 1994/04/15 13:46:27 dbc Exp dbc $

% $Log: symtab.pl,v $
% Revision 1.2  1994/04/15  13:46:27  dbc
% Add `symPrintKeys' debug entry point.
%
% Revision 1.1  1994/04/11  10:40:28  dbc
% Initial revision
%

% ----- Hierarchical symbol table -----

symCreate(sym(0, [])).

symNewBlk(sym(L1, [Blk | Blks]), sym(L, Blks)) :-
    blkCreate(Blk),
    L1 is L + 1.


symInstall(handle(L, Id), Key, Data, sym(L, [Blk | _])) :-
    blkInstall(Id, Key, Data, Blk).


symHandle(handle(L, Id), Key, sym(L, [Blk | _])) :-
    blkHandle(Id, Key, Blk), !.
symHandle(Handle, Key, sym(L, [_ | Blks])) :-
    L1 is L - 1, symHandle(Handle, Key, sym(L1, Blks)).
    
symLookUp(handle(L, Id), Data, sym(D, Blks)) :-
    N is D - L + 1, isNth(N, Blks, Blk),
    blkLookUp(Id, Data, Blk).
 
symLocals(Handles, sym(L, [Blk | _])) :-
    blkIndex(Ids, Blk),
    buildHandles(Handles, L, Ids).

symLevel(handle(L, _), Level, sym(D, _)) :-
    Level is D - L.


buildHandles([], _, []).
buildHandles([handle(L, Id) | Handles], L, [Id | Ids]) :-
    buildHandles(Handles, L, Ids).

% Debug
symPrintKeys(sym(_, [])).
symPrintKeys(sym(_, [Blk | Blks])) :-
    blkPrintKeys(Blk),
    symPrintKeys(sym(_, Blks)).
    

% ---- Primitive flat symbol table ----


blkCreate(_).


blkInstall(1, Key, Data, Tab) :-
    var(Tab), !,
    (ground(Key), !,
      Tab = [node(Key, Data) | _]
    |true,
      Tab = [node(anon(key), Data) | _]).  % anon(key) is impossible identifier
blkInstall(_, Key, _, [node(KeyOld, _) | _]) :-
    ground(Key),
    Key = KeyOld,
    symError1(Key).
blkInstall(Id, Key, Data, [node(_, _) | Tab]) :-
    blkInstall(Id1, Key, Data, Tab),
    Id is Id1 + 1.


blkHandle(_, _, Tab)                   :- var(Tab), !, fail.
blkHandle(1, Key, [node(Key, _) | _])  :- !.
blkHandle(Id, Key, [node(_, _) | Tab]) :-
    blkHandle(Id1, Key, Tab),
    Id is Id1 + 1.

blkLookUp(Id, Data, Tab) :- isNth(Id, Tab, node(_, Data)).

blkIndex(Ids, Tab) :- blkIndexN(Ids, Tab, 1).

blkIndexN([], Tab, _)              :- var(Tab), !.
blkIndexN([N | Ids], [_ | Tab], N) :-
    N1 is N + 1,
    blkIndexN(Ids, Tab, N1).

% Debug
blkPrintKeys(Tab) :- var(Tab), !.
blkPrintKeys([node(Key, _) | Tab]) :-
    (Key = anon(key), !,
      true
    |true,
      print(Key), nl),
    blkPrintKeys(Tab).

% ----- Error reporting -----

symError1(Key) :- printString("Symbol "), print(Key),
                  printString(" multiply defined in scoping unit."), abort.

