sourcepawn/compiler/sc.h
author David Anderson <dvander@alliedmods.net>
Thu Mar 15 20:44:23 2007 +0000 (2007-03-15)
changeset 619 6934bf39171e
parent 510 546acad59370
child 632 5fd3bbbf2dc0
permissions -rw-r--r--
random touchups that might not be so great
     1 /*  Pawn compiler
     2  *
     3  *  Drafted after the Small-C compiler Version 2.01, originally created
     4  *  by Ron Cain, july 1980, and enhanced by James E. Hendrix.
     5  *
     6  *  This version comes close to a complete rewrite.
     7  *
     8  *  Copyright R. Cain, 1980
     9  *  Copyright J.E. Hendrix, 1982, 1983
    10  *  Copyright ITB CompuPhase, 1997-2006
    11  *
    12  *  This software is provided "as-is", without any express or implied warranty.
    13  *  In no event will the authors be held liable for any damages arising from
    14  *  the use of this software.
    15  *
    16  *  Permission is granted to anyone to use this software for any purpose,
    17  *  including commercial applications, and to alter it and redistribute it
    18  *  freely, subject to the following restrictions:
    19  *
    20  *  1.  The origin of this software must not be misrepresented; you must not
    21  *      claim that you wrote the original software. If you use this software in
    22  *      a product, an acknowledgment in the product documentation would be
    23  *      appreciated but is not required.
    24  *  2.  Altered source versions must be plainly marked as such, and must not be
    25  *      misrepresented as being the original software.
    26  *  3.  This notice may not be removed or altered from any source distribution.
    27  *
    28  *  Version: $Id$
    29  */
    30 #ifndef SC_H_INCLUDED
    31 #define SC_H_INCLUDED
    32 #include <limits.h>
    33 #include <stdarg.h>
    34 #include <stdio.h>
    35 #if defined __BORLANDC__ && defined _Windows && !(defined __32BIT__ || defined __WIN32__)
    36   /* setjmp() and longjmp() not well supported in 16-bit windows */
    37   #include <windows.h>
    38   typedef int jmp_buf[9];
    39   #define setjmp(b)     Catch(b)
    40   #define longjmp(b,e)  Throw(b,e)
    41 #else
    42   #include <setjmp.h>
    43 #endif
    44 #include "osdefs.h"
    45 #include "amx.h"
    46 
    47 /* Note: the "cell" and "ucell" types are defined in AMX.H */
    48 
    49 #define PUBLIC_CHAR '@'     /* character that defines a function "public" */
    50 #define CTRL_CHAR   '\\'    /* default control character */
    51 #define sCHARBITS   8       /* size of a packed character */
    52 
    53 #define sDIMEN_MAX     4    /* maximum number of array dimensions */
    54 #define sLINEMAX     1023   /* input line length (in characters) */
    55 #define sCOMP_STACK   32    /* maximum nesting of #if .. #endif sections */
    56 #define sDEF_LITMAX  500    /* initial size of the literal pool, in "cells" */
    57 #define sDEF_AMXSTACK 4096  /* default stack size for AMX files */
    58 #define PREPROC_TERM  '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
    59 #define sDEF_PREFIX   "sourcemod.inc" /* default prefix filename */
    60 #define sARGS_MAX		32	/* number of arguments a function can have, max */
    61 #define sTAGS_MAX		16  /* maximum number of tags on an argument */
    62 
    63 typedef union {
    64   void *pv;                 /* e.g. a name */
    65   int i;
    66 } stkitem;                  /* type of items stored on the compiler stack */
    67 
    68 typedef struct s_arginfo {  /* function argument info */
    69   char name[sNAMEMAX+1];
    70   char ident;           /* iVARIABLE, iREFERENCE, iREFARRAY or iVARARGS */
    71   char usage;           /* uCONST */
    72   int *tags;            /* argument tag id. list */
    73   int numtags;          /* number of tags in the tag list */
    74   int dim[sDIMEN_MAX];
    75   int idxtag[sDIMEN_MAX];
    76   int numdim;           /* number of dimensions */
    77   unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
    78   union {
    79     cell val;           /* default value */
    80     struct {
    81       char *symname;    /* name of another symbol */
    82       short level;      /* indirection level for that symbol */
    83     } size;             /* used for "sizeof" default value */
    84     struct {
    85       cell *data;       /* values of default array */
    86       int size;         /* complete length of default array */
    87       int arraysize;    /* size to reserve on the heap */
    88       cell addr;        /* address of the default array in the data segment */
    89     } array;
    90   } defvalue;           /* default value, or pointer to default array */
    91   int defvalue_tag;     /* tag of the default value */
    92 } arginfo;
    93 
    94 /*  Equate table, tagname table, library table */
    95 typedef struct s_constvalue {
    96   struct s_constvalue *next;
    97   char name[sNAMEMAX+1];
    98   cell value;
    99   int index;            /* index level, for constants referring to array sizes/tags
   100                          * automaton id. for states and automatons
   101                          * tag for enumeration lists */
   102 } constvalue;
   103 
   104 /*  Symbol table format
   105  *
   106  *  The symbol name read from the input file is stored in "name", the
   107  *  value of "addr" is written to the output file. The address in "addr"
   108  *  depends on the class of the symbol:
   109  *      global          offset into the data segment
   110  *      local           offset relative to the stack frame
   111  *      label           generated hexadecimal number
   112  *      function        offset into code segment
   113  */
   114 typedef struct s_symbol {
   115   struct s_symbol *next;
   116   struct s_symbol *parent;  /* hierarchical types (multi-dimensional arrays) */
   117   char name[sNAMEMAX+1];
   118   uint32_t hash;        /* value derived from name, for quicker searching */
   119   cell addr;            /* address or offset (or value for constant, index for native function) */
   120   cell codeaddr;        /* address (in the code segment) where the symbol declaration starts */
   121   char vclass;          /* sLOCAL if "addr" refers to a local symbol */
   122   char ident;           /* see below for possible values */
   123   short usage;          /* see below for possible values */
   124   char flags;           /* see below for possible values */
   125   int compound;         /* compound level (braces nesting level) */
   126   int tag;              /* tagname id */
   127   union {
   128     int declared;       /* label: how many local variables are declared */
   129     struct {
   130       int index;        /* array & enum: tag of array indices or the enum item */
   131       int field;        /* enumeration fields, where a size is attached to the field */
   132     } tags;             /* extra tags */
   133     constvalue *lib;    /* native function: library it is part of */
   134     long stacksize;     /* normal/public function: stack requirements */
   135   } x;                  /* 'x' for 'extra' */
   136   union {
   137     arginfo *arglist;   /* types of all parameters for functions */
   138     constvalue *enumlist;/* list of names for the "root" of an enumeration */
   139     struct {
   140       cell length;      /* arrays: length (size) */
   141       cell slength;		/* if a string index, this will be set to the original size */
   142       short level;      /* number of dimensions below this level */
   143     } array;
   144   } dim;                /* for 'dimension', both functions and arrays */
   145   constvalue *states;   /* list of state function/state variable ids + addresses */
   146   int fnumber;          /* static global variables: file number in which the declaration is visible */
   147   int lnumber;          /* line number (in the current source file) for the declaration */
   148   struct s_symbol **refer;  /* referrer list, functions that "use" this symbol */
   149   int numrefers;        /* number of entries in the referrer list */
   150   char *documentation;  /* optional documentation string */
   151 } symbol;
   152 
   153 
   154 /*  Possible entries for "ident". These are used in the "symbol", "value"
   155  *  and arginfo structures. Not every constant is valid for every use.
   156  *  In an argument list, the list is terminated with a "zero" ident; labels
   157  *  cannot be passed as function arguments, so the value 0 is overloaded.
   158  */
   159 #define iLABEL      0
   160 #define iVARIABLE   1   /* cell that has an address and that can be fetched directly (lvalue) */
   161 #define iREFERENCE  2   /* iVARIABLE, but must be dereferenced */
   162 #define iARRAY      3
   163 #define iREFARRAY   4   /* an array passed by reference (i.e. a pointer) */
   164 #define iARRAYCELL  5   /* array element, cell that must be fetched indirectly */
   165 #define iARRAYCHAR  6   /* array element, character from cell from array */
   166 #define iEXPRESSION 7   /* expression result, has no address (rvalue) */
   167 #define iCONSTEXPR  8   /* constant expression (or constant symbol) */
   168 #define iFUNCTN     9
   169 #define iREFFUNC    10
   170 #define iVARARGS    11  /* function specified ... as argument(s) */
   171 
   172 /*  Possible entries for "usage"
   173  *
   174  *  This byte is used as a serie of bits, the syntax is different for
   175  *  functions and other symbols:
   176  *
   177  *  VARIABLE
   178  *  bits: 0     (uDEFINE) the variable is defined in the source file
   179  *        1     (uREAD) the variable is "read" (accessed) in the source file
   180  *        2     (uWRITTEN) the variable is altered (assigned a value)
   181  *        3     (uCONST) the variable is constant (may not be assigned to)
   182  *        4     (uPUBLIC) the variable is public
   183  *        6     (uSTOCK) the variable is discardable (without warning)
   184  *
   185  *  FUNCTION
   186  *  bits: 0     (uDEFINE) the function is defined ("implemented") in the source file
   187  *        1     (uREAD) the function is invoked in the source file
   188  *        2     (uRETVALUE) the function returns a value (or should return a value)
   189  *        3     (uPROTOTYPED) the function was prototyped (implicitly via a definition or explicitly)
   190  *        4     (uPUBLIC) the function is public
   191  *        5     (uNATIVE) the function is native
   192  *        6     (uSTOCK) the function is discardable (without warning)
   193  *        7     (uMISSING) the function is not implemented in this source file
   194  *        8     (uFORWARD) the function is explicitly forwardly declared
   195  *
   196  *  CONSTANT
   197  *  bits: 0     (uDEFINE) the symbol is defined in the source file
   198  *        1     (uREAD) the constant is "read" (accessed) in the source file
   199  *        2     (uWRITTEN) redundant, but may be set for constants passed by reference
   200  *        3     (uPREDEF) the constant is pre-defined and should be kept between passes
   201  *        5     (uENUMROOT) the constant is the "root" of an enumeration
   202  *        6     (uENUMFIELD) the constant is a field in a named enumeration
   203  */
   204 #define uDEFINE   0x001
   205 #define uREAD     0x002
   206 #define uWRITTEN  0x004
   207 #define uRETVALUE 0x004 /* function returns (or should return) a value */
   208 #define uCONST    0x008
   209 #define uPROTOTYPED 0x008
   210 #define uPREDEF   0x008 /* constant is pre-defined */
   211 #define uPUBLIC   0x010
   212 #define uNATIVE   0x020
   213 #define uENUMROOT 0x020
   214 #define uSTOCK    0x040
   215 #define uENUMFIELD 0x040
   216 #define uMISSING  0x080
   217 #define uFORWARD  0x100
   218 #define uSTRUCT	  0x200 /* :TODO: make this an ident */
   219 /* uRETNONE is not stored in the "usage" field of a symbol. It is
   220  * used during parsing a function, to detect a mix of "return;" and
   221  * "return value;" in a few special cases.
   222  */
   223 #define uRETNONE  0x10
   224 
   225 #define flgDEPRECATED 0x01  /* symbol is deprecated (avoid use) */
   226 
   227 #define uCOUNTOF  0x20  /* set in the "hasdefault" field of the arginfo struct */
   228 #define uTAGOF    0x40  /* set in the "hasdefault" field of the arginfo struct */
   229 #define uSIZEOF   0x80  /* set in the "hasdefault" field of the arginfo struct */
   230 
   231 #define uMAINFUNC "main"
   232 #define uENTRYFUNC "entry"
   233 
   234 #define sGLOBAL   0     /* global variable/constant class (no states) */
   235 #define sLOCAL    1     /* local variable/constant */
   236 #define sSTATIC   2     /* global life, local scope */
   237 
   238 #define sSTATEVAR  3    /* criterion to find variables (sSTATEVAR implies a global variable) */
   239 
   240 typedef struct s_value {
   241   symbol *sym;          /* symbol in symbol table, NULL for (constant) expression */
   242   cell constval;        /* value of the constant expression (if ident==iCONSTEXPR)
   243                          * also used for the size of a literal array */
   244   int tag;              /* tag (of the expression) */
   245   int cmptag;           /* for searching symbols: choose the one with the matching tag */
   246   char ident;           /* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
   247                          * iEXPRESSION or iREFERENCE */
   248   char boolresult;      /* boolean result for relational operators */
   249   cell *arrayidx;       /* last used array indices, for checking self assignment */
   250 } value;
   251 
   252 /*  "while" statement queue (also used for "for" and "do - while" loops) */
   253 enum {
   254   wqBRK,        /* used to restore stack for "break" */
   255   wqCONT,       /* used to restore stack for "continue" */
   256   wqLOOP,       /* loop start label number */
   257   wqEXIT,       /* loop exit label number (jump if false) */
   258   /* --- */
   259   wqSIZE        /* "while queue" size */
   260 };
   261 #define wqTABSZ (24*wqSIZE)    /* 24 nested loop statements */
   262 
   263 enum {
   264   statIDLE,     /* not compiling yet */
   265   statFIRST,    /* first pass */
   266   statWRITE,    /* writing output */
   267   statSKIP,     /* skipping output */
   268 };
   269 
   270 typedef struct s_stringlist {
   271   struct s_stringlist *next;
   272   char *line;
   273 } stringlist;
   274 
   275 typedef struct s_stringpair {
   276   struct s_stringpair *next;
   277   char *first;
   278   char *second;
   279   int matchlength;
   280 } stringpair;
   281 
   282 /* macros for code generation */
   283 #define opcodes(n)      ((n)*sizeof(cell))      /* opcode size */
   284 #define opargs(n)       ((n)*sizeof(cell))      /* size of typical argument */
   285 
   286 /*  Tokens recognized by lex()
   287  *  Some of these constants are assigned as well to the variable "lastst" (see SC1.C)
   288  */
   289 #define tFIRST   256    /* value of first multi-character operator */
   290 #define tMIDDLE  280    /* value of last multi-character operator */
   291 #define tLAST    333    /* value of last multi-character match-able token */
   292 /* multi-character operators */
   293 #define taMULT   256    /* *= */
   294 #define taDIV    257    /* /= */
   295 #define taMOD    258    /* %= */
   296 #define taADD    259    /* += */
   297 #define taSUB    260    /* -= */
   298 #define taSHL    261    /* <<= */
   299 #define taSHRU   262    /* >>>= */
   300 #define taSHR    263    /* >>= */
   301 #define taAND    264    /* &= */
   302 #define taXOR    265    /* ^= */
   303 #define taOR     266    /* |= */
   304 #define tlOR     267    /* || */
   305 #define tlAND    268    /* && */
   306 #define tlEQ     269    /* == */
   307 #define tlNE     270    /* != */
   308 #define tlLE     271    /* <= */
   309 #define tlGE     272    /* >= */
   310 #define tSHL     273    /* << */
   311 #define tSHRU    274    /* >>> */
   312 #define tSHR     275    /* >> */
   313 #define tINC     276    /* ++ */
   314 #define tDEC     277    /* -- */
   315 #define tELLIPS  278    /* ... */
   316 #define tDBLDOT  279    /* .. */
   317 #define tDBLCOLON 280   /* :: */
   318 /* reserved words (statements) */
   319 #define tASSERT  281
   320 #define tBEGIN   282
   321 #define tBREAK   283
   322 #define tCASE    284
   323 #define tCELLSOF 285
   324 #define tCHAR    286
   325 #define tCONST   287
   326 #define tCONTINUE 288
   327 #define tDEFAULT 289
   328 #define tDEFINED 290
   329 #define tDO      291
   330 #define tELSE    292
   331 #define tEND     293
   332 #define tENUM    294
   333 #define tEXIT    295
   334 #define tFOR     296
   335 #define tFORWARD 297
   336 #define tFUNCENUM 298
   337 #define tFUNCTAG 299
   338 #define tGOTO    300
   339 #define tIF      301
   340 #define tNATIVE  302
   341 #define tNEW     303
   342 #define tDECL    304
   343 #define tOPERATOR 305
   344 #define tPUBLIC  306
   345 #define tRETURN  307
   346 #define tSIZEOF  308
   347 #define tSLEEP   309
   348 #define tSTATE   310
   349 #define tSTATIC  311
   350 #define tSTOCK   312
   351 #define tSTRUCT  313
   352 #define tSWITCH  314
   353 #define tTAGOF   315
   354 #define tTHEN    316
   355 #define tWHILE   317
   356 /* compiler directives */
   357 #define tpASSERT 318    /* #assert */
   358 #define tpDEFINE 319
   359 #define tpELSE   320    /* #else */
   360 #define tpELSEIF 321    /* #elseif */
   361 #define tpEMIT   322
   362 #define tpENDIF  323
   363 #define tpENDINPUT 324
   364 #define tpENDSCRPT 325
   365 #define tpERROR  326
   366 #define tpFILE   327
   367 #define tpIF     328    /* #if */
   368 #define tINCLUDE 329
   369 #define tpLINE   330
   370 #define tpPRAGMA 331
   371 #define tpTRYINCLUDE 332
   372 #define tpUNDEF  333
   373 /* semicolon is a special case, because it can be optional */
   374 #define tTERM    333    /* semicolon or newline */
   375 #define tENDEXPR 334    /* forced end of expression */
   376 /* other recognized tokens */
   377 #define tNUMBER  335    /* integer number */
   378 #define tRATIONAL 336   /* rational number */
   379 #define tSYMBOL  337
   380 #define tLABEL   338
   381 #define tSTRING  339
   382 #define tEXPR    340 /* for assigment to "lastst" only (see SC1.C) */
   383 #define tENDLESS 341 /* endless loop, for assigment to "lastst" only */
   384 
   385 /* (reversed) evaluation of staging buffer */
   386 #define sSTARTREORDER 0x01
   387 #define sENDREORDER   0x02
   388 #define sEXPRSTART    0x80      /* top bit set, rest is free */
   389 #define sMAXARGS      127       /* relates to the bit pattern of sEXPRSTART */
   390 
   391 #define sDOCSEP       0x01      /* to separate documentation comments between functions */
   392 
   393 /* codes for ffabort() */
   394 #define xEXIT           1       /* exit code in PRI */
   395 #define xASSERTION      2       /* abort caused by failing assertion */
   396 #define xSTACKERROR     3       /* stack/heap overflow */
   397 #define xBOUNDSERROR    4       /* array index out of bounds */
   398 #define xMEMACCESS      5       /* data access error */
   399 #define xINVINSTR       6       /* invalid instruction */
   400 #define xSTACKUNDERFLOW 7       /* stack underflow */
   401 #define xHEAPUNDERFLOW  8       /* heap underflow */
   402 #define xCALLBACKERR    9       /* no, or invalid, callback */
   403 #define xSLEEP         12       /* sleep, exit code in PRI, tag in ALT */
   404 
   405 /* Miscellaneous  */
   406 #if !defined TRUE
   407   #define FALSE         0
   408   #define TRUE          1
   409 #endif
   410 #define sIN_CSEG        1       /* if parsing CODE */
   411 #define sIN_DSEG        2       /* if parsing DATA */
   412 #define sCHKBOUNDS      1       /* bit position in "debug" variable: check bounds */
   413 #define sSYMBOLIC       2       /* bit position in "debug" variable: symbolic info */
   414 #define sRESET          0       /* reset error flag */
   415 #define sFORCESET       1       /* force error flag on */
   416 #define sEXPRMARK       2       /* mark start of expression */
   417 #define sEXPRRELEASE    3       /* mark end of expression */
   418 #define sSETPOS         4       /* set line number for the error */
   419 
   420 enum {
   421   sOPTIMIZE_NONE,               /* no optimization */
   422   sOPTIMIZE_NOMACRO,            /* no macro instructions */
   423   sOPTIMIZE_DEFAULT,            /* full optimization */
   424   /* ----- */
   425   sOPTIMIZE_NUMBER
   426 };
   427 
   428 typedef enum s_regid {
   429   sPRI,                         /* indicates the primary register */
   430   sALT,                         /* indicates the secundary register */
   431 } regid;
   432 
   433 typedef enum s_optmark {
   434   sEXPR,                        /* end of expression (for expressions that form a statement) */
   435   sPARM,                        /* end of parameter (in a function parameter list) */
   436   sLDECL,                       /* start of local declaration (variable) */
   437 } optmark;
   438 
   439 #define suSLEEP_INSTR 0x01      /* the "sleep" instruction was used */
   440 
   441 #if INT_MAX<0x8000u
   442   #define PUBLICTAG   0x8000u
   443   #define FIXEDTAG    0x4000u
   444   #define FUNCTAG     0x2000u
   445 #else
   446   #define PUBLICTAG   0x80000000Lu
   447   #define FIXEDTAG    0x40000000Lu
   448   #define FUNCTAG     0x20000000Lu
   449 #endif
   450 #define TAGMASK       (~PUBLICTAG)
   451 #define CELL_MAX      (((ucell)1 << (sizeof(cell)*8-1)) - 1)
   452 
   453 
   454 /* interface functions */
   455 #if defined __cplusplus
   456   extern "C" {
   457 #endif
   458 
   459 /*
   460  * Functions you call from the "driver" program
   461  */
   462 int pc_compile(int argc, char **argv);
   463 int pc_addconstant(char *name,cell value,int tag);
   464 int pc_addtag(char *name);
   465 int pc_addfunctag(char *name);
   466 int pc_enablewarning(int number,int enable);
   467 
   468 /*
   469  * Functions called from the compiler (to be implemented by you)
   470  */
   471 
   472 /* general console output */
   473 int pc_printf(const char *message,...);
   474 
   475 /* error report function */
   476 int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
   477 
   478 /* input from source file */
   479 void *pc_opensrc(char *filename); /* reading only */
   480 void *pc_createsrc(char *filename);
   481 void pc_closesrc(void *handle);   /* never delete */
   482 void pc_resetsrc(void *handle,void *position);  /* reset to a position marked earlier */
   483 char *pc_readsrc(void *handle,unsigned char *target,int maxchars);
   484 int pc_writesrc(void *handle,unsigned char *source);
   485 void *pc_getpossrc(void *handle); /* mark the current position */
   486 int  pc_eofsrc(void *handle);
   487 
   488 /* output to intermediate (.ASM) file */
   489 void *pc_openasm(char *filename); /* read/write */
   490 void pc_closeasm(void *handle,int deletefile);
   491 void pc_resetasm(void *handle);
   492 int  pc_writeasm(void *handle,char *str);
   493 char *pc_readasm(void *handle,char *target,int maxchars);
   494 
   495 /* output to binary (.AMX) file */
   496 void *pc_openbin(char *filename);
   497 void pc_closebin(void *handle,int deletefile);
   498 void pc_resetbin(void *handle,long offset);
   499 int  pc_writebin(void *handle,void *buffer,int size);
   500 long pc_lengthbin(void *handle); /* return the length of the file */
   501 
   502 #if defined __cplusplus
   503   }
   504 #endif
   505 
   506 
   507 /* by default, functions and variables used in throughout the compiler
   508  * files are "external"
   509  */
   510 #if !defined SC_FUNC
   511   #define SC_FUNC
   512 #endif
   513 #if !defined SC_VDECL
   514   #define SC_VDECL  extern
   515 #endif
   516 #if !defined SC_VDEFINE
   517   #define SC_VDEFINE
   518 #endif
   519 
   520 /* function prototypes in SC1.C */
   521 SC_FUNC void set_extension(char *filename,char *extension,int force);
   522 SC_FUNC symbol *fetchfunc(char *name,int tag);
   523 SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
   524 SC_FUNC char *funcdisplayname(char *dest,char *funcname);
   525 SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr);
   526 SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index);
   527 SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
   528 SC_FUNC void delete_consttable(constvalue *table);
   529 SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
   530 SC_FUNC void exporttag(int tag);
   531 SC_FUNC void sc_attachdocumentation(symbol *sym);
   532 SC_FUNC constvalue *find_tag_byval(int tag);
   533 
   534 /* function prototypes in SC2.C */
   535 #define PUSHSTK_P(v)  { stkitem s_; s_.pv=(v); pushstk(s_); }
   536 #define PUSHSTK_I(v)  { stkitem s_; s_.i=(v); pushstk(s_); }
   537 #define POPSTK_P()    (popstk().pv)
   538 #define POPSTK_I()    (popstk().i)
   539 SC_FUNC void pushstk(stkitem val);
   540 SC_FUNC stkitem popstk(void);
   541 SC_FUNC void clearstk(void);
   542 SC_FUNC int plungequalifiedfile(char *name);  /* explicit path included */
   543 SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths);   /* search through "include" paths */
   544 SC_FUNC void preprocess(void);
   545 SC_FUNC void lexinit(void);
   546 SC_FUNC int lex(cell *lexvalue,char **lexsym);
   547 SC_FUNC void lexpush(void);
   548 SC_FUNC void lexclr(int clreol);
   549 SC_FUNC int matchtoken(int token);
   550 SC_FUNC int tokeninfo(cell *val,char **str);
   551 SC_FUNC int needtoken(int token);
   552 SC_FUNC void litadd(cell value);
   553 SC_FUNC void litinsert(cell value,int pos);
   554 SC_FUNC int alphanum(char c);
   555 SC_FUNC int ishex(char c);
   556 SC_FUNC void delete_symbol(symbol *root,symbol *sym);
   557 SC_FUNC void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
   558 SC_FUNC int refer_symbol(symbol *entry,symbol *bywhom);
   559 SC_FUNC void markusage(symbol *sym,int usage);
   560 SC_FUNC uint32_t namehash(const char *name);
   561 SC_FUNC symbol *findglb(const char *name,int filter);
   562 SC_FUNC symbol *findloc(const char *name);
   563 SC_FUNC symbol *findconst(const char *name,int *matchtag);
   564 SC_FUNC symbol *finddepend(const symbol *parent);
   565 SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
   566                        int usage);
   567 SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
   568                             int dim[],int numdim,int idxtag[]);
   569 SC_FUNC symbol *addvariable2(const char *name,cell addr,int ident,int vclass,int tag,
   570 							 int dim[],int numdim,int idxtag[],int slength);
   571 SC_FUNC int getlabel(void);
   572 SC_FUNC char *itoh(ucell val);
   573 
   574 /* function prototypes in SC3.C */
   575 SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
   576                          value *lval,int *resulttag);
   577 SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce);
   578 SC_FUNC int checktag(int tags[],int numtags,int exprtag);
   579 SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult,value *_lval);
   580 SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state);
   581 SC_FUNC cell array_totalsize(symbol *sym);
   582 SC_FUNC int matchtag_string(int ident, int tag);
   583 SC_FUNC int checktag_string(value *sym1, value *sym2);
   584 SC_FUNC int checktags_string(int tags[], int numtags, value *sym1);
   585 
   586 /* function prototypes in SC4.C */
   587 SC_FUNC void writeleader(symbol *root);
   588 SC_FUNC void writetrailer(void);
   589 SC_FUNC void begcseg(void);
   590 SC_FUNC void begdseg(void);
   591 SC_FUNC void setline(int chkbounds);
   592 SC_FUNC void setfiledirect(char *name);
   593 SC_FUNC void setlinedirect(int line);
   594 SC_FUNC void setlabel(int index);
   595 SC_FUNC void markexpr(optmark type,const char *name,cell offset);
   596 SC_FUNC void startfunc(char *fname);
   597 SC_FUNC void endfunc(void);
   598 SC_FUNC void alignframe(int numbytes);
   599 SC_FUNC void rvalue(value *lval);
   600 SC_FUNC void address(symbol *ptr,regid reg);
   601 SC_FUNC void store(value *lval);
   602 SC_FUNC void loadreg(cell address,regid reg);
   603 SC_FUNC void storereg(cell address,regid reg);
   604 SC_FUNC void memcopy(cell size);
   605 SC_FUNC void copyarray(symbol *sym,cell size);
   606 SC_FUNC void fillarray(symbol *sym,cell size,cell value);
   607 SC_FUNC void ldconst(cell val,regid reg);
   608 SC_FUNC void moveto1(void);
   609 SC_FUNC void pushreg(regid reg);
   610 SC_FUNC void pushval(cell val);
   611 SC_FUNC void popreg(regid reg);
   612 SC_FUNC void genarray(int dims, int _autozero);
   613 SC_FUNC void swap1(void);
   614 SC_FUNC void ffswitch(int label);
   615 SC_FUNC void ffcase(cell value,char *labelname,int newtable);
   616 SC_FUNC void ffcall(symbol *sym,const char *label,int numargs);
   617 SC_FUNC void ffret(int remparams);
   618 SC_FUNC void ffabort(int reason);
   619 SC_FUNC void ffbounds(cell size);
   620 SC_FUNC void jumplabel(int number);
   621 SC_FUNC void defstorage(void);
   622 SC_FUNC void modstk(int delta);
   623 SC_FUNC void setstk(cell value);
   624 SC_FUNC void modheap(int delta);
   625 SC_FUNC void modheap_i();
   626 SC_FUNC void setheap_pri(void);
   627 SC_FUNC void setheap(cell value);
   628 SC_FUNC void cell2addr(void);
   629 SC_FUNC void cell2addr_alt(void);
   630 SC_FUNC void addr2cell(void);
   631 SC_FUNC void char2addr(void);
   632 SC_FUNC void charalign(void);
   633 SC_FUNC void addconst(cell value);
   634 SC_FUNC void setheap_save(cell value);
   635 SC_FUNC void stradjust(regid reg);
   636 
   637 /*  Code generation functions for arithmetic operators.
   638  *
   639  *  Syntax: o[u|s|b]_name
   640  *          |   |   | +--- name of operator
   641  *          |   |   +----- underscore
   642  *          |   +--------- "u"nsigned operator, "s"igned operator or "b"oth
   643  *          +------------- "o"perator
   644  */
   645 SC_FUNC void os_mult(void); /* multiplication (signed) */
   646 SC_FUNC void os_div(void);  /* division (signed) */
   647 SC_FUNC void os_mod(void);  /* modulus (signed) */
   648 SC_FUNC void ob_add(void);  /* addition */
   649 SC_FUNC void ob_sub(void);  /* subtraction */
   650 SC_FUNC void ob_sal(void);  /* shift left (arithmetic) */
   651 SC_FUNC void os_sar(void);  /* shift right (arithmetic, signed) */
   652 SC_FUNC void ou_sar(void);  /* shift right (logical, unsigned) */
   653 SC_FUNC void ob_or(void);   /* bitwise or */
   654 SC_FUNC void ob_xor(void);  /* bitwise xor */
   655 SC_FUNC void ob_and(void);  /* bitwise and */
   656 SC_FUNC void ob_eq(void);   /* equality */
   657 SC_FUNC void ob_ne(void);   /* inequality */
   658 SC_FUNC void relop_prefix(void);
   659 SC_FUNC void relop_suffix(void);
   660 SC_FUNC void os_le(void);   /* less or equal (signed) */
   661 SC_FUNC void os_ge(void);   /* greater or equal (signed) */
   662 SC_FUNC void os_lt(void);   /* less (signed) */
   663 SC_FUNC void os_gt(void);   /* greater (signed) */
   664 
   665 SC_FUNC void lneg(void);
   666 SC_FUNC void neg(void);
   667 SC_FUNC void invert(void);
   668 SC_FUNC void nooperation(void);
   669 SC_FUNC void inc(value *lval);
   670 SC_FUNC void dec(value *lval);
   671 SC_FUNC void jmp_ne0(int number);
   672 SC_FUNC void jmp_eq0(int number);
   673 SC_FUNC void outval(cell val,int newline);
   674 
   675 /* function prototypes in SC5.C */
   676 SC_FUNC int error(int number,...);
   677 SC_FUNC void errorset(int code,int line);
   678 
   679 /* function prototypes in SC6.C */
   680 SC_FUNC int assemble(FILE *fout,FILE *fin);
   681 
   682 /* function prototypes in SC7.C */
   683 SC_FUNC void stgbuffer_cleanup(void);
   684 SC_FUNC void stgmark(char mark);
   685 SC_FUNC void stgwrite(const char *st);
   686 SC_FUNC void stgout(int index);
   687 SC_FUNC void stgdel(int index,cell code_index);
   688 SC_FUNC int stgget(int *index,cell *code_index);
   689 SC_FUNC void stgset(int onoff);
   690 SC_FUNC int phopt_init(void);
   691 SC_FUNC int phopt_cleanup(void);
   692 
   693 /* function prototypes in SCLIST.C */
   694 SC_FUNC char* duplicatestring(const char* sourcestring);
   695 SC_FUNC stringpair *insert_alias(char *name,char *alias);
   696 SC_FUNC stringpair *find_alias(char *name);
   697 SC_FUNC int lookup_alias(char *target,char *name);
   698 SC_FUNC void delete_aliastable(void);
   699 SC_FUNC stringlist *insert_path(char *path);
   700 SC_FUNC char *get_path(int index);
   701 SC_FUNC void delete_pathtable(void);
   702 SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen);
   703 SC_FUNC int get_subst(int index,char **pattern,char **substitution);
   704 SC_FUNC stringpair *find_subst(char *name,int length);
   705 SC_FUNC int delete_subst(char *name,int length);
   706 SC_FUNC void delete_substtable(void);
   707 SC_FUNC stringlist *insert_sourcefile(char *string);
   708 SC_FUNC char *get_sourcefile(int index);
   709 SC_FUNC void delete_sourcefiletable(void);
   710 SC_FUNC stringlist *insert_docstring(char *string);
   711 SC_FUNC char *get_docstring(int index);
   712 SC_FUNC void delete_docstring(int index);
   713 SC_FUNC void delete_docstringtable(void);
   714 SC_FUNC stringlist *insert_autolist(char *string);
   715 SC_FUNC char *get_autolist(int index);
   716 SC_FUNC void delete_autolisttable(void);
   717 SC_FUNC stringlist *insert_dbgfile(const char *filename);
   718 SC_FUNC stringlist *insert_dbgline(int linenr);
   719 SC_FUNC stringlist *insert_dbgsymbol(symbol *sym);
   720 SC_FUNC char *get_dbgstring(int index);
   721 SC_FUNC void delete_dbgstringtable(void);
   722 
   723 /* function prototypes in SCMEMFILE.C */
   724 #if !defined tMEMFILE
   725   typedef unsigned char MEMFILE;
   726   #define tMEMFILE  1
   727 #endif
   728 MEMFILE *mfcreate(const char *filename);
   729 void mfclose(MEMFILE *mf);
   730 int mfdump(MEMFILE *mf);
   731 long mflength(const MEMFILE *mf);
   732 long mfseek(MEMFILE *mf,long offset,int whence);
   733 unsigned int mfwrite(MEMFILE *mf,const unsigned char *buffer,unsigned int size);
   734 unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size);
   735 char *mfgets(MEMFILE *mf,char *string,unsigned int size);
   736 int mfputs(MEMFILE *mf,const char *string);
   737 
   738 /* function prototypes in SCI18N.C */
   739 #define MAXCODEPAGE 12
   740 SC_FUNC int cp_path(const char *root,const char *directory);
   741 SC_FUNC int cp_set(const char *name);
   742 SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr);
   743 SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr);
   744 SC_FUNC int scan_utf8(FILE *fp,const char *filename);
   745 
   746 /* function prototypes in SCSTATE.C */
   747 SC_FUNC constvalue *automaton_add(const char *name);
   748 SC_FUNC constvalue *automaton_find(const char *name);
   749 SC_FUNC constvalue *automaton_findid(int id);
   750 SC_FUNC constvalue *state_add(const char *name,int fsa_id);
   751 SC_FUNC constvalue *state_find(const char *name,int fsa_id);
   752 SC_FUNC constvalue *state_findid(int id);
   753 SC_FUNC void state_buildlist(int **list,int *listsize,int *count,int stateid);
   754 SC_FUNC int state_addlist(int *list,int count,int fsa_id);
   755 SC_FUNC void state_deletetable(void);
   756 SC_FUNC int state_getfsa(int listid);
   757 SC_FUNC int state_count(int listid);
   758 SC_FUNC int state_inlist(int listid,int state);
   759 SC_FUNC int state_listitem(int listid,int index);
   760 SC_FUNC void state_conflict(symbol *root);
   761 SC_FUNC int state_conflict_id(int listid1,int listid2);
   762 
   763 /* external variables (defined in scvars.c) */
   764 #if !defined SC_SKIP_VDECL
   765 SC_VDECL symbol loctab;       /* local symbol table */
   766 SC_VDECL symbol glbtab;       /* global symbol table */
   767 SC_VDECL cell *litq;          /* the literal queue */
   768 SC_VDECL unsigned char pline[]; /* the line read from the input file */
   769 SC_VDECL const unsigned char *lptr;/* points to the current position in "pline" */
   770 SC_VDECL constvalue tagname_tab;/* tagname table */
   771 SC_VDECL constvalue libname_tab;/* library table (#pragma library "..." syntax) */
   772 SC_VDECL constvalue *curlibrary;/* current library */
   773 SC_VDECL int pc_addlibtable;  /* is the library table added to the AMX file? */
   774 SC_VDECL symbol *curfunc;     /* pointer to current function */
   775 SC_VDECL char *inpfname;      /* name of the file currently read from */
   776 SC_VDECL char outfname[];     /* intermediate (assembler) file name */
   777 SC_VDECL char binfname[];     /* binary file name */
   778 SC_VDECL char errfname[];     /* error file name */
   779 SC_VDECL char sc_ctrlchar;    /* the control character (or escape character) */
   780 SC_VDECL char sc_ctrlchar_org;/* the default control character */
   781 SC_VDECL int litidx;          /* index to literal table */
   782 SC_VDECL int litmax;          /* current size of the literal table */
   783 SC_VDECL int stgidx;          /* index to the staging buffer */
   784 SC_VDECL int sc_labnum;       /* number of (internal) labels */
   785 SC_VDECL int staging;         /* true if staging output */
   786 SC_VDECL cell declared;       /* number of local cells declared */
   787 SC_VDECL cell glb_declared;   /* number of global cells declared */
   788 SC_VDECL cell code_idx;       /* number of bytes with generated code */
   789 SC_VDECL int ntv_funcid;      /* incremental number of native function */
   790 SC_VDECL int errnum;          /* number of errors */
   791 SC_VDECL int warnnum;         /* number of warnings */
   792 SC_VDECL int sc_debug;        /* debug/optimization options (bit field) */
   793 SC_VDECL int sc_packstr;      /* strings are packed by default? */
   794 SC_VDECL int sc_asmfile;      /* create .ASM file? */
   795 SC_VDECL int sc_listing;      /* create .LST file? */
   796 SC_VDECL int sc_compress;     /* compress bytecode? */
   797 SC_VDECL int sc_needsemicolon;/* semicolon required to terminate expressions? */
   798 SC_VDECL int sc_dataalign;    /* data alignment value */
   799 SC_VDECL int sc_alignnext;    /* must frame of the next function be aligned? */
   800 SC_VDECL int pc_docexpr;      /* must expression be attached to documentation comment? */
   801 SC_VDECL int curseg;          /* 1 if currently parsing CODE, 2 if parsing DATA */
   802 SC_VDECL cell pc_stksize;     /* stack size */
   803 SC_VDECL cell pc_amxlimit;    /* abstract machine size limit (code + data, or only code) */
   804 SC_VDECL cell pc_amxram;      /* abstract machine data size limit */
   805 SC_VDECL int freading;        /* is there an input file ready for reading? */
   806 SC_VDECL int fline;           /* the line number in the current file */
   807 SC_VDECL short fnumber;       /* number of files in the file table (debugging) */
   808 SC_VDECL short fcurrent;      /* current file being processed (debugging) */
   809 SC_VDECL short sc_intest;     /* true if inside a test */
   810 SC_VDECL int sideeffect;      /* true if an expression causes a side-effect */
   811 SC_VDECL int stmtindent;      /* current indent of the statement */
   812 SC_VDECL int indent_nowarn;   /* skip warning "217 loose indentation" */
   813 SC_VDECL int sc_tabsize;      /* number of spaces that a TAB represents */
   814 SC_VDECL short sc_allowtags;  /* allow/detect tagnames in lex() */
   815 SC_VDECL int sc_status;       /* read/write status */
   816 SC_VDECL int sc_rationaltag;  /* tag for rational numbers */
   817 SC_VDECL int rational_digits; /* number of fractional digits */
   818 SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
   819 SC_VDECL short sc_is_utf8;    /* is this source file in UTF-8 encoding */
   820 SC_VDECL char *pc_deprecate;  /* if non-NULL, mark next declaration as deprecated */
   821 SC_VDECL int sc_curstates;    /* ID of the current state list */
   822 SC_VDECL int pc_optimize;     /* (peephole) optimization level */
   823 SC_VDECL int pc_memflags;     /* special flags for the stack/heap usage */
   824 SC_VDECL int pc_functag;      /* global function tag */
   825 SC_VDECL int pc_tag_string;   /* global string tag */
   826 SC_VDECL int glbstringread;	  /* last global string read */
   827 
   828 SC_VDECL constvalue sc_automaton_tab; /* automaton table */
   829 SC_VDECL constvalue sc_state_tab;     /* state table */
   830 
   831 SC_VDECL FILE *inpf;          /* file read from (source or include) */
   832 SC_VDECL FILE *inpf_org;      /* main source file */
   833 SC_VDECL FILE *outf;          /* file written to */
   834 
   835 SC_VDECL jmp_buf errbuf;      /* target of longjmp() on a fatal error */
   836 
   837 #if !defined SC_LIGHT
   838   SC_VDECL int sc_makereport; /* generate a cross-reference report */
   839 #endif
   840 
   841 #if defined WIN32
   842 #if !defined snprintf
   843 #define snprintf _snprintf
   844 #endif
   845 #endif
   846 
   847 #endif /* SC_SKIP_VDECL */
   848 
   849 #endif /* SC_H_INCLUDED */