cc}pt.clu 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. % CC_PT CLU
  2. %
  3. % For printing a CLU 3.1 abstract syntax tree.
  4. % Uses an own variable for the roving left margin.
  5. BEGIN
  6. # include "clucmp/cc_syn.equate"
  7. absolute_left = 0;
  8. delta = 4;
  9. END
  10. print = proc (def: definition, f: file);
  11. set_margin(absolute_left);
  12. pt_newline(f);
  13. pt_definition(def, f);
  14. pt_newline(f);
  15. end print;
  16. pt_newline = proc (f: file);
  17. pt_nextline(get_margin(), f);
  18. end pt_newline;
  19. pt_nextline = proc (i: int, f: file);
  20. file$putc(f, '\n');
  21. for j: int := 1 to i do begin
  22. file$putc(f, ' ');
  23. end;
  24. end pt_nextline;
  25. new_margin = proc (f: file);
  26. set_margin(file$column(f));
  27. end new_margin;
  28. pt_strid = proc (id: strid, f: file);
  29. pt_str(strid$get_str(id), f);
  30. end pt_strid;
  31. pt_str = proc (s: str, f: file);
  32. file$putc(f, '"');
  33. pt_charseq(s, true, f);
  34. file$putc(f, '"');
  35. end pt_str;
  36. pt_intid = proc (id: intid, f: file);
  37. file$puti(f, intid$get_int(id));
  38. end pt_intid;
  39. pt_charid = proc (id: charid, f: file);
  40. pt_char(charid$get_char(id), f);
  41. end pt_charid;
  42. pt_char = proc (c: char, f: file);
  43. file$puts(f, "'");
  44. pt_charseq(str$c2s(c), false, f);
  45. file$puts(f, "'");
  46. end pt_char;
  47. pt_name = proc (n: name, f: file);
  48. file$puts(f, name$get_str(n));
  49. end pt_name;
  50. pt_idn = proc (i: idn, f: file);
  51. file$puts(f, idn$get_str(i));
  52. end pt_idn;
  53. pt_charseq = proc (s: str, is_str: bool, f: file);
  54. for i: int := 1 to str$size(s) do begin
  55. c: char := s[i];
  56. j: int := char$c2i(c);
  57. if j < 32
  58. then begin
  59. file$putc(f, '\\');
  60. file$putc(f, char$i2c(j + 64));
  61. end;
  62. else if j = 34
  63. then if is_str
  64. then file$puts(f, "\\\"");
  65. else file$putc(f, '"');
  66. else if j = 39
  67. then if is_str
  68. then file$putc(f, '\'');
  69. else file$puts(f, "\\'");
  70. else if j = 92
  71. then file$puts(f, "\\\\");
  72. else file$putc(f, c);
  73. end;
  74. end pt_charseq;
  75. pt_constlist = proc (list: constlist, f: file);
  76. pt_konstlist(list, "[]", f);
  77. end pt_constlist;
  78. pt_konstlist = proc (list: constlist, brackets: str, f: file);
  79. if constlist$size(list) = 0
  80. then return;
  81. file$putc(f, str$fetch(brackets, 1));
  82. high: int := constlist$high(list);
  83. for i: int := constlist$low(list) to high do begin
  84. pt_const(list[i], f);
  85. if i < high
  86. then file$puts(f, ", ");
  87. else file$putc(f, str$fetch(brackets, 2));
  88. end;
  89. end pt_konstlist;
  90. pt_namelist = proc (list: namelist, f: file);
  91. high: int := namelist$high(list);
  92. for i: int := namelist$low(list) to high do begin
  93. pt_name(list[i], f);
  94. if i < high then file$puts(f, ", ");
  95. end;
  96. end pt_namelist;
  97. pt_idnlist = proc (list: idnlist, f: file);
  98. high: int := idnlist$high(list);
  99. for i: int := idnlist$low(list) to high do begin
  100. pt_idn(list[i], f);
  101. if i < high then file$puts(f, ", ");
  102. end;
  103. end pt_idnlist;
  104. pt_typelist = proc (list: typelist, f: file);
  105. high: int := typelist$high(list);
  106. for i: int := typelist$low(list) to high do begin
  107. pt_typespec(list[i], f);
  108. if i < high then file$puts(f, ", ");
  109. end;
  110. end pt_typelist;
  111. pt_stmtlist = proc (list: stmtlist, f: file);
  112. high: int := stmtlist$high(list);
  113. for i: int := stmtlist$low(list) to high do begin
  114. pt_stmt(list[i], f);
  115. file$putc(f, ';');
  116. if i < high then pt_newline(f);
  117. end;
  118. end pt_stmtlist;
  119. pt_exprlist = proc (list: exprlist, f: file);
  120. high: int := exprlist$high(list);
  121. for i: int := exprlist$low(list) to high do begin
  122. pt_expr(list[i], f);
  123. if i < high then file$puts(f, ", ");
  124. end;
  125. end pt_exprlist;
  126. pt_equatelist = proc (list: equatelist, f: file);
  127. high: int := equatelist$high(list);
  128. for i: int := equatelist$low(list) to high do begin
  129. pt_equate(list[i], f);
  130. file$putc(f, ';');
  131. if i < high then pt_newline(f);
  132. end;
  133. end pt_equatelist;
  134. pt_apply = proc (op: apply, f: file);
  135. pt_idn(op.idn, f);
  136. pt_constlist(op.parms, f);
  137. end pt_apply;
  138. pt_clusterop = proc (op: clusterop, f: file);
  139. pt_typespec(op.type_, f);
  140. file$putc(f, '$');
  141. pt_name(op.name, f);
  142. pt_constlist(op.parms, f);
  143. end pt_clusterop;
  144. pt_oneup = proc (up1: oneup, f: file);
  145. pt_typespec(up1.type_, f);
  146. file$puts(f, "$make_");
  147. pt_name(up1.sel, f);
  148. file$putc(f, '(');
  149. pt_const(up1.obj, f);
  150. file$putc(f, ')');
  151. end pt_oneup;
  152. pt_constref = proc (ref: constref, f: file);
  153. pt_idn(ref.idn, f);
  154. pt_constlist(ref.parms, f);
  155. end pt_constref;
  156. pt_const = proc (c: const, f: file);
  157. pt_constabs(const$get_print(c), f);
  158. end pt_const;
  159. pt_constabs = proc (ca: constabs, f: file);
  160. x: constabs := ca;
  161. tagcase x in
  162. int_:% (x: intid):
  163. pt_intid(x, f);
  164. bool_:% (x: bool):
  165. file$puts(f, if x then "true" else "false");
  166. char_:% (x: charid):
  167. pt_charid(x, f);
  168. str:% (x: strid):
  169. pt_strid(x, f);
  170. null_:
  171. file$puts(f, "nil");
  172. oneup:% (x: oneup):
  173. pt_oneup(x, f);
  174. type_:% (x: typespec):
  175. pt_typespec(x, f);
  176. force_:% (x: typespec):
  177. begin
  178. file$puts(f, "force[");
  179. pt_typespec(x, f);
  180. file$putc(f, ')');
  181. end;
  182. apply:% (x: apply):
  183. pt_apply(x, f);
  184. op:% (x: clusterop):
  185. pt_clusterop(x, f);
  186. parm:% (x: idn):
  187. pt_idn(x, f);
  188. ref:% (x: constref):
  189. pt_constref(x, f);
  190. unknown:% (x: expr):
  191. pt_expr(x, f);
  192. bad:
  193. file$puts(f, "?const?");
  194. end;
  195. end pt_constabs;
  196. pt_opname = proc (op: opname, f: file);
  197. pt_name(op.name, f);
  198. pt_constlist(op.parms, f);
  199. end pt_opname;
  200. pt_opnamelist = proc (list: opnamelist, f: file);
  201. high: int := opnamelist$high(list);
  202. for i: int := opnamelist$low(list) to high do begin
  203. pt_opname(list[i], f);
  204. if i < high then file$puts(f, ", ");
  205. end;
  206. end pt_opnamelist;
  207. pt_operdecl = proc (dec: operdecl, f: file);
  208. pt_opnamelist(dec.opers, f);
  209. file$puts(f, ": ");
  210. pt_typespec(dec.type_, f);
  211. end pt_operdecl;
  212. pt_operdecllist = proc (list: operdecllist, f: file);
  213. high: int := operdecllist$high(list);
  214. for i: int := operdecllist$low(list) to high do begin
  215. pt_operdecl(list[i], f);
  216. if i < high
  217. then begin
  218. file$putc(f, ',');
  219. pt_newline(f);
  220. end;
  221. end;
  222. end pt_operdecllist;
  223. pt_typeset = proc (set: typeset, f: file);
  224. margin: int := get_margin();
  225. file$puts(f, "{ ");
  226. pt_idn(set.idn, f);
  227. file$puts(f, " | ");
  228. mar: int := file$column(f);
  229. pt_idn(set.idn, f);
  230. file$puts(f, " has ");
  231. new_margin(f);
  232. pt_operdecllist(set.ops, f);
  233. file$putc(f, ';');
  234. set_margin(mar);
  235. pt_newline(f);
  236. pt_equatelist(set.equates, f);
  237. file$putc(f, '}');
  238. set_margin(margin);
  239. end pt_typeset;
  240. pt_rename = proc (tab: rename, f: file);
  241. pt_namelist(tab.old, f);
  242. file$puts(f, " to ");
  243. pt_name(tab.new, f);
  244. end pt_rename;
  245. pt_renamelist = proc (list: renamelist, f: file);
  246. margin: int := get_margin();
  247. high: int := renamelist$high(list);
  248. file$putc(f, '[');
  249. new_margin(f);
  250. for i: int := renamelist$low(list) to high do begin
  251. pt_rename(list[i], f);
  252. if i < high
  253. then begin
  254. file$putc(f, ',');
  255. pt_newline(f);
  256. end;
  257. end;
  258. file$putc(f, ']');
  259. set_margin(margin);
  260. end pt_renamelist;
  261. pt_equateval = proc (val: equateval, f: file);
  262. x: equateval := val;
  263. tagcase x in
  264. const:% (const):
  265. pt_const(x, f);
  266. typeset:% (x: typeset):
  267. pt_typeset(x, f);
  268. rename:% (x: renamelist):
  269. pt_renamelist(x, f);
  270. end;
  271. end pt_equateval;
  272. pt_equate = proc (equ: equate, f: file);
  273. pt_idn(equate$get_idn(equ), f);
  274. file$puts(f, " = ");
  275. pt_equateval(equate$get_val(equ), f);
  276. end pt_equate;
  277. pt_exception = proc (x: exception, f: file);
  278. pt_name(x.name, f);
  279. if typelist$size(x.types) = 0 then return;
  280. file$putc(f, '(');
  281. pt_typelist(x.types, f);
  282. file$putc(f, ')');
  283. end pt_exception;
  284. pt_exceptionlist = proc (list: exceptionlist, f: file);
  285. high: int := exceptionlist$high(list);
  286. for i: int := exceptionlist$low(list) to high do begin
  287. pt_exception(list[i], f);
  288. if i < high then file$puts(f, ", ");
  289. end;
  290. end pt_exceptionlist;
  291. pt_restrictkind = proc (k: restrictkind, f: file);
  292. x: restrictkind := k;
  293. tagcase x in
  294. has_:% (x: operdecllist):
  295. begin
  296. margin: int := get_margin();
  297. file$puts(f, "has ");
  298. new_margin(f);
  299. pt_operdecllist(x, f);
  300. set_margin(margin);
  301. end;
  302. idn:% (x: idn):
  303. begin
  304. file$puts(f, "in ");
  305. pt_idn(x, f);
  306. end;
  307. set:% (x: typeset):
  308. begin
  309. margin: int := get_margin();
  310. file$puts(f, "in ");
  311. new_margin(f);
  312. pt_typeset(x, f);
  313. set_margin(margin);
  314. end;
  315. end;
  316. end pt_restrictkind;
  317. pt_restrict = proc (rest: restrict, f: file);
  318. pt_idn(rest.idn, f);
  319. pt_restrictkind(rest.kind, f);
  320. end pt_restrict;
  321. pt_restrictlist = proc (list: restrictlist, f: file);
  322. high: int := restrictlist$high(list);
  323. for i: int := restrictlist$low(list) to high do begin
  324. pt_restrict(list[i], f);
  325. if i < high
  326. then begin
  327. file$putc(f, ',');
  328. pt_newline(f);
  329. end;
  330. end;
  331. end pt_restrictlist;
  332. pt_body = proc (bod: body, f: file);
  333. pt_equatelist(bod.equates, f);
  334. if equatelist$size(bod.equates) > 0
  335. then pt_newline(f);
  336. pt_stmtlist(bod.stmts, f);
  337. end pt_body;
  338. pt_decl = proc (dec: decl, f: file);
  339. pt_idnlist(dec.idns, f);
  340. file$puts(f, ": ");
  341. pt_typespec(dec.type_, f);
  342. end pt_decl;
  343. pt_decllist = proc (list: decllist, f: file);
  344. high: int := decllist$high(list);
  345. for i: int := decllist$low(list) to high do begin
  346. pt_decl(list[i], f);
  347. if i < high then file$puts(f, ", ");
  348. end;
  349. end pt_decllist;
  350. pt_applyspek = proc (spec: applyspec, op: str, val: str, f: file);
  351. margin: int := get_margin();
  352. posn: int;
  353. pt_idn(spec.idn, f);
  354. file$puts(f, " = ");
  355. file$puts(f, op);
  356. posn := file$column(f) + 1;
  357. if decllist$size(spec.parms) > 0
  358. then begin
  359. file$puts(f, " [");
  360. pt_decllist(spec.parms, f);
  361. file$putc(f, ']');
  362. end;
  363. file$puts(f, " (");
  364. pt_decllist(spec.args, f);
  365. file$putc(f, ')');
  366. if typelist$size(spec.vals) > 0
  367. then begin
  368. file$putc(f, ' ');
  369. file$puts(f, val);
  370. file$puts(f, " (");
  371. pt_typelist(spec.vals, f);
  372. file$putc(f, ')');
  373. end;
  374. if exceptionlist$size(spec.sigs) > 0
  375. then begin
  376. file$puts(f, " signals (");
  377. pt_exceptionlist(spec.sigs, f);
  378. file$putc(f, ')');
  379. end;
  380. if restrictlist$size(spec.where_) > 0
  381. then begin
  382. pt_nextline(posn, f);
  383. file$puts(f, "where ");
  384. new_margin(f);
  385. pt_restrictlist(spec.where_, f);
  386. set_margin(margin);
  387. end;
  388. file$putc(f, ';');
  389. set_margin(margin + delta);
  390. pt_newline(f);
  391. pt_body(spec.body, f);
  392. pt_newline(f);
  393. file$puts(f, "end ");
  394. pt_idn(spec.idn, f);
  395. set_margin(margin);
  396. end pt_applyspek;
  397. pt_applyspec = proc (spec: applyspec, f: file);
  398. pt_applyspek(spec, "oper", "vals", f);
  399. end pt_applyspec;
  400. pt_operdefn = proc (op: operdefn, f: file);
  401. x: operdefn := op;
  402. tagcase x in
  403. proc_:% (x: applyspec):
  404. pt_applyspek(x, "proc", "returns", f);
  405. iter_:% (x: applyspec):
  406. pt_applyspek(x, "iter", "yields", f);
  407. end;
  408. end pt_operdefn;
  409. pt_operdefnlist = proc (list: operdefnlist, f: file);
  410. high: int := operdefnlist$high(list);
  411. for i: int := operdefnlist$low(list) to high do begin
  412. pt_operdefn(list[i], f);
  413. file$putc(f, ';');
  414. if i < high
  415. then begin
  416. pt_newline(f);
  417. pt_newline(f);
  418. end;
  419. end;
  420. end pt_operdefnlist;
  421. pt_cluspec = proc (spec: cluspec, f: file);
  422. margin: int := get_margin();
  423. ops: idnlist := spec.ops;
  424. high: int := idnlist$high(ops);
  425. pt_idn(spec.idn, f);
  426. file$puts(f, " = cluster ");
  427. posn: int := file$column(f);
  428. if decllist$size(spec.parms) > 0
  429. then begin
  430. file$putc(f, '[');
  431. pt_decllist(spec.parms, f);
  432. file$puts(f, "] ");
  433. end;
  434. file$puts(f, "is ");
  435. new_margin(f);
  436. for i: int := idnlist$low(ops) to high do begin
  437. pt_idn(ops[i], f);
  438. if i < high
  439. then begin
  440. file$putc(f, ',');
  441. pt_newline(f);
  442. end;
  443. end;
  444. if restrictlist$size(spec.where_) > 0
  445. then begin
  446. pt_nextline(posn, f);
  447. file$puts(f, "where ");
  448. new_margin(f);
  449. pt_restrictlist(spec.where_, f);
  450. end;
  451. file$putc(f, ';');
  452. set_margin(margin);
  453. pt_newline(f);
  454. pt_newline(f);
  455. pt_equatelist(spec.equates, f);
  456. if equatelist$size(spec.equates) > 0
  457. then begin
  458. pt_newline(f);
  459. pt_newline(f);
  460. end;
  461. pt_operdefnlist(spec.body, f);
  462. pt_newline(f);
  463. pt_newline(f);
  464. file$puts(f, "end ");
  465. pt_idn(spec.idn, f);
  466. end pt_cluspec;
  467. pt_definition = proc (def: definition, f: file);
  468. x: definition := def;
  469. tagcase x in
  470. equates:% (x: equatelist):
  471. pt_equatelist(x, f);
  472. proc_:% (x: applyspec):
  473. begin
  474. pt_applyspek(x, "proc", "returns", f);
  475. file$putc(f, ';');
  476. end;
  477. iter_:% (x: applyspec):
  478. begin
  479. pt_applyspek(x, "iter", "yields", f);
  480. file$putc(f, ';');
  481. end;
  482. clu:% (x: cluspec):
  483. begin
  484. pt_cluspec(x, f);
  485. file$putc(f, ';');
  486. end;
  487. end;
  488. end pt_definition;
  489. pt_declinit = proc (dec: declinit, f: file);
  490. pt_decllist(dec.decls, f);
  491. file$puts(f, " := ");
  492. pt_expr(dec.expr, f);
  493. end pt_declinit;
  494. pt_invoke = proc (inv: invoke, f: file);
  495. pt_expr(inv.apply, f);
  496. file$putc(f, '(');
  497. pt_exprlist(inv.args, f);
  498. file$putc(f, ')');
  499. tab: renaming := inv.rename;
  500. tagcase tab in
  501. idn:% (tab: idn):
  502. begin
  503. file$putc(f, '!');
  504. pt_idn(tab, f);
  505. end;
  506. list:% (tab: renamelist):
  507. begin
  508. file$putc(f, '!');
  509. pt_renamelist(tab, f);
  510. end;
  511. out: ;
  512. end;
  513. end pt_invoke;
  514. pt_assn = proc (asn: assn, f: file);
  515. pt_idnlist(asn.left, f);
  516. file$puts(f, " := ");
  517. pt_exprlist(asn.right, f);
  518. end pt_assn;
  519. pt_sugarassn = proc (asn: sugarassn, f: file);
  520. pt_expr(asn.left, f);
  521. file$puts(f, " := ");
  522. pt_expr(asn.right, f);
  523. end pt_sugarassn;
  524. pt_whilestmt = proc (ws: whilestmt, f: file);
  525. margin: int := get_margin();
  526. file$puts(f, "while ");
  527. pt_expr(ws.test, f);
  528. file$puts(f, " do");
  529. set_margin(margin + delta);
  530. pt_newline(f);
  531. pt_body(ws.body, f);
  532. pt_newline(f);
  533. file$puts(f, "end");
  534. set_margin(margin);
  535. end pt_whilestmt;
  536. pt_forvars = proc (vars: forvars, f: file);
  537. x: forvars := vars;
  538. tagcase x in
  539. old:% (x: idnlist):
  540. pt_idnlist(x, f);
  541. new:% (x: decllist):
  542. pt_decllist(x, f);
  543. end;
  544. end pt_forvars;
  545. pt_forstmt = proc (fs: forstmt, f: file);
  546. margin: int := get_margin();
  547. file$puts(f, "for ");
  548. pt_forvars(fs.vars, f);
  549. file$puts(f, " in ");
  550. pt_invoke(fs.call, f);
  551. file$puts(f, " do");
  552. set_margin(margin + delta);
  553. pt_newline(f);
  554. pt_body(fs.body, f);
  555. pt_newline(f);
  556. file$puts(f, "end");
  557. set_margin(margin);
  558. end pt_forstmt;
  559. pt_ifarm = proc (arm: ifarm, f: file);
  560. margin: int := get_margin();
  561. new_margin(f);
  562. pt_expr(arm.test, f);
  563. pt_newline(f);
  564. file$puts(f, "then ");
  565. new_margin(f);
  566. pt_body(arm.body, f);
  567. set_margin(margin);
  568. end pt_ifarm;
  569. pt_ifarmlist = proc (list: ifarmlist, f: file);
  570. margin: int := get_margin();
  571. high: int := ifarmlist$high(list);
  572. low: int := ifarmlist$low(list);
  573. file$puts(f, "if ");
  574. new_margin(f);
  575. pt_ifarm(list[low], f);
  576. for i: int := low + 1 to high do begin
  577. pt_newline(f);
  578. file$puts(f, "elseif ");
  579. pt_ifarm(list[i], f);
  580. end;
  581. set_margin(margin);
  582. end pt_ifarmlist;
  583. pt_ifstmt = proc (ifs: ifstmt, f: file);
  584. pt_ifarmlist(ifs.arms, f);
  585. mbod: mbody := ifs.else_;
  586. tagcase mbod in
  587. body:% (mbod: body):
  588. begin
  589. margin: int := get_margin();
  590. pt_newline(f);
  591. file$puts(f, " else ");
  592. new_margin(f);
  593. pt_body(mbod, f);
  594. set_margin(margin);
  595. end;
  596. none: ;
  597. end;
  598. pt_newline(f);
  599. file$puts(f, " end");
  600. end pt_ifstmt;
  601. pt_tagarm = proc (arm: tagarm, f: file);
  602. margin: int := get_margin();
  603. file$puts(f, "tag ");
  604. pt_namelist(arm.tags, f);
  605. dec: mdecl := arm.var;
  606. tagcase dec in
  607. decl:% (dec: decl):
  608. begin
  609. file$puts(f, " (");
  610. pt_decl(dec, f);
  611. file$putc(f, ')');
  612. end;
  613. none: ;
  614. end;
  615. file$putc(f, ':');
  616. set_margin(margin + delta);
  617. pt_newline(f);
  618. pt_body(arm.body, f);
  619. set_margin(margin);
  620. end pt_tagarm;
  621. pt_tagarmlist = proc (list: tagarmlist, f: file);
  622. high: int := tagarmlist$high(list);
  623. for i: int := tagarmlist$low(list) to high do begin
  624. pt_tagarm(list[i], f);
  625. if i < high then pt_newline(f);
  626. end;
  627. end pt_tagarmlist;
  628. pt_tagstmt = proc (ts: tagstmt, f: file);
  629. margin: int := get_margin();
  630. file$puts(f, "tagcase ");
  631. pt_expr(ts.obj, f);
  632. set_margin(margin + delta);
  633. pt_newline(f);
  634. pt_tagarmlist(ts.arms, f);
  635. mbod: mbody := ts.others_;
  636. tagcase mbod in
  637. body:% (mbod: body):
  638. begin
  639. pt_newline(f);
  640. file$puts(f, "others:");
  641. set_margin(margin + 2 * delta);
  642. pt_newline(f);
  643. pt_body(mbod, f);
  644. end;
  645. none: ;
  646. end;
  647. set_margin(margin);
  648. pt_nextline(margin + delta, f);
  649. file$puts(f, "end");
  650. end pt_tagstmt;
  651. pt_error = proc (err: error, f: file);
  652. args: exprlist := err.args;
  653. pt_name(err.name, f);
  654. if exprlist$size(args) = 0
  655. then return;
  656. file$putc(f, '(');
  657. pt_exprlist(args, f);
  658. file$putc(f, ')');
  659. end pt_error;
  660. pt_whendecl = proc (dec: whendecl, f: file);
  661. x: whendecl := dec;
  662. tagcase x in
  663. decls:% (x: decllist):
  664. begin
  665. file$putc(f, '(');
  666. pt_decllist(x, f);
  667. file$putc(f, ')');
  668. end;
  669. star: file$puts(f, "(*)");
  670. none: ;
  671. end;
  672. end pt_whendecl;
  673. pt_handler = proc (h: handler, f: file);
  674. margin: int := get_margin();
  675. file$puts(f, "when ");
  676. new_margin(f);
  677. pt_namelist(h.names, f);
  678. pt_whendecl(h.vars, f);
  679. file$putc(f, ':');
  680. set_margin(margin + delta);
  681. pt_newline(f);
  682. pt_body(h.body, f);
  683. set_margin(margin);
  684. end pt_handler;
  685. pt_handlerlist = proc (list: handlerlist, f: file);
  686. high: int := handlerlist$high(list);
  687. for i: int := handlerlist$low(list) to high do begin
  688. pt_handler(list[i], f);
  689. if i < high then pt_newline(f);
  690. end;
  691. end pt_handlerlist;
  692. pt_othersarm = proc (arm: othersarm, f: file);
  693. margin: int := get_margin();
  694. file$puts(f, "others");
  695. dec: mdecl := arm.decl;
  696. tagcase dec in
  697. decl:% (dec: decl):
  698. begin
  699. file$puts(f, " (");
  700. pt_decl(dec, f);
  701. file$putc(f, ')');
  702. end;
  703. none: ;
  704. end;
  705. file$putc(f, ':');
  706. set_margin(margin + delta);
  707. pt_newline(f);
  708. pt_body(arm.body, f);
  709. set_margin(margin);
  710. end pt_othersarm;
  711. pt_exceptstmt = proc (ex: exceptstmt, f: file);
  712. margin: int := get_margin();
  713. pt_stmt(ex.stmt, f);
  714. file$putc(f, ';');
  715. pt_nextline(margin + delta, f);
  716. file$puts(f, "except");
  717. set_margin(margin + delta + 3);
  718. pt_newline(f);
  719. pt_handlerlist(ex.arms, f);
  720. moth: mothersarm := ex.others_;
  721. tagcase moth in
  722. arm:% (moth: othersarm):
  723. begin
  724. pt_newline(f);
  725. pt_othersarm(moth, f);
  726. end;
  727. none: ;
  728. end;
  729. pt_newline(f);
  730. file$puts(f, "end");
  731. set_margin(margin);
  732. end pt_exceptstmt;
  733. pt_stmt = proc (s: stmt, f: file);
  734. pt_stmtabs(stmt$get_abs(s), f);
  735. end pt_stmt;
  736. pt_stmtabs = proc (sa: stmtabs, f: file);
  737. x: stmtabs := sa;
  738. tagcase x in
  739. decl:% (x: decl):
  740. pt_decl(x, f);
  741. declinit:% (x: declinit):
  742. pt_declinit(x, f);
  743. assn:% (x: assn):
  744. pt_assn(x, f);
  745. sugarassn:% (x: sugarassn):
  746. pt_sugarassn(x, f);
  747. invoke:% (x: invoke):
  748. pt_invoke(x, f);
  749. while_:% (x: whilestmt):
  750. pt_whilestmt(x, f);
  751. for_:% (x: forstmt):
  752. pt_forstmt(x, f);
  753. if_:% (x: ifstmt):
  754. pt_ifstmt(x, f);
  755. tag_:% (x: tagstmt):
  756. pt_tagstmt(x, f);
  757. return_:% (x: exprlist):
  758. begin
  759. file$puts(f, "return");
  760. if exprlist$size(x) = 0
  761. then return;
  762. file$putc(f, '(');
  763. pt_exprlist(x, f);
  764. file$putc(f, ')');
  765. end;
  766. yield_:% (x: exprlist):
  767. begin
  768. file$puts(f, "yield");
  769. if exprlist$size(x) = 0
  770. then return;
  771. file$putc(f, '(');
  772. pt_exprlist(x, f);
  773. file$putc(f, ')');
  774. end;
  775. signal_:% (x: error):
  776. begin
  777. file$puts(f, "signal ");
  778. pt_error(x, f);
  779. end;
  780. break_:
  781. file$puts(f, "break");
  782. body:% (x: body):
  783. begin
  784. margin: int := get_margin();
  785. file$puts(f, "begin");
  786. set_margin(margin + delta);
  787. pt_newline(f);
  788. pt_body(x, f);
  789. set_margin(margin);
  790. pt_newline(f);
  791. file$puts(f, "end");
  792. end;
  793. except_:% (x: exceptstmt, f):
  794. pt_exceptstmt(x, f);
  795. bad: file$puts(f, "?stmt?");
  796. end;
  797. end pt_stmtabs;
  798. pt_applytyp = proc (typ: applytype, op: str, val: str, f: file);
  799. file$puts(f, op);
  800. file$puts(f, " (");
  801. pt_typelist(typ.args, f);
  802. file$putc(f, ')');
  803. if typelist$size(typ.vals) > 0
  804. then begin
  805. file$putc(f, ' ');
  806. file$puts(f, val);
  807. file$puts(f, " (");
  808. pt_typelist(typ.vals, f);
  809. file$putc(f, ')');
  810. end;
  811. if exceptionlist$size(typ.sigs) > 0
  812. then begin
  813. file$puts(f, " signals (");
  814. pt_exceptionlist(typ.sigs, f);
  815. file$putc(f, ')');
  816. end;
  817. end pt_applytyp;
  818. pt_applytype = proc (typ: applytype, f: file);
  819. pt_applytyp(typ, "opertype", "vals", f);
  820. end pt_applytype;
  821. pt_atype = proc (typ: atype, f: file);
  822. pt_idn(typ.idn, f);
  823. pt_constlist(typ.parms, f);
  824. end pt_atype;
  825. pt_dutype = proc (typ: dutype, f: file);
  826. file$puts(f, DU$get_unique(typ.mod));
  827. pt_constlist(typ.parms, f);
  828. end pt_dutype;
  829. pt_fieldspek = proc (spec: fieldspec, space: int, f: file);
  830. pt_name(spec.sel, f);
  831. file$putc(f, ':');
  832. for i: int := file$column(f) to space do begin
  833. file$putc(f, ' ');
  834. end;
  835. pt_typespec(spec.type_, f);
  836. end pt_fieldspek;
  837. pt_fieldspec = proc (spec: fieldspec, f: file);
  838. pt_fieldspek(spec, str$size(name$get_str(spec.sel)) + 1, f);
  839. end pt_fieldspec;
  840. pt_seltype = proc (list: fieldspeclist, mod: str, f: file);
  841. margin: int := get_margin();
  842. high: int := fieldspeclist$high(list);
  843. space: int := 0;
  844. file$puts(f, mod);
  845. file$putc(f, '[');
  846. new_margin(f);
  847. for i: int := fieldspeclist$low(list) to high do begin
  848. size: int := str$size(name$get_str(list[i].sel));
  849. if size > space then space := size;
  850. end;
  851. space := space + file$column(f) + 1;
  852. for i: int := fieldspeclist$low(list) to high do begin
  853. pt_fieldspek(list[i], space, f);
  854. if i < high
  855. then begin
  856. file$putc(f, ',');
  857. pt_newline(f);
  858. end;
  859. end;
  860. file$putc(f, ']');
  861. set_margin(margin);
  862. end pt_seltype;
  863. pt_fieldspeclist = proc (list: fieldspeclist, f: file);
  864. pt_seltype(list, "select", f);
  865. end pt_fieldspeclist;
  866. pt_othertype = proc (ot: othertype, f: file);
  867. x: othertype := ot;
  868. tagcase x in
  869. apply:% (x: apply):
  870. begin
  871. file$puts(f, "type_of(");
  872. pt_apply(x, f);
  873. file$putc(f, ')');
  874. end;
  875. op:% (x: clusterop):
  876. begin
  877. file$puts(f, "type_of(");
  878. pt_clusterop(x, f);
  879. file$putc(f, ')');
  880. end;
  881. return_:% (x: typespec):
  882. begin
  883. file$puts(f, "return_type(");
  884. pt_typespec(x, f);
  885. file$putc(f, ')');
  886. end;
  887. end;
  888. end pt_othertype;
  889. pt_typespec = proc (typ: typespec, f: file);
  890. pt_typeabs(typespec$get_print(typ), f);
  891. end pt_typespec;
  892. pt_typeabs = proc (ta: typeabs, f: file);
  893. x: typeabs := ta;
  894. tagcase x in
  895. bool_: file$puts(f, "bool");
  896. int_: file$puts(f, "int");
  897. str: file$puts(f, "string");
  898. char_: file$puts(f, "char");
  899. null_: file$puts(f, "null");
  900. any_: file$puts(f, "any");
  901. type_: file$puts(f, "type");
  902. cvt_: file$puts(f, "cvt");
  903. rep_: file$puts(f, "rep", f);
  904. record_:% (x: fieldspeclist):
  905. pt_seltype(x, "record", f);
  906. oneof_:% (x: fieldspeclist):
  907. pt_seltype(x, "oneof", f);
  908. array_:% (x: typespec):
  909. begin
  910. file$puts(f, "array[");
  911. pt_typespec(x, f);
  912. file$putc(f, ']');
  913. end;
  914. proc_:% (x: applytype):
  915. pt_applytyp(x, "proctype", "returns", f);
  916. iter_:% (x: applytype):
  917. pt_applytyp(x, "itertype", "yields", f);
  918. abstract:% (x: atype):
  919. pt_atype(x, f);
  920. du:% (x: dutype):
  921. pt_dutype(x, f);
  922. parm:% (x: idn):
  923. pt_idn(x, f);
  924. other:% (x: othertype):
  925. pt_othertype(x, f);
  926. unknown: file$puts(f, "?type?");
  927. end;
  928. end pt_typeabs;
  929. pt_infixop = proc (op: infixop, f: file);
  930. s: str;
  931. tagcase op in
  932. pow: s := "**";
  933. mod: s := "//";
  934. div: s := "/";
  935. mul: s := "*";
  936. cat: s := "||";
  937. add: s := "+";
  938. sub: s := "-";
  939. lt: s := "<";
  940. nge: s := "~>=";
  941. le: s := "<=";
  942. ngt: s := "~>";
  943. gt: s := ">";
  944. nle: s := "~<=";
  945. ge: s := ">=";
  946. nlt: s := "~<";
  947. eq: s := "=";
  948. neq: s := "~=";
  949. and: s := "&";
  950. cand_: s := "cand";
  951. or: s := "|";
  952. cor_: s := "cor";
  953. end;
  954. file$puts(f, s);
  955. end pt_infixop;
  956. pt_infix = proc (inf: infix, f: file);
  957. lp: int := get_expr_prec(inf.left);
  958. cp: int := get_prec(inf.op);
  959. rp: int := get_expr_prec(inf.right);
  960. if cor(lp < cp, cand(cp = 5, lp = 5))
  961. then begin
  962. file$putc(f, '(');
  963. pt_expr(inf.left, f);
  964. file$putc(f, ')');
  965. end;
  966. else pt_expr(inf.left, f);
  967. file$putc(f, ' ');
  968. pt_infixop(inf.op, f);
  969. file$putc(f, ' ');
  970. if cand(rp <= cp, ~cand(cp = 5, rp = 5))
  971. then begin
  972. file$putc(f, '(');
  973. pt_expr(inf.right, f);
  974. file$putc(f, ')');
  975. end;
  976. else pt_expr(inf.right, f);
  977. end pt_infix;
  978. get_expr_prec = proc (x: expr) returns (int);
  979. xa: exprabs := expr$get_abs(x);
  980. tagcase xa in
  981. infix: return(get_prec(xa.op));
  982. out: return(6);
  983. end;
  984. end get_expr_prec;
  985. get_prec = proc (op: infixop) returns (int);
  986. tagcase op in
  987. pow: return(5);
  988. mod, div, mul: return(4);
  989. cat, add, sub: return(3);
  990. lt, nge, le, ngt, gt,
  991. nle, ge, nlt, eq, neq: return(2);
  992. and, cand_: return(1);
  993. or, cor_: return(0);
  994. end;
  995. end get_prec;
  996. pt_get_sugar = proc (ref: get_sugar, f: file);
  997. pt_expr(ref.object, f);
  998. file$putc(f, '.');
  999. pt_name(ref.sel, f);
  1000. end pt_get_sugar;
  1001. pt_fetch_sugar = proc (ref: fetch_sugar, f: file);
  1002. pt_expr(ref.object, f);
  1003. file$putc(f, '[');
  1004. pt_expr(ref.index, f);
  1005. file$putc(f, ']');
  1006. end pt_fetch_sugar;
  1007. pt_arraycons = proc (cons: arraycons, f: file);
  1008. pt_typespec(cons.type_, f);
  1009. file$puts(f, "$[");
  1010. mx: mexpr := cons.low;
  1011. tagcase mx in
  1012. one:% (mx: expr):
  1013. begin
  1014. pt_expr(mx, f);
  1015. file$puts(f, ": ");
  1016. end;
  1017. none: ;
  1018. end;
  1019. pt_exprlist(cons.elts, f);
  1020. file$putc(f, ']');
  1021. end pt_arraycons;
  1022. pt_field = proc (fld: field, f: file);
  1023. pt_namelist(fld.sels, f);
  1024. file$puts(f, ": ");
  1025. pt_expr(fld.val, f);
  1026. end pt_field;
  1027. pt_fieldlist = proc (list: fieldlist, f: file);
  1028. high: int := fieldlist$high(list);
  1029. for i: int := fieldlist$low(list) to high do begin
  1030. pt_field(list[i], f);
  1031. if i < high
  1032. then begin
  1033. file$putc(f, ',');
  1034. pt_newline(f);
  1035. end;
  1036. end;
  1037. end pt_fieldlist;
  1038. pt_recordcons = proc (cons: recordcons, f: file);
  1039. margin: int := get_margin();
  1040. pt_typespec(cons.type_, f);
  1041. file$puts(f, "${");
  1042. new_margin(f);
  1043. pt_fieldlist(cons.fields, f);
  1044. file$putc(f, '}');
  1045. set_margin(margin);
  1046. end pt_recordcons;
  1047. pt_bracketref = proc (ref: bracketref, f: file);
  1048. pt_idn(ref.idn, f);
  1049. pt_constlist(ref.parms, f);
  1050. end pt_bracketref;
  1051. pt_expr = proc (ex: expr, f: file);
  1052. pt_exprabs(expr$get_abs(ex), f);
  1053. end pt_expr;
  1054. pt_exprabs = proc (ea: exprabs, f: file);
  1055. x: exprabs := ea;
  1056. tagcase x in
  1057. infix:% (x: infix):
  1058. pt_infix(x, f);
  1059. null_:
  1060. file$puts(f, "nil");
  1061. bool_:% (x: bool):
  1062. file$puts(f, if x then "true" else "false");
  1063. str:% (x: strid):
  1064. pt_strid(x, f);
  1065. int_:% (x: intid):
  1066. pt_intid(x, f);
  1067. char_:% (x: charid):
  1068. pt_charid(x, f);
  1069. idn:% (x: idn):
  1070. pt_idn(x, f);
  1071. not:% (x: expr):
  1072. begin
  1073. file$putc(f, '~');
  1074. pt_expr(x, f);
  1075. end;
  1076. minus:% (x: expr):
  1077. begin
  1078. file$putc(f, '-');
  1079. pt_expr(x, f);
  1080. end;
  1081. get:% (x: get_sugar):
  1082. pt_get_sugar(x, f);
  1083. fetch:% (x: fetch_sugar):
  1084. pt_fetch_sugar(x, f);
  1085. invoke:% (x: invoke):
  1086. pt_invoke(x, f);
  1087. a_cons:% (x: arraycons):
  1088. pt_arraycons(x, f);
  1089. r_cons:% (x: recordcons):
  1090. pt_recordcons(x, f);
  1091. apply:% (x: apply):
  1092. pt_apply(x, f);
  1093. op:% (x: clusterop):
  1094. pt_clusterop(x, f);
  1095. force_:% (x: typespec):
  1096. begin
  1097. file$puts(f, "force[");
  1098. pt_typespec(x, f);
  1099. file$putc(f, ']');
  1100. end;
  1101. up_:% (x: expr, f):
  1102. begin
  1103. file$puts(f, "up(");
  1104. pt_expr(x, f);
  1105. file$putc(f, ')');
  1106. end;
  1107. down_:% (x: expr):
  1108. begin
  1109. file$puts(f, "down(");
  1110. pt_expr(x, f);
  1111. file$putc(f, ')');
  1112. end;
  1113. ref:% (x: bracketref):
  1114. pt_bracketref(x, f);
  1115. bad:
  1116. file$puts(f, "?expr?");
  1117. end;
  1118. end pt_exprabs;