/* declarations.c */
#include "declarations.h"
#include "parse.h"
#include "stdlib.h"
#include "vars.h"

/*
	Declare a static variable (i.e. define for use).
	Makes an entry in the symbol table so subsequent
	references can call symbol by name.
*/
/** globals (statics) are found outside a function block **/
/** this fn is called when a TYPE `int or `char is found **/
void declstatic(int typ)					/* typ is cchar or cint */
{
	int k,j;
	char sname[NAMESIZE]; 					/** 1st mention of sname array **/
	/** sname is an auto, on stack processing array. **/

	while (1) /** loop while comma'd **/
	{
		while (1)
		{  /** is_identifier() gets & validates identifier **/
			if (endst()) return;		/* do line */
			k = 1;				/* assume 1 element */

			if (match("*"))			/* pointer ? */
				j = POINTER;		/* yes */
			else
				j = VARIABLE;		/* no */

			if (is_identifier(sname) == 0)	/* name ok? */
				illname();		/* no... const, */
			if(findstatic(sname))		/* already there? */
				multidef(sname);
			if (match("["))			/* array? */
			{
				k = mk_subscript(); 	/* get size */
				if (k) j = ARRAY;	/* !0=array */
				else j = POINTER; 	/* 0=ptr, a[] */
			}
			addstatic(sname,j,typ,k); 	/* add symbol */
			break;
		}
		if (match(",") == 0)
			return;				/* more? */
	}
}

/* Declare auto variables (i.e. define for use). */
/* Works just like "declstatic" but modifies machine stack */
/* and adds symbol table entry with appropriate stack offset to find it again */
/** called when symbol is an automatic **/
void declauto(int typ)					/* typ is cchar or cint */
{
	int k,j;
	char sname[NAMESIZE];

	while (1)
	{
		while (1)
		{ 
			/** is_identifier() gets & validates identifier **/
			if (endst())
				return;

			if (match("*"))
				j = POINTER;
			else
				j = VARIABLE;

			if (is_identifier(sname) == 0)
				illname();		/** const **/

			if (findauto(sname))
				multidef(sname);

			if (match("["))
			{
				k = mk_subscript();
				if (k)
				{
					/** if int, double size of char **/
					j = ARRAY;
					if (typ == CINT)
						k = 4 * k;
				}
				else
				{
					j = POINTER;
					k = 4;		/** was 2 **/
				}
			}
			else
				if ((typ == CCHAR) & (j != POINTER))
					k = 1;
				else
					k = 4;		/** was 4 **/

			/* change machine stack */
			/** negative from activation frame, sp, for auto **/

			Msp = Msp - k;
			addauto(sname,j,typ,Msp);
			break;
		}
		if (match(",") == 0)
			return;
	}
}