/* Arbitrary limits used in hoc. Some day these should be removed.
   NSTACK should be replaced by an endstack pointer, with possible
   enlarging realloc of the stack when necessary.
   NFRAME should be the only one remaining a limit (to catch erronous
   infinite recursions), but it too should be possible to reallocate
   on runtime.
*/
#ifndef NSTACK		/* Maximum stack size. The stack is used for keeping */
#define NSTACK 1024	/* function parameters */
#endif
#ifndef NFRAME		/* Maximum frame size. The frame needs one entry for */
#define NFRAME 256      /* each level of recursion */
#endif
#ifndef NPROG		/* Maximum "program" size. This limits the size of */
#define NPROG 2000	/* one statement, or one func/proc definitions. */
#endif

/* Use prototypes like: double add _PROTO((double n1, int n2))
   which work whether or not prototypes are available
*/
#ifdef __STDC__
#define _PROTO(x) x
#else
#define _PROTO(x) ()
#endif

/* Functions used as stack-machine instructions, i.e., added to the program
   using code() during the compilation phase and later executed by execute()
   must all return the same type of value, since execute() cannot know which
   function it calls, and it assumes it knows which type is returned so it
   can ignore it. This type will be called SMI (for "stack machine
   instruction"), and will be typically be defined as void.

   Inst is the type for intructions kept in the "program" (instruction list).
   Each instruction is a pointer to the appropriate function, i.e., it is
   a pointer to a function returning SMI.
*/
typedef void SMI;
typedef SMI (*Inst)();

typedef struct Local Local;
typedef struct Constant Constant;
typedef struct Symbol {
	char *name;
	short type;
	union {
		double val;	/*VAR*/
		double (*ptr)();/*BLTIN*/
		Inst defn;	/*FUNCTION,PROCEDURE*/
		char *str;	/*STRING*/
		Local *localptr;/*LOCAL*/
		Constant *Const;/*CONST*/
	} u;
	struct Symbol *left;
	struct Symbol *right;
} Symbol;
struct Constant {
	double d;
	struct Constant *left;
	struct Constant *right;
};

typedef union Datum {
	double val;
	Symbol *sym;
} Datum;
typedef struct Frame {
	Symbol *sp;
	Inst *retpc;
	Datum *argn;
	int nargs;
	Local *locals;
} Frame;
struct Local {
	double val;		/* value of local variable */
	Local *nextdef;		/* definition from previous scope of
				   this variable */
	Local *nextlocal;	/* next local variable in this function */
	Symbol *real;		/* pointer to the global structure */
	union {
		Frame *frame;		/* pointer to frame that called
					   mklocal, needed in all the Local
					   structures in the linked list
					   exept the last one */ 
		short type;		/* type: VAR or UNDEF, needed only
				   	   for the last Local structure
				   	   in the linked list */
	} p;
};

/* hoc.y */
extern void execerror _PROTO((char *s, char *t));
extern void warning _PROTO((char *s, char *t));
extern void init _PROTO((void));
extern void run _PROTO((void));
extern void versioninfo _PROTO((void));
/* code.c */
extern void initcode _PROTO((void));
extern void define _PROTO((Symbol *sp));
extern void Line _PROTO((Inst lineinfile, Inst filename));
extern Inst *code _PROTO((Inst f));
extern void move _PROTO((Inst *p, int n));
extern void execute _PROTO((Inst *p));
/* math.c */
extern double Pow _PROTO((double x, double y));
/* symbol.c */
extern Symbol *symstart _PROTO((void));
extern Symbol *lookup _PROTO((char *s));
extern Symbol *install _PROTO((char *s,int t, double d));
extern Constant *installd _PROTO((double n));
extern char *emalloc _PROTO((unsigned n));


/* Pointers to the following functions can be put in the "program", by code()
   to be executed, i.e., this is the stack-machine instruction list.
*/
#define STOP (Inst)0
extern SMI eval(),add(),sub(),mul(),Div(),negate(),power(),mod();
extern SMI assign(),bltin(),varpush(),constpush(),print(),varread(),postdec();
extern SMI prexpr(),prstr(),System(),Mod(),poweq(),argpoweq();
extern SMI gt(),lt(),eq(),ge(),le(),ne(),and(),or(),not(),forcode(),preinc();
extern SMI ifcode(),whilecode(),call(),arg(),argassign(),printnames(),predec();
extern SMI funcret(),procret(),Break(),Breakn(),exitn(),doflush(),postinc();
extern SMI cont(),contn(),argcnt(),Free(),conditional(),makelocal();
extern SMI argpredec(),argpostdec(),argpreinc(),argpostinc(),addeq(),subeq();
extern SMI muleq(),diveq(),argaddeq(),argsubeq(),argmuleq(),argdiveq(),Set();
extern SMI approxeq(),notapproxeq(),modeq(),argmodeq(),Include(),findtype();
extern SMI makeconst(), printversion(),Abort(),Doeof(),Chdir(),popandforget();
extern SMI exit0();
/* End of "program code" functions. */

/* Builtins. Builtins are all functions taking one double argument and
   returning a double, and they are defined in math.c (except Arg() defined
   in code.c). They are called by the state machine instruction bltin().
   The pointers to the builtin functions are put in the symbol table in BLTIN
   type variables, in init.c.
*/
typedef double Builtin _PROTO((double));
typedef double (*Builtinp) _PROTO((double));
extern Builtin Log,Log10,Sqrt,Exp,integer,frac,rnd,randomize,Time,Logamma,Sinh;
extern Builtin Cosh,Tanh,Tan,Asin,Acos,Gamma,Sec,Cosec,Cot,Arg;
/* End of "builtin" functions. */

/* External variables used between files. These should be kept to a minimum.
*/
/* hoc.y */
extern int indef, lineno, nlstate, interactive;
extern char *infile;
extern Inst deffunc[], defproc[];
/* TODO: 'fin' and 'begin' should also be defined (they are externed in
   code.c) but that requires inclusion of stdio.h and setjmp.h)
*/
/* code.c */
extern Inst *progp,*progbase,prog[];
extern Frame frame[],*fp;
/* init.c */
extern Symbol *vpERROR, *vpDIGITS;
/* version.c */
extern char *version_array[];
/* End of external variables */

extern int *getmem _PROTO((int i));
extern void freemem _PROTO((int *p, int i));
#define NEWLOCAL() ((Local *)getmem(sizeof(Local)/sizeof(int)))
#define FREELOCAL(p) freemem((int*)p,sizeof(Local)/sizeof(int))
#define S_CHANGED 0
#define S_IGNOREUNDEF 1
#define S_TRACECALLS 2
#define S_ALLNAMES 5
#define S_ALL 3
#define S_DEFAULT 4


syntax highlighted by Code2HTML, v. 0.9.1