rprint.red 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. module rprint; % The Standard LISP to REDUCE pretty-printer.
  2. % Author: Anthony C. Hearn.
  3. create!-package('(rprint),'(util));
  4. fluid '(!*n buffp combuff!* curmark curpos orig pretop pretoprinf rmar);
  5. global '(rprifn!* rterfn!*);
  6. Comment RPRIFN!* allows output from RPRINT to be handled differently,
  7. RTERFN!* allows end of lines to be handled differently;
  8. pretop := 'op; pretoprinf := 'oprinf;
  9. symbolic procedure rprint u;
  10. begin integer !*n; scalar buff,buffp,curmark,rmar,x;
  11. curmark := 0;
  12. buff := buffp := list list(0,0);
  13. rmar := linelength nil;
  14. x := get('!*semicol!*,pretop);
  15. !*n := 0;
  16. mprino1(u,list(caar x,cadar x));
  17. prin2ox ";";
  18. omarko curmark;
  19. prinos buff
  20. end;
  21. symbolic procedure rprin1 u;
  22. begin scalar buff,buffp,curmark,x;
  23. curmark := 0;
  24. buff := buffp := list list(0,0);
  25. x := get('!*semicol!*,pretop);
  26. mprino1(u,list(caar x,cadar x));
  27. omarko curmark;
  28. prinos buff
  29. end;
  30. symbolic procedure mprino u; mprino1(u,list(0,0));
  31. symbolic procedure mprino1(u,v);
  32. begin scalar x;
  33. if x := atsoc(u,combuff!*)
  34. then <<for each y in cdr x do comprox y;
  35. combuff!* := delete(x,combuff!*)>>;
  36. if numberp u and u<0 and (x := get('difference,pretop))
  37. then return begin scalar p;
  38. x := car x;
  39. p := (not car x>cadr v) or (not cadr x>car v);
  40. if p then prin2ox "(";
  41. prinox u;
  42. if p then prinox ")"
  43. end
  44. else if atom u then return prinox u
  45. else if not atom car u
  46. then <<curmark := curmark+1;
  47. prin2ox "("; mprino car u; prin2ox ")";
  48. omark list(curmark,3); curmark := curmark-1>>
  49. else if x := get(car u,pretoprinf)
  50. then return begin scalar p;
  51. p := car v>0
  52. and not car u
  53. memq '(block procedure prog quote string);
  54. if p then prin2ox "(";
  55. apply1(x,cdr u);
  56. if p then prin2ox ")"
  57. end
  58. else if x := get(car u,pretop)
  59. then return if car x then inprinox(u,car x,v)
  60. % Next line commented out since not all user infix operators are binary.
  61. % else if cddr u then rederr "Syntax error"
  62. else if null cadr x then inprinox(u,list(100,1),v)
  63. else inprinox(u,list(100,cadr x),v)
  64. else if flagp(car u,'modefn) and eqcar(cadr u,'procedure)
  65. then return proceox(cadadr u . car u . cdr cddadr u)
  66. else prinox car u;
  67. if rlistatp car u then return rlpri cdr u;
  68. u := cdr u;
  69. if null u then prin2ox "()"
  70. else mprargs(u,v)
  71. end;
  72. symbolic procedure mprargs(u,v);
  73. if null cdr u then <<prin2ox " "; mprino1(car u,list(100,100))>>
  74. else inprinox('!*comma!* . u,list(0,0),v);
  75. symbolic procedure inprinox(u,x,v);
  76. begin scalar p;
  77. p := (not car x>cadr v) or (not cadr x>car v);
  78. if p then prin2ox "("; omark '(m u);
  79. inprino(car u,x,cdr u);
  80. if p then prin2ox ")"; omark '(m d)
  81. end;
  82. symbolic procedure inprino(opr,v,l);
  83. begin scalar flg,x;
  84. curmark := curmark+2;
  85. x := get(opr,pretop);
  86. if x and car x
  87. then <<mprino1(car l,list(car v,0)); l := cdr l; flg := t>>;
  88. while l do
  89. <<if opr eq '!*comma!* then <<prin2ox ","; omarko curmark>>
  90. else if opr eq 'setq
  91. then <<prin2ox " := "; omark list(curmark,1)>>
  92. else if atom car l or not opr eq get(caar l,'alt)
  93. then <<omark list(curmark,1); oprino(opr,flg); flg := t>>;
  94. mprino1(car l,list(if null cdr l then 0 else car v,
  95. if null flg then 0 else cadr v));
  96. l := cdr l>>;
  97. curmark := curmark-2
  98. end;
  99. symbolic procedure oprino(opr,b);
  100. (lambda x; if null x
  101. then <<if b then prin2ox " "; prinox opr; prin2ox " ">>
  102. else <<if y then prin2ox " "; prin2ox x;
  103. if y then prin2ox " ">>
  104. where y = flagp(opr,'spaced))
  105. get(opr,'prtch);
  106. flag('(cons),'spaced);
  107. symbolic procedure prin2ox u;
  108. <<rplacd(buffp,explodex u);
  109. while cdr buffp do buffp := cdr buffp>>;
  110. symbolic procedure explodex u;
  111. % "Explodes" atom U without including escape characters.
  112. if numberp u then explode u
  113. else if stringp u then reversip cdr reversip cdr explode u
  114. else explodex1 explode u;
  115. symbolic procedure explodex1 u;
  116. if null u then nil
  117. else if car u eq '!! then cadr u . explodex1 cddr u
  118. else check!-downcase car u . explodex1 cdr u;
  119. symbolic procedure explodey u;
  120. begin scalar v;
  121. v := explode u;
  122. if idp u then v := for each x in v collect check!-downcase x;
  123. return v
  124. end;
  125. symbolic procedure check!-downcase u;
  126. begin scalar z;
  127. return if liter u
  128. and (z := atsoc(u,
  129. '((!A . !a) (!B . !b) (!C . !c) (!D . !d) (!E . !e)
  130. (!F . !f) (!G . !g) (!H . !h) (!I . !i) (!J . !j)
  131. (!K . !k) (!L . !l) (!M . !m) (!N . !n) (!O . !o)
  132. (!P . !p) (!Q . !q) (!R . !r) (!S . !s) (!T . !t)
  133. (!U . !u) (!V . !v) (!W . !w) (!X . !x) (!Y . !y)
  134. (!Z . !z))))
  135. then cdr z
  136. else u
  137. end;
  138. symbolic procedure prinox u;
  139. <<if x then u := x;
  140. rplacd(buffp,explodey u);
  141. while cdr buffp do buffp := cdr buffp>>
  142. where x = get(u,'oldnam);
  143. symbolic procedure omark u;
  144. <<rplacd(buffp,list u); buffp := cdr buffp>>;
  145. symbolic procedure omarko u; omark list(u,0);
  146. symbolic procedure comprox u;
  147. begin scalar x;
  148. if car buffp = '(0 0)
  149. then return <<for each j in u do prin2ox j;
  150. omark '(0 0)>>;
  151. x := car buffp;
  152. rplaca(buffp,list(curmark+1,3));
  153. for each j in u do prin2ox j;
  154. omark x
  155. end;
  156. symbolic procedure rlistatp u;
  157. get(u,'stat) member '(endstat rlis);
  158. symbolic procedure rlpri u;
  159. if null u then nil
  160. else begin
  161. prin2ox " ";
  162. omark '(m u);
  163. inprino('!*comma!*,list(0,0),u);
  164. omark '(m d)
  165. end;
  166. symbolic procedure condox u;
  167. begin scalar x;
  168. omark '(m u);
  169. curmark := curmark+2;
  170. while u do
  171. <<prin2ox "if "; mprino caar u; omark list(curmark,1);
  172. prin2ox " then ";
  173. if cdr u and eqcar(cadar u,'cond)
  174. and not eqcar(car reverse cadar u,'t)
  175. then <<x := t; prin2ox "(">>;
  176. mprino cadar u;
  177. if x then prin2ox ")";
  178. u := cdr u;
  179. if u then <<omarko(curmark-1); prin2ox " else ">>;
  180. if u and null cdr u and caar u eq 't
  181. then <<mprino cadar u; u := nil>>>>;
  182. curmark := curmark-2;
  183. omark '(m d)
  184. end;
  185. put('cond,pretoprinf,'condox);
  186. symbolic procedure blockox u;
  187. begin
  188. omark '(m u);
  189. curmark := curmark+2;
  190. prin2ox "begin ";
  191. if car u then varprx car u;
  192. u := labchk cdr u;
  193. omark list(curmark,if eqcar(car u,'!*label) then 1 else 3);
  194. while u do
  195. <<mprino car u;
  196. if not eqcar(car u,'!*label) and cdr u then prin2ox "; ";
  197. u := cdr u;
  198. if u
  199. then omark list(curmark,
  200. if eqcar(car u,'!*label) then 1 else 3)>>;
  201. omark list(curmark-1,-1);
  202. prin2ox " end";
  203. curmark := curmark-2;
  204. omark '(m d)
  205. end;
  206. symbolic procedure retox u;
  207. begin
  208. omark '(m u);
  209. curmark := curmark+2;
  210. prin2ox "return ";
  211. omark '(m u);
  212. mprino car u;
  213. curmark := curmark-2;
  214. omark '(m d);
  215. omark '(m d)
  216. end;
  217. put('return,pretoprinf,'retox);
  218. % symbolic procedure varprx u;
  219. % mapc(cdr u,function (lambda j;
  220. % <<prin2ox car j;
  221. % prin2ox " ";
  222. % inprino('!*comma!*,list(0,0),cdr j);
  223. % prin2ox "; ";
  224. % omark list(curmark,6)>>));
  225. Comment a version for the old parser;
  226. symbolic procedure varprx u;
  227. begin scalar typ;
  228. u := reverse u;
  229. while u do
  230. <<if cdar u eq typ
  231. then <<prin2ox ","; omarko(curmark+1); prinox caar u>>
  232. else <<if typ then <<prin2ox "; "; omark '(m d)>>;
  233. prinox (typ := cdar u);
  234. prin2ox " "; omark '(m u); prinox caar u>>;
  235. u := cdr u>>;
  236. prin2ox "; ";
  237. omark '(m d)
  238. end;
  239. put('block,pretoprinf,'blockox);
  240. symbolic procedure progox u;
  241. blockox(mapcar(reverse car u,function (lambda j; j . 'scalar))
  242. . cdr u);
  243. symbolic procedure labchk u;
  244. begin scalar x;
  245. for each z in u do if atom z
  246. then x := list('!*label,z) . x else x := z . x;
  247. return reversip x
  248. end;
  249. put('prog,pretoprinf,'progox);
  250. symbolic procedure gox u;
  251. <<prin2ox "go to "; prinox car u>>;
  252. put('go,pretoprinf,'gox);
  253. symbolic procedure labox u;
  254. <<prinox car u; prin2ox ": ">>;
  255. put('!*label,pretoprinf,'labox);
  256. symbolic procedure quotox u;
  257. if stringp u then prinox u else <<prin2ox "'"; prinsox car u>>;
  258. symbolic procedure prinsox u;
  259. if atom u then prinox u
  260. else <<prin2ox "(";
  261. omark '(m u);
  262. curmark := curmark+1;
  263. while u do <<prinsox car u;
  264. u := cdr u;
  265. if u then <<omark list(curmark,-1);
  266. if atom u
  267. then <<prin2ox " . "; prinsox u; u := nil>>
  268. else prin2ox " ">>>>;
  269. curmark := curmark-1;
  270. omark '(m d);
  271. prin2ox ")">>;
  272. put('quote,pretoprinf,'quotox);
  273. symbolic procedure prognox u;
  274. begin
  275. curmark := curmark+1;
  276. prin2ox "<<";
  277. omark '(m u);
  278. while u do <<mprino car u; u := cdr u;
  279. if u then <<prin2ox "; "; omarko curmark>>>>;
  280. omark '(m d);
  281. prin2ox ">>";
  282. curmark := curmark-1
  283. end;
  284. put('prog2,pretoprinf,'prognox);
  285. put('progn,pretoprinf,'prognox);
  286. symbolic procedure repeatox u;
  287. begin
  288. curmark := curmark+1;
  289. omark '(m u);
  290. prin2ox "repeat ";
  291. mprino car u;
  292. prin2ox " until ";
  293. omark list(curmark,3);
  294. mprino cadr u;
  295. omark '(m d);
  296. curmark := curmark-1
  297. end;
  298. put('repeat,pretoprinf,'repeatox);
  299. symbolic procedure whileox u;
  300. begin
  301. curmark := curmark+1;
  302. omark '(m u);
  303. prin2ox "while ";
  304. mprino car u;
  305. prin2ox " do ";
  306. omark list(curmark,3);
  307. mprino cadr u;
  308. omark '(m d);
  309. curmark := curmark-1
  310. end;
  311. put('while,pretoprinf,'whileox);
  312. symbolic procedure procox u;
  313. begin
  314. omark '(m u);
  315. curmark := curmark+1;
  316. if cadddr cdr u then <<mprino cadddr cdr u; prin2ox " ">>;
  317. prin2ox "procedure ";
  318. procox1(car u,cadr u,caddr u)
  319. end;
  320. symbolic procedure procox1(u,v,w);
  321. begin
  322. prinox u;
  323. if v then mprargs(v,list(0,0));
  324. prin2ox "; ";
  325. omark list(curmark,3);
  326. mprino w;
  327. curmark := curmark-1;
  328. omark '(m d)
  329. end;
  330. put('proc,pretoprinf,'procox);
  331. symbolic procedure proceox u;
  332. begin
  333. omark '(m u);
  334. curmark := curmark+1;
  335. if cadr u then <<mprino cadr u; prin2ox " ">>;
  336. if not caddr u eq 'expr then <<mprino caddr u; prin2ox " ">>;
  337. prin2ox "procedure ";
  338. proceox1(car u,cadddr u,car cddddr u)
  339. end;
  340. symbolic procedure proceox1(u,v,w);
  341. begin
  342. prinox u;
  343. if v
  344. then <<if not atom car v then v:= for each j in v collect car j;
  345. %allows for typing to be included with proc arguments;
  346. mprargs(v,list(0,0))>>;
  347. prin2ox "; ";
  348. omark list(curmark,3);
  349. mprino w;
  350. curmark := curmark -1;
  351. omark '(m d)
  352. end;
  353. put('procedure,pretoprinf,'proceox);
  354. symbolic procedure proceox0(u,v,w,x);
  355. proceox list(u,'symbolic,v,
  356. mapcar(w,function (lambda j; j . 'symbolic)),x);
  357. symbolic procedure deox u;
  358. proceox0(car u,'expr,cadr u,caddr u);
  359. put('de,pretoprinf,'deox);
  360. % symbolic procedure dfox u;
  361. % proceox0(car u,'fexpr,cadr u,caddr u);
  362. %put('df,pretoprinf,'dfox); % Commented out because of confusion with
  363. % differentiation.
  364. symbolic procedure stringox u;
  365. <<prin2ox '!"; prin2ox car u; prin2ox '!">>;
  366. put('string,pretoprinf,'stringox);
  367. symbolic procedure lambdox u;
  368. begin
  369. omark '(m u);
  370. curmark := curmark+1;
  371. procox1('lambda,car u,cadr u)
  372. end;
  373. put('lambda,pretoprinf,'lambdox);
  374. symbolic procedure eachox u;
  375. <<prin2ox "for each ";
  376. while cdr u do <<mprino car u; prin2ox " "; u := cdr u>>;
  377. mprino car u>>;
  378. put('foreach,pretoprinf,'eachox);
  379. symbolic procedure forox u;
  380. begin
  381. curmark := curmark+1;
  382. omark '(m u);
  383. prin2ox "for ";
  384. mprino car u;
  385. prin2ox " := ";
  386. mprino caadr u;
  387. if cadr cadr u neq 1
  388. then <<prin2ox " step "; mprino cadr cadr u; prin2ox " until ">>
  389. else prin2ox ":";
  390. mprino caddr cadr u;
  391. prin2ox " ";
  392. mprino caddr u;
  393. prin2ox " ";
  394. omark list(curmark,3);
  395. mprino cadddr u;
  396. omark '(m d);
  397. curmark := curmark-1
  398. end;
  399. put('for,pretoprinf,'forox);
  400. symbolic procedure forallox u;
  401. begin
  402. curmark := curmark+1;
  403. omark '(m u);
  404. prin2ox "for all ";
  405. inprino('!*comma!*,list(0,0),car u);
  406. if cadr u
  407. then <<omark list(curmark,3);
  408. prin2ox " such that ";
  409. mprino cadr u>>;
  410. prin2ox " ";
  411. omark list(curmark,3);
  412. mprino caddr u;
  413. omark '(m d);
  414. curmark := curmark-1
  415. end;
  416. put('forall,pretoprinf,'forallox);
  417. Comment Declarations needed by old parser;
  418. if null get('!*semicol!*,'op)
  419. then <<put('!*semicol!*,'op,'((-1 0)));
  420. put('!*comma!*,'op,'((5 6)))>>;
  421. Comment RPRINT MODULE, Part 2;
  422. fluid '(orig curpos);
  423. symbolic procedure prinos u;
  424. begin integer curpos;
  425. scalar orig;
  426. orig := list posn();
  427. curpos := car orig;
  428. prinoy(u,0);
  429. terpri0x()
  430. end;
  431. symbolic procedure prinoy(u,n);
  432. begin scalar x;
  433. if car(x := spaceleft(u,n)) then return prinom(u,n)
  434. else if null cdr x then return if car orig<10 then prinom(u,n)
  435. else <<orig := 9 . cdr orig;
  436. terpri0x();
  437. spaces20x(curpos := 9+cadar u);
  438. prinoy(u,n)>>
  439. else begin
  440. a: u := prinoy(u,n+1);
  441. if null cdr u or caar u<=n then return;
  442. terpri0x();
  443. spaces20x(curpos := car orig+cadar u);
  444. go to a end;
  445. return u
  446. end;
  447. symbolic procedure spaceleft(u,mark);
  448. %U is an expanded buffer of characters delimited by non-atom marks
  449. %of the form: '(M ...) or '(INT INT))
  450. %MARK is an integer;
  451. begin integer n; scalar flg,mflg;
  452. n := rmar - curpos;
  453. u := cdr u; %move over the first mark;
  454. while u and not flg and n>=0 do
  455. <<if atom car u then n := n-1
  456. else if caar u eq 'm then nil
  457. else if mark>=caar u then <<flg := t; u := nil . u>>
  458. else mflg := t;
  459. u := cdr u>>;
  460. return ((n>=0) . mflg)
  461. end;
  462. symbolic procedure prinom(u,mark);
  463. begin integer n; scalar flg,x;
  464. n := curpos;
  465. u := cdr u;
  466. while u and not flg do
  467. <<if atom car u then <<x := prin20x car u; n := n+1>>
  468. else if caar u eq 'm
  469. then if cadar u eq 'u then orig := n . orig
  470. else orig := cdr orig
  471. else if mark>=caar u
  472. and not(x='!, and rmar-n-6>charspace(u,x,mark))
  473. then <<flg := t; u := nil . u>>;
  474. u := cdr u>>;
  475. curpos := n;
  476. if mark=0 and cdr u
  477. then <<terpri0x();
  478. terpri0x();
  479. orig := list 0; curpos := 0; prinoy(u,mark)>>;
  480. %must be a top level constant;
  481. return u
  482. end;
  483. symbolic procedure charspace(u,char,mark);
  484. %determines if there is space until the next character CHAR;
  485. begin integer n;
  486. n := 0;
  487. while u do
  488. <<if car u = char then u := list nil
  489. else if atom car u then n := n+1
  490. else if car u='(m u) then <<n := 1000; u := list nil>>
  491. else if numberp caar u and caar u<mark then u := list nil;
  492. u := cdr u>>;
  493. return n
  494. end;
  495. symbolic procedure spaces20x n;
  496. %for i := 1:n do prin20x '! ;
  497. while n>0 do <<prin20x '! ; n := n-1>>;
  498. symbolic procedure prin2rox u;
  499. begin integer m,n; scalar x,y;
  500. m := rmar-12;
  501. n := rmar-1;
  502. while u do
  503. if car u eq '!"
  504. then <<if not stringspace(cdr u,n-!*n)
  505. then <<terpri0x(); !*n := 0>>
  506. else nil;
  507. prin20x '!";
  508. u := cdr u;
  509. while not car u eq '!" do
  510. <<prin20x car u; u := cdr u; !*n := !*n+1>>;
  511. prin20x '!";
  512. u := cdr u;
  513. !*n := !*n+2;
  514. x := y := nil>>
  515. else if atom car u and not(car u eq '! and (!*n=0 or null x
  516. or cdr u and breakp cadr u or breakp x and not y eq '!!))
  517. then <<y := x; prin20x(x := car u); !*n := !*n+1;
  518. u := cdr u;
  519. if !*n=n or !*n>m and not breakp car u and nospace(u,n-!*n)
  520. then <<terpri0x(); x := y := nil>> else nil>>
  521. else u := cdr u
  522. end;
  523. symbolic procedure nospace(u,n);
  524. if n<1 then t
  525. else if null u then nil
  526. else if not atom car u then nospace(cdr u,n)
  527. else if not car u eq '!! and (cadr u eq '! or breakp cadr u)
  528. then nil
  529. else nospace(cdr u,n-1);
  530. symbolic procedure breakp u;
  531. u member '(!< !> !; !: != !) !+ !- !, !' !");
  532. symbolic procedure stringspace(u,n);
  533. if n<1 then nil else car u eq '!" or stringspace(cdr u,n-1);
  534. Comment Some interfaces needed;
  535. symbolic procedure prin20x u;
  536. if rprifn!* then apply1(rprifn!*,u) else prin2 u;
  537. symbolic procedure terpri0x;
  538. if rterfn!* then lispapply(rterfn!*,nil) else terpri();
  539. endmodule;
  540. end;