rprint.red 22 KB

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