1 
2 #include "cmdlib.h"
3 #include <stdio.h>
4 #include <setjmp.h>
5 
6 #include "pr_comp.h"
7 
8 /*
9 
10 TODO:
11 
12 "stopped at 10 errors"
13 
14 other pointer types for models and clients?
15 
16 compact string heap?
17 
18 allways initialize all variables to something safe
19 
20 the def->type->type arrangement is really silly.
21 
22 return type checking
23 
24 parm count type checking
25 
26 immediate overflow checking
27 
28 pass the first two parms in call->b and call->c
29 
30 */
31 
32 /*
33 
34 comments
35 --------
36 // comments discard text until the end of line
37 / *  * / comments discard all enclosed text (spaced out on this line because this documentation is in a regular C comment block, and typing them in normally causes a parse error)
38 
39 code structure
40 --------------
41 A definition is:
42 	<type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
43 
44 
45 types
46 -----
47 simple types: void, float, vector, string, or entity
48 	float		width, height;
49 	string		name;
50 	entity		self, other;
51 
52 vector types:
53 	vector		org;	// also creates org_x, org_y, and org_z float defs
54 
55 
56 A function type is specified as: 	simpletype ( type name {,type name} )
57 The names are ignored except when the function is initialized.
58 	void()		think;
59 	entity()	FindTarget;
60 	void(vector destination, float speed, void() callback)	SUB_CalcMove;
61 	void(...)	dprint;		// variable argument builtin
62 
63 A field type is specified as:  .type
64 	.vector		origin;
65 	.string		netname;
66 	.void()		think, touch, use;
67 
68 
69 names
70 -----
71 Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
72 
73 There are two levels of scoping: global, and function.  The parameter list of a function and any vars declared inside a function with the "local" statement are only visible within that function,
74 
75 
76 immediates
77 ----------
78 Float immediates must begin with 0-9 or minus sign.  .5 is illegal.
79 
80 A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error.  Seperate the - from the digits with a space "a - 5" to get the proper behavior.
81 	12
82 	1.6
83 	0.5
84 	-100
85 
86 Vector immediates are three float immediates enclosed in single quotes.
87 	'0 0 0'
88 	'20.5 -10 0.00001'
89 
90 String immediates are characters enclosed in double quotes.  The string cannot contain explicit newlines, but the escape character \n can embed one.  The \" escape can be used to include a quote in the string.
91 	"maps/jrwiz1.bsp"
92 	"sound/nin/pain.wav"
93 	"ouch!\n"
94 
95 Code immediates are statements enclosed in {} braces.
96 statement:
97 	{ <multiple statements> }
98 	<expression>;
99 	local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
100 	return <expression>;
101 	if ( <expression> ) <statement> [ else <statement> ];
102 	while ( <expression> ) <statement>;
103 	do <statement> while ( <expression> );
104 	<function name> ( <function parms> );
105 
106 expression:
107 	combiations of names and these operators with standard C precedence:
108 	"&&", "||", "<=", ">=","==", "!=", "!", "*", "/", "-", "+", "=", ".", "<", ">", "&", "|"
109 	Parenthesis can be used to alter order of operation.
110 	The & and | operations perform integral bit ops on floats
111 
112 A built in function immediate is a number sign followed by an integer.
113 	#1
114 	#12
115 
116 
117 compilation
118 -----------
119 Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all other files.
120 
121 The language is strongly typed and there are no casts.
122 
123 Anything that is initialized is assumed to be constant, and will have immediates folded into it.  If you change the value, your program will malfunction.  All uninitialized globals will be saved to savegame files.
124 
125 Functions cannot have more than eight parameters.
126 
127 Error recovery during compilation is minimal.  It will skip to the next global definition, so you will never see more than one error at a time in a given function.  All compilation aborts after ten error messages.
128 
129 Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
130 
131 void()	MyFunction;			// the prototype
132 
133 void()	MyFunction =		// the initialization
134 {
135 	dprint ("we're here\n");
136 };
137 
138 
139 entities and fields
140 -------------------
141 
142 
143 execution
144 ---------
145 Code execution is initiated by C code in quake from two main places:  the timed think routines for periodic control, and the touch function when two objects impact each other.
146 
147 There are three global variables that are set before beginning code execution:
148 	entity	world;		// the server's world object, which holds all global
149 						// state for the server, like the deathmatch flags
150 						// and the body ques.
151 	entity	self;		// the entity the function is executing for
152 	entity	other;		// the other object in an impact, not used for thinks
153 	float	time;		// the current game time.  Note that because the
154 						// entities in the world are simulated sequentially,
155 						// time is NOT strictly increasing.  An impact late
156 						// in one entity's time slice may set time higher
157 						// than the think function of the next entity.
158 						// The difference is limited to 0.1 seconds.
159 Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
160 
161 There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
162 
163 It is acceptable to change the system set global variables.  This is usually done to pose as another entity by changing self and calling a function.
164 
165 The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code.  All time consuming operations should be made into built in functions.
166 
167 A profile counter is kept for each function, and incremented for each interpreted instruction inside that function.  The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters.  The "profile all" command will dump sorted stats for every function that has been executed.
168 
169 
170 afunc ( 4, bfunc(1,2,3));
171 will fail because there is a shared parameter marshaling area, which will cause the 1 from bfunc to overwrite the 4 allready placed in parm0.  When a function is called, it copies the parms from the globals into it's privately scoped variables, so there is no collision when calling another function.
172 
173 total = factorial(3) + factorial(4);
174 Will fail because the return value from functions is held in a single global area.  If this really gets on your nerves, tell me and I can work around it at a slight performance and space penalty by allocating a new register for the function call and copying it out.
175 
176 
177 built in functions
178 ------------------
179 void(string text)	dprint;
180 Prints the string to the server console.
181 
182 void(entity client, string text)	cprint;
183 Prints a message to a specific client.
184 
185 void(string text)	bprint;
186 Broadcast prints a message to all clients on the current server.
187 
188 entity()	spawn;
189 Returns a totally empty entity.  You can manually set everything up, or just set the origin and call one of the existing entity setup functions.
190 
191 entity(entity start, .string field, string match) find;
192 Searches the server entity list beginning at start, looking for an entity that has entity.field = match.  To start at the beginning of the list, pass world.  World is returned when the end of the list is reached.
193 
194 <FIXME: define all the other functions...>
195 
196 
197 gotchas
198 -------
199 
200 The && and || operators DO NOT EARLY OUT like C!
201 
202 Don't confuse single quoted vectors with double quoted strings
203 
204 The function declaration syntax takes a little getting used to.
205 
206 Don't forget the ; after the trailing brace of a function initialization.
207 
208 Don't forget the "local" before defining local variables.
209 
210 There are no ++ / -- operators, or operate/assign operators.
211 
212 */
213 
214 //=============================================================================
215 
216 // offsets are allways multiplied by 4 before using
217 typedef int	gofs_t;				// offset in global data block
218 typedef struct function_s function_t;
219 
220 #define	MAX_PARMS	8
221 
222 typedef struct type_s
223 {
224 	etype_t			type;
225 	struct def_s	*def;		// a def that points to this type
226 	struct type_s	*next;
227 // function types are more complex
228 	struct type_s	*aux_type;	// return type or field type
229 	int				num_parms;	// -1 = variable args
230 	struct type_s	*parm_types[MAX_PARMS];	// only [num_parms] allocated
231 } type_t;
232 
233 typedef struct def_s
234 {
235 	type_t		*type;
236 	char		*name;
237 	struct def_s	*next;
238 	gofs_t		ofs;
239 	struct def_s	*scope;		// function the var was defined in, or NULL
240 	int			initialized;	// 1 when a declaration included "= immediate"
241 } def_t;
242 
243 //============================================================================
244 
245 // pr_loc.h -- program local defs
246 
247 #define	MAX_ERRORS		10
248 
249 #define	MAX_NAME		64		// chars long
250 
251 #define	MAX_REGS		16384
252 
253 //=============================================================================
254 
255 typedef union eval_s
256 {
257 	string_t			string;
258 	float				_float;
259 	float				vector[3];
260 	func_t				function;
261 	int					_int;
262 	union eval_s		*ptr;
263 } eval_t;
264 
265 extern	int		type_size[8];
266 extern	def_t	*def_for_type[8];
267 
268 extern	type_t	type_void, type_string, type_float, type_vector, type_entity, type_field, type_function, type_pointer, type_floatfield;
269 
270 extern	def_t	def_void, def_string, def_float, def_vector, def_entity, def_field, def_function, def_pointer;
271 
272 struct function_s
273 {
274 	int					builtin;	// if non 0, call an internal function
275 	int					code;		// first statement
276 	char				*file;		// source file with definition
277 	int					file_line;
278 	struct def_s		*def;
279 	int					parm_ofs[MAX_PARMS];	// allways contiguous, right?
280 };
281 
282 
283 //
284 // output generated by prog parsing
285 //
286 typedef struct
287 {
288 	char		*memory;
289 	int			max_memory;
290 	int			current_memory;
291 	type_t		*types;
292 
293 	def_t		def_head;		// unused head of linked list
294 	def_t		*def_tail;		// add new defs after this and move it
295 
296 	int			size_fields;
297 } pr_info_t;
298 
299 extern	pr_info_t	pr;
300 
301 typedef struct
302 {
303 	char		*name;
304 	char		*opname;
305 	float		priority;
306 	boolean	right_associative;
307 	def_t		*type_a, *type_b, *type_c;
308 } opcode_t;
309 
310 //============================================================================
311 
312 
313 extern	opcode_t	pr_opcodes[99];		// sized by initialization
314 
315 extern	boolean	pr_dumpasm;
316 
317 extern	def_t		*pr_global_defs[MAX_REGS];	// to find def for a global variable
318 
319 typedef enum {
320 tt_eof,			// end of file reached
321 tt_name, 		// an alphanumeric name token
322 tt_punct, 		// code punctuation
323 tt_immediate,	// string, float, vector
324 } token_type_t;
325 
326 extern	char		pr_token[2048];
327 extern	token_type_t	pr_token_type;
328 extern	type_t		*pr_immediate_type;
329 extern	eval_t		pr_immediate;
330 
331 void PR_PrintStatement (dstatement_t *s);
332 
333 void PR_Lex (void);
334 // reads the next token into pr_token and classifies its type
335 
336 type_t *PR_ParseType (void);
337 char *PR_ParseName (void);
338 
339 boolean PR_Check (char *string);
340 void PR_Expect (char *string);
341 void PR_ParseError (char *error, ...);
342 
343 
344 extern	jmp_buf		pr_parse_abort;		// longjump with this on parse error
345 extern	int			pr_source_line;
346 extern	char		*pr_file_p;
347 
348 void *PR_Malloc (int size);
349 
350 
351 #define	OFS_NULL		0
352 #define	OFS_RETURN		1
353 #define	OFS_PARM0		4		// leave 3 ofs for each parm to hold vectors
354 #define	OFS_PARM1		7
355 #define	OFS_PARM2		10
356 #define	OFS_PARM3		13
357 #define	OFS_PARM4		16
358 #define	RESERVED_OFS	28
359 
360 
361 extern	def_t	*pr_scope;
362 extern	int		pr_error_count;
363 
364 void PR_NewLine (void);
365 def_t *PR_GetDef (type_t *type, char *name, def_t *scope, boolean allocate);
366 
367 void PR_PrintDefs (void);
368 
369 void PR_SkipToSemicolon (void);
370 
371 extern	char		pr_parm_names[MAX_PARMS][MAX_NAME];
372 extern	boolean	pr_trace;
373 
374 #define	G_FLOAT(o) (pr_globals[o])
375 #define	G_INT(o) (*(int *)&pr_globals[o])
376 #define	G_VECTOR(o) (&pr_globals[o])
377 #define	G_STRING(o) (strings + *(string_t *)&pr_globals[o])
378 #define	G_FUNCTION(o) (*(func_t *)&pr_globals[o])
379 
380 char *PR_ValueString (etype_t type, void *val);
381 
382 void PR_ClearGrabMacros (void);
383 
384 boolean	PR_CompileFile (char *string, char *filename);
385 
386 extern	boolean	pr_dumpasm;
387 
388 extern	string_t	s_file;			// filename for function definition
389 
390 extern	def_t	def_ret, def_parms[MAX_PARMS];
391 
392 //=============================================================================
393 
394 #define	MAX_STRINGS		500000
395 #define	MAX_GLOBALS		16384
396 #define	MAX_FIELDS		1024
397 #define	MAX_STATEMENTS	65536
398 #define	MAX_FUNCTIONS	8192
399 
400 #define	MAX_SOUNDS		1024
401 #define	MAX_MODELS		1024
402 #define	MAX_FILES		1024
403 #define	MAX_DATA_PATH	64
404 
405 extern	char	strings[MAX_STRINGS];
406 extern	int		strofs;
407 
408 extern	dstatement_t	statements[MAX_STATEMENTS];
409 extern	int			numstatements;
410 extern	int			statement_linenums[MAX_STATEMENTS];
411 
412 extern	dfunction_t	functions[MAX_FUNCTIONS];
413 extern	int			numfunctions;
414 
415 extern	float		pr_globals[MAX_REGS];
416 extern	int			numpr_globals;
417 
418 extern	char	pr_immediate_string[2048];
419 
420 extern	char		precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
421 extern	int			precache_sounds_block[MAX_SOUNDS];
422 extern	int			numsounds;
423 
424 extern	char		precache_models[MAX_MODELS][MAX_DATA_PATH];
425 extern	int			precache_models_block[MAX_SOUNDS];
426 extern	int			nummodels;
427 
428 extern	char		precache_files[MAX_FILES][MAX_DATA_PATH];
429 extern	int			precache_files_block[MAX_SOUNDS];
430 extern	int			numfiles;
431 
432 int	CopyString (char *str);
433 
434 
435