home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / FUNC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-06  |  8.0 KB  |  306 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, 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 sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include        "expr.h"
  23. #include        "c.h"
  24. #include        "gen.h"
  25. #include        "cglbdec.h"
  26.  
  27. extern TYP *head, *tail;
  28. extern char declid[100];
  29. extern int prm_listfile;
  30. extern int prm_cplusplus;
  31.  
  32. extern int goodcode;
  33.  
  34. TABLE oldlsym;
  35.  
  36. static int skm_func[] = { closepa,begin,semicolon,0 };
  37.  
  38. SYM *currentfunc=0;
  39.  
  40. /*      function compilation routines           */
  41. void funcini(void)
  42. {
  43.     currentfunc = 0;
  44. }
  45. void declfuncarg(void)
  46. {       char    *names[50];             /* 50 parameters maximum */
  47.         int     nparms, poffset, i, inline;
  48.         SYM     *sp1, *sp2, *spsave[50], *oldargs=0;
  49.                 TYP *temp, *temp1;
  50.                 char oldeclare[100];
  51.                 char *nm;
  52.         poffset = 0;            /* size of return block */
  53.         nparms = 0;
  54.                 temp = head;
  55.                 temp1 = tail;
  56.                 if (!prm_cplusplus) {
  57.                     sp2 = gsearch(declid);
  58.                     if (sp2) {
  59.                         oldargs = sp2->tp->lst.head;
  60.                     }
  61.                 }
  62.                 temp->lst.head = temp->lst.tail = 0;
  63.                 if (lastst == kw_void) {
  64.                     getsym();
  65.                     if (lastst != closepa) {
  66.                         backup(lastst);
  67.                         lastst = kw_void;
  68.                     }
  69.                     else {
  70.                         temp->lst.head = (SYM *)-1;
  71.                         getsym();
  72.                       goto verify;
  73.                     }
  74.                 }
  75.                 else
  76.                     if (lastst == closepa) {
  77.                         getsym();
  78.                         goto verify;
  79.                     }
  80.                 strcpy(oldeclare,declid);
  81.         if(!prm_cplusplus && lastst == id && 
  82.                             ((sp1 = search(nm=litlate(lastid),&gsyms)) ==0 || sp1->storage_class != sc_type) 
  83.                             && ((sp1 = search(nm,&lsyms)) ==0 || sp1->storage_class != sc_type)) {
  84.               /* declare parameters */
  85.                     global_flag = 0;
  86.                 while(lastst == id) {
  87.                         names[nparms++] = nm;
  88.                         getsym();
  89.                         if( lastst == comma)
  90.                                 getsym();
  91.                         else
  92.                                 break;
  93.                         }
  94.                     global_flag = 1;
  95.                 needpunc(closepa,skm_func);
  96.                 doargdecl(sc_member,0,0,&temp->lst,inline = FALSE);      /* declare parameters */
  97.                 }
  98.                 else {
  99.                     doargdecl(sc_member,names,&nparms,&temp->lst,inline = TRUE);
  100.                     needpunc(closepa,skm_func);
  101.                 }
  102.                 strcpy(declid,oldeclare);
  103.                 if (temp->btp->type == bt_struct || temp->btp->type == bt_union)
  104.                     poffset += 4;
  105.         for(i = 0;i < nparms;++i) {
  106.             if ((sp1 = search(names[i],&temp->lst)) == 0 && !inline)
  107.               sp1 = makeint(litlate(names[i]),&temp->lst);
  108.                         if (sp1->tp)
  109.                             sp1->tp->uflags |= UF_DEFINED;
  110.                         spsave[i] = sp1;
  111.                         if( sp1->tp->size < 4 )
  112.                         {
  113. #ifdef i386
  114.                             sp1->value.i = poffset;
  115. #else
  116.                             sp1->value.i = poffset + (4 - sp1->tp->size);
  117. #endif
  118.                             poffset += 4;
  119.                         }
  120.                         else
  121.                         {
  122.                             sp1->value.i = poffset;
  123.                             poffset += sp1->tp->size;
  124.                         }
  125.                         sp1->storage_class = sc_auto;
  126.                 }
  127.                 if (!inline) {
  128.                     temp->lst.head = temp->lst.tail = 0;
  129.                     for (i=0; i < nparms; i++)
  130.                         insert(spsave[i],&temp->lst);
  131.                 }
  132.                 if (prm_cplusplus && temp->lst.head == 0)
  133.                     temp->lst.head = (SYM *) -1; /* () is equiv to (void) in cpp */
  134. verify:
  135.                 head = temp;
  136.                 tail = temp1;
  137.                 if (prm_cplusplus)
  138.                     return;
  139.                 
  140.                 if (oldargs && head->sname) {
  141.                     SYM *newargs = head->lst.head;
  142.                     while (oldargs && newargs) {
  143.                         if (!checktype(oldargs->tp,newargs->tp))
  144.                             gensymerror(ERR_ARGMISMATCH,newargs->name);
  145.                         if (oldargs == (SYM *)-1 || newargs == (SYM *)-1)
  146.                             break;
  147.                         oldargs = oldargs->next;
  148.                         newargs = newargs->next;
  149.                     }
  150.                     if (oldargs && oldargs != (SYM *)-1)
  151.                         gensymerror(ERR_ARGLENSHORT,head->sname);
  152.                     if (newargs && newargs != (SYM *)-1)
  153.                         gensymerror(ERR_ARGLENLONG,head->sname);
  154.                 }
  155.                 if (sp2 && !checktype(sp2->tp,head))
  156.                     gensymerror(ERR_FUNCMISMATCH,head->sname);
  157. }
  158. void check_funcused(TABLE *oldlsym, TABLE *lsyms)
  159. {
  160.     /* oldlsym Must BE 0 at the end of a function */
  161.     SYM *sym1;
  162.     if (oldlsym && oldlsym->head == lsyms->head) {
  163.         return;
  164.     }
  165.     sym1 = lsyms->head;
  166.     while (sym1 && (!oldlsym || sym1 != oldlsym->head)) {
  167.         if (sym1->tp->type != bt_func && sym1->tp->type != bt_ifunc
  168.                 && sym1->storage_class != sc_type) {
  169.             if (!(sym1->tp->uflags & UF_USED)) {
  170.                 if (sym1->storage_class == sc_label) {
  171.                     if (!oldlsym)
  172.                         gensymerror(ERR_UNUSEDLABEL,sym1->name);
  173.                 }
  174.                 else gensymerror(ERR_SYMUNUSED,sym1->name);
  175.             }
  176.             if (sym1->tp->uflags & UF_ASSIGNED)
  177.                 gensymerror(ERR_SYMASSIGNED,sym1->name);
  178.             if (!oldlsym && sym1->storage_class == sc_ulabel)
  179.                 gensymerror(ERR_UNDEFLABEL,sym1->name);
  180.         }
  181.         sym1 = sym1->next;
  182.     }
  183. }
  184. void funcbody(SYM *sp)
  185. /*
  186.  */
  187. {
  188.                 SYM *sp1 = sp->tp->lst.head, *sp2;
  189.         global_flag = 0;
  190.                 if (sp1 != (SYM *)-1) {
  191.                     while (sp1) {
  192.                         if (sp1->name[0] != '*') {
  193.                             sp2 = xalloc(sizeof(SYM));
  194.                             memcpy(sp2,sp1,sizeof(SYM));
  195.                             insert(sp2,&lsyms);
  196.                         }
  197.                         sp1 = sp1->next;
  198.                     }
  199.                 }
  200.                 currentfunc = sp;
  201.         cseg();
  202.            gen_strlab(sp->name);
  203.                 goodcode &= ~GF_RETURN;
  204.         block();
  205.                 check_funcused(0,&lsyms);
  206.                 if (sp->tp->btp->type != bt_void && !(goodcode &GF_RETURN)) 
  207.                     generror(ERR_FUNCRETVAL,0,0);
  208.         nl();
  209.                 currentfunc = 0;
  210.         lc_auto = lc_maxauto = 0;
  211.                 if (prm_listfile) {
  212.           fprintf(listFile,"\n\n*** local symbol table ***\n\n");
  213.           list_table(&lsyms,0);
  214.           fprintf(listFile,"\n\n\n");
  215.                 }
  216.  
  217.         release_local();        /* release local symbols */
  218.         global_flag = 1;
  219. }
  220.  
  221. SYM     *makeint(char *name, TABLE *table)
  222. {       SYM     *sp;
  223.         TYP     *tp;
  224.                 global_flag++;
  225.         sp = xalloc(sizeof(SYM));
  226.         tp = xalloc(sizeof(TYP));
  227.                 global_flag--;
  228.         tp->type = bt_long;
  229.         tp->size = 4;
  230.         tp->btp = tp->lst.head = 0;
  231.         tp->sname = 0;
  232.         sp->name = name;
  233.         sp->storage_class = sc_auto;
  234.         sp->tp = tp;
  235.         insert(sp,table);
  236.         return sp;
  237. }
  238.  
  239. void block(void)
  240. {       
  241.                 SNODE *snp3;
  242.                 lastst = 0;
  243.                 snp3 = snp_line();
  244.                 lastst = begin;
  245.                 needpunc(begin,0);
  246.         dodecl(sc_auto);
  247.                 lc_maxauto = lc_auto;
  248.                 cseg();
  249.                 if (snp3)
  250.                     snp3->next = compound();
  251.                 else
  252.                     snp3 = compound();
  253.                 if (lc_maxauto < lc_auto) {
  254.                     lc_maxauto = lc_auto;
  255.                 }
  256.                 lc_maxauto +=3;
  257.                 lc_maxauto &= 0xfffffffcL;
  258.         genfunc(snp3);
  259.         flush_peep();
  260. }
  261. void gather_labels(TABLE *oldlsym, TABLE *lsyms)
  262. {
  263.     if (oldlsym->head == lsyms->head) {
  264.         return;
  265.     }
  266.     else {
  267.         SYM *sp = lsyms->head,*r = oldlsym->head;
  268.         while (sp && sp != r) {
  269.             SYM *q = sp->next;
  270.             if (sp->storage_class == sc_label || sp->storage_class == sc_ulabel) {
  271.                 if (!oldlsym->head) {
  272.                     oldlsym->head = oldlsym->tail = sp;
  273.                     lsyms->tail = lsyms->tail->next = sp;
  274.                 }
  275.                 else {
  276.                     oldlsym->tail->next = sp;
  277.                     sp->next = 0;
  278.                     oldlsym->tail = sp;
  279.                 }
  280.             }
  281.             sp = q;
  282.         }
  283.         if (oldlsym->tail)
  284.             oldlsym->tail->next = 0;
  285.     }
  286. }
  287. SNODE *compoundblock(void)
  288. {
  289.     SNODE *snp;
  290.     TABLE oldoldlsym;
  291.     int oldlcauto = lc_auto;
  292.     oldoldlsym = oldlsym;
  293.     oldlsym = lsyms;
  294.     dodecl(sc_auto);
  295.     if (lc_auto > lc_maxauto) {
  296.         lc_maxauto = lc_auto;
  297.     }
  298.     cseg();
  299.     snp = compound();
  300.     check_funcused(&oldlsym,&lsyms);
  301.     gather_labels(&oldlsym,&lsyms);
  302.     lc_auto = oldlcauto;
  303.     lsyms = oldlsym;
  304.     oldlsym.head = oldoldlsym.head;
  305.     return(snp);
  306. }