#include        <stdio.h>
#include        "c.h"
#include        "expr.h"
#include        "gen.h"
#include        "cglbdec.h"

/*
 *68000 C compiler
 *
 *Copyright 1984, 1985, 1986 Matthew Brandt.
 *  all commercial rights reserved.
 *
 *This compiler is intended as an instructive tool for personal use. Any
 *use for profit without the written consent of the author is prohibited.
 *
 *This compiler may be distributed freely for non-commercial use as long
 *as this notice stays intact. Please forward any enhancements or questions
 *to:
 *
 *Matthew Brandt
 *Box 920337
 *Norcross, Ga 30092
 */

extern char 	*litlate();
extern SYM	*search();
extern struct snode *compound();

/*      function compilation routines           */

funcbody(sp)
/*
 *      funcbody starts with the current symbol being either
 *      the first parameter id or the begin for the local
 *      block. If begin is the current symbol then funcbody
 *      assumes that the function has no parameters.
 */
SYM     *sp;
{       char    *names[20];             /* 20 parameters maximum */
        int     nparms, poffset, i, size;
        SYM     *sp1, *makeint();
        global_flag = 0;
        poffset = 8;            /* size of return block */
        nparms = 0;
        if(lastst == id) {              /* declare parameters */
                while(lastst == id) {
                        names[nparms++] = litlate(lastid);
                        getsym();
                        if( lastst == comma)
                                getsym();
                        else
                                break;
                        }
                needpunc(closepa);
                dodecl(sc_member);      /* declare parameters */
                for(i = 0;i < nparms;++i) {
                        if( (sp1 = search(names[i],lsyms.head)) == 0)
                                sp1 = makeint(names[i]);
			if ( sp1->tp->type == bt_pointer )
			   size = 4;
			else
			   size = sp1->tp->size;
			sp1->value.i = poffset;
			if( size < 4 )
			   {
				if ( size == 1)
				  ++sp1->value.i;
				poffset += 2;
			    }
			else
			   poffset += size;
			sp1->storage_class = sc_auto;
		}
        }
        if(lastst != begin)
                error(ERR_BLOCK);
        else    {
                cseg();
                gen_strlab(sp->name);
                block();
                funcbottom();
                }
        global_flag = 1;
}

SYM     *makeint(name)
char    *name;
{       SYM     *sp;
        TYP     *tp;
        sp = xalloc(sizeof(SYM));
        tp = xalloc(sizeof(TYP));
        tp->type = bt_long;
        tp->size = 4;
        tp->btp = tp->lst.head = 0;
        tp->sname = 0;
        sp->name = name;
        sp->storage_class = sc_auto;
        sp->tp = tp;
        insert(sp,&lsyms);
        return sp;
}

check_table(head)
SYM     *head;
{      char *err;

       err = (char *)"*** UNDEFINED LABEL - %s\n";
       while( head != 0 ) 
	 {
           if( head->storage_class == sc_ulabel )
	     {
		if ( Options.List )
                   fprintf(list, err, head->name);
		printf( err, head->name );
	     }
           head = head->next;
	 }
}

funcbottom()
{       nl();
        check_table(lsyms.head);
        lc_auto = 0;
	if ( Options.List )
           fprintf(list,"\n\n*** local symbol table ***\n\n");
        list_table(&lsyms,0);
	if ( Options.List )
           fprintf(list,"\n\n\n");
        release_local();        /* release local symbols */
}

block()
{       needpunc(begin);
        dodecl(sc_auto);
cseg();
        genfunc(compound());
        flush_peep();
}

