Script_Compiler.cpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition 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 BFG Edition 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. #pragma hdrstop
  21. #include "../../idlib/precompiled.h"
  22. #include "../Game_local.h"
  23. #define FUNCTION_PRIORITY 2
  24. #define INT_PRIORITY 2
  25. #define NOT_PRIORITY 5
  26. #define TILDE_PRIORITY 5
  27. #define TOP_PRIORITY 7
  28. bool idCompiler::punctuationValid[ 256 ];
  29. char *idCompiler::punctuation[] = {
  30. "+=", "-=", "*=", "/=", "%=", "&=", "|=", "++", "--",
  31. "&&", "||", "<=", ">=", "==", "!=", "::", ";", ",",
  32. "~", "!", "*", "/", "%", "(", ")", "-", "+",
  33. "=", "[", "]", ".", "<", ">" , "&", "|", ":", NULL
  34. };
  35. opcode_t idCompiler::opcodes[] = {
  36. { "<RETURN>", "RETURN", -1, false, &def_void, &def_void, &def_void },
  37. { "++", "UINC_F", 1, true, &def_float, &def_void, &def_void },
  38. { "++", "UINCP_F", 1, true, &def_object, &def_field, &def_float },
  39. { "--", "UDEC_F", 1, true, &def_float, &def_void, &def_void },
  40. { "--", "UDECP_F", 1, true, &def_object, &def_field, &def_float },
  41. { "~", "COMP_F", -1, false, &def_float, &def_void, &def_float },
  42. { "*", "MUL_F", 3, false, &def_float, &def_float, &def_float },
  43. { "*", "MUL_V", 3, false, &def_vector, &def_vector, &def_float },
  44. { "*", "MUL_FV", 3, false, &def_float, &def_vector, &def_vector },
  45. { "*", "MUL_VF", 3, false, &def_vector, &def_float, &def_vector },
  46. { "/", "DIV", 3, false, &def_float, &def_float, &def_float },
  47. { "%", "MOD_F", 3, false, &def_float, &def_float, &def_float },
  48. { "+", "ADD_F", 4, false, &def_float, &def_float, &def_float },
  49. { "+", "ADD_V", 4, false, &def_vector, &def_vector, &def_vector },
  50. { "+", "ADD_S", 4, false, &def_string, &def_string, &def_string },
  51. { "+", "ADD_FS", 4, false, &def_float, &def_string, &def_string },
  52. { "+", "ADD_SF", 4, false, &def_string, &def_float, &def_string },
  53. { "+", "ADD_VS", 4, false, &def_vector, &def_string, &def_string },
  54. { "+", "ADD_SV", 4, false, &def_string, &def_vector, &def_string },
  55. { "-", "SUB_F", 4, false, &def_float, &def_float, &def_float },
  56. { "-", "SUB_V", 4, false, &def_vector, &def_vector, &def_vector },
  57. { "==", "EQ_F", 5, false, &def_float, &def_float, &def_float },
  58. { "==", "EQ_V", 5, false, &def_vector, &def_vector, &def_float },
  59. { "==", "EQ_S", 5, false, &def_string, &def_string, &def_float },
  60. { "==", "EQ_E", 5, false, &def_entity, &def_entity, &def_float },
  61. { "==", "EQ_EO", 5, false, &def_entity, &def_object, &def_float },
  62. { "==", "EQ_OE", 5, false, &def_object, &def_entity, &def_float },
  63. { "==", "EQ_OO", 5, false, &def_object, &def_object, &def_float },
  64. { "!=", "NE_F", 5, false, &def_float, &def_float, &def_float },
  65. { "!=", "NE_V", 5, false, &def_vector, &def_vector, &def_float },
  66. { "!=", "NE_S", 5, false, &def_string, &def_string, &def_float },
  67. { "!=", "NE_E", 5, false, &def_entity, &def_entity, &def_float },
  68. { "!=", "NE_EO", 5, false, &def_entity, &def_object, &def_float },
  69. { "!=", "NE_OE", 5, false, &def_object, &def_entity, &def_float },
  70. { "!=", "NE_OO", 5, false, &def_object, &def_object, &def_float },
  71. { "<=", "LE", 5, false, &def_float, &def_float, &def_float },
  72. { ">=", "GE", 5, false, &def_float, &def_float, &def_float },
  73. { "<", "LT", 5, false, &def_float, &def_float, &def_float },
  74. { ">", "GT", 5, false, &def_float, &def_float, &def_float },
  75. { ".", "INDIRECT_F", 1, false, &def_object, &def_field, &def_float },
  76. { ".", "INDIRECT_V", 1, false, &def_object, &def_field, &def_vector },
  77. { ".", "INDIRECT_S", 1, false, &def_object, &def_field, &def_string },
  78. { ".", "INDIRECT_E", 1, false, &def_object, &def_field, &def_entity },
  79. { ".", "INDIRECT_BOOL", 1, false, &def_object, &def_field, &def_boolean },
  80. { ".", "INDIRECT_OBJ", 1, false, &def_object, &def_field, &def_object },
  81. { ".", "ADDRESS", 1, false, &def_entity, &def_field, &def_pointer },
  82. { ".", "EVENTCALL", 2, false, &def_entity, &def_function, &def_void },
  83. { ".", "OBJECTCALL", 2, false, &def_object, &def_function, &def_void },
  84. { ".", "SYSCALL", 2, false, &def_void, &def_function, &def_void },
  85. { "=", "STORE_F", 6, true, &def_float, &def_float, &def_float },
  86. { "=", "STORE_V", 6, true, &def_vector, &def_vector, &def_vector },
  87. { "=", "STORE_S", 6, true, &def_string, &def_string, &def_string },
  88. { "=", "STORE_ENT", 6, true, &def_entity, &def_entity, &def_entity },
  89. { "=", "STORE_BOOL", 6, true, &def_boolean, &def_boolean, &def_boolean },
  90. { "=", "STORE_OBJENT", 6, true, &def_object, &def_entity, &def_object },
  91. { "=", "STORE_OBJ", 6, true, &def_object, &def_object, &def_object },
  92. { "=", "STORE_OBJENT", 6, true, &def_entity, &def_object, &def_object },
  93. { "=", "STORE_FTOS", 6, true, &def_string, &def_float, &def_string },
  94. { "=", "STORE_BTOS", 6, true, &def_string, &def_boolean, &def_string },
  95. { "=", "STORE_VTOS", 6, true, &def_string, &def_vector, &def_string },
  96. { "=", "STORE_FTOBOOL", 6, true, &def_boolean, &def_float, &def_boolean },
  97. { "=", "STORE_BOOLTOF", 6, true, &def_float, &def_boolean, &def_float },
  98. { "=", "STOREP_F", 6, true, &def_pointer, &def_float, &def_float },
  99. { "=", "STOREP_V", 6, true, &def_pointer, &def_vector, &def_vector },
  100. { "=", "STOREP_S", 6, true, &def_pointer, &def_string, &def_string },
  101. { "=", "STOREP_ENT", 6, true, &def_pointer, &def_entity, &def_entity },
  102. { "=", "STOREP_FLD", 6, true, &def_pointer, &def_field, &def_field },
  103. { "=", "STOREP_BOOL", 6, true, &def_pointer, &def_boolean, &def_boolean },
  104. { "=", "STOREP_OBJ", 6, true, &def_pointer, &def_object, &def_object },
  105. { "=", "STOREP_OBJENT", 6, true, &def_pointer, &def_object, &def_object },
  106. { "<=>", "STOREP_FTOS", 6, true, &def_pointer, &def_float, &def_string },
  107. { "<=>", "STOREP_BTOS", 6, true, &def_pointer, &def_boolean, &def_string },
  108. { "<=>", "STOREP_VTOS", 6, true, &def_pointer, &def_vector, &def_string },
  109. { "<=>", "STOREP_FTOBOOL", 6, true, &def_pointer, &def_float, &def_boolean },
  110. { "<=>", "STOREP_BOOLTOF", 6, true, &def_pointer, &def_boolean, &def_float },
  111. { "*=", "UMUL_F", 6, true, &def_float, &def_float, &def_void },
  112. { "*=", "UMUL_V", 6, true, &def_vector, &def_float, &def_void },
  113. { "/=", "UDIV_F", 6, true, &def_float, &def_float, &def_void },
  114. { "/=", "UDIV_V", 6, true, &def_vector, &def_float, &def_void },
  115. { "%=", "UMOD_F", 6, true, &def_float, &def_float, &def_void },
  116. { "+=", "UADD_F", 6, true, &def_float, &def_float, &def_void },
  117. { "+=", "UADD_V", 6, true, &def_vector, &def_vector, &def_void },
  118. { "-=", "USUB_F", 6, true, &def_float, &def_float, &def_void },
  119. { "-=", "USUB_V", 6, true, &def_vector, &def_vector, &def_void },
  120. { "&=", "UAND_F", 6, true, &def_float, &def_float, &def_void },
  121. { "|=", "UOR_F", 6, true, &def_float, &def_float, &def_void },
  122. { "!", "NOT_BOOL", -1, false, &def_boolean, &def_void, &def_float },
  123. { "!", "NOT_F", -1, false, &def_float, &def_void, &def_float },
  124. { "!", "NOT_V", -1, false, &def_vector, &def_void, &def_float },
  125. { "!", "NOT_S", -1, false, &def_vector, &def_void, &def_float },
  126. { "!", "NOT_ENT", -1, false, &def_entity, &def_void, &def_float },
  127. { "<NEG_F>", "NEG_F", -1, false, &def_float, &def_void, &def_float },
  128. { "<NEG_V>", "NEG_V", -1, false, &def_vector, &def_void, &def_vector },
  129. { "int", "INT_F", -1, false, &def_float, &def_void, &def_float },
  130. { "<IF>", "IF", -1, false, &def_float, &def_jumpoffset, &def_void },
  131. { "<IFNOT>", "IFNOT", -1, false, &def_float, &def_jumpoffset, &def_void },
  132. // calls returns REG_RETURN
  133. { "<CALL>", "CALL", -1, false, &def_function, &def_argsize, &def_void },
  134. { "<THREAD>", "THREAD", -1, false, &def_function, &def_argsize, &def_void },
  135. { "<THREAD>", "OBJTHREAD", -1, false, &def_function, &def_argsize, &def_void },
  136. { "<PUSH>", "PUSH_F", -1, false, &def_float, &def_float, &def_void },
  137. { "<PUSH>", "PUSH_V", -1, false, &def_vector, &def_vector, &def_void },
  138. { "<PUSH>", "PUSH_S", -1, false, &def_string, &def_string, &def_void },
  139. { "<PUSH>", "PUSH_ENT", -1, false, &def_entity, &def_entity, &def_void },
  140. { "<PUSH>", "PUSH_OBJ", -1, false, &def_object, &def_object, &def_void },
  141. { "<PUSH>", "PUSH_OBJENT", -1, false, &def_entity, &def_object, &def_void },
  142. { "<PUSH>", "PUSH_FTOS", -1, false, &def_string, &def_float, &def_void },
  143. { "<PUSH>", "PUSH_BTOF", -1, false, &def_float, &def_boolean, &def_void },
  144. { "<PUSH>", "PUSH_FTOB", -1, false, &def_boolean, &def_float, &def_void },
  145. { "<PUSH>", "PUSH_VTOS", -1, false, &def_string, &def_vector, &def_void },
  146. { "<PUSH>", "PUSH_BTOS", -1, false, &def_string, &def_boolean, &def_void },
  147. { "<GOTO>", "GOTO", -1, false, &def_jumpoffset, &def_void, &def_void },
  148. { "&&", "AND", 7, false, &def_float, &def_float, &def_float },
  149. { "&&", "AND_BOOLF", 7, false, &def_boolean, &def_float, &def_float },
  150. { "&&", "AND_FBOOL", 7, false, &def_float, &def_boolean, &def_float },
  151. { "&&", "AND_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float },
  152. { "||", "OR", 7, false, &def_float, &def_float, &def_float },
  153. { "||", "OR_BOOLF", 7, false, &def_boolean, &def_float, &def_float },
  154. { "||", "OR_FBOOL", 7, false, &def_float, &def_boolean, &def_float },
  155. { "||", "OR_BOOLBOOL", 7, false, &def_boolean, &def_boolean, &def_float },
  156. { "&", "BITAND", 3, false, &def_float, &def_float, &def_float },
  157. { "|", "BITOR", 3, false, &def_float, &def_float, &def_float },
  158. { "<BREAK>", "BREAK", -1, false, &def_float, &def_void, &def_void },
  159. { "<CONTINUE>", "CONTINUE", -1, false, &def_float, &def_void, &def_void },
  160. { NULL }
  161. };
  162. /*
  163. ================
  164. idCompiler::idCompiler()
  165. ================
  166. */
  167. idCompiler::idCompiler() {
  168. char **ptr;
  169. int id;
  170. // make sure we have the right # of opcodes in the table
  171. assert( ( sizeof( opcodes ) / sizeof( opcodes[ 0 ] ) ) == ( NUM_OPCODES + 1 ) );
  172. parserPtr = &parser;
  173. callthread = false;
  174. loopDepth = 0;
  175. eof = false;
  176. braceDepth = 0;
  177. immediateType = NULL;
  178. basetype = NULL;
  179. currentLineNumber = 0;
  180. currentFileNumber = 0;
  181. errorCount = 0;
  182. console = false;
  183. scope = &def_namespace;
  184. memset( &immediate, 0, sizeof( immediate ) );
  185. memset( punctuationValid, 0, sizeof( punctuationValid ) );
  186. for( ptr = punctuation; *ptr != NULL; ptr++ ) {
  187. id = parserPtr->GetPunctuationId( *ptr );
  188. if ( ( id >= 0 ) && ( id < 256 ) ) {
  189. punctuationValid[ id ] = true;
  190. }
  191. }
  192. }
  193. /*
  194. ============
  195. idCompiler::Error
  196. Aborts the current file load
  197. ============
  198. */
  199. void idCompiler::Error( const char *message, ... ) const {
  200. va_list argptr;
  201. char string[ 1024 ];
  202. va_start( argptr, message );
  203. vsprintf( string, message, argptr );
  204. va_end( argptr );
  205. throw idCompileError( string );
  206. }
  207. /*
  208. ============
  209. idCompiler::Warning
  210. Prints a warning about the current line
  211. ============
  212. */
  213. void idCompiler::Warning( const char *message, ... ) const {
  214. va_list argptr;
  215. char string[ 1024 ];
  216. va_start( argptr, message );
  217. vsprintf( string, message, argptr );
  218. va_end( argptr );
  219. parserPtr->Warning( "%s", string );
  220. }
  221. /*
  222. ============
  223. idCompiler::VirtualFunctionConstant
  224. Creates a def for an index into a virtual function table
  225. ============
  226. */
  227. ID_INLINE idVarDef *idCompiler::VirtualFunctionConstant( idVarDef *func ) {
  228. eval_t eval;
  229. memset( &eval, 0, sizeof( eval ) );
  230. eval._int = func->scope->TypeDef()->GetFunctionNumber( func->value.functionPtr );
  231. if ( eval._int < 0 ) {
  232. Error( "Function '%s' not found in scope '%s'", func->Name(), func->scope->Name() );
  233. }
  234. return GetImmediate( &type_virtualfunction, &eval, "" );
  235. }
  236. /*
  237. ============
  238. idCompiler::SizeConstant
  239. Creates a def for a size constant
  240. ============
  241. */
  242. ID_INLINE idVarDef *idCompiler::SizeConstant( int size ) {
  243. eval_t eval;
  244. memset( &eval, 0, sizeof( eval ) );
  245. eval._int = size;
  246. return GetImmediate( &type_argsize, &eval, "" );
  247. }
  248. /*
  249. ============
  250. idCompiler::JumpConstant
  251. Creates a def for a jump constant
  252. ============
  253. */
  254. ID_INLINE idVarDef *idCompiler::JumpConstant( int value ) {
  255. eval_t eval;
  256. memset( &eval, 0, sizeof( eval ) );
  257. eval._int = value;
  258. return GetImmediate( &type_jumpoffset, &eval, "" );
  259. }
  260. /*
  261. ============
  262. idCompiler::JumpDef
  263. Creates a def for a relative jump from one code location to another
  264. ============
  265. */
  266. ID_INLINE idVarDef *idCompiler::JumpDef( int jumpfrom, int jumpto ) {
  267. return JumpConstant( jumpto - jumpfrom );
  268. }
  269. /*
  270. ============
  271. idCompiler::JumpTo
  272. Creates a def for a relative jump from current code location
  273. ============
  274. */
  275. ID_INLINE idVarDef *idCompiler::JumpTo( int jumpto ) {
  276. return JumpDef( gameLocal.program.NumStatements(), jumpto );
  277. }
  278. /*
  279. ============
  280. idCompiler::JumpFrom
  281. Creates a def for a relative jump from code location to current code location
  282. ============
  283. */
  284. ID_INLINE idVarDef *idCompiler::JumpFrom( int jumpfrom ) {
  285. return JumpDef( jumpfrom, gameLocal.program.NumStatements() );
  286. }
  287. /*
  288. ============
  289. idCompiler::Divide
  290. ============
  291. */
  292. ID_INLINE float idCompiler::Divide( float numerator, float denominator ) {
  293. if ( denominator == 0 ) {
  294. Error( "Divide by zero" );
  295. }
  296. return numerator / denominator;
  297. }
  298. /*
  299. ============
  300. idCompiler::FindImmediate
  301. tries to find an existing immediate with the same value
  302. ============
  303. */
  304. idVarDef *idCompiler::FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const {
  305. idVarDef *def;
  306. etype_t etype;
  307. etype = type->Type();
  308. // check for a constant with the same value
  309. for( def = gameLocal.program.GetDefList( "<IMMEDIATE>" ); def != NULL; def = def->Next() ) {
  310. if ( def->TypeDef() != type ) {
  311. continue;
  312. }
  313. switch( etype ) {
  314. case ev_field :
  315. if ( *def->value.intPtr == eval->_int ) {
  316. return def;
  317. }
  318. break;
  319. case ev_argsize :
  320. if ( def->value.argSize == eval->_int ) {
  321. return def;
  322. }
  323. break;
  324. case ev_jumpoffset :
  325. if ( def->value.jumpOffset == eval->_int ) {
  326. return def;
  327. }
  328. break;
  329. case ev_entity :
  330. if ( *def->value.intPtr == eval->entity ) {
  331. return def;
  332. }
  333. break;
  334. case ev_string :
  335. if ( idStr::Cmp( def->value.stringPtr, string ) == 0 ) {
  336. return def;
  337. }
  338. break;
  339. case ev_float :
  340. if ( *def->value.floatPtr == eval->_float ) {
  341. return def;
  342. }
  343. break;
  344. case ev_virtualfunction :
  345. if ( def->value.virtualFunction == eval->_int ) {
  346. return def;
  347. }
  348. break;
  349. case ev_vector :
  350. if ( ( def->value.vectorPtr->x == eval->vector[ 0 ] ) &&
  351. ( def->value.vectorPtr->y == eval->vector[ 1 ] ) &&
  352. ( def->value.vectorPtr->z == eval->vector[ 2 ] ) ) {
  353. return def;
  354. }
  355. break;
  356. default :
  357. Error( "weird immediate type" );
  358. break;
  359. }
  360. }
  361. return NULL;
  362. }
  363. /*
  364. ============
  365. idCompiler::GetImmediate
  366. returns an existing immediate with the same value, or allocates a new one
  367. ============
  368. */
  369. idVarDef *idCompiler::GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ) {
  370. idVarDef *def;
  371. def = FindImmediate( type, eval, string );
  372. if ( def ) {
  373. def->numUsers++;
  374. } else {
  375. // allocate a new def
  376. def = gameLocal.program.AllocDef( type, "<IMMEDIATE>", &def_namespace, true );
  377. if ( type->Type() == ev_string ) {
  378. def->SetString( string, true );
  379. } else {
  380. def->SetValue( *eval, true );
  381. }
  382. }
  383. return def;
  384. }
  385. /*
  386. ============
  387. idCompiler::OptimizeOpcode
  388. try to optimize when the operator works on constants only
  389. ============
  390. */
  391. idVarDef *idCompiler::OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) {
  392. eval_t c;
  393. idTypeDef *type;
  394. if ( var_a == NULL || var_a->initialized != idVarDef::initializedConstant ) {
  395. return NULL;
  396. }
  397. if ( var_b == NULL || var_b->initialized != idVarDef::initializedConstant ) {
  398. return NULL;
  399. }
  400. idVec3 &vec_c = *reinterpret_cast<idVec3 *>( &c.vector[ 0 ] );
  401. memset( &c, 0, sizeof( c ) );
  402. switch( op - opcodes ) {
  403. case OP_ADD_F: c._float = *var_a->value.floatPtr + *var_b->value.floatPtr; type = &type_float; break;
  404. case OP_ADD_V: vec_c = *var_a->value.vectorPtr + *var_b->value.vectorPtr; type = &type_vector; break;
  405. case OP_SUB_F: c._float = *var_a->value.floatPtr - *var_b->value.floatPtr; type = &type_float; break;
  406. case OP_SUB_V: vec_c = *var_a->value.vectorPtr - *var_b->value.vectorPtr; type = &type_vector; break;
  407. case OP_MUL_F: c._float = *var_a->value.floatPtr * *var_b->value.floatPtr; type = &type_float; break;
  408. case OP_MUL_V: c._float = *var_a->value.vectorPtr * *var_b->value.vectorPtr; type = &type_float; break;
  409. case OP_MUL_FV: vec_c = *var_b->value.vectorPtr * *var_a->value.floatPtr; type = &type_vector; break;
  410. case OP_MUL_VF: vec_c = *var_a->value.vectorPtr * *var_b->value.floatPtr; type = &type_vector; break;
  411. case OP_DIV_F: c._float = Divide( *var_a->value.floatPtr, *var_b->value.floatPtr ); type = &type_float; break;
  412. case OP_MOD_F: c._float = (int)*var_a->value.floatPtr % (int)*var_b->value.floatPtr; type = &type_float; break;
  413. case OP_BITAND: c._float = ( int )*var_a->value.floatPtr & ( int )*var_b->value.floatPtr; type = &type_float; break;
  414. case OP_BITOR: c._float = ( int )*var_a->value.floatPtr | ( int )*var_b->value.floatPtr; type = &type_float; break;
  415. case OP_GE: c._float = *var_a->value.floatPtr >= *var_b->value.floatPtr; type = &type_float; break;
  416. case OP_LE: c._float = *var_a->value.floatPtr <= *var_b->value.floatPtr; type = &type_float; break;
  417. case OP_GT: c._float = *var_a->value.floatPtr > *var_b->value.floatPtr; type = &type_float; break;
  418. case OP_LT: c._float = *var_a->value.floatPtr < *var_b->value.floatPtr; type = &type_float; break;
  419. case OP_AND: c._float = *var_a->value.floatPtr && *var_b->value.floatPtr; type = &type_float; break;
  420. case OP_OR: c._float = *var_a->value.floatPtr || *var_b->value.floatPtr; type = &type_float; break;
  421. case OP_NOT_BOOL: c._int = !*var_a->value.intPtr; type = &type_boolean; break;
  422. case OP_NOT_F: c._float = !*var_a->value.floatPtr; type = &type_float; break;
  423. case OP_NOT_V: c._float = !var_a->value.vectorPtr->x && !var_a->value.vectorPtr->y && !var_a->value.vectorPtr->z; type = &type_float; break;
  424. case OP_NEG_F: c._float = -*var_a->value.floatPtr; type = &type_float; break;
  425. case OP_NEG_V: vec_c = -*var_a->value.vectorPtr; type = &type_vector; break;
  426. case OP_INT_F: c._float = ( int )*var_a->value.floatPtr; type = &type_float; break;
  427. case OP_EQ_F: c._float = ( *var_a->value.floatPtr == *var_b->value.floatPtr ); type = &type_float; break;
  428. case OP_EQ_V: c._float = var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break;
  429. case OP_EQ_E: c._float = ( *var_a->value.intPtr == *var_b->value.intPtr ); type = &type_float; break;
  430. case OP_NE_F: c._float = ( *var_a->value.floatPtr != *var_b->value.floatPtr ); type = &type_float; break;
  431. case OP_NE_V: c._float = !var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break;
  432. case OP_NE_E: c._float = ( *var_a->value.intPtr != *var_b->value.intPtr ); type = &type_float; break;
  433. case OP_UADD_F: c._float = *var_b->value.floatPtr + *var_a->value.floatPtr; type = &type_float; break;
  434. case OP_USUB_F: c._float = *var_b->value.floatPtr - *var_a->value.floatPtr; type = &type_float; break;
  435. case OP_UMUL_F: c._float = *var_b->value.floatPtr * *var_a->value.floatPtr; type = &type_float; break;
  436. case OP_UDIV_F: c._float = Divide( *var_b->value.floatPtr, *var_a->value.floatPtr ); type = &type_float; break;
  437. case OP_UMOD_F: c._float = ( int ) *var_b->value.floatPtr % ( int )*var_a->value.floatPtr; type = &type_float; break;
  438. case OP_UOR_F: c._float = ( int )*var_b->value.floatPtr | ( int )*var_a->value.floatPtr; type = &type_float; break;
  439. case OP_UAND_F: c._float = ( int )*var_b->value.floatPtr & ( int )*var_a->value.floatPtr; type = &type_float; break;
  440. case OP_UINC_F: c._float = *var_a->value.floatPtr + 1; type = &type_float; break;
  441. case OP_UDEC_F: c._float = *var_a->value.floatPtr - 1; type = &type_float; break;
  442. case OP_COMP_F: c._float = ( float )~( int )*var_a->value.floatPtr; type = &type_float; break;
  443. default: type = NULL; break;
  444. }
  445. if ( !type ) {
  446. return NULL;
  447. }
  448. if ( var_a ) {
  449. var_a->numUsers--;
  450. if ( var_a->numUsers <= 0 ) {
  451. gameLocal.program.FreeDef( var_a, NULL );
  452. }
  453. }
  454. if ( var_b ) {
  455. var_b->numUsers--;
  456. if ( var_b->numUsers <= 0 ) {
  457. gameLocal.program.FreeDef( var_b, NULL );
  458. }
  459. }
  460. return GetImmediate( type, &c, "" );
  461. }
  462. /*
  463. ============
  464. idCompiler::EmitOpcode
  465. Emits a primitive statement, returning the var it places it's value in
  466. ============
  467. */
  468. idVarDef *idCompiler::EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) {
  469. statement_t *statement;
  470. idVarDef *var_c;
  471. var_c = OptimizeOpcode( op, var_a, var_b );
  472. if ( var_c ) {
  473. return var_c;
  474. }
  475. if ( var_a && !strcmp( var_a->Name(), RESULT_STRING ) ) {
  476. var_a->numUsers++;
  477. }
  478. if ( var_b && !strcmp( var_b->Name(), RESULT_STRING ) ) {
  479. var_b->numUsers++;
  480. }
  481. statement = gameLocal.program.AllocStatement();
  482. statement->linenumber = currentLineNumber;
  483. statement->file = currentFileNumber;
  484. if ( ( op->type_c == &def_void ) || op->rightAssociative ) {
  485. // ifs, gotos, and assignments don't need vars allocated
  486. var_c = NULL;
  487. } else {
  488. // allocate result space
  489. // try to reuse result defs as much as possible
  490. var_c = gameLocal.program.FindFreeResultDef( op->type_c->TypeDef(), RESULT_STRING, scope, var_a, var_b );
  491. // set user count back to 1, a result def needs to be used twice before it can be reused
  492. var_c->numUsers = 1;
  493. }
  494. statement->op = op - opcodes;
  495. statement->a = var_a;
  496. statement->b = var_b;
  497. statement->c = var_c;
  498. if ( op->rightAssociative ) {
  499. return var_a;
  500. }
  501. return var_c;
  502. }
  503. /*
  504. ============
  505. idCompiler::EmitOpcode
  506. Emits a primitive statement, returning the var it places it's value in
  507. ============
  508. */
  509. ID_INLINE idVarDef *idCompiler::EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ) {
  510. return EmitOpcode( &opcodes[ op ], var_a, var_b );
  511. }
  512. /*
  513. ============
  514. idCompiler::EmitPush
  515. Emits an opcode to push the variable onto the stack.
  516. ============
  517. */
  518. bool idCompiler::EmitPush( idVarDef *expression, const idTypeDef *funcArg ) {
  519. opcode_t *op;
  520. opcode_t *out;
  521. out = NULL;
  522. for( op = &opcodes[ OP_PUSH_F ]; op->name && !strcmp( op->name, "<PUSH>" ); op++ ) {
  523. if ( ( funcArg->Type() == op->type_a->Type() ) && ( expression->Type() == op->type_b->Type() ) ) {
  524. out = op;
  525. break;
  526. }
  527. }
  528. if ( !out ) {
  529. if ( ( expression->TypeDef() != funcArg ) && !expression->TypeDef()->Inherits( funcArg ) ) {
  530. return false;
  531. }
  532. out = &opcodes[ OP_PUSH_ENT ];
  533. }
  534. EmitOpcode( out, expression, 0 );
  535. return true;
  536. }
  537. /*
  538. ==============
  539. idCompiler::NextToken
  540. Sets token, immediateType, and possibly immediate
  541. ==============
  542. */
  543. void idCompiler::NextToken() {
  544. int i;
  545. // reset our type
  546. immediateType = NULL;
  547. memset( &immediate, 0, sizeof( immediate ) );
  548. // Save the token's line number and filename since when we emit opcodes the current
  549. // token is always the next one to be read
  550. currentLineNumber = token.line;
  551. currentFileNumber = gameLocal.program.GetFilenum( parserPtr->GetFileName() );
  552. if ( !parserPtr->ReadToken( &token ) ) {
  553. eof = true;
  554. return;
  555. }
  556. if ( currentFileNumber != gameLocal.program.GetFilenum( parserPtr->GetFileName() ) ) {
  557. if ( ( braceDepth > 0 ) && ( token != "}" ) ) {
  558. // missing a closing brace. try to give as much info as possible.
  559. if ( scope->Type() == ev_function ) {
  560. Error( "Unexpected end of file inside function '%s'. Missing closing braces.", scope->Name() );
  561. } else if ( scope->Type() == ev_object ) {
  562. Error( "Unexpected end of file inside object '%s'. Missing closing braces.", scope->Name() );
  563. } else if ( scope->Type() == ev_namespace ) {
  564. Error( "Unexpected end of file inside namespace '%s'. Missing closing braces.", scope->Name() );
  565. } else {
  566. Error( "Unexpected end of file inside braced section" );
  567. }
  568. }
  569. }
  570. switch( token.type ) {
  571. case TT_STRING:
  572. // handle quoted strings as a unit
  573. immediateType = &type_string;
  574. return;
  575. case TT_LITERAL: {
  576. // handle quoted vectors as a unit
  577. immediateType = &type_vector;
  578. idLexer lex( token, token.Length(), parserPtr->GetFileName(), LEXFL_NOERRORS );
  579. idToken token2;
  580. for( i = 0; i < 3; i++ ) {
  581. if ( !lex.ReadToken( &token2 ) ) {
  582. Error( "Couldn't read vector. '%s' is not in the form of 'x y z'", token.c_str() );
  583. }
  584. if ( token2.type == TT_PUNCTUATION && token2 == "-" ) {
  585. if ( !lex.CheckTokenType( TT_NUMBER, 0, &token2 ) ) {
  586. Error( "expected a number following '-' but found '%s' in vector '%s'", token2.c_str(), token.c_str() );
  587. }
  588. immediate.vector[ i ] = -token2.GetFloatValue();
  589. } else if ( token2.type == TT_NUMBER ) {
  590. immediate.vector[ i ] = token2.GetFloatValue();
  591. } else {
  592. Error( "vector '%s' is not in the form of 'x y z'. expected float value, found '%s'", token.c_str(), token2.c_str() );
  593. }
  594. }
  595. return;
  596. }
  597. case TT_NUMBER:
  598. immediateType = &type_float;
  599. immediate._float = token.GetFloatValue();
  600. return;
  601. case TT_PUNCTUATION:
  602. // entity names
  603. if ( token == "$" ) {
  604. immediateType = &type_entity;
  605. parserPtr->ReadToken( &token );
  606. return;
  607. }
  608. if ( token == "{" ) {
  609. braceDepth++;
  610. return;
  611. }
  612. if ( token == "}" ) {
  613. braceDepth--;
  614. return;
  615. }
  616. if ( punctuationValid[ token.subtype ] ) {
  617. return;
  618. }
  619. Error( "Unknown punctuation '%s'", token.c_str() );
  620. break;
  621. case TT_NAME:
  622. return;
  623. default:
  624. Error( "Unknown token '%s'", token.c_str() );
  625. }
  626. }
  627. /*
  628. =============
  629. idCompiler::ExpectToken
  630. Issues an Error if the current token isn't equal to string
  631. Gets the next token
  632. =============
  633. */
  634. void idCompiler::ExpectToken( const char *string ) {
  635. if ( token != string ) {
  636. Error( "expected '%s', found '%s'", string, token.c_str() );
  637. }
  638. NextToken();
  639. }
  640. /*
  641. =============
  642. idCompiler::CheckToken
  643. Returns true and gets the next token if the current token equals string
  644. Returns false and does nothing otherwise
  645. =============
  646. */
  647. bool idCompiler::CheckToken( const char *string ) {
  648. if ( token != string ) {
  649. return false;
  650. }
  651. NextToken();
  652. return true;
  653. }
  654. /*
  655. ============
  656. idCompiler::ParseName
  657. Checks to see if the current token is a valid name
  658. ============
  659. */
  660. void idCompiler::ParseName( idStr &name ) {
  661. if ( token.type != TT_NAME ) {
  662. Error( "'%s' is not a name", token.c_str() );
  663. }
  664. name = token;
  665. NextToken();
  666. }
  667. /*
  668. ============
  669. idCompiler::SkipOutOfFunction
  670. For error recovery, pops out of nested braces
  671. ============
  672. */
  673. void idCompiler::SkipOutOfFunction() {
  674. while( braceDepth ) {
  675. parserPtr->SkipBracedSection( false );
  676. braceDepth--;
  677. }
  678. NextToken();
  679. }
  680. /*
  681. ============
  682. idCompiler::SkipToSemicolon
  683. For error recovery
  684. ============
  685. */
  686. void idCompiler::SkipToSemicolon() {
  687. do {
  688. if ( CheckToken( ";" ) ) {
  689. return;
  690. }
  691. NextToken();
  692. } while( !eof );
  693. }
  694. /*
  695. ============
  696. idCompiler::CheckType
  697. Parses a variable type, including functions types
  698. ============
  699. */
  700. idTypeDef *idCompiler::CheckType() {
  701. idTypeDef *type;
  702. if ( token == "float" ) {
  703. type = &type_float;
  704. } else if ( token == "vector" ) {
  705. type = &type_vector;
  706. } else if ( token == "entity" ) {
  707. type = &type_entity;
  708. } else if ( token == "string" ) {
  709. type = &type_string;
  710. } else if ( token == "void" ) {
  711. type = &type_void;
  712. } else if ( token == "object" ) {
  713. type = &type_object;
  714. } else if ( token == "boolean" ) {
  715. type = &type_boolean;
  716. } else if ( token == "namespace" ) {
  717. type = &type_namespace;
  718. } else if ( token == "scriptEvent" ) {
  719. type = &type_scriptevent;
  720. } else {
  721. type = gameLocal.program.FindType( token.c_str() );
  722. if ( type != NULL && !type->Inherits( &type_object ) ) {
  723. type = NULL;
  724. }
  725. }
  726. return type;
  727. }
  728. /*
  729. ============
  730. idCompiler::ParseType
  731. Parses a variable type, including functions types
  732. ============
  733. */
  734. idTypeDef *idCompiler::ParseType() {
  735. idTypeDef *type;
  736. type = CheckType();
  737. if ( !type ) {
  738. Error( "\"%s\" is not a type", token.c_str() );
  739. }
  740. if ( ( type == &type_scriptevent ) && ( scope != &def_namespace ) ) {
  741. Error( "scriptEvents can only defined in the global namespace" );
  742. }
  743. if ( ( type == &type_namespace ) && ( scope->Type() != ev_namespace ) ) {
  744. Error( "A namespace may only be defined globally, or within another namespace" );
  745. }
  746. NextToken();
  747. return type;
  748. }
  749. /*
  750. ============
  751. idCompiler::ParseImmediate
  752. Looks for a preexisting constant
  753. ============
  754. */
  755. idVarDef *idCompiler::ParseImmediate() {
  756. idVarDef *def;
  757. def = GetImmediate( immediateType, &immediate, token.c_str() );
  758. NextToken();
  759. return def;
  760. }
  761. /*
  762. ============
  763. idCompiler::EmitFunctionParms
  764. ============
  765. */
  766. idVarDef *idCompiler::EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ) {
  767. idVarDef *e;
  768. const idTypeDef *type;
  769. const idTypeDef *funcArg;
  770. idVarDef *returnDef;
  771. idTypeDef *returnType;
  772. int arg;
  773. int size;
  774. int resultOp;
  775. type = func->TypeDef();
  776. if ( func->Type() != ev_function ) {
  777. Error( "'%s' is not a function", func->Name() );
  778. }
  779. // copy the parameters to the global parameter variables
  780. arg = startarg;
  781. size = startsize;
  782. if ( !CheckToken( ")" ) ) {
  783. do {
  784. if ( arg >= type->NumParameters() ) {
  785. Error( "too many parameters" );
  786. }
  787. e = GetExpression( TOP_PRIORITY );
  788. funcArg = type->GetParmType( arg );
  789. if ( !EmitPush( e, funcArg ) ) {
  790. Error( "type mismatch on parm %i of call to '%s'", arg + 1, func->Name() );
  791. }
  792. if ( funcArg->Type() == ev_object ) {
  793. size += type_object.Size();
  794. } else {
  795. size += funcArg->Size();
  796. }
  797. arg++;
  798. } while( CheckToken( "," ) );
  799. ExpectToken( ")" );
  800. }
  801. if ( arg < type->NumParameters() ) {
  802. Error( "too few parameters for function '%s'", func->Name() );
  803. }
  804. if ( op == OP_CALL ) {
  805. EmitOpcode( op, func, 0 );
  806. } else if ( ( op == OP_OBJECTCALL ) || ( op == OP_OBJTHREAD ) ) {
  807. EmitOpcode( op, object, VirtualFunctionConstant( func ) );
  808. // need arg size seperate since script object may be NULL
  809. statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 );
  810. statement.c = SizeConstant( func->value.functionPtr->parmTotal );
  811. } else {
  812. EmitOpcode( op, func, SizeConstant( size ) );
  813. }
  814. // we need to copy off the result into a temporary result location, so figure out the opcode
  815. returnType = type->ReturnType();
  816. if ( returnType->Type() == ev_string ) {
  817. resultOp = OP_STORE_S;
  818. returnDef = gameLocal.program.returnStringDef;
  819. } else {
  820. gameLocal.program.returnDef->SetTypeDef( returnType );
  821. returnDef = gameLocal.program.returnDef;
  822. switch( returnType->Type() ) {
  823. case ev_void :
  824. resultOp = OP_STORE_F;
  825. break;
  826. case ev_boolean :
  827. resultOp = OP_STORE_BOOL;
  828. break;
  829. case ev_float :
  830. resultOp = OP_STORE_F;
  831. break;
  832. case ev_vector :
  833. resultOp = OP_STORE_V;
  834. break;
  835. case ev_entity :
  836. resultOp = OP_STORE_ENT;
  837. break;
  838. case ev_object :
  839. resultOp = OP_STORE_OBJ;
  840. break;
  841. default :
  842. // shut up compiler
  843. resultOp = OP_STORE_OBJ;
  844. Error( "Invalid return type for function '%s'", func->Name() );
  845. }
  846. }
  847. if ( returnType->Type() == ev_void ) {
  848. // don't need result space since there's no result, so just return the normal result def.
  849. return returnDef;
  850. }
  851. // allocate result space
  852. // try to reuse result defs as much as possible
  853. statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 );
  854. idVarDef *resultDef = gameLocal.program.FindFreeResultDef( returnType, RESULT_STRING, scope, statement.a, statement.b );
  855. // set user count back to 0, a result def needs to be used twice before it can be reused
  856. resultDef->numUsers = 0;
  857. EmitOpcode( resultOp, returnDef, resultDef );
  858. return resultDef;
  859. }
  860. /*
  861. ============
  862. idCompiler::ParseFunctionCall
  863. ============
  864. */
  865. idVarDef *idCompiler::ParseFunctionCall( idVarDef *funcDef ) {
  866. assert( funcDef );
  867. if ( funcDef->Type() != ev_function ) {
  868. Error( "'%s' is not a function", funcDef->Name() );
  869. }
  870. if ( funcDef->initialized == idVarDef::uninitialized ) {
  871. Error( "Function '%s' has not been defined yet", funcDef->GlobalName() );
  872. }
  873. assert( funcDef->value.functionPtr );
  874. if ( callthread ) {
  875. if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) {
  876. Error( "Built-in functions cannot be called as threads" );
  877. }
  878. callthread = false;
  879. return EmitFunctionParms( OP_THREAD, funcDef, 0, 0, NULL );
  880. } else {
  881. if ( ( funcDef->initialized != idVarDef::uninitialized ) && funcDef->value.functionPtr->eventdef ) {
  882. if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) {
  883. // get the local object pointer
  884. idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope );
  885. if ( !thisdef ) {
  886. Error( "No 'self' within scope" );
  887. }
  888. return ParseEventCall( thisdef, funcDef );
  889. } else {
  890. Error( "Built-in functions cannot be called without an object" );
  891. }
  892. }
  893. return EmitFunctionParms( OP_CALL, funcDef, 0, 0, NULL );
  894. }
  895. }
  896. /*
  897. ============
  898. idCompiler::ParseObjectCall
  899. ============
  900. */
  901. idVarDef *idCompiler::ParseObjectCall( idVarDef *object, idVarDef *func ) {
  902. EmitPush( object, object->TypeDef() );
  903. if ( callthread ) {
  904. callthread = false;
  905. return EmitFunctionParms( OP_OBJTHREAD, func, 1, type_object.Size(), object );
  906. } else {
  907. return EmitFunctionParms( OP_OBJECTCALL, func, 1, 0, object );
  908. }
  909. }
  910. /*
  911. ============
  912. idCompiler::ParseEventCall
  913. ============
  914. */
  915. idVarDef *idCompiler::ParseEventCall( idVarDef *object, idVarDef *funcDef ) {
  916. if ( callthread ) {
  917. Error( "Cannot call built-in functions as a thread" );
  918. }
  919. if ( funcDef->Type() != ev_function ) {
  920. Error( "'%s' is not a function", funcDef->Name() );
  921. }
  922. if ( !funcDef->value.functionPtr->eventdef ) {
  923. Error( "\"%s\" cannot be called with object notation", funcDef->Name() );
  924. }
  925. if ( object->Type() == ev_object ) {
  926. EmitPush( object, &type_entity );
  927. } else {
  928. EmitPush( object, object->TypeDef() );
  929. }
  930. return EmitFunctionParms( OP_EVENTCALL, funcDef, 0, type_object.Size(), NULL );
  931. }
  932. /*
  933. ============
  934. idCompiler::ParseSysObjectCall
  935. ============
  936. */
  937. idVarDef *idCompiler::ParseSysObjectCall( idVarDef *funcDef ) {
  938. if ( callthread ) {
  939. Error( "Cannot call built-in functions as a thread" );
  940. }
  941. if ( funcDef->Type() != ev_function ) {
  942. Error( "'%s' is not a function", funcDef->Name() );
  943. }
  944. if ( funcDef->value.functionPtr->eventdef == NULL ) {
  945. Error( "\"%s\" cannot be called with object notation", funcDef->Name() );
  946. }
  947. assert( funcDef->value.functionPtr->eventdef != NULL ); // to remove stupid analyze warning
  948. if ( !idThread::Type.RespondsTo( *funcDef->value.functionPtr->eventdef ) ) {
  949. Error( "\"%s\" is not callable as a 'sys' function", funcDef->Name() );
  950. }
  951. return EmitFunctionParms( OP_SYSCALL, funcDef, 0, 0, NULL );
  952. }
  953. /*
  954. ============
  955. idCompiler::LookupDef
  956. ============
  957. */
  958. idVarDef *idCompiler::LookupDef( const char *name, const idVarDef *baseobj ) {
  959. idVarDef *def;
  960. idVarDef *field;
  961. etype_t type_b;
  962. etype_t type_c;
  963. opcode_t *op;
  964. // check if we're accessing a field
  965. if ( baseobj && ( baseobj->Type() == ev_object ) ) {
  966. const idVarDef *tdef;
  967. def = NULL;
  968. for( tdef = baseobj; tdef != &def_object; tdef = tdef->TypeDef()->SuperClass()->def ) {
  969. def = gameLocal.program.GetDef( NULL, name, tdef );
  970. if ( def ) {
  971. break;
  972. }
  973. }
  974. } else {
  975. // first look through the defs in our scope
  976. def = gameLocal.program.GetDef( NULL, name, scope );
  977. if ( !def ) {
  978. // if we're in a member function, check types local to the object
  979. if ( ( scope->Type() != ev_namespace ) && ( scope->scope->Type() == ev_object ) ) {
  980. // get the local object pointer
  981. idVarDef *thisdef = gameLocal.program.GetDef( scope->scope->TypeDef(), "self", scope );
  982. field = LookupDef( name, scope->scope->TypeDef()->def );
  983. if ( !field ) {
  984. Error( "Unknown value \"%s\"", name );
  985. }
  986. // type check
  987. type_b = field->Type();
  988. if ( field->Type() == ev_function ) {
  989. type_c = field->TypeDef()->ReturnType()->Type();
  990. } else {
  991. type_c = field->TypeDef()->FieldType()->Type(); // field access gets type from field
  992. if ( CheckToken( "++" ) ) {
  993. if ( type_c != ev_float ) {
  994. Error( "Invalid type for ++" );
  995. }
  996. def = EmitOpcode( OP_UINCP_F, thisdef, field );
  997. return def;
  998. } else if ( CheckToken( "--" ) ) {
  999. if ( type_c != ev_float ) {
  1000. Error( "Invalid type for --" );
  1001. }
  1002. def = EmitOpcode( OP_UDECP_F, thisdef, field );
  1003. return def;
  1004. }
  1005. }
  1006. op = &opcodes[ OP_INDIRECT_F ];
  1007. while( ( op->type_a->Type() != ev_object )
  1008. || ( type_b != op->type_b->Type() ) || ( type_c != op->type_c->Type() ) ) {
  1009. if ( ( op->priority == FUNCTION_PRIORITY ) && ( op->type_a->Type() == ev_object ) && ( op->type_c->Type() == ev_void ) &&
  1010. ( type_c != op->type_c->Type() ) ) {
  1011. // catches object calls that return a value
  1012. break;
  1013. }
  1014. op++;
  1015. if ( !op->name || strcmp( op->name, "." ) ) {
  1016. Error( "no valid opcode to access type '%s'", field->TypeDef()->SuperClass()->Name() );
  1017. }
  1018. }
  1019. if ( ( op - opcodes ) == OP_OBJECTCALL ) {
  1020. ExpectToken( "(" );
  1021. def = ParseObjectCall( thisdef, field );
  1022. } else {
  1023. // emit the conversion opcode
  1024. def = EmitOpcode( op, thisdef, field );
  1025. // field access gets type from field
  1026. def->SetTypeDef( field->TypeDef()->FieldType() );
  1027. }
  1028. }
  1029. }
  1030. }
  1031. return def;
  1032. }
  1033. /*
  1034. ============
  1035. idCompiler::ParseValue
  1036. Returns the def for the current token
  1037. ============
  1038. */
  1039. idVarDef *idCompiler::ParseValue() {
  1040. idVarDef *def;
  1041. idVarDef *namespaceDef;
  1042. idStr name;
  1043. if ( immediateType == &type_entity ) {
  1044. // if an immediate entity ($-prefaced name) then create or lookup a def for it.
  1045. // when entities are spawned, they'll lookup the def and point it to them.
  1046. def = gameLocal.program.GetDef( &type_entity, "$" + token, &def_namespace );
  1047. if ( !def ) {
  1048. def = gameLocal.program.AllocDef( &type_entity, "$" + token, &def_namespace, true );
  1049. }
  1050. NextToken();
  1051. return def;
  1052. } else if ( immediateType ) {
  1053. // if the token is an immediate, allocate a constant for it
  1054. return ParseImmediate();
  1055. }
  1056. ParseName( name );
  1057. def = LookupDef( name, basetype );
  1058. if ( def == NULL ) {
  1059. if ( basetype ) {
  1060. Error( "%s is not a member of %s", name.c_str(), basetype->TypeDef()->Name() );
  1061. } else {
  1062. Error( "Unknown value \"%s\"", name.c_str() );
  1063. }
  1064. // if namespace, then look up the variable in that namespace
  1065. } else if ( def->Type() == ev_namespace ) {
  1066. while( def->Type() == ev_namespace ) {
  1067. ExpectToken( "::" );
  1068. ParseName( name );
  1069. namespaceDef = def;
  1070. def = gameLocal.program.GetDef( NULL, name, namespaceDef );
  1071. if ( def == NULL ) {
  1072. if ( namespaceDef != NULL ) {
  1073. Error( "Unknown value \"%s::%s\"", namespaceDef->GlobalName(), name.c_str() );
  1074. } else {
  1075. Error( "Unknown value \"%s\"", name.c_str() );
  1076. }
  1077. break;
  1078. }
  1079. }
  1080. //def = LookupDef( name, basetype );
  1081. }
  1082. return def;
  1083. }
  1084. /*
  1085. ============
  1086. idCompiler::GetTerm
  1087. ============
  1088. */
  1089. idVarDef *idCompiler::GetTerm() {
  1090. idVarDef *e;
  1091. int op;
  1092. if ( !immediateType && CheckToken( "~" ) ) {
  1093. e = GetExpression( TILDE_PRIORITY );
  1094. switch( e->Type() ) {
  1095. case ev_float :
  1096. op = OP_COMP_F;
  1097. break;
  1098. default :
  1099. // shut up compiler
  1100. op = OP_COMP_F;
  1101. Error( "type mismatch for ~" );
  1102. }
  1103. return EmitOpcode( op, e, 0 );
  1104. }
  1105. if ( !immediateType && CheckToken( "!" ) ) {
  1106. e = GetExpression( NOT_PRIORITY );
  1107. switch( e->Type() ) {
  1108. case ev_boolean :
  1109. op = OP_NOT_BOOL;
  1110. break;
  1111. case ev_float :
  1112. op = OP_NOT_F;
  1113. break;
  1114. case ev_string :
  1115. op = OP_NOT_S;
  1116. break;
  1117. case ev_vector :
  1118. op = OP_NOT_V;
  1119. break;
  1120. case ev_entity :
  1121. op = OP_NOT_ENT;
  1122. break;
  1123. case ev_function :
  1124. // shut up compiler
  1125. op = OP_NOT_F;
  1126. Error( "Invalid type for !" );
  1127. break;
  1128. case ev_object :
  1129. op = OP_NOT_ENT;
  1130. break;
  1131. default :
  1132. // shut up compiler
  1133. op = OP_NOT_F;
  1134. Error( "type mismatch for !" );
  1135. }
  1136. return EmitOpcode( op, e, 0 );
  1137. }
  1138. // check for negation operator
  1139. if ( !immediateType && CheckToken( "-" ) ) {
  1140. // constants are directly negated without an instruction
  1141. if ( immediateType == &type_float ) {
  1142. immediate._float = -immediate._float;
  1143. return ParseImmediate();
  1144. } else if ( immediateType == &type_vector ) {
  1145. immediate.vector[0] = -immediate.vector[0];
  1146. immediate.vector[1] = -immediate.vector[1];
  1147. immediate.vector[2] = -immediate.vector[2];
  1148. return ParseImmediate();
  1149. } else {
  1150. e = GetExpression( NOT_PRIORITY );
  1151. switch( e->Type() ) {
  1152. case ev_float :
  1153. op = OP_NEG_F;
  1154. break;
  1155. case ev_vector :
  1156. op = OP_NEG_V;
  1157. break;
  1158. default :
  1159. // shut up compiler
  1160. op = OP_NEG_F;
  1161. Error( "type mismatch for -" );
  1162. }
  1163. return EmitOpcode( &opcodes[ op ], e, 0 );
  1164. }
  1165. }
  1166. if ( CheckToken( "int" ) ) {
  1167. ExpectToken( "(" );
  1168. e = GetExpression( INT_PRIORITY );
  1169. if ( e->Type() != ev_float ) {
  1170. Error( "type mismatch for int()" );
  1171. }
  1172. ExpectToken( ")" );
  1173. return EmitOpcode( OP_INT_F, e, 0 );
  1174. }
  1175. if ( CheckToken( "thread" ) ) {
  1176. callthread = true;
  1177. e = GetExpression( FUNCTION_PRIORITY );
  1178. if ( callthread ) {
  1179. Error( "Invalid thread call" );
  1180. }
  1181. // threads return the thread number
  1182. gameLocal.program.returnDef->SetTypeDef( &type_float );
  1183. return gameLocal.program.returnDef;
  1184. }
  1185. if ( !immediateType && CheckToken( "(" ) ) {
  1186. e = GetExpression( TOP_PRIORITY );
  1187. ExpectToken( ")" );
  1188. return e;
  1189. }
  1190. return ParseValue();
  1191. }
  1192. /*
  1193. ==============
  1194. idCompiler::TypeMatches
  1195. ==============
  1196. */
  1197. bool idCompiler::TypeMatches( etype_t type1, etype_t type2 ) const {
  1198. if ( type1 == type2 ) {
  1199. return true;
  1200. }
  1201. //if ( ( type1 == ev_entity ) && ( type2 == ev_object ) ) {
  1202. // return true;
  1203. //}
  1204. //if ( ( type2 == ev_entity ) && ( type1 == ev_object ) ) {
  1205. // return true;
  1206. //}
  1207. return false;
  1208. }
  1209. /*
  1210. ==============
  1211. idCompiler::GetExpression
  1212. ==============
  1213. */
  1214. idVarDef *idCompiler::GetExpression( int priority ) {
  1215. opcode_t *op;
  1216. opcode_t *oldop;
  1217. idVarDef *e;
  1218. idVarDef *e2;
  1219. const idVarDef *oldtype;
  1220. etype_t type_a;
  1221. etype_t type_b;
  1222. etype_t type_c;
  1223. if ( priority == 0 ) {
  1224. return GetTerm();
  1225. }
  1226. e = GetExpression( priority - 1 );
  1227. if ( token == ";" ) {
  1228. // save us from searching through the opcodes unneccesarily
  1229. return e;
  1230. }
  1231. while( 1 ) {
  1232. if ( ( priority == FUNCTION_PRIORITY ) && CheckToken( "(" ) ) {
  1233. return ParseFunctionCall( e );
  1234. }
  1235. // has to be a punctuation
  1236. if ( immediateType ) {
  1237. break;
  1238. }
  1239. for( op = opcodes; op->name; op++ ) {
  1240. if ( ( op->priority == priority ) && CheckToken( op->name ) ) {
  1241. break;
  1242. }
  1243. }
  1244. if ( !op->name ) {
  1245. // next token isn't at this priority level
  1246. break;
  1247. }
  1248. // unary operators act only on the left operand
  1249. if ( op->type_b == &def_void ) {
  1250. e = EmitOpcode( op, e, 0 );
  1251. return e;
  1252. }
  1253. // preserve our base type
  1254. oldtype = basetype;
  1255. // field access needs scope from object
  1256. if ( ( op->name[ 0 ] == '.' ) && e->TypeDef()->Inherits( &type_object ) ) {
  1257. // save off what type this field is part of
  1258. basetype = e->TypeDef()->def;
  1259. }
  1260. if ( op->rightAssociative ) {
  1261. // if last statement is an indirect, change it to an address of
  1262. if ( gameLocal.program.NumStatements() > 0 ) {
  1263. statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 );
  1264. if ( ( statement.op >= OP_INDIRECT_F ) && ( statement.op < OP_ADDRESS ) ) {
  1265. statement.op = OP_ADDRESS;
  1266. type_pointer.SetPointerType( e->TypeDef() );
  1267. e->SetTypeDef( &type_pointer );
  1268. }
  1269. }
  1270. e2 = GetExpression( priority );
  1271. } else {
  1272. e2 = GetExpression( priority - 1 );
  1273. }
  1274. // restore type
  1275. basetype = oldtype;
  1276. // type check
  1277. type_a = e->Type();
  1278. type_b = e2->Type();
  1279. // field access gets type from field
  1280. if ( op->name[ 0 ] == '.' ) {
  1281. if ( ( e2->Type() == ev_function ) && e2->TypeDef()->ReturnType() ) {
  1282. type_c = e2->TypeDef()->ReturnType()->Type();
  1283. } else if ( e2->TypeDef()->FieldType() ) {
  1284. type_c = e2->TypeDef()->FieldType()->Type();
  1285. } else {
  1286. // not a field
  1287. type_c = ev_error;
  1288. }
  1289. } else {
  1290. type_c = ev_void;
  1291. }
  1292. oldop = op;
  1293. while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) ||
  1294. ( ( type_c != ev_void ) && !TypeMatches( type_c, op->type_c->Type() ) ) ) {
  1295. if ( ( op->priority == FUNCTION_PRIORITY ) && TypeMatches( type_a, op->type_a->Type() ) && TypeMatches( type_b, op->type_b->Type() ) ) {
  1296. break;
  1297. }
  1298. op++;
  1299. if ( !op->name || strcmp( op->name, oldop->name ) ) {
  1300. Error( "type mismatch for '%s'", oldop->name );
  1301. }
  1302. }
  1303. switch( op - opcodes ) {
  1304. case OP_SYSCALL :
  1305. ExpectToken( "(" );
  1306. e = ParseSysObjectCall( e2 );
  1307. break;
  1308. case OP_OBJECTCALL :
  1309. ExpectToken( "(" );
  1310. if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) {
  1311. e = ParseEventCall( e, e2 );
  1312. } else {
  1313. e = ParseObjectCall( e, e2 );
  1314. }
  1315. break;
  1316. case OP_EVENTCALL :
  1317. ExpectToken( "(" );
  1318. if ( ( e2->initialized != idVarDef::uninitialized ) && e2->value.functionPtr->eventdef ) {
  1319. e = ParseEventCall( e, e2 );
  1320. } else {
  1321. e = ParseObjectCall( e, e2 );
  1322. }
  1323. break;
  1324. default:
  1325. if ( callthread ) {
  1326. Error( "Expecting function call after 'thread'" );
  1327. }
  1328. if ( ( type_a == ev_pointer ) && ( type_b != e->TypeDef()->PointerType()->Type() ) ) {
  1329. // FIXME: need to make a general case for this
  1330. if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_boolean ) ) {
  1331. // copy from float to boolean pointer
  1332. op = &opcodes[ OP_STOREP_FTOBOOL ];
  1333. } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_float ) ) {
  1334. // copy from boolean to float pointer
  1335. op = &opcodes[ OP_STOREP_BOOLTOF ];
  1336. } else if ( ( op - opcodes == OP_STOREP_F ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) {
  1337. // copy from float to string pointer
  1338. op = &opcodes[ OP_STOREP_FTOS ];
  1339. } else if ( ( op - opcodes == OP_STOREP_BOOL ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) {
  1340. // copy from boolean to string pointer
  1341. op = &opcodes[ OP_STOREP_BTOS ];
  1342. } else if ( ( op - opcodes == OP_STOREP_V ) && ( e->TypeDef()->PointerType()->Type() == ev_string ) ) {
  1343. // copy from vector to string pointer
  1344. op = &opcodes[ OP_STOREP_VTOS ];
  1345. } else if ( ( op - opcodes == OP_STOREP_ENT ) && ( e->TypeDef()->PointerType()->Type() == ev_object ) ) {
  1346. // store an entity into an object pointer
  1347. op = &opcodes[ OP_STOREP_OBJENT ];
  1348. } else {
  1349. Error( "type mismatch for '%s'", op->name );
  1350. }
  1351. }
  1352. if ( op->rightAssociative ) {
  1353. e = EmitOpcode( op, e2, e );
  1354. } else {
  1355. e = EmitOpcode( op, e, e2 );
  1356. }
  1357. if ( op - opcodes == OP_STOREP_OBJENT ) {
  1358. // statement.b points to type_pointer, which is just a temporary that gets its type reassigned, so we store the real type in statement.c
  1359. // so that we can do a type check during run time since we don't know what type the script object is at compile time because it
  1360. // comes from an entity
  1361. statement_t &statement = gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 );
  1362. statement.c = type_pointer.PointerType()->def;
  1363. }
  1364. // field access gets type from field
  1365. if ( type_c != ev_void ) {
  1366. e->SetTypeDef( e2->TypeDef()->FieldType() );
  1367. }
  1368. break;
  1369. }
  1370. }
  1371. return e;
  1372. }
  1373. /*
  1374. ================
  1375. idCompiler::PatchLoop
  1376. ================
  1377. */
  1378. void idCompiler::PatchLoop( int start, int continuePos ) {
  1379. int i;
  1380. statement_t *pos;
  1381. pos = &gameLocal.program.GetStatement( start );
  1382. for( i = start; i < gameLocal.program.NumStatements(); i++, pos++ ) {
  1383. if ( pos->op == OP_BREAK ) {
  1384. pos->op = OP_GOTO;
  1385. pos->a = JumpFrom( i );
  1386. } else if ( pos->op == OP_CONTINUE ) {
  1387. pos->op = OP_GOTO;
  1388. pos->a = JumpDef( i, continuePos );
  1389. }
  1390. }
  1391. }
  1392. /*
  1393. ================
  1394. idCompiler::ParseReturnStatement
  1395. ================
  1396. */
  1397. void idCompiler::ParseReturnStatement() {
  1398. idVarDef *e;
  1399. etype_t type_a;
  1400. etype_t type_b;
  1401. opcode_t *op;
  1402. if ( CheckToken( ";" ) ) {
  1403. if ( scope->TypeDef()->ReturnType()->Type() != ev_void ) {
  1404. Error( "expecting return value" );
  1405. }
  1406. EmitOpcode( OP_RETURN, 0, 0 );
  1407. return;
  1408. }
  1409. e = GetExpression( TOP_PRIORITY );
  1410. ExpectToken( ";" );
  1411. type_a = e->Type();
  1412. type_b = scope->TypeDef()->ReturnType()->Type();
  1413. if ( TypeMatches( type_a, type_b ) ) {
  1414. EmitOpcode( OP_RETURN, e, 0 );
  1415. return;
  1416. }
  1417. for( op = opcodes; op->name; op++ ) {
  1418. if ( !strcmp( op->name, "=" ) ) {
  1419. break;
  1420. }
  1421. }
  1422. assert( op->name );
  1423. while( !TypeMatches( type_a, op->type_a->Type() ) || !TypeMatches( type_b, op->type_b->Type() ) ) {
  1424. op++;
  1425. if ( !op->name || strcmp( op->name, "=" ) ) {
  1426. Error( "type mismatch for return value" );
  1427. }
  1428. }
  1429. idTypeDef *returnType = scope->TypeDef()->ReturnType();
  1430. if ( returnType->Type() == ev_string ) {
  1431. EmitOpcode( op, e, gameLocal.program.returnStringDef );
  1432. } else {
  1433. gameLocal.program.returnDef->SetTypeDef( returnType );
  1434. EmitOpcode( op, e, gameLocal.program.returnDef );
  1435. }
  1436. EmitOpcode( OP_RETURN, 0, 0 );
  1437. }
  1438. /*
  1439. ================
  1440. idCompiler::ParseWhileStatement
  1441. ================
  1442. */
  1443. void idCompiler::ParseWhileStatement() {
  1444. idVarDef *e;
  1445. int patch1;
  1446. int patch2;
  1447. loopDepth++;
  1448. ExpectToken( "(" );
  1449. patch2 = gameLocal.program.NumStatements();
  1450. e = GetExpression( TOP_PRIORITY );
  1451. ExpectToken( ")" );
  1452. if ( ( e->initialized == idVarDef::initializedConstant ) && ( *e->value.intPtr != 0 ) ) {
  1453. //FIXME: we can completely skip generation of this code in the opposite case
  1454. ParseStatement();
  1455. EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 );
  1456. } else {
  1457. patch1 = gameLocal.program.NumStatements();
  1458. EmitOpcode( OP_IFNOT, e, 0 );
  1459. ParseStatement();
  1460. EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 );
  1461. gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 );
  1462. }
  1463. // fixup breaks and continues
  1464. PatchLoop( patch2, patch2 );
  1465. loopDepth--;
  1466. }
  1467. /*
  1468. ================
  1469. idCompiler::ParseForStatement
  1470. Form of for statement with a counter:
  1471. a = 0;
  1472. start: << patch4
  1473. if ( !( a < 10 ) ) {
  1474. goto end; << patch1
  1475. } else {
  1476. goto process; << patch3
  1477. }
  1478. increment: << patch2
  1479. a = a + 1;
  1480. goto start; << goto patch4
  1481. process:
  1482. statements;
  1483. goto increment; << goto patch2
  1484. end:
  1485. Form of for statement without a counter:
  1486. a = 0;
  1487. start: << patch2
  1488. if ( !( a < 10 ) ) {
  1489. goto end; << patch1
  1490. }
  1491. process:
  1492. statements;
  1493. goto start; << goto patch2
  1494. end:
  1495. ================
  1496. */
  1497. void idCompiler::ParseForStatement() {
  1498. idVarDef *e;
  1499. int start;
  1500. int patch1;
  1501. int patch2;
  1502. int patch3;
  1503. int patch4;
  1504. loopDepth++;
  1505. start = gameLocal.program.NumStatements();
  1506. ExpectToken( "(" );
  1507. // init
  1508. if ( !CheckToken( ";" ) ) {
  1509. do {
  1510. GetExpression( TOP_PRIORITY );
  1511. } while( CheckToken( "," ) );
  1512. ExpectToken( ";" );
  1513. }
  1514. // condition
  1515. patch2 = gameLocal.program.NumStatements();
  1516. e = GetExpression( TOP_PRIORITY );
  1517. ExpectToken( ";" );
  1518. //FIXME: add check for constant expression
  1519. patch1 = gameLocal.program.NumStatements();
  1520. EmitOpcode( OP_IFNOT, e, 0 );
  1521. // counter
  1522. if ( !CheckToken( ")" ) ) {
  1523. patch3 = gameLocal.program.NumStatements();
  1524. EmitOpcode( OP_IF, e, 0 );
  1525. patch4 = patch2;
  1526. patch2 = gameLocal.program.NumStatements();
  1527. do {
  1528. GetExpression( TOP_PRIORITY );
  1529. } while( CheckToken( "," ) );
  1530. ExpectToken( ")" );
  1531. // goto patch4
  1532. EmitOpcode( OP_GOTO, JumpTo( patch4 ), 0 );
  1533. // fixup patch3
  1534. gameLocal.program.GetStatement( patch3 ).b = JumpFrom( patch3 );
  1535. }
  1536. ParseStatement();
  1537. // goto patch2
  1538. EmitOpcode( OP_GOTO, JumpTo( patch2 ), 0 );
  1539. // fixup patch1
  1540. gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 );
  1541. // fixup breaks and continues
  1542. PatchLoop( start, patch2 );
  1543. loopDepth--;
  1544. }
  1545. /*
  1546. ================
  1547. idCompiler::ParseDoWhileStatement
  1548. ================
  1549. */
  1550. void idCompiler::ParseDoWhileStatement() {
  1551. idVarDef *e;
  1552. int patch1;
  1553. loopDepth++;
  1554. patch1 = gameLocal.program.NumStatements();
  1555. ParseStatement();
  1556. ExpectToken( "while" );
  1557. ExpectToken( "(" );
  1558. e = GetExpression( TOP_PRIORITY );
  1559. ExpectToken( ")" );
  1560. ExpectToken( ";" );
  1561. EmitOpcode( OP_IF, e, JumpTo( patch1 ) );
  1562. // fixup breaks and continues
  1563. PatchLoop( patch1, patch1 );
  1564. loopDepth--;
  1565. }
  1566. /*
  1567. ================
  1568. idCompiler::ParseIfStatement
  1569. ================
  1570. */
  1571. void idCompiler::ParseIfStatement() {
  1572. idVarDef *e;
  1573. int patch1;
  1574. int patch2;
  1575. ExpectToken( "(" );
  1576. e = GetExpression( TOP_PRIORITY );
  1577. ExpectToken( ")" );
  1578. //FIXME: add check for constant expression
  1579. patch1 = gameLocal.program.NumStatements();
  1580. EmitOpcode( OP_IFNOT, e, 0 );
  1581. ParseStatement();
  1582. if ( CheckToken( "else" ) ) {
  1583. patch2 = gameLocal.program.NumStatements();
  1584. EmitOpcode( OP_GOTO, 0, 0 );
  1585. gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 );
  1586. ParseStatement();
  1587. gameLocal.program.GetStatement( patch2 ).a = JumpFrom( patch2 );
  1588. } else {
  1589. gameLocal.program.GetStatement( patch1 ).b = JumpFrom( patch1 );
  1590. }
  1591. }
  1592. /*
  1593. ============
  1594. idCompiler::ParseStatement
  1595. ============
  1596. */
  1597. void idCompiler::ParseStatement() {
  1598. if ( CheckToken( ";" ) ) {
  1599. // skip semicolons, which are harmless and ok syntax
  1600. return;
  1601. }
  1602. if ( CheckToken( "{" ) ) {
  1603. do {
  1604. ParseStatement();
  1605. } while( !CheckToken( "}" ) );
  1606. return;
  1607. }
  1608. if ( CheckToken( "return" ) ) {
  1609. ParseReturnStatement();
  1610. return;
  1611. }
  1612. if ( CheckToken( "while" ) ) {
  1613. ParseWhileStatement();
  1614. return;
  1615. }
  1616. if ( CheckToken( "for" ) ) {
  1617. ParseForStatement();
  1618. return;
  1619. }
  1620. if ( CheckToken( "do" ) ) {
  1621. ParseDoWhileStatement();
  1622. return;
  1623. }
  1624. if ( CheckToken( "break" ) ) {
  1625. ExpectToken( ";" );
  1626. if ( !loopDepth ) {
  1627. Error( "cannot break outside of a loop" );
  1628. }
  1629. EmitOpcode( OP_BREAK, 0, 0 );
  1630. return;
  1631. }
  1632. if ( CheckToken( "continue" ) ) {
  1633. ExpectToken( ";" );
  1634. if ( !loopDepth ) {
  1635. Error( "cannot contine outside of a loop" );
  1636. }
  1637. EmitOpcode( OP_CONTINUE, 0, 0 );
  1638. return;
  1639. }
  1640. if ( CheckType() != NULL ) {
  1641. ParseDefs();
  1642. return;
  1643. }
  1644. if ( CheckToken( "if" ) ) {
  1645. ParseIfStatement();
  1646. return;
  1647. }
  1648. GetExpression( TOP_PRIORITY );
  1649. ExpectToken(";");
  1650. }
  1651. /*
  1652. ================
  1653. idCompiler::ParseObjectDef
  1654. ================
  1655. */
  1656. void idCompiler::ParseObjectDef( const char *objname ) {
  1657. idTypeDef *objtype;
  1658. idTypeDef *type;
  1659. idTypeDef *parentType;
  1660. idTypeDef *fieldtype;
  1661. idStr name;
  1662. const char *fieldname;
  1663. idTypeDef newtype( ev_field, NULL, "", 0, NULL );
  1664. idVarDef *oldscope;
  1665. int num;
  1666. int i;
  1667. oldscope = scope;
  1668. if ( scope->Type() != ev_namespace ) {
  1669. Error( "Objects cannot be defined within functions or other objects" );
  1670. }
  1671. // make sure it doesn't exist before we create it
  1672. if ( gameLocal.program.FindType( objname ) != NULL ) {
  1673. Error( "'%s' : redefinition; different basic types", objname );
  1674. }
  1675. // base type
  1676. if ( !CheckToken( ":" ) ) {
  1677. parentType = &type_object;
  1678. } else {
  1679. parentType = ParseType();
  1680. if ( !parentType->Inherits( &type_object ) ) {
  1681. Error( "Objects may only inherit from objects." );
  1682. }
  1683. }
  1684. objtype = gameLocal.program.AllocType( ev_object, NULL, objname, parentType == &type_object ? 0 : parentType->Size(), parentType );
  1685. objtype->def = gameLocal.program.AllocDef( objtype, objname, scope, true );
  1686. scope = objtype->def;
  1687. // inherit all the functions
  1688. num = parentType->NumFunctions();
  1689. for( i = 0; i < parentType->NumFunctions(); i++ ) {
  1690. const function_t *func = parentType->GetFunction( i );
  1691. objtype->AddFunction( func );
  1692. }
  1693. ExpectToken( "{" );
  1694. do {
  1695. if ( CheckToken( ";" ) ) {
  1696. // skip semicolons, which are harmless and ok syntax
  1697. continue;
  1698. }
  1699. fieldtype = ParseType();
  1700. newtype.SetFieldType( fieldtype );
  1701. fieldname = va( "%s field", fieldtype->Name() );
  1702. newtype.SetName( fieldname );
  1703. ParseName( name );
  1704. // check for a function prototype or declaraction
  1705. if ( CheckToken( "(" ) ) {
  1706. ParseFunctionDef( newtype.FieldType(), name );
  1707. } else {
  1708. type = gameLocal.program.GetType( newtype, true );
  1709. assert( !type->def );
  1710. gameLocal.program.AllocDef( type, name, scope, true );
  1711. objtype->AddField( type, name );
  1712. ExpectToken( ";" );
  1713. }
  1714. } while( !CheckToken( "}" ) );
  1715. scope = oldscope;
  1716. ExpectToken( ";" );
  1717. }
  1718. /*
  1719. ============
  1720. idCompiler::ParseFunction
  1721. parse a function type
  1722. ============
  1723. */
  1724. idTypeDef *idCompiler::ParseFunction( idTypeDef *returnType, const char *name ) {
  1725. idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType );
  1726. idTypeDef *type;
  1727. if ( scope->Type() != ev_namespace ) {
  1728. // create self pointer
  1729. newtype.AddFunctionParm( scope->TypeDef(), "self" );
  1730. }
  1731. if ( !CheckToken( ")" ) ) {
  1732. idStr parmName;
  1733. do {
  1734. type = ParseType();
  1735. ParseName( parmName );
  1736. newtype.AddFunctionParm( type, parmName );
  1737. } while( CheckToken( "," ) );
  1738. ExpectToken( ")" );
  1739. }
  1740. return gameLocal.program.GetType( newtype, true );
  1741. }
  1742. /*
  1743. ================
  1744. idCompiler::ParseFunctionDef
  1745. ================
  1746. */
  1747. void idCompiler::ParseFunctionDef( idTypeDef *returnType, const char *name ) {
  1748. idTypeDef *type;
  1749. idVarDef *def;
  1750. const idVarDef *parm;
  1751. idVarDef *oldscope;
  1752. int i;
  1753. int numParms;
  1754. const idTypeDef *parmType;
  1755. function_t *func;
  1756. statement_t *pos;
  1757. if ( ( scope->Type() != ev_namespace ) && !scope->TypeDef()->Inherits( &type_object ) ) {
  1758. Error( "Functions may not be defined within other functions" );
  1759. }
  1760. type = ParseFunction( returnType, name );
  1761. def = gameLocal.program.GetDef( type, name, scope );
  1762. if ( !def ) {
  1763. def = gameLocal.program.AllocDef( type, name, scope, true );
  1764. type->def = def;
  1765. func = &gameLocal.program.AllocFunction( def );
  1766. if ( scope->TypeDef()->Inherits( &type_object ) ) {
  1767. scope->TypeDef()->AddFunction( func );
  1768. }
  1769. } else {
  1770. func = def->value.functionPtr;
  1771. assert( func );
  1772. if ( func->firstStatement ) {
  1773. Error( "%s redeclared", def->GlobalName() );
  1774. }
  1775. }
  1776. // check if this is a prototype or declaration
  1777. if ( !CheckToken( "{" ) ) {
  1778. // it's just a prototype, so get the ; and move on
  1779. ExpectToken( ";" );
  1780. return;
  1781. }
  1782. // calculate stack space used by parms
  1783. numParms = type->NumParameters();
  1784. func->parmSize.SetNum( numParms );
  1785. for( i = 0; i < numParms; i++ ) {
  1786. parmType = type->GetParmType( i );
  1787. if ( parmType->Inherits( &type_object ) ) {
  1788. func->parmSize[ i ] = type_object.Size();
  1789. } else {
  1790. func->parmSize[ i ] = parmType->Size();
  1791. }
  1792. func->parmTotal += func->parmSize[ i ];
  1793. }
  1794. // define the parms
  1795. for( i = 0; i < numParms; i++ ) {
  1796. if ( gameLocal.program.GetDef( type->GetParmType( i ), type->GetParmName( i ), def ) ) {
  1797. Error( "'%s' defined more than once in function parameters", type->GetParmName( i ) );
  1798. }
  1799. parm = gameLocal.program.AllocDef( type->GetParmType( i ), type->GetParmName( i ), def, false );
  1800. }
  1801. oldscope = scope;
  1802. scope = def;
  1803. func->firstStatement = gameLocal.program.NumStatements();
  1804. // check if we should call the super class constructor
  1805. if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "init" ) ) {
  1806. idTypeDef *superClass;
  1807. function_t *constructorFunc = NULL;
  1808. // find the superclass constructor
  1809. for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) {
  1810. constructorFunc = gameLocal.program.FindFunction( va( "%s::init", superClass->Name() ) );
  1811. if ( constructorFunc ) {
  1812. break;
  1813. }
  1814. }
  1815. // emit the call to the constructor
  1816. if ( constructorFunc ) {
  1817. idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def );
  1818. assert( selfDef );
  1819. EmitPush( selfDef, selfDef->TypeDef() );
  1820. EmitOpcode( &opcodes[ OP_CALL ], constructorFunc->def, 0 );
  1821. }
  1822. }
  1823. // parse regular statements
  1824. while( !CheckToken( "}" ) ) {
  1825. ParseStatement();
  1826. }
  1827. // check if we should call the super class destructor
  1828. if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "destroy" ) ) {
  1829. idTypeDef *superClass;
  1830. function_t *destructorFunc = NULL;
  1831. // find the superclass destructor
  1832. for( superClass = oldscope->TypeDef()->SuperClass(); superClass != &type_object; superClass = superClass->SuperClass() ) {
  1833. destructorFunc = gameLocal.program.FindFunction( va( "%s::destroy", superClass->Name() ) );
  1834. if ( destructorFunc ) {
  1835. break;
  1836. }
  1837. }
  1838. if ( destructorFunc ) {
  1839. if ( func->firstStatement < gameLocal.program.NumStatements() ) {
  1840. // change all returns to point to the call to the destructor
  1841. pos = &gameLocal.program.GetStatement( func->firstStatement );
  1842. for( i = func->firstStatement; i < gameLocal.program.NumStatements(); i++, pos++ ) {
  1843. if ( pos->op == OP_RETURN ) {
  1844. pos->op = OP_GOTO;
  1845. pos->a = JumpDef( i, gameLocal.program.NumStatements() );
  1846. }
  1847. }
  1848. }
  1849. // emit the call to the destructor
  1850. idVarDef *selfDef = gameLocal.program.GetDef( type->GetParmType( 0 ), type->GetParmName( 0 ), def );
  1851. assert( selfDef );
  1852. EmitPush( selfDef, selfDef->TypeDef() );
  1853. EmitOpcode( &opcodes[ OP_CALL ], destructorFunc->def, 0 );
  1854. }
  1855. }
  1856. // Disabled code since it caused a function to fall through to the next function when last statement is in the form "if ( x ) { return; }"
  1857. #if 0
  1858. // don't bother adding a return opcode if the "return" statement was used.
  1859. if ( ( func->firstStatement == gameLocal.program.NumStatements() ) || ( gameLocal.program.GetStatement( gameLocal.program.NumStatements() - 1 ).op != OP_RETURN ) ) {
  1860. // emit an end of statements opcode
  1861. EmitOpcode( OP_RETURN, 0, 0 );
  1862. }
  1863. #else
  1864. // always emit the return opcode
  1865. EmitOpcode( OP_RETURN, 0, 0 );
  1866. #endif
  1867. // record the number of statements in the function
  1868. func->numStatements = gameLocal.program.NumStatements() - func->firstStatement;
  1869. scope = oldscope;
  1870. }
  1871. /*
  1872. ================
  1873. idCompiler::ParseVariableDef
  1874. ================
  1875. */
  1876. void idCompiler::ParseVariableDef( idTypeDef *type, const char *name ) {
  1877. idVarDef *def, *def2;
  1878. bool negate;
  1879. def = gameLocal.program.GetDef( type, name, scope );
  1880. if ( def ) {
  1881. Error( "%s redeclared", name );
  1882. }
  1883. def = gameLocal.program.AllocDef( type, name, scope, false );
  1884. // check for an initialization
  1885. if ( CheckToken( "=" ) ) {
  1886. // if a local variable in a function then write out interpreter code to initialize variable
  1887. if ( scope->Type() == ev_function ) {
  1888. def2 = GetExpression( TOP_PRIORITY );
  1889. if ( ( type == &type_float ) && ( def2->TypeDef() == &type_float ) ) {
  1890. EmitOpcode( OP_STORE_F, def2, def );
  1891. } else if ( ( type == &type_vector ) && ( def2->TypeDef() == &type_vector ) ) {
  1892. EmitOpcode( OP_STORE_V, def2, def );
  1893. } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_string ) ) {
  1894. EmitOpcode( OP_STORE_S, def2, def );
  1895. } else if ( ( type == &type_entity ) && ( ( def2->TypeDef() == &type_entity ) || ( def2->TypeDef()->Inherits( &type_object ) ) ) ) {
  1896. EmitOpcode( OP_STORE_ENT, def2, def );
  1897. } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef() == &type_entity ) ) {
  1898. EmitOpcode( OP_STORE_OBJENT, def2, def );
  1899. } else if ( ( type->Inherits( &type_object ) ) && ( def2->TypeDef()->Inherits( type ) ) ) {
  1900. EmitOpcode( OP_STORE_OBJ, def2, def );
  1901. } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_boolean ) ) {
  1902. EmitOpcode( OP_STORE_BOOL, def2, def );
  1903. } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_float ) ) {
  1904. EmitOpcode( OP_STORE_FTOS, def2, def );
  1905. } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_boolean ) ) {
  1906. EmitOpcode( OP_STORE_BTOS, def2, def );
  1907. } else if ( ( type == &type_string ) && ( def2->TypeDef() == &type_vector ) ) {
  1908. EmitOpcode( OP_STORE_VTOS, def2, def );
  1909. } else if ( ( type == &type_boolean ) && ( def2->TypeDef() == &type_float ) ) {
  1910. EmitOpcode( OP_STORE_FTOBOOL, def2, def );
  1911. } else if ( ( type == &type_float ) && ( def2->TypeDef() == &type_boolean ) ) {
  1912. EmitOpcode( OP_STORE_BOOLTOF, def2, def );
  1913. } else {
  1914. Error( "bad initialization for '%s'", name );
  1915. }
  1916. } else {
  1917. // global variables can only be initialized with immediate values
  1918. negate = false;
  1919. if ( token.type == TT_PUNCTUATION && token == "-" ) {
  1920. negate = true;
  1921. NextToken();
  1922. if ( immediateType != &type_float ) {
  1923. Error( "wrong immediate type for '-' on variable '%s'", name );
  1924. }
  1925. }
  1926. if ( immediateType != type ) {
  1927. Error( "wrong immediate type for '%s'", name );
  1928. }
  1929. // global variables are initialized at start up
  1930. if ( type == &type_string ) {
  1931. def->SetString( token, false );
  1932. } else {
  1933. if ( negate ) {
  1934. immediate._float = -immediate._float;
  1935. }
  1936. def->SetValue( immediate, false );
  1937. }
  1938. NextToken();
  1939. }
  1940. } else if ( type == &type_string ) {
  1941. // local strings on the stack are initialized in the interpreter
  1942. if ( scope->Type() != ev_function ) {
  1943. def->SetString( "", false );
  1944. }
  1945. } else if ( type->Inherits( &type_object ) ) {
  1946. if ( scope->Type() != ev_function ) {
  1947. def->SetObject( NULL );
  1948. }
  1949. }
  1950. }
  1951. /*
  1952. ================
  1953. idCompiler::GetTypeForEventArg
  1954. ================
  1955. */
  1956. idTypeDef *idCompiler::GetTypeForEventArg( char argType ) {
  1957. idTypeDef *type;
  1958. switch( argType ) {
  1959. case D_EVENT_INTEGER :
  1960. // this will get converted to int by the interpreter
  1961. type = &type_float;
  1962. break;
  1963. case D_EVENT_FLOAT :
  1964. type = &type_float;
  1965. break;
  1966. case D_EVENT_VECTOR :
  1967. type = &type_vector;
  1968. break;
  1969. case D_EVENT_STRING :
  1970. type = &type_string;
  1971. break;
  1972. case D_EVENT_ENTITY :
  1973. case D_EVENT_ENTITY_NULL :
  1974. type = &type_entity;
  1975. break;
  1976. case D_EVENT_VOID :
  1977. type = &type_void;
  1978. break;
  1979. case D_EVENT_TRACE :
  1980. // This data type isn't available from script
  1981. type = NULL;
  1982. break;
  1983. default:
  1984. // probably a typo
  1985. type = NULL;
  1986. break;
  1987. }
  1988. return type;
  1989. }
  1990. /*
  1991. ================
  1992. idCompiler::ParseEventDef
  1993. ================
  1994. */
  1995. void idCompiler::ParseEventDef( idTypeDef *returnType, const char *name ) {
  1996. const idTypeDef *expectedType;
  1997. idTypeDef *argType;
  1998. idTypeDef *type;
  1999. int i;
  2000. int num;
  2001. const char *format;
  2002. const idEventDef *ev;
  2003. idStr parmName;
  2004. ev = idEventDef::FindEvent( name );
  2005. if ( ev == NULL ) {
  2006. Error( "Unknown event '%s'", name );
  2007. return;
  2008. }
  2009. // set the return type
  2010. expectedType = GetTypeForEventArg( ev->GetReturnType() );
  2011. if ( expectedType == NULL ) {
  2012. Error( "Invalid return type '%c' in definition of '%s' event.", ev->GetReturnType(), name );
  2013. return;
  2014. }
  2015. if ( returnType != expectedType ) {
  2016. Error( "Return type doesn't match internal return type '%s'", expectedType->Name() );
  2017. }
  2018. idTypeDef newtype( ev_function, NULL, name, type_function.Size(), returnType );
  2019. ExpectToken( "(" );
  2020. format = ev->GetArgFormat();
  2021. num = strlen( format );
  2022. for( i = 0; i < num; i++ ) {
  2023. expectedType = GetTypeForEventArg( format[ i ] );
  2024. if ( expectedType == NULL || ( expectedType == &type_void ) ) {
  2025. Error( "Invalid parameter '%c' in definition of '%s' event.", format[ i ], name );
  2026. return;
  2027. }
  2028. argType = ParseType();
  2029. ParseName( parmName );
  2030. if ( argType != expectedType ) {
  2031. Error( "The type of parm %d ('%s') does not match the internal type '%s' in definition of '%s' event.",
  2032. i + 1, parmName.c_str(), expectedType->Name(), name );
  2033. }
  2034. newtype.AddFunctionParm( argType, "" );
  2035. if ( i < num - 1 ) {
  2036. if ( CheckToken( ")" ) ) {
  2037. Error( "Too few parameters for event definition. Internal definition has %d parameters.", num );
  2038. }
  2039. ExpectToken( "," );
  2040. }
  2041. }
  2042. if ( !CheckToken( ")" ) ) {
  2043. Error( "Too many parameters for event definition. Internal definition has %d parameters.", num );
  2044. }
  2045. ExpectToken( ";" );
  2046. type = gameLocal.program.FindType( name );
  2047. if ( type ) {
  2048. if ( !newtype.MatchesType( *type ) || ( type->def->value.functionPtr->eventdef != ev ) ) {
  2049. Error( "Type mismatch on redefinition of '%s'", name );
  2050. }
  2051. } else {
  2052. type = gameLocal.program.AllocType( newtype );
  2053. type->def = gameLocal.program.AllocDef( type, name, &def_namespace, true );
  2054. function_t &func = gameLocal.program.AllocFunction( type->def );
  2055. func.eventdef = ev;
  2056. func.parmSize.SetNum( num );
  2057. for( i = 0; i < num; i++ ) {
  2058. argType = newtype.GetParmType( i );
  2059. func.parmTotal += argType->Size();
  2060. func.parmSize[ i ] = argType->Size();
  2061. }
  2062. // mark the parms as local
  2063. func.locals = func.parmTotal;
  2064. }
  2065. }
  2066. /*
  2067. ================
  2068. idCompiler::ParseDefs
  2069. Called at the outer layer and when a local statement is hit
  2070. ================
  2071. */
  2072. void idCompiler::ParseDefs() {
  2073. idStr name;
  2074. idTypeDef *type;
  2075. idVarDef *def;
  2076. idVarDef *oldscope;
  2077. if ( CheckToken( ";" ) ) {
  2078. // skip semicolons, which are harmless and ok syntax
  2079. return;
  2080. }
  2081. type = ParseType();
  2082. if ( type == &type_scriptevent ) {
  2083. type = ParseType();
  2084. ParseName( name );
  2085. ParseEventDef( type, name );
  2086. return;
  2087. }
  2088. ParseName( name );
  2089. if ( type == &type_namespace ) {
  2090. def = gameLocal.program.GetDef( type, name, scope );
  2091. if ( !def ) {
  2092. def = gameLocal.program.AllocDef( type, name, scope, true );
  2093. }
  2094. ParseNamespace( def );
  2095. } else if ( CheckToken( "::" ) ) {
  2096. def = gameLocal.program.GetDef( NULL, name, scope );
  2097. if ( !def ) {
  2098. Error( "Unknown object name '%s'", name.c_str() );
  2099. }
  2100. ParseName( name );
  2101. oldscope = scope;
  2102. scope = def;
  2103. ExpectToken( "(" );
  2104. ParseFunctionDef( type, name.c_str() );
  2105. scope = oldscope;
  2106. } else if ( type == &type_object ) {
  2107. ParseObjectDef( name.c_str() );
  2108. } else if ( CheckToken( "(" ) ) { // check for a function prototype or declaraction
  2109. ParseFunctionDef( type, name.c_str() );
  2110. } else {
  2111. ParseVariableDef( type, name.c_str() );
  2112. while( CheckToken( "," ) ) {
  2113. ParseName( name );
  2114. ParseVariableDef( type, name.c_str() );
  2115. }
  2116. ExpectToken( ";" );
  2117. }
  2118. }
  2119. /*
  2120. ================
  2121. idCompiler::ParseNamespace
  2122. Parses anything within a namespace definition
  2123. ================
  2124. */
  2125. void idCompiler::ParseNamespace( idVarDef *newScope ) {
  2126. idVarDef *oldscope;
  2127. oldscope = scope;
  2128. if ( newScope != &def_namespace ) {
  2129. ExpectToken( "{" );
  2130. }
  2131. while( !eof ) {
  2132. scope = newScope;
  2133. callthread = false;
  2134. if ( ( newScope != &def_namespace ) && CheckToken( "}" ) ) {
  2135. break;
  2136. }
  2137. ParseDefs();
  2138. }
  2139. scope = oldscope;
  2140. }
  2141. /*
  2142. ============
  2143. idCompiler::CompileFile
  2144. compiles the 0 terminated text, adding definitions to the program structure
  2145. ============
  2146. */
  2147. void idCompiler::CompileFile( const char *text, const char *filename, bool toConsole ) {
  2148. idTimer compile_time;
  2149. bool error;
  2150. compile_time.Start();
  2151. scope = &def_namespace;
  2152. basetype = NULL;
  2153. callthread = false;
  2154. loopDepth = 0;
  2155. eof = false;
  2156. braceDepth = 0;
  2157. immediateType = NULL;
  2158. currentLineNumber = 0;
  2159. console = toConsole;
  2160. memset( &immediate, 0, sizeof( immediate ) );
  2161. parser.SetFlags( LEXFL_ALLOWMULTICHARLITERALS );
  2162. parser.LoadMemory( text, strlen( text ), filename );
  2163. parserPtr = &parser;
  2164. // unread tokens to include script defines
  2165. token = SCRIPT_DEFAULTDEFS;
  2166. token.type = TT_STRING;
  2167. token.subtype = token.Length();
  2168. token.line = token.linesCrossed = 0;
  2169. parser.UnreadToken( &token );
  2170. token = "include";
  2171. token.type = TT_NAME;
  2172. token.subtype = token.Length();
  2173. token.line = token.linesCrossed = 0;
  2174. parser.UnreadToken( &token );
  2175. token = "#";
  2176. token.type = TT_PUNCTUATION;
  2177. token.subtype = P_PRECOMP;
  2178. token.line = token.linesCrossed = 0;
  2179. parser.UnreadToken( &token );
  2180. // init the current token line to be the first line so that currentLineNumber is set correctly in NextToken
  2181. token.line = 1;
  2182. error = false;
  2183. try {
  2184. // read first token
  2185. NextToken();
  2186. while( !eof && !error ) {
  2187. // parse from global namespace
  2188. ParseNamespace( &def_namespace );
  2189. }
  2190. }
  2191. catch( idCompileError &err ) {
  2192. idStr error;
  2193. if ( console ) {
  2194. // don't print line number of an error if were calling script from the console using the "script" command
  2195. sprintf( error, "Error: %s\n", err.GetError() );
  2196. } else {
  2197. sprintf( error, "Error: file %s, line %d: %s\n", gameLocal.program.GetFilename( currentFileNumber ), currentLineNumber, err.GetError() );
  2198. }
  2199. parser.FreeSource();
  2200. throw idCompileError( error );
  2201. }
  2202. parser.FreeSource();
  2203. compile_time.Stop();
  2204. if ( !toConsole ) {
  2205. gameLocal.Printf( "Compiled '%s': %.1f ms\n", filename, compile_time.Milliseconds() );
  2206. }
  2207. }