redlsp.red 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. module redlsp; %% GENTRAN LISP Code Generation Module %%
  2. %% Author: Barbara L. Gates %%
  3. %% December 1986 %%
  4. % Entry Point: LispCode
  5. symbolic$
  6. % GENTRAN Global Variables %
  7. global '(!*lisparithexpops!* !*lisplogexpops!* !*redarithexpops!*
  8. !*redlogexpops!* !*redreswds!* !*redstmtgpops!* !*redstmtops!*)$
  9. !*redarithexpops!*:= '(difference expt minus plus quotient recip times)$
  10. !*redlogexpops!* := '(and equal geq greaterp leq lessp neq not or)$
  11. !*redreswds!*:= '(and rblock cond de difference end equal expt !~for for
  12. geq getel go greaterp leq lessp list minus neq not or
  13. plus plus2 prog progn procedure quotient read recip
  14. repeat return setel setk setq stop times times2
  15. while write)$ %REDUCE reserved words
  16. !*redstmtgpops!* := '(rblock progn)$
  17. !*redstmtops!* := '(cond end !~for for go repeat return setq stop
  18. while write)$
  19. % REDUCE Non-local Variable %
  20. fluid '(!*period);
  21. global '(deftype!*)$
  22. global '(!*do!* !*for!*)$
  23. % Irena variable referenced here.
  24. global '(irena!-constants)$
  25. irena!-constants := nil$
  26. procedure lispcode forms;
  27. for each f in forms collect
  28. if redexpp f then
  29. lispcodeexp(f, !*period)
  30. else if redstmtp f or redstmtgpp f then
  31. lispcodestmt f
  32. else if reddefp f then
  33. lispcodedef f
  34. else if pairp f then
  35. for each e in f collect lispcode e$
  36. symbolic procedure check!-for!-irena!-constants form;
  37. if listp form and memq(car form,!*redarithexpops!*) then
  38. for each u in cdr form do check!-for!-irena!-constants(u)
  39. else if pairp form and car form memq '( !:cr!: !:crn!: !:gi!: )then
  40. repeat
  41. <<
  42. form := cdr form;
  43. check!-for!-irena!-constants(if atom form then form else car form);
  44. >>
  45. until atom form
  46. else if form and atom form then
  47. if memq(form,irena!-constants) then set(get(form,'!*found!-flag),t)$
  48. symbolic procedure lispcodeexp(form, fp);
  49. % (RECIP exp) ==> (QUOTIENT 1.0 exp) %
  50. % (DIFFERENCE exp1 exp2) ==> (PLUS exp1 (MINUS exp2)) %
  51. % integer ==> floating point iff PERIOD flag is ON & %
  52. % not exponent & %
  53. % not subscript & %
  54. % not loop index %
  55. % The above is a little simplistic. We have problems
  56. % With expressions like x**(1/2)
  57. % Now believed fixed. JHD 14.5.88
  58. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  59. %
  60. % mcd 16-11-88. Added code to spot certain variables which irena
  61. % needs to generate values for.
  62. %
  63. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  64. begin
  65. return if numberp form then
  66. if fp then
  67. float form
  68. else
  69. form
  70. % Substitute (EXP 1) for e - mcd 29/4/88 %
  71. else if form eq 'e then
  72. lispcodeexp(list('exp,1.0),fp)
  73. else if atom form or car form memq '( !:rd!: !:cr!: !:crn!: !:gi!: )then
  74. <<
  75. if irena!-constants and form and not stringp form then
  76. check!-for!-irena!-constants form;
  77. form
  78. >>
  79. else if car form eq 'expt then
  80. % Changes (EXPT E X) to (EXP X). mcd 29/4/88 %
  81. if cadr form eq 'e then
  82. lispcodeexp(list('exp,caddr form),fp)
  83. else if caddr form = '(quotient 1 2) then
  84. lispcodeexp(list('sqrt,cadr form),fp)
  85. else if eqcar(caddr form,'!:rd!:) then begin scalar r;
  86. r := realrat caddr form;
  87. return if r = '(1 . 2)
  88. then {'sqrt,lispcodeexp(cadr form, fp)}
  89. else {'expt,lispcodeexp(cadr form, fp),
  90. lispcodeexp({'quotient,car r,cdr r},nil)}
  91. end
  92. else
  93. list('expt,lispcodeexp(cadr form,fp),lispcodeexp(caddr form,nil))
  94. else if car form eq 'quotient then % re-instate periods if necessary
  95. %e.g. in expressions like **(1/3)
  96. list('quotient, lispcodeexp(cadr form, t),
  97. lispcodeexp(caddr form, t))
  98. else if car form eq 'recip then
  99. if !*period then % test this not FP, for same reason as above
  100. list('quotient, 1.0, lispcodeexp(cadr form, fp))
  101. else
  102. list('quotient, 1, lispcodeexp(cadr form, fp))
  103. else if car form eq 'difference then
  104. list('plus, lispcodeexp(cadr form, fp),
  105. list('minus, lispcodeexp(caddr form, fp)))
  106. else if not(car form memq !*lisparithexpops!*) and
  107. not(car form memq !*lisplogexpops!*) then
  108. for each elt in form collect lispcodeexp(elt, nil)
  109. else
  110. for each elt in form collect lispcodeexp(elt, fp)$
  111. end$
  112. procedure lispcodestmt form;
  113. if atom form then
  114. form
  115. else if redassignp form then
  116. lispcodeassign form
  117. else if redreadp form then
  118. lispcoderead form
  119. else if redprintp form then
  120. lispcodeprint form
  121. else if redwhilep form then
  122. lispcodewhile form
  123. else if redrepeatp form then
  124. lispcoderepeat form
  125. else if redforp form then
  126. lispcodefor form
  127. else if redcondp form then
  128. lispcodecond form
  129. else if redreturnp form then
  130. lispcodereturn form
  131. else if redstmtgpp form then
  132. lispcodestmtgp form
  133. else if reddefp form then
  134. lispcodedef form
  135. else if car form eq 'literal then
  136. for each elt in form collect lispcodeexp(elt, nil)
  137. else
  138. for each elt in form collect lispcodeexp(elt, !*period)$
  139. symbolic procedure lispcodeassign form;
  140. % Modified mcd 27/11/87 to prevent coercing things already declared as
  141. % integers to reals when the PERIOD flag is on.
  142. %
  143. % (SETQ var (MAT lst lst')) --> (PROGN (SETQ (var 1 1) exp11) %
  144. % (SETQ (var 1 2) exp12) %
  145. % . %
  146. % . %
  147. % (SETQ (var m n) expmn)) %
  148. if eqcar( caddr form, 'mat) then
  149. begin
  150. scalar name, r, c, relts, result,ftype;
  151. name := cadr form;
  152. form := caddr form;
  153. r := c := 1;
  154. ftype := symtabget(nil,name);
  155. if null ftype then ftype := !*period else
  156. << ftype := cadr ftype;
  157. ftype := if ftype equal 'integer or
  158. (ftype equal 'scalar and deftype!* equal 'integer) then nil
  159. else !*period;
  160. >>;
  161. while form := cdr form do
  162. <<
  163. relts := car form;
  164. repeat
  165. <<
  166. result := mkassign(list(name, r, c),
  167. lispcodeexp(car relts, ftype))
  168. . result;
  169. c := add1 c
  170. >>
  171. until null(relts := cdr relts);
  172. r := add1 r;
  173. c := 1
  174. >>;
  175. return mkstmtgp(nil, reverse result)
  176. end
  177. else begin
  178. scalar ftype,name;
  179. name := cadr form;
  180. if pairp name then name := car name;
  181. ftype := symtabget(nil,name);
  182. if null ftype then ftype := !*period else
  183. << ftype := cadr ftype;
  184. ftype := if ftype equal 'integer or
  185. (ftype equal 'scalar and deftype!* equal 'integer) then nil
  186. else !*period;
  187. >>;
  188. if cadr form eq 'e then % To prevent an 'e on the lhs
  189. % being changed to exp(1) by lispcodeexp
  190. % mcd 29/4/88
  191. return mkassign('e,lispcodeexp(caddr form, ftype))
  192. else
  193. return mkassign(lispcodeexp(cadr form, ftype),
  194. lispcodeexp(caddr form, ftype))
  195. end$
  196. procedure lispcoderead form;
  197. % (SETQ var (READ)) --> (READ var) %
  198. list('read, lispcodeexp(cadr form, nil))$
  199. procedure lispcodeprint form;
  200. 'write . for each elt in cdr form collect lispcodeexp(elt, !*period)$
  201. procedure lispcodewhile form;
  202. 'while . lispcodeexp(cadr form, !*period) .
  203. foreach st in cddr form collect lispcodestmt st$
  204. procedure lispcoderepeat form;
  205. begin
  206. scalar body, logexp;
  207. body := reverse cdr form;
  208. logexp := car body;
  209. body := reverse cdr body;
  210. return 'repeat . append(foreach st in body collect lispcodestmt st,
  211. list lispcodeexp(logexp, !*period))
  212. end$
  213. procedure lispcodefor form;
  214. % (SETQ var1 (FOR var (exp1 exp2 exp3) SUM exp))
  215. % --> (PROGN (SETQ var1 0/0.0)
  216. % (FOR var (exp1 exp2 exp3) DO (SETQ var1 (PLUS var1 exp))))
  217. % (SETQ var1 (FOR var (exp1 exp2 exp3) PRODUCT exp))
  218. % --> (PROGN (SETQ var1 1/1.0)
  219. % (FOR var (exp1 exp2 exp3) DO (SETQ var1 (TIMES var1 exp))))
  220. if car form eq 'for then
  221. begin
  222. scalar explst, stmtlst;
  223. explst := list(cadr form, caddr form);
  224. stmtlst := cddddr form;
  225. return append(!*for!* .
  226. foreach exp in explst collect lispcodeexp(exp, nil),
  227. !*do!* .
  228. foreach st in stmtlst collect lispcodestmt st)
  229. end
  230. else
  231. begin
  232. scalar var1, var, explst, op, exp;
  233. var1 := cadr form;
  234. form := caddr form;
  235. var := cadr form;
  236. explst := caddr form;
  237. if cadddr form eq 'sum then
  238. op := 'plus
  239. else
  240. op := 'times;
  241. exp := car cddddr form;
  242. form := list('prog, nil,
  243. lispcode list('setq,var1,if op eq 'plus then 0 else 1),
  244. lispcode list(!*for!*, var, explst, !*do!*,
  245. list('setq, var1, list(op, var1, exp))));
  246. return lispcodestmt form
  247. end$
  248. procedure lispcodecond form;
  249. begin
  250. scalar result, pr;
  251. while form := cdr form do
  252. <<
  253. pr := car form;
  254. pr := lispcodeexp(car pr, !*period)
  255. . for each stmt in cdr pr collect lispcodestmt stmt;
  256. result := pr . result
  257. >>;
  258. return mkcond reverse result
  259. end$
  260. procedure lispcodereturn form;
  261. % (RETURN NIL) --> (RETURN) %
  262. if form member '((return) (return nil)) then
  263. list 'return
  264. else
  265. mkreturn lispcodeexp(cadr form, !*period)$
  266. procedure lispcodestmtgp form;
  267. % (RBLOCK () stmt1 stmt2 .. stmtm) %
  268. % --> (PROG () stmt1 stmt2 .. stmtm) %
  269. if car form memq '(prog rblock) then
  270. mkstmtgp(cadr form,
  271. for each stmt in cddr form collect lispcodestmt stmt)
  272. else
  273. mkstmtgp(0, for each stmt in cdr form collect lispcodestmt stmt)$
  274. procedure lispcodedef form;
  275. % (PROCEDURE id NIL EXPR (p1 p2 .. pn) stmt') %
  276. % --> (DEFUN id (p1 p2 .. pn) stmt') %
  277. if car form eq 'procedure then
  278. mkdef(cadr form, car cddddr form, for each stmt in cdr cddddr form
  279. collect lispcodestmt stmt)
  280. else
  281. mkdef(cadr form, caddr form, for each stmt in cdddr form
  282. collect lispcodestmt stmt)$
  283. %% REDUCE Form Predicates %%
  284. procedure redassignp form;
  285. eqcar(form, 'setq) and redassign1p caddr form$
  286. procedure redassign1p form;
  287. if atom form then
  288. t
  289. else if car form eq 'setq then
  290. redassign1p caddr form
  291. else if car form memq '(read for) then
  292. nil
  293. else
  294. t$
  295. procedure redcondp form;
  296. eqcar(form, 'cond)$
  297. procedure reddefp form;
  298. eqcar(form, 'procedure)$
  299. procedure redexpp form;
  300. atom form or
  301. car form memq !*redarithexpops!* or
  302. car form memq !*redlogexpops!* or
  303. not(car form memq !*redreswds!*)$
  304. procedure redforp form;
  305. if pairp form then
  306. if car form eq 'for then
  307. t
  308. else if car form eq 'setq then
  309. redfor1p caddr form$
  310. procedure redfor1p form;
  311. if atom form then
  312. nil
  313. else if car form eq 'setq then
  314. redfor1p caddr form
  315. else if car form eq 'for then
  316. t$
  317. procedure redprintp form;
  318. eqcar(form, 'write)$
  319. procedure redreadp form;
  320. eqcar(form, 'setq) and redread1p caddr form$
  321. procedure redread1p form;
  322. if atom form then
  323. nil
  324. else if car form eq 'setq then
  325. redread1p caddr form
  326. else if car form eq 'read then
  327. t$
  328. procedure redrepeatp form;
  329. eqcar(form, 'repeat)$
  330. procedure redreturnp form;
  331. eqcar(form, 'return)$
  332. procedure redstmtp form;
  333. atom form or
  334. car form memq !*redstmtops!* or
  335. atom car form and not(car form memq !*redreswds!*)$
  336. procedure redstmtgpp form;
  337. pairp form and car form memq !*redstmtgpops!*$
  338. procedure redwhilep form;
  339. eqcar(form, 'while)$
  340. endmodule;
  341. end;