]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/script/Script_Program.h
hello world
[icculus/iodoom3.git] / neo / d3xp / script / Script_Program.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #ifndef __SCRIPT_PROGRAM_H__
30 #define __SCRIPT_PROGRAM_H__
31
32 class idScriptObject;
33 class idEventDef;
34 class idVarDef;
35 class idTypeDef;
36 class idEntity;
37 class idThread;
38 class idSaveGame;
39 class idRestoreGame;
40
41 #define MAX_STRING_LEN          128
42 #ifdef _D3XP
43 #define MAX_GLOBALS                     296608                  // in bytes
44 #else
45 #define MAX_GLOBALS                     196608                  // in bytes
46 #endif
47 #define MAX_STRINGS                     1024
48
49 #ifdef _D3XP
50 #define MAX_FUNCS                       3584
51 #else
52 #define MAX_FUNCS                       3072
53 #endif
54
55 #ifdef _D3XP
56 #define MAX_STATEMENTS          131072                  // statement_t - 18 bytes last I checked
57 #else
58 #define MAX_STATEMENTS          81920                   // statement_t - 18 bytes last I checked
59 #endif
60
61 typedef enum {
62         ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean
63 } etype_t;
64
65 class function_t {
66 public:
67                                                 function_t();
68
69         size_t                          Allocated( void ) const;
70         void                            SetName( const char *name );
71         const char                      *Name( void ) const;
72         void                            Clear( void );
73
74 private:
75         idStr                           name;
76 public:
77         const idEventDef        *eventdef;
78         idVarDef                        *def;
79         const idTypeDef         *type;
80         int                             firstStatement;
81         int                             numStatements;
82         int                             parmTotal;
83         int                             locals;                         // total ints of parms + locals
84         int                                     filenum;                        // source file defined in
85         idList<int>                     parmSize;
86 };
87
88 typedef union eval_s {
89         const char                      *stringPtr;
90         float                           _float;
91         float                           vector[ 3 ];
92         function_t                      *function;
93         int                             _int;
94         int                             entity;
95 } eval_t;
96
97 /***********************************************************************
98
99 idTypeDef
100
101 Contains type information for variables and functions.
102
103 ***********************************************************************/
104
105 class idTypeDef {
106 private:
107         etype_t                                         type;
108         idStr                                           name;
109         int                                                     size;
110
111         // function types are more complex
112         idTypeDef                                       *auxType;                                       // return type
113         idList<idTypeDef *>                     parmTypes;
114         idStrList                                       parmNames;
115         idList<const function_t *>      functions;
116
117 public:
118         idVarDef                                        *def;                                           // a def that points to this type
119
120                                                 idTypeDef( const idTypeDef &other );
121                                                 idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
122         void                            operator=( const idTypeDef& other );
123         size_t                          Allocated( void ) const;
124
125         bool                            Inherits( const idTypeDef *basetype ) const;
126         bool                            MatchesType( const idTypeDef &matchtype ) const;
127         bool                            MatchesVirtualFunction( const idTypeDef &matchfunc ) const;
128         void                            AddFunctionParm( idTypeDef *parmtype, const char *name );
129         void                            AddField( idTypeDef *fieldtype, const char *name );
130
131         void                            SetName( const char *newname );
132         const char                      *Name( void ) const;
133
134         etype_t                         Type( void ) const;
135         int                                     Size( void ) const;
136
137         idTypeDef                       *SuperClass( void ) const;
138         
139         idTypeDef                       *ReturnType( void ) const;
140         void                            SetReturnType( idTypeDef *type );
141
142         idTypeDef                       *FieldType( void ) const;
143         void                            SetFieldType( idTypeDef *type );
144
145         idTypeDef                       *PointerType( void ) const;
146         void                            SetPointerType( idTypeDef *type );
147
148         int                                     NumParameters( void ) const;
149         idTypeDef                       *GetParmType( int parmNumber ) const;
150         const char                      *GetParmName( int parmNumber ) const;
151
152         int                                     NumFunctions( void ) const;
153         int                                     GetFunctionNumber( const function_t *func ) const;
154         const function_t        *GetFunction( int funcNumber ) const;
155         void                            AddFunction( const function_t *func );
156 };
157
158 /***********************************************************************
159
160 idScriptObject
161
162 In-game representation of objects in scripts.  Use the idScriptVariable template
163 (below) to access variables.
164
165 ***********************************************************************/
166
167 class idScriptObject {
168 private:
169         idTypeDef                                       *type;
170         
171 public:
172         byte                                            *data;
173
174                                                                 idScriptObject();
175                                                                 ~idScriptObject();
176
177         void                                            Save( idSaveGame *savefile ) const;                     // archives object for save game file
178         void                                            Restore( idRestoreGame *savefile );                     // unarchives object from save game file
179
180         void                                            Free( void );
181         bool                                            SetType( const char *typeName );
182         void                                            ClearObject( void );
183         bool                                            HasObject( void ) const;
184         idTypeDef                                       *GetTypeDef( void ) const;
185         const char                                      *GetTypeName( void ) const;
186         const function_t                        *GetConstructor( void ) const;
187         const function_t                        *GetDestructor( void ) const;
188         const function_t                        *GetFunction( const char *name ) const;
189
190         byte                                            *GetVariable( const char *name, etype_t etype ) const;
191 };
192
193 /***********************************************************************
194
195 idScriptVariable
196
197 Helper template that handles looking up script variables stored in objects.
198 If the specified variable doesn't exist, or is the wrong data type, idScriptVariable
199 will cause an error.
200
201 ***********************************************************************/
202
203 template<class type, etype_t etype, class returnType>
204 class idScriptVariable {
205 private:
206         type                            *data;
207
208 public:
209                                                 idScriptVariable();
210         bool                            IsLinked( void ) const;
211         void                            Unlink( void );
212         void                            LinkTo( idScriptObject &obj, const char *name );
213         idScriptVariable        &operator=( const returnType &value );
214                                                 operator returnType() const;
215 };
216
217 template<class type, etype_t etype, class returnType>
218 ID_INLINE idScriptVariable<type, etype, returnType>::idScriptVariable() {
219         data = NULL;
220 }
221
222 template<class type, etype_t etype, class returnType>
223 ID_INLINE bool idScriptVariable<type, etype, returnType>::IsLinked( void ) const {
224         return ( data != NULL );
225 }
226
227 template<class type, etype_t etype, class returnType>
228 ID_INLINE void idScriptVariable<type, etype, returnType>::Unlink( void ) {
229         data = NULL;
230 }
231
232 template<class type, etype_t etype, class returnType>
233 ID_INLINE void idScriptVariable<type, etype, returnType>::LinkTo( idScriptObject &obj, const char *name ) {
234         data = ( type * )obj.GetVariable( name, etype );
235         if ( !data ) {
236                 gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() );
237         }
238 }
239
240 template<class type, etype_t etype, class returnType>
241 ID_INLINE idScriptVariable<type, etype, returnType> &idScriptVariable<type, etype, returnType>::operator=( const returnType &value ) {
242         // check if we attempt to access the object before it's been linked
243         assert( data );
244
245         // make sure we don't crash if we don't have a pointer
246         if ( data ) {
247                 *data = ( type )value;
248         }
249         return *this;
250 }
251
252 template<class type, etype_t etype, class returnType>
253 ID_INLINE idScriptVariable<type, etype, returnType>::operator returnType() const {
254         // check if we attempt to access the object before it's been linked
255         assert( data );
256
257         // make sure we don't crash if we don't have a pointer
258         if ( data ) {
259                 return ( const returnType )*data;
260         } else {
261                 // reasonably safe value
262                 return ( const returnType )0;
263         }
264 }
265
266 /***********************************************************************
267
268 Script object variable access template instantiations
269
270 These objects will automatically handle looking up of the current value
271 of a variable in a script object.  They can be stored as part of a class
272 for up-to-date values of the variable, or can be used in functions to
273 sample the data for non-dynamic values.
274
275 ***********************************************************************/
276
277 typedef idScriptVariable<int, ev_boolean, int>                          idScriptBool;
278 typedef idScriptVariable<float, ev_float, float>                        idScriptFloat;
279 typedef idScriptVariable<float, ev_float, int>                          idScriptInt;
280 typedef idScriptVariable<idVec3, ev_vector, idVec3>                     idScriptVector;
281 typedef idScriptVariable<idStr, ev_string, const char *>        idScriptString;
282
283 /***********************************************************************
284
285 idCompileError
286
287 Causes the compiler to exit out of compiling the current function and
288 display an error message with line and file info.
289
290 ***********************************************************************/
291
292 class idCompileError : public idException {
293 public:
294         idCompileError( const char *text ) : idException( text ) {}
295 };
296
297 /***********************************************************************
298
299 idVarDef
300
301 Define the name, type, and location of variables, functions, and objects
302 defined in script.
303
304 ***********************************************************************/
305
306 typedef union varEval_s {
307         idScriptObject                  **objectPtrPtr;
308         char                                    *stringPtr;
309         float                                   *floatPtr;
310         idVec3                                  *vectorPtr;
311         function_t                              *functionPtr;
312         int                                     *intPtr;
313         byte                                    *bytePtr;
314         int                                     *entityNumberPtr;
315         int                                             virtualFunction;
316         int                                             jumpOffset;
317         int                                             stackOffset;            // offset in stack for local variables
318         int                                             argSize;
319         varEval_s                               *evalPtr;
320         int                                             ptrOffset;
321 } varEval_t;
322
323 class idVarDefName;
324
325 class idVarDef {
326         friend class idVarDefName;
327
328 public:
329         int                                             num;
330         varEval_t                               value;
331         idVarDef *                              scope;                  // function, namespace, or object the var was defined in
332         int                                             numUsers;               // number of users if this is a constant
333
334         typedef enum {
335                 uninitialized, initializedVariable, initializedConstant, stackVariable
336         } initialized_t;
337
338         initialized_t                   initialized;
339
340 public:
341                                                         idVarDef( idTypeDef *typeptr = NULL );
342                                                         ~idVarDef();
343
344         const char *                    Name( void ) const;
345         const char *                    GlobalName( void ) const;
346
347         void                                    SetTypeDef( idTypeDef *_type ) { typeDef = _type; }
348         idTypeDef *                             TypeDef( void ) const { return typeDef; }
349         etype_t                                 Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; }
350
351         int                                             DepthOfScope( const idVarDef *otherScope ) const;
352
353         void                                    SetFunction( function_t *func );
354         void                                    SetObject( idScriptObject *object );
355         void                                    SetValue( const eval_t &value, bool constant );
356         void                                    SetString( const char *string, bool constant );
357
358         idVarDef *                              Next( void ) const { return next; }             // next var def with same name
359
360         void                                    PrintInfo( idFile *file, int instructionPointer ) const;
361
362 private:
363         idTypeDef *                             typeDef;
364         idVarDefName *                  name;           // name of this var
365         idVarDef *                              next;           // next var with the same name
366 };
367
368 /***********************************************************************
369
370   idVarDefName
371
372 ***********************************************************************/
373
374 class idVarDefName {
375 public:
376                                                         idVarDefName( void ) { defs = NULL; }
377                                                         idVarDefName( const char *n ) { name = n; defs = NULL; }
378
379         const char *                    Name( void ) const { return name; }
380         idVarDef *                              GetDefs( void ) const { return defs; }
381
382         void                                    AddDef( idVarDef *def );
383         void                                    RemoveDef( idVarDef *def );
384
385 private:
386         idStr                                   name;
387         idVarDef *                              defs;
388 };
389
390 /***********************************************************************
391
392   Variable and type defintions
393
394 ***********************************************************************/
395
396 extern  idTypeDef       type_void;
397 extern  idTypeDef       type_scriptevent;
398 extern  idTypeDef       type_namespace;
399 extern  idTypeDef       type_string;
400 extern  idTypeDef       type_float;
401 extern  idTypeDef       type_vector;
402 extern  idTypeDef       type_entity;
403 extern  idTypeDef       type_field;
404 extern  idTypeDef       type_function;
405 extern  idTypeDef       type_virtualfunction;
406 extern  idTypeDef       type_pointer;
407 extern  idTypeDef       type_object;
408 extern  idTypeDef       type_jumpoffset;        // only used for jump opcodes
409 extern  idTypeDef       type_argsize;           // only used for function call and thread opcodes
410 extern  idTypeDef       type_boolean;
411
412 extern  idVarDef        def_void;
413 extern  idVarDef        def_scriptevent;
414 extern  idVarDef        def_namespace;
415 extern  idVarDef        def_string;
416 extern  idVarDef        def_float;
417 extern  idVarDef        def_vector;
418 extern  idVarDef        def_entity;
419 extern  idVarDef        def_field;
420 extern  idVarDef        def_function;
421 extern  idVarDef        def_virtualfunction;
422 extern  idVarDef        def_pointer;
423 extern  idVarDef        def_object;
424 extern  idVarDef        def_jumpoffset;         // only used for jump opcodes
425 extern  idVarDef        def_argsize;            // only used for function call and thread opcodes
426 extern  idVarDef        def_boolean;
427
428 typedef struct statement_s {
429         unsigned short  op;
430         idVarDef                *a;
431         idVarDef                *b;
432         idVarDef                *c;
433         unsigned short  linenumber;
434         unsigned short  file;
435 } statement_t;
436
437 /***********************************************************************
438
439 idProgram
440
441 Handles compiling and storage of script data.  Multiple idProgram objects
442 would represent seperate programs with no knowledge of each other.  Scripts
443 meant to access shared data and functions should all be compiled by a
444 single idProgram.
445
446 ***********************************************************************/
447
448 class idProgram {
449 private:
450         idStrList                                                                       fileList;
451         idStr                                                                           filename;
452         int                                                                                     filenum;
453
454         int                                                                                     numVariables;
455         byte                                                                            variables[ MAX_GLOBALS ];
456         idStaticList<byte,MAX_GLOBALS>                          variableDefaults;
457         idStaticList<function_t,MAX_FUNCS>                      functions;
458         idStaticList<statement_t,MAX_STATEMENTS>        statements;
459         idList<idTypeDef *>                                                     types;
460         idList<idVarDefName *>                                          varDefNames;
461         idHashIndex                                                                     varDefNameHash;
462         idList<idVarDef *>                                                      varDefs;
463
464         idVarDef                                                                        *sysDef;
465
466         int                                                                                     top_functions;
467         int                                                                                     top_statements;
468         int                                                                                     top_types;
469         int                                                                                     top_defs;
470         int                                                                                     top_files;
471
472         void                                                                            CompileStats( void );
473
474 public:
475         idVarDef                                                                        *returnDef;
476         idVarDef                                                                        *returnStringDef;
477
478                                                                                                 idProgram();
479                                                                                                 ~idProgram();
480
481         // save games
482         void                                                                            Save( idSaveGame *savefile ) const;
483         bool                                                                            Restore( idRestoreGame *savefile );
484         int                                                                                     CalculateChecksum( void ) const;                // Used to insure program code has not
485                                                                                                                                                                                 //    changed between savegames
486
487         void                                                                            Startup( const char *defaultScript );
488         void                                                                            Restart( void );
489         bool                                                                            CompileText( const char *source, const char *text, bool console );
490         const function_t                                                        *CompileFunction( const char *functionName, const char *text );
491         void                                                                            CompileFile( const char *filename );
492         void                                                                            BeginCompilation( void );
493         void                                                                            FinishCompilation( void );
494         void                                                                            DisassembleStatement( idFile *file, int instructionPointer ) const;
495         void                                                                            Disassemble( void ) const;
496         void                                                                            FreeData( void );
497
498         const char                                                                      *GetFilename( int num );
499         int                                                                                     GetFilenum( const char *name );
500         int                                                                                     GetLineNumberForStatement( int index );
501         const char                                                                      *GetFilenameForStatement( int index );
502
503         idTypeDef                                                                       *AllocType( idTypeDef &type );
504         idTypeDef                                                                       *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
505         idTypeDef                                                                       *GetType( idTypeDef &type, bool allocate );
506         idTypeDef                                                                       *FindType( const char *name );
507
508         idVarDef                                                                        *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant );
509         idVarDef                                                                        *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const;
510         void                                                                            FreeDef( idVarDef *d, const idVarDef *scope );
511         idVarDef                                                                        *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b );
512         idVarDef                                                                        *GetDefList( const char *name ) const;
513         void                                                                            AddDefToNameList( idVarDef *def, const char *name );
514
515         function_t                                                                      *FindFunction( const char *name ) const;                                                // returns NULL if function not found
516         function_t                                                                      *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found
517         function_t                                                                      &AllocFunction( idVarDef *def );
518         function_t                                                                      *GetFunction( int index );
519         int                                                                                     GetFunctionIndex( const function_t *func );
520
521         void                                                                            SetEntity( const char *name, idEntity *ent );
522
523         statement_t                                                                     *AllocStatement( void );
524         statement_t                                                                     &GetStatement( int index );
525         int                                                                                     NumStatements( void ) { return statements.Num(); }
526
527         int                                                                             GetReturnedInteger( void );
528
529         void                                                                            ReturnFloat( float value );
530         void                                                                            ReturnInteger( int value );
531         void                                                                            ReturnVector( idVec3 const &vec );
532         void                                                                            ReturnString( const char *string );
533         void                                                                            ReturnEntity( idEntity *ent );
534         
535         int                                                                                     NumFilenames( void ) { return fileList.Num( ); }
536 };
537
538 /*
539 ================
540 idProgram::GetStatement
541 ================
542 */
543 ID_INLINE statement_t &idProgram::GetStatement( int index ) {
544         return statements[ index ];
545 }
546
547 /*
548 ================
549 idProgram::GetFunction
550 ================
551 */
552 ID_INLINE function_t *idProgram::GetFunction( int index ) {
553         return &functions[ index ];
554 }
555
556 /*
557 ================
558 idProgram::GetFunctionIndex
559 ================
560 */
561 ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) {
562         return func - &functions[0];
563 }
564
565 /*
566 ================
567 idProgram::GetReturnedInteger
568 ================
569 */
570 ID_INLINE int idProgram::GetReturnedInteger( void ) {
571         return *returnDef->value.intPtr;
572 }
573
574 /*
575 ================
576 idProgram::ReturnFloat
577 ================
578 */
579 ID_INLINE void idProgram::ReturnFloat( float value ) {
580         *returnDef->value.floatPtr = value;
581 }
582
583 /*
584 ================
585 idProgram::ReturnInteger
586 ================
587 */
588 ID_INLINE void idProgram::ReturnInteger( int value ) {
589         *returnDef->value.intPtr = value;
590 }
591
592 /*
593 ================
594 idProgram::ReturnVector
595 ================
596 */
597 ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) {
598         *returnDef->value.vectorPtr = vec;
599 }
600
601 /*
602 ================
603 idProgram::ReturnString
604 ================
605 */
606 ID_INLINE void idProgram::ReturnString( const char *string ) {
607         idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN );
608 }
609
610 /*
611 ================
612 idProgram::GetFilename
613 ================
614 */
615 ID_INLINE const char *idProgram::GetFilename( int num ) {
616         return fileList[ num ];
617 }
618
619 /*
620 ================
621 idProgram::GetLineNumberForStatement
622 ================
623 */
624 ID_INLINE int idProgram::GetLineNumberForStatement( int index ) {
625         return statements[ index ].linenumber;
626 }
627
628 /*
629 ================
630 idProgram::GetFilenameForStatement
631 ================
632 */
633 ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) {
634         return GetFilename( statements[ index ].file );
635 }
636
637 #endif /* !__SCRIPT_PROGRAM_H__ */