/*
 * MEM.H -- Define the dictionary, the stack, indices of various kinds, 
 * and ways of converting the indices into true address pointers.
 *
 * Structures that live within the dictionary may use pointers to
 * point at other structures (such as the task and parameter chains) but
 * things that simply point AT the dictionary and that move around are indices
 * into what appears to be the array of unsigned integers called dictionary.
 * This is to facilitate putting things of disparate types into the array.
 */

/* bytes per int;
 * typically used when putting things in the dictionary like strings, operands
 * and codeentries. also, the pc must be advanced in ints.
 *
 * N.B. it is FUNDAMENTALLY ASSUMED throughout that an int is large enough to
 * hold a pointer to an int. Further, although casts are used carefully as
 * much as possible and so a good compiler will do much of the work,
 * it is also pretty much taken for granted that all pointers are the
 * same size, in particular that (char *) is the same size as (unsigned *).
 */

#define	BPI	(sizeof (memel))
#define	btoi(x)	((int)((((x)+BPI-1)/BPI))) /* avoid promotion to unsigned */
#define dtoi(x) ((int)(sizeof(double))/(sizeof(memel))*x)

/* the dictionary starts at the top of the system break and grows as needed.
 * if this is hard to do on your os, declare it as a genuine array and
 *   forever fix the value of maxd by initializing them in their declarations
 *   in compile.c. see machdep.c.
 */


extern memel *dictionary;    /* base of the dictionary; never moves */

/* ----------
 * convert a dictionary index into a structure pointer.
 * also, dereference a pointer to a dictionary index.
 */

#define	reference(sname,index)	((struct sname *) (&dictionary[index]))
/*
#define	dereference(ptr) \
(((unsigned)(char *)(ptr) - (unsigned)(char *)(dictionary))/BPI)
*/
#define	dereference(ptr) \
(((char *)(ptr) - (char *)(dictionary))/BPI)

/* ----------
 * Generic push/pop memory routines.  Can be used to push/pop any integer type
 * argument regardless of size, so long as it fits in a memel.
 */
#define push(v)		pushmem((memel)v)
#define ppush(v)	ppushmem((memel)v)
#define pop		popmem

/* ----------
 * convert a dictionary index into a genuine address; type will be 
 * the type of dictionary.
 */

#define	daddr(x)			(&dictionary[x])

/* ----------
 * maxd: smallest d. index that is out of range and will give mem fault if
 *	referenced. commonly referred to as the "system break".
 * topd: next d. index available for use, ie, it is the smallest d. index
 *	not in use.
 * pachead: dictionary index of most recently added package.
 * parhead: 		   "			    pfile.
 * envhead:                "                        environment.
 */

extern XINT maxd;
extern XINT topd;
extern XINT pachead;
extern XINT parhead;
extern XINT envhead;

/* ----------
 * these are indices into the stack defined in stack.c.
 * topcs: the smallest index into stack[], ie, the "top" index of the control
 *	stack since it grows downwards, that has been used.
 * topos: the largest index into stack[], ie, the top of the operand stack
 *	since it grows upwards, that has been used.
 * pc: at compile time, this is the stack[] index at which the next codeentry
 *	may be compiled; at run time, it is the program counter and points
 *	to the next codeentry to be run	(it is bumped before the "execute"
 *	cycle begins. see run()).
 * basos: not used at compile time, but when compilation ends and runtime
 *	begins, it is set to pc and thus serves as the base of the operand
 *	stack as everything below it will be compiled code. when compiling
 *	starts again, this, and pc, are set to zero to forcibly clear the
 *	operand stack.
 */

extern memel stack[];		/* space for the stacks			*/
extern XINT topcs;		/* top of control stack			*/
extern XINT topos;		/* top of operand stack			*/
extern XINT basos;		/* base of operand stack		*/
extern XINT pc;			/* program counter			*/

/* ----------
 * reference a codeentry in stack at x.
 */
#define	coderef(x)	((struct codeentry *)&stack[x])

extern char *memneed(int incr);		/* insures enough core, returns start	*/
extern char *comdstr(char *s);		/* compile string at topd, return start	*/
