LSS.Mod.txt 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. MODULE LSS; (* NW 16.10.93 / 13.8.2018*)
  2. IMPORT Texts, Oberon;
  3. CONST IdLen* = 32; NofKeys = 11;
  4. (*symbols*) null = 0;
  5. arrow* = 1; times* = 2; div* = 3; and* = 4; plus* = 5; minus* = 6; or* = 7; xor* = 8; not* = 9;
  6. eql* = 10; neq* = 11; lss* = 12; leq* = 13; gtr* = 14; geq* = 15;
  7. at* = 16; apo* = 17; period* = 18; comma* = 19; colon* = 20; rparen* = 21; rbrak* = 22; rbrace* = 23;
  8. then* = 24; lparen* = 26; lbrak* = 27; lbrace* = 28; repl* = 29; becomes* = 30;
  9. integer* = 31; ident* = 32; ts* = 33; semicolon* = 40; end* = 41;
  10. const* = 51; type* = 52; reg* = 53; var* = 54; out* = 55; inout* = 56; in* = 57;
  11. begin* = 58; module* = 59; eof = 60;
  12. TYPE Ident* = ARRAY IdLen OF CHAR;
  13. VAR val*: LONGINT;
  14. id*: Ident;
  15. error*: BOOLEAN;
  16. ch: CHAR;
  17. errpos: LONGINT;
  18. R: Texts.Reader;
  19. W: Texts.Writer;
  20. key: ARRAY NofKeys OF Ident;
  21. symno: ARRAY NofKeys OF INTEGER;
  22. PROCEDURE Mark*(msg: ARRAY OF CHAR);
  23. VAR p: LONGINT;
  24. BEGIN p := Texts.Pos(R);
  25. IF p > errpos+2 THEN
  26. Texts.WriteString(W, " pos "); Texts.WriteInt(W, p, 1);
  27. Texts.WriteString(W, " err: "); Texts.WriteString(W, msg);
  28. Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
  29. END ;
  30. errpos := p; error := TRUE
  31. END Mark;
  32. PROCEDURE identifier(VAR sym: INTEGER);
  33. VAR i: INTEGER;
  34. BEGIN i := 0;
  35. REPEAT
  36. IF i < IdLen THEN id[i] := ch; INC(i) END ;
  37. Texts.Read(R, ch)
  38. UNTIL (ch < "0") OR (ch > "9") & (ch < "A") OR (ch > "Z") & (ch < "a") OR (ch > "z");
  39. IF ch = "'" THEN
  40. IF i < IdLen THEN id[i] := ch; INC(i) END ;
  41. Texts.Read(R, ch)
  42. END ;
  43. IF i = IdLen THEN Mark("ident too long"); id[IdLen-1] := 0X
  44. ELSE id[i] := 0X
  45. END ;
  46. i := 0;
  47. WHILE (i < NofKeys) & (id # key[i]) DO INC(i) END ;
  48. IF i < NofKeys THEN sym := symno[i] ELSE sym := ident END
  49. END identifier;
  50. PROCEDURE Number(VAR sym: INTEGER);
  51. VAR i, k, h, n, d: LONGINT;
  52. hex: BOOLEAN;
  53. dig: ARRAY 16 OF LONGINT;
  54. BEGIN sym := integer; i := 0; k := 0; n := 0; hex := FALSE;
  55. REPEAT
  56. IF n < 16 THEN d := ORD(ch)-30H;
  57. IF d >= 10 THEN hex := TRUE ; d := d - 7 END ;
  58. dig[n] := d; INC(n)
  59. ELSE Mark("too many digits"); n := 0
  60. END ;
  61. Texts.Read(R, ch)
  62. UNTIL (ch < "0") OR (ch > "9") & (ch < "A") OR (ch > "F");
  63. IF ch = "H" THEN (*hex*)
  64. REPEAT h := dig[i]; k := k*10H + h; INC(i) (*no overflow check*)
  65. UNTIL i = n;
  66. Texts.Read(R, ch)
  67. ELSE
  68. IF hex THEN Mark("illegal hex digit") END ;
  69. REPEAT k := k*10 + dig[i]; INC(i) UNTIL i = n
  70. END ;
  71. val := k
  72. END Number;
  73. PROCEDURE comment;
  74. BEGIN Texts.Read(R, ch);
  75. REPEAT
  76. WHILE ~R.eot & (ch # "*") DO
  77. IF ch = "(" THEN Texts.Read(R, ch);
  78. IF ch = "*" THEN comment END
  79. ELSE Texts.Read(R, ch)
  80. END
  81. END ;
  82. WHILE ch = "*" DO Texts.Read(R, ch) END
  83. UNTIL (ch = ")") OR R.eot;
  84. IF ~R.eot THEN Texts.Read(R, ch) ELSE Mark("comment not terminated") END
  85. END comment;
  86. PROCEDURE Get*(VAR sym: INTEGER);
  87. BEGIN
  88. REPEAT
  89. WHILE ~R.eot & (ch <= " ") DO Texts.Read(R, ch) END;
  90. IF R.eot THEN sym := eof
  91. ELSIF ch < "A" THEN
  92. IF ch < "0" THEN
  93. IF ch = "!" THEN Texts.Read(R, ch); sym := repl
  94. ELSIF ch = "#" THEN Texts.Read(R, ch); sym := neq
  95. ELSIF ch = "$" THEN Texts.Read(R, ch); sym := null
  96. ELSIF ch = "&" THEN Texts.Read(R, ch); sym := and
  97. ELSIF ch = "'" THEN Texts.Read(R, ch); sym := apo
  98. ELSIF ch = "(" THEN Texts.Read(R, ch);
  99. IF ch = "*" THEN sym := null; comment ELSE sym := lparen END
  100. ELSIF ch = ")" THEN Texts.Read(R, ch); sym := rparen
  101. ELSIF ch = "*" THEN Texts.Read(R, ch); sym := times
  102. ELSIF ch = "+" THEN Texts.Read(R, ch); sym := plus
  103. ELSIF ch = "," THEN Texts.Read(R, ch); sym := comma
  104. ELSIF ch = "-" THEN Texts.Read(R, ch);
  105. IF ch = ">" THEN Texts.Read(R, ch); sym := then ELSE sym := minus END
  106. ELSIF ch = "." THEN Texts.Read(R, ch); sym := period
  107. ELSIF ch = "/" THEN Texts.Read(R, ch); sym := div
  108. ELSE sym := null
  109. END
  110. ELSIF ch <= "9" THEN Number(sym)
  111. ELSIF ch = ":" THEN Texts.Read(R, ch);
  112. IF ch = "=" THEN Texts.Read(R, ch); sym := becomes ELSE sym := colon END
  113. ELSIF ch = ";" THEN Texts.Read(R, ch); sym := semicolon
  114. ELSIF ch = "<" THEN Texts.Read(R, ch);
  115. IF ch = "=" THEN Texts.Read(R, ch); sym := leq ELSE sym := lss END
  116. ELSIF ch = "=" THEN Texts.Read(R, ch); sym := eql
  117. ELSIF ch = ">" THEN Texts.Read(R, ch);
  118. IF ch = "=" THEN Texts.Read(R, ch); sym := geq ELSE sym := gtr END
  119. ELSIF ch = "?" THEN Texts.Read(R, ch); sym := then
  120. ELSIF ch = "@" THEN Texts.Read(R, ch); sym := at
  121. ELSE sym := null
  122. END
  123. ELSIF ch <= "Z" THEN identifier(sym)
  124. ELSIF ch < "a" THEN
  125. IF ch = "[" THEN Texts.Read(R, ch); sym := lbrak
  126. ELSIF ch = "]" THEN Texts.Read(R, ch); sym := rbrak
  127. ELSIF ch = "^" THEN Texts.Read(R, ch); sym := xor
  128. ELSE sym := null
  129. END
  130. ELSIF ch <= "z" THEN identifier(sym)
  131. ELSIF ch <= "{" THEN Texts.Read(R, ch); sym := lbrace
  132. ELSIF ch <= "|" THEN Texts.Read(R, ch); sym := or
  133. ELSIF ch <= "}" THEN Texts.Read(R, ch); sym := rbrace
  134. ELSIF ch <= "~" THEN Texts.Read(R, ch); sym := not
  135. ELSE sym := null
  136. END
  137. UNTIL sym # null
  138. END Get;
  139. PROCEDURE Init*(T: Texts.Text; pos: LONGINT);
  140. BEGIN error := FALSE; errpos := pos; Texts.OpenReader(R, T, pos); Texts.Read(R, ch)
  141. END Init;
  142. BEGIN Texts.OpenWriter(W);
  143. key[ 0] := "BEGIN"; symno[0] := begin;
  144. key[ 1] := "CONST"; symno[1] := const;
  145. key[ 2] := "END"; symno[2] := end;
  146. key[3] := "IN"; symno[3] := in;
  147. key[4] := "INOUT"; symno[4] := inout;
  148. key[5] := "MODULE"; symno[5] := module;
  149. key[6] := "OUT"; symno[6] := out;
  150. key[7] := "REG"; symno[7] := reg;
  151. key[8] := "TYPE"; symno[8] := type;
  152. key[9] := "VAR"; symno[9] := var;
  153. key[10] := "TS"; symno[10] := ts
  154. END LSS.