amac1.clu_0 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. % AMAC1 CLU
  2. %
  3. % CLUMAC assembler: macro definitions
  4. m_comment = proc (e: env);
  5. get_literal(e);
  6. end m_comment;
  7. m_insrt = proc (e: env);
  8. get_literal(e);
  9. end m_insrt;
  10. m_cluster = proc (e: env);
  11. env$begin_cluster(e);
  12. env$add_link(e, string_lit(e, get_symbol(e)));
  13. atype: wrd := get_wrd(e);
  14. env$add_mlink(e, atype);
  15. rtype: wrd := get_wrd(e);
  16. if get_flag(atype) = _tdc_cp
  17. then env$add_clink(e, atype);
  18. env$add_clink(e, rtype);
  19. else env$add_link(e, atype);
  20. env$add_link(e, rtype);
  21. end;
  22. for parm: wrd in get_wrds(e) do
  23. env$add_clink(e, parm);
  24. end;
  25. end m_cluster;
  26. m_retsulc = proc (e: env);
  27. get_symbol(e);
  28. env$end_cluster(e);
  29. end m_retsulc;
  30. m_oduse = proc (e: env);
  31. env$use_owndata(e);
  32. end m_oduse;
  33. m_proc = proc (e: env);
  34. env$begin_proc(e);
  35. name: str := get_symbol(e);
  36. args: as := as$predict(1, 3);
  37. for arg: str in get_symbols(e) do
  38. as$addh(args, arg);
  39. end;
  40. e.arg_count := as$size(args);
  41. as$set_low(args, - 1 - e.arg_count);
  42. for i: int in as$indexes(args) do
  43. env$define(e, args[i], wrd$create(0, i));
  44. end;
  45. vars: as := as$predict(1, 3);
  46. for var: str in get_symbols(e) do
  47. as$addh(vars, var);
  48. end;
  49. vz: int := as$size(vars);
  50. iz: int := 0;
  51. for init: wrd in get_wrds(e) do
  52. iz := iz + 1;
  53. if iz <= vz
  54. then disp: int := env$add_vinit(e, init);
  55. env$define(e, vars[iz], wrd$create(0, disp));
  56. end;
  57. end;
  58. if iz ~= vz
  59. then env$err(e, "variable initialization of wrong length");
  60. zero: wrd := wrd$create(0, 0);
  61. for iz in int$from_to(iz + 1, vz) do
  62. disp: int := env$add_vinit(e, zero);
  63. env$define(e, vars[iz], wrd$create(0, disp));
  64. end;
  65. end;
  66. ptype: wrd := get_wrd(e);
  67. e.proc_type := ptype;
  68. for parm: wrd in get_wrds(e) do
  69. env$add_plink(e, parm);
  70. end;
  71. env$add_option(e, get_flag(ptype));
  72. end m_proc;
  73. m_iter = proc (e: env);
  74. m_proc(e);
  75. env$add_option(e, _prc_it);
  76. end m_iter;
  77. m_corp = proc (e: env);
  78. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _frog));
  79. env$add_eblock(e);
  80. env$add_wrd(e, string_lit(e, get_symbol(e)));
  81. cnt: int := 0;
  82. for arg: str in get_symbols(e) do
  83. env$add_wrd(e, string_lit(e, arg));
  84. cnt := cnt + 1;
  85. end;
  86. if cnt ~= e.arg_count
  87. then env$err(e, "number of arguments in proc/iter and corp/reti disagree");
  88. end;
  89. env$end_proc(e);
  90. end m_corp;
  91. m_reti = m_corp;
  92. m_rtnc = proc (e: env);
  93. loc: wrd := wrd$iadd(get_wrd(e), 1);
  94. env$add_wrd(e, wrd$inst(JRST, 0, 0, loc));
  95. end m_rtnc;
  96. m_odlink = proc (e: env);
  97. disp: str := get_symbol(e);
  98. env$define(e, disp, wrd$create(0, env$add_odlink(e, get_wrd(e))));
  99. end m_odlink;
  100. m_odget = proc (e: env);
  101. env$add_wrd(e, wrd$xinst(MOVE, R0, MR, _en_odv));
  102. reg: int := get_number(e);
  103. disp: wrd := get_wrd(e);
  104. env$add_wrd(e, wrd$inst(MOVE, reg, R0, disp));
  105. end m_odget;
  106. m_odset = proc (e: env);
  107. env$add_wrd(e, wrd$xinst(MOVE, R0, MR, _en_odv));
  108. reg: int := get_number(e);
  109. disp: wrd := get_wrd(e);
  110. env$add_wrd(e, wrd$inst(MOVEM, reg, R0, disp));
  111. end m_odset;
  112. m_massn = proc (e: env);
  113. addrs: aw := aw$predict(1, 2);
  114. for addr: wrd in get_wrds(e) do
  115. aw$addh(addrs, addr);
  116. end;
  117. mcheck(e, aw$size(addrs));
  118. for addr: wrd in aw$elements(addrs) do
  119. env$add_wrd(e, wrd$inst(POP, SP, 0, addr));
  120. end;
  121. end m_massn;
  122. m_mcheck = proc (e: env);
  123. mcheck(e, get_number(e));
  124. end m_mcheck;
  125. mcheck = proc (e: env, n: int);
  126. disp: int := env$add_link(e, wrd$create(_tmrtn, n));
  127. env$add_wrd(e, wrd$xinst(CAME, RR, LR, disp));
  128. env$add_wrd(e, wrd$xinst(JSP, XR, 0, _badrtn));
  129. end mcheck;
  130. m_assn = proc (e: env);
  131. dst: wrd := get_wrd(e);
  132. src: wrd := get_wrd(e);
  133. if ~wrd$iequal(dst, RR)
  134. then env$add_wrd(e, wrd$inst(MOVE, RR, 0, dst)); end;
  135. if ~wrd$iequal(src, RR)
  136. then env$add_wrd(e, wrd$inst(MOVEM, RR, 0, src)); end;
  137. end m_assn;
  138. m_pops = proc (e: env);
  139. for addr: wrd in get_wrds(e) do
  140. env$add_wrd(e, wrd$inst(POP, SP, 0, addr));
  141. end;
  142. end m_pops;
  143. m_mflush = proc (e: env);
  144. env$add_wrd(e, wrd$xinst(HRLZ, N1, 0, RR));
  145. env$add_wrd(e, wrd$xinst(CAIN, N1, 0, _tmrtn));
  146. env$add_wrd(e, wrd$xinst(SUBI, SP, RR, 0));
  147. end m_mflush;
  148. m_loop = env$begin_loop;
  149. m_pool = proc (e: env);
  150. env$add_wrd(e, wrd$inst(JRST, 0, PR, e.loop_disp));
  151. env$end_loop(e);
  152. end m_pool;
  153. m_for = proc (e: env);
  154. lbl: wrd := get_wrd(e);
  155. addrs: aw := aw$new();
  156. for addr: wrd in get_wrds(e) do
  157. aw$addh(addrs, addr);
  158. end;
  159. do_line(e);
  160. env$add_wrd(e, wrd$inst(JRST, 0, PR, lbl));
  161. n: int := aw$size(addrs);
  162. if n > 1
  163. then mcheck(e, n);
  164. for addr: wrd in aw$elements(addrs) do
  165. env$add_wrd(e, wrd$inst(POP, SP, 0, addr));
  166. end;
  167. elseif n = 1
  168. then addr: wrd := aw$bottom(addrs);
  169. if ~wrd$iequal(addr, RR)
  170. then env$add_wrd(e, wrd$inst(MOVEM, RR, 0, addr)); end;
  171. end;
  172. end m_for;
  173. m_rof = proc (e: env);
  174. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _resume));
  175. env$label(e, get_symbol(e));
  176. end m_rof;
  177. m_label = proc (e: env);
  178. env$label(e, get_symbol(e));
  179. end m_label;
  180. m_anyize = proc (e: env);
  181. addr: wrd := get_wrd(e);
  182. env$add_wrd(e, wrd$inst(PUSH, SP, 0, addr));
  183. end m_anyize;
  184. m_go = proc (e: env);
  185. env$add_wrd(e, wrd$inst(JRST, 0, PR, get_wrd(e)));
  186. end m_go;
  187. m_if = proc (e: env);
  188. env$begin_if(e);
  189. do_line(e);
  190. end m_if;
  191. m_iff = proc (e: env);
  192. env$begin_if(e);
  193. do_line(e);
  194. env$add_wrd(e, wrd$xinst(CAME, RR, 0, _dfalse));
  195. end m_iff;
  196. m_ift = proc (e: env);
  197. env$begin_if(e);
  198. do_line(e);
  199. env$add_wrd(e, wrd$xinst(CAME, RR, 0, _dtrue));
  200. end m_ift;
  201. m_test = proc (e: env);
  202. do_line(e);
  203. env$add_wrd(e, wrd$xinst(CAME, RR, 0, _dtrue));
  204. end m_test;
  205. m_testf = proc (e: env);
  206. do_line(e);
  207. env$add_wrd(e, wrd$xinst(CAME, RR, 0, _dfalse));
  208. end m_testf;
  209. m_else = proc (e: env);
  210. env$add_wrd(e, wrd$inst(JRST, 0, PR, e.fi_disp));
  211. env$begin_else(e);
  212. do_line(e);
  213. end m_else;
  214. m_elf = m_else;
  215. m_then = proc (e: env);
  216. env$add_wrd(e, wrd$inst(JRST, 0, PR, e.else_disp));
  217. do_line(e);
  218. end m_then;
  219. m_fi = env$end_if;
  220. m_tagcase = proc (e: env);
  221. var: wrd := get_wrd(e);
  222. refchk(e, RR, var);
  223. repchk(e, RR, _torep);
  224. env$add_wrd(e, wrd$xinst(HRRZ, N1, RR, 0));
  225. env$add_wrd(e, wrd$xinst(MOVE, RR, RR, 1));
  226. if ~wrd$iequal(var, RR)
  227. then env$add_wrd(e, wrd$inst(MOVEM, RR, 0, var)); end;
  228. env$begin_tagcase(e);
  229. end m_tagcase;
  230. m_tag = proc (e: env);
  231. if e.tags_exist
  232. then env$add_wrd(e, wrd$inst(JRST,0, PR, e.fi_disp));
  233. env$begin_else(e);
  234. end;
  235. cnt: int := 0;
  236. for sel: int in get_numbers(e) do
  237. env$add_wrd(e, wrd$xinst(CAIN, N1, 0, sel));
  238. env$add_wrd(e, wrd$xinst(SKIPA, 0, 0, 0));
  239. cnt := cnt + 1;
  240. end;
  241. if cnt > 0
  242. then env$add_wrd(e, wrd$inst(JRST, 0, PR, e.else_disp));
  243. e.tags_exist := true;
  244. end;
  245. end m_tag;
  246. m_etagcase = env$end_tagcase;
  247. m_rtn = proc (e: env);
  248. addr: wrd := get_wrd(e);
  249. if ~wrd$iequal(addr, RR)
  250. then env$add_wrd(e, wrd$inst(MOVE, RR, 0, addr)); end;
  251. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _exiter));
  252. end m_rtn;
  253. m_mrtn = proc (e: env);
  254. left, right: int := wrd$w2i(get_wrd(e));
  255. m_args(e);
  256. if left > 0
  257. then env$add_wrd(e, wrd$xinst(MOVEI, RR, left, right));
  258. env$add_wrd(e, wrd$xinst(HRLI, RR, 0, _tmrtn));
  259. env$add_wrd(e, wrd$xinst(HRRZ, R0, 0, SP));
  260. env$add_wrd(e, wrd$xinst(SUBI, R0, RR, -1));
  261. env$add_wrd(e, wrd$xinst(MOVEI, BR, ER, - 1 - e.arg_count));
  262. env$add_wrd(e, wrd$xinst(HRL, BR, 0, R0));
  263. else w: wrd := wrd$create(_tmrtn, right);
  264. disp: int := env$add_link(e, w);
  265. env$add_wrd(e, wrd$xinst(MOVE, RR, LR, disp));
  266. env$add_wrd(e, wrd$xinst(MOVEI, BR, ER, - 1 - e.arg_count));
  267. env$add_wrd(e, wrd$xinst(HRLI, BR, SP, 1 - right));
  268. end;
  269. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _mexit));
  270. end m_mrtn;
  271. m_yield = proc (e: env);
  272. addr: wrd := get_wrd(e);
  273. if ~wrd$iequal(addr, RR)
  274. then env$add_wrd(e, wrd$inst(MOVE, RR, 0, addr)); end;
  275. env$add_wrd(e, wrd$xinst(JSP, 0, 0, _yield));
  276. end m_yield;
  277. m_myield = proc (e: env);
  278. n: int := get_number(e);
  279. w: wrd := wrd$create(_tmrtn, n);
  280. disp: int := env$add_link(e, w);
  281. env$add_wrd(e, wrd$xinst(MOVE, RR, LR, disp));
  282. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _myield));
  283. end m_myield;
  284. m_fakef = proc (e: env);
  285. env$add_wrd(e, wrd$xinst(PUSH, SP, 0, _dnone));
  286. env$add_wrd(e, wrd$xinst(PUSH, SP, 0, _dnone));
  287. end m_fakef;
  288. m_signal = proc (e: env);
  289. name: wrd := get_wrd(e);
  290. num: int := get_number(e);
  291. m_args(e);
  292. env$add_wrd(e, wrd$xinst(MOVEI, RR, 0, num));
  293. env$add_wrd(e, wrd$xinst(PUSH, SP, 0, RR));
  294. reg, disp: int := tdlink(e, name);
  295. env$add_wrd(e, wrd$xinst(PUSH, SP, reg, disp));
  296. env$add_wrd(e, wrd$xinst(JSP, XR, 0, _siggy));
  297. end m_signal;
  298. m_itpop = proc (e: env);
  299. env$add_wrd(e, wrd$xinst(JSP, XR, 0, _itpop));
  300. end m_itpop;
  301. m_cont = proc (e: env);
  302. env$add_wrd(e, wrd$inst(JRST, 0, PR, e.loop_disp));
  303. end m_cont;
  304. m_resume = proc (e: env);
  305. env$add_wrd(e, wrd$xinst(JRST, 0, 0, _resume));
  306. end m_resume;
  307. m_catch = proc (e: env);
  308. env$begin_catch(e);
  309. env$add_wrd(e, wrd$inst(HRROM, SP, 0, get_wrd(e)));
  310. end m_catch;
  311. m_uncatch = proc (e: env);
  312. env$end_catch(e);
  313. env$add_wrd(e, wrd$inst(HRR, SP, 0, get_wrd(e)));
  314. end m_uncatch;
  315. m_except = proc (e: env);
  316. env$add_wrd(e, wrd$inst(JRST, 0, PR, e.uncatch_disp));
  317. var: wrd := get_wrd(e);
  318. names: aw := aw$create(1);
  319. for name: wrd in get_wrds(e) do
  320. aw$addh(names, name);
  321. end;
  322. env$begin_except(e, var, names);
  323. vars: aw := aw$new();
  324. for v: wrd in get_wrds(e) do
  325. aw$addh(vars, v);
  326. end;
  327. for lbl: str in get_symbols(e) do
  328. env$label(e, lbl);
  329. end;
  330. for v: wrd in aw$elements(vars) do
  331. env$add_wrd(e, wrd$inst(POP, SP, 0, v));
  332. end;
  333. env$add_wrd(e, wrd$inst(HRR, SP, 0, var));
  334. end m_except;
  335. m_link = proc (e: env);
  336. name: str := get_symbol(e);
  337. disp: int := env$add_link(e, get_wrd(e));
  338. env$define(e, name, wrd$create(0, disp));
  339. end m_link;
  340. m_args = proc (e: env);
  341. for addr: wrd in get_wrds(e) do
  342. env$add_wrd(e, wrd$inst(PUSH, SP, 0, addr));
  343. end;
  344. end m_args;