| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- IMPLEMENTATION MODULE StringTable; (* gf 01.11.88 (pl0) *)
- FROM Scanner IMPORT SYMBOL, IDENT;
- CONST bufLen = 1000;
- maxId = 200;
- VAR id, id1 : CARDINAL; (* indices to identifier buffer *)
- buf : ARRAY[0..bufLen-1] OF CHAR;
- (* character buffer; identifiers are stored with
- leading length *)
- idKinds : ARRAY [0..maxId] OF
- RECORD
- ind: CARDINAL; (* index into buf *)
- sym: SYMBOL
- END;
- K : CARDINAL; (* no of key words *)
- nIds : CARDINAL; (* no of identifiers (incl. key words) *)
- PROCEDURE Diff(u, v : CARDINAL): INTEGER;
- VAR w : CARDINAL;
- BEGIN
- w := ORD(buf[u]);
- LOOP
- IF w = 0 THEN RETURN 0 END;
- IF buf[u] # buf[v] THEN
- RETURN INTEGER(ORD(buf[u])) - INTEGER(ORD(buf[v]))
- ELSE
- INC(u); INC(v); DEC(w)
- END
- END
- END Diff;
- PROCEDURE InsertIdent(s: ARRAY OF CHAR): IDENT;
- VAR i, k, l, m : CARDINAL;
- d : INTEGER;
- BEGIN
- id1 := id + 1; l := 0;
- REPEAT
- buf[id1] := s[l]; INC(id1); INC(l);
- UNTIL (l > HIGH(s)) OR (s[l] = 0C);
- buf[id] := CHR(id1 - id );
- buf[id1] := 0C; INC(id1);
- k := 1; l := K;
- REPEAT
- m := (k + l) DIV 2;
- d := Diff(id, idKinds[m].ind);
- IF d <= 0 THEN l := m - 1 END;
- IF d >= 0 THEN k := m + 1 END;
- UNTIL k > l;
- IF k > l + 1 THEN
- RETURN IDENT(m) (* is a key word *)
- ELSE
- (* don't store it twice if it already exists *)
- FOR i := K+1 TO nIds DO
- IF Diff(id, idKinds[i].ind) = 0 THEN RETURN IDENT(i) END
- END;
- INC(nIds);
- WITH idKinds[nIds] DO
- ind := id;
- sym := sIdent
- END;
- id := id1;
- RETURN IDENT(nIds)
- END
- END InsertIdent;
- PROCEDURE IdKind(idno: IDENT): SYMBOL;
- BEGIN
- IF CARDINAL(idno) > nIds THEN
- RETURN sNull
- ELSE
- RETURN idKinds[CARDINAL(idno)].sym
- END;
- END IdKind;
- PROCEDURE SameId(id1, id2: IDENT): BOOLEAN;
- BEGIN
- RETURN CARDINAL(id1) = CARDINAL(id2)
- END SameId;
- PROCEDURE IdString(idno: IDENT; VAR s: ARRAY OF CHAR);
- BEGIN
- (* not implemented *)
- END IdString;
- PROCEDURE EnterKeyWord(sym: SYMBOL; name : ARRAY OF CHAR);
- VAR l, L : CARDINAL;
- BEGIN
- INC(K); INC(nIds);
- idKinds[K].sym := sym;
- idKinds[K].ind := id;
- l := 0; L := HIGH(name);
- buf[id] := CHR(L + 1); INC(id);
- LOOP
- IF l > L THEN EXIT END;
- buf[id] := name[l]; INC(id); INC(l)
- END;
- buf[id] := 0C; INC(id)
- END EnterKeyWord;
- PROCEDURE InitStringTable;
- BEGIN
- id := 0;
- K := 0; nIds := 0
- END InitStringTable;
- BEGIN
- END StringTable.
|