FUNC.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:10k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include "list.h"
  24. #include        "expr.h"
  25. #include        "c.h"
  26. #include "errors.h"
  27. extern int ispascal;
  28. extern FILE *listFile;
  29. extern enum e_sym lastst;
  30. extern long firstlabel,nextlabel;
  31. extern char lastid[];
  32. extern TABLE gsyms,lsyms;
  33. extern int global_flag;
  34. extern int stdaddrsize, stdretblocksize;
  35. extern int stackadd,stackmod;
  36. extern TYP *head, *tail;
  37. extern char declid[100];
  38. extern int prm_listfile;
  39. extern int prm_cplusplus;
  40. extern int stdintsize;
  41. extern int goodcode;
  42. extern int prm_linkreg;
  43. extern TABLE lsyms;
  44. int block_nesting;
  45. TABLE oldlsym;
  46. LIST *varlisthead,*varlisttail;
  47. static int skm_func[] = { closepa,begin,semicolon,0 };
  48. SYM *currentfunc=0;
  49. /*      function compilation routines           */
  50. void funcini(void)
  51. {
  52. currentfunc = 0;
  53. }
  54. void declfuncarg(int isint)
  55. {       char    *names[50];             /* 50 parameters maximum */
  56.         int     nparms, poffset, i, isinline;
  57.         SYM     *sp1, *sp2, *spsave[50], *oldargs=0;
  58. TYP *temp, *temp1;
  59. char oldeclare[100];
  60. char *nm;
  61. if (prm_linkreg && !isint)
  62.          poffset = stdretblocksize;            /* size of return block */
  63. else
  64.          poffset = 0;            /* size of return block */
  65.         nparms = 0;
  66. temp = head;
  67. temp1 = tail;
  68. if (!prm_cplusplus) {
  69. sp2 = gsearch(declid);
  70. if (sp2) {
  71. oldargs = sp2->tp->lst.head;
  72. }
  73. }
  74. temp->lst.head = temp->lst.tail = 0;
  75. if (lastst == kw_void) {
  76. getsym();
  77. if (lastst != closepa) {
  78. backup(lastst);
  79. lastst = kw_void;
  80. }
  81. else {
  82. temp->lst.head = (SYM *)-1;
  83. getsym();
  84.   goto verify;
  85. }
  86. }
  87. else
  88. if (lastst == closepa) {
  89. getsym();
  90. goto verify;
  91. }
  92. strcpy(oldeclare,declid);
  93.         if(!prm_cplusplus && lastst == id && 
  94. ((sp1 = search(nm=litlate(lastid),&gsyms)) ==0 || sp1->storage_class != sc_type) 
  95. && ((sp1 = search(nm,&lsyms)) ==0 || sp1->storage_class != sc_type)) {
  96.               /* declare parameters */
  97. global_flag = 0;
  98.                 while(lastst == id) {
  99.                         names[nparms++] = nm;
  100.                         getsym();
  101.                         if( lastst == comma)
  102.                                 getsym();
  103.                         else
  104.                                 break;
  105.                         }
  106. global_flag = 1;
  107.                 needpunc(closepa,skm_func);
  108.                 doargdecl(sc_member,0,0,&temp->lst,isinline = FALSE);      /* declare parameters */
  109. }
  110. else {
  111. doargdecl(sc_member,names,&nparms,&temp->lst,isinline = TRUE);
  112. needpunc(closepa,skm_func);
  113. }
  114. strcpy(declid,oldeclare);
  115. if (!ispascal && 
  116. (temp->btp->type == bt_struct || temp->btp->type == bt_union))
  117. poffset += stdaddrsize;
  118.         for(i = 0;i < nparms;++i) {
  119.             if ((sp1 = search(names[i],&temp->lst)) == 0 && !isinline)
  120.               sp1 = makeint(litlate(names[i]),&temp->lst);
  121. if (sp1->tp)
  122. sp1->tp->uflags |= UF_DEFINED;
  123. sp1->funcparm = TRUE;
  124. spsave[i] = sp1;
  125.             sp1->storage_class = sc_auto;
  126. }
  127. /*
  128.  * parameter allocation.  Have to do things backwards if this
  129.  * function has the _pascal declarator
  130.  */
  131. if (!ispascal)
  132.          for(i = 0;i < nparms;++i) {
  133. sp1 = spsave[i];
  134. if( sp1->tp->type != bt_pointer && sp1->tp->size < stdintsize)
  135. {
  136. sp1->value.i = poffset + funcvaluesize(sp1->tp->size);
  137. poffset += stdintsize;
  138. }
  139. else
  140. {
  141. sp1->value.i = poffset;
  142. if (sp1->tp->type == bt_pointer)
  143. poffset += stdaddrsize;
  144. else
  145. poffset += sp1->tp->size;
  146. }
  147. }
  148. else
  149.          for(i = nparms-1;i >=0;--i) {
  150. sp1 = spsave[i];
  151. if( sp1->tp->type != bt_pointer && sp1->tp->size < stdintsize)
  152. {
  153. sp1->value.i = poffset + funcvaluesize(sp1->tp->size);
  154. poffset += stdintsize;
  155. }
  156. else
  157. {
  158. sp1->value.i = poffset;
  159. if (sp1->tp->type == bt_pointer)
  160. poffset += stdintsize;
  161. else
  162. poffset += sp1->tp->size;
  163. }
  164. }
  165. if (!isinline) {
  166. temp->lst.head = temp->lst.tail = 0;
  167. for (i=0; i < nparms; i++)
  168. insert(spsave[i],&temp->lst);
  169. }
  170. #ifdef CPLUSPLUS
  171. if (prm_cplusplus && temp->lst.head == 0)
  172. temp->lst.head = (SYM *) -1; /* () is equiv to (void) in cpp */
  173. #endif
  174. verify:
  175. head = temp;
  176. tail = temp1;
  177. #ifdef CPLUSPLUS
  178. if (prm_cplusplus)
  179. return;
  180. #endif
  181. if (oldargs && head->sname) {
  182. SYM *newargs = head->lst.head;
  183. while (oldargs && newargs) {
  184. if (!checktype(oldargs->tp,newargs->tp))
  185. gensymerror(ERR_ARGMISMATCH,newargs->name);
  186. if (oldargs == (SYM *)-1 || newargs == (SYM *)-1)
  187. break;
  188. oldargs = oldargs->next;
  189. newargs = newargs->next;
  190. }
  191. if (oldargs && oldargs != (SYM *)-1)
  192. gensymerror(ERR_ARGLENSHORT,head->sname);
  193. if (newargs && newargs != (SYM *)-1)
  194. gensymerror(ERR_ARGLENLONG,head->sname);
  195. }
  196. if (sp2 && !checktype(sp2->tp->btp,head->btp))
  197. gensymerror(ERR_DECLMISMATCH,sp2->name);
  198. }
  199. void check_funcused(TABLE *oldlsym, TABLE *lsyms)
  200. {
  201. /* oldlsym Must BE 0 at the end of a function */
  202. SYM *sym1;
  203. if (oldlsym && oldlsym->head == lsyms->head) {
  204. return;
  205. }
  206. sym1 = lsyms->head;
  207. while (sym1 && (!oldlsym || sym1 != oldlsym->head)) {
  208. if (sym1->tp->type != bt_func && sym1->tp->type != bt_ifunc
  209. && sym1->storage_class != sc_type) {
  210. if (!(sym1->tp->uflags & UF_USED)) {
  211. if (sym1->storage_class == sc_label) {
  212. if (!oldlsym)
  213. gensymerror(ERR_UNUSEDLABEL,sym1->name);
  214. }
  215. else gensymerror(ERR_SYMUNUSED,sym1->name);
  216. }
  217. if (sym1->tp->uflags & UF_ASSIGNED)
  218. gensymerror(ERR_SYMASSIGNED,sym1->name);
  219. if (!oldlsym && sym1->storage_class == sc_ulabel)
  220. gensymerror(ERR_UNDEFLABEL,sym1->name);
  221. }
  222. sym1 = sym1->next;
  223. }
  224. }
  225. void funcbody(SYM *sp)
  226. /*
  227.  */
  228. {
  229. SYM *sp1 = sp->tp->lst.head, *sp2;
  230. varlisthead = 0;
  231.         global_flag = 0;
  232. if (sp1 != (SYM *)-1) {
  233. while (sp1) {
  234. if (sp1->name[0] != '*') {
  235. sp2 = xalloc(sizeof(SYM));
  236. memcpy(sp2,sp1,sizeof(SYM));
  237. insert(sp2,&lsyms);
  238. }
  239. sp1 = sp1->next;
  240. }
  241. }
  242. currentfunc = sp;
  243.         cseg();
  244. firstlabel = nextlabel;
  245. if (sp->storage_class == sc_global)
  246. globaldef(sp);
  247. goodcode &= ~GF_RETURN;
  248.         block();
  249. check_funcused(0,&lsyms);
  250. if (prm_listfile && varlisthead) {
  251. LIST *q = varlisthead;
  252.        fprintf(listFile,"nn*** local symbol table ***nn");
  253. while (q) {
  254. SYM *sp = q->data;
  255. while (sp) {
  256. list_var(sp,0);
  257. sp = sp->next;
  258. }
  259. q = q->link;
  260. }
  261. }
  262. if (sp->tp->btp->type != bt_void && !(goodcode &GF_RETURN)) 
  263. generror(ERR_FUNCRETVAL,0,0);
  264.         nl();
  265. currentfunc = 0;
  266.         release_local();        /* release local symbols */
  267.    lsyms.head = 0;
  268. oldlsym.head = oldlsym.tail = 0;
  269.         global_flag = 1;
  270. }
  271. SYM     *makeint(char *name, TABLE *table)
  272. {       SYM     *sp;
  273.         TYP     *tp;
  274. global_flag++;
  275.         sp = xalloc(sizeof(SYM));
  276.         tp = xalloc(sizeof(TYP));
  277. global_flag--;
  278.         tp->type = bt_long;
  279.         tp->size = 4;
  280.         tp->btp = tp->lst.head = 0;
  281.         tp->sname = 0;
  282.         sp->name = name;
  283.         sp->storage_class = sc_auto;
  284.         sp->tp = tp;
  285.         insert(sp,table);
  286.         return sp;
  287. }
  288. void addblocklist(SYM *sp)
  289. {
  290. LIST *l;
  291. if (!sp) return;
  292. l = xalloc(sizeof(LIST));
  293. l->link = 0;
  294. l->data = sp;
  295. if (varlisthead)
  296. varlisttail = varlisttail->link = l;
  297. else
  298. varlisthead = varlisttail = l;
  299. }
  300. void block(void)
  301. {       
  302. SNODE *snp3;
  303. block_nesting = 1;
  304. lastst = 0;
  305. snp3 = snp_line();
  306. lastst = begin;
  307. needpunc(begin,0);
  308.         dodecl(sc_auto);
  309. cseg();
  310. if (snp3)
  311. snp3->next = compound();
  312. else
  313. snp3 = compound();
  314. addblocklist(lsyms.head);
  315.         genfunc(snp3);
  316.         flush_peep();
  317. }
  318. void gather_labels(TABLE *oldlsym, TABLE *lsyms)
  319. {
  320. TABLE sym;
  321. sym.head = 0;
  322. if (oldlsym->head == lsyms->head) {
  323. return;
  324. }
  325. else {
  326. SYM *sp = lsyms->head,*r = oldlsym->head;
  327. lsyms->head = 0;
  328. while (sp && sp != r) {
  329. SYM *q = sp->next;
  330. sp->next = 0;
  331. if (sp->storage_class == sc_label || sp->storage_class == sc_ulabel) {
  332. if (!oldlsym->head) {
  333. oldlsym->head = oldlsym->tail = sp;
  334. }
  335. else {
  336. oldlsym->tail->next = sp;
  337. oldlsym->tail = sp;
  338. }
  339. }
  340. else
  341. if (!lsyms->head)
  342. lsyms->head = lsyms->tail = sp;
  343. else
  344. lsyms->tail = lsyms->tail->next = sp;
  345. sp = q;
  346. }
  347. if (oldlsym->tail)
  348. oldlsym->tail->next = 0;
  349. }
  350. }
  351. SNODE *compoundblock(void)
  352. {
  353. SNODE *snp;
  354. TABLE oldoldlsym;
  355. SYM *q;
  356. block_nesting++;
  357. oldoldlsym = oldlsym;
  358. oldlsym = lsyms;
  359. dodecl(sc_auto);
  360. cseg();
  361. snp = compound();
  362. check_funcused(&oldlsym,&lsyms);
  363. q = lsyms.head;
  364. gather_labels(&oldlsym,&lsyms);
  365. while (q && q->next != oldlsym.head)
  366. q = q->next;
  367. if (q) 
  368. q->next = 0;
  369. addblocklist(lsyms.head);
  370. lsyms = oldlsym;
  371. oldlsym.head = oldoldlsym.head;
  372. block_nesting--;
  373. return(snp);
  374. }