1 /*  Small 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 T. Riemersma, 1997-2003
11  *
12  *  Version: $Id$
13  *
14  *  This software is provided "as-is", without any express or implied warranty.
15  *  In no event will the authors be held liable for any damages arising from
16  *  the use of this software.
17  *
18  *  Permission is granted to anyone to use this software for any purpose,
19  *  including commercial applications, and to alter it and redistribute it
20  *  freely, subject to the following restrictions:
21  *
22  *  1.  The origin of this software must not be misrepresented; you must not
23  *      claim that you wrote the original software. If you use this software in
24  *      a product, an acknowledgment in the product documentation would be
25  *      appreciated but is not required.
26  *  2.  Altered source versions must be plainly marked as such, and must not be
27  *      misrepresented as being the original software.
28  *  3.  This notice may not be removed or altered from any source distribution.
29  */
30 
31 #ifndef EMBRYO_CC_SC_H
32 #define EMBRYO_CC_SC_H
33 
34 #include <limits.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <setjmp.h>
38 #include <stdint.h>
39 
40 #include "embryo_cc_amx.h"
41 
42 /* Note: the "cell" and "ucell" types are defined in AMX.H */
43 
44 #define PUBLIC_CHAR '@'		/* character that defines a function "public" */
45 #define CTRL_CHAR   '\\'	/* default control character */
46 
47 #define DIRSEP_CHAR '/'		/* directory separator character */
48 
49 #define sDIMEN_MAX     2	/* maximum number of array dimensions */
50 #define sDEF_LITMAX  500	/* initial size of the literal pool, in "cells" */
51 #define sLINEMAX (640 * 1024)	/* input line length (in characters) */
52 #define sDEF_AMXSTACK 4096	/* default stack size for AMX files */
53 #define sSTKMAX       80	/* stack for nested #includes and other uses */
54 #define PREPROC_TERM  '\x7f'	/* termination character for preprocessor expressions (the "DEL" code) */
55 #define sDEF_PREFIX   "default.inc"	/* default prefix filename */
56 
57 typedef intptr_t stkitem;	/* type of items stored on the stack */
58 
59 typedef struct __s_arginfo
60 {				/* function argument info */
61    char                name[sNAMEMAX + 1];
62    char                ident;	/* iVARIABLE, iREFERENCE, iREFARRAY or iVARARGS */
63    char                usage;	/* uCONST */
64    int                *tags;	/* argument tag id. list */
65    int                 numtags;	/* number of tags in the tag list */
66    int                 dim[sDIMEN_MAX];
67    int                 numdim;	/* number of dimensions */
68    unsigned char       hasdefault;	/* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
69    union
70    {
71       cell                val;	/* default value */
72       struct
73       {
74 	 char               *symname;	/* name of another symbol */
75 	 short               level;	/* indirection level for that symbol */
76       } size;			/* used for "sizeof" default value */
77       struct
78       {
79 	 cell               *data;	/* values of default array */
80 	 int                 size;	/* complete length of default array */
81 	 int                 arraysize;	/* size to reserve on the heap */
82 	 cell                addr;	/* address of the default array in the data segment */
83       } array;
84    } defvalue;			/* default value, or pointer to default array */
85    int                 defvalue_tag;	/* tag of the default value */
86 } arginfo;
87 
88 /*  Equate table, tagname table, library table */
89 typedef struct __s_constvalue
90 {
91    struct __s_constvalue *next;
92    char                name[sNAMEMAX + 1];
93    cell                value;
94    short               index;
95 } constvalue;
96 
97 /*  Symbol table format
98  *
99  *  The symbol name read from the input file is stored in "name", the
100  *  value of "addr" is written to the output file. The address in "addr"
101  *  depends on the class of the symbol:
102  *      global          offset into the data segment
103  *      local           offset relative to the stack frame
104  *      label           generated hexadecimal number
105  *      function        offset into code segment
106  */
107 typedef struct __s_symbol
108 {
109    struct __s_symbol  *next;
110    struct __s_symbol  *parent;	/* hierarchical types (multi-dimensional arrays) */
111    char                name[sNAMEMAX + 1];
112    unsigned int        hash;	/* value derived from name, for quicker searching */
113    cell                addr;	/* address or offset (or value for constant, index for native function) */
114    char                vclass;	/* sLOCAL if "addr" refers to a local symbol */
115    char                ident;	/* see below for possible values */
116    char                usage;	/* see below for possible values */
117    int                 compound;	/* compound level (braces nesting level) */
118    int                 tag;	/* tagname id */
119    union
120    {
121       int                 declared;	/* label: how many local variables are declared */
122       int                 idxtag;	/* array: tag of array indices */
123       constvalue         *lib;	/* native function: library it is part of *///??? use "stringlist"
124    } x;				/* 'x' for 'extra' */
125    union
126    {
127       arginfo            *arglist;	/* types of all parameters for functions */
128       struct
129       {
130 	 cell                length;	/* arrays: length (size) */
131 	 short               level;	/* number of dimensions below this level */
132       } array;
133    } dim;			/* for 'dimension', both functions and arrays */
134    int                 fnumber;	/* static global variables: file number in which the declaration is visible */
135    struct __s_symbol **refer;	/* referrer list, functions that "use" this symbol */
136    int                 numrefers;	/* number of entries in the referrer list */
137 } symbol;
138 
139 /*  Possible entries for "ident". These are used in the "symbol", "value"
140  *  and arginfo structures. Not every constant is valid for every use.
141  *  In an argument list, the list is terminated with a "zero" ident; labels
142  *  cannot be passed as function arguments, so the value 0 is overloaded.
143  */
144 #define iLABEL      0
145 #define iVARIABLE   1		/* cell that has an address and that can be fetched directly (lvalue) */
146 #define iREFERENCE  2		/* iVARIABLE, but must be dereferenced */
147 #define iARRAY      3
148 #define iREFARRAY   4		/* an array passed by reference (i.e. a pointer) */
149 #define iARRAYCELL  5		/* array element, cell that must be fetched indirectly */
150 #define iARRAYCHAR  6		/* array element, character from cell from array */
151 #define iEXPRESSION 7		/* expression result, has no address (rvalue) */
152 #define iCONSTEXPR  8		/* constant expression (or constant symbol) */
153 #define iFUNCTN     9
154 #define iREFFUNC    10		/* function passed as a parameter */
155 #define iVARARGS    11		/* function specified ... as argument(s) */
156 
157 /*  Possible entries for "usage"
158  *
159  *  This byte is used as a series of bits, the syntax is different for
160  *  functions and other symbols:
161  *
162  *  VARIABLE
163  *  bits: 0     (uDEFINE) the variable is defined in the source file
164  *        1     (uREAD) the variable is "read" (accessed) in the source file
165  *        2     (uWRITTEN) the variable is altered (assigned a value)
166  *        3     (uCONST) the variable is constant (may not be assigned to)
167  *        4     (uPUBLIC) the variable is public
168  *        6     (uSTOCK) the variable is discardable (without warning)
169  *
170  *  FUNCTION
171  *  bits: 0     (uDEFINE) the function is defined ("implemented") in the source file
172  *        1     (uREAD) the function is invoked in the source file
173  *        2     (uRETVALUE) the function returns a value (or should return a value)
174  *        3     (uPROTOTYPED) the function was prototyped
175  *        4     (uPUBLIC) the function is public
176  *        5     (uNATIVE) the function is native
177  *        6     (uSTOCK) the function is discardable (without warning)
178  *        7     (uMISSING) the function is not implemented in this source file
179  *
180  *  CONSTANT
181  *  bits: 0     (uDEFINE) the symbol is defined in the source file
182  *        1     (uREAD) the constant is "read" (accessed) in the source file
183  *        3     (uPREDEF) the constant is pre-defined and should be kept between passes
184  */
185 #define uDEFINE   0x01
186 #define uREAD     0x02
187 #define uWRITTEN  0x04
188 #define uRETVALUE 0x04		/* function returns (or should return) a value */
189 #define uCONST    0x08
190 #define uPROTOTYPED 0x08
191 #define uPREDEF   0x08		/* constant is pre-defined */
192 #define uPUBLIC   0x10
193 #define uNATIVE   0x20
194 #define uSTOCK    0x40
195 #define uMISSING  0x80
196 /* uRETNONE is not stored in the "usage" field of a symbol. It is
197  * used during parsing a function, to detect a mix of "return;" and
198  * "return value;" in a few special cases.
199  */
200 #define uRETNONE  0x10
201 
202 #define uTAGOF    0x40		/* set in the "hasdefault" field of the arginfo struct */
203 #define uSIZEOF   0x80		/* set in the "hasdefault" field of the arginfo struct */
204 
205 #define uMAINFUNC "main"
206 
207 #define sGLOBAL   0		/* global/local variable/constant class */
208 #define sLOCAL    1
209 #define sSTATIC   2		/* global life, local scope */
210 
211 typedef struct
212 {
213    symbol             *sym;	/* symbol in symbol table, NULL for (constant) expression */
214    cell                constval;	/* value of the constant expression (if ident==iCONSTEXPR)
215 					 * also used for the size of a literal array */
216    int                 tag;	/* tagname id (of the expression) */
217    char                ident;	/* iCONSTEXPR, iVARIABLE, iARRAY, iARRAYCELL,
218 				 * iEXPRESSION or iREFERENCE */
219    char                boolresult;	/* boolean result for relational operators */
220    cell               *arrayidx;	/* last used array indices, for checking self assignment */
221 } value;
222 
223 /*  "while" statement queue (also used for "for" and "do - while" loops) */
224 enum
225 {
226    wqBRK,			/* used to restore stack for "break" */
227    wqCONT,			/* used to restore stack for "continue" */
228    wqLOOP,			/* loop start label number */
229    wqEXIT,			/* loop exit label number (jump if false) */
230    /* --- */
231    wqSIZE			/* "while queue" size */
232 };
233 
234 #define wqTABSZ (24*wqSIZE)	/* 24 nested loop statements */
235 
236 enum
237 {
238    statIDLE,			/* not compiling yet */
239    statFIRST,			/* first pass */
240    statWRITE,			/* writing output */
241    statSKIP,			/* skipping output */
242 };
243 
244 typedef struct __s_stringlist
245 {
246    struct __s_stringlist *next;
247    char               *line;
248 } stringlist;
249 
250 typedef struct __s_stringpair
251 {
252    struct __s_stringpair *next;
253    char               *first;
254    char               *second;
255    int                 matchlength;
256 } stringpair;
257 
258 /* macros for code generation */
259 #define opcodes(n)      ((n)*sizeof(cell))	/* opcode size */
260 #define opargs(n)       ((n)*sizeof(cell))	/* size of typical argument */
261 
262 /*  Tokens recognized by lex()
263  *  Some of these constants are assigned as well to the variable "lastst"
264  */
265 #define tFIRST   256		/* value of first multi-character operator */
266 #define tMIDDLE  279		/* value of last multi-character operator */
267 #define tLAST    320		/* value of last multi-character match-able token */
268 /* multi-character operators */
269 #define taMULT   256		/* *= */
270 #define taDIV    257		/* /= */
271 #define taMOD    258		/* %= */
272 #define taADD    259		/* += */
273 #define taSUB    260		/* -= */
274 #define taSHL    261		/* <<= */
275 #define taSHRU   262		/* >>>= */
276 #define taSHR    263		/* >>= */
277 #define taAND    264		/* &= */
278 #define taXOR    265		/* ^= */
279 #define taOR     266		/* |= */
280 #define tlOR     267		/* || */
281 #define tlAND    268		/* && */
282 #define tlEQ     269		/* == */
283 #define tlNE     270		/* != */
284 #define tlLE     271		/* <= */
285 #define tlGE     272		/* >= */
286 #define tSHL     273		/* << */
287 #define tSHRU    274		/* >>> */
288 #define tSHR     275		/* >> */
289 #define tINC     276		/* ++ */
290 #define tDEC     277		/* -- */
291 #define tELLIPS  278		/* ... */
292 #define tDBLDOT  279		/* .. */
293 /* reserved words (statements) */
294 #define tASSERT  280
295 #define tBREAK   281
296 #define tCASE    282
297 #define tCHAR    283
298 #define tCONST   284
299 #define tCONTINUE 285
300 #define tDEFAULT 286
301 #define tDEFINED 287
302 #define tDO      288
303 #define tELSE    289
304 #define tENUM    290
305 #define tEXIT    291
306 #define tFOR     292
307 #define tFORWARD 293
308 #define tGOTO    294
309 #define tIF      295
310 #define tNATIVE  296
311 #define tNEW     297
312 #define tOPERATOR 298
313 #define tPUBLIC  299
314 #define tRETURN  300
315 #define tSIZEOF  301
316 #define tSLEEP   302
317 #define tSTATIC  303
318 #define tSTOCK   304
319 #define tSWITCH  305
320 #define tTAGOF   306
321 #define tWHILE   307
322 /* compiler directives */
323 #define tpASSERT 308		/* #assert */
324 #define tpDEFINE 309
325 #define tpELSE   310		/* #else */
326 #define tpEMIT   311
327 #define tpENDIF  312
328 #define tpENDINPUT 313
329 #define tpENDSCRPT 314
330 #define tpFILE   315
331 #define tpIF     316		/* #if */
332 #define tINCLUDE 317
333 #define tpLINE   318
334 #define tpPRAGMA 319
335 #define tpUNDEF  320
336 /* semicolon is a special case, because it can be optional */
337 #define tTERM    321		/* semicolon or newline */
338 #define tENDEXPR 322		/* forced end of expression */
339 /* other recognized tokens */
340 #define tNUMBER  323		/* integer number */
341 #define tRATIONAL 324		/* rational number */
342 #define tSYMBOL  325
343 #define tLABEL   326
344 #define tSTRING  327
345 #define tEXPR    328		/* for assigment to "lastst" only */
346 
347 /* (reversed) evaluation of staging buffer */
348 #define sSTARTREORDER 1
349 #define sENDREORDER   2
350 #define sEXPRSTART    0xc0	/* top 2 bits set, rest is free */
351 #define sMAXARGS      64	/* relates to the bit pattern of sEXPRSTART */
352 
353 /* codes for ffabort() */
354 #define xEXIT           1	/* exit code in PRI */
355 #define xASSERTION      2	/* abort caused by failing assertion */
356 #define xSTACKERROR     3	/* stack/heap overflow */
357 #define xBOUNDSERROR    4	/* array index out of bounds */
358 #define xMEMACCESS      5	/* data access error */
359 #define xINVINSTR       6	/* invalid instruction */
360 #define xSTACKUNDERFLOW 7	/* stack underflow */
361 #define xHEAPUNDERFLOW  8	/* heap underflow */
362 #define xCALLBACKERR    9	/* no, or invalid, callback */
363 #define xSLEEP         12	/* sleep, exit code in PRI, tag in ALT */
364 
365 /* Miscellaneous  */
366 #if !defined TRUE
367 #define FALSE         0
368 #define TRUE          1
369 #endif
370 #define sIN_CSEG        1	/* if parsing CODE */
371 #define sIN_DSEG        2	/* if parsing DATA */
372 #define sCHKBOUNDS      1	/* bit position in "debug" variable: check bounds */
373 #define sSYMBOLIC       2	/* bit position in "debug" variable: symbolic info */
374 #define sNOOPTIMIZE     4	/* bit position in "debug" variable: no optimization */
375 #define sRESET          0	/* reset error flag */
376 #define sFORCESET       1	/* force error flag on */
377 #define sEXPRMARK       2	/* mark start of expression */
378 #define sEXPRRELEASE    3	/* mark end of expression */
379 
380 #if INT_MAX<0x8000u
381 #define PUBLICTAG   0x8000u
382 #define FIXEDTAG    0x4000u
383 #else
384 #define PUBLICTAG   0x80000000Lu
385 #define FIXEDTAG    0x40000000Lu
386 #endif
387 #define TAGMASK       (~PUBLICTAG)
388 
389 
390 /*
391  * Functions you call from the "driver" program
392  */
393    int                 sc_compile(int argc, char **argv);
394    int                 sc_addconstant(char *name, cell value, int tag);
395    int                 sc_addtag(char *name);
396 
397 /*
398  * Functions called from the compiler (to be implemented by you)
399  */
400 
401 /* general console output */
402    int                 sc_printf(const char *message, ...);
403 
404 /* error report function */
405    int                 sc_error(int number, char *message, char *filename,
406 				int firstline, int lastline, va_list argptr);
407 
408 /* input from source file */
409    void               *sc_opensrc(char *filename);	/* reading only */
410    void                sc_closesrc(void *handle);	/* never delete */
411    void                sc_resetsrc(void *handle, void *position);	/* reset to a position marked earlier */
412    char               *sc_readsrc(void *handle, char *target, int maxchars);
413    void               *sc_getpossrc(void *handle);	/* mark the current position */
414    int                 sc_eofsrc(void *handle);
415 
416 /* output to intermediate (.ASM) file */
417    void               *sc_openasm(int fd);	/* read/write */
418    void                sc_closeasm(void *handle);
419    void                sc_resetasm(void *handle);
420    int                 sc_writeasm(void *handle, char *str);
421    char               *sc_readasm(void *handle, char *target, int maxchars);
422 
423 /* output to binary (.AMX) file */
424    void               *sc_openbin(char *filename);
425    void                sc_closebin(void *handle, int deletefile);
426    void                sc_resetbin(void *handle);
427    int                 sc_writebin(void *handle, void *buffer, int size);
428    long                sc_lengthbin(void *handle);	/* return the length of the file */
429 
430 /* function prototypes in SC1.C */
431 symbol     *fetchfunc(char *name, int tag);
432 char       *operator_symname(char *symname, char *opername, int tag1,
433 				     int tag2, int numtags, int resulttag);
434 char       *funcdisplayname(char *dest, char *funcname);
435 int         constexpr(cell * val, int *tag);
436 constvalue *append_constval(constvalue * table, char *name, cell val,
437 				    short index);
438 constvalue *find_constval(constvalue * table, char *name, short index);
439 void        delete_consttable(constvalue * table);
440 void        add_constant(char *name, cell val, int vclass, int tag);
441 void        exporttag(int tag);
442 
443 /* function prototypes in SC2.C */
444 void        pushstk(stkitem val);
445 stkitem     popstk(void);
446 int         plungequalifiedfile(char *name);	/* explicit path included */
447 int         plungefile(char *name, int try_currentpath, int try_includepaths);	/* search through "include" paths */
448 void        preprocess(void);
449 void        lexinit(void);
450 int         lex(cell * lexvalue, char **lexsym);
451 void        lexpush(void);
452 void        lexclr(int clreol);
453 int         matchtoken(int token);
454 int         tokeninfo(cell * val, char **str);
455 int         needtoken(int token);
456 void        stowlit(cell value);
457 int         alphanum(char c);
458 void        delete_symbol(symbol * root, symbol * sym);
459 void        delete_symbols(symbol * root, int level, int del_labels,
460 				   int delete_functions);
461 int         refer_symbol(symbol * entry, symbol * bywhom);
462 void        markusage(symbol * sym, int usage);
463 unsigned int namehash(char *name);
464 symbol     *findglb(char *name);
465 symbol     *findloc(char *name);
466 symbol     *findconst(char *name);
467 symbol     *finddepend(symbol * parent);
468 symbol     *addsym(char *name, cell addr, int ident, int vclass,
469 			   int tag, int usage);
470 symbol     *addvariable(char *name, cell addr, int ident, int vclass,
471 				int tag, int dim[], int numdim, int idxtag[]);
472 int         getlabel(void);
473 char       *itoh(ucell val);
474 
475 /* function prototypes in SC3.C */
476 int         check_userop(void (*oper) (void), int tag1, int tag2,
477 				 int numparam, value * lval, int *resulttag);
478 int         matchtag(int formaltag, int actualtag, int allowcoerce);
479 int         expression(int *constant, cell * val, int *tag,
480 			       int chkfuncresult);
481 int         hier14(value * lval1);	/* the highest expression level */
482 
483 /* function prototypes in SC4.C */
484 void        writeleader(void);
485 void        writetrailer(void);
486 void        begcseg(void);
487 void        begdseg(void);
488 void        setactivefile(int fnumber);
489 cell        nameincells(char *name);
490 void        setfile(char *name, int fileno);
491 void        setline(int line, int fileno);
492 void        setlabel(int index);
493 void        endexpr(int fullexpr);
494 void        startfunc(char *fname);
495 void        endfunc(void);
496 void        alignframe(int numbytes);
497 void        defsymbol(char *name, int ident, int vclass, cell offset,
498 			      int tag);
499 void        symbolrange(int level, cell size);
500 void        rvalue(value * lval);
501 void        address(symbol * ptr);
502 void        store(value * lval);
503 void        memcopy(cell size);
504 void        copyarray(symbol * sym, cell size);
505 void        fillarray(symbol * sym, cell size, cell value);
506 void        const1(cell val);
507 void        const2(cell val);
508 void        moveto1(void);
509 void        push1(void);
510 void        push2(void);
511 void        pushval(cell val);
512 void        pop1(void);
513 void        pop2(void);
514 void        swap1(void);
515 void        ffswitch(int label);
516 void        ffcase(cell value, char *labelname, int newtable);
517 void        ffcall(symbol * sym, int numargs);
518 void        ffret(void);
519 void        ffabort(int reason);
520 void        ffbounds(cell size);
521 void        jumplabel(int number);
522 void        defstorage(void);
523 void        modstk(int delta);
524 void        setstk(cell value);
525 void        modheap(int delta);
526 void        setheap_pri(void);
527 void        setheap(cell value);
528 void        cell2addr(void);
529 void        cell2addr_alt(void);
530 void        addr2cell(void);
531 void        char2addr(void);
532 void        charalign(void);
533 void        addconst(cell value);
534 
535 /*  Code generation functions for arithmetic operators.
536  *
537  *  Syntax: o[u|s|b]_name
538  *          |   |   | +--- name of operator
539  *          |   |   +----- underscore
540  *          |   +--------- "u"nsigned operator, "s"igned operator or "b"oth
541  *          +------------- "o"perator
542  */
543 void        os_mult(void);	/* multiplication (signed) */
544 void        os_div(void);	/* division (signed) */
545 void        os_mod(void);	/* modulus (signed) */
546 void        ob_add(void);	/* addition */
547 void        ob_sub(void);	/* subtraction */
548 void        ob_sal(void);	/* shift left (arithmetic) */
549 void        os_sar(void);	/* shift right (arithmetic, signed) */
550 void        ou_sar(void);	/* shift right (logical, unsigned) */
551 void        ob_or(void);	/* bitwise or */
552 void        ob_xor(void);	/* bitwise xor */
553 void        ob_and(void);	/* bitwise and */
554 void        ob_eq(void);	/* equality */
555 void        ob_ne(void);	/* inequality */
556 void        relop_prefix(void);
557 void        relop_suffix(void);
558 void        os_le(void);	/* less or equal (signed) */
559 void        os_ge(void);	/* greater or equal (signed) */
560 void        os_lt(void);	/* less (signed) */
561 void        os_gt(void);	/* greater (signed) */
562 
563 void        lneg(void);
564 void        neg(void);
565 void        invert(void);
566 void        nooperation(void);
567 void        inc(value * lval);
568 void        dec(value * lval);
569 void        jmp_ne0(int number);
570 void        jmp_eq0(int number);
571 void        outval(cell val, int newline);
572 
573 /* function prototypes in SC5.C */
574 int         error(int number, ...);
575 void        errorset(int code);
576 
577 /* function prototypes in SC6.C */
578 void        assemble(FILE * fout, FILE * fin);
579 
580 /* function prototypes in SC7.C */
581 void        stgbuffer_cleanup(void);
582 void        stgmark(char mark);
583 void        stgwrite(char *st);
584 void        stgout(int index);
585 void        stgdel(int index, cell code_index);
586 int         stgget(int *index, cell * code_index);
587 void        stgset(int onoff);
588 int         phopt_init(void);
589 int         phopt_cleanup(void);
590 
591 /* function prototypes in SCLIST.C */
592 stringpair *insert_alias(char *name, char *alias);
593 stringpair *find_alias(char *name);
594 int         lookup_alias(char *target, char *name);
595 void        delete_aliastable(void);
596 stringlist *insert_path(char *path);
597 char       *get_path(int index);
598 void        delete_pathtable(void);
599 stringpair *insert_subst(char *pattern, char *substitution,
600 				 int prefixlen);
601 int         get_subst(int index, char **pattern, char **substitution);
602 stringpair *find_subst(char *name, int length);
603 int         delete_subst(char *name, int length);
604 void        delete_substtable(void);
605 
606 /* external variables (defined in scvars.c) */
607 extern symbol     loctab;	/* local symbol table */
608 extern symbol     glbtab;	/* global symbol table */
609 extern cell      *litq;	/* the literal queue */
610 extern char       pline[];	/* the line read from the input file */
611 extern char      *lptr;	/* points to the current position in "pline" */
612 extern constvalue tagname_tab;	/* tagname table */
613 extern constvalue libname_tab;	/* library table (#pragma library "..." syntax) *///??? use "stringlist" type
614 extern constvalue *curlibrary;	/* current library */
615 extern symbol    *curfunc;	/* pointer to current function */
616 extern char      *inpfname;	/* name of the file currently read from */
617 extern char       sc_ctrlchar;	/* the control character (or escape character) */
618 extern int        litidx;	/* index to literal table */
619 extern int        litmax;	/* current size of the literal table */
620 extern int        stgidx;	/* index to the staging buffer */
621 extern int        labnum;	/* number of (internal) labels */
622 extern int        staging;	/* true if staging output */
623 extern cell       declared;	/* number of local cells declared */
624 extern cell       glb_declared;	/* number of global cells declared */
625 extern cell       code_idx;	/* number of bytes with generated code */
626 extern int        ntv_funcid;	/* incremental number of native function */
627 extern int        errnum;	/* number of errors */
628 extern int        warnnum;	/* number of warnings */
629 extern int        sc_debug;	/* debug/optimization options (bit field) */
630 extern int        charbits;	/* number of bits for a character */
631 extern int        sc_packstr;	/* strings are packed by default? */
632 extern int        sc_asmfile;	/* create .ASM file? */
633 extern int        sc_listing;	/* create .LST file? */
634 extern int        sc_compress;	/* compress bytecode? */
635 extern int        sc_needsemicolon;	/* semicolon required to terminate expressions? */
636 extern int        sc_dataalign;	/* data alignment value */
637 extern int        sc_alignnext;	/* must frame of the next function be aligned? */
638 extern int        curseg;	/* 1 if currently parsing CODE, 2 if parsing DATA */
639 extern cell       sc_stksize;	/* stack size */
640 extern int        freading;	/* is there an input file ready for reading? */
641 extern int        fline;	/* the line number in the current file */
642 extern int        fnumber;	/* number of files in the file table (debugging) */
643 extern int        fcurrent;	/* current file being processed (debugging) */
644 extern int        intest;	/* true if inside a test */
645 extern int        sideeffect;	/* true if an expression causes a side-effect */
646 extern int        stmtindent;	/* current indent of the statement */
647 extern int        indent_nowarn;	/* skip warning "217 loose indentation" */
648 extern int        sc_tabsize;	/* number of spaces that a TAB represents */
649 extern int        sc_allowtags;	/* allow/detect tagnames in lex() */
650 extern int        sc_status;	/* read/write status */
651 extern int        sc_rationaltag;	/* tag for rational numbers */
652 extern int        rational_digits;	/* number of fractional digits */
653 
654 extern FILE      *inpf;	/* file read from (source or include) */
655 extern FILE      *inpf_org;	/* main source file */
656 extern FILE      *outf;	/* file written to */
657 
658 extern jmp_buf    errbuf;	/* target of longjmp() on a fatal error */
659 
660 #define sc_isspace(x)  isspace ((int)((unsigned char)x))
661 #define sc_isalpha(x)  isalpha ((int)((unsigned char)x))
662 #define sc_isdigit(x)  isdigit ((int)((unsigned char)x))
663 #define sc_isupper(x)  isupper ((int)((unsigned char)x))
664 #define sc_isxdigit(x) isxdigit((int)((unsigned char)x))
665 
666 #endif
667