cc}p3.clu 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. % CC_P3 CLU
  2. %
  3. % CLU 3 compiler: parsing routines for constants and types
  4. BEGIN
  5. # include "clucmp/cc_syn.equate"
  6. # include "clucmp/cc_p.equate"
  7. END
  8. p_const = proc (e: env) returns (const);
  9. abs: constabs;
  10. k: token := e.peek_token;
  11. tagcase k in
  12. typekey: begin
  13. t: typespec := p_type(e);
  14. tk: token := e.peek_token;
  15. tagcase tk in
  16. dollar: begin
  17. x: expr := p_more_primary(e, p_cons_or_op(e, t));
  18. abs := constabs$make_unknown(
  19. p_more_expr(e, x, min_prec));
  20. end;
  21. out: abs := constabs$make_type_(t);
  22. end;
  23. end;
  24. out: abs := constabs$make_unknown(p_expr(e, min_prec));
  25. end;
  26. return(const$create(abs));
  27. end p_const;
  28. p_constlist = proc (e: env) returns (constlist);
  29. consts: constlist := constlist$create(1);
  30. k: token := e.peek_token;
  31. tagcase k in
  32. l_bkt: env$next_token(e);
  33. out: return(consts);
  34. end;
  35. while true do begin
  36. constlist$addh(consts, p_const(e));
  37. k := e.peek_token;
  38. tagcase k in
  39. comma: env$next_token(e);
  40. r_bkt: begin
  41. env$next_token(e);
  42. return(consts);
  43. end;
  44. out: begin
  45. env$assume(e, "] in [constlist]");
  46. return(consts);
  47. end;
  48. end;
  49. end;
  50. end p_constlist;
  51. p_type = proc (e: env) returns (typespec);
  52. abs: typeabs;
  53. k: token := e.peek_token;
  54. tagcase k in
  55. typekey: %(k: typekey):
  56. begin
  57. env$next_token(e);
  58. tagcase k in
  59. record_: abs := typeabs$make_record_(p_fieldspeclist(e));
  60. oneof_: abs := typeabs$make_oneof_(p_fieldspeclist(e));
  61. proctype_: begin
  62. args: typelist := p_typelist(e, true);
  63. vals: typelist := p_returns(e);
  64. sigs: exceptionlist := p_signals(e);
  65. abs := typeabs$make_proc_({args: args,
  66. vals: vals,
  67. sigs: sigs});
  68. end;
  69. itertype_: begin
  70. args: typelist := p_typelist(e, true);
  71. vals: typelist := p_yields(e);
  72. sigs: exceptionlist := p_signals(e);
  73. abs := typeabs$make_iter_({args: args,
  74. vals: vals,
  75. sigs: sigs});
  76. end;
  77. array_: abs := typeabs$make_array_(p_arraytype(e));
  78. bool_: abs := typeabs$make_bool_(nil);
  79. int_: abs := typeabs$make_int_(nil);
  80. string_: abs := typeabs$make_str(nil);
  81. char_: abs := typeabs$make_char_(nil);
  82. rep_: abs := typeabs$make_rep_(nil);
  83. null_: abs := typeabs$make_null_(nil);
  84. cvt_: abs := typeabs$make_cvt_(nil);
  85. any_: abs := typeabs$make_any_(nil);
  86. type_: abs := typeabs$make_type_(nil);
  87. end;
  88. end;
  89. ident: %(k: ident):
  90. begin
  91. env$next_token(e);
  92. parms: constlist := p_constlist(e);
  93. abs := typeabs$make_abstract({idn: env$get_idn(e, k),
  94. parms: parms});
  95. end;
  96. out: begin
  97. env$assume(e, "type");
  98. abs := typeabs$make_unknown(nil);
  99. end;
  100. end;
  101. return(env$get_type(e, abs));
  102. end p_type;
  103. p_fieldspeclist = proc (e: env) returns (fieldspeclist);
  104. specs: fieldspeclist := fieldspeclist$create(1);
  105. k: token := e.peek_token;
  106. tagcase k in
  107. l_bkt: env$next_token(e);
  108. out: begin
  109. env$assume(e, "[fieldspeclist] in RECORD or ONEOF");
  110. return(specs);
  111. end;
  112. end;
  113. while true do begin
  114. sels: namelist := p_namelist(e);
  115. t: typespec;
  116. k := e.peek_token;
  117. tagcase k in
  118. colon: begin
  119. env$next_token(e);
  120. t := p_type(e);
  121. end;
  122. out: begin
  123. env$assume(e, ": type in fieldspec");
  124. t := e.unknown_type;
  125. end;
  126. end;
  127. for i: int := namelist$low(sels) to namelist$high(sels) do begin
  128. fieldspeclist$addh(specs, {sel: sels[i],
  129. type_: t});
  130. end;
  131. k := e.peek_token;
  132. tagcase k in
  133. comma: env$next_token(e);
  134. r_bkt: begin
  135. env$next_token(e);
  136. return(specs);
  137. end;
  138. out: begin
  139. env$assume(e, "] in [fieldspeclist]");
  140. return(specs);
  141. end;
  142. end;
  143. end;
  144. end p_fieldspeclist;
  145. p_returns = proc (e: env) returns (typelist);
  146. nonempty = false;
  147. k: token := e.peek_token;
  148. tagcase k in
  149. returns_: begin
  150. env$next_token(e);
  151. return(p_typelist(e, nonempty));
  152. end;
  153. out: return(typelist$create(1));
  154. end;
  155. end p_returns;
  156. p_yields = proc (e: env) returns (typelist);
  157. nonempty = false;
  158. k: token := e.peek_token;
  159. tagcase k in
  160. yields_: begin
  161. env$next_token(e);
  162. return(p_typelist(e, nonempty));
  163. end;
  164. out: return(typelist$create(1));
  165. end;
  166. end p_yields;
  167. p_signals = proc (e: env) returns (exceptionlist);
  168. k: token := e.peek_token;
  169. tagcase k in
  170. signals_: begin
  171. env$next_token(e);
  172. return(p_exceptionlist(e));
  173. end;
  174. out: return(exceptionlist$create(1));
  175. end;
  176. end p_signals;
  177. p_arraytype = proc (e: env) returns (typespec);
  178. k: token := e.peek_token;
  179. tagcase k in
  180. l_bkt: env$next_token(e);
  181. out: begin
  182. env$assume(e, "[type] in ARRAY[type]");
  183. return(e.unknown_type);
  184. end;
  185. end;
  186. t: typespec := p_type(e);
  187. k := e.peek_token;
  188. tagcase k in
  189. r_bkt: env$next_token(e);
  190. out: env$assume(e, "] in ARRAY[type]");
  191. end;
  192. return(t);
  193. end p_arraytype;
  194. p_typelist = proc (e: env, emptyok: bool) returns (typelist);
  195. types: typelist := typelist$create(1);
  196. k: token := e.peek_token;
  197. tagcase k in
  198. l_paren: env$next_token(e);
  199. out: begin
  200. env$assume(e, "(typelist)");
  201. return(types);
  202. end;
  203. end;
  204. k := e.peek_token;
  205. tagcase k in
  206. r_paren: if emptyok
  207. then begin
  208. env$next_token(e);
  209. return(types);
  210. end;
  211. out: ;
  212. end;
  213. while true do begin
  214. typelist$addh(types, p_type(e));
  215. k := e.peek_token;
  216. tagcase k in
  217. comma: env$next_token(e);
  218. r_paren: begin
  219. env$next_token(e);
  220. return(types);
  221. end;
  222. out: begin
  223. env$assume(e, ") in (typelist)");
  224. return(types);
  225. end;
  226. end;
  227. end;
  228. end p_typelist;
  229. p_exceptionlist = proc (e: env) returns (exceptionlist);
  230. nonempty = false;
  231. list: exceptionlist := exceptionlist$create(1);
  232. k: token := e.peek_token;
  233. tagcase k in
  234. l_paren: env$next_token(e);
  235. out: begin
  236. env$assume(e, "(exceptionlist)");
  237. return(list);
  238. end;
  239. end;
  240. while true do begin
  241. n: name := p_name(e);
  242. types: typelist;
  243. k := e.peek_token;
  244. tagcase k in
  245. l_paren: types := p_typelist(e, nonempty);
  246. out: types := typelist$create(1);
  247. end;
  248. exceptionlist$addh(list, {name: n,
  249. types: types});
  250. k := e.peek_token;
  251. tagcase k in
  252. comma: env$next_token(e);
  253. r_paren: begin
  254. env$next_token(e);
  255. return(list);
  256. end;
  257. out: begin
  258. env$assume(e, ") in (exceptionlist)");
  259. return(list);
  260. end;
  261. end;
  262. end;
  263. end p_exceptionlist;