ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
#ifndef LEX_H__
#define LEX_H__ 1

#include "driver.h"
#include "typedefs.h"
#include "strfuns.h"

/* --- Types --- */

/* --- struct lpc_predef_s: predefined preprocessor macros ---
 *
 * The structures are used in a list to store macro definitions
 * given to the driver on the commandline. The list is evaluated
 * when the lexer is first initialised.
 */

struct lpc_predef_s
{
    char  * flag;
      /* The raw text of the definition in the form 'NAME' or 'NAME=<value>'
       * in its own allocated memory.
       */
    struct lpc_predef_s *next;
      /* Next predefinition in the list, or NULL.
       */
};


/* --- typedef defn_fun: dynamic macro expansion ---
 *
 * Functions of this type are used to provide dynamic macro expansions.
 * When used in a macro definition instead of a static replacement text,
 * they are called at every point of macro use.
 *
 * If the implemented macro takes no argument, NULL is passed
 * in the call and the function has to return a fresh allocation of
 * the replacement text.
 *
 * If the macro takes arguments, they are passed as char** with as
 * many arguments as the definition requires. The macro has to add
 * the replacement text via add_input() and return NULL.
 *
 * TODO: Also, the different handling of the replacement text is ugly.
 */

typedef char * (*defn_fun)(char **);


/* --- struct defn: definition of a macro ---
 *
 * Macros are stored in the ident_table[] as I_TYPE_DEFINEs. Their replacement
 * can be given as literal text, or as the result of a function called every
 * time the macro is used.
 *
 * The function is passed an char*[] with the current macro argument values,
 * terminated with a NULL, and has to return an allocated string with
 * the replacement text.
 *
 * The replacement text must not contain comments.
 *
 * Function macros (.nargs >= 0) expect the replacement text to contain
 * special MARKS sequences ('@' followed by another character) to mark
 * the places where the function arguments are to be inserted. The code
 * of the second character minus ('@'+1) gives the number of the argument
 * to insert. The sequence '@@' stands for the literal '@' character.
 *
 * Plain macros (.nargs < 0) take the replacement text as it is.
 */

struct defn
{
    union {            /* The replacement text: */
        char *str;     /*   given as xalloced literal (.special is false) */
        defn_fun fun;  /*   return by fun() (.special is true) */
    } exps;
    short nargs;       /* Number of arguments, 0 for non-function macros */
    SBool permanent;   /* true: permanent define */
    SBool special;     /* true: <fun> returns the replacement text */
};


/* --- struct ident_s: known identifiers ---
 *
 * The structure is used to keep the information about all identifiers
 * encountered so far (including reserved words, efuns, etc).
 *
 * There can several entries for the same identifier name but with
 * different types in the table. These entries are put into a list formed
 * by their .inferior pointers, sorted by falling type values. The entry
 * with the highest type is the one linked into the hash chain.
 *
 * The identifiers are stored in a table of chains, hashed over their names.
 * The most recently identifier always brought to the head of its hash-chain.
 *
 * Additionally, all efuns and defines are stored in their
 * own 'all_...' lists, linked by the '.next_all' field.
 */

struct ident_s
{
    char *name;              /* Name of the identifier (shared string) */
    short type;              /* Type of this entry */
    short hash;              /* Hashvalue of this identifier */
    ident_t *next;           /* Next in hash chain */
    ident_t *inferior;       /* Ident of same name, but lower type */
    union {                  /* Type-depend data: */
        struct defn define;  /*   Macro definition */
        int code;            /*   Reserved word: lexem code */
        struct {             /*   Global identifier: */
            short function;
              /* >= 0: lfun: Index number of the lfun in den function table,
               * < 0: -2: efun/sefun, -1: gvar
               */
            short variable;
              /* >= 0: variable: Index number in the variable table.
               *       During compilation, virtual variables are offset
               *       by VIRTUAL_VAR_TAG.
               * < 0: -2: efun/sefun, -1: lfun/inherited hidden var
               */
            short efun;
              /* efun: Index in instrs[], negative else
               * < 0: -1: lfun/gvar/sefun
               */
            short sim_efun;
              /* simul-efun: Index in simul_efun[], negative else
               * < 0: -1: efun/lfun/gvar
               */
        } global;
        struct {             /*   Local identifier: */
            int num;         /*     Number, also the index on the stack */
            int depth;       /*     Definition depth */
        } local;
    } u;
    ident_t *next_all;       /* 'all_...' list link */
};

/* ident_t.type values: */

#define I_TYPE_UNKNOWN    0
#define I_TYPE_GLOBAL     2  /* function, variable or efuns/simul_efuns */
#define I_TYPE_LOCAL      3
#define I_TYPE_RESWORD    4  /* reserved word */
#define I_TYPE_DEFINE     5

/* ident_t.global magic values */

#define I_GLOBAL_FUNCTION_VAR    (-1)
#define I_GLOBAL_FUNCTION_EFUN   (-2)
#define I_GLOBAL_VARIABLE_OTHER  (-1)
#define I_GLOBAL_VARIABLE_FUN    (-2)
#define I_GLOBAL_EFUN_OTHER      (-1)
#define I_GLOBAL_SEFUN_OTHER     (-1)


#define lookup_predef(p) (p->type == I_TYPE_GLOBAL ? p->u.global.efun : -1)


/* --- struct inline_fun: linked list element of saved function texts ---
 *
 * The functions inlined by (: ... :) have their code (plus the function
 * header and trailer) saved for later parsing in a list of these
 * structures.
 */

struct inline_fun
{
    strbuf_t buf;              /* the complete function text */
    struct inline_fun * next;  /* next list element */
};


/* --- Variables --- */

extern struct lpc_predef_s * lpc_predefs;
extern int current_line;
extern int total_lines;
extern char *current_file;
extern int pragma_strict_types;
extern Bool pragma_use_local_scopes;
extern Bool pragma_save_types;
extern Bool pragma_combine_strings;
extern Bool pragma_verbose_errors;
extern Bool pragma_no_clone;
extern Bool pragma_no_inherit;
extern Bool pragma_no_shadow;
extern Bool pragma_pedantic;
extern Bool pragma_warn_deprecated;
extern char *last_lex_string;
extern ident_t *all_efuns;
extern struct inline_fun * first_inline_fun;
extern Bool insert_inline_fun_now;
extern unsigned int next_inline_fun;

/* Values of pragma_strict_types */

#define PRAGMA_KEEP_TYPES    (-1) /* Only used in struct incstate */
#define PRAGMA_WEAK_TYPES    0
#define PRAGMA_STRONG_TYPES  1
#define PRAGMA_STRICT_TYPES  2


/* --- Prototypes --- */

extern void init_lexer(void);
extern ident_t *lookfor_shared_identifier(char *, int, int, Bool);
#define make_shared_identifier(s,n,d) lookfor_shared_identifier(s,n,d, MY_TRUE)
#define find_shared_identifier(s,n,d) lookfor_shared_identifier(s,n,d, MY_FALSE)
extern ident_t *make_global_identifier(char *, int);
extern void free_shared_identifier(ident_t*);
extern int yylex(void);
extern void end_new_file(void);
extern void lex_close(char *msg);
extern void start_new_file(int fd);
extern char *get_f_name(int n);
extern void free_defines(void);
extern size_t show_lexer_status (strbuf_t * sbuf, Bool verbose);
extern void set_inc_list(vector_t *v);
extern void remove_unknown_identifier(void);
extern char *lex_error_context(void);
extern svalue_t *f_expand_define(svalue_t *sp);

#ifdef GC_SUPPORT
extern void count_lex_refs(void);
#endif /* GC_SUPPORT */

#endif /* LEX_H__ */