aenv.clu_0 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. % AENV CLU
  2. %
  3. % CLUMAC assembler: assembler environment
  4. a_env = cluster is create, % -> env
  5. set_input, % env, file ->
  6. get_input, % env -> file
  7. set_output, % file -> env
  8. get_output, % file -> env
  9. get_lh_equate, % env -> bool
  10. set_lh_equate, % env, bool ->
  11. begin_cluster, % env ->
  12. end_cluster, % env ->
  13. use_owndata, % env ->
  14. begin_proc, % env ->
  15. end_proc, % env ->
  16. get_arg_count, % env -> int
  17. set_arg_count, % env, int ->
  18. set_proc_type, % env, wrd ->
  19. add_option, % env, int ->
  20. add_clink, % env, wrd ->
  21. add_plink, % env, wrd -> int
  22. add_link, % env, wrd -> int
  23. add_odlink, % env, wrd -> int
  24. add_vinit, % env, wrd -> int
  25. add_mlink, % env, wrd ->
  26. add_rlink, % env, int, aw -> wrd
  27. add_wrd, % env, wrd
  28. add_eblock, % env ->
  29. begin_loop, % env ->
  30. end_loop, % env ->
  31. get_loop_disp, % env -> wrd
  32. begin_if, % env ->
  33. begin_else, % env ->
  34. end_if, % env ->
  35. get_fi_disp, % env -> wrd
  36. get_else_disp, % env -> wrd
  37. begin_tagcase, % env ->
  38. end_tagcase, % env ->
  39. get_tags_exist, % env -> bool
  40. set_tags_exist, % env, bool ->
  41. begin_catch, % env ->
  42. begin_except, % env, wrd, aw ->
  43. end_catch, % env ->
  44. get_uncatch_disp, % env -> wrd
  45. define, % env, str, wrd ->
  46. defmac, % env, str, mtype ->
  47. label, % env, str -> wrd
  48. lookup, % env, str -> wrd
  49. dlookup, % env, str -> def
  50. err, % env, str ->
  51. get_err, % env -> bool
  52. set_err, % env, bool ->
  53. undefined, % env, str ->
  54. get_char_tab, % env -> ai
  55. get_temp_ac, % env -> ac
  56. newline, % env ->
  57. dump; % env, chan ->
  58. _ld_cod = 0; % offsets in initial vector of binary output
  59. _ld_siz = 1;
  60. _ld_low = 2;
  61. _ld_ent = 3;
  62. _ld_ver = 4;
  63. _ld_ref = 5;
  64. dtab = table[def];
  65. unknownlist = array[unknown];
  66. unknown = record[loc: int,
  67. wrd: wrd];
  68. rep = record[input: file,
  69. lineno: int,
  70. output: file,
  71. err: bool,
  72. lh_equate: bool,
  73. in_cluster: bool,
  74. oduse: int,
  75. in_proc: bool,
  76. proc_type: wrd,
  77. arg_count: int,
  78. options: int,
  79. memory: memory,
  80. defs: dtab,
  81. unknowns: unknownlist,
  82. ppart: aw,
  83. eblock: aw,
  84. clinks: aw,
  85. plinks: aw,
  86. links: aw,
  87. odlinks: aw,
  88. vinits: aw,
  89. mlinks: aw,
  90. rlinks: aaw,
  91. ppart_sym: str,
  92. eblock_point: int,
  93. clink_sym: str,
  94. plink_sym: str,
  95. link_sym: str,
  96. odlink_sym: str,
  97. vinit_sym: str,
  98. fi_sym: str,
  99. else_sym: str,
  100. catch_sym: str,
  101. uncatch_sym: str,
  102. rlink_disp: wrd,
  103. loop_disps: aw,
  104. fi_disps: as,
  105. else_disps: as,
  106. tag_flags: ab,
  107. uncatch_disps: as,
  108. rlink_count: int,
  109. catch_counts: ai,
  110. catch_disps: aw,
  111. char_tab: ai,
  112. temp_ac: ac];
  113. create = proc () returns (cvt);
  114. zero: wrd := wrd$create(0, 0);
  115. e: rep := rep${ input: file$open_read("nul:"),
  116. lineno: 1,
  117. output: file$tyo(),
  118. err: false,
  119. lh_equate: false,
  120. in_cluster: false,
  121. oduse: 0,
  122. in_proc: false,
  123. proc_type: zero,
  124. arg_count: 0,
  125. options: 0,
  126. memory: memory$create(),
  127. defs: dtab$create(),
  128. unknowns: unknownlist$predict(1, 1000),
  129. ppart: aw$predict(1, 1000),
  130. eblock: aw$predict(1, 100),
  131. clinks: aw$predict(1, 20),
  132. plinks: aw$predict(1, 20),
  133. links: aw$predict(1, 1000),
  134. odlinks: aw$predict(1, 10),
  135. vinits: aw$predict(1, 30),
  136. mlinks: aw$predict(1, 100),
  137. rlinks: aaw$predict(1, 2000),
  138. ppart_sym: ",ppart_1",
  139. eblock_point: 0,
  140. clink_sym: ",clink_1",
  141. plink_sym: ",plink_1",
  142. link_sym: ",link_1",
  143. odlink_sym: ",odlink_1",
  144. vinit_sym: ",vinit_1",
  145. fi_sym: ",fi_1",
  146. else_sym: ",else_1",
  147. catch_sym: ",catch_1",
  148. uncatch_sym: ",uncatch_1",
  149. rlink_disp: wrd$make_unknown(",rlink"),
  150. loop_disps: aw$predict(1, 5),
  151. fi_disps: as$predict(1, 5),
  152. else_disps: as$predict(1, 5),
  153. tag_flags: ab$predict(1, 5),
  154. uncatch_disps: as$predict(1, 5),
  155. rlink_count: 0,
  156. catch_counts: ai$predict(1, 5),
  157. catch_disps: aw$predict(1, 5),
  158. char_tab: create_char_tab(),
  159. temp_ac: ac$predict(1, 30)};
  160. ppart: aw := e.ppart;
  161. for i: int in int$from_to(1, _pr_go - 1) do
  162. aw$addh(ppart, zero);
  163. end;
  164. mem: memory := e.memory;
  165. mem.loc := _userlo;
  166. memory$deposit(mem, _tvec, 6);
  167. memory$deposit(mem, 0, 0);
  168. memory$deposit(mem, 0, _userlo);
  169. memory$deposit(mem, 0, 0);
  170. memory$deposit(mem, _vers_format, _vers_feature);
  171. memory$deposit(mem, 0, 0);
  172. return(e);
  173. end create;
  174. get_input = proc (e: cvt) returns (file);
  175. return(e.input);
  176. end get_input;
  177. set_input = proc (e: cvt, f: file);
  178. e.input := f;
  179. e.lineno := 1;
  180. end set_input;
  181. get_output = proc (e: cvt) returns (file);
  182. return(e.output);
  183. end get_output;
  184. set_output = proc (e: cvt, f: file);
  185. e.output := f;
  186. end set_output;
  187. get_err = proc (e: cvt) returns (bool);
  188. return(e.err);
  189. end get_err;
  190. set_err = proc (e: cvt, b: bool);
  191. e.err := b;
  192. end set_err;
  193. get_lh_equate = proc (e: cvt) returns (bool);
  194. return(e.lh_equate);
  195. end get_lh_equate;
  196. set_lh_equate = proc (e: cvt, b: bool);
  197. e.lh_equate := b;
  198. end set_lh_equate;
  199. begin_cluster = proc (e: cvt);
  200. if e.in_cluster
  201. then err(up(e), "unterminated cluster");
  202. end_cluster(up(e));
  203. end;
  204. e.in_cluster := true;
  205. end begin_cluster;
  206. end_cluster = proc (e: cvt);
  207. if ~e.in_cluster
  208. then err(up(e), "not in cluster");
  209. return;
  210. end;
  211. if e.in_proc
  212. then err(up(e), "unterminated proc/iter");
  213. end_proc(up(e));
  214. end;
  215. voutput(e, e.links, e.link_sym);
  216. voutput(e, e.clinks, e.clink_sym);
  217. voutput(e, e.odlinks, e.odlink_sym);
  218. e.link_sym := new_sym(e.link_sym);
  219. e.clink_sym := new_sym(e.clink_sym);
  220. e.odlink_sym := new_sym(e.odlink_sym);
  221. e.in_cluster := false;
  222. end end_cluster;
  223. use_owndata = proc (e: cvt);
  224. e.oduse := 1;
  225. end use_owndata;
  226. begin_proc = proc (e: cvt);
  227. if ~e.in_cluster
  228. then err(up(e), "not in cluster");
  229. begin_cluster(up(e));
  230. end;
  231. if e.in_proc
  232. then err(up(e), "unterminated proc/iter");
  233. end_proc(up(e));
  234. end;
  235. e.in_proc := true;
  236. end begin_proc;
  237. end_proc = proc (ee: env);
  238. e: rep := down(ee);
  239. if ~e.in_proc
  240. then err(ee, "not in proc/iter");
  241. return;
  242. end;
  243. if as$size(e.fi_disps) > 0
  244. then err(ee, "not all $if's properly ended");
  245. as$trim(e.fi_disps, 1, 0);
  246. as$trim(e.else_disps, 1, 0);
  247. end;
  248. if aw$size(e.loop_disps) > 0
  249. then err(ee, "not all $loop's properly ended");
  250. aw$trim(e.loop_disps, 1, 0);
  251. end;
  252. if as$size(e.uncatch_disps) > 0
  253. then err(ee, "not all $catch's properly ended");
  254. as$trim(e.uncatch_disps, 1, 0);
  255. aw$trim(e.catch_disps, 1, 0);
  256. ai$trim(e.catch_counts, 1, 0);
  257. end;
  258. put_entry_block(e);
  259. put_pure_part(e);
  260. voutput(e, e.vinits, e.vinit_sym);
  261. voutput(e, e.plinks, e.plink_sym);
  262. e.vinit_sym := new_sym(e.vinit_sym);
  263. e.plink_sym := new_sym(e.plink_sym);
  264. e.proc_type := wrd$create(0, 0);
  265. e.options := 0;
  266. e.oduse := 0;
  267. e.arg_count := 0;
  268. e.in_proc := false;
  269. end end_proc;
  270. put_entry_block = proc (e: rep);
  271. ee: env := up(e);
  272. zero: wrd := wrd$create(0, 0);
  273. add_mlink(ee, wrd$create(_tref, e.memory.loc));
  274. put_wrd(e, wrd$create(_terep, _en_dat + e.oduse));
  275. viz: int := aw$size(e.vinits);
  276. viwrd: wrd;
  277. if viz = 0
  278. then put_wrd(e, wrd$xinst(PUSHJ, SP, 0, _qsetup));
  279. viwrd := wrd$create(0, 0);
  280. else put_wrd(e, wrd$xinst(PUSHJ, SP, 0, _setup));
  281. viwrd := wrd$r2l(lookup(ee, e.vinit_sym)) + wrd$create(1, viz);
  282. end;
  283. ppaddr: wrd := lookup(ee, e.ppart_sym);
  284. laddr: wrd := lookup(ee, e.link_sym);
  285. put_wrd(e, wrd$r2l(laddr) + ppaddr);
  286. put_wrd(e, viwrd);
  287. paddr: wrd := lookup(ee, e.plink_sym);
  288. caddr: wrd := lookup(ee, e.clink_sym);
  289. put_wrd(e, wrd$r2l(paddr) + caddr);
  290. put_wrd(e, zero);
  291. put_wrd(e, e.proc_type);
  292. put_wrd(e, zero);
  293. if e.oduse > 0
  294. then odaddr: wrd := lookup(ee, e.odlink_sym);
  295. put_wrd(e, wrd$iaddl(odaddr, _tref));
  296. end;
  297. end put_entry_block;
  298. put_pure_part = proc (e: rep);
  299. ee: env := up(e);
  300. define(ee, e.ppart_sym, wrd$create(0, e.memory.loc));
  301. ppart: aw := e.ppart;
  302. eblock: aw := e.eblock;
  303. bz: int := e.eblock_point;
  304. pz: int := aw$size(ppart);
  305. ez: int := aw$size(eblock);
  306. put_wrd(e, wrd$create(_tprep, pz + ez + 1));
  307. put_wrd(e, wrd$create(e.options, bz));
  308. put_wrd(e, wrd$create(0, e.arg_count + 2));
  309. put_wrd(e, wrd$create(0, bz + ez));
  310. for i: int in int$from_to(_pr_go, bz - 1) do
  311. put_wrd(e, ppart[i]);
  312. end;
  313. for w: wrd in aw$elements(eblock) do
  314. put_wrd(e, w);
  315. end;
  316. for i: int in int$from_to(bz, pz) do
  317. put_wrd(e, ppart[i]);
  318. end;
  319. aw$trim(ppart, 1, _pr_go - 1);
  320. aw$trim(eblock, 1, 0);
  321. e.ppart_sym := new_sym(e.ppart_sym);
  322. e.eblock_point := 0;
  323. end put_pure_part;
  324. voutput = proc (e: rep, vec: aw, sym: str);
  325. z: int := aw$size(vec);
  326. if z = 0
  327. then define(up(e), sym, wrd$create(0, 0));
  328. return;
  329. end;
  330. define(up(e), sym, wrd$create(0, e.memory.loc));
  331. put_wrd(e, wrd$create(_tvec, z + 1));
  332. for w: wrd in aw$elements(vec) do
  333. put_wrd(e, w);
  334. end;
  335. aw$trim(vec, 1, 0);
  336. end voutput;
  337. get_arg_count = proc (e: cvt) returns (int);
  338. return(e.arg_count);
  339. end get_arg_count;
  340. set_arg_count = proc (e: cvt, cnt: int);
  341. e.arg_count := cnt;
  342. end set_arg_count;
  343. set_proc_type = proc (e: cvt, w: wrd);
  344. e.proc_type := w;
  345. end set_proc_type;
  346. add_option = proc (e: cvt, opt: int);
  347. e.options := i_or(e.options, opt);
  348. end add_option;
  349. add_clink = proc (e: cvt, w: wrd) returns (int);
  350. clinks: aw := e.clinks;
  351. aw$addh(clinks, w);
  352. return(aw$size(clinks));
  353. end add_clink;
  354. add_plink = proc (e: cvt, w: wrd) returns (int);
  355. plinks: aw := e.plinks;
  356. aw$addh(plinks, w);
  357. return(aw$size(plinks));
  358. end add_plink;
  359. add_link = proc (e: cvt, w: wrd) returns (int);
  360. links: aw := e.links;
  361. aw$addh(links, w);
  362. return(aw$size(links));
  363. end add_link;
  364. add_odlink = proc (e: cvt, w: wrd) returns (int);
  365. odlinks: aw := e.odlinks;
  366. aw$addh(odlinks, w);
  367. return(aw$size(odlinks));
  368. end add_odlink;
  369. add_vinit = proc (e: cvt, w: wrd) returns (int);
  370. vinits: aw := e.vinits;
  371. aw$addh(vinits, w);
  372. return(aw$size(vinits));
  373. end add_vinit;
  374. add_mlink = proc (e: cvt, w: wrd);
  375. aw$addh(e.mlinks, w);
  376. end add_mlink;
  377. add_rlink = proc (e: cvt, typ: int, vec: aw) returns (wrd);
  378. cnt: int := e.rlink_count;
  379. aaw$addh(e.rlinks, vec);
  380. head: wrd := wrd$create(typ, cnt);
  381. e.rlink_count := cnt + aw$size(vec);
  382. return(head + e.rlink_disp);
  383. end add_rlink;
  384. add_wrd = proc (e: cvt, w: wrd);
  385. aw$addh(e.ppart, w);
  386. end add_wrd;
  387. add_eblock = proc (e: cvt);
  388. e.eblock_point := aw$size(e.ppart) + 1;
  389. end add_eblock;
  390. begin_loop = proc (e: cvt);
  391. disp: int := aw$size(e.ppart) + 1;
  392. aw$addh(e.loop_disps, wrd$create(0, disp));
  393. end begin_loop;
  394. end_loop = proc (e: cvt);
  395. aw$remh(e.loop_disps);
  396. except when bounds: err(up(e), "not in $loop");
  397. end;
  398. end end_loop;
  399. get_loop_disp = proc (e: cvt) returns (wrd);
  400. return(aw$top(e.loop_disps));
  401. except when bounds: ; end;
  402. err(up(e), "not in $loop");
  403. return(wrd$create(0, 0));
  404. end get_loop_disp;
  405. begin_if = proc (e: cvt);
  406. as$addh(e.fi_disps, e.fi_sym);
  407. as$addh(e.else_disps, e.else_sym);
  408. e.fi_sym := new_sym(e.fi_sym);
  409. e.else_sym := new_sym(e.else_sym);
  410. end begin_if;
  411. begin_else = proc (e: cvt);
  412. label(up(e), as$remh(e.else_disps));
  413. except when bounds: err(up(e), "not in $if");
  414. return;
  415. end;
  416. as$addh(e.else_disps, e.else_sym);
  417. e.else_sym := new_sym(e.else_sym);
  418. end begin_else;
  419. end_if = proc (e: cvt);
  420. label(up(e), as$remh(e.fi_disps));
  421. except when bounds: err(up(e), "not in $if");
  422. return;
  423. end;
  424. label(up(e), as$remh(e.else_disps));
  425. end end_if;
  426. get_fi_disp = proc (e: cvt) returns (wrd);
  427. return(lookup(up(e), as$top(e.fi_disps)));
  428. except when bounds: ; end;
  429. err(up(e), "not in $if");
  430. return(wrd$create(0, 0));
  431. end get_fi_disp;
  432. get_else_disp = proc (e: cvt) returns (wrd);
  433. return(lookup(up(e), as$top(e.fi_disps)));
  434. except when bounds: ; end;
  435. err(up(e), "not if $if");
  436. return(wrd$create(0, 0));
  437. end get_else_disp;
  438. begin_tagcase = proc (e: cvt);
  439. ab$addh(e.tag_flags, false);
  440. begin_if(up(e));
  441. end begin_tagcase;
  442. get_tags_exist = proc (e: cvt) returns (bool);
  443. return(ab$top(e.tag_flags));
  444. except when bounds: ; end;
  445. err(up(e), "not in $tagcase");
  446. return(false);
  447. end get_tags_exist;
  448. set_tags_exist = proc (e: cvt, b: bool);
  449. e.tag_flags[ab$size(e.tag_flags)] := b;
  450. except when bounds: err(up(e), "not in $tagcase");
  451. return;
  452. end;
  453. end set_tags_exist;
  454. end_tagcase = proc (e: cvt);
  455. ab$remh(e.tag_flags);
  456. except when bounds: err(up(e), "not in $tagcase");
  457. return;
  458. end;
  459. end_if(up(e));
  460. end end_tagcase;
  461. begin_catch = proc (e: cvt);
  462. as$addh(e.uncatch_disps, e.uncatch_sym);
  463. e.uncatch_sym := new_sym(e.uncatch_sym);
  464. ai$addh(e.catch_counts, aw$size(e.ppart) + 1);
  465. aw$addh(e.catch_disps, label(up(e), e.catch_sym));
  466. e.catch_sym := new_sym(e.catch_sym);
  467. end begin_catch;
  468. begin_except = proc (e: cvt, var: wrd, names: aw);
  469. counts: ai := e.catch_counts;
  470. disps: aw := e.catch_disps;
  471. cnt: int := ai$top(counts);
  472. except when bounds: err(up(e), "not in $catch");
  473. return;
  474. end;
  475. disp: wrd := aw$top(disps);
  476. ncnt: int := aw$size(e.ppart) + 1;
  477. if cnt > 0
  478. then cnt := cnt - ncnt;
  479. z: int := ai$high(counts);
  480. counts[z] := cnt;
  481. disp := wrd$iaddl(disp, cnt);
  482. disps[z] := disp;
  483. end;
  484. eblock: aw := e.eblock;
  485. aw$addh(eblock, disp);
  486. aw$addh(eblock, wrd$create(aw$size(names), ncnt));
  487. aw$addh(eblock, var.right);
  488. for name: wrd in aw$elements(names) do
  489. aw$addh(eblock, name);
  490. end;
  491. end begin_except;
  492. end_catch = proc (e: cvt);
  493. label(up(e), as$remh(e.uncatch_disps));
  494. except when bounds: err(up(e), "not in $catch");
  495. return;
  496. end;
  497. ai$remh(e.catch_counts);
  498. aw$remh(e.catch_disps);
  499. end end_catch;
  500. get_uncatch_disp = proc (e: cvt) returns (wrd);
  501. return(lookup(up(e), as$top(e.uncatch_disps)));
  502. except when bounds: ; end;
  503. err(up(e), "not in $catch");
  504. return(wrd$create(0, 0));
  505. end get_uncatch_disp;
  506. define = proc (e: cvt, sym: str, val: wrd);
  507. dtab$alter(e.defs, sym, def$make_value(val));
  508. end define;
  509. defmac = proc (e: cvt, sym: str, mac: mtype);
  510. dtab$alter(e.defs, sym, def$make_macro(mac));
  511. end defmac;
  512. label = proc (e: cvt, sym: str) returns (wrd);
  513. val: wrd := wrd$create(0, aw$size(e.ppart) + 1);
  514. dtab$alter(e.defs, sym, def$make_value(val));
  515. return(val);
  516. end label;
  517. lookup = proc (e: cvt, sym: str) returns (wrd);
  518. d: def := dtab$lookup(e.defs, sym);
  519. except when not_found: val: wrd := wrd$make_unknown(sym);
  520. dtab$enter(e.defs, sym, def$make_undef(val));
  521. return(val);
  522. end;
  523. tagcase d
  524. tag value, undef (val: wrd):
  525. return(val);
  526. tag macro:
  527. err(up(e), "use of macro in expression");
  528. return(wrd$create(0, 0));
  529. end;
  530. end lookup;
  531. dlookup = proc (e: cvt, sym: str) returns (def);
  532. return(dtab$lookup(e.defs, sym));
  533. except when not_found: ; end;
  534. d: def := def$make_undef(wrd$make_unknown(sym));
  535. dtab$enter(e.defs, sym, d);
  536. return(d);
  537. end dlookup;
  538. err = proc (e: cvt, why: str);
  539. e.err := true;
  540. f: file := e.output;
  541. file$puti(f, e.lineno);
  542. file$puts(f, ":\t");
  543. file$puts(f, why);
  544. file$putc(f, '\n');
  545. end err;
  546. undefined = proc (e: cvt, sym: str);
  547. e.err := true;
  548. f: file := e.output;
  549. file$puti(f, e.lineno);
  550. file$puts(f, ":\tundefined symbol: ");
  551. file$puts(f, sym);
  552. file$putc(f, '\n');
  553. end undefined;
  554. get_char_tab = proc (e: cvt) returns (ai);
  555. return(e.char_tab);
  556. end get_char_tab;
  557. get_temp_ac = proc (e: cvt) returns (ac);
  558. a: ac := e.temp_ac;
  559. ac$trim(a, 1, 0);
  560. return(a);
  561. end get_temp_ac;
  562. newline = proc (e: cvt);
  563. e.lineno := e.lineno + 1;
  564. end newline;
  565. new_sym = proc (s: str) returns (str);
  566. n: int := str$indexc('_', s);
  567. ns: str := int$unparse(1 + int$parse(str$rest(s, n + 1)));
  568. return(str$substr(s, 1, n) || ns);
  569. end new_sym;
  570. put_wrd = proc (e: rep, w: wrd);
  571. if wrd$has_unknowns(w)
  572. then unknownlist$addh(e.unknowns, unknown${loc: e.memory.loc,
  573. wrd: w});
  574. memory$deposit(e.memory, 0, 0);
  575. else left, right: int := wrd$w2i(w);
  576. memory$deposit(e.memory, left, right);
  577. end;
  578. end put_wrd;
  579. dump = proc (e: cvt, c: chan);
  580. if e.in_cluster
  581. then err(up(e), "unterminated cluster");
  582. end_cluster(up(e));
  583. end;
  584. mem: memory := e.memory;
  585. mlinks: aw := e.mlinks;
  586. z: int := aw$size(mlinks);
  587. if z = 0
  588. then return; end;
  589. memory$store(mem, _userlo + _ld_ent, _tref, mem.loc);
  590. put_wrd(e, wrd$create(_tvec, z + 1));
  591. for w: wrd in aw$elements(mlinks) do
  592. put_wrd(e, w);
  593. end;
  594. put_wrd(e, wrd$create(0, 0));
  595. aw$trim(mlinks, 1, 0);
  596. memory$store(mem, _userlo + _ld_ref, _tref, mem.loc);
  597. define(up(e), ",rlink", wrd$create(0, mem.loc));
  598. rlinks: aaw := e.rlinks;
  599. for a: aw in aaw$elements(rlinks) do
  600. for w: wrd in aw$elements(a) do
  601. put_wrd(e, w);
  602. end;
  603. end;
  604. high: int := mem.loc;
  605. memory$deposit(mem, 0, 0);
  606. top: int := mem.loc;
  607. aaw$trim(rlinks, 1, 0);
  608. l, r: int := i_sub4(0, top, 0, _userlo);
  609. memory$store(mem, _userlo + _ld_siz, l, r);
  610. unks: unknownlist := e.unknowns;
  611. for unk: unknown in unknownlist$elements(unks) do
  612. l, r := eval_wrd(e, unk.wrd);
  613. memory$store(mem, unk.loc, l, r);
  614. end;
  615. unknownlist$trim(unks, 1, 0);
  616. memory$dump(mem, _userlo, high, c);
  617. end dump;
  618. eval_wrd = proc (e: rep, w: wrd) returns (int, int);
  619. l, r: int, ul, ur: str := wrd$w2all(w);
  620. ulv, urv, spare: int;
  621. if ul = ""
  622. then ulv := 0;
  623. else spare, ulv := eval_wrd(e, vlookup(e, ul));
  624. end;
  625. if ur = ""
  626. then urv := 0;
  627. else spare, urv := eval_wrd(e, vlookup(e, ur));
  628. end;
  629. l, r := i_add4(l, r, ulv, urv);
  630. return(l, r);
  631. end eval_wrd;
  632. vlookup = proc (e: rep, sym: str) returns (wrd);
  633. return(def$value_value(dtab$lookup(e.defs, sym)));
  634. except when wrong_tag, not_found: ; end;
  635. undefined(up(e), sym);
  636. w: wrd := wrd$create(0, 0);
  637. define(up(e), sym, w);
  638. return(w);
  639. end vlookup;
  640. create_char_tab = proc () returns (ai);
  641. return(ai$[0:
  642. _badch, _badch, _badch, _badch, _badch, _badch, _badch, _badch,
  643. _badch, _space, _eol, _badch, _space, _badch, _badch, _badch,
  644. _badch, _badch, _badch, _badch, _badch, _badch, _badch, _badch,
  645. _badch, _badch, _badch, _lower, _badch, _badch, _badch, _badch,
  646. _space, _badch, _badch, _funny, _lower, _lower, _and, _badch,
  647. _lparen, _rparen, _times, _plus, _comma, _minus, _lower, _badch,
  648. _digit, _digit, _digit, _digit, _digit, _digit, _digit, _digit,
  649. _digit, _digit, _badch, _semi, _langle, _equal, _rangle, _lower,
  650. _at, _upper, _upper, _upper, _upper, _upper, _upper, _upper,
  651. _upper, _upper, _upper, _upper, _upper, _upper, _upper, _upper,
  652. _upper, _upper, _upper, _upper, _upper, _upper, _upper, _upper,
  653. _upper, _upper, _upper, _lbkt, _bslash, _rbkt, _funny, _lower,
  654. _badch, _lower, _lower, _lower, _lower, _lower, _lower, _lower,
  655. _lower, _lower, _lower, _lower, _lower, _lower, _lower, _lower,
  656. _lower, _lower, _lower, _lower, _lower, _lower, _lower, _lower,
  657. _lower, _lower, _lower, _lcurly, _funny, _rcurly, _badch, _badch
  658. ]);
  659. end create_char_tab;
  660. end a_env;