2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #ifndef __SCRIPT_PROGRAM_H__
30 #define __SCRIPT_PROGRAM_H__
41 #define MAX_STRING_LEN 128
42 #define MAX_GLOBALS 196608 // in bytes
43 #define MAX_STRINGS 1024
44 #define MAX_FUNCS 3072
45 #define MAX_STATEMENTS 81920 // statement_t - 18 bytes last I checked
48 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
55 size_t Allocated( void ) const;
56 void SetName( const char *name );
57 const char *Name( void ) const;
63 const idEventDef *eventdef;
65 const idTypeDef *type;
69 int locals; // total ints of parms + locals
70 int filenum; // source file defined in
74 typedef union eval_s {
75 const char *stringPtr;
83 /***********************************************************************
87 Contains type information for variables and functions.
89 ***********************************************************************/
97 // function types are more complex
98 idTypeDef *auxType; // return type
99 idList<idTypeDef *> parmTypes;
101 idList<const function_t *> functions;
104 idVarDef *def; // a def that points to this type
106 idTypeDef( const idTypeDef &other );
107 idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
108 void operator=( const idTypeDef& other );
109 size_t Allocated( void ) const;
111 bool Inherits( const idTypeDef *basetype ) const;
112 bool MatchesType( const idTypeDef &matchtype ) const;
113 bool MatchesVirtualFunction( const idTypeDef &matchfunc ) const;
114 void AddFunctionParm( idTypeDef *parmtype, const char *name );
115 void AddField( idTypeDef *fieldtype, const char *name );
117 void SetName( const char *newname );
118 const char *Name( void ) const;
120 etype_t Type( void ) const;
121 int Size( void ) const;
123 idTypeDef *SuperClass( void ) const;
125 idTypeDef *ReturnType( void ) const;
126 void SetReturnType( idTypeDef *type );
128 idTypeDef *FieldType( void ) const;
129 void SetFieldType( idTypeDef *type );
131 idTypeDef *PointerType( void ) const;
132 void SetPointerType( idTypeDef *type );
134 int NumParameters( void ) const;
135 idTypeDef *GetParmType( int parmNumber ) const;
136 const char *GetParmName( int parmNumber ) const;
138 int NumFunctions( void ) const;
139 int GetFunctionNumber( const function_t *func ) const;
140 const function_t *GetFunction( int funcNumber ) const;
141 void AddFunction( const function_t *func );
144 /***********************************************************************
148 In-game representation of objects in scripts. Use the idScriptVariable template
149 (below) to access variables.
151 ***********************************************************************/
153 class idScriptObject {
163 void Save( idSaveGame *savefile ) const; // archives object for save game file
164 void Restore( idRestoreGame *savefile ); // unarchives object from save game file
167 bool SetType( const char *typeName );
168 void ClearObject( void );
169 bool HasObject( void ) const;
170 idTypeDef *GetTypeDef( void ) const;
171 const char *GetTypeName( void ) const;
172 const function_t *GetConstructor( void ) const;
173 const function_t *GetDestructor( void ) const;
174 const function_t *GetFunction( const char *name ) const;
176 byte *GetVariable( const char *name, etype_t etype ) const;
179 /***********************************************************************
183 Helper template that handles looking up script variables stored in objects.
184 If the specified variable doesn't exist, or is the wrong data type, idScriptVariable
187 ***********************************************************************/
189 template<class type, etype_t etype, class returnType>
190 class idScriptVariable {
196 bool IsLinked( void ) const;
198 void LinkTo( idScriptObject &obj, const char *name );
199 idScriptVariable &operator=( const returnType &value );
200 operator returnType() const;
203 template<class type, etype_t etype, class returnType>
204 ID_INLINE idScriptVariable<type, etype, returnType>::idScriptVariable() {
208 template<class type, etype_t etype, class returnType>
209 ID_INLINE bool idScriptVariable<type, etype, returnType>::IsLinked( void ) const {
210 return ( data != NULL );
213 template<class type, etype_t etype, class returnType>
214 ID_INLINE void idScriptVariable<type, etype, returnType>::Unlink( void ) {
218 template<class type, etype_t etype, class returnType>
219 ID_INLINE void idScriptVariable<type, etype, returnType>::LinkTo( idScriptObject &obj, const char *name ) {
220 data = ( type * )obj.GetVariable( name, etype );
222 gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() );
226 template<class type, etype_t etype, class returnType>
227 ID_INLINE idScriptVariable<type, etype, returnType> &idScriptVariable<type, etype, returnType>::operator=( const returnType &value ) {
228 // check if we attempt to access the object before it's been linked
231 // make sure we don't crash if we don't have a pointer
233 *data = ( type )value;
238 template<class type, etype_t etype, class returnType>
239 ID_INLINE idScriptVariable<type, etype, returnType>::operator returnType() const {
240 // check if we attempt to access the object before it's been linked
243 // make sure we don't crash if we don't have a pointer
245 return ( const returnType )*data;
247 // reasonably safe value
248 return ( const returnType )0;
252 /***********************************************************************
254 Script object variable access template instantiations
256 These objects will automatically handle looking up of the current value
257 of a variable in a script object. They can be stored as part of a class
258 for up-to-date values of the variable, or can be used in functions to
259 sample the data for non-dynamic values.
261 ***********************************************************************/
263 typedef idScriptVariable<int, ev_boolean, int> idScriptBool;
264 typedef idScriptVariable<float, ev_float, float> idScriptFloat;
265 typedef idScriptVariable<float, ev_float, int> idScriptInt;
266 typedef idScriptVariable<idVec3, ev_vector, idVec3> idScriptVector;
267 typedef idScriptVariable<idStr, ev_string, const char *> idScriptString;
269 /***********************************************************************
273 Causes the compiler to exit out of compiling the current function and
274 display an error message with line and file info.
276 ***********************************************************************/
278 class idCompileError : public idException {
280 idCompileError( const char *text ) : idException( text ) {}
283 /***********************************************************************
287 Define the name, type, and location of variables, functions, and objects
290 ***********************************************************************/
292 typedef union varEval_s {
293 idScriptObject **objectPtrPtr;
297 function_t *functionPtr;
300 int *entityNumberPtr;
303 int stackOffset; // offset in stack for local variables
312 friend class idVarDefName;
317 idVarDef * scope; // function, namespace, or object the var was defined in
318 int numUsers; // number of users if this is a constant
321 uninitialized, initializedVariable, initializedConstant, stackVariable
324 initialized_t initialized;
327 idVarDef( idTypeDef *typeptr = NULL );
330 const char * Name( void ) const;
331 const char * GlobalName( void ) const;
333 void SetTypeDef( idTypeDef *_type ) { typeDef = _type; }
334 idTypeDef * TypeDef( void ) const { return typeDef; }
335 etype_t Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; }
337 int DepthOfScope( const idVarDef *otherScope ) const;
339 void SetFunction( function_t *func );
340 void SetObject( idScriptObject *object );
341 void SetValue( const eval_t &value, bool constant );
342 void SetString( const char *string, bool constant );
344 idVarDef * Next( void ) const { return next; } // next var def with same name
346 void PrintInfo( idFile *file, int instructionPointer ) const;
350 idVarDefName * name; // name of this var
351 idVarDef * next; // next var with the same name
354 /***********************************************************************
358 ***********************************************************************/
362 idVarDefName( void ) { defs = NULL; }
363 idVarDefName( const char *n ) { name = n; defs = NULL; }
365 const char * Name( void ) const { return name; }
366 idVarDef * GetDefs( void ) const { return defs; }
368 void AddDef( idVarDef *def );
369 void RemoveDef( idVarDef *def );
376 /***********************************************************************
378 Variable and type defintions
380 ***********************************************************************/
382 extern idTypeDef type_void;
383 extern idTypeDef type_scriptevent;
384 extern idTypeDef type_namespace;
385 extern idTypeDef type_string;
386 extern idTypeDef type_float;
387 extern idTypeDef type_vector;
388 extern idTypeDef type_entity;
389 extern idTypeDef type_field;
390 extern idTypeDef type_function;
391 extern idTypeDef type_virtualfunction;
392 extern idTypeDef type_pointer;
393 extern idTypeDef type_object;
394 extern idTypeDef type_jumpoffset; // only used for jump opcodes
395 extern idTypeDef type_argsize; // only used for function call and thread opcodes
396 extern idTypeDef type_boolean;
398 extern idVarDef def_void;
399 extern idVarDef def_scriptevent;
400 extern idVarDef def_namespace;
401 extern idVarDef def_string;
402 extern idVarDef def_float;
403 extern idVarDef def_vector;
404 extern idVarDef def_entity;
405 extern idVarDef def_field;
406 extern idVarDef def_function;
407 extern idVarDef def_virtualfunction;
408 extern idVarDef def_pointer;
409 extern idVarDef def_object;
410 extern idVarDef def_jumpoffset; // only used for jump opcodes
411 extern idVarDef def_argsize; // only used for function call and thread opcodes
412 extern idVarDef def_boolean;
414 typedef struct statement_s {
419 unsigned short linenumber;
423 /***********************************************************************
427 Handles compiling and storage of script data. Multiple idProgram objects
428 would represent seperate programs with no knowledge of each other. Scripts
429 meant to access shared data and functions should all be compiled by a
432 ***********************************************************************/
441 byte variables[ MAX_GLOBALS ];
442 idStaticList<byte,MAX_GLOBALS> variableDefaults;
443 idStaticList<function_t,MAX_FUNCS> functions;
444 idStaticList<statement_t,MAX_STATEMENTS> statements;
445 idList<idTypeDef *> types;
446 idList<idVarDefName *> varDefNames;
447 idHashIndex varDefNameHash;
448 idList<idVarDef *> varDefs;
458 void CompileStats( void );
462 idVarDef *returnStringDef;
468 void Save( idSaveGame *savefile ) const;
469 bool Restore( idRestoreGame *savefile );
470 int CalculateChecksum( void ) const; // Used to insure program code has not
471 // changed between savegames
473 void Startup( const char *defaultScript );
474 void Restart( void );
475 bool CompileText( const char *source, const char *text, bool console );
476 const function_t *CompileFunction( const char *functionName, const char *text );
477 void CompileFile( const char *filename );
478 void BeginCompilation( void );
479 void FinishCompilation( void );
480 void DisassembleStatement( idFile *file, int instructionPointer ) const;
481 void Disassemble( void ) const;
482 void FreeData( void );
484 const char *GetFilename( int num );
485 int GetFilenum( const char *name );
486 int GetLineNumberForStatement( int index );
487 const char *GetFilenameForStatement( int index );
489 idTypeDef *AllocType( idTypeDef &type );
490 idTypeDef *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
491 idTypeDef *GetType( idTypeDef &type, bool allocate );
492 idTypeDef *FindType( const char *name );
494 idVarDef *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant );
495 idVarDef *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const;
496 void FreeDef( idVarDef *d, const idVarDef *scope );
497 idVarDef *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b );
498 idVarDef *GetDefList( const char *name ) const;
499 void AddDefToNameList( idVarDef *def, const char *name );
501 function_t *FindFunction( const char *name ) const; // returns NULL if function not found
502 function_t *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found
503 function_t &AllocFunction( idVarDef *def );
504 function_t *GetFunction( int index );
505 int GetFunctionIndex( const function_t *func );
507 void SetEntity( const char *name, idEntity *ent );
509 statement_t *AllocStatement( void );
510 statement_t &GetStatement( int index );
511 int NumStatements( void ) { return statements.Num(); }
513 int GetReturnedInteger( void );
515 void ReturnFloat( float value );
516 void ReturnInteger( int value );
517 void ReturnVector( idVec3 const &vec );
518 void ReturnString( const char *string );
519 void ReturnEntity( idEntity *ent );
521 int NumFilenames( void ) { return fileList.Num( ); }
526 idProgram::GetStatement
529 ID_INLINE statement_t &idProgram::GetStatement( int index ) {
530 return statements[ index ];
535 idProgram::GetFunction
538 ID_INLINE function_t *idProgram::GetFunction( int index ) {
539 return &functions[ index ];
544 idProgram::GetFunctionIndex
547 ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) {
548 return func - &functions[0];
553 idProgram::GetReturnedInteger
556 ID_INLINE int idProgram::GetReturnedInteger( void ) {
557 return *returnDef->value.intPtr;
562 idProgram::ReturnFloat
565 ID_INLINE void idProgram::ReturnFloat( float value ) {
566 *returnDef->value.floatPtr = value;
571 idProgram::ReturnInteger
574 ID_INLINE void idProgram::ReturnInteger( int value ) {
575 *returnDef->value.intPtr = value;
580 idProgram::ReturnVector
583 ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) {
584 *returnDef->value.vectorPtr = vec;
589 idProgram::ReturnString
592 ID_INLINE void idProgram::ReturnString( const char *string ) {
593 idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN );
598 idProgram::GetFilename
601 ID_INLINE const char *idProgram::GetFilename( int num ) {
602 return fileList[ num ];
607 idProgram::GetLineNumberForStatement
610 ID_INLINE int idProgram::GetLineNumberForStatement( int index ) {
611 return statements[ index ].linenumber;
616 idProgram::GetFilenameForStatement
619 ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) {
620 return GetFilename( statements[ index ].file );
623 #endif /* !__SCRIPT_PROGRAM_H__ */