StringTable.mod 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. IMPLEMENTATION MODULE StringTable; (* gf 01.11.88 (pl0) *)
  2. FROM Scanner IMPORT SYMBOL, IDENT;
  3. CONST bufLen = 1000;
  4. maxId = 200;
  5. VAR id, id1 : CARDINAL; (* indices to identifier buffer *)
  6. buf : ARRAY[0..bufLen-1] OF CHAR;
  7. (* character buffer; identifiers are stored with
  8. leading length *)
  9. idKinds : ARRAY [0..maxId] OF
  10. RECORD
  11. ind: CARDINAL; (* index into buf *)
  12. sym: SYMBOL
  13. END;
  14. K : CARDINAL; (* no of key words *)
  15. nIds : CARDINAL; (* no of identifiers (incl. key words) *)
  16. PROCEDURE Diff(u, v : CARDINAL): INTEGER;
  17. VAR w : CARDINAL;
  18. BEGIN
  19. w := ORD(buf[u]);
  20. LOOP
  21. IF w = 0 THEN RETURN 0 END;
  22. IF buf[u] # buf[v] THEN
  23. RETURN INTEGER(ORD(buf[u])) - INTEGER(ORD(buf[v]))
  24. ELSE
  25. INC(u); INC(v); DEC(w)
  26. END
  27. END
  28. END Diff;
  29. PROCEDURE InsertIdent(s: ARRAY OF CHAR): IDENT;
  30. VAR i, k, l, m : CARDINAL;
  31. d : INTEGER;
  32. BEGIN
  33. id1 := id + 1; l := 0;
  34. REPEAT
  35. buf[id1] := s[l]; INC(id1); INC(l);
  36. UNTIL (l > HIGH(s)) OR (s[l] = 0C);
  37. buf[id] := CHR(id1 - id );
  38. buf[id1] := 0C; INC(id1);
  39. k := 1; l := K;
  40. REPEAT
  41. m := (k + l) DIV 2;
  42. d := Diff(id, idKinds[m].ind);
  43. IF d <= 0 THEN l := m - 1 END;
  44. IF d >= 0 THEN k := m + 1 END;
  45. UNTIL k > l;
  46. IF k > l + 1 THEN
  47. RETURN IDENT(m) (* is a key word *)
  48. ELSE
  49. (* don't store it twice if it already exists *)
  50. FOR i := K+1 TO nIds DO
  51. IF Diff(id, idKinds[i].ind) = 0 THEN RETURN IDENT(i) END
  52. END;
  53. INC(nIds);
  54. WITH idKinds[nIds] DO
  55. ind := id;
  56. sym := sIdent
  57. END;
  58. id := id1;
  59. RETURN IDENT(nIds)
  60. END
  61. END InsertIdent;
  62. PROCEDURE IdKind(idno: IDENT): SYMBOL;
  63. BEGIN
  64. IF CARDINAL(idno) > nIds THEN
  65. RETURN sNull
  66. ELSE
  67. RETURN idKinds[CARDINAL(idno)].sym
  68. END;
  69. END IdKind;
  70. PROCEDURE SameId(id1, id2: IDENT): BOOLEAN;
  71. BEGIN
  72. RETURN CARDINAL(id1) = CARDINAL(id2)
  73. END SameId;
  74. PROCEDURE IdString(idno: IDENT; VAR s: ARRAY OF CHAR);
  75. BEGIN
  76. (* not implemented *)
  77. END IdString;
  78. PROCEDURE EnterKeyWord(sym: SYMBOL; name : ARRAY OF CHAR);
  79. VAR l, L : CARDINAL;
  80. BEGIN
  81. INC(K); INC(nIds);
  82. idKinds[K].sym := sym;
  83. idKinds[K].ind := id;
  84. l := 0; L := HIGH(name);
  85. buf[id] := CHR(L + 1); INC(id);
  86. LOOP
  87. IF l > L THEN EXIT END;
  88. buf[id] := name[l]; INC(id); INC(l)
  89. END;
  90. buf[id] := 0C; INC(id)
  91. END EnterKeyWord;
  92. PROCEDURE InitStringTable;
  93. BEGIN
  94. id := 0;
  95. K := 0; nIds := 0
  96. END InitStringTable;
  97. BEGIN
  98. END StringTable.