summaryrefslogtreecommitdiff
path: root/src/bin/embryo_cc_sc.h
blob: 9eaf6b86e05a9f6c8d40edc70cf55ecf2548ac51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
/*  Small 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 T. Riemersma, 1997-2003
 *
 *  Version: $Id$
 *
 *  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 EMBRYO_CC_SC_H
#define EMBRYO_CC_SC_H

#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <setjmp.h>

#ifndef _MSC_VER
# include <stdint.h>
#else
# include <stddef.h>
# include <Evil.h>
#endif

#include "embryo_cc_amx.h"

/* 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 DIRSEP_CHAR '/'		/* directory separator character */

#define sDIMEN_MAX     2	/* maximum number of array dimensions */
#define sDEF_LITMAX  500	/* initial size of the literal pool, in "cells" */
#define sLINEMAX (640 * 1024)	/* input line length (in characters) */
#define sDEF_AMXSTACK 4096	/* default stack size for AMX files */
#define sSTKMAX       80	/* stack for nested #includes and other uses */
#define PREPROC_TERM  '\x7f'	/* termination character for preprocessor expressions (the "DEL" code) */
#define sDEF_PREFIX   "default.inc"	/* default prefix filename */

typedef intptr_t stkitem;	/* type of items stored on the 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                 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;
} 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];
   unsigned int        hash;	/* value derived from name, for quicker searching */
   cell                addr;	/* address or offset (or value for constant, index for native function) */
   char                vclass;	/* sLOCAL if "addr" refers to a local symbol */
   char                ident;	/* see below for possible values */
   char                usage;	/* see below for possible values */
   int                 compound;	/* compound level (braces nesting level) */
   int                 tag;	/* tagname id */
   union
   {
      int                 declared;	/* label: how many local variables are declared */
      int                 idxtag;	/* array: tag of array indices */
      constvalue         *lib;	/* native function: library it is part of *///??? use "stringlist"
   } x;				/* 'x' for 'extra' */
   union
   {
      arginfo            *arglist;	/* types of all parameters for functions */
      struct
      {
	 cell                length;	/* arrays: length (size) */
	 short               level;	/* number of dimensions below this level */
      } array;
   } dim;			/* for 'dimension', both functions and arrays */
   int                 fnumber;	/* static global variables: file number in which the declaration is visible */
   struct __s_symbol **refer;	/* referrer list, functions that "use" this symbol */
   int                 numrefers;	/* number of entries in the referrer list */
} 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		/* function passed as a parameter */
#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
 *        3     (uPREDEF) the constant is pre-defined and should be kept between passes
 */
#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 uSTOCK    0x40
#define uMISSING  0x80
/* 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 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 sGLOBAL   0		/* global/local variable/constant class */
#define sLOCAL    1
#define sSTATIC   2		/* global life, local scope */

typedef struct
{
   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                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;
} stringpair;

/* 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  279		/* value of last multi-character operator */
#define tLAST    320		/* 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		/* .. */
/* reserved words (statements) */
#define tASSERT  280
#define tBREAK   281
#define tCASE    282
#define tCHAR    283
#define tCONST   284
#define tCONTINUE 285
#define tDEFAULT 286
#define tDEFINED 287
#define tDO      288
#define tELSE    289
#define tENUM    290
#define tEXIT    291
#define tFOR     292
#define tFORWARD 293
#define tGOTO    294
#define tIF      295
#define tNATIVE  296
#define tNEW     297
#define tOPERATOR 298
#define tPUBLIC  299
#define tRETURN  300
#define tSIZEOF  301
#define tSLEEP   302
#define tSTATIC  303
#define tSTOCK   304
#define tSWITCH  305
#define tTAGOF   306
#define tWHILE   307
/* compiler directives */
#define tpASSERT 308		/* #assert */
#define tpDEFINE 309
#define tpELSE   310		/* #else */
#define tpEMIT   311
#define tpENDIF  312
#define tpENDINPUT 313
#define tpENDSCRPT 314
#define tpFILE   315
#define tpIF     316		/* #if */
#define tINCLUDE 317
#define tpLINE   318
#define tpPRAGMA 319
#define tpUNDEF  320
/* semicolon is a special case, because it can be optional */
#define tTERM    321		/* semicolon or newline */
#define tENDEXPR 322		/* forced end of expression */
/* other recognized tokens */
#define tNUMBER  323		/* integer number */
#define tRATIONAL 324		/* rational number */
#define tSYMBOL  325
#define tLABEL   326
#define tSTRING  327
#define tEXPR    328		/* for assigment to "lastst" only */

/* (reversed) evaluation of staging buffer */
#define sSTARTREORDER 1
#define sENDREORDER   2
#define sEXPRSTART    0xc0	/* top 2 bits set, rest is free */
#define sMAXARGS      64	/* relates to the bit pattern of sEXPRSTART */

/* 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 */

#if INT_MAX<0x8000u
#define PUBLICTAG   0x8000u
#define FIXEDTAG    0x4000u
#else
#define PUBLICTAG   0x80000000Lu
#define FIXEDTAG    0x40000000Lu
#endif
#define TAGMASK       (~PUBLICTAG)


/*
 * Functions you call from the "driver" program
 */
   int                 sc_compile(int argc, char **argv);
   int                 sc_addconstant(char *name, cell value, int tag);
   int                 sc_addtag(char *name);

/*
 * Functions called from the compiler (to be implemented by you)
 */

/* general console output */
   int                 sc_printf(const char *message, ...);

/* error report function */
   int                 sc_error(int number, char *message, char *filename,
				int firstline, int lastline, va_list argptr);

/* input from source file */
   void               *sc_opensrc(char *filename);	/* reading only */
   void                sc_closesrc(void *handle);	/* never delete */
   void                sc_resetsrc(void *handle, void *position);	/* reset to a position marked earlier */
   char               *sc_readsrc(void *handle, char *target, int maxchars);
   void               *sc_getpossrc(void *handle);	/* mark the current position */
   int                 sc_eofsrc(void *handle);

/* output to intermediate (.ASM) file */
   void               *sc_openasm(int fd);	/* read/write */
   void                sc_closeasm(void *handle);
   void                sc_resetasm(void *handle);
   int                 sc_writeasm(void *handle, char *str);
   char               *sc_readasm(void *handle, char *target, int maxchars);

/* output to binary (.AMX) file */
   void               *sc_openbin(char *filename);
   void                sc_closebin(void *handle, int deletefile);
   void                sc_resetbin(void *handle);
   int                 sc_writebin(void *handle, void *buffer, int size);
   long                sc_lengthbin(void *handle);	/* return the length of the file */

/* function prototypes in SC1.C */
symbol     *fetchfunc(char *name, int tag);
char       *operator_symname(char *symname, char *opername, int tag1,
				     int tag2, int numtags, int resulttag);
char       *funcdisplayname(char *dest, char *funcname);
int         constexpr(cell * val, int *tag);
constvalue *append_constval(constvalue * table, char *name, cell val,
				    short index);
constvalue *find_constval(constvalue * table, char *name, short index);
void        delete_consttable(constvalue * table);
void        add_constant(char *name, cell val, int vclass, int tag);
void        exporttag(int tag);

/* function prototypes in SC2.C */
void        pushstk(stkitem val);
stkitem     popstk(void);
int         plungequalifiedfile(char *name);	/* explicit path included */
int         plungefile(char *name, int try_currentpath, int try_includepaths);	/* search through "include" paths */
void        preprocess(void);
void        lexinit(void);
int         lex(cell * lexvalue, char **lexsym);
void        lexpush(void);
void        lexclr(int clreol);
int         matchtoken(int token);
int         tokeninfo(cell * val, char **str);
int         needtoken(int token);
void        stowlit(cell value);
int         alphanum(char c);
void        delete_symbol(symbol * root, symbol * sym);
void        delete_symbols(symbol * root, int level, int del_labels,
				   int delete_functions);
int         refer_symbol(symbol * entry, symbol * bywhom);
void        markusage(symbol * sym, int usage);
unsigned int namehash(char *name);
symbol     *findglb(char *name);
symbol     *findloc(char *name);
symbol     *findconst(char *name);
symbol     *finddepend(symbol * parent);
symbol     *addsym(char *name, cell addr, int ident, int vclass,
			   int tag, int usage);
symbol     *addvariable(char *name, cell addr, int ident, int vclass,
				int tag, int dim[], int numdim, int idxtag[]);
int         getlabel(void);
char       *itoh(ucell val);

/* function prototypes in SC3.C */
int         check_userop(void (*oper) (void), int tag1, int tag2,
				 int numparam, value * lval, int *resulttag);
int         matchtag(int formaltag, int actualtag, int allowcoerce);
int         expression(int *constant, cell * val, int *tag,
			       int chkfuncresult);
int         hier14(value * lval1);	/* the highest expression level */

/* function prototypes in SC4.C */
void        writeleader(void);
void        writetrailer(void);
void        begcseg(void);
void        begdseg(void);
void        setactivefile(int fnumber);
cell        nameincells(char *name);
void        setfile(char *name, int fileno);
void        setline(int line, int fileno);
void        setlabel(int index);
void        endexpr(int fullexpr);
void        startfunc(char *fname);
void        endfunc(void);
void        alignframe(int numbytes);
void        defsymbol(char *name, int ident, int vclass, cell offset,
			      int tag);
void        symbolrange(int level, cell size);
void        rvalue(value * lval);
void        address(symbol * ptr);
void        store(value * lval);
void        memcopy(cell size);
void        copyarray(symbol * sym, cell size);
void        fillarray(symbol * sym, cell size, cell value);
void        const1(cell val);
void        const2(cell val);
void        moveto1(void);
void        push1(void);
void        push2(void);
void        pushval(cell val);
void        pop1(void);
void        pop2(void);
void        swap1(void);
void        ffswitch(int label);
void        ffcase(cell value, char *labelname, int newtable);
void        ffcall(symbol * sym, int numargs);
void        ffret(void);
void        ffabort(int reason);
void        ffbounds(cell size);
void        jumplabel(int number);
void        defstorage(void);
void        modstk(int delta);
void        setstk(cell value);
void        modheap(int delta);
void        setheap_pri(void);
void        setheap(cell value);
void        cell2addr(void);
void        cell2addr_alt(void);
void        addr2cell(void);
void        char2addr(void);
void        charalign(void);
void        addconst(cell value);

/*  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
 */
void        os_mult(void);	/* multiplication (signed) */
void        os_div(void);	/* division (signed) */
void        os_mod(void);	/* modulus (signed) */
void        ob_add(void);	/* addition */
void        ob_sub(void);	/* subtraction */
void        ob_sal(void);	/* shift left (arithmetic) */
void        os_sar(void);	/* shift right (arithmetic, signed) */
void        ou_sar(void);	/* shift right (logical, unsigned) */
void        ob_or(void);	/* bitwise or */
void        ob_xor(void);	/* bitwise xor */
void        ob_and(void);	/* bitwise and */
void        ob_eq(void);	/* equality */
void        ob_ne(void);	/* inequality */
void        relop_prefix(void);
void        relop_suffix(void);
void        os_le(void);	/* less or equal (signed) */
void        os_ge(void);	/* greater or equal (signed) */
void        os_lt(void);	/* less (signed) */
void        os_gt(void);	/* greater (signed) */

void        lneg(void);
void        neg(void);
void        invert(void);
void        nooperation(void);
void        inc(value * lval);
void        dec(value * lval);
void        jmp_ne0(int number);
void        jmp_eq0(int number);
void        outval(cell val, int newline);

/* function prototypes in SC5.C */
int         error(int number, ...);
void        errorset(int code);

/* function prototypes in SC6.C */
void        assemble(FILE * fout, FILE * fin);

/* function prototypes in SC7.C */
void        stgbuffer_cleanup(void);
void        stgmark(char mark);
void        stgwrite(char *st);
void        stgout(int index);
void        stgdel(int index, cell code_index);
int         stgget(int *index, cell * code_index);
void        stgset(int onoff);
int         phopt_init(void);
int         phopt_cleanup(void);

/* function prototypes in SCLIST.C */
stringpair *insert_alias(char *name, char *alias);
stringpair *find_alias(char *name);
int         lookup_alias(char *target, char *name);
void        delete_aliastable(void);
stringlist *insert_path(char *path);
char       *get_path(int index);
void        delete_pathtable(void);
stringpair *insert_subst(char *pattern, char *substitution,
				 int prefixlen);
int         get_subst(int index, char **pattern, char **substitution);
stringpair *find_subst(char *name, int length);
int         delete_subst(char *name, int length);
void        delete_substtable(void);

/* external variables (defined in scvars.c) */
extern symbol     loctab;	/* local symbol table */
extern symbol     glbtab;	/* global symbol table */
extern cell      *litq;	/* the literal queue */
extern char       pline[];	/* the line read from the input file */
extern char      *lptr;	/* points to the current position in "pline" */
extern constvalue tagname_tab;	/* tagname table */
extern constvalue libname_tab;	/* library table (#pragma library "..." syntax) *///??? use "stringlist" type
extern constvalue *curlibrary;	/* current library */
extern symbol    *curfunc;	/* pointer to current function */
extern char      *inpfname;	/* name of the file currently read from */
extern char       outfname[];	/* output file name */
extern char       sc_ctrlchar;	/* the control character (or escape character) */
extern int        litidx;	/* index to literal table */
extern int        litmax;	/* current size of the literal table */
extern int        stgidx;	/* index to the staging buffer */
extern int        labnum;	/* number of (internal) labels */
extern int        staging;	/* true if staging output */
extern cell       declared;	/* number of local cells declared */
extern cell       glb_declared;	/* number of global cells declared */
extern cell       code_idx;	/* number of bytes with generated code */
extern int        ntv_funcid;	/* incremental number of native function */
extern int        errnum;	/* number of errors */
extern int        warnnum;	/* number of warnings */
extern int        sc_debug;	/* debug/optimization options (bit field) */
extern int        charbits;	/* number of bits for a character */
extern int        sc_packstr;	/* strings are packed by default? */
extern int        sc_asmfile;	/* create .ASM file? */
extern int        sc_listing;	/* create .LST file? */
extern int        sc_compress;	/* compress bytecode? */
extern int        sc_needsemicolon;	/* semicolon required to terminate expressions? */
extern int        sc_dataalign;	/* data alignment value */
extern int        sc_alignnext;	/* must frame of the next function be aligned? */
extern int        curseg;	/* 1 if currently parsing CODE, 2 if parsing DATA */
extern cell       sc_stksize;	/* stack size */
extern int        freading;	/* is there an input file ready for reading? */
extern int        fline;	/* the line number in the current file */
extern int        fnumber;	/* number of files in the file table (debugging) */
extern int        fcurrent;	/* current file being processed (debugging) */
extern int        intest;	/* true if inside a test */
extern int        sideeffect;	/* true if an expression causes a side-effect */
extern int        stmtindent;	/* current indent of the statement */
extern int        indent_nowarn;	/* skip warning "217 loose indentation" */
extern int        sc_tabsize;	/* number of spaces that a TAB represents */
extern int        sc_allowtags;	/* allow/detect tagnames in lex() */
extern int        sc_status;	/* read/write status */
extern int        sc_rationaltag;	/* tag for rational numbers */
extern int        rational_digits;	/* number of fractional digits */

extern FILE      *inpf;	/* file read from (source or include) */
extern FILE      *inpf_org;	/* main source file */
extern FILE      *outf;	/* file written to */

extern jmp_buf    errbuf;	/* target of longjmp() on a fatal error */

#define sc_isspace(x)  isspace ((int)((unsigned char)x))
#define sc_isalpha(x)  isalpha ((int)((unsigned char)x))
#define sc_isdigit(x)  isdigit ((int)((unsigned char)x))
#define sc_isupper(x)  isupper ((int)((unsigned char)x))
#define sc_isxdigit(x) isxdigit((int)((unsigned char)x))

#endif