Script_Program.h 19 KB

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