text: /*  Pawn compiler
   *
   *  Drafted after the Small-C compiler Version 2.01, originally created
   *  by Ron Cain, july 1980, and enhanced by James E. Hendrix.
   *
   *  This version comes close to a complete rewrite.
   *
   *  Copyright R. Cain, 1980
   *  Copyright J.E. Hendrix, 1982, 1983
   *  Copyright ITB CompuPhase, 1997-2005
   *
   *  This software is provided "as-is", without any express or implied warranty.
   *  In no event will the authors be held liable for any damages arising from
   *  the use of this software.
   *
   *  Permission is granted to anyone to use this software for any purpose,
   *  including commercial applications, and to alter it and redistribute it
   *  freely, subject to the following restrictions:
   *
   *  1.  The origin of this software must not be misrepresented; you must not
   *      claim that you wrote the original software. If you use this software in
   *      a product, an acknowledgment in the product documentation would be
   *      appreciated but is not required.
   *  2.  Altered source versions must be plainly marked as such, and must not be
   *      misrepresented as being the original software.
   *  3.  This notice may not be removed or altered from any source distribution.
   */
  
  #ifndef SC_H_INCLUDED
  #define SC_H_INCLUDED
  #include <limits.h>
  #include <stdarg.h>
  #include <stdio.h>
  #if defined __BORLANDC__ && defined _Windows && !(defined __32BIT__ || defined __WIN32__)
    /* setjmp() and longjmp() not well supported in 16-bit windows */
    #include <windows.h>
    typedef int jmp_buf[9];
    #define setjmp(b)     Catch(b)
    #define longjmp(b,e)  Throw(b,e)
  #else
    #include <setjmp.h>
  #endif
  #include "osdefs.h"
  #include "amx.h"
  
  #if PAWN_CELL_SIZE==64 && !defined _I64_MIN
  #define _I64_MIN    (-9223372036854775807ULL - 1)
  #define _I64_MAX      9223372036854775807ULL
  #endif
  
  /* Note: the "cell" and "ucell" types are defined in AMX.H */
  
  #define PUBLIC_CHAR '@'     /* character that defines a function "public" */
  #define CTRL_CHAR   '^'    /* default control character */
  #define sCHARBITS   8       /* size of a packed character */
  
  #define sDIMEN_MAX     4    /* maximum number of array dimensions */
  #define sLINEMAX     4095    /* input line length (in characters) */
  #define sCOMP_STACK   32    /* maximum nesting of #if .. #endif sections */
  #define sDEF_LITMAX  500    /* initial size of the literal pool, in "cells" */
  #define sDEF_AMXSTACK 4096  /* default stack size for AMX files */
  #define PREPROC_TERM  '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
  #define sDEF_PREFIX   "default.inc" /* default prefix filename */
  
  #if defined WIN32 || defined __clang__
  #define INVISIBLE
  #else
  #define INVISIBLE __attribute__((visibility("protected")))
  #endif
  
  typedef union {
    void *pv;                 /* e.g. a name */
    int i;
  } stkitem;                  /* type of items stored on the compiler stack */
  
  typedef struct s_arginfo {  /* function argument info */
    char name[sNAMEMAX+1];
    char ident;           /* iVARIABLE, iREFERENCE, iREFARRAY or iVARARGS */
    char usage;           /* uCONST */
    int *tags;            /* argument tag id. list */
    int numtags;          /* number of tags in the tag list */
    int dim[sDIMEN_MAX];
    int idxtag[sDIMEN_MAX];
    int numdim;           /* number of dimensions */
    unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
    union {
      cell val;           /* default value */
      struct {
        char *symname;    /* name of another symbol */
        short level;      /* indirection level for that symbol */
      } size;             /* used for "sizeof" default value */
      struct {
        cell *data;       /* values of default array */
        int size;         /* complete length of default array */
        int arraysize;    /* size to reserve on the heap */
        cell addr;        /* address of the default array in the data segment */
      } array;
    } defvalue;           /* default value, or pointer to default array */
    int defvalue_tag;     /* tag of the default value */
  } arginfo;
  
  /*  Equate table, tagname table, library table */
  typedef struct s_constvalue {
    struct s_constvalue *next;
    char name[sNAMEMAX+1];
    cell value;
    short index;          /* index level, for constants referring to array sizes/tags
                           * automaton id. for states and automatons */
  } constvalue;
  
  /*  Symbol table format
   *
   *  The symbol name read from the input file is stored in "name", the
   *  value of "addr" is written to the output file. The address in "addr"
   *  depends on the class of the symbol:
   *      global          offset into the data segment
   *      local           offset relative to the stack frame
   *      label           generated hexadecimal number
   *      function        offset into code segment
   */
  typedef struct s_symbol {
    struct s_symbol *next;
    struct s_symbol *parent;  /* hierarchical types (multi-dimensional arrays) */
    char name[sNAMEMAX+1];
    uint32_t hash;        /* value derived from name, for quicker searching */
    cell addr;            /* address or offset (or value for constant, index for native function) */
    cell codeaddr;        /* address (in the code segment) where the symbol declaration starts */
    char vclass;          /* sLOCAL if "addr" refers to a local symbol */
    char ident;           /* see below for possible values */
    short usage;          /* see below for possible values */
    char flags;          /* see below for possible values */
    int compound;         /* compound level (braces nesting level) */
    int tag;              /* tagname id */
    int fieldtag;         /* enumeration fields, where a size is attached to the field */
    union {
      int declared;       /* label: how many local variables are declared */
      int idxtag;         /* array & enum: tag of array indices or the enum item */
      constvalue *lib;    /* native function: library it is part of */
      long stacksize;     /* normal/public function: stack requirements */
    } x;                  /* 'x' for 'extra' */
    union {
      arginfo *arglist;   /* types of all parameters for functions */
      constvalue *enumlist;/* list of names for the "root" of an enumeration */
      struct {
        cell length;      /* arrays: length (size) */
        short level;      /* number of dimensions below this level */
      } array;
    } dim;                /* for 'dimension', both functions and arrays */
    constvalue *states;   /* list of state function addresses */
    int fnumber;          /* static global variables: file number in which the declaration is visible */
    int lnumber;          /* line number (in the current source file) for the declaration */
    struct s_symbol **refer;  /* referrer list, functions that "use" this symbol */
    int numrefers;        /* number of entries in the referrer list */
    char *documentation;  /* optional documentation string */
  } symbol;
  
  
  /*  Possible entries for "ident". These are used in the "symbol", "value"
   *  and arginfo structures. Not every constant is valid for every use.
   *  In an argument list, the list is terminated with a "zero" ident; labels
   *  cannot be passed as function arguments, so the value 0 is overloaded.
   */
  #define iLABEL      0
  #define iVARIABLE   1   /* cell that has an address and that can be fetched directly (lvalue) */
  #define iREFERENCE  2   /* iVARIABLE, but must be dereferenced */
  #define iARRAY      3
  #define iREFARRAY   4   /* an array passed by reference (i.e. a pointer) */
  #define iARRAYCELL  5   /* array element, cell that must be fetched indirectly */
  #define iARRAYCHAR  6   /* array element, character from cell from array */
  #define iEXPRESSION 7   /* expression result, has no address (rvalue) */
  #define iCONSTEXPR  8   /* constant expression (or constant symbol) */
  #define iFUNCTN     9
  #define iREFFUNC    10
  #define iVARARGS    11  /* function specified ... as argument(s) */
  
  /*  Possible entries for "usage"
   *
   *  This byte is used as a serie of bits, the syntax is different for
   *  functions and other symbols:
   *
   *  VARIABLE
   *  bits: 0     (uDEFINE) the variable is defined in the source file
   *        1     (uREAD) the variable is "read" (accessed) in the source file
   *        2     (uWRITTEN) the variable is altered (assigned a value)
   *        3     (uCONST) the variable is constant (may not be assigned to)
   *        4     (uPUBLIC) the variable is public
   *        6     (uSTOCK) the variable is discardable (without warning)
   *
   *  FUNCTION
   *  bits: 0     (uDEFINE) the function is defined ("implemented") in the source file
   *        1     (uREAD) the function is invoked in the source file
   *        2     (uRETVALUE) the function returns a value (or should return a value)
   *        3     (uPROTOTYPED) the function was prototyped
   *        4     (uPUBLIC) the function is public
   *        5     (uNATIVE) the function is native
   *        6     (uSTOCK) the function is discardable (without warning)
   *        7     (uMISSING) the function is not implemented in this source file
   *
   *  CONSTANT
   *  bits: 0     (uDEFINE) the symbol is defined in the source file
   *        1     (uREAD) the constant is "read" (accessed) in the source file
   *        2     (uWRITTEN) redundant, but may be set for constants passed by reference
   *        3     (uPREDEF) the constant is pre-defined and should be kept between passes
   *        5     (uENUMROOT) the constant is the "root" of an enumeration
   *        6     (uENUMFIELD) the constant is a field in a named enumeration
   */
  #define uDEFINE   0x01
  #define uREAD     0x02
  #define uWRITTEN  0x04
  #define uRETVALUE 0x04  /* function returns (or should return) a value */
  #define uCONST    0x08
  #define uPROTOTYPED 0x08
  #define uPREDEF   0x08  /* constant is pre-defined */
  #define uPUBLIC   0x10
  #define uNATIVE   0x20
  #define uENUMROOT 0x20
  #define uSTOCK    0x40
  #define uENUMFIELD 0x40
  #define uMISSING  0x80
  #define uVISITED  0x100 /* temporary flag, to mark fields as "visited" in recursive loops */
  /* uRETNONE is not stored in the "usage" field of a symbol. It is
   * used during parsing a function, to detect a mix of "return;" and
   * "return value;" in a few special cases.
   */
  #define uRETNONE  0x10
  
  #define flgDEPRECATED 0x01  /* symbol is deprecated (avoid use) */
  
  #define uTAGOF    0x40  /* set in the "hasdefault" field of the arginfo struct */
  #define uSIZEOF   0x80  /* set in the "hasdefault" field of the arginfo struct */
  
  #define uMAINFUNC "main"
  #define uENTRYFUNC "entry"
  
  #define sGLOBAL   0     /* global/local variable/constant class */
  #define sLOCAL    1
  #define sSTATIC   2     /* global life, local scope */
  
  typedef struct s_value {
    symbol *sym;          /* symbol in symbol table, NULL for (constant) expression */
    cell constval;        /* value of the constant expression (if ident==iCONSTEXPR)
                           * also used for the size of a literal array */
    int tag;              /* tagname id (of the expression) */
    char forceuntag;      /* whether expression is untagged using _: */
    char ident;           /* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
                           * iEXPRESSION or iREFERENCE */
    char boolresult;      /* boolean result for relational operators */
    cell *arrayidx;       /* last used array indices, for checking self assignment */
  } value;
  
  /*  "while" statement queue (also used for "for" and "do - while" loops) */
  enum {
    wqBRK,        /* used to restore stack for "break" */
    wqCONT,       /* used to restore stack for "continue" */
    wqLOOP,       /* loop start label number */
    wqEXIT,       /* loop exit label number (jump if false) */
    /* --- */
    wqSIZE        /* "while queue" size */
  };
  #define wqTABSZ (24*wqSIZE)    /* 24 nested loop statements */
  
  enum {
    statIDLE,     /* not compiling yet */
    statFIRST,    /* first pass */
    statWRITE,    /* writing output */
    statSKIP,     /* skipping output */
  };
  
  typedef struct s_stringlist {
    struct s_stringlist *next;
    char *line;
  } stringlist;
  
  typedef struct s_stringpair {
    struct s_stringpair *next;
    char *first;
    char *second;
    int matchlength;
    char flags;
    char *documentation;
  } stringpair;
  
  typedef struct s_valuepair {
    struct s_valuepair *next;
    long first;
    long second;
  } valuepair;
  
  /* macros for code generation */
  #define opcodes(n)      ((n)*sizeof(cell))      /* opcode size */
  #define opargs(n)       ((n)*sizeof(cell))      /* size of typical argument */
  
  /*  Tokens recognized by lex()
   *  Some of these constants are assigned as well to the variable "lastst"
   */
  #define tFIRST   256    /* value of first multi-character operator */
  #define tMIDDLE  280    /* value of last multi-character operator */
  #define tLAST    325    /* value of last multi-character match-able token */
  /* multi-character operators */
  #define taMULT   256    /* *= */
  #define taDIV    257    /* /= */
  #define taMOD    258    /* %= */
  #define taADD    259    /* += */
  #define taSUB    260    /* -= */
  #define taSHL    261    /* <<= */
  #define taSHRU   262    /* >>>= */
  #define taSHR    263    /* >>= */
  #define taAND    264    /* &= */
  #define taXOR    265    /* ^= */
  #define taOR     266    /* |= */
  #define tlOR     267    /* || */
  #define tlAND    268    /* && */
  #define tlEQ     269    /* == */
  #define tlNE     270    /* != */
  #define tlLE     271    /* <= */
  #define tlGE     272    /* >= */
  #define tSHL     273    /* << */
  #define tSHRU    274    /* >>> */
  #define tSHR     275    /* >> */
  #define tINC     276    /* ++ */
  #define tDEC     277    /* -- */
  #define tELLIPS  278    /* ... */
  #define tDBLDOT  279    /* .. */
  #define tDBLCOLON 280   /* :: */
  /* reserved words (statements) */
  #define tASSERT  281
  #define tBREAK   282
  #define tCASE    283
  #define tCHAR    284
  #define tCONST   285
  #define tCONTINUE 286
  #define tDEFAULT 287
  #define tDEFINED 288
  #define tDO      289
  #define tELSE    290
  #define tENUM    291
  #define tEXIT    292
  #define tFOR     293
  #define tFORWARD 294
  #define tGOTO    295
  #define tIF      296
  #define tNATIVE  297
  #define tNEW     298
  #define tOPERATOR 299
  #define tPUBLIC  300
  #define tRETURN  301
  #define tSIZEOF  302
  #define tSLEEP   303
  #define tSTATE   304
  #define tSTATIC  305
  #define tSTOCK   306
  #define tSWITCH  307
  #define tTAGOF   308
  #define tWHILE   309
  /* compiler directives */
  #define tpASSERT 310    /* #assert */
  #define tpDEFINE 311
  #define tpELSE   312    /* #else */
  #define tpELSEIF 313    /* #elseif */
  #define tpEMIT   314
  #define tpENDIF  315
  #define tpENDINPUT 316
  #define tpENDSCRPT 317
  #define tpERROR  318
  #define tpFILE   319
  #define tpIF     320    /* #if */
  #define tINCLUDE 321
  #define tpLINE   322
  #define tpPRAGMA 323
  #define tpTRYINCLUDE 324
  #define tpUNDEF  325
  /* semicolon is a special case, because it can be optional */
  #define tTERM    326    /* semicolon or newline */
  #define tENDEXPR 327    /* forced end of expression */
  /* other recognized tokens */
  #define tNUMBER  328    /* integer number */
  #define tRATIONAL 329   /* rational number */
  #define tSYMBOL  330
  #define tLABEL   331
  #define tSTRING  332
  #define tPENDING_STRING 333
  #define tEXPR    334    /* for assigment to "lastst" only */
  #define tEMPTYBLOCK 335 /* empty blocks for AM bug 4825 */
  
  /* (reversed) evaluation of staging buffer */
  #define sSTARTREORDER 0x01
  #define sENDREORDER   0x02
  #define sEXPRSTART    0x80      /* top bit set, rest is free */
  #define sMAXARGS      127       /* relates to the bit pattern of sEXPRSTART */
  
  #define sDOCSEP       0x01      /* to separate documentation comments between functions */
  
  /* codes for ffabort() */
  #define xEXIT           1       /* exit code in PRI */
  #define xASSERTION      2       /* abort caused by failing assertion */
  #define xSTACKERROR     3       /* stack/heap overflow */
  #define xBOUNDSERROR    4       /* array index out of bounds */
  #define xMEMACCESS      5       /* data access error */
  #define xINVINSTR       6       /* invalid instruction */
  #define xSTACKUNDERFLOW 7       /* stack underflow */
  #define xHEAPUNDERFLOW  8       /* heap underflow */
  #define xCALLBACKERR    9       /* no, or invalid, callback */
  #define xSLEEP         12       /* sleep, exit code in PRI, tag in ALT */
  
  /* Miscellaneous  */
  #if !defined TRUE
    #define FALSE         0
    #define TRUE          1
  #endif
  #define sIN_CSEG        1       /* if parsing CODE */
  #define sIN_DSEG        2       /* if parsing DATA */
  #define sCHKBOUNDS      1       /* bit position in "debug" variable: check bounds */
  #define sSYMBOLIC       2       /* bit position in "debug" variable: symbolic info */
  #define sNOOPTIMIZE     4       /* bit position in "debug" variable: no optimization */
  #define sRESET          0       /* reset error flag */
  #define sFORCESET       1       /* force error flag on */
  #define sEXPRMARK       2       /* mark start of expression */
  #define sEXPRRELEASE    3       /* mark end of expression */
  #define sSETLINE        4       /* set line number for the error */
  #define sSETFILE        5       /* set file number for the error */
  
  typedef enum s_regid {
    sPRI,                         /* indicates the primary register */
    sALT,                         /* indicates the secundary register */
  } regid;
  
  typedef enum s_optmark {
    sEXPR,                        /* end of expression (for expressions that form a statement) */
    sPARM,                        /* end of parameter (in a function parameter list) */
    sLDECL,                       /* start of local declaration (variable) */
  } optmark;
  
  #if INT_MAX<0x8000u
    #define PUBLICTAG   0x8000u
    #define FIXEDTAG    0x4000u
  #else
    #define PUBLICTAG   0x80000000Lu
    #define FIXEDTAG    0x40000000Lu
  #endif
  #define TAGMASK       (~PUBLICTAG)
  
  
  /* interface functions */
  #if defined __cplusplus
    extern "C" {
  #endif
  
  /*
   * Functions you call from the "driver" program
   */
  int pc_compile(int argc, char **argv);
  int pc_addconstant(char *name,cell value,int tag);
  int pc_addtag(char *name);
  int pc_enablewarning(int number,int enable);
  
  /*
   * Functions called from the compiler (to be implemented by you)
   */
  
  /* general console output */
  #if PAWN_CELL_SIZE==32
  #if defined __WIN32__ || defined _WIN32 || defined WIN32
   __declspec (dllexport)
  int pc_printf(const char *message,...);
  #else
  extern int __attribute__((visibility("default"))) pc_printf(const char *message,...);
  #endif
  #else
  int pc_printf(const char *message, ...) INVISIBLE;
  #endif
  
  /* error report function */
  int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
  
  /* input from source file */
  void *pc_opensrc(char *filename); /* reading only */
  void *pc_createsrc(char *filename);
  void pc_closesrc(void *handle);   /* never delete */
  void pc_resetsrc(void *handle,void *position);  /* reset to a position marked earlier */
  char *pc_readsrc(void *handle,unsigned char *target,int maxchars);
  int pc_writesrc(void *handle,unsigned char *source);
  void *pc_getpossrc(void *handle); /* mark the current position */
  int  pc_eofsrc(void *handle);
  
  /* output to intermediate (.ASM) file */
  void *pc_openasm(char *filename); /* read/write */
  void pc_closeasm(void *handle,int deletefile);
  void pc_resetasm(void *handle);
  int  pc_writeasm(void *handle,char *str);
  char *pc_readasm(void *handle,char *target,int maxchars);
  
  /* output to binary (.AMX) file */
  void *pc_openbin(char *filename);
  void pc_closebin(void *handle,int deletefile);
  void pc_resetbin(void *handle,long offset);
  int  pc_writebin(void *handle,void *buffer,int size);
  long pc_lengthbin(void *handle); /* return the length of the file */
  
  #if defined __cplusplus
    }
  #endif
  
  
  /* by default, functions and variables used in throughout the compiler
   * files are "external"
   */
  #if !defined SC_FUNC
    #define SC_FUNC
  #endif
  #if !defined SC_VDECL
    #define SC_VDECL  extern
  #endif
  #if !defined SC_VDEFINE
    #define SC_VDEFINE
  #endif
  
  /* function prototypes in SC1.C */
  SC_FUNC void set_extension(char *filename,char *extension,int force);
  SC_FUNC symbol *fetchfunc(char *name,int tag);
  SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
  SC_FUNC char *funcdisplayname(char *dest,char *funcname);
  SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr);
  SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,short index);
  SC_FUNC constvalue *find_constval(constvalue *table,char *name,short index);
  SC_FUNC void delete_consttable(constvalue *table);
  SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
  SC_FUNC void exporttag(int tag);
  SC_FUNC void sc_attachdocumentation(symbol *sym);
  SC_FUNC int get_actual_compound(symbol *sym);
  #if !defined NO_DEFINE
  SC_FUNC void inst_file_name(char* filename, int strip_path);
  #endif
  
  
  /* function prototypes in SC2.C */
  #define PUSHSTK_P(v)  { stkitem s_; s_.pv=(v); pushstk(s_); }
  #define PUSHSTK_I(v)  { stkitem s_; s_.i=(v); pushstk(s_); }
  #define POPSTK_P()    (popstk().pv)
  #define POPSTK_I()    (popstk().i)
  SC_FUNC void pushstk(stkitem val);
  SC_FUNC stkitem popstk(void);
  SC_FUNC void clearstk(void);
  SC_FUNC int plungequalifiedfile(char *name);  /* explicit path included */
  SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths);   /* search through "include" paths */
  SC_FUNC void preprocess(void);
  SC_FUNC void lexinit(void);
  SC_FUNC int lex(cell *lexvalue,char **lexsym);
  SC_FUNC void lexpush(void);
  SC_FUNC void lexclr(int clreol);
  SC_FUNC int matchtoken(int token);
  SC_FUNC int tokeninfo(cell *val,char **str);
  SC_FUNC int needtoken(int token);
  SC_FUNC void litadd(cell value);
  SC_FUNC void litinsert(cell value,int pos);
  SC_FUNC int alphanum(char c);
  SC_FUNC int ishex(char c);
  SC_FUNC void delete_symbol(symbol *root,symbol *sym);
  SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
  SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
  SC_FUNC void markusage(symbol *sym,int usage);
  SC_FUNC symbol *findglb(const char *name);
  SC_FUNC symbol *findloc(const char *name);
  SC_FUNC symbol *findconst(const char *name);
  SC_FUNC symbol *finddepend(const symbol *parent);
  SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
                         int usage);
  SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
                              int dim[],int numdim,int idxtag[]);
  SC_FUNC int getlabel(void);
  SC_FUNC char *itoh(ucell val);
  
  /* function prototypes in SC3.C */
  SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
                           value *lval,int *resulttag);
  SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce);
  SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult);
  
  /* function prototypes in SC4.C */
  SC_FUNC void writeleader(symbol *root);
  SC_FUNC void writetrailer(void);
  SC_FUNC void begcseg(void);
  SC_FUNC void begdseg(void);
  SC_FUNC void setline(int chkbounds);
  SC_FUNC void setfiledirect(char *name);
  SC_FUNC void setlinedirect(int line);
  SC_FUNC void setlabel(int index);
  SC_FUNC void markexpr(optmark type,const char *name,cell offset);
  SC_FUNC void startfunc(char *fname);
  SC_FUNC void endfunc(void);
  SC_FUNC void alignframe(int numbytes);
  SC_FUNC void rvalue(value *lval);
  SC_FUNC void address(symbol *ptr,regid reg);
  SC_FUNC void store(value *lval);
  SC_FUNC void storereg(cell address,regid reg);
  SC_FUNC void memcopy(cell size);
  SC_FUNC void copyarray(symbol *sym,cell size);
  SC_FUNC void fillarray(symbol *sym,cell size,cell value);
  SC_FUNC void ldconst(cell val,regid reg);
  SC_FUNC void moveto1(void);
  SC_FUNC void pushreg(regid reg);
  SC_FUNC void pushval(cell val);
  SC_FUNC void popreg(regid reg);
  SC_FUNC void swap1(void);
  SC_FUNC void ffswitch(int label);
  SC_FUNC void ffcase(cell value,char *labelname,int newtable);
  SC_FUNC void ffcall(symbol *sym,const char *label,int numargs);
  SC_FUNC void ffret(void);
  SC_FUNC void ffabort(int reason);
  SC_FUNC void ffbounds(cell size);
  SC_FUNC void jumplabel(int number);
  SC_FUNC void defstorage(void);
  SC_FUNC void modstk(int delta);
  SC_FUNC void setstk(cell value);
  SC_FUNC void modheap(int delta);
  SC_FUNC void setheap_pri(void);
  SC_FUNC void setheap(cell value);
  SC_FUNC void cell2addr(void);
  SC_FUNC void cell2addr_alt(void);
  SC_FUNC void addr2cell(void);
  SC_FUNC void char2addr(void);
  SC_FUNC void charalign(void);
  SC_FUNC void addconst(cell value);
  SC_FUNC void move_alt(void);
  SC_FUNC void load_hidden_arg();
  
  /*  Code generation functions for arithmetic operators.
   *
   *  Syntax: o[u|s|b]_name
   *          |   |   | +--- name of operator
   *          |   |   +----- underscore
   *          |   +--------- "u"nsigned operator, "s"igned operator or "b"oth
   *          +------------- "o"perator
   */
  SC_FUNC void os_mult(void); /* multiplication (signed) */
  SC_FUNC void os_div(void);  /* division (signed) */
  SC_FUNC void os_mod(void);  /* modulus (signed) */
  SC_FUNC void ob_add(void);  /* addition */
  SC_FUNC void ob_sub(void);  /* subtraction */
  SC_FUNC void ob_sal(void);  /* shift left (arithmetic) */
  SC_FUNC void os_sar(void);  /* shift right (arithmetic, signed) */
  SC_FUNC void ou_sar(void);  /* shift right (logical, unsigned) */
  SC_FUNC void ob_or(void);   /* bitwise or */
  SC_FUNC void ob_xor(void);  /* bitwise xor */
  SC_FUNC void ob_and(void);  /* bitwise and */
  SC_FUNC void ob_eq(void);   /* equality */
  SC_FUNC void ob_ne(void);   /* inequality */
  SC_FUNC void relop_prefix(void);
  SC_FUNC void relop_suffix(void);
  SC_FUNC void os_le(void);   /* less or equal (signed) */
  SC_FUNC void os_ge(void);   /* greater or equal (signed) */
  SC_FUNC void os_lt(void);   /* less (signed) */
  SC_FUNC void os_gt(void);   /* greater (signed) */
  
  SC_FUNC void lneg(void);
  SC_FUNC void neg(void);
  SC_FUNC void invert(void);
  SC_FUNC void nooperation(void);
  SC_FUNC void inc(value *lval);
  SC_FUNC void dec(value *lval);
  SC_FUNC void jmp_ne0(int number);
  SC_FUNC void jmp_eq0(int number);
  SC_FUNC void outval(cell val,int newline);
  
  /* function prototypes in SC5.C */
  SC_FUNC int error(int number,...) INVISIBLE;
  SC_FUNC void errorset(int code, int line);
  
  /* function prototypes in SC6.C */
  SC_FUNC int assemble(FILE *fout,FILE *fin);
  
  /* function prototypes in SC7.C */
  SC_FUNC void stgbuffer_cleanup(void);
  SC_FUNC void stgmark(char mark);
  SC_FUNC void stgwrite(const char *st);
  SC_FUNC void stgout(int index);
  SC_FUNC void stgdel(int index,cell code_index);
  SC_FUNC int stgget(int *index,cell *code_index);
  SC_FUNC void stgset(int onoff);
  SC_FUNC int phopt_init(void);
  SC_FUNC int phopt_cleanup(void);
  
  /* function prototypes in SCLIST.C */
  SC_FUNC char* duplicatestring(const char* sourcestring);
  SC_FUNC stringpair *insert_alias(char *name,char *alias);
  SC_FUNC stringpair *find_alias(char *name);
  SC_FUNC int lookup_alias(char *target,char *name);
  SC_FUNC void delete_aliastable(void);
  SC_FUNC stringlist *insert_path(char *path);
  SC_FUNC char *get_path(int index);
  SC_FUNC void delete_pathtable(void);
  SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen);
  SC_FUNC int get_subst(int index,char **pattern,char **substitution);
  SC_FUNC stringpair *find_subst(char *name,int length);
  SC_FUNC int delete_subst(char *name,int length);
  SC_FUNC void delete_substtable(void);
  SC_FUNC stringlist *insert_sourcefile(char *string);
  SC_FUNC char *get_sourcefile(int index);
  SC_FUNC void delete_sourcefiletable(void);
  SC_FUNC stringlist *insert_inputfile(char *string);
  SC_FUNC char *get_inputfile(int index);
  SC_FUNC void delete_inputfiletable(void);
  SC_FUNC stringlist *insert_docstring(char *string);
  SC_FUNC char *get_docstring(int index);
  SC_FUNC void delete_docstring(int index);
  SC_FUNC void delete_docstringtable(void);
  SC_FUNC stringlist *insert_autolist(char *string);
  SC_FUNC char *get_autolist(int index);
  SC_FUNC void delete_autolisttable(void);
  SC_FUNC valuepair *push_heaplist(long first, long second);
  SC_FUNC int popfront_heaplist(long *first, long *second);
  SC_FUNC void delete_heaplisttable(void);
  SC_FUNC stringlist *insert_dbgfile(const char *filename);
  SC_FUNC stringlist *insert_dbgline(int linenr);
  SC_FUNC stringlist *insert_dbgsymbol(symbol *sym);
  SC_FUNC char *get_dbgstring(int index);
  SC_FUNC void delete_dbgstringtable(void);
  
  /* function prototypes in SCMEMFILE.C */
  #if !defined tMEMFILE
    typedef unsigned char MEMFILE;
    #define tMEMFILE  1
  #endif
  MEMFILE *mfcreate(char *filename);
  void mfclose(MEMFILE *mf);
  int mfdump(MEMFILE *mf);
  long mflength(MEMFILE *mf);
  long mfseek(MEMFILE *mf,long offset,int whence);
  unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size);
  unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size);
  char *mfgets(MEMFILE *mf,char *string,unsigned int size);
  int mfputs(MEMFILE *mf,char *string);
  
  /* function prototypes in SCI18N.C */
  #define MAXCODEPAGE 12
  SC_FUNC int cp_path(const char *root,const char *directory);
  SC_FUNC int cp_set(const char *name);
  SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr);
  
  /* function prototypes in SCSTATE.C */
  SC_FUNC constvalue *automaton_add(const char *name);
  SC_FUNC constvalue *automaton_find(const char *name);
  SC_FUNC constvalue *automaton_findid(int id);
  SC_FUNC constvalue *state_add(const char *name,int fsa_id);
  SC_FUNC constvalue *state_find(const char *name,int fsa_id);
  SC_FUNC constvalue *state_findid(int id);
  SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid);
  SC_FUNC int state_addlist(int *list,int count,int fsa_id);
  SC_FUNC void state_deletetable(void);
  SC_FUNC int state_getfsa(int listid);
  SC_FUNC int state_count(int listid);
  SC_FUNC int state_inlist(int listid,int state);
  SC_FUNC int state_listitem(int listid,int index);
  SC_FUNC void state_conflict(symbol *root);
  
  /* external variables (defined in scvars.c) */
  #if !defined SC_SKIP_VDECL
  typedef struct HashTable HashTable;
  SC_VDECL struct HashTable *sp_Globals;
  SC_VDECL symbol loctab;       /* local symbol table */
  SC_VDECL symbol glbtab;       /* global symbol table */
  SC_VDECL cell *litq;          /* the literal queue */
  SC_VDECL unsigned char pline[]; /* the line read from the input file */
  SC_VDECL const unsigned char *lptr;/* points to the current position in "pline" */
  SC_VDECL constvalue tagname_tab;/* tagname table */
  SC_VDECL constvalue libname_tab;/* library table (#pragma library "..." syntax) */
  SC_VDECL constvalue *curlibrary;/* current library */
  SC_VDECL int pc_addlibtable;  /* is the library table added to the AMX file? */
  SC_VDECL symbol *curfunc;     /* pointer to current function */
  SC_VDECL char *inpfname;      /* name of the file currently read from */
  SC_VDECL char outfname[];     /* intermediate (assembler) file name */
  SC_VDECL char binfname[];     /* binary file name */
  SC_VDECL char errfname[];     /* error file name */
  SC_VDECL char sc_ctrlchar;    /* the control character (or escape character) */
  SC_VDECL char sc_ctrlchar_org;/* the default control character */
  SC_VDECL int litidx;          /* index to literal table */
  SC_VDECL int litmax;          /* current size of the literal table */
  SC_VDECL int stgidx;          /* index to the staging buffer */
  SC_VDECL int sc_labnum;       /* number of (internal) labels */
  SC_VDECL int staging;         /* true if staging output */
  SC_VDECL cell declared;       /* number of local cells declared */
  SC_VDECL cell glb_declared;   /* number of global cells declared */
  SC_VDECL cell code_idx;       /* number of bytes with generated code */
  SC_VDECL int ntv_funcid;      /* incremental number of native function */
  SC_VDECL int errnum;          /* number of errors */
  SC_VDECL int warnnum;         /* number of warnings */
  SC_VDECL int sc_debug;        /* debug/optimization options (bit field) */
  SC_VDECL int sc_packstr;      /* strings are packed by default? */
  SC_VDECL int sc_asmfile;      /* create .ASM file? */
  SC_VDECL int sc_listing;      /* create .LST file? */
  SC_VDECL int sc_compress;     /* compress bytecode? */
  SC_VDECL int sc_needsemicolon;/* semicolon required to terminate expressions? */
  SC_VDECL int sc_dataalign;    /* data alignment value */
  SC_VDECL int sc_alignnext;    /* must frame of the next function be aligned? */
  SC_VDECL int pc_docexpr;      /* must expression be attached to documentation comment? */
  SC_VDECL int sc_showincludes; /* show include files? */
  SC_VDECL int curseg;          /* 1 if currently parsing CODE, 2 if parsing DATA */
  SC_VDECL cell sc_stksize;     /* stack size */
  SC_VDECL cell sc_amxlimit;    /* abstract machine size limit */
  SC_VDECL int freading;        /* is there an input file ready for reading? */
  SC_VDECL int fline;           /* the line number in the current file */
  SC_VDECL short fnumber;       /* number of files in the input file table */
  SC_VDECL short fcurrent;      /* current file being processed */
  SC_VDECL short sc_intest;     /* true if inside a test */
  SC_VDECL int sideeffect;      /* true if an expression causes a side-effect */
  SC_VDECL int stmtindent;      /* current indent of the statement */
  SC_VDECL int indent_nowarn;   /* skip warning "217 loose indentation" */
  SC_VDECL int sc_tabsize;      /* number of spaces that a TAB represents */
  SC_VDECL short sc_allowtags;  /* allow/detect tagnames in lex() */
  SC_VDECL int sc_status;       /* read/write status */
  SC_VDECL int sc_rationaltag;  /* tag for rational numbers */
  SC_VDECL int rational_digits; /* number of fractional digits */
  SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
  SC_VDECL char *pc_deprecate;  /* if non-NULL, mark next declaration as deprecated */
  SC_VDECL int sc_warnings_are_errors;
  
  SC_VDECL constvalue sc_automaton_tab; /* automaton table */
  SC_VDECL constvalue sc_state_tab;     /* state table */
  
  SC_VDECL int pc_anytag;
  
  SC_VDECL FILE *inpf;          /* file read from (source or include) */
  SC_VDECL FILE *inpf_org;      /* main source file */
  SC_VDECL FILE *outf;          /* file written to */
  
  SC_VDECL jmp_buf errbuf;      /* target of longjmp() on a fatal error */
  
  SC_VDECL SC_VDEFINE char sLiteralQueueDisabled;
  
  #if !defined SC_LIGHT
    SC_VDECL int sc_makereport; /* generate a cross-reference report */
  #endif
  
  #endif /* SC_SKIP_VDECL */
  
  #endif /* SC_H_INCLUDED */
  