intrfc.red 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. module intrfc; %% GENTRAN Parsing Routines & Control Functions %%
  2. %% Author: Barbara L. Gates %%
  3. %% December 1986 %%
  4. % Entry Points:
  5. % DeclareStat, GENDECS, GenInStat (GentranIn), GenOutStat
  6. % (GentranOutPush), GenPopStat (GentranPop), GenPushStat, GenShutStat
  7. % (GentranShut), GenStat (Gentran), (GENTRANPAIRS),
  8. % LiteralStat, SYM!-GENTRAN, SYM!-GENTRANIN, SYM!-GENTRANOUT,
  9. % SYM!-GENTRANSHUT,
  10. % SYM!-GENTRANPUSH, SYM!-GENTRANPOP
  11. fluid '(!*getdecs);
  12. % GENTRAN Commands %
  13. put('gentran, 'stat, 'genstat )$
  14. put('gentranin, 'stat, 'geninstat )$
  15. put('gentranout, 'stat, 'genoutstat )$
  16. put('gentranshut, 'stat, 'genshutstat)$
  17. put('gentranpush, 'stat, 'genpushstat)$
  18. put('gentranpop, 'stat, 'genpopstat )$
  19. % Form Analysis Function %
  20. put('gentran, 'formfn, 'formgentran)$
  21. put('gentranin, 'formfn, 'formgentran)$
  22. put('gentranoutpush, 'formfn, 'formgentran)$
  23. put('gentranshut, 'formfn, 'formgentran)$
  24. put('gentranpop, 'formfn, 'formgentran)$
  25. % GENTRAN Functions %
  26. put('declare, 'stat, 'declarestat)$
  27. put('literal, 'stat, 'literalstat)$
  28. % GENTRAN Operators %
  29. newtok '((!: !: !=) lsetq )$ infix ::= $
  30. newtok '((!: != !:) rsetq )$ infix :=: $
  31. newtok '((!: !: != !:) lrsetq)$ infix ::=:$
  32. % User-Accessible Primitive Function %
  33. operator gendecs$
  34. % GENTRAN Mode Switches %
  35. fluid '(!*gendecs)$
  36. !*gendecs := t$
  37. put('gendecs, 'simpfg, '((nil) (t (gendecs nil))))$
  38. switch gendecs$
  39. %See procedure gendecs:
  40. fluid '(!*keepdecs)$
  41. !*keepdecs := nil$
  42. switch keepdecs$
  43. % GENTRAN Flags %
  44. fluid '(!*gentranopt !*gentranseg !*period);
  45. !*gentranseg := t$
  46. switch gentranseg$
  47. % User-Accessible Global Variable %
  48. global '(gentranlang!*)$
  49. share gentranlang!*$
  50. gentranlang!* := 'fortran$
  51. % GENTRAN Global Variable %
  52. global '(!*term!* !*stdin!* !*stdout!* !*instk!* !*currin!* !*outstk!*
  53. !*currout!* !*outchanl!*)$
  54. !*term!* := (t . nil)$ %terminal filepair
  55. !*stdin!* := !*term!*$ %standard input filepair
  56. !*stdout!* := !*term!*$ %standard output filepair
  57. !*instk!* := list !*stdin!*$ %template file stack
  58. !*currin!* := car !*instk!*$ %current input filepair
  59. !*outstk!* := list !*stdout!*$ %output file stack
  60. !*currout!* := car !*outstk!*$ %current output filepair
  61. !*outchanl!* := list cdr !*currout!*$ %current output channel list
  62. global '(!*do!* !*for!*)$
  63. off quotenewnam$
  64. !*do!* := 'do$
  65. !*for!* := 'for$
  66. on quotenewnam$
  67. global '(!*lispstmtops!*);
  68. !*lispstmtops!* := !*for!* . !*lispstmtops!*; % added by R. Liska to
  69. % handle long FOR loops.
  70. % REDUCE Variables %
  71. global '(cursym!* !*vars!*)$
  72. fluid '(!*mode)$
  73. %% %%
  74. %% PARSING ROUTINES %%
  75. %% %%
  76. %% GENTRAN Command Parsers %%
  77. procedure genstat;
  78. % %
  79. % GENTRAN %
  80. % stmt %
  81. % [OUT f1,f2,...,fn]; %
  82. % %
  83. begin
  84. scalar stmt;
  85. flag('(out), 'delim);
  86. stmt := xread t;
  87. remflag('(out), 'delim);
  88. if cursym!* eq 'out then
  89. return list('gentran, stmt, readfargs())
  90. else if endofstmtp() then
  91. return list('gentran, stmt, nil)
  92. else
  93. gentranerr('e, nil, "INVALID SYNTAX", nil)
  94. end$
  95. procedure geninstat;
  96. % %
  97. % GENTRANIN %
  98. % f1,f2,...,fm %
  99. % [OUT f1,f2,...,fn]; %
  100. % %
  101. begin
  102. scalar f1, f2;
  103. flag('(out), 'delim);
  104. f1 := xread nil;
  105. if atom f1 then f1 := list f1 else f1 := cdr f1;
  106. remflag('(out), 'delim);
  107. if cursym!* eq 'out then
  108. f2 := readfargs();
  109. return list('gentranin, f1, f2)
  110. end$
  111. procedure genoutstat;
  112. % %
  113. % GENTRANOUT f1,f2,...,fn; %
  114. % %
  115. list('gentranoutpush, readfargs())$
  116. procedure genshutstat;
  117. % %
  118. % GENTRANSHUT f1,f2,...,fn; %
  119. % %
  120. list('gentranshut, readfargs())$
  121. procedure genpushstat;
  122. % %
  123. % GENTRANPUSH f1,f2,...,fn; %
  124. % %
  125. list('gentranoutpush, readfargs())$
  126. procedure genpopstat;
  127. % %
  128. % GENTRANPOP f1,f2,...,fn; %
  129. % %
  130. list('gentranpop, readfargs())$
  131. %% GENTRAN Function Parsers %%
  132. newtok '((!: !:) range);
  133. % Used for declarations with lower and upper bounds;
  134. procedure declarestat;
  135. % %
  136. % DECLARE v1,v2,...,vn : type; %
  137. % %
  138. % DECLARE %
  139. % << %
  140. % v1,v2,...,vn1 : type1; %
  141. % v1,v2,...,vn2 : type2; %
  142. % . %
  143. % . %
  144. % v1,v2,...,vnn : typen %
  145. % >>; %
  146. % %
  147. begin
  148. scalar res, varlst, type;
  149. scan();
  150. put('range,'infix,4);
  151. put('range,'op,'((4 4)));
  152. if cursym!* eq '!*lsqbkt!* then
  153. <<
  154. scan();
  155. while cursym!* neq '!*rsqbkt!* do
  156. <<
  157. varlst := list xread1 'for;
  158. while cursym!* neq '!*colon!* do
  159. varlst := append(varlst, list xread 'for);
  160. type := declarestat1();
  161. res := append(res, list(type . varlst));
  162. if cursym!* eq '!*semicol!* then scan()
  163. >>;
  164. scan()
  165. >>
  166. else
  167. <<
  168. varlst := list xread1 'for;
  169. while cursym!* neq '!*colon!* do
  170. varlst := append(varlst, list xread 'for);
  171. type := declarestat1();
  172. res := list (type . varlst);
  173. >>;
  174. if not endofstmtp() then
  175. gentranerr('e, nil, "INVALID SYNTAX", nil);
  176. remprop('range,'infix);
  177. remprop('range,'op);
  178. return ('declare . res)
  179. end$
  180. procedure declarestat1;
  181. begin
  182. scalar res;
  183. scan();
  184. if endofstmtp() then
  185. return nil;
  186. if cursym!* eq 'implicit then
  187. <<
  188. scan();
  189. res := intern compress append(explode 'implicit! , explode cursym!*)
  190. >>
  191. else
  192. res := cursym!*;
  193. scan();
  194. if cursym!* eq 'times then
  195. <<
  196. scan();
  197. if numberp cursym!* then
  198. <<
  199. res := intern compress append(append(explode res, explode '!*),
  200. explode cursym!*);
  201. scan()
  202. >>
  203. else
  204. gentranerr('e, nil, "INVALID SYNTAX", nil)
  205. >>;
  206. return res
  207. end$
  208. procedure literalstat;
  209. % %
  210. % LITERAL arg1,arg2,...,argn; %
  211. % %
  212. begin
  213. scalar res;
  214. repeat
  215. res := append(res, list xread t)
  216. until endofstmtp();
  217. if atom res then
  218. return list('literal, res)
  219. else if car res eq '!*comma!* then
  220. return rplaca(res, 'literal)
  221. else
  222. return('literal . res)
  223. end$
  224. %% %%
  225. %% Symbolic Mode Functions %%
  226. %% %%
  227. procedure sym!-gentran form;
  228. lispeval formgentran(list('gentran, form, nil), !*vars!*, !*mode)$
  229. procedure sym!-gentranin flist;
  230. if flist then
  231. lispeval formgentran(list('gentranin,
  232. (if atom flist then list flist else flist),
  233. nil),
  234. !*vars!*, !*mode)$
  235. procedure sym!-gentranout flist;
  236. lispeval formgentran(list('gentranoutpush,
  237. if atom flist then list flist else flist),
  238. !*vars!*, !*mode)$
  239. procedure sym!-gentranshut flist;
  240. lispeval formgentran(list('gentranshut,
  241. if atom flist then list flist else flist),
  242. !*vars!*, !*mode)$
  243. procedure sym!-gentranpush flist;
  244. lispeval formgentran(list('gentranoutpush,
  245. if atom flist then list flist else flist),
  246. !*vars!*, !*mode)$
  247. procedure sym!-gentranpop flist;
  248. lispeval formgentran(list('gentranpop,
  249. if atom flist then list flist else flist),
  250. !*vars!*, !*mode)$
  251. %% %%
  252. %% Form Analysis Functions %%
  253. %% %%
  254. procedure formgentran(u, vars, mode);
  255. (car u) . foreach arg in cdr u collect formgentran1(arg, vars, mode)$
  256. symbolic procedure formgentran1(u, vars, mode);
  257. if pairp u and car u eq '!:dn!: then
  258. mkquote <<precmsg length explode abs car(u := cdr u);
  259. decimal2internal(car u,cdr u)>>
  260. else if pairp u and car u eq '!:rd!: then mkquote u
  261. else if pairp u and not listp u then
  262. if !*getdecs
  263. then formgentran1(list ('declare,list(cdr u,car u)),vars,mode)
  264. % Amended mcd 13/11/87 to allow local definitions.
  265. else gentranerr('e,u,
  266. "Scalar definitions cannot be translated",nil)
  267. else if atom u then
  268. mkquote u
  269. else if car u eq 'eval then
  270. if mode eq 'algebraic then
  271. list('aeval, form1(cadr u, vars, mode))
  272. else
  273. form1(cadr u, vars, mode)
  274. else if car u memq '(lsetq rsetq lrsetq) then
  275. % (LSETQ (var s1 s2 ... sn) exp) %
  276. % -> (SETQ (var (EVAL s1) (EVAL s2) ... (EVAL sn)) exp) %
  277. % (RSETQ var exp) %
  278. % -> (SETQ var (EVAL exp)) %
  279. % (LRSETQ (var s1 s2 ... sn) exp) %
  280. % -> (SETQ (var (EVAL s1) (EVAL s2) ... (EVAL sn)) (EVAL exp)) %
  281. begin
  282. scalar op, lhs, rhs;
  283. op := car u;
  284. lhs := cadr u;
  285. rhs := caddr u;
  286. if op memq '(lsetq lrsetq) and listp lhs then
  287. lhs := car lhs . foreach s in cdr lhs collect list('eval, s);
  288. if op memq '(rsetq lrsetq) then
  289. rhs := list('eval, rhs);
  290. return formgentran1(list('setq, lhs, rhs), vars, mode)
  291. end
  292. else
  293. 'list . foreach elt in u
  294. collect formgentran1(elt, vars, mode)$
  295. %% %%
  296. %% Control Functions %%
  297. %% %%
  298. %% Command Control Functions %%
  299. symbolic procedure gentran(forms, flist);
  300. begin scalar !:print!-prec!: ; % Gentran ignores print_precision
  301. if flist then
  302. lispeval list('gentranoutpush, list('quote, flist));
  303. forms := preproc list forms;
  304. if gentranparse(forms) then
  305. <<
  306. forms := lispcode forms;
  307. if smemq('differentiate,forms) then
  308. <<load!-package 'adiff; forms := adiff!-eval forms>>;
  309. if !*gentranopt then forms := opt forms;
  310. if !*gentranseg then forms := seg forms;
  311. apply1(get(gentranlang!*,'formatter) or get('fortran,'formatter),
  312. apply1(get(gentranlang!*,'codegen) or get('fortran,'codegen),
  313. forms))
  314. >>;
  315. if flist then
  316. <<
  317. flist := car !*currout!* or ('list . cdr !*currout!*);
  318. lispeval '(gentranpop '(nil));
  319. return flist
  320. >>
  321. else
  322. return car !*currout!* or ('list . cdr !*currout!*)
  323. end$
  324. procedure gentranin(inlist, outlist);
  325. begin
  326. scalar ich;
  327. foreach f in inlist do
  328. if pairp f then
  329. gentranerr('e, f, "Wrong Type of Arg", nil)
  330. else if not !*filep!* f and f neq car !*stdin!* then
  331. gentranerr('e, f, "Nonexistent Input File", nil);
  332. if outlist then
  333. lispeval list('gentranoutpush, mkquote outlist);
  334. ich := rds nil;
  335. foreach f in inlist do
  336. <<
  337. if f = car !*stdin!* then
  338. pushinputstack !*stdin!*
  339. else if retrieveinputfilepair f then
  340. gentranerr('e, f, "Template File Already Open for Input", nil)
  341. else
  342. pushinputstack makeinputfilepair f;
  343. rds cdr !*currin!*;
  344. lispapply(get(gentranlang!*,'proctem) or get('fortran,'proctem),
  345. nil);
  346. % if gentranlang!* eq 'ratfor then
  347. % procrattem()
  348. % else if gentranlang!* eq 'c then
  349. % procctem()
  350. % else
  351. % procforttem();
  352. rds ich;
  353. popinputstack()
  354. >>;
  355. if outlist then
  356. <<
  357. outlist := car !*currout!* or ('list . cdr !*currout!*);
  358. lispeval '(gentranpop '(nil));
  359. return outlist
  360. >>
  361. else
  362. return car !*currout!* or ('list . cdr !*currout!*)
  363. end$
  364. procedure gentranoutpush flist;
  365. <<
  366. if onep length (flist := fargstonames(flist, t)) then
  367. flist := car flist;
  368. pushoutputstack (retrieveoutputfilepair flist
  369. or makeoutputfilepair flist);
  370. car !*currout!* or ('list . cdr !*currout!*)
  371. >>$
  372. procedure gentranshut flist;
  373. % close, delete, [output to T] %
  374. begin
  375. scalar trm;
  376. flist := fargstonames(flist, nil);
  377. trm := if onep length flist then (car flist = car !*currout!*)
  378. else if car !*currout!*
  379. then (if car !*currout!* member flist then t)
  380. else lispeval('and . foreach f in cdr !*currout!*
  381. collect (if f member flist then t));
  382. deletefromoutputstack flist;
  383. if trm and !*currout!* neq !*stdout!* then
  384. pushoutputstack !*stdout!*;
  385. return car !*currout!* or ('list . cdr !*currout!*)
  386. end$
  387. procedure gentranpop flist;
  388. <<
  389. if 'all!* member flist then
  390. while !*outstk!* neq list !*stdout!* do
  391. lispeval '(gentranpop '(nil))
  392. else
  393. <<
  394. flist := fargstonames(flist,nil);
  395. if onep length flist then
  396. flist := car flist;
  397. popoutputstack flist
  398. >>;
  399. car !*currout!* or ('list . cdr !*currout!*)
  400. >>$
  401. %% Mode Switch Control Function %%
  402. procedure gendecs name;
  403. % Hacked 15/11/88 to make it actually tidy up symbol table properly.
  404. % KEEPDECS also added. mcd.
  405. %%%%%%%%%%%%%%%%%%%%%%%%
  406. % %
  407. % ON/OFF GENDECS; %
  408. % %
  409. % GENDECS subprogname; %
  410. % %
  411. %%%%%%%%%%%%%%%%%%%%%%%%
  412. <<
  413. if name equal 0 then name := nil;
  414. apply1(get(gentranlang!*,'formatter) or get('fortran,'formatter),
  415. apply1(get(gentranlang!*,'gendecs) or get('fortran,'gendecs),
  416. symtabget(name, '!*decs!*)));
  417. % if gentranlang!* eq 'ratfor then
  418. % formatrat ratdecs symtabget(name, '!*decs!*)
  419. % else if gentranlang!* eq 'c then
  420. % formatc cdecs symtabget(name, '!*decs!*)
  421. % else
  422. % formatfort fortdecs symtabget(name, '!*decs!*);
  423. % Sometimes it would be handy to know just what we've generated.
  424. % If the switch KEEPDECS is on (usually off) this is done.
  425. if null !*keepdecs then
  426. <<
  427. symtabrem(name, '!*decs!*);
  428. symtabrem(name, '!*type!*);
  429. >>;
  430. symtabrem(name, nil);
  431. >>$
  432. %% Misc. Control Functions %%
  433. procedure gentranpairs prs;
  434. % %
  435. % GENTRANPAIRS dottedpairlist; %
  436. % %
  437. begin
  438. scalar formatfn,assignfn;
  439. formatfn:=get(gentranlang!*,'formatter) or get('fortran,'formatter);
  440. assignfn:=get(gentranlang!*,'assigner) or get('fortran,'assigner);
  441. return
  442. for each pr in prs do
  443. apply1(formatfn,apply2(assignfn,lispcodeexp(car pr, !*period),
  444. lispcodeexp(cdr pr, !*period)))
  445. end;
  446. %procedure gentranpairs prs;
  447. %% %
  448. %% GENTRANPAIRS dottedpairlist; %
  449. %% %
  450. %if gentranlang!* eq 'ratfor then
  451. % for each pr in prs do
  452. % formatrat mkfratassign(lispcodeexp(car pr, !*period),
  453. % lispcodeexp(cdr pr, !*period))
  454. %else if gentranlang!* eq 'c then
  455. % for each pr in prs do
  456. % formatc mkfcassign(lispcodeexp(car pr, !*period),
  457. % lispcodeexp(cdr pr, !*period))
  458. %else
  459. % for each pr in prs do
  460. % formatfort mkffortassign(lispcodeexp(car pr, !*period),
  461. % lispcodeexp(cdr pr, !*period))$
  462. %% %%
  463. %% Input & Output File Stack Manipulation Functions %%
  464. %% %%
  465. %% Input Stack Manipulation Functions %%
  466. procedure makeinputfilepair fname;
  467. (fname . open(mkfil fname, 'input))$
  468. procedure retrieveinputfilepair fname;
  469. retrievefilepair(fname, !*instk!*)$
  470. procedure pushinputstack pr;
  471. <<
  472. !*instk!* := pr . !*instk!*;
  473. !*currin!* := car !*instk!*;
  474. !*instk!*
  475. >>$
  476. procedure popinputstack;
  477. begin scalar x;
  478. x := !*currin!*;
  479. if cdr !*currin!* then close cdr !*currin!*;
  480. !*instk!* := cdr !*instk!* or list !*stdin!*;
  481. !*currin!* := car !*instk!*;
  482. return x
  483. end$
  484. %% Output File Stack Manipulation Functions %%
  485. procedure makeoutputfilepair f;
  486. if atom f then
  487. (f . open(mkfil f, 'output))
  488. else
  489. aconc((nil . f) .
  490. foreach fn in f
  491. conc if not retrieveoutputfilepair fn
  492. then list makeoutputfilepair fn,
  493. (nil . nil))$
  494. procedure retrieveoutputfilepair f;
  495. if atom f
  496. then retrievefilepair(f, !*outstk!*)
  497. else retrievepfilepair(f, !*outstk!*)$
  498. procedure pushoutputstack pr;
  499. <<
  500. !*outstk!* := if atom cdr pr
  501. then (pr . !*outstk!*)
  502. else append(pr, !*outstk!*);
  503. !*currout!* := car !*outstk!*;
  504. !*outchanl!* := if car !*currout!*
  505. then list cdr !*currout!*
  506. else foreach f in cdr !*currout!*
  507. collect cdr retrieveoutputfilepair f;
  508. !*outstk!*
  509. >>$
  510. procedure popoutputstack f;
  511. % [close], remove top-most exact occurrence, reset vars %
  512. begin
  513. scalar pr, s;
  514. if atom f then
  515. <<
  516. pr := retrieveoutputfilepair f;
  517. while !*outstk!* and car !*outstk!* neq pr do
  518. if caar !*outstk!* then
  519. <<s := aconc(s, car !*outstk!*); !*outstk!* := cdr !*outstk!*>>
  520. else
  521. <<
  522. while car !*outstk!* neq (nil . nil) do
  523. << s := aconc(s, car !*outstk!*);
  524. !*outstk!* := cdr !*outstk!* >>;
  525. s := aconc(s, car !*outstk!*);
  526. !*outstk!* := cdr !*outstk!*
  527. >>;
  528. if !*outstk!* then s := append(s, cdr !*outstk!*);
  529. !*outstk!* := s;
  530. if not retrieveoutputfilepair f then close cdr pr
  531. >>
  532. else
  533. <<
  534. pr := foreach fn in f collect retrieveoutputfilepair fn;
  535. while !*outstk!* and not filelistequivp(cdar !*outstk!*, f) do
  536. if caar !*outstk!* then
  537. << s := aconc(s, car !*outstk!*);
  538. !*outstk!* := cdr !*outstk!* >>
  539. else
  540. <<
  541. while car !*outstk!* neq (nil . nil) do
  542. << s := aconc(s, car !*outstk!*);
  543. !*outstk!* := cdr !*outstk!* >>;
  544. s := aconc(s, car !*outstk!*);
  545. !*outstk!* := cdr !*outstk!*
  546. >>;
  547. if !*outstk!* then
  548. <<
  549. while car !*outstk!* neq (nil . nil) do
  550. !*outstk!* := cdr !*outstk!*;
  551. s := append(s, cdr !*outstk!*)
  552. >>;
  553. !*outstk!* := s;
  554. foreach fn in f do pr := delete(retrieveoutputfilepair fn, pr);
  555. foreach p in pr do close cdr p
  556. >>;
  557. !*outstk!* := !*outstk!* or list !*stdout!*;
  558. !*currout!* := car !*outstk!*;
  559. !*outchanl!* := if car !*currout!*
  560. then list cdr !*currout!*
  561. else foreach fn in cdr !*currout!*
  562. collect cdr retrieveoutputfilepair fn;
  563. return f
  564. end$
  565. procedure deletefromoutputstack f;
  566. begin
  567. scalar s, pr;
  568. if atom f then
  569. <<
  570. pr := retrieveoutputfilepair f;
  571. while retrieveoutputfilepair f do
  572. !*outstk!* := delete(pr, !*outstk!*);
  573. close cdr pr;
  574. foreach pr in !*outstk!* do
  575. if listp cdr pr and pairp cdr pr and f member cdr pr then
  576. rplacd(pr, delete(f, cdr pr)) % Fixed 26-2-88 mcd
  577. >>
  578. else
  579. <<
  580. foreach fn in f do
  581. deletefromoutputstack fn;
  582. foreach fn in f do
  583. foreach pr in !*outstk!* do
  584. if pairp cdr pr and fn member cdr pr then
  585. rplacd(pr, delete(fn, cdr pr))
  586. >>;
  587. while !*outstk!* do
  588. if caar !*outstk!* and caar !*outstk!* neq 't then
  589. <<
  590. s := aconc(s, car !*outstk!*);
  591. !*outstk!* := cdr !*outstk!*
  592. >>
  593. else if cdar !*outstk!* and cdar !*outstk!* neq '(t) then
  594. <<
  595. while car !*outstk!* neq (nil . nil) do
  596. <<
  597. s := aconc(s, car !*outstk!*);
  598. !*outstk!* := cdr !*outstk!*
  599. >>;
  600. s := aconc(s, car !*outstk!*);
  601. !*outstk!* := cdr !*outstk!*
  602. >>
  603. else
  604. if cdr !*outstk!* then !*outstk!* := cddr !*outstk!*
  605. else !*outstk!*:=nil;
  606. !*outstk!* := s or list !*stdout!*;
  607. !*currout!* := car !*outstk!*;
  608. !*outchanl!* := if car !*currout!*
  609. then list cdr !*currout!*
  610. else foreach fn in cdr !*currout!*
  611. collect cdr retrieveoutputfilepair fn;
  612. return f
  613. end$
  614. procedure retrievefilepair(fname, stk);
  615. if null stk then
  616. nil
  617. else if caar stk and mkfil fname = mkfil caar stk then
  618. car stk
  619. else
  620. retrievefilepair(fname, cdr stk)$
  621. procedure retrievepfilepair(f, stk);
  622. if null stk then
  623. nil
  624. else if null caar stk and filelistequivp(f, cdar stk) then
  625. list(car stk, (nil . nil))
  626. else
  627. retrievepfilepair(f, cdr stk)$
  628. procedure filelistequivp(f1, f2);
  629. if pairp f1 and pairp f2 then
  630. <<
  631. f1 := foreach f in f1 collect mkfil f;
  632. f2 := foreach f in f2 collect mkfil f;
  633. while (car f1 member f2) do
  634. <<
  635. f2 := delete(car f1, f2);
  636. f1 := cdr f1
  637. >>;
  638. null f1 and null f2
  639. >>$
  640. %%
  641. procedure !*filep!* f;
  642. not errorp errorset(list('close,
  643. list('open,list('mkfil,mkquote f),''input)),
  644. nil,nil)$
  645. %% %%
  646. %% Scanning & Arg-Conversion Functions %%
  647. %% %%
  648. procedure endofstmtp;
  649. if cursym!* member '(!*semicol!* !*rsqbkt!* end) then t$
  650. procedure fargstonames(fargs, openp);
  651. begin
  652. scalar names;
  653. fargs :=
  654. for each a in fargs conc
  655. if a memq '(nil 0) then
  656. if car !*currout!* then
  657. list car !*currout!*
  658. else
  659. cdr !*currout!*
  660. else if a eq 't then
  661. list car !*stdout!*
  662. else if a eq 'all!* then
  663. for each fp in !*outstk!* conc
  664. (if car fp and not(fp equal !*stdout!*) then list car fp)
  665. else if atom a then
  666. if openp then
  667. <<
  668. if null getd 'bpsmove and
  669. % That essentially disables the test on IBM SLISP
  670. % where it causes chaos with the PDS management.
  671. !*filep!* a and null assoc(a, !*outstk!*) then
  672. gentranerr('w, a, "OUTPUT FILE ALREADY EXISTS",
  673. "CONTINUE?");
  674. list a
  675. >>
  676. else
  677. if retrieveoutputfilepair a then
  678. list a
  679. else
  680. gentranerr('w, a, "File not Open for Output", nil)
  681. else
  682. gentranerr('e, a, "WRONG TYPE OF ARG", nil);
  683. repeat
  684. if not (car fargs member names) then
  685. names := append(names, list car fargs)
  686. until null (fargs := cdr fargs);
  687. return names
  688. end$
  689. procedure readfargs;
  690. begin
  691. scalar f;
  692. while not endofstmtp() do
  693. f := append(f, list xread t);
  694. return f or list nil
  695. end$
  696. endmodule;
  697. end;