Parser.y 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. %{
  2. // rcg10042001 Changed to specify Ecc directory...
  3. #include "Ecc/StdH.h"
  4. #include "Ecc/Main.h"
  5. static char *_strCurrentClass;
  6. static int _iCurrentClassID;
  7. static char *_strCurrentBase;
  8. static char *_strCurrentDescription;
  9. static char *_strCurrentThumbnail;
  10. static char *_strCurrentEnum;
  11. static int _bClassIsExported = 0;
  12. static char *_strCurrentPropertyID;
  13. static char *_strCurrentPropertyIdentifier;
  14. static char *_strCurrentPropertyPropertyType;
  15. static char *_strCurrentPropertyEnumType;
  16. static char *_strCurrentPropertyDataType;
  17. static char *_strCurrentPropertyName;
  18. static char *_strCurrentPropertyShortcut;
  19. static char *_strCurrentPropertyColor;
  20. static char *_strCurrentPropertyFlags;
  21. static char *_strCurrentPropertyDefaultCode;
  22. static char *_strCurrentComponentIdentifier;
  23. static char *_strCurrentComponentType;
  24. static char *_strCurrentComponentID;
  25. static char *_strCurrentComponentFileName;
  26. static int _ctInProcedureHandler = 0;
  27. static char _strLastProcedureName[256];
  28. static char _strInWaitName[256];
  29. static char _strAfterWaitName[256];
  30. static char _strInWaitID[256];
  31. static char _strAfterWaitID[256];
  32. static char _strInLoopName[256];
  33. static char _strAfterLoopName[256];
  34. static char _strInLoopID[256];
  35. static char _strAfterLoopID[256];
  36. static char _strCurrentStateID[256];
  37. static int _bInProcedure; // set if currently compiling a procedure
  38. static int _bInHandler;
  39. static int _bHasOtherwise; // set if current 'wait' block has an 'otherwise' statement
  40. static char *_strCurrentEvent;
  41. static int _bFeature_AbstractBaseClass;
  42. static int _bFeature_ImplementsOnInitClass;
  43. static int _bFeature_ImplementsOnEndClass;
  44. static int _bFeature_ImplementsOnPrecache;
  45. static int _bFeature_ImplementsOnWorldInit;
  46. static int _bFeature_ImplementsOnWorldEnd;
  47. static int _bFeature_ImplementsOnWorldTick;
  48. static int _bFeature_ImplementsOnWorldRender;
  49. static int _bFeature_CanBePredictable;
  50. static int _iNextFreeID;
  51. inline int CreateID(void) {
  52. return _iNextFreeID++;
  53. }
  54. static int _ctBraces = 0;
  55. void OpenBrace(void) {
  56. _ctBraces++;
  57. }
  58. void CloseBrace(void) {
  59. _ctBraces--;
  60. }
  61. SType Braces(int iBraces) {
  62. static char strBraces[50];
  63. memset(strBraces, '}', sizeof(strBraces));
  64. strBraces[iBraces] = 0;
  65. return SType(strBraces);
  66. }
  67. char *RemoveLineDirective(char *str)
  68. {
  69. if (str[0]=='\n' && str[1]=='#') {
  70. return strchr(str+2, '\n')+1;
  71. } else {
  72. return str;
  73. }
  74. }
  75. char *GetLineDirective(SType &st)
  76. {
  77. char *str = st.strString;
  78. if (str[0]=='\n' && str[1]=='#' && str[2]=='l') {
  79. char *strResult = strdup(str);
  80. strchr(strResult+3,'\n')[1] = 0;
  81. return strResult;
  82. } else {
  83. return "";
  84. }
  85. }
  86. void AddHandlerFunction(char *strProcedureName, int iStateID)
  87. {
  88. fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName);
  89. fprintf(_fTables, " {0x%08x, -1, CEntity::pEventHandler(&%s::%s), "
  90. "DEBUGSTRING(\"%s::%s\")},\n",
  91. iStateID, _strCurrentClass, strProcedureName, _strCurrentClass, strProcedureName);
  92. }
  93. void AddHandlerFunction(char *strProcedureName, char *strStateID, char *strBaseStateID)
  94. {
  95. fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName);
  96. fprintf(_fTables, " {%s, %s, CEntity::pEventHandler(&%s::%s),"
  97. "DEBUGSTRING(\"%s::%s\")},\n",
  98. strStateID, strBaseStateID, _strCurrentClass, strProcedureName,
  99. _strCurrentClass, RemoveLineDirective(strProcedureName));
  100. strcpy(_strLastProcedureName, RemoveLineDirective(strProcedureName));
  101. _ctInProcedureHandler = 0;
  102. }
  103. void CreateInternalHandlerFunction(char *strFunctionName, char *strID)
  104. {
  105. int iID = CreateID();
  106. _ctInProcedureHandler++;
  107. sprintf(strID, "0x%08x", iID);
  108. sprintf(strFunctionName, "H0x%08x_%s_%02d", iID, _strLastProcedureName, _ctInProcedureHandler);
  109. AddHandlerFunction(strFunctionName, iID);
  110. }
  111. void DeclareFeatureProperties(void)
  112. {
  113. if (_bFeature_CanBePredictable) {
  114. fprintf(_fTables, " CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x%08x<<8)+%s, offsetof(%s, %s), %s, %s, %s, %s),\n",
  115. _iCurrentClassID,
  116. "255",
  117. _strCurrentClass,
  118. "m_penPrediction",
  119. "\"\"",
  120. "0",
  121. "0",
  122. "0");
  123. fprintf(_fDeclaration, " %s %s;\n",
  124. "CEntityPointer",
  125. "m_penPrediction"
  126. );
  127. fprintf(_fImplementation, " m_penPrediction = NULL;\n");
  128. }
  129. }
  130. #undef YYERROR_VERBOSE
  131. %}
  132. /* BISON Declarations */
  133. /* different type of constants */
  134. %token c_char
  135. %token c_int
  136. %token c_float
  137. %token c_bool
  138. %token c_string
  139. /* the standard cpp identifier */
  140. %token identifier
  141. /* specially bracketed cpp blocks */
  142. %token cppblock
  143. /* standard cpp-keywords */
  144. %token k_while
  145. %token k_for
  146. %token k_if
  147. %token k_else
  148. %token k_enum
  149. %token k_switch
  150. %token k_case
  151. %token k_class
  152. %token k_do
  153. %token k_void
  154. %token k_const
  155. %token k_inline
  156. %token k_static
  157. %token k_virtual
  158. %token k_return
  159. %token k_autowait
  160. %token k_autocall
  161. %token k_waitevent
  162. /* aditional keywords */
  163. %token k_event
  164. %token k_name
  165. %token k_thumbnail
  166. %token k_features
  167. %token k_uses
  168. %token k_export
  169. %token k_texture
  170. %token k_sound
  171. %token k_model
  172. %token k_properties
  173. %token k_components
  174. %token k_functions
  175. %token k_procedures
  176. %token k_wait
  177. %token k_on
  178. %token k_otherwise
  179. %token k_call
  180. %token k_jump
  181. %token k_stop
  182. %token k_resume
  183. %token k_pass
  184. /* special data types */
  185. %token k_CTString
  186. %token k_CTStringTrans
  187. %token k_CTFileName
  188. %token k_CTFileNameNoDep
  189. %token k_BOOL
  190. %token k_COLOR
  191. %token k_FLOAT
  192. %token k_INDEX
  193. %token k_RANGE
  194. %token k_CEntityPointer
  195. %token k_CModelObject
  196. %token k_CModelInstance
  197. %token k_CAnimObject
  198. %token k_CSoundObject
  199. %token k_CPlacement3D
  200. %token k_FLOATaabbox3D
  201. %token k_FLOATmatrix3D
  202. %token k_FLOATquat3D
  203. %token k_ANGLE
  204. %token k_FLOAT3D
  205. %token k_ANGLE3D
  206. %token k_FLOATplane3D
  207. %token k_ANIMATION
  208. %token k_ILLUMINATIONTYPE
  209. %token k_FLAGS
  210. %start program
  211. %%
  212. /*/////////////////////////////////////////////////////////
  213. * Global structure of the source file.
  214. */
  215. program
  216. : /* empty file */ {}
  217. | c_int {
  218. int iID = atoi($1.strString);
  219. if(iID>32767) {
  220. yyerror("Maximum allowed id for entity source file is 32767");
  221. }
  222. _iCurrentClassID = iID;
  223. _iNextFreeID = iID<<16;
  224. fprintf(_fDeclaration, "#ifndef _%s_INCLUDED\n", _strFileNameBaseIdentifier);
  225. fprintf(_fDeclaration, "#define _%s_INCLUDED 1\n", _strFileNameBaseIdentifier);
  226. } opt_global_cppblock {
  227. //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllimport)\n");
  228. } uses_list {
  229. //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllexport)\n");
  230. fprintf(_fImplementation, "#include <%s.h>\n", _strFileNameBase);
  231. fprintf(_fImplementation, "#include <%s_tables.h>\n", _strFileNameBase);
  232. } enum_and_event_declarations_list {
  233. } opt_global_cppblock {
  234. } opt_class_declaration {
  235. fprintf(_fDeclaration, "#endif // _%s_INCLUDED\n", _strFileNameBaseIdentifier);
  236. }
  237. ;
  238. /*
  239. * Prolog cpp code.
  240. */
  241. opt_global_cppblock
  242. : /* null */
  243. | cppblock { fprintf(_fImplementation, "%s\n", $1.strString); }
  244. ;
  245. uses_list
  246. : /* null */
  247. | uses_list uses_statement
  248. ;
  249. uses_statement
  250. : k_uses c_string ';' {
  251. char *strUsedFileName = strdup($2.strString);
  252. strUsedFileName[strlen(strUsedFileName)-1] = 0;
  253. fprintf(_fDeclaration, "#include <%s.h>\n", strUsedFileName+1);
  254. }
  255. ;
  256. enum_and_event_declarations_list
  257. : /* null */
  258. | enum_and_event_declarations_list enum_declaration
  259. | enum_and_event_declarations_list event_declaration
  260. ;
  261. /*/////////////////////////////////////////////////////////
  262. * Enum types declarations
  263. */
  264. enum_declaration
  265. : k_enum identifier {
  266. _strCurrentEnum = $2.strString;
  267. fprintf(_fTables, "EP_ENUMBEG(%s)\n", _strCurrentEnum );
  268. fprintf(_fDeclaration, "extern DECL_DLL CEntityPropertyEnumType %s_enum;\n", _strCurrentEnum );
  269. fprintf(_fDeclaration, "enum %s {\n", _strCurrentEnum );
  270. } '{' enum_values_list opt_comma '}' ';' {
  271. fprintf(_fTables, "EP_ENUMEND(%s);\n\n", _strCurrentEnum);
  272. fprintf(_fDeclaration, "};\n");
  273. fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = (%s)0; } ;\n", _strCurrentEnum, _strCurrentEnum);
  274. }
  275. ;
  276. opt_comma : /*null*/ | ',';
  277. enum_values_list
  278. : enum_value
  279. | enum_values_list ',' enum_value
  280. ;
  281. enum_value
  282. : c_int identifier c_string {
  283. fprintf(_fTables, " EP_ENUMVALUE(%s, %s),\n", $2.strString, $3.strString);
  284. fprintf(_fDeclaration, " %s = %s,\n", $2.strString, $1.strString);
  285. }
  286. ;
  287. /*/////////////////////////////////////////////////////////
  288. * Event declarations
  289. */
  290. event_declaration
  291. : k_event identifier {
  292. _strCurrentEvent = $2.strString;
  293. int iID = CreateID();
  294. fprintf(_fDeclaration, "#define EVENTCODE_%s 0x%08x\n", _strCurrentEvent, iID);
  295. fprintf(_fDeclaration, "class DECL_DLL %s : public CEntityEvent {\npublic:\n",
  296. _strCurrentEvent);
  297. fprintf(_fDeclaration, "%s();\n", _strCurrentEvent );
  298. fprintf(_fDeclaration, "CEntityEvent *MakeCopy(void);\n");
  299. fprintf(_fImplementation,
  300. "CEntityEvent *%s::MakeCopy(void) { "
  301. "CEntityEvent *peeCopy = new %s(*this); "
  302. "return peeCopy;}\n",
  303. _strCurrentEvent, _strCurrentEvent);
  304. fprintf(_fImplementation, "%s::%s() : CEntityEvent(EVENTCODE_%s) {;\n",
  305. _strCurrentEvent, _strCurrentEvent, _strCurrentEvent);
  306. } '{' event_members_list opt_comma '}' ';' {
  307. fprintf(_fImplementation, "};\n");
  308. fprintf(_fDeclaration, "};\n");
  309. fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = %s(); } ;\n", _strCurrentEvent, _strCurrentEvent);
  310. }
  311. ;
  312. event_members_list
  313. : /* null */
  314. | non_empty_event_members_list
  315. ;
  316. non_empty_event_members_list
  317. : event_member
  318. | event_members_list ',' event_member
  319. ;
  320. event_member
  321. : any_type identifier {
  322. fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString);
  323. fprintf(_fImplementation, " ClearToDefault(%s);\n", $2.strString);
  324. }
  325. ;
  326. /*/////////////////////////////////////////////////////////
  327. * The class declaration structure.
  328. */
  329. opt_class_declaration
  330. : /* null */
  331. | class_declaration
  332. ;
  333. class_declaration
  334. : /* null */
  335. | class_optexport identifier ':' identifier '{'
  336. k_name c_string ';'
  337. k_thumbnail c_string ';' {
  338. _strCurrentClass = $2.strString;
  339. _strCurrentBase = $4.strString;
  340. _strCurrentDescription = $7.strString;
  341. _strCurrentThumbnail = $10.strString;
  342. fprintf(_fTables, "#define ENTITYCLASS %s\n\n", _strCurrentClass);
  343. fprintf(_fDeclaration, "extern \"C\" DECL_DLL CDLLEntityClass %s_DLLClass;\n",
  344. _strCurrentClass);
  345. fprintf(_fDeclaration, "%s %s : public %s {\npublic:\n",
  346. $1.strString, _strCurrentClass, _strCurrentBase);
  347. } opt_features {
  348. fprintf(_fDeclaration, " %s virtual void SetDefaultProperties(void);\n", _bClassIsExported?"":"DECL_DLL");
  349. fprintf(_fImplementation, "void %s::SetDefaultProperties(void) {\n", _strCurrentClass);
  350. fprintf(_fTables, "CEntityProperty %s_properties[] = {\n", _strCurrentClass);
  351. } k_properties ':' property_declaration_list {
  352. fprintf(_fImplementation, " %s::SetDefaultProperties();\n}\n", _strCurrentBase);
  353. fprintf(_fTables, "CEntityComponent %s_components[] = {\n", _strCurrentClass);
  354. } opt_internal_properties {
  355. } k_components ':' component_declaration_list {
  356. _bTrackLineInformation = 1;
  357. fprintf(_fTables, "CEventHandlerEntry %s_handlers[] = {\n", _strCurrentClass);
  358. _bInProcedure = 0;
  359. _bInHandler = 0;
  360. } k_functions ':' function_list {
  361. _bInProcedure = 1;
  362. } k_procedures ':' procedure_list {
  363. } '}' ';' {
  364. fprintf(_fTables, "};\n#define %s_handlersct ARRAYCOUNT(%s_handlers)\n",
  365. _strCurrentClass, _strCurrentClass);
  366. fprintf(_fTables, "\n");
  367. if (_bFeature_AbstractBaseClass) {
  368. fprintf(_fTables, "CEntity *%s_New(void) { return NULL; };\n",
  369. _strCurrentClass);
  370. } else {
  371. fprintf(_fTables, "CEntity *%s_New(void) { return new %s; };\n",
  372. _strCurrentClass, _strCurrentClass);
  373. }
  374. if (!_bFeature_ImplementsOnInitClass) {
  375. fprintf(_fTables, "void %s_OnInitClass(void) {};\n", _strCurrentClass);
  376. } else {
  377. fprintf(_fTables, "void %s_OnInitClass(void);\n", _strCurrentClass);
  378. }
  379. if (!_bFeature_ImplementsOnEndClass) {
  380. fprintf(_fTables, "void %s_OnEndClass(void) {};\n", _strCurrentClass);
  381. } else {
  382. fprintf(_fTables, "void %s_OnEndClass(void);\n", _strCurrentClass);
  383. }
  384. if (!_bFeature_ImplementsOnPrecache) {
  385. fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser) {};\n", _strCurrentClass);
  386. } else {
  387. fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser);\n", _strCurrentClass);
  388. }
  389. if (!_bFeature_ImplementsOnWorldEnd) {
  390. fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo) {};\n", _strCurrentClass);
  391. } else {
  392. fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo);\n", _strCurrentClass);
  393. }
  394. if (!_bFeature_ImplementsOnWorldInit) {
  395. fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo) {};\n", _strCurrentClass);
  396. } else {
  397. fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo);\n", _strCurrentClass);
  398. }
  399. if (!_bFeature_ImplementsOnWorldTick) {
  400. fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo) {};\n", _strCurrentClass);
  401. } else {
  402. fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo);\n", _strCurrentClass);
  403. }
  404. if (!_bFeature_ImplementsOnWorldRender) {
  405. fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo) {};\n", _strCurrentClass);
  406. } else {
  407. fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo);\n", _strCurrentClass);
  408. }
  409. fprintf(_fTables, "ENTITY_CLASSDEFINITION(%s, %s, %s, %s, 0x%08x);\n",
  410. _strCurrentClass, _strCurrentBase,
  411. _strCurrentDescription, _strCurrentThumbnail, _iCurrentClassID);
  412. fprintf(_fTables, "DECLARE_CTFILENAME(_fnm%s_tbn, %s);\n", _strCurrentClass, _strCurrentThumbnail);
  413. fprintf(_fDeclaration, "};\n");
  414. }
  415. ;
  416. class_optexport
  417. : k_class { $$ = $1; _bClassIsExported = 0; }
  418. | k_class k_export { $$ = $1+" DECL_DLL "; _bClassIsExported = 1; }
  419. ;
  420. opt_features
  421. : /*null */
  422. | k_features {
  423. _bFeature_ImplementsOnWorldInit = 0;
  424. _bFeature_ImplementsOnWorldEnd = 0;
  425. _bFeature_ImplementsOnWorldTick = 0;
  426. _bFeature_ImplementsOnWorldRender = 0;
  427. _bFeature_ImplementsOnInitClass = 0;
  428. _bFeature_ImplementsOnEndClass = 0;
  429. _bFeature_ImplementsOnPrecache = 0;
  430. _bFeature_AbstractBaseClass = 0;
  431. _bFeature_CanBePredictable = 0;
  432. }features_list ';'
  433. ;
  434. features_list
  435. : feature
  436. | features_list ',' feature
  437. ;
  438. feature
  439. : c_string {
  440. if (strcmp($1.strString, "\"AbstractBaseClass\"")==0) {
  441. _bFeature_AbstractBaseClass = 1;
  442. } else if (strcmp($1.strString, "\"IsTargetable\"")==0) {
  443. fprintf(_fDeclaration, "virtual BOOL IsTargetable(void) const { return TRUE; };\n");
  444. } else if (strcmp($1.strString, "\"IsImportant\"")==0) {
  445. fprintf(_fDeclaration, "virtual BOOL IsImportant(void) const { return TRUE; };\n");
  446. } else if (strcmp($1.strString, "\"HasName\"")==0) {
  447. fprintf(_fDeclaration,
  448. "virtual const CTString &GetName(void) const { return m_strName; };\n");
  449. } else if (strcmp($1.strString, "\"CanBePredictable\"")==0) {
  450. fprintf(_fDeclaration,
  451. "virtual CEntity *GetPredictionPair(void) { return m_penPrediction; };\n");
  452. fprintf(_fDeclaration,
  453. "virtual void SetPredictionPair(CEntity *penPair) { m_penPrediction = penPair; };\n");
  454. _bFeature_CanBePredictable = 1;
  455. } else if (strcmp($1.strString, "\"HasDescription\"")==0) {
  456. fprintf(_fDeclaration,
  457. "virtual const CTString &GetDescription(void) const { return m_strDescription; };\n");
  458. } else if (strcmp($1.strString, "\"HasTarget\"")==0) {
  459. fprintf(_fDeclaration,
  460. "virtual CEntity *GetTarget(void) const { return m_penTarget; };\n");
  461. } else if (strcmp($1.strString, "\"ImplementsOnInitClass\"")==0) {
  462. _bFeature_ImplementsOnInitClass = 1;
  463. } else if (strcmp($1.strString, "\"ImplementsOnEndClass\"")==0) {
  464. _bFeature_ImplementsOnEndClass = 1;
  465. } else if (strcmp($1.strString, "\"ImplementsOnPrecache\"")==0) {
  466. _bFeature_ImplementsOnPrecache = 1;
  467. } else if (strcmp($1.strString, "\"ImplementsOnWorldInit\"")==0) {
  468. _bFeature_ImplementsOnWorldInit = 1;
  469. } else if (strcmp($1.strString, "\"ImplementsOnWorldEnd\"")==0) {
  470. _bFeature_ImplementsOnWorldEnd = 1;
  471. } else if (strcmp($1.strString, "\"ImplementsOnWorldTick\"")==0) {
  472. _bFeature_ImplementsOnWorldTick = 1;
  473. } else if (strcmp($1.strString, "\"ImplementsOnWorldRender\"")==0) {
  474. _bFeature_ImplementsOnWorldRender = 1;
  475. } else {
  476. yyerror((SType("Unknown feature: ")+$1).strString);
  477. }
  478. }
  479. ;
  480. opt_internal_properties
  481. : /* null */
  482. | '{' internal_property_list '}'
  483. ;
  484. internal_property_list
  485. : /* null */
  486. | internal_property_list internal_property
  487. ;
  488. internal_property
  489. : any_type identifier ';' {
  490. fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString);
  491. }
  492. ;
  493. /*/////////////////////////////////////////////////////////
  494. * Property declarations
  495. */
  496. property_declaration_list
  497. : empty_property_declaration_list {
  498. DeclareFeatureProperties(); // this won't work, but at least it will generate an error!!!!
  499. fprintf(_fTables, " CEntityProperty()\n};\n");
  500. fprintf(_fTables, "#define %s_propertiesct 0\n", _strCurrentClass);
  501. fprintf(_fTables, "\n");
  502. fprintf(_fTables, "\n");
  503. }
  504. | nonempty_property_declaration_list opt_comma {
  505. DeclareFeatureProperties();
  506. fprintf(_fTables, "};\n");
  507. fprintf(_fTables, "#define %s_propertiesct ARRAYCOUNT(%s_properties)\n",
  508. _strCurrentClass, _strCurrentClass);
  509. fprintf(_fTables, "\n");
  510. }
  511. ;
  512. nonempty_property_declaration_list
  513. : property_declaration
  514. | nonempty_property_declaration_list ',' property_declaration
  515. ;
  516. empty_property_declaration_list
  517. : /* null */
  518. ;
  519. property_declaration
  520. : property_id property_type property_identifier property_wed_name_opt property_default_opt property_flags_opt {
  521. fprintf(_fTables, " CEntityProperty(%s, %s, (0x%08x<<8)+%s, offsetof(%s, %s), %s, %s, %s, %s),\n",
  522. _strCurrentPropertyPropertyType,
  523. _strCurrentPropertyEnumType,
  524. _iCurrentClassID,
  525. _strCurrentPropertyID,
  526. _strCurrentClass,
  527. _strCurrentPropertyIdentifier,
  528. _strCurrentPropertyName,
  529. _strCurrentPropertyShortcut,
  530. _strCurrentPropertyColor,
  531. _strCurrentPropertyFlags);
  532. fprintf(_fDeclaration, " %s %s;\n",
  533. _strCurrentPropertyDataType,
  534. _strCurrentPropertyIdentifier
  535. );
  536. if (strlen(_strCurrentPropertyDefaultCode)>0) {
  537. fprintf(_fImplementation, " %s\n", _strCurrentPropertyDefaultCode);
  538. }
  539. }
  540. ;
  541. property_id : c_int { _strCurrentPropertyID = $1.strString; };
  542. property_identifier : identifier { _strCurrentPropertyIdentifier = $1.strString; };
  543. property_type
  544. : k_enum identifier {
  545. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENUM";
  546. _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString;
  547. _strCurrentPropertyDataType = (SType("enum ")+$2.strString).strString;
  548. }
  549. | k_FLAGS identifier {
  550. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLAGS";
  551. _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString;
  552. _strCurrentPropertyDataType = "ULONG";
  553. }
  554. | k_CTString {
  555. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRING";
  556. _strCurrentPropertyEnumType = "NULL";
  557. _strCurrentPropertyDataType = "CTString";
  558. }
  559. | k_CTStringTrans {
  560. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRINGTRANS";
  561. _strCurrentPropertyEnumType = "NULL";
  562. _strCurrentPropertyDataType = "CTStringTrans";
  563. }
  564. | k_CTFileName {
  565. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAME";
  566. _strCurrentPropertyEnumType = "NULL";
  567. _strCurrentPropertyDataType = "CTFileName";
  568. }
  569. | k_CTFileNameNoDep {
  570. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAMENODEP";
  571. _strCurrentPropertyEnumType = "NULL";
  572. _strCurrentPropertyDataType = "CTFileNameNoDep";
  573. }
  574. | k_BOOL {
  575. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_BOOL";
  576. _strCurrentPropertyEnumType = "NULL";
  577. _strCurrentPropertyDataType = "BOOL";
  578. }
  579. | k_COLOR {
  580. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_COLOR";
  581. _strCurrentPropertyEnumType = "NULL";
  582. _strCurrentPropertyDataType = "COLOR";
  583. }
  584. | k_FLOAT {
  585. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT";
  586. _strCurrentPropertyEnumType = "NULL";
  587. _strCurrentPropertyDataType = "FLOAT";
  588. }
  589. | k_INDEX {
  590. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_INDEX";
  591. _strCurrentPropertyEnumType = "NULL";
  592. _strCurrentPropertyDataType = "INDEX";
  593. }
  594. | k_RANGE {
  595. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_RANGE";
  596. _strCurrentPropertyEnumType = "NULL";
  597. _strCurrentPropertyDataType = "RANGE";
  598. }
  599. | k_CEntityPointer {
  600. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENTITYPTR";
  601. _strCurrentPropertyEnumType = "NULL";
  602. _strCurrentPropertyDataType = "CEntityPointer";
  603. }
  604. | k_CModelObject {
  605. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELOBJECT";
  606. _strCurrentPropertyEnumType = "NULL";
  607. _strCurrentPropertyDataType = "CModelObject";
  608. }
  609. | k_CModelInstance {
  610. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELINSTANCE";
  611. _strCurrentPropertyEnumType = "NULL";
  612. _strCurrentPropertyDataType = "CModelInstance";
  613. }
  614. | k_CAnimObject {
  615. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMOBJECT";
  616. _strCurrentPropertyEnumType = "NULL";
  617. _strCurrentPropertyDataType = "CAnimObject";
  618. }
  619. | k_CSoundObject {
  620. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_SOUNDOBJECT";
  621. _strCurrentPropertyEnumType = "NULL";
  622. _strCurrentPropertyDataType = "CSoundObject";
  623. }
  624. | k_CPlacement3D {
  625. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_PLACEMENT3D";
  626. _strCurrentPropertyEnumType = "NULL";
  627. _strCurrentPropertyDataType = "CPlacement3D";
  628. }
  629. | k_FLOATaabbox3D {
  630. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATAABBOX3D";
  631. _strCurrentPropertyEnumType = "NULL";
  632. _strCurrentPropertyDataType = "FLOATaabbox3D";
  633. }
  634. | k_FLOATmatrix3D {
  635. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATMATRIX3D";
  636. _strCurrentPropertyEnumType = "NULL";
  637. _strCurrentPropertyDataType = "FLOATmatrix3D";
  638. }
  639. | k_FLOATquat3D {
  640. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATQUAT3D";
  641. _strCurrentPropertyEnumType = "NULL";
  642. _strCurrentPropertyDataType = "FLOATquat3D";
  643. }
  644. | k_ANGLE {
  645. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE";
  646. _strCurrentPropertyEnumType = "NULL";
  647. _strCurrentPropertyDataType = "ANGLE";
  648. }
  649. | k_ANGLE3D {
  650. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE3D";
  651. _strCurrentPropertyEnumType = "NULL";
  652. _strCurrentPropertyDataType = "ANGLE3D";
  653. }
  654. | k_FLOAT3D {
  655. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT3D";
  656. _strCurrentPropertyEnumType = "NULL";
  657. _strCurrentPropertyDataType = "FLOAT3D";
  658. }
  659. | k_FLOATplane3D {
  660. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATplane3D";
  661. _strCurrentPropertyEnumType = "NULL";
  662. _strCurrentPropertyDataType = "FLOATplane3D";
  663. }
  664. | k_ILLUMINATIONTYPE {
  665. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ILLUMINATIONTYPE";
  666. _strCurrentPropertyEnumType = "NULL";
  667. _strCurrentPropertyDataType = "ILLUMINATIONTYPE";
  668. }
  669. | k_ANIMATION {
  670. _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMATION";
  671. _strCurrentPropertyEnumType = "NULL";
  672. _strCurrentPropertyDataType = "ANIMATION";
  673. }
  674. ;
  675. property_wed_name_opt
  676. : /* null */ {
  677. _strCurrentPropertyName = "\"\"";
  678. _strCurrentPropertyShortcut = "0";
  679. _strCurrentPropertyColor = "0"; // this won't be rendered anyway
  680. }
  681. | c_string property_shortcut_opt property_color_opt {
  682. _strCurrentPropertyName = $1.strString;
  683. }
  684. ;
  685. property_shortcut_opt
  686. : /* null */ {
  687. _strCurrentPropertyShortcut = "0";
  688. }
  689. | c_char {
  690. _strCurrentPropertyShortcut = $1.strString;
  691. }
  692. property_color_opt
  693. : /* null */ {
  694. _strCurrentPropertyColor = "0x7F0000FFUL"; // dark red
  695. }
  696. | k_COLOR '(' expression ')' {
  697. _strCurrentPropertyColor = $3.strString;
  698. }
  699. property_flags_opt
  700. : /* null */ {
  701. _strCurrentPropertyFlags = "0"; // dark red
  702. }
  703. | k_features '(' expression ')' {
  704. _strCurrentPropertyFlags = $3.strString;
  705. }
  706. property_default_opt
  707. : /* null */ {
  708. if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) {
  709. _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = NULL;").strString;
  710. } else if (strcmp(_strCurrentPropertyDataType,"CModelObject")==0) {
  711. _strCurrentPropertyDefaultCode =
  712. (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n"+
  713. _strCurrentPropertyIdentifier+".mo_toTexture.SetData(NULL);").strString;
  714. } else if (strcmp(_strCurrentPropertyDataType,"CModelInstance")==0) {
  715. _strCurrentPropertyDefaultCode =
  716. (SType(_strCurrentPropertyIdentifier)+".Clear();\n").strString;
  717. } else if (strcmp(_strCurrentPropertyDataType,"CAnimObject")==0) {
  718. _strCurrentPropertyDefaultCode =
  719. (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n").strString;
  720. } else if (strcmp(_strCurrentPropertyDataType,"CSoundObject")==0) {
  721. _strCurrentPropertyDefaultCode =
  722. (SType(_strCurrentPropertyIdentifier)+".SetOwner(this);\n"+
  723. _strCurrentPropertyIdentifier+".Stop_internal();").strString;
  724. } else {
  725. yyerror("this kind of property must have default value");
  726. _strCurrentPropertyDefaultCode = "";
  727. }
  728. }
  729. | '=' property_default_expression {
  730. if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) {
  731. yyerror("CEntityPointer type properties always default to NULL");
  732. } else {
  733. _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = "+$2.strString+";").strString;
  734. }
  735. }
  736. ;
  737. property_default_expression
  738. : c_int|c_float|c_bool|c_char|c_string
  739. | identifier {$$ = $1 + " ";}
  740. | identifier '(' expression ')' {$$ = $1+$2+$3+$4;}
  741. | type_keyword '(' expression ')' {$$ = $1+$2+$3+$4;}
  742. | '-' property_default_expression {$$ = $1+$2;}
  743. | '(' expression ')' {$$ = $1+$2+$3;}
  744. ;
  745. /*/////////////////////////////////////////////////////////
  746. * Component declarations
  747. */
  748. component_declaration_list
  749. : empty_component_declaration_list {
  750. fprintf(_fTables, " CEntityComponent()\n};\n");
  751. fprintf(_fTables, "#define %s_componentsct 0\n", _strCurrentClass);
  752. fprintf(_fTables, "\n");
  753. fprintf(_fTables, "\n");
  754. }
  755. | nonempty_component_declaration_list opt_comma {
  756. fprintf(_fTables, "};\n");
  757. fprintf(_fTables, "#define %s_componentsct ARRAYCOUNT(%s_components)\n",
  758. _strCurrentClass, _strCurrentClass);
  759. fprintf(_fTables, "\n");
  760. }
  761. ;
  762. nonempty_component_declaration_list
  763. : component_declaration
  764. | nonempty_component_declaration_list ',' component_declaration
  765. ;
  766. empty_component_declaration_list
  767. : /* null */
  768. ;
  769. component_declaration
  770. : component_id component_type component_identifier component_filename {
  771. fprintf(_fTables, "#define %s ((0x%08x<<8)+%s)\n",
  772. _strCurrentComponentIdentifier,
  773. _iCurrentClassID,
  774. _strCurrentComponentID);
  775. fprintf(_fTables, " CEntityComponent(%s, %s, \"%s%s\" %s),\n",
  776. _strCurrentComponentType,
  777. _strCurrentComponentIdentifier,
  778. "EF","NM",
  779. _strCurrentComponentFileName);
  780. }
  781. ;
  782. component_id : c_int { _strCurrentComponentID = $1.strString; };
  783. component_identifier : identifier { _strCurrentComponentIdentifier = $1.strString; };
  784. component_filename : c_string { _strCurrentComponentFileName = $1.strString; };
  785. component_type
  786. : k_model { _strCurrentComponentType = "ECT_MODEL"; }
  787. | k_texture { _strCurrentComponentType = "ECT_TEXTURE"; }
  788. | k_sound { _strCurrentComponentType = "ECT_SOUND"; }
  789. | k_class { _strCurrentComponentType = "ECT_CLASS"; }
  790. ;
  791. /*/////////////////////////////////////////////////////////
  792. * Functions
  793. */
  794. function_list
  795. : { $$ = "";}
  796. | function_list function_implementation {$$ = $1+$2;}
  797. ;
  798. function_implementation
  799. : opt_export opt_virtual return_type opt_tilde identifier '(' parameters_list ')' opt_const
  800. '{' statements '}' opt_semicolon {
  801. char *strReturnType = $3.strString;
  802. char *strFunctionHeader = ($4+$5+$6+$7+$8+$9).strString;
  803. char *strFunctionBody = ($10+$11+$12).strString;
  804. if (strcmp($5.strString, _strCurrentClass)==0) {
  805. if (strcmp(strReturnType+strlen(strReturnType)-4, "void")==0 ) {
  806. strReturnType = "";
  807. } else {
  808. yyerror("use 'void' as return type for constructors");
  809. }
  810. }
  811. fprintf(_fDeclaration, " %s %s %s %s;\n",
  812. $1.strString, $2.strString, strReturnType, strFunctionHeader);
  813. fprintf(_fImplementation, " %s %s::%s %s\n",
  814. strReturnType, _strCurrentClass, strFunctionHeader, strFunctionBody);
  815. }
  816. ;
  817. opt_tilde
  818. : { $$ = "";}
  819. | '~' { $$ = " ~ "; }
  820. ;
  821. opt_export
  822. : { $$ = "";}
  823. | k_export {
  824. if (_bClassIsExported) {
  825. $$ = "";
  826. } else {
  827. $$ = " DECL_DLL ";
  828. }
  829. }
  830. ;
  831. opt_const
  832. : { $$ = "";}
  833. | k_const { $$ = $1; }
  834. ;
  835. opt_virtual
  836. : { $$ = "";}
  837. | k_virtual { $$ = $1; }
  838. ;
  839. opt_semicolon
  840. : /* null */
  841. | ';'
  842. ;
  843. parameters_list
  844. : { $$ = "";}
  845. | k_void
  846. | non_void_parameters_list
  847. ;
  848. non_void_parameters_list
  849. : parameter_declaration
  850. | non_void_parameters_list ',' parameter_declaration {$$ = $1+$2+$3;}
  851. ;
  852. parameter_declaration
  853. : any_type identifier { $$=$1+" "+$2; }
  854. ;
  855. return_type
  856. : any_type
  857. | k_void
  858. ;
  859. any_type
  860. : type_keyword
  861. | identifier
  862. | k_enum identifier { $$=$1+" "+$2; }
  863. | any_type '*' { $$=$1+" "+$2; }
  864. | any_type '&' { $$=$1+" "+$2; }
  865. | k_void '*' { $$=$1+" "+$2; }
  866. | k_const any_type { $$=$1+" "+$2; }
  867. | k_inline any_type { $$=$1+" "+$2; }
  868. | k_static any_type { $$=$1+" "+$2; }
  869. | k_class any_type { $$=$1+" "+$2; }
  870. | identifier '<' any_type '>' { $$=$1+" "+$2+" "+$3+" "+$4; }
  871. ;
  872. /*/////////////////////////////////////////////////////////
  873. * Procedures
  874. */
  875. procedure_list
  876. : { $$ = "";}
  877. | procedure_list procedure_implementation {$$ = $1+$2;}
  878. ;
  879. opt_override
  880. : { $$ = "-1"; }
  881. | ':' identifier ':' ':' identifier {
  882. $$ = SType("STATE_")+$2+"_"+$5;
  883. }
  884. ;
  885. procedure_implementation
  886. : identifier '(' event_specification ')' opt_override {
  887. char *strProcedureName = $1.strString;
  888. char strInputEventType[80];
  889. char strInputEventName[80];
  890. sscanf($3.strString, "%s %s", strInputEventType, strInputEventName);
  891. char strStateID[256];
  892. char *strBaseStateID = "-1";
  893. if(strcmp(RemoveLineDirective(strProcedureName), "Main")==0){
  894. strcpy(strStateID, "1");
  895. if(strncmp(strInputEventType, "EVoid", 4)!=0 && _strCurrentThumbnail[2]!=0) {
  896. yyerror("procedure 'Main' can take input parameters only in classes without thumbnails");
  897. }
  898. } else {
  899. sprintf(strStateID, "0x%08x", CreateID());
  900. }
  901. sprintf(_strCurrentStateID, "STATE_%s_%s",
  902. _strCurrentClass, RemoveLineDirective(strProcedureName));
  903. fprintf(_fDeclaration, "#define %s %s\n", _strCurrentStateID, strStateID);
  904. AddHandlerFunction(strProcedureName, strStateID, $5.strString);
  905. fprintf(_fImplementation,
  906. "BOOL %s::%s(const CEntityEvent &__eeInput) {\n#undef STATE_CURRENT\n#define STATE_CURRENT %s\n",
  907. _strCurrentClass, strProcedureName, _strCurrentStateID);
  908. fprintf(_fImplementation,
  909. " ASSERTMSG(__eeInput.ee_slEvent==EVENTCODE_%s, \"%s::%s expects '%s' as input!\");",
  910. strInputEventType, _strCurrentClass, RemoveLineDirective(strProcedureName),
  911. strInputEventType);
  912. fprintf(_fImplementation, " const %s &%s = (const %s &)__eeInput;",
  913. strInputEventType, strInputEventName, strInputEventType);
  914. } '{' statements '}' opt_semicolon {
  915. char *strFunctionBody = $8.strString;
  916. fprintf(_fImplementation, "%s ASSERT(FALSE); return TRUE;};", strFunctionBody);
  917. }
  918. ;
  919. event_specification
  920. : {
  921. $$="EVoid e";
  922. }
  923. | identifier {
  924. $$=$1+" e";
  925. }
  926. | identifier identifier {
  927. $$=$1+" "+$2;
  928. }
  929. ;
  930. expression
  931. : c_int|c_float|c_bool|c_char|c_string
  932. | identifier {$$ = $1 + " ";}
  933. | type_keyword
  934. | '='|'+'|'-'|'<'|'>'|'!'|'|'|'&'|'*'|'/'|'%'|'^'|'['|']'|':'|','|'.'|'?'|'~'
  935. | '(' ')' {$$=$1+$2;}
  936. | '+' '+' {$$=$1+$2;}
  937. | '-' '-' {$$=$1+$2;}
  938. | '-' '>' {$$=$1+$2;}
  939. | ':' ':' {$$=$1+$2;}
  940. | '&' '&' {$$=$1+$2;}
  941. | '|' '|' {$$=$1+$2;}
  942. | '^' '^' {$$=$1+$2;}
  943. | '>' '>' {$$=$1+$2;}
  944. | '<' '<' {$$=$1+$2;}
  945. | '=' '=' {$$=$1+$2;}
  946. | '!' '=' {$$=$1+$2;}
  947. | '>' '=' {$$=$1+$2;}
  948. | '<' '=' {$$=$1+$2;}
  949. | '&' '=' {$$=$1+$2;}
  950. | '|' '=' {$$=$1+$2;}
  951. | '^' '=' {$$=$1+$2;}
  952. | '+' '=' {$$=$1+$2;}
  953. | '-' '=' {$$=$1+$2;}
  954. | '/' '=' {$$=$1+$2;}
  955. | '%' '=' {$$=$1+$2;}
  956. | '*' '=' {$$=$1+$2;}
  957. | '>' '>' '=' {$$=$1+$2+$3;}
  958. | '<' '<' '=' {$$=$1+$2+$3;}
  959. | '(' expression ')' {$$ = $1+$2+$3;}
  960. | expression expression {$$ = $1+" "+$2;}
  961. ;
  962. type_keyword
  963. : k_CTString|k_CTStringTrans|k_CTFileName|k_CTFileNameNoDep
  964. | k_BOOL|k_COLOR|k_FLOAT|k_INDEX|k_RANGE
  965. | k_CEntityPointer|k_CModelObject|k_CModelInstance|k_CAnimObject|k_CSoundObject
  966. | k_CPlacement3D | k_FLOATaabbox3D|k_FLOATmatrix3D| k_FLOATquat3D|k_ANGLE|k_ANIMATION|k_ILLUMINATIONTYPE
  967. | k_ANGLE3D|k_FLOAT3D|k_FLOATplane3D
  968. | k_const
  969. | k_static
  970. ;
  971. case_constant_expression
  972. : c_int|c_float|c_bool|c_char|c_string
  973. | identifier {$$ = $1 + " ";}
  974. ;
  975. /* Simple statements:
  976. */
  977. statements
  978. : { $$ = "";}
  979. | statements statement { $$ = $1+$2; }
  980. ;
  981. statement
  982. : expression ';' {$$=$1+$2;}
  983. | k_switch '(' expression ')' '{' statements '}' {$$=$1+$2+$3+$4+$5+$6+$7;}
  984. | k_case case_constant_expression ':' {$$=$1+" "+$2+$3+" ";}
  985. | '{' statements '}' {$$=$1+$2+$3;}
  986. | expression '{' statements '}' {$$=$1+$2+$3+$4;}
  987. | statement_while
  988. | statement_dowhile
  989. | statement_for
  990. | statement_if
  991. | statement_if_else
  992. | statement_wait
  993. | statement_autowait
  994. | statement_waitevent
  995. | statement_call
  996. | statement_autocall
  997. | statement_stop
  998. | statement_resume
  999. | statement_pass
  1000. | statement_return
  1001. | statement_jump
  1002. | ';'
  1003. ;
  1004. statement_if
  1005. : k_if '(' expression ')' '{' statements '}' {
  1006. if ($6.bCrossesStates) {
  1007. char strAfterIfName[80], strAfterIfID[11];
  1008. CreateInternalHandlerFunction(strAfterIfName, strAfterIfID);
  1009. $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+$6+
  1010. "Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+
  1011. "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+
  1012. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1013. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n";
  1014. } else {
  1015. $$ = $1+$2+$3+$4+$5+$6+$7;
  1016. }
  1017. }
  1018. ;
  1019. statement_if_else
  1020. : k_if '(' expression ')' '{' statements '}' k_else statement {
  1021. if ($6.bCrossesStates || $9.bCrossesStates) {
  1022. char strAfterIfName[80], strAfterIfID[11];
  1023. char strElseName[80], strElseID[11];
  1024. CreateInternalHandlerFunction(strAfterIfName, strAfterIfID);
  1025. CreateInternalHandlerFunction(strElseName, strElseID);
  1026. $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strElseID+", FALSE, EInternal());return TRUE;}"+
  1027. $6+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+
  1028. "BOOL "+_strCurrentClass+"::"+strElseName+"(const CEntityEvent &__eeInput){"+
  1029. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1030. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strElseID+"\n"+
  1031. $9+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}\n"+
  1032. "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+
  1033. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1034. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n";
  1035. } else {
  1036. $$ = $1+$2+$3+$4+$5+$6+$7+$8+" "+$9;
  1037. }
  1038. }
  1039. ;
  1040. statement_while
  1041. : k_while '(' expression ')' {
  1042. if (strlen(_strInLoopName)>0) {
  1043. yyerror("Nested loops are not implemented yet");
  1044. }
  1045. } '{' statements '}' {
  1046. if ($7.bCrossesStates) {
  1047. CreateInternalHandlerFunction(_strInLoopName, _strInLoopID);
  1048. CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID);
  1049. $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+
  1050. "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$6+
  1051. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1052. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+
  1053. "if(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+
  1054. $7+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$8+
  1055. "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+
  1056. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1057. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n";
  1058. } else {
  1059. $$ = $1+$2+$3+$4+$6+$7+$8;
  1060. }
  1061. _strInLoopName[0] = 0;
  1062. }
  1063. ;
  1064. statement_dowhile
  1065. : k_do '{' statements '}' {
  1066. if (strlen(_strInLoopName)>0) {
  1067. yyerror("Nested loops are not implemented yet");
  1068. }
  1069. _strInLoopName[0] = 0;
  1070. } k_while '(' expression ')' ';' {
  1071. if ($3.bCrossesStates) {
  1072. CreateInternalHandlerFunction(_strInLoopName, _strInLoopID);
  1073. CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID);
  1074. $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+
  1075. "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$2+
  1076. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1077. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+$3+
  1078. "if(!"+$7+$8+$9+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+
  1079. "Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$4+
  1080. "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+
  1081. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1082. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n";
  1083. } else {
  1084. $$ = $1+$2+$3+$4+$6+$7+$8+$9+$10;
  1085. }
  1086. _strInLoopName[0] = 0;
  1087. }
  1088. ;
  1089. statement_for
  1090. : k_for '(' expression ';' expression ';' expression ')' {
  1091. if (strlen(_strInLoopName)>0) {
  1092. yyerror("Nested loops are not implemented yet");
  1093. }
  1094. } '{' statements '}' {
  1095. if ($11.bCrossesStates) {
  1096. CreateInternalHandlerFunction(_strInLoopName, _strInLoopID);
  1097. CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID);
  1098. yyerror("For loops across states are not supported");
  1099. } else {
  1100. $$ = $1+$2+$3+$4+$5+$6+$7+$8+$10+$11+$12;
  1101. }
  1102. _strInLoopName[0] = 0;
  1103. }
  1104. ;
  1105. statement_wait
  1106. : k_wait wait_expression {
  1107. if (!_bInProcedure) {
  1108. yyerror("Cannot have 'wait' in functions");
  1109. }
  1110. CreateInternalHandlerFunction(_strInWaitName, _strInWaitID);
  1111. CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID);
  1112. _bHasOtherwise = 0;
  1113. _bInHandler = 1;
  1114. } '{' handlers_list '}' {
  1115. if ($5.bCrossesStates) {
  1116. yyerror("'wait' statements must not be nested");
  1117. $$ = "";
  1118. } else {
  1119. SType stDefault;
  1120. if (!_bHasOtherwise) {
  1121. stDefault = SType("default: return FALSE; break;");
  1122. } else {
  1123. stDefault = SType("");
  1124. }
  1125. $$ = SType(GetLineDirective($1))+$2+";\n"+
  1126. "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+
  1127. "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+
  1128. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+
  1129. "switch(__eeInput.ee_slEvent)"+$4+$5+stDefault+$6+
  1130. "return TRUE;}BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+
  1131. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1132. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n";
  1133. $$.bCrossesStates = 1;
  1134. _bInHandler = 0;
  1135. }
  1136. }
  1137. ;
  1138. statement_autowait
  1139. : k_autowait wait_expression ';' {
  1140. if (!_bInProcedure) {
  1141. yyerror("Cannot have 'autowait' in functions");
  1142. }
  1143. CreateInternalHandlerFunction(_strInWaitName, _strInWaitID);
  1144. CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID);
  1145. _bHasOtherwise = 0;
  1146. $$ = SType(GetLineDirective($1))+$2+";\n"+
  1147. "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+
  1148. "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+
  1149. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+
  1150. "switch(__eeInput.ee_slEvent) {"+
  1151. "case EVENTCODE_EBegin: return TRUE;"+
  1152. "case EVENTCODE_ETimer: Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, EInternal()); return TRUE;"+
  1153. "default: return FALSE; }}"+
  1154. "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+
  1155. "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+
  1156. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+$3;
  1157. $$.bCrossesStates = 1;
  1158. }
  1159. ;
  1160. statement_waitevent
  1161. : k_waitevent wait_expression identifier opt_eventvar ';' {
  1162. if (!_bInProcedure) {
  1163. yyerror("Cannot have 'autocall' in functions");
  1164. }
  1165. CreateInternalHandlerFunction(_strInWaitName, _strInWaitID);
  1166. CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID);
  1167. _bHasOtherwise = 0;
  1168. $$ = SType(GetLineDirective($1))+$2+";\n"+
  1169. "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+
  1170. "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+
  1171. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+
  1172. "switch(__eeInput.ee_slEvent) {"+
  1173. "case EVENTCODE_EBegin: return TRUE;"+
  1174. "case EVENTCODE_"+$3+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+
  1175. "default: return FALSE; }}"+
  1176. "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+
  1177. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+
  1178. "const "+$3+"&"+$4+"= ("+$3+"&)__eeInput;\n"+$5;
  1179. $$.bCrossesStates = 1;
  1180. }
  1181. ;
  1182. opt_eventvar
  1183. : {
  1184. $$ = SType("__e");
  1185. }
  1186. | identifier {
  1187. $$ = $1;
  1188. }
  1189. statement_autocall
  1190. : k_autocall jumptarget '(' event_expression ')' identifier opt_eventvar ';' {
  1191. if (!_bInProcedure) {
  1192. yyerror("Cannot have 'autocall' in functions");
  1193. }
  1194. CreateInternalHandlerFunction(_strInWaitName, _strInWaitID);
  1195. CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID);
  1196. _bHasOtherwise = 0;
  1197. $$ = SType(GetLineDirective($1))+$2+";\n"+
  1198. "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+
  1199. "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+
  1200. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+
  1201. "switch(__eeInput.ee_slEvent) {"+
  1202. "case EVENTCODE_EBegin: Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"+
  1203. "case EVENTCODE_"+$6+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+
  1204. "default: return FALSE; }}"+
  1205. "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+
  1206. "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+
  1207. "const "+$6+"&"+$7+"= ("+$6+"&)__eeInput;\n"+$8;
  1208. $$.bCrossesStates = 1;
  1209. }
  1210. ;
  1211. wait_expression
  1212. : '(' ')' {
  1213. $$ = SType("SetTimerAt(THINKTIME_NEVER)");
  1214. }
  1215. | '(' expression ')' {
  1216. $$ = SType("SetTimerAfter")+$1+$2+$3;
  1217. }
  1218. ;
  1219. statement_jump
  1220. : k_jump jumptarget '(' event_expression ')' ';' {
  1221. if (!_bInProcedure) {
  1222. yyerror("Cannot have 'jump' in functions");
  1223. }
  1224. $$ = SType(GetLineDirective($1))+"Jump"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;";
  1225. }
  1226. ;
  1227. statement_call
  1228. : k_call jumptarget '(' event_expression')' ';' {
  1229. if (!_bInProcedure) {
  1230. yyerror("Cannot have 'call' in functions");
  1231. }
  1232. if (!_bInHandler) {
  1233. yyerror("'call' must be inside a 'wait' statement");
  1234. }
  1235. $$ = SType(GetLineDirective($1))+"Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;";
  1236. }
  1237. ;
  1238. event_expression
  1239. : expression {
  1240. $$ = $1;
  1241. }
  1242. | {
  1243. $$ = SType("EVoid()");
  1244. }
  1245. ;
  1246. jumptarget
  1247. : identifier {
  1248. $$ = SType("STATE_")+_strCurrentClass+"_"+$1+", TRUE";
  1249. }
  1250. | identifier ':' ':' identifier {
  1251. $$ = SType("STATE_")+$1+"_"+$4+", FALSE";
  1252. }
  1253. ;
  1254. statement_stop
  1255. : k_stop ';' {
  1256. $$ = SType(GetLineDirective($1))+"UnsetTimer();Jump(STATE_CURRENT,"
  1257. +_strAfterWaitID+", FALSE, EInternal());"+"return TRUE"+$2;
  1258. }
  1259. ;
  1260. statement_resume
  1261. : k_resume ';' {
  1262. $$ = SType(GetLineDirective($1))+"return TRUE"+$2;
  1263. }
  1264. ;
  1265. statement_pass
  1266. : k_pass ';' {
  1267. $$ = SType(GetLineDirective($1))+"return FALSE"+$2;
  1268. }
  1269. ;
  1270. statement_return
  1271. : k_return opt_expression ';' {
  1272. if (!_bInProcedure) {
  1273. $$ = $1+" "+$2+$3;
  1274. } else {
  1275. if (strlen($2.strString)==0) {
  1276. $2 = SType("EVoid()");
  1277. }
  1278. $$ = SType(GetLineDirective($1))
  1279. +"Return(STATE_CURRENT,"+$2+");"
  1280. +$1+" TRUE"+$3;
  1281. }
  1282. }
  1283. ;
  1284. opt_expression
  1285. : {$$ = "";}
  1286. | expression
  1287. ;
  1288. handler
  1289. : k_on '(' event_specification ')' ':' '{' statements '}' opt_semicolon {
  1290. char strInputEventType[80];
  1291. char strInputEventName[80];
  1292. sscanf($3.strString, "%s %s", strInputEventType, strInputEventName);
  1293. $$ = SType("case")+$2+"EVENTCODE_"+strInputEventType+$4+$5+$6+
  1294. "const "+strInputEventType+"&"+strInputEventName+"= ("+
  1295. strInputEventType+"&)__eeInput;\n"+$7+$8+"ASSERT(FALSE);break;";
  1296. }
  1297. | k_otherwise '(' event_specification ')' ':' '{' statements '}' opt_semicolon {
  1298. char strInputEventType[80];
  1299. char strInputEventName[80];
  1300. sscanf($3.strString, "%s %s", strInputEventType, strInputEventName);
  1301. $$ = SType("default")+$5+$6+$7+$8+"ASSERT(FALSE);break;";
  1302. _bHasOtherwise = 1;
  1303. }
  1304. ;
  1305. handlers_list
  1306. : { $$ = "";}
  1307. | handlers_list handler { $$ = $1+$2; }
  1308. ;
  1309. %%