pennmush/game/
pennmush/game/data/
pennmush/game/log/
pennmush/game/save/
pennmush/game/txt/evt/
pennmush/game/txt/nws/
pennmush/os2/
/* parse.h - parser declarations and macros

 * Written by T. Alexander Popiel, 13 May 1995
 * Last modified by T. Alexander Popiel, 26 May 1995
 *
 * Copyright (c) 1995 by T. Alexander Popiel
 * See copyrite.h for details.
 */

#ifndef _PARSE_H_
#define _PARSE_H_

#include "copyrite.h"

#include "config.h"
#ifdef I_STDLIB
#include <stdlib.h>
#endif
#ifdef I_LIMITS
#include <limits.h>
#else
#ifdef I_VALUES
#include <values.h>
#endif
#endif
#include <math.h>
#include "dbdefs.h"
#include "confmagic.h"

/* This is the type to be used for numbers which may be non-integral. */

#ifdef FLOATING_POINTS
#define NVAL double
#define HUGE_NVAL	HUGE_DOUBLE
#else
#define NVAL int
#define HUGE_NVAL	HUGE_INT
#endif

/* These are some common error messages. */
extern char e_int[];		/* #-1 ARGUMENT MUST BE INTEGER */
extern char e_ints[];		/* #-1 ARGUMENTS MUST BE INTEGERS */
#ifdef FLOATING_POINTS
extern char e_num[];		/* #-1 ARGUMENT MUST BE NUMBER */
extern char e_nums[];		/* #-1 ARGUMENTS MUST BE NUMBERS */
#else
#define e_num	e_int		/* #-1 ARGUMENT MUST BE INTEGER */
#define e_nums	e_ints		/* #-1 ARGUMENTS MUST BE INTEGERS */
#endif

/* This type is used by process_expression().  In all but parse.c,
 * this should be left as an incompletely-specified type, making it
 * impossible to declare anything but pointers to it.
 */

typedef struct pe_info PE_Info;

/* The following routines all take strings as arguments, and return
 * data of the appropriate types.  
 */

int parse_boolean _((char const *str));

#define parse_integer(str) atoi(str)

#ifdef FLOATING_POINTS
#define parse_number(str) atof(str)
#else
#define parse_number(str) atoi(str)
#endif

/* The following routines all take varoius arguments, and return
 * string representations of same.  The string representations
 * are stored in static buffers, so the next call to each function
 * will destroy any old string that was there.
 */

#define unparse_boolean(x) ((x) ? "1" : "0")

char *unparse_dbref _((dbref num));
char *unparse_integer _((int num));
char *unparse_number _((NVAL num));

/* The following routines all take strings as arguments, and return
 * true iff the string is a valid representation of the appropriate type.
 */
int is_dbref _((char const *str));

int is_integer _((char const *str));
int is_boolean _((char const *str));


/* All function declarations follow the format: */

#ifdef CAN_NEWSTYLE
#define FUNCTION(fun_name) \
  /* ARGSUSED */ /* try to keep lint happy */ \
  void fun_name _((char *buff, char **bp, int nargs, char *args[], \
		   dbref executor, dbref caller, dbref enactor, \
		   char const *called_as, PE_Info *pe_info)); \
  void fun_name(char *buff, char **bp, int nargs, char *args[], \
		dbref executor, dbref caller, dbref enactor, \
		char const *called_as, PE_Info *pe_info)
#else
#define FUNCTION(fun_name) \
  /* ARGSUSED */ /* try to make lint happy */ \
  void fun_name _((char *buff, char **bp, int nargs, char *args[], \
		   dbref executor, dbref caller, dbref enactor, \
		   char const *called_as, PE_Info *pe_info)); \
  void fun_name(buff, bp, nargs, args, executor, caller, enactor, \
		called_as, pe_info) \
      char *buff; \
      char **bp; \
      int nargs; \
      char *args[]; \
      dbref executor; \
      dbref caller; \
      dbref enactor; \
      char const *called_as; \
      PE_Info *pe_info;
#endif

/* All results are returned in buff, at the point *bp.  *bp is likely
 * not equal to buff, so make no assumptions about writing at the
 * start of the buffer.  *bp must be updated to point at the next
 * place to be filled (ala safe_str() and safe_chr()).  Be very
 * careful about not overflowing buff; use of safe_str() and safe_chr()
 * for all writes into buff is highly recommended.
 *
 * nargs is the count of the number of arguments passed to the function,
 * and args is an array of pointers to them.  args will have at least
 * nargs elements, or 10 elements, whichever is greater.  The first ten
 * elements are initialized to NULL for ease of porting functions from
 * the old style, but relying on such is considered bad form.
 * The argument strings are stored in BUFFER_LEN buffers, but reliance
 * on that size is also considered bad form.  The argument strings may
 * be modified, but modifying the pointers to the argument strings will
 * cause crashes. 
 *
 * executor corresponds to %!, the object invoking the function.
 * caller   corresponds to %@, the last object to do a U() or similar.
 * enactor  corresponds to %#, the object that started the whole mess.
 * Note that fun_ufun() and similar must swap around these parameters
 * in calling process_expression(); no checks are made in the parser
 * itself to maintain these values.
 *
 * called_as contains a pointer to the name of the function called
 * (taken from the function table).  This may be used to distinguish
 * multiple functions which use the same C function for implementation.
 *
 * pe_info holds context information used by the parser.  It should
 * be passed untouched to process_expression(), if it is called.
 * pe_info should be treated as a black box; its structure and contents
 * may change without notice.
 */

/* process_expression() evaluates expressions.  What a concept. */

void process_expression _((char *buff, char **bp, char const **str,
			   dbref executor, dbref caller, dbref enactor,
			   int eflags, int tflags, PE_Info * pe_info));

/* buff is a pointer to a BUFFER_LEN string to contain the expression
 * result.  *bp is the point in buff at which the result should be written.
 * *bp will be updated to point one past the result of the expression,
 * and the result will _NOT_ be null-terminated.
 * For top-level calls to process_expression(), *bp should probably equal
 * buff.  For calls to process_expression() inside function implementations,
 * buff and bp should probably be the values passed into the implementation.
 *
 * *str is a pointer to a string containing the expression to evaluate.
 * *str will be updated to point at the terminator which caused return
 * from process_expression().  The string pointed to by *str will not
 * be modified.
 *
 * executor, caller, and enactor represent %!, %@, and %#, respectively.
 * No validity checking of any sort is done on these parameters, so please
 * be careful with them.
 *
 * eflags consists of one or more of the following evaluation flags:
 */

#define PE_NOTHING		0
#define PE_COMPRESS_SPACES	0x00000001
#define PE_STRIP_BRACES		0x00000002
#define PE_EVALUATE		0x00000010
#define PE_FUNCTION_CHECK	0x00000020
#define PE_FUNCTION_MANDATORY	0x00000040
#define PE_LITERAL		0x00000100

#define PE_DEFAULT (PE_COMPRESS_SPACES | PE_STRIP_BRACES | \
		    PE_EVALUATE | PE_FUNCTION_CHECK)

/* PE_COMPRESS_SPACES strips leading and trailing spaces, and reduces sets
 * of internal spaces to one space.
 *
 * PE_STRIP_BRACES strips off top-level braces.
 *
 * PE_EVALUATE allows %-substitutions, []-evaluation, function evaluation,
 * and \-stripping.
 *
 * PE_FUNCTION_CHECK allows function evaluation.  Note that both PE_EVALUATE
 * and PE_FUNCTION_CHECK must be active for function evaluation to occur.
 *
 * PE_FUNCTION_MANDATORY causes an error to be reported if a function call
 * is attempted for a non-existant function.  Otherwise, the function call
 * is not evaluated, but rather treated as normal text.
 *
 * PE_LITERAL prevents { and [ from being recognized and causing recursion.
 *
 * PE_DEFAULT is the most commonly used set of flags, normally sufficient
 * for calls to process_expression().
 *
 *
 * tflags consists of one or more of the following termination flags:
 */

#define PT_NOTHING	0
#define PT_BRACE	0x00000001
#define PT_BRACKET	0x00000002
#define PT_PAREN	0x00000004
#define PT_COMMA	0x00000008
#define PT_SEMI		0x00000010
#define PT_EQUALS	0x00000020
#define PT_SPACE	0x00000040

/* These represent '\0', '}', ']', ')', ',', ';', '=', and ' ', respectively.
 * If the character corresponding to a set flag is encountered, then
 * process_expression() will exit, with *str pointing at the terminating
 * charater.  '\0' is always a terminating character.
 *
 * PT_DEFAULT, below, is provided as syntactic sugar.
 */

#define PT_DEFAULT PT_NOTHING

/* pe_info is a pointer to a structure of internal state information
 * for process_expression().  Top-level calls to process_expression()
 * should pass a NULL as pe_info.  Calls to process_expression() from
 * function implementations should pass their pe_info as pe_info.
 * In no case should any other pe_info be passed to process_expression().
 */

/* Miscellany */
void do_userfn _((char *buff, char **bp, dbref obj, ATTR *attrib,
		  int nargs, char **args, dbref executor, dbref caller,
		  dbref enactor, PE_Info * pe_info));
void init_process_expression _((void));

#endif				/* !_PARSE_H_ */