subr.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. #ifndef NORCSID
  2. static char rcsid[] = "$Id$";
  3. #endif
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include "assert.h"
  7. #include "param.h"
  8. #include "tables.h"
  9. #include "types.h"
  10. #include <cgg_cg.h>
  11. #include "data.h"
  12. #include "result.h"
  13. #include "extern.h"
  14. /*
  15. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  16. * See the copyright notice in the ACK home directory, in the file "Copyright".
  17. *
  18. * Author: Hans van Staveren
  19. */
  20. string myalloc();
  21. unsigned codegen();
  22. match(tp,tep,optexp) register token_p tp; register set_p tep; {
  23. register bitno;
  24. token_p ct;
  25. result_t result;
  26. if (tp->t_token == -1) { /* register frame */
  27. bitno = tp->t_att[0].ar;
  28. if (tep->set_val[bitno>>4]&(1<<(bitno&017)))
  29. if (tep->set_val[0]&1 || getrefcount(bitno, FALSE)<=1)
  30. goto oklabel;
  31. return(0);
  32. } else { /* token frame */
  33. bitno = tp->t_token+NREGS;
  34. if ((tep->set_val[bitno>>4]&(1<<(bitno&017)))==0)
  35. return(0);
  36. }
  37. oklabel:
  38. if (optexp==0)
  39. return(1);
  40. ct=curtoken;
  41. curtoken=tp;
  42. compute(&enodes[optexp], &result);
  43. curtoken=ct;
  44. return(result.e_v.e_con);
  45. }
  46. instance(instno,token) register token_p token; {
  47. register inst_p inp;
  48. int i;
  49. register token_p tp;
  50. #if MAXMEMBERS != 0
  51. struct reginfo *rp;
  52. #endif
  53. int regno;
  54. result_t result;
  55. if (instno==0) {
  56. token->t_token = 0;
  57. for (i=TOKENSIZE-1;i>=0;i--)
  58. token->t_att[i].aw=0;
  59. return;
  60. }
  61. inp= &tokeninstances[instno];
  62. switch(inp->in_which) {
  63. default:
  64. assert(FALSE);
  65. case IN_COPY:
  66. if (inp->in_info[0] == 0)
  67. if (curtoken) tp = curtoken;
  68. else tp = &fakestack[stackheight-1];
  69. else tp= &fakestack[stackheight-inp->in_info[0]];
  70. if (inp->in_info[1]==0) {
  71. *token = *tp;
  72. } else {
  73. token->t_token= -1;
  74. #if MAXMEMBERS!=0
  75. assert(tp->t_token == -1);
  76. rp = &machregs[tp->t_att[0].ar];
  77. token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
  78. #else
  79. assert(FALSE);
  80. #endif
  81. }
  82. return;
  83. case IN_MEMB:
  84. if (inp->in_info[0] == 0)
  85. if (curtoken) tp = curtoken;
  86. else tp = &fakestack[stackheight-1];
  87. else tp= &fakestack[stackheight-inp->in_info[0]];
  88. assert(inp->in_info[1]!=0);
  89. assert(tp->t_token>0);
  90. token->t_token= -1;
  91. assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
  92. token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
  93. return;
  94. case IN_RIDENT:
  95. token->t_token= -1;
  96. token->t_att[0].ar= inp->in_info[0];
  97. return;
  98. case IN_ALLOC:
  99. token->t_token= -1;
  100. regno=allreg[inp->in_info[0]];
  101. #if MAXMEMBERS!=0
  102. if (inp->in_info[1])
  103. regno=machregs[regno].r_members[inp->in_info[1]-1];
  104. #endif
  105. token->t_att[0].ar = regno;
  106. return;
  107. #ifdef REGVARS
  108. case IN_S_DESCR:
  109. case IN_D_DESCR:
  110. compute(&enodes[inp->in_info[1]], &result);
  111. assert(result.e_typ==EV_INT);
  112. if ((regno=isregvar(result.e_v.e_con)) > 0) {
  113. token->t_token = -1;
  114. token->t_att[0].ar = regno;
  115. for (i=TOKENSIZE-1;i>0;i--)
  116. token->t_att[i].aw = 0;
  117. return;
  118. }
  119. /* fall through */
  120. #endif
  121. case IN_DESCR:
  122. token->t_token=inp->in_info[0];
  123. for (i=0;i<TOKENSIZE;i++)
  124. if (inp->in_info[i+1]==0) {
  125. assert(tokens[token->t_token].t_type[i]==0);
  126. token->t_att[i].aw=0;
  127. } else {
  128. compute(&enodes[inp->in_info[i+1]], &result);
  129. assert(tokens[token->t_token].t_type[i]==result.e_typ);
  130. if (result.e_typ==EV_INT)
  131. token->t_att[i].aw=result.e_v.e_con;
  132. else if (result.e_typ==EV_ADDR)
  133. token->t_att[i].aa= result.e_v.e_addr;
  134. else
  135. token->t_att[i].ar=result.e_v.e_reg;
  136. }
  137. return;
  138. }
  139. }
  140. cinstance(instno,token,tp,regno) register token_p token,tp; {
  141. register inst_p inp;
  142. int i;
  143. #if MAXMEMBERS != 0
  144. struct reginfo *rp;
  145. #endif
  146. result_t result;
  147. int sh; /* saved stackheight */
  148. assert(instno!=0);
  149. inp= &tokeninstances[instno];
  150. switch(inp->in_which) {
  151. default:
  152. assert(FALSE);
  153. case IN_COPY:
  154. assert(inp->in_info[0] <= 1);
  155. if (inp->in_info[1]==0) {
  156. *token = *tp;
  157. } else {
  158. token->t_token= -1;
  159. #if MAXMEMBERS!=0
  160. assert(tp->t_token == -1);
  161. rp = &machregs[tp->t_att[0].ar];
  162. token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
  163. #else
  164. assert(FALSE);
  165. #endif
  166. }
  167. return;
  168. case IN_MEMB:
  169. assert(inp->in_info[0] <= 1);
  170. token->t_token= -1;
  171. assert(tp->t_token>0);
  172. assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
  173. token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
  174. return;
  175. case IN_RIDENT:
  176. token->t_token= -1;
  177. token->t_att[0].ar= inp->in_info[0];
  178. return;
  179. case IN_ALLOC:
  180. token->t_token= -1;
  181. assert(inp->in_info[0]==0);
  182. #if MAXMEMBERS!=0
  183. if (inp->in_info[1])
  184. regno=machregs[regno].r_members[inp->in_info[1]-1];
  185. #endif
  186. token->t_att[0].ar = regno;
  187. return;
  188. #ifdef REGVARS
  189. case IN_S_DESCR:
  190. case IN_D_DESCR:
  191. { token_p ct = curtoken;
  192. curtoken = tp;
  193. compute(&enodes[inp->in_info[1]], &result);
  194. curtoken = ct;
  195. assert(result.e_typ==EV_INT);
  196. if ((regno=isregvar(result.e_v.e_con)) > 0) {
  197. token->t_token = -1;
  198. token->t_att[0].ar = regno;
  199. for (i=TOKENSIZE-1;i>0;i--)
  200. token->t_att[i].aw = 0;
  201. return;
  202. }
  203. }
  204. /* fall through */
  205. #endif
  206. case IN_DESCR:
  207. sh = stackheight;
  208. stackheight = tp - fakestack + 1;
  209. token->t_token=inp->in_info[0];
  210. for (i=0;i<TOKENSIZE;i++)
  211. if (inp->in_info[i+1]==0) {
  212. assert(tokens[token->t_token].t_type[i]==0);
  213. token->t_att[i].aw=0;
  214. } else {
  215. token_p ct = curtoken;
  216. curtoken = tp;
  217. compute(&enodes[inp->in_info[i+1]], &result);
  218. curtoken = ct;
  219. assert(tokens[token->t_token].t_type[i]==result.e_typ);
  220. if (result.e_typ==EV_INT)
  221. token->t_att[i].aw=result.e_v.e_con;
  222. else if (result.e_typ==EV_ADDR)
  223. token->t_att[i].aa= result.e_v.e_addr;
  224. else
  225. token->t_att[i].ar=result.e_v.e_reg;
  226. }
  227. stackheight = sh;
  228. return;
  229. }
  230. }
  231. eqtoken(tp1,tp2) token_p tp1,tp2; {
  232. register i;
  233. register tkdef_p tdp;
  234. if (tp1->t_token!=tp2->t_token)
  235. return(0);
  236. if (tp1->t_token==0)
  237. return(1);
  238. if (tp1->t_token==-1) {
  239. if (tp1->t_att[0].ar!=tp2->t_att[0].ar)
  240. return(0);
  241. return(1);
  242. }
  243. tdp = &tokens[tp1->t_token];
  244. for (i=0;i<TOKENSIZE;i++)
  245. switch(tdp->t_type[i]) {
  246. default:
  247. return(1);
  248. case EV_INT:
  249. if (tp1->t_att[i].aw != tp2->t_att[i].aw)
  250. return(0);
  251. break;
  252. case EV_REG:
  253. if (tp1->t_att[i].ar != tp2->t_att[i].ar)
  254. return(0);
  255. break;
  256. case EV_ADDR:
  257. if (strcmp(tp1->t_att[i].aa.ea_str, tp2->t_att[i].aa.ea_str))
  258. return(0);
  259. if (tp1->t_att[i].aa.ea_off!=tp2->t_att[i].aa.ea_off)
  260. return(0);
  261. break;
  262. }
  263. return(1);
  264. }
  265. distance(cindex) {
  266. register char *bp;
  267. register i;
  268. register token_p tp;
  269. int tokexp,tpl;
  270. int expsize,toksize,exact;
  271. int xsekt=0;
  272. int fromstackneeded=0;
  273. bp = &coderules[cindex];
  274. #ifndef NDEBUG
  275. if (*bp==DO_DLINE) {
  276. ++bp;
  277. getint(i,bp);
  278. }
  279. #endif
  280. switch( (*bp)&037 ) {
  281. default:
  282. return(stackheight==0 ? 0 : 100);
  283. case DO_MATCH:
  284. break;
  285. case DO_XXMATCH:
  286. xsekt++;
  287. case DO_XMATCH:
  288. xsekt++;
  289. break;
  290. }
  291. tpl= ((*bp++)>>5)&07;
  292. if (stackheight < tpl) {
  293. if (xsekt)
  294. return(MAXINT);
  295. fromstackneeded = tpl - stackheight;
  296. tpl = stackheight;
  297. } else
  298. if (stackheight != tpl && xsekt==2)
  299. return(MAXINT);
  300. exact=0;
  301. tp= &fakestack[stackheight-1];
  302. for (i=0;i<tpl;i++,tp--) {
  303. getint(tokexp,bp);
  304. if (!match(tp, &machsets[tokexp], 0)) {
  305. if (xsekt)
  306. return(MAXINT);
  307. expsize = ssize(tokexp);
  308. toksize = tsize(tp);
  309. if (expsize>toksize)
  310. return(100);
  311. if (expsize<toksize)
  312. return(99-i);
  313. /* Now we have a match in size, but it is not exact.
  314. Therefore, make sure that we can at least
  315. create it from the stack!
  316. */
  317. if (! from_stack(&machsets[tokexp])) {
  318. return MAXINT;
  319. }
  320. } else
  321. exact++;
  322. }
  323. for (;i<tpl+fromstackneeded;i++) {
  324. /* Make sure that any pattern we pick can be
  325. made from the stack
  326. */
  327. getint(tokexp,bp);
  328. if (! from_stack(&machsets[tokexp])) {
  329. return(MAXINT);
  330. }
  331. }
  332. if (exact==tpl && ! fromstackneeded) {
  333. if (xsekt)
  334. return(0);
  335. return(10-exact);
  336. }
  337. return(20-2*exact+fromstackneeded);
  338. }
  339. extern set_t unstackset;
  340. int from_stack(s1)
  341. register set_p s1;
  342. {
  343. register set_p s2 = &unstackset;
  344. register int i;
  345. for (i = 0; i < SETSIZE; i++) {
  346. if ((s1->set_val[i] & s2->set_val[i]) != 0) return 1;
  347. }
  348. return 0;
  349. }
  350. unsigned costcalc(cost) cost_t cost; {
  351. extern unsigned cc1,cc2,cc3,cc4;
  352. return(cost.ct_space*cc1/cc2 + cost.ct_time*cc3/cc4);
  353. }
  354. ssize(tokexpno) {
  355. return(machsets[tokexpno].set_size);
  356. }
  357. tsize(tp) register token_p tp; {
  358. if (tp->t_token==-1)
  359. return(machregs[tp->t_att[0].ar].r_size);
  360. return(tokens[tp->t_token].t_size);
  361. }
  362. #ifdef MAXSPLIT
  363. instsize(tinstno,tp) token_p tp; {
  364. inst_p inp;
  365. struct reginfo *rp;
  366. inp = &tokeninstances[tinstno];
  367. switch(inp->in_which) {
  368. default:
  369. assert(FALSE);
  370. case IN_COPY:
  371. assert(inp->in_info[0]<=1);
  372. #if MAXMEMBERS!=0
  373. if (inp->in_info[1]==0)
  374. #endif
  375. return(tsize(tp));
  376. #if MAXMEMBERS!=0
  377. else {
  378. assert(tp->t_token == -1);
  379. rp = &machregs[tp->t_att[0].ar];
  380. return(machregs[rp->r_members[inp->in_info[1]-1]].r_size);
  381. }
  382. #endif
  383. case IN_RIDENT:
  384. return(machregs[inp->in_info[0]].r_size);
  385. case IN_ALLOC:
  386. assert(FALSE); /* cannot occur in splitting coercion */
  387. case IN_DESCR:
  388. case IN_S_DESCR:
  389. case IN_D_DESCR:
  390. return(tokens[inp->in_info[0]].t_size);
  391. }
  392. }
  393. #endif /* MAXSPLIT */
  394. tref(tp,amount) register token_p tp; {
  395. register i;
  396. register byte *tdpb;
  397. if (tp->t_token==-1)
  398. chrefcount(tp->t_att[0].ar,amount,FALSE);
  399. else {
  400. tdpb= &tokens[tp->t_token].t_type[0];
  401. for(i=0;i<TOKENSIZE;i++)
  402. if (*tdpb++==EV_REG)
  403. chrefcount(tp->t_att[i].ar,amount,FALSE);
  404. }
  405. }
  406. #define MAXSAVE 10
  407. /* A few routines to save the top of the current stack,
  408. restore it and check whether a certain register is present in the
  409. saved stack
  410. */
  411. token_t aside[MAXSAVE] ;
  412. int aside_length = -1 ;
  413. save_stack(tp) register token_p tp ; {
  414. int i ;
  415. token_p tmp = &fakestack[stackheight - 1];
  416. /*aside_length = &fakestack[stackheight-1] -tp;
  417. This did not compile on Xenix V3.2: CODE GENERATION ERROR!
  418. */
  419. aside_length = tmp - tp;
  420. assert(aside_length<=MAXSAVE);
  421. #ifndef NDEBUG
  422. if (aside_length!=0 && Debug>1)
  423. fprintf(stderr,"Saving %d items from fakestack\n",aside_length);
  424. #endif
  425. for (i=1;i<=aside_length;i++)
  426. aside[i-1] = tp[i];
  427. stackheight -= aside_length;
  428. }
  429. in_stack(reg) {
  430. register token_p tp ;
  431. register i ;
  432. register tkdef_p tdp ;
  433. for ( i=0, tp=aside ; i<aside_length ; i++, tp++ )
  434. if (tp->t_token==-1) {
  435. if(tp->t_att[0].ar==reg)
  436. goto gotone ;
  437. } else {
  438. tdp = &tokens[tp->t_token];
  439. for(i=0;i<TOKENSIZE;i++)
  440. if (tdp->t_type[i]==EV_REG &&
  441. tp->t_att[i].ar==reg)
  442. goto gotone ;
  443. }
  444. return 0 ;
  445. gotone:
  446. #ifndef NDEBUG
  447. if ( Debug>2 )
  448. fprintf(stderr,"Register %d present on non-visible stack\n",
  449. reg ) ;
  450. #endif
  451. return 1 ;
  452. }
  453. rest_stack() {
  454. register int i ;
  455. assert(aside_length!= -1);
  456. #ifndef NDEBUG
  457. if (aside_length!=0 && Debug>1)
  458. fprintf(stderr,"Restoring %d items to fakestack(%d)\n",
  459. aside_length,stackheight);
  460. #endif
  461. for (i=0;i<aside_length;i++)
  462. fakestack[stackheight++] = aside[i];
  463. aside_length= -1 ;
  464. }
  465. #ifdef MAXSPLIT
  466. split(tp,ip,ply,toplevel) token_p tp; register int *ip; {
  467. register c2_p cp;
  468. token_t savestack[MAXSAVE];
  469. int ok;
  470. register i;
  471. int diff;
  472. token_p stp;
  473. int tpl;
  474. for (cp=c2coercs;cp->c2_texpno>=0; cp++) {
  475. if (!match(tp,&machsets[cp->c2_texpno],0))
  476. continue;
  477. ok=1;
  478. for (i=0; ok && i<cp->c2_nsplit;i++) {
  479. if (ip[i]==0)
  480. goto found;
  481. if (instsize(cp->c2_repl[i],tp) != ssize(ip[i]))
  482. ok=0;
  483. }
  484. goto found;
  485. }
  486. return(0);
  487. found:
  488. assert(stackheight+cp->c2_nsplit-1<MAXFSTACK);
  489. save_stack(tp);
  490. tpl = tokpatlen;
  491. tokpatlen = 1;
  492. codegen(&coderules[cp->c2_codep],ply,toplevel,MAXINT,0);
  493. tokpatlen = tpl;
  494. rest_stack();
  495. return(cp->c2_nsplit);
  496. }
  497. #endif /* MAXSPLIT */
  498. unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; register c3_p cp; {
  499. unsigned cost;
  500. int tpl; /* saved tokpatlen */
  501. save_stack(tp) ;
  502. tpl = tokpatlen;
  503. tokpatlen = 1;
  504. cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced);
  505. tokpatlen = tpl;
  506. rest_stack() ;
  507. nallreg = 0;
  508. return(cost);
  509. }
  510. unsigned stackupto(limit,ply,toplevel) token_p limit; {
  511. token_t savestack[MAXFSTACK];
  512. token_p stp;
  513. int i,diff;
  514. int tpl; /* saved tokpatlen */
  515. int nareg; /* saved nareg */
  516. int areg[MAXALLREG];
  517. register c1_p cp;
  518. register token_p tp;
  519. unsigned totalcost=0;
  520. struct reginfo *rp,**rpp;
  521. for (tp=fakestack;tp<=limit;limit--) {
  522. for (cp=c1coercs;cp->c1_texpno>=0; cp++) {
  523. if (match(tp,&machsets[cp->c1_texpno],cp->c1_expr)) {
  524. if (cp->c1_prop>=0) {
  525. for (rpp=reglist[cp->c1_prop];
  526. (rp = *rpp)!=0 &&
  527. getrefcount((int)(rp-machregs), TRUE)!=0;
  528. rpp++)
  529. ;
  530. if (rp==0)
  531. continue;
  532. /* look for other possibility */
  533. }
  534. stp = &fakestack[stackheight-1];
  535. diff = stp -tp;
  536. assert(diff<=MAXFSTACK);
  537. for (i=1;i<=diff;i++)
  538. savestack[i-1] = tp[i];
  539. stackheight -= diff;
  540. tpl = tokpatlen;
  541. tokpatlen = 1;
  542. nareg = nallreg;
  543. for (i=0;i<nareg;i++)
  544. areg[i] = allreg[i];
  545. if (cp->c1_prop>=0) {
  546. nallreg=1; allreg[0] = rp-machregs;
  547. chrefcount(allreg[0],1,FALSE);
  548. } else
  549. nallreg=0;
  550. totalcost+= codegen(&coderules[cp->c1_codep],ply,toplevel,MAXINT,0);
  551. tokpatlen = tpl;
  552. for (i=0;i<diff;i++) {
  553. fakestack[stackheight] = savestack[i];
  554. stackheight++;
  555. /* not cobmined in one statement;
  556. this poor Xenix C compiler sometimes
  557. gets failed assertions when you do
  558. that!
  559. */
  560. }
  561. nallreg=nareg;
  562. for (i=0;i<nareg;i++)
  563. allreg[i] = areg[i];
  564. goto contin;
  565. }
  566. }
  567. assert(FALSE);
  568. contin: ;
  569. }
  570. return(totalcost);
  571. }
  572. c3_p findcoerc(tp,tep) token_p tp; set_p tep; {
  573. register c3_p cp;
  574. token_t rtoken;
  575. register i;
  576. register struct reginfo **rpp;
  577. for (cp=c3coercs;cp->c3_texpno>=0; cp++) {
  578. if (tp!=(token_p) 0) {
  579. if (cp->c3_texpno==0)
  580. continue;
  581. if (!match(tp,&machsets[cp->c3_texpno],cp->c3_expr))
  582. continue;
  583. } else {
  584. if (cp->c3_texpno!=0)
  585. continue;
  586. }
  587. if (cp->c3_prop<0) { /* no reg needed */
  588. cinstance(cp->c3_repl,&rtoken,tp,0);
  589. if (match(&rtoken,tep,0))
  590. return(cp);
  591. } else {
  592. curreglist = (rl_p) myalloc(sizeof (rl_t));
  593. curreglist->rl_n = 0;
  594. for (rpp=reglist[cp->c3_prop];*rpp;rpp++) {
  595. i = *rpp - machregs;
  596. cinstance(cp->c3_repl,&rtoken,tp,i);
  597. if (match(&rtoken,tep,0))
  598. curreglist->rl_list[curreglist->rl_n++] = i;
  599. }
  600. if (curreglist->rl_n != 0)
  601. return(cp);
  602. myfree((string)curreglist);
  603. }
  604. }
  605. return(0); /* nothing found */
  606. }
  607. itokcost() {
  608. register tkdef_p tdp;
  609. for(tdp=tokens+1;tdp->t_size!=0;tdp++)
  610. tdp->t_cost.ct_space = costcalc(tdp->t_cost);
  611. }
  612. /*VARARGS1*/
  613. error(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
  614. fprintf(stderr,"Error: ");
  615. fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
  616. fprintf(stderr,"\n");
  617. #ifdef TABLEDEBUG
  618. ruletrace();
  619. #endif
  620. out_finish();
  621. exit(-1);
  622. }
  623. /*VARARGS1*/
  624. fatal(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
  625. fprintf(stderr,"Fatal: ");
  626. fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
  627. fprintf(stderr,"\n");
  628. #ifdef TABLEDEBUG
  629. ruletrace();
  630. #endif
  631. out_finish();
  632. abort();
  633. exit(-1);
  634. }
  635. #ifdef TABLEDEBUG
  636. ruletrace() {
  637. register i;
  638. extern int tablelines[MAXTDBUG];
  639. extern int ntableline;
  640. extern char *tablename;
  641. fprintf(stderr,"Last code rules used\n");
  642. i=ntableline-1;
  643. while(i!=ntableline) {
  644. if (i<0)
  645. i += MAXTDBUG;
  646. if (tablelines[i]!=0)
  647. fprintf(stderr,"\%d: \"%s\", line %d\n",i,tablename,tablelines[i]);
  648. i--;
  649. }
  650. }
  651. #endif
  652. #ifndef NDEBUG
  653. badassertion(asstr,file,line) char *asstr, *file; {
  654. fatal("\"%s\", line %d:Assertion \"%s\" failed",file,line,asstr);
  655. }
  656. #endif