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