#include <stdlib.h>
#include <setjmp.h>

#define SLEN	80		/* Maximum length of an input string	*/
#define MLEN	10		/* Length of a macro name		*/
#define NUMDO	10		/* Maximum # of direct objs allowed	*/
#define NUMACT	10		/* Maximum # of actors allowed		*/
#define NUMDEM	10		/* Maximum # of daemons allowed		*/
#define	NUMFUS	10		/* Maximum # of fuses allowed		*/
#define NUMVEC	10		/* Default size of verb vector		*/
#define NUMTEMP	4096		/* Maximum # of temp. chars allowed	*/
#define NUMSAVE	1024		/* Maximum # of saved chars allowed	*/
#define STACKSIZE 1024		/* Maximum stack depth			*/

/* Error messages */
#define ADLERR_DIVZERO           1 /* Divide by zero */
#define ADLERR_NUMARGS           2 /* Too few arguments */
#define ADLERR_BUILTIN           3 /* Illegal builtin */
#define ADLERR_SDEM              4 /* Illegal routine for $sdem */
#define ADLERR_SFUS_ROUT         5 /* Illegal routine for $sfus */
#define ADLERR_PROMPT            6 /* Illegal routine for $prompt */
#define ADLERR_ACTOR             7 /* Illegal object for $actor */
#define ADLERR_OVERFLOW          8 /* Stack overflow */
#define ADLERR_UNDERFLOW         9 /* Stack underflow */
#define ADLERR_BADROUT          10 /* Illegal routine call */
#define ADLERR_BADINSTR         11 /* Illegal instruction */
#define ADLERR_BADROUT2         12 /* Illegal routine call */
#define ADLERR_GLOB             13 /* Illegal global for $glob */
#define ADLERR_SETG             14 /* Illegal global for $setg */
#define ADLERR_SETP_OBJ         15 /* Illegal object for $setp */
#define ADLERR_SETP_PROP        16 /* Illegal propnum for $setp */
#define ADLERR_MOVE             17 /* Illegal object for $move */
#define ADLERR_PROP_OBJ         18 /* Illegal object for $prop */
#define ADLERR_PROP_PROP        19 /* Illegal propnum for $prop */
#define ADLERR_VSET_VERB        20 /* Illegal verb for $vset */
#define ADLERR_VSET_PROP        21 /* Illegal propnum for $vset */
#define ADLERR_VPROP_VERB       22 /* Illegal verb for $vprop */
#define ADLERR_VPROP_PROP       23 /* Illegal propnum for $vprop */
#define ADLERR_SPEC             24 /* Illegal parameter for $spec */
#define ADLERR_NAME             25 /* Illegal object for $name */
#define ADLERR_MISS             26 /* Illegal rout for $miss */
#define ADLERR_MEMORY           27 /* Out of memory */
#define ADLERR_EXIT             28 /* Illegal exitcode */
#define ADLERR_TERMCAP          29 /* Bad termcap */
#define ADLERR_SFUS_ACTOR       30 /* Illegal actor for $sfus */
#define ADLERR_SPEC_11          31 /* Illegal actor for $spec 11 */
#define ADLERR_TTY              32 /* Bad tty name */
#define ADLERR_SPEC_12          33 /* Illegal actor for $spec 12 */
#define ADLERR_VERB_VEC         34 /* Bad vector size */

/* Structure of a macro definition */
struct	macro {
    char
	name[ MLEN ],		/* Name of the macro			*/
	val[ SLEN ];		/* Replacement text of the macro	*/
    struct macro
	*next;			/* Next macro in the stack		*/
};


/* Structure of an actor */
struct actrec {
    int16
	actor;			/* Object id of this actor		*/
    char
	*linebuf,		/* Pointer to current input line	*/
	savebuf[ SLEN ];	/* Static save area for input line	*/
    int16
	interact;		/* Get new string if null linebuf?	*/
};


/* Structure of a $exit place */
struct exit_place {
    jmp_buf
	exit_goto;		/* Where to go for ($exit n)		*/
    int16
	exit_ok;		/* Is it OK to perform ($exit n)	*/
};

#if MSDOS & LATTICE
#  define SET_EXIT(n) (exits[n].exit_ok=1, setjmp(&(exits[n].exit_goto)))
#  define DO_EXIT(n)  (exits[n].exit_ok=0, longjmp(&(exits[n].exit_goto),1))
#else
#  define SET_EXIT(n) (exits[n].exit_ok=1, setjmp(exits[n].exit_goto))
#  define DO_EXIT(n)  (exits[n].exit_ok=0, longjmp(exits[n].exit_goto,1))
#endif
#define CLR_EXIT(n)   (exits[n].exit_ok=0)

extern struct actrec
    actlist[];			/* List of actors			*/

extern address
    ip;				/* Instruction pointer			*/
extern int16
    stack[],			/* Execution stack			*/
    sp,				/* Stack pointer			*/
    bp,				/* Base pointer, or Frame pointer	*/
    numact,			/* Number of Actors in Actlist		*/
    curract,			/* Current Actor			*/
    Verb,			/* Current verb				*/
    Prep,			/* Current preposition			*/
    Iobj,			/* Current indirect object		*/
    Inoun,			/*   and its noun			*/
    Imod,			/*   and its modifier			*/
    Conj[],			/* List of conjunctions			*/
    Dobj[],			/* List of direct objects		*/
    Dnoun[],			/*   and their nouns			*/
    Dmod[],			/*   and their modifiers		*/
    NumDobj,			/* Number of direct objects		*/
    vecsize,			/* Number of verbs in verb list		*/
    *vecverb,			/* Verb list				*/
    demons[],			/* List of active demons		*/
    fuses[],			/* List of active fuses			*/
    ftimes[],			/* When to activate fuses		*/
    f_actors[],			/* Actors associated with fuses		*/
    numd,			/* Number of active demons		*/
    numf,			/* Number of active fuses		*/
    currturn,			/* Current turn counter			*/
    prompter,			/* Prompting routine			*/
    numsave,			/* Number of "saved" characters		*/
    debug,			/* Print out debugging info?		*/
    header,			/* Should we print out header bar?	*/
    wordwrite,			/* Should we write unknown words?	*/
    restarted,			/* Is the game being restarted?		*/
    scrwidth,			/* Width of the screen			*/
    numcol,			/* How far we've written across		*/
    t_type,			/* Current token type			*/
    t_val,			/* Current token value			*/
    read_t,			/* TRUE iff lexer is to read next token	*/
    Phase;			/* Current phase #			*/

extern struct exit_place
    exits[];			/* List of exit places			*/

extern char
    *H_STR,			/* Header format string			*/
    *s,				/* Current token			*/
    *xp;			/* Macro expansion of s			*/

extern FILE
    *wordfile,			/* If so, write them to this file.	*/
    *scriptfile;		/* File for "scripting" output		*/

extern char
    savec[];			/* The saved string array		*/

extern struct macro
    *mactab;			/* Table of macro expansions		*/

extern int16
    bitpat[],			/* Bit patterns for masking		*/
    ibitpat[];			/* Bitwise NOT of above			*/



#if ERRCHECK
extern void
    push( int16 );		/* Push something on the stack */
extern int16
    pop( void );		/* Pop the top of the stack		*/
#else
#	define push(x)	(stack[sp++]=x)
#	define pop(x)	(stack[--sp])
#	define assertargs(s,n) 0
#endif

#if LONG_ADDRESS
#  define puship()	{push((int16)(ip&0xFFFF));push((int16)(ip>>16)&0xFFFF);}
#  define popip()	{ip = pop() << 16; ip |= (pop() & 0xFFFF);}
#else
#  define puship()	push( ip )   /* Push the IP (in case of 32-bit)	*/
#  define popip()	(ip = pop()) /* Pop the IP (in case of 32-bit)	*/
#endif

#define	CURRACT		actlist[ curract ].actor
#define PSTRING		actlist[ curract ].linebuf
#define SAVEBUF		actlist[ curract ].savebuf
#define INTERACT	actlist[ curract ].interact

#define	ARG( n )	stack[ bp + n ]	/* n'th argument to this rout	*/
#define	RETVAL		stack[ bp ]	/* Return val. from this rout	*/

/* From adlarith.c */
extern int16
    myrand( int16 );
extern void
    do_div( void ),
    do_mod( void ),
    do_and( void ),
    do_or( void );

/* From adldwim.c */
extern int16
    dwimmer( int16, int16 ),
    dwimadj( int16, int16 ),
    dwimnoun( int16, int16 );
extern void
    dwimerror( int16 );
extern int
    dwimi( void ),
    dwimd( void );

/* From adlerr.c */
extern void
    error( int );

/* From adlfuncs.c */
extern void
    dosysfunc( int16 ),
#if ERRCHECK
    assertargs( char *, int16 ),
#endif
    do_rtrn( void ),
    do_exit( void ),
    do_val( void ),
    do_args( void );
extern int16
    yesno( void );

/* From adlintrn.c */
extern void
    setdemon( void ),
    deldemon( void ),
    setfuse( void ),
    delfuse( int16, int16 ),
    incturn( void ),
    retturn( void ),
    doprompt( void ),
    setactor( void ),
    delactor( int16 );

/* From adlmach.c */
extern void
    callrouts( void ),
    execdems( void ),
    execfuses( void ),
    runprog( void ),
    doret( void ),
    breaker( void ),
    docall( int16 ),
#if ERRCHECK
    printstack( void ),
#endif
    callone( int16 ),
    u_prompt( void );

/* From adlmacro.c */
extern void
    define( char *, char * ),
    undef( char * ),
    clearmacro( void );
extern int16
    nummacro( void );
extern char
    *expand( char * );

/* From adlmiscr.c */
extern void
    varconts( int16 ),
    setg( void ),
    saystr( void );

/* From adlobjr.c */
extern void
    setp( void ),
    move_obj( void ),
    objprop( int16 ),
    vset( void ),
    vprop( void );

/* From adlrun.c */
extern int
    adlmain( int, char ** );
extern void
    getadlargs( int, char ** ),
    init( int16 ),
    driver( void ),
    rand_seed( void ),
    loadarray( char **, struct adldir *, int16 ),
    getchunk( char **, char * );
extern int
    getbuffer( void );
extern char
    *getnext( int *, char ** );
extern int16
    noun_exists( int16, int16 );

/* From adlscrn.c */
extern void
    sayer( char * ),
    crlf( void ),
    getstring( char * ),
    head_setup( void ),
    write_head( void ),
    head_term( void );

/* From adlspec.c */
void
    special( void ),
    restart( void ),
    set_tty( void ),
    change_tty( void ),
    invert( char *, int16 ),
    savegame( char * ),
    do_wordfile( void ),
    callextern( void ),
    change_vec( void ),
    scripter( void );
extern int
    restoregame( char * );

/* From adlstr.c */
extern void
    eqstring( void ),
    substring( void ),
    lengstring( void ),
    readstring( void ),
    catstring( void ),
    chrstring( void ),
    ordstring( void ),
    posstring( void ),
    savestr( void ),
    do_str( void ),
    do_num( void ),
    do_name( void ),
    do_vname( void ),
    do_mname( void ),
    do_pname(void ),
    do_define( void ),
    do_undef( void );
extern int16
    strpos( char *, char * );

/* From adltrans.c */
extern void
    setverb( void ),
    hitverb( void ),
    missverb( void );

/* From rtdict.c */
extern int16
    insertkey( char *, int16, int16, int16 ),
    lookup( char *, int16 * );
extern void
    read_symtab( FILE *, struct adldir * );
extern char
    *findone( int16, int16 );

/* From rtlex.c */
extern void
    gettoken( void ),
    getquotes( int16 ),
    eatwhite( void );
extern int
    lexer( void ),
    try_expand( void ),
    numberp( char * ),
    adlchr( int );

/* From rtparse.c */
extern void
    initvars( void );
extern int
    parse( void );
    
/*** EOF adlrun.h ***/
