rprint.red 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. module rprint; % The Standard LISP to REDUCE pretty-printer.
  2. % Author: Anthony C. Hearn.
  3. % Modifications by: Francis J. Wright.
  4. create!-package('(rprint),'(util));
  5. fluid '(!*lower !*n buffp combuff!* curmark curpos orig pretop
  6. pretoprinf rmar rprifn!* rterfn!*);
  7. comment RPRIFN!* allows output from RPRINT to be handled differently,
  8. RTERFN!* allows end of lines to be handled differently;
  9. pretop := 'op; pretoprinf := 'oprinf;
  10. symbolic procedure rprint u;
  11. begin integer !*n; scalar buff,buffp,curmark,rmar,x;
  12. curmark := 0;
  13. buff := buffp := list list(0,0);
  14. rmar := linelength nil;
  15. x := get('!*semicol!*,pretop);
  16. !*n := 0;
  17. mprino1(u,list(caar x,cadar x));
  18. prin2ox ";";
  19. omarko curmark;
  20. prinos buff
  21. end;
  22. symbolic procedure rprin1 u;
  23. begin scalar buff,buffp,curmark,x;
  24. curmark := 0;
  25. buff := buffp := list list(0,0);
  26. x := get('!*semicol!*,pretop);
  27. mprino1(u,list(caar x,cadar x));
  28. omarko curmark;
  29. prinos buff
  30. end;
  31. symbolic procedure mprino u; mprino1(u,list(0,0));
  32. symbolic procedure mprino1(u,v);
  33. begin scalar x;
  34. if x := atsoc(u,combuff!*)
  35. then <<for each y in cdr x do comprox y;
  36. combuff!* := delete(x,combuff!*)>>;
  37. if numberp u and u<0 and (x := get('difference,pretop))
  38. then return begin scalar p;
  39. x := car x;
  40. p := not(car x>cadr v) or not(cadr x>car v);
  41. if p then prin2ox "(";
  42. prinox u;
  43. if p then prinox ")"
  44. end
  45. else if atom u then return prinox u
  46. else if not atom car u and (x:=strangeop u)
  47. then return mprino1(x,v)
  48. else if not atom car u
  49. then <<curmark := curmark+1;
  50. prin2ox "("; mprino car u; prin2ox ")";
  51. omark list(curmark,3); curmark := curmark - 1>>
  52. else if x := get(car u,pretoprinf)
  53. then return begin scalar p;
  54. p := car v>0
  55. and not(car u memq
  56. '(list procedure prog quote rblock string));
  57. if p then prin2ox "(";
  58. apply1(x,cdr u);
  59. if p then prin2ox ")"
  60. end
  61. else if x := get(car u,pretop)
  62. then return if car x then inprinox(u,car x,v)
  63. % Next line commented out since not all user infix operators are binary.
  64. % else if cddr u then rederr "Syntax error"
  65. else if null cadr x then inprinox(u,list(100,1),v)
  66. else inprinox(u,list(100,cadr x),v)
  67. else if flagp(car u,'modefn) and eqcar(cadr u,'procedure)
  68. then return proceox(cadadr u . car u . cdr cddadr u)
  69. else prinox car u;
  70. if rlistatp car u then return rlpri cdr u;
  71. u := cdr u;
  72. if null u then prin2ox "()"
  73. else mprargs(u,v)
  74. end;
  75. symbolic procedure strangeop u;
  76. % U is a non-atomic operator; try to find a better print form for it.
  77. % The commented definition doesn't check the complexity of the
  78. % argument, and so can lead to more computation.
  79. % if caar u='lambda and length cadar u=1 then
  80. % subst(cadr u,car cadar u,car cddar u);
  81. nil;
  82. symbolic procedure mprargs(u,v);
  83. if null cdr u then <<prin2ox " "; mprino1(car u,list(100,100))>>
  84. else inprinox('!*comma!* . u,list(0,0),v);
  85. symbolic procedure inprinox(u,x,v);
  86. begin scalar p;
  87. p := not(car x>cadr v) or not(cadr x>car v);
  88. if p then prin2ox "("; omark '(m u);
  89. inprino(car u,x,cdr u);
  90. if p then prin2ox ")"; omark '(m d)
  91. end;
  92. symbolic procedure inprino(opr,v,l);
  93. begin scalar flg,x;
  94. curmark := curmark+2;
  95. x := get(opr,pretop);
  96. if x and car x
  97. then <<mprino1(car l,list(car v,0)); l := cdr l; flg := t>>;
  98. while l do
  99. <<if opr eq '!*comma!* then <<prin2ox ","; omarko curmark>>
  100. else if opr eq 'setq
  101. then <<prin2ox " := "; omark list(curmark,1)>>
  102. else if atom car l or not(opr eq get(caar l,'alt))
  103. then <<omark list(curmark,1); oprino(opr,flg); flg := t>>;
  104. mprino1(car l,list(if null cdr l then 0 else car v,
  105. if null flg then 0 else cadr v));
  106. l := cdr l>>;
  107. curmark := curmark - 2
  108. end;
  109. symbolic procedure oprino(opr,b);
  110. (lambda x; if null x
  111. then <<if b then prin2ox " "; prinox opr; prin2ox " ">>
  112. else <<if y then prin2ox " "; prin2ox x;
  113. if y then prin2ox " ">>
  114. where y = flagp(opr,'spaced))
  115. get(opr,'prtch);
  116. flag('(cons),'spaced);
  117. flag('(add mult over to),'spaced); % So that we don't have 1./1 etc.
  118. symbolic procedure prin2ox u;
  119. <<rplacd(buffp,explodex u);
  120. while cdr buffp do buffp := cdr buffp>>;
  121. symbolic procedure explodex u;
  122. % "Explodes" atom U without including escape characters.
  123. if numberp u then explode u
  124. else if stringp u then reversip cdr reversip cdr explode u
  125. else explodex1 explode u;
  126. symbolic procedure explodex1 u;
  127. if null u then nil
  128. else if car u eq '!! then cadr u . explodex1 cddr u
  129. else check!-downcase car u . explodex1 cdr u;
  130. symbolic procedure explodey u;
  131. begin scalar v;
  132. v := explode u;
  133. if idp u then v := for each x in v collect check!-downcase x;
  134. return v
  135. end;
  136. symbolic procedure check!-downcase u;
  137. begin scalar z;
  138. return if liter u
  139. and (z := atsoc(u,
  140. '((!A . !a) (!B . !b) (!C . !c) (!D . !d) (!E . !e)
  141. (!F . !f) (!G . !g) (!H . !h) (!I . !i) (!J . !j)
  142. (!K . !k) (!L . !l) (!M . !m) (!N . !n) (!O . !o)
  143. (!P . !p) (!Q . !q) (!R . !r) (!S . !s) (!T . !t)
  144. (!U . !u) (!V . !v) (!W . !w) (!X . !x) (!Y . !y)
  145. (!Z . !z))))
  146. then cdr z
  147. else u
  148. end;
  149. symbolic procedure prinox u;
  150. <<if x then u := x;
  151. rplacd(buffp,explodey u);
  152. while cdr buffp do buffp := cdr buffp>>
  153. where x = get(u,'oldnam);
  154. symbolic procedure omark u;
  155. <<rplacd(buffp,list u); buffp := cdr buffp>>;
  156. symbolic procedure omarko u; omark list(u,0);
  157. symbolic procedure comprox u;
  158. begin scalar x;
  159. if car buffp = '(0 0)
  160. then return <<for each j in u do prin2ox j;
  161. omark '(0 0)>>;
  162. x := car buffp;
  163. rplaca(buffp,list(curmark+1,3));
  164. for each j in u do prin2ox j;
  165. omark x
  166. end;
  167. symbolic procedure rlistatp u;
  168. get(u,'stat) member '(endstat rlis);
  169. symbolic procedure rlpri u;
  170. if null u then nil
  171. else begin
  172. prin2ox " ";
  173. omark '(m u);
  174. inprino('!*comma!*,list(0,0),u);
  175. omark '(m d)
  176. end;
  177. symbolic procedure condox u;
  178. begin scalar x;
  179. omark '(m u);
  180. curmark := curmark+2;
  181. while u do
  182. <<prin2ox "if "; mprino caar u; omark list(curmark,1);
  183. prin2ox " then ";
  184. if cdr u and eqcar(cadar u,'cond)
  185. and not eqcar(car reverse cadar u,'t)
  186. then <<x := t; prin2ox "(">>;
  187. mprino cadar u;
  188. if x then prin2ox ")";
  189. u := cdr u;
  190. if u then <<omarko(curmark - 1); prin2ox " else ">>;
  191. if u and null cdr u and caar u eq 't
  192. then <<mprino cadar u; u := nil>>>>;
  193. curmark := curmark - 2;
  194. omark '(m d)
  195. end;
  196. put('cond,pretoprinf,'condox);
  197. symbolic procedure blockox u;
  198. begin
  199. omark '(m u);
  200. curmark := curmark+2;
  201. prin2ox "begin ";
  202. if car u then varprx car u;
  203. u := labchk cdr u;
  204. omark list(curmark,if eqcar(car u,'!*label) then 1 else 3);
  205. while u do
  206. <<mprino car u;
  207. if not eqcar(car u,'!*label) and cdr u then prin2ox "; ";
  208. u := cdr u;
  209. if u
  210. then omark list(curmark,
  211. if eqcar(car u,'!*label) then 1 else 3)>>;
  212. omark list(curmark - 1,-1);
  213. prin2ox " end";
  214. curmark := curmark - 2;
  215. omark '(m d)
  216. end;
  217. symbolic procedure retox u;
  218. begin
  219. omark '(m u);
  220. curmark := curmark+2;
  221. prin2ox "return ";
  222. omark '(m u);
  223. mprino car u;
  224. curmark := curmark - 2;
  225. omark '(m d);
  226. omark '(m d)
  227. end;
  228. put('return,pretoprinf,'retox);
  229. symbolic procedure varprx u;
  230. begin scalar typ;
  231. while u do
  232. <<if cdar u eq typ
  233. then <<prin2ox ","; omarko(curmark+1); prinox caar u>>
  234. else <<if typ then <<prin2ox "; "; omark '(m d)>>;
  235. prinox (typ := cdar u);
  236. prin2ox " "; omark '(m u); prinox caar u>>;
  237. u := cdr u>>;
  238. prin2ox "; ";
  239. omark '(m d)
  240. end;
  241. put('rblock,pretoprinf,'blockox);
  242. symbolic procedure progox u;
  243. blockox((for each j in reverse car u collect j . 'scalar) . cdr u);
  244. symbolic procedure labchk u;
  245. begin scalar x;
  246. for each z in u do if atom z
  247. then x := list('!*label,z) . x else x := z . x;
  248. return reversip x
  249. end;
  250. put('prog,pretoprinf,'progox);
  251. symbolic procedure gox u;
  252. <<prin2ox "go to "; prinox car u>>;
  253. put('go,pretoprinf,'gox);
  254. symbolic procedure labox u;
  255. <<prinox car u; prin2ox ": ">>;
  256. put('!*label,pretoprinf,'labox);
  257. symbolic procedure quotoxx u;
  258. begin
  259. if stringp u then return prinox u;
  260. prin2ox "'";
  261. u := car u;
  262. if atom u then return prinox u;
  263. curmark := curmark+1;
  264. prin2ox "(";
  265. omark '(m u);
  266. a: if atom u then <<prin2ox " . "; prinox u; u := nil>>
  267. else <<mprino car u; u := cdr u;
  268. if u then <<prin2ox '! ; omarko curmark>>>>;
  269. if u then go to a;
  270. omark '(m d);
  271. prin2ox ")";
  272. curmark := curmark - 1
  273. end;
  274. symbolic procedure quotox u;
  275. if stringp u then prinox u else <<prin2ox "'"; prinsox car u>>;
  276. symbolic procedure prinsox u;
  277. if atom u then prinox u
  278. else <<curmark := curmark+1;
  279. prin2ox "(";
  280. omark '(m u);
  281. while u do <<prinsox car u;
  282. u := cdr u;
  283. if u then <<omark list(curmark,-1);
  284. if atom u
  285. then <<prin2ox " . "; prinsox u; u := nil>>
  286. else prin2ox " ">>>>;
  287. omark '(m d);
  288. prin2ox ")";
  289. curmark := curmark - 1>>;
  290. put('quote,pretoprinf,'quotox);
  291. symbolic procedure prognox u;
  292. begin
  293. curmark := curmark+1;
  294. prin2ox "<<";
  295. omark '(m u);
  296. while u do <<mprino car u; u := cdr u;
  297. if u then <<prin2ox "; "; omarko curmark>>>>;
  298. omark '(m d);
  299. prin2ox ">>";
  300. curmark := curmark - 1
  301. end;
  302. put('prog2,pretoprinf,'prognox);
  303. put('progn,pretoprinf,'prognox);
  304. symbolic procedure listox u;
  305. begin
  306. curmark := curmark+1;
  307. prin2ox "{";
  308. omark '(m u);
  309. while u do <<mprino car u; u := cdr u;
  310. % if u then <<prin2ox ", "; omarko curmark>>>>;
  311. if u then <<prin2ox ","; omarko curmark>>>>;
  312. omark '(m d);
  313. prin2ox "}";
  314. curmark := curmark - 1
  315. end;
  316. put('list,pretoprinf,'listox);
  317. symbolic procedure repeatox u;
  318. begin
  319. curmark := curmark+1;
  320. omark '(m u);
  321. prin2ox "repeat ";
  322. mprino car u;
  323. prin2ox " until ";
  324. omark list(curmark,3);
  325. mprino cadr u;
  326. omark '(m d);
  327. curmark := curmark - 1
  328. end;
  329. put('repeat,pretoprinf,'repeatox);
  330. symbolic procedure whileox u;
  331. begin
  332. curmark := curmark+1;
  333. omark '(m u);
  334. prin2ox "while ";
  335. mprino car u;
  336. prin2ox " do ";
  337. omark list(curmark,3);
  338. mprino cadr u;
  339. omark '(m d);
  340. curmark := curmark - 1
  341. end;
  342. put('while,pretoprinf,'whileox);
  343. symbolic procedure procox u;
  344. begin
  345. omark '(m u);
  346. curmark := curmark+1;
  347. if cadddr cdr u then <<mprino cadddr cdr u; prin2ox " ">>;
  348. prin2ox "procedure ";
  349. procox1(car u,cadr u,caddr u)
  350. end;
  351. symbolic procedure procox1(u,v,w);
  352. begin
  353. prinox u;
  354. if v then mprargs(v,list(0,0));
  355. prin2ox "; ";
  356. omark list(curmark,3);
  357. mprino w;
  358. curmark := curmark - 1;
  359. omark '(m d)
  360. end;
  361. put('proc,pretoprinf,'procox);
  362. symbolic procedure proceox u;
  363. begin
  364. omark '(m u);
  365. curmark := curmark+1;
  366. if cadr u then <<mprino cadr u; prin2ox " ">>;
  367. if not(caddr u eq 'expr) then <<mprino caddr u; prin2ox " ">>;
  368. prin2ox "procedure ";
  369. proceox1(car u,cadddr u,car cddddr u)
  370. end;
  371. symbolic procedure proceox1(u,v,w);
  372. % Prettyprint the procedure's argument list, any active annotation,
  373. % and its body.
  374. begin scalar annot;
  375. prinox u;
  376. if v
  377. then <<if not atom car v then v := mapovercar v;
  378. %allows for typing to be included with proc arguments;
  379. mprargs(v,list(0,0))>>;
  380. prin2ox "; ";
  381. if annot := get(u,'active!-annotation) then
  382. <<omark list(curmark,3);
  383. prin2ox "/* ";
  384. princom car annot;
  385. prin2ox " */";
  386. omark '(m d)>>;
  387. omark list(curmark,3);
  388. mprino w;
  389. curmark := curmark - 1;
  390. omark '(m d)
  391. end;
  392. put('procedure,pretoprinf,'proceox);
  393. symbolic procedure proceox0(u,v,w,x);
  394. proceox list(u,'symbolic,v,for each j in w collect j . 'symbolic,x);
  395. symbolic procedure deox u;
  396. proceox0(car u,'expr,cadr u,caddr u);
  397. put('de,pretoprinf,'deox);
  398. % symbolic procedure dfox u;
  399. % proceox0(car u,'fexpr,cadr u,caddr u);
  400. %put('df,pretoprinf,'dfox); % Commented out because of confusion with
  401. % differentiation. We also want to
  402. % discourage use of fexpr in REDUCE.
  403. symbolic procedure dsox u;
  404. proceox0(car u,'smacro,cadr u,caddr u);
  405. put('ds,pretoprinf,'dsox);
  406. symbolic procedure stringox u;
  407. <<prin2ox '!"; prin2ox car u; prin2ox '!">>;
  408. put('string,pretoprinf,'stringox);
  409. symbolic procedure lambdox u;
  410. begin
  411. omark '(m u);
  412. curmark := curmark+1;
  413. procox1('lambda,car u,cadr u)
  414. end;
  415. put('lambda,pretoprinf,'lambdox);
  416. symbolic procedure eachox u;
  417. <<prin2ox "for each ";
  418. while cdr u do <<mprino car u; prin2ox " "; u := cdr u>>;
  419. mprino car u>>;
  420. put('foreach,pretoprinf,'eachox);
  421. symbolic procedure forox u;
  422. begin
  423. curmark := curmark+1;
  424. omark '(m u);
  425. prin2ox "for ";
  426. mprino car u;
  427. prin2ox " := ";
  428. mprino caadr u;
  429. if cadr cadr u neq 1
  430. then <<prin2ox " step "; mprino cadr cadr u; prin2ox " until ">>
  431. else prin2ox ":";
  432. mprino caddr cadr u;
  433. prin2ox " ";
  434. mprino caddr u;
  435. prin2ox " ";
  436. omark list(curmark,3);
  437. mprino cadddr u;
  438. omark '(m d);
  439. curmark := curmark - 1
  440. end;
  441. put('for,pretoprinf,'forox);
  442. symbolic procedure forallox u;
  443. begin
  444. curmark := curmark+1;
  445. omark '(m u);
  446. prin2ox "for all ";
  447. inprino('!*comma!*,list(0,0),car u);
  448. if cadr u
  449. then <<omark list(curmark,3);
  450. prin2ox " such that ";
  451. mprino cadr u>>;
  452. prin2ox " ";
  453. omark list(curmark,3);
  454. mprino caddr u;
  455. omark '(m d);
  456. curmark := curmark - 1
  457. end;
  458. put('forall,pretoprinf,'forallox);
  459. comment Support for printing algebraic mode code;
  460. put('aeval!*,pretoprinf,'aevalox);
  461. put('aeval,pretoprinf,'aevalox);
  462. put('revalx,pretoprinf,'aevalox); % FJW.
  463. symbolic procedure aevalox(u);
  464. mprino aevalox1 car u;
  465. symbolic procedure aevalox1 u;
  466. % unquote and listify.
  467. if eqcar(u,'quote) then cadr u else
  468. if eqcar(u,'list) then
  469. for each q in u collect aevalox1 q else u;
  470. symbolic procedure minuspox u;
  471. if eqcar(car u,'difference) then
  472. mprino('lessp.cdar u) else mprino('lessp.car u.'(0));
  473. put('minusp,pretoprinf,'minuspox);
  474. put('aminusp!:,pretoprinf,'minuspox);
  475. put('evalequal,pretoprinf,function (lambda u;mprino('equal.u)));
  476. put('evalgreaterp,pretoprinf,function (lambda u;mprino('greaterp.u)));
  477. put('evalgeq,pretoprinf,function (lambda u;mprino('geq.u)));
  478. put('evallessp,pretoprinf,function (lambda u;mprino('lessp.u)));
  479. put('evalleq,pretoprinf,function (lambda u;mprino('leq.u)));
  480. put('evalneq,pretoprinf,function (lambda u;mprino('neq.u)));
  481. put('!:dn!:,pretoprinf,function (lambda u;
  482. mprino(float car u*expt(float 10,cdr u))));
  483. put('!:rd!:,pretoprinf,function (lambda u;
  484. mprino(if atom u then u else
  485. float car u*expt(float 2,cdr u))));
  486. put('plus2,pretoprinf,function(lambda u;mprino('plus.u)));
  487. comment Declarations needed by old parser;
  488. if null get('!*semicol!*,'op)
  489. then <<put('!*semicol!*,'op,'((-1 0)));
  490. put('!*comma!*,'op,'((5 6)))>>;
  491. % Code for printing active comments.
  492. symbolic procedure princom u;
  493. % Print an active comment.
  494. begin scalar w,x,y,z; integer n;
  495. x := explode2 u;
  496. % Process first line.
  497. while car x eq '! do x := cdr x;
  498. while x and car x neq !$eol!$ do <<y := car x . y; x := cdr x>>;
  499. while y and car y eq '! do y := cdr y;
  500. w := reversip!* y; % Header line.
  501. % Process remaining lines.
  502. while x and (x := cdr x) do
  503. <<y := nil;
  504. n := 0;
  505. while car x eq '! do <<x := cdr x; n := n+1>>;
  506. while x and car x neq !$eol!$ do <<y := car x . y; x:= cdr x>>;
  507. while y and car y eq '! do y := cdr y;
  508. z := (n . reversip!* y) . z>>;
  509. % Find line with least blanks.
  510. y := z;
  511. if y
  512. then <<n := caar y; while (y := cdr y) do n := min(n,caar y)>>;
  513. while z do <<y := addblanks(cdar z,caar z - n) . y; z := cdr z>>;
  514. % Now merge lines where possible.
  515. while y do
  516. <<z := car y;
  517. if not(car z eq '! ) and not(car w eq '! )
  518. then <<z := '! . z; w := nconc!*(w,z)>>
  519. else <<x := w . x; w := z>>;
  520. y := cdr y>>;
  521. x := w . x;
  522. % Final processing.
  523. x := reversip!* x;
  524. while x do <<addmarks car x; x := cdr x;
  525. if x then omark list(curmark,3)>>
  526. end;
  527. symbolic procedure addblanks(u,n);
  528. if n=0 then u else '! . addblanks(u,n - 1);
  529. symbolic procedure addmarks u;
  530. begin scalar bool,x;
  531. while u do
  532. <<if car u eq '! then (if null bool
  533. then <<bool := t; x := {'M,'L} . x>>)
  534. else bool := nil;
  535. x := car u . x; u := cdr u>>;
  536. rplacd(buffp,reversip!* x);
  537. while cdr buffp do buffp := cdr buffp
  538. end;
  539. comment RPRINT MODULE, Part 2;
  540. fluid '(orig curpos);
  541. symbolic procedure prinos u;
  542. begin integer curpos;
  543. scalar !*lower,orig;
  544. orig := list posn();
  545. curpos := car orig;
  546. prinoy(u,0);
  547. terpri0x()
  548. end;
  549. symbolic procedure prinoy(u,n);
  550. begin scalar x;
  551. if car(x := spaceleft(u,n)) then return prinom(u,n)
  552. else if null cdr x then return if car orig<10 then prinom(u,n)
  553. else <<orig := 9 . cdr orig;
  554. terpri0x();
  555. spaces20x(curpos := 9+cadar u);
  556. prinoy(u,n)>>
  557. else begin
  558. a: u := prinoy(u,n+1);
  559. if null cdr u or caar u<=n then return;
  560. terpri0x();
  561. spaces20x(curpos := car orig+cadar u);
  562. go to a end;
  563. return u
  564. end;
  565. symbolic procedure spaceleft(u,mark);
  566. %U is an expanded buffer of characters delimited by non-atom marks
  567. %of the form: '(M ...) or '(INT INT))
  568. %MARK is an integer;
  569. begin integer n; scalar flg,mflg;
  570. n := rmar - curpos;
  571. u := cdr u; %move over the first mark;
  572. while u and not flg and n>=0 do
  573. <<if atom car u then n := n - 1
  574. else if caar u eq 'm then nil
  575. else if mark>=caar u then <<flg := t; u := nil . u>>
  576. else mflg := t;
  577. u := cdr u>>;
  578. return ((n>=0) . mflg)
  579. end;
  580. symbolic procedure prinom(u,mark);
  581. begin integer n; scalar flg,x;
  582. n := curpos;
  583. u := cdr u;
  584. while u and not flg do
  585. <<if atom car u then <<x := prin20x car u; n := n+1>>
  586. else if caar u eq 'm
  587. then if cadar u eq 'u then orig := n . orig
  588. else if cadar u eq 'l
  589. then (if chars2 cdr u > (rmar - posn())
  590. then <<terpri0x(); spaces20x(curmark+5)>>)
  591. else orig := cdr orig
  592. % Check for long thin lists.
  593. else if mark>=caar u
  594. and not(x memq '(!,) % '(!, ! )
  595. and rmar - n - 6>charspace(u,x,mark))
  596. then <<flg := t; u := nil . u>>;
  597. u := cdr u>>;
  598. curpos := n;
  599. if mark=0 and cdr u
  600. then <<terpri0x();
  601. % terpri0x();
  602. orig := list 0; curpos := 0; prinoy(u,mark)>>;
  603. %must be a top level constant;
  604. return u
  605. end;
  606. symbolic procedure chars2 u; chars21(u,0);
  607. symbolic procedure chars21(u,n);
  608. if eqcar(car u,'m) then n else chars21(cdr u,n+1);
  609. symbolic procedure charspace(u,char,mark);
  610. % Determines if there is space until the next character CHAR.
  611. begin integer n;
  612. n := 0;
  613. while u do
  614. <<if car u = char then u := list nil
  615. else if atom car u then n := n+1
  616. else if car u='(m u) then <<n := 1000; u := list nil>>
  617. else if numberp caar u and caar u<mark then u := list nil;
  618. u := cdr u>>;
  619. return n
  620. end;
  621. symbolic procedure spaces20x n;
  622. %for i := 1:n do prin20x '! ;
  623. while n>0 do <<prin20x '! ; n := n - 1>>;
  624. symbolic procedure prin2rox u;
  625. begin integer m,n; scalar x,y;
  626. m := rmar - 12;
  627. n := rmar - 1;
  628. while u do
  629. if car u eq '!"
  630. then <<if not stringspace(cdr u,n - !*n)
  631. then <<terpri0x(); !*n := 0>>
  632. else nil;
  633. prin20x '!";
  634. u := cdr u;
  635. while not(car u eq '!") do
  636. <<prin20x car u; u := cdr u; !*n := !*n+1>>;
  637. prin20x '!";
  638. u := cdr u;
  639. !*n := !*n+2;
  640. x := y := nil>>
  641. else if atom car u and not(car u eq '! and (!*n=0 or null x
  642. or cdr u and breakp cadr u or breakp x and not(y eq '!!)))
  643. then <<y := x; prin20x(x := car u); !*n := !*n+1;
  644. u := cdr u;
  645. if !*n=n or !*n>m and not breakp car u and nospace(u,n - !*n)
  646. then <<terpri0x(); x := y := nil>> else nil>>
  647. else u := cdr u
  648. end;
  649. symbolic procedure nospace(u,n);
  650. if n<1 then t
  651. else if null u then nil
  652. else if not atom car u then nospace(cdr u,n)
  653. else if not(car u eq '!!) and (cadr u eq '! or breakp cadr u)
  654. then nil
  655. else nospace(cdr u,n - 1);
  656. symbolic procedure breakp u;
  657. u member '(!< !> !; !: != !) !+ !- !, !' !");
  658. symbolic procedure stringspace(u,n);
  659. if n<1 then nil else car u eq '!" or stringspace(cdr u,n - 1);
  660. comment Some interfaces needed;
  661. symbolic procedure prin20x u;
  662. if rprifn!* then apply1(rprifn!*,u) else prin2 u;
  663. symbolic procedure terpri0x;
  664. if rterfn!* then lispeval {rterfn!*} else terpri();
  665. endmodule;
  666. end;