as_parser.cpp 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2011 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. [email protected]
  22. */
  23. //
  24. // as_parser.cpp
  25. //
  26. // This class parses the script code and builds a tree for compilation
  27. //
  28. #include "as_config.h"
  29. #include "as_parser.h"
  30. #include "as_tokendef.h"
  31. #include "as_texts.h"
  32. #ifdef _MSC_VER
  33. #pragma warning(disable:4702) // unreachable code
  34. #endif
  35. BEGIN_AS_NAMESPACE
  36. asCParser::asCParser(asCBuilder *builder)
  37. {
  38. this->builder = builder;
  39. this->engine = builder->engine;
  40. script = 0;
  41. scriptNode = 0;
  42. checkValidTypes = false;
  43. isParsingAppInterface = false;
  44. }
  45. asCParser::~asCParser()
  46. {
  47. Reset();
  48. }
  49. void asCParser::Reset()
  50. {
  51. errorWhileParsing = false;
  52. isSyntaxError = false;
  53. checkValidTypes = false;
  54. isParsingAppInterface = false;
  55. sourcePos = 0;
  56. if( scriptNode )
  57. {
  58. scriptNode->Destroy(engine);
  59. }
  60. scriptNode = 0;
  61. script = 0;
  62. }
  63. asCScriptNode *asCParser::GetScriptNode()
  64. {
  65. return scriptNode;
  66. }
  67. int asCParser::ParseScript(asCScriptCode *script)
  68. {
  69. Reset();
  70. this->script = script;
  71. scriptNode = ParseScript();
  72. if( errorWhileParsing )
  73. return -1;
  74. return 0;
  75. }
  76. int asCParser::ParseFunctionDefinition(asCScriptCode *script)
  77. {
  78. Reset();
  79. // Set flag that permits ? as datatype for parameters
  80. isParsingAppInterface = true;
  81. this->script = script;
  82. scriptNode = ParseFunctionDefinition();
  83. // The declaration should end after the definition
  84. if( !isSyntaxError )
  85. {
  86. sToken t;
  87. GetToken(&t);
  88. if( t.type != ttEnd )
  89. {
  90. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)).AddressOf(), &t);
  91. return -1;
  92. }
  93. }
  94. if( errorWhileParsing )
  95. return -1;
  96. return 0;
  97. }
  98. int asCParser::ParseExpression(asCScriptCode *script)
  99. {
  100. Reset();
  101. this->script = script;
  102. scriptNode = ParseExpression();
  103. if( errorWhileParsing )
  104. return -1;
  105. return 0;
  106. }
  107. int asCParser::ParseDataType(asCScriptCode *script)
  108. {
  109. Reset();
  110. this->script = script;
  111. scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  112. scriptNode->AddChildLast(ParseType(true));
  113. if( isSyntaxError ) return -1;
  114. // The declaration should end after the type
  115. sToken t;
  116. GetToken(&t);
  117. if( t.type != ttEnd )
  118. {
  119. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)).AddressOf(), &t);
  120. return -1;
  121. }
  122. if( errorWhileParsing )
  123. return -1;
  124. return 0;
  125. }
  126. // Parse a template declaration: IDENTIFIER '<' 'class'? IDENTIFIER '>'
  127. int asCParser::ParseTemplateDecl(asCScriptCode *script)
  128. {
  129. Reset();
  130. this->script = script;
  131. scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
  132. scriptNode->AddChildLast(ParseIdentifier());
  133. if( isSyntaxError ) return -1;
  134. sToken t;
  135. GetToken(&t);
  136. if( t.type != ttLessThan )
  137. {
  138. Error(ExpectedToken(asCTokenizer::GetDefinition(ttLessThan)).AddressOf(), &t);
  139. return -1;
  140. }
  141. // The class token is optional
  142. GetToken(&t);
  143. if( t.type != ttClass )
  144. RewindTo(&t);
  145. scriptNode->AddChildLast(ParseIdentifier());
  146. if( isSyntaxError ) return -1;
  147. GetToken(&t);
  148. if( t.type != ttGreaterThan )
  149. {
  150. Error(ExpectedToken(asCTokenizer::GetDefinition(ttGreaterThan)).AddressOf(), &t);
  151. return -1;
  152. }
  153. GetToken(&t);
  154. if( t.type != ttEnd )
  155. {
  156. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)).AddressOf(), &t);
  157. return -1;
  158. }
  159. if( errorWhileParsing )
  160. return -1;
  161. return 0;
  162. }
  163. int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
  164. {
  165. Reset();
  166. this->script = script;
  167. scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
  168. scriptNode->AddChildLast(ParseType(true));
  169. if( isSyntaxError ) return -1;
  170. scriptNode->AddChildLast(ParseIdentifier());
  171. if( isSyntaxError ) return -1;
  172. // The declaration should end after the identifier
  173. sToken t;
  174. GetToken(&t);
  175. if( t.type != ttEnd )
  176. {
  177. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)).AddressOf(), &t);
  178. return -1;
  179. }
  180. return 0;
  181. }
  182. int asCParser::ParseVirtualPropertyDeclaration(asCScriptCode *script, bool asMethod)
  183. {
  184. Reset();
  185. this->script = script;
  186. scriptNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVirtualProperty);
  187. sToken t;
  188. scriptNode->AddChildLast(ParseType(true));
  189. if( isSyntaxError ) return -1;
  190. scriptNode->AddChildLast(ParseTypeMod(false));
  191. if( isSyntaxError ) return -1;
  192. scriptNode->AddChildLast(ParseIdentifier());
  193. if( isSyntaxError ) return -1;
  194. if( asMethod )
  195. {
  196. GetToken(&t);
  197. RewindTo(&t);
  198. if( t.type == ttConst )
  199. {
  200. scriptNode->AddChildLast(ParseToken(ttConst));
  201. if( isSyntaxError ) return -1;
  202. }
  203. }
  204. GetToken(&t);
  205. // The declaration should end after the identifier
  206. if( t.type != ttEnd )
  207. {
  208. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnd)).AddressOf(), &t);
  209. return -1;
  210. }
  211. return 0;
  212. }
  213. asCScriptNode *asCParser::ParseImport()
  214. {
  215. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snImport);
  216. sToken t;
  217. GetToken(&t);
  218. if( t.type != ttImport )
  219. {
  220. Error(ExpectedToken(asCTokenizer::GetDefinition(ttImport)).AddressOf(), &t);
  221. return node;
  222. }
  223. node->SetToken(&t);
  224. node->UpdateSourcePos(t.pos, t.length);
  225. node->AddChildLast(ParseFunctionDefinition());
  226. if( isSyntaxError ) return node;
  227. GetToken(&t);
  228. if( t.type != ttIdentifier )
  229. {
  230. Error(ExpectedToken(FROM_TOKEN).AddressOf(), &t);
  231. return node;
  232. }
  233. asCString str;
  234. str.Assign(&script->code[t.pos], t.length);
  235. if( str != FROM_TOKEN )
  236. {
  237. Error(ExpectedToken(FROM_TOKEN).AddressOf(), &t);
  238. return node;
  239. }
  240. node->UpdateSourcePos(t.pos, t.length);
  241. GetToken(&t);
  242. if( t.type != ttStringConstant )
  243. {
  244. Error(TXT_EXPECTED_STRING, &t);
  245. return node;
  246. }
  247. asCScriptNode *mod = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
  248. node->AddChildLast(mod);
  249. mod->SetToken(&t);
  250. mod->UpdateSourcePos(t.pos, t.length);
  251. GetToken(&t);
  252. if( t.type != ttEndStatement )
  253. {
  254. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEndStatement)).AddressOf(), &t);
  255. return node;
  256. }
  257. node->UpdateSourcePos(t.pos, t.length);
  258. return node;
  259. }
  260. asCScriptNode *asCParser::ParseFunctionDefinition()
  261. {
  262. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
  263. node->AddChildLast(ParseType(true));
  264. if( isSyntaxError ) return node;
  265. node->AddChildLast(ParseTypeMod(false));
  266. if( isSyntaxError ) return node;
  267. node->AddChildLast(ParseIdentifier());
  268. if( isSyntaxError ) return node;
  269. node->AddChildLast(ParseParameterList());
  270. if( isSyntaxError ) return node;
  271. // Parse an optional const after the function definition (used for object methods)
  272. sToken t1;
  273. GetToken(&t1);
  274. RewindTo(&t1);
  275. if( t1.type == ttConst )
  276. node->AddChildLast(ParseToken(ttConst));
  277. return node;
  278. }
  279. bool asCParser::IdentifierIs(const sToken &t, const char *str)
  280. {
  281. if( t.type != ttIdentifier )
  282. return false;
  283. return script->TokenEquals(t.pos, t.length, str);
  284. }
  285. asCScriptNode *asCParser::ParseScript()
  286. {
  287. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snScript);
  288. // Determine type of node
  289. sToken t1, t2;
  290. for(;;)
  291. {
  292. while( !isSyntaxError )
  293. {
  294. GetToken(&t1);
  295. GetToken(&t2);
  296. RewindTo(&t1);
  297. if( t1.type == ttImport )
  298. node->AddChildLast(ParseImport());
  299. else if( t1.type == ttEnum )
  300. node->AddChildLast(ParseEnumeration()); // Handle enumerations
  301. else if( t1.type == ttTypedef )
  302. node->AddChildLast(ParseTypedef()); // Handle primitive typedefs
  303. else if( t1.type == ttClass ||
  304. ((IdentifierIs(t1, SHARED_TOKEN) || IdentifierIs(t1, FINAL_TOKEN)) && t2.type == ttClass) ||
  305. (IdentifierIs(t1, SHARED_TOKEN) && IdentifierIs(t2, FINAL_TOKEN)) )
  306. node->AddChildLast(ParseClass());
  307. else if( t1.type == ttInterface || (t1.type == ttIdentifier && t2.type == ttInterface) )
  308. node->AddChildLast(ParseInterface());
  309. else if( t1.type == ttFuncDef )
  310. node->AddChildLast(ParseFuncDef());
  311. else if( t1.type == ttConst || IsDataType(t1) )
  312. {
  313. if( IsVirtualPropertyDecl() )
  314. node->AddChildLast(ParseVirtualPropertyDecl(false, false));
  315. else if( IsVarDecl() )
  316. node->AddChildLast(ParseGlobalVar());
  317. else
  318. node->AddChildLast(ParseFunction());
  319. }
  320. else if( t1.type == ttEndStatement )
  321. {
  322. // Ignore a semicolon by itself
  323. GetToken(&t1);
  324. }
  325. else if( t1.type == ttEnd )
  326. return node;
  327. else
  328. {
  329. asCString str;
  330. const char *t = asCTokenizer::GetDefinition(t1.type);
  331. if( t == 0 ) t = "<unknown token>";
  332. str.Format(TXT_UNEXPECTED_TOKEN_s, t);
  333. Error(str.AddressOf(), &t1);
  334. }
  335. }
  336. if( isSyntaxError )
  337. {
  338. // Search for either ';' or '{' or end
  339. GetToken(&t1);
  340. while( t1.type != ttEndStatement && t1.type != ttEnd &&
  341. t1.type != ttStartStatementBlock )
  342. GetToken(&t1);
  343. if( t1.type == ttStartStatementBlock )
  344. {
  345. // Find the end of the block and skip nested blocks
  346. int level = 1;
  347. while( level > 0 )
  348. {
  349. GetToken(&t1);
  350. if( t1.type == ttStartStatementBlock ) level++;
  351. if( t1.type == ttEndStatementBlock ) level--;
  352. if( t1.type == ttEnd ) break;
  353. }
  354. }
  355. isSyntaxError = false;
  356. }
  357. }
  358. UNREACHABLE_RETURN;
  359. }
  360. int asCParser::ParseStatementBlock(asCScriptCode *script, asCScriptNode *block)
  361. {
  362. Reset();
  363. // Tell the parser to validate the identifiers as valid types
  364. checkValidTypes = true;
  365. this->script = script;
  366. sourcePos = block->tokenPos;
  367. scriptNode = ParseStatementBlock();
  368. if( isSyntaxError || errorWhileParsing )
  369. return -1;
  370. return 0;
  371. }
  372. asCScriptNode *asCParser::ParseEnumeration()
  373. {
  374. asCScriptNode *ident;
  375. asCScriptNode *dataType;
  376. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snEnum);
  377. sToken token;
  378. // Check for enum
  379. GetToken(&token);
  380. if( token.type != ttEnum )
  381. {
  382. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEnum)).AddressOf(), &token);
  383. return node;
  384. }
  385. node->SetToken(&token);
  386. node->UpdateSourcePos(token.pos, token.length);
  387. // Get the identifier
  388. GetToken(&token);
  389. if(ttIdentifier != token.type)
  390. {
  391. Error(TXT_EXPECTED_IDENTIFIER, &token);
  392. return node;
  393. }
  394. dataType = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  395. node->AddChildLast(dataType);
  396. ident = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
  397. ident->SetToken(&token);
  398. ident->UpdateSourcePos(token.pos, token.length);
  399. dataType->AddChildLast(ident);
  400. // check for the start of the declaration block
  401. GetToken(&token);
  402. if( token.type != ttStartStatementBlock )
  403. {
  404. RewindTo(&token);
  405. Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)).AddressOf(), &token);
  406. return node;
  407. }
  408. while(ttEnd != token.type)
  409. {
  410. GetToken(&token);
  411. if( ttEndStatementBlock == token.type )
  412. {
  413. RewindTo(&token);
  414. break;
  415. }
  416. if(ttIdentifier != token.type)
  417. {
  418. Error(TXT_EXPECTED_IDENTIFIER, &token);
  419. return node;
  420. }
  421. // Add the enum element
  422. ident = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
  423. ident->SetToken(&token);
  424. ident->UpdateSourcePos(token.pos, token.length);
  425. node->AddChildLast(ident);
  426. GetToken(&token);
  427. if( token.type == ttAssignment )
  428. {
  429. asCScriptNode *tmp;
  430. RewindTo(&token);
  431. tmp = SuperficiallyParseGlobalVarInit();
  432. node->AddChildLast(tmp);
  433. if( isSyntaxError ) return node;
  434. GetToken(&token);
  435. }
  436. if(ttListSeparator != token.type)
  437. {
  438. RewindTo(&token);
  439. break;
  440. }
  441. }
  442. // check for the end of the declaration block
  443. GetToken(&token);
  444. if( token.type != ttEndStatementBlock )
  445. {
  446. RewindTo(&token);
  447. Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)).AddressOf(), &token);
  448. return node;
  449. }
  450. // Parse the declarations
  451. return node;
  452. }
  453. bool asCParser::CheckTemplateType(sToken &t)
  454. {
  455. // Is this a template type?
  456. asCString typeName;
  457. typeName.Assign(&script->code[t.pos], t.length);
  458. if( engine->IsTemplateType(typeName.AddressOf()) )
  459. {
  460. // Expect the sub type within < >
  461. GetToken(&t);
  462. if( t.type != ttLessThan )
  463. return false;
  464. // Now there must be a data type
  465. GetToken(&t);
  466. if( !IsDataType(t) )
  467. return false;
  468. if( !CheckTemplateType(t) )
  469. return false;
  470. GetToken(&t);
  471. // Is it a handle or array?
  472. while( t.type == ttHandle || t.type == ttOpenBracket )
  473. {
  474. if( t.type == ttOpenBracket )
  475. {
  476. GetToken(&t);
  477. if( t.type != ttCloseBracket )
  478. return false;
  479. }
  480. GetToken(&t);
  481. }
  482. // Accept >> and >>> tokens too. But then force the tokenizer to move
  483. // only 1 character ahead (thus splitting the token in two).
  484. if( script->code[t.pos] != '>' )
  485. return false;
  486. else if( t.length != 1 )
  487. {
  488. // We need to break the token, so that only the first character is parsed
  489. sToken t2 = t;
  490. t2.pos = t.pos + 1;
  491. RewindTo(&t2);
  492. }
  493. }
  494. return true;
  495. }
  496. bool asCParser::IsVarDecl()
  497. {
  498. // Set start point so that we can rewind
  499. sToken t;
  500. GetToken(&t);
  501. RewindTo(&t);
  502. // A class property decl can be preceded by 'private'
  503. sToken t1;
  504. GetToken(&t1);
  505. if( t1.type != ttPrivate )
  506. RewindTo(&t1);
  507. // A variable decl can start with a const
  508. GetToken(&t1);
  509. if( t1.type == ttConst )
  510. GetToken(&t1);
  511. // We don't validate if the identifier is an actual declared type at this moment
  512. // as it may wrongly identify the statement as a non-declaration if the user typed
  513. // the name incorrectly. The real type is validated in ParseDeclaration where a
  514. // proper error message can be given.
  515. if( !IsRealType(t1.type) && t1.type != ttIdentifier )
  516. {
  517. RewindTo(&t);
  518. return false;
  519. }
  520. if( !CheckTemplateType(t1) )
  521. {
  522. RewindTo(&t);
  523. return false;
  524. }
  525. // Object handles can be interleaved with the array brackets
  526. sToken t2;
  527. GetToken(&t2);
  528. while( t2.type == ttHandle || t2.type == ttOpenBracket )
  529. {
  530. if( t2.type == ttOpenBracket )
  531. {
  532. GetToken(&t2);
  533. if( t2.type != ttCloseBracket )
  534. {
  535. RewindTo(&t);
  536. return false;
  537. }
  538. }
  539. GetToken(&t2);
  540. }
  541. if( t2.type != ttIdentifier )
  542. {
  543. RewindTo(&t);
  544. return false;
  545. }
  546. GetToken(&t2);
  547. if( t2.type == ttEndStatement || t2.type == ttAssignment || t2.type == ttListSeparator )
  548. {
  549. RewindTo(&t);
  550. return true;
  551. }
  552. if( t2.type == ttOpenParanthesis )
  553. {
  554. // If the closing paranthesis is followed by a statement
  555. // block or end-of-file, then treat it as a function.
  556. while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
  557. GetToken(&t2);
  558. if( t2.type == ttEnd )
  559. return false;
  560. else
  561. {
  562. GetToken(&t1);
  563. RewindTo(&t);
  564. if( t1.type == ttStartStatementBlock || t1.type == ttEnd )
  565. return false;
  566. }
  567. RewindTo(&t);
  568. return true;
  569. }
  570. RewindTo(&t);
  571. return false;
  572. }
  573. bool asCParser::IsVirtualPropertyDecl()
  574. {
  575. // Set start point so that we can rewind
  576. sToken t;
  577. GetToken(&t);
  578. RewindTo(&t);
  579. // A class property decl can be preceded by 'private'
  580. sToken t1;
  581. GetToken(&t1);
  582. if( t1.type != ttPrivate )
  583. RewindTo(&t1);
  584. // A variable decl can start with a const
  585. GetToken(&t1);
  586. if( t1.type == ttConst )
  587. GetToken(&t1);
  588. // We don't validate if the identifier is an actual declared type at this moment
  589. // as it may wrongly identify the statement as a non-declaration if the user typed
  590. // the name incorrectly. The real type is validated in ParseDeclaration where a
  591. // proper error message can be given.
  592. if( !IsRealType(t1.type) && t1.type != ttIdentifier )
  593. {
  594. RewindTo(&t);
  595. return false;
  596. }
  597. if( !CheckTemplateType(t1) )
  598. {
  599. RewindTo(&t);
  600. return false;
  601. }
  602. // Object handles can be interleaved with the array brackets
  603. sToken t2;
  604. GetToken(&t2);
  605. while( t2.type == ttHandle || t2.type == ttOpenBracket )
  606. {
  607. if( t2.type == ttOpenBracket )
  608. {
  609. GetToken(&t2);
  610. if( t2.type != ttCloseBracket )
  611. {
  612. RewindTo(&t);
  613. return false;
  614. }
  615. }
  616. GetToken(&t2);
  617. }
  618. if( t2.type != ttIdentifier )
  619. {
  620. RewindTo(&t);
  621. return false;
  622. }
  623. GetToken(&t2);
  624. if( t2.type == ttStartStatementBlock )
  625. {
  626. RewindTo(&t);
  627. return true;
  628. }
  629. RewindTo(&t);
  630. return false;
  631. }
  632. bool asCParser::IsFuncDecl(bool isMethod)
  633. {
  634. // Set start point so that we can rewind
  635. sToken t;
  636. GetToken(&t);
  637. RewindTo(&t);
  638. // A class method decl can be preceded by 'private'
  639. if( isMethod )
  640. {
  641. sToken t1;
  642. GetToken(&t1);
  643. if( t1.type != ttPrivate )
  644. RewindTo(&t1);
  645. }
  646. // A class constructor starts with identifier followed by parenthesis
  647. // A class destructor starts with the ~ token
  648. if( isMethod )
  649. {
  650. sToken t1, t2;
  651. GetToken(&t1);
  652. GetToken(&t2);
  653. RewindTo(&t1);
  654. if( (t1.type == ttIdentifier && t2.type == ttOpenParanthesis) || t1.type == ttBitNot )
  655. {
  656. RewindTo(&t);
  657. return true;
  658. }
  659. }
  660. // A function decl can start with a const
  661. sToken t1;
  662. GetToken(&t1);
  663. if( t1.type == ttConst )
  664. GetToken(&t1);
  665. if( !IsDataType(t1) )
  666. {
  667. RewindTo(&t);
  668. return false;
  669. }
  670. if( !CheckTemplateType(t1) )
  671. {
  672. RewindTo(&t);
  673. return false;
  674. }
  675. // Object handles can be interleaved with the array brackets
  676. sToken t2;
  677. GetToken(&t2);
  678. while( t2.type == ttHandle || t2.type == ttOpenBracket )
  679. {
  680. if( t2.type == ttOpenBracket )
  681. {
  682. GetToken(&t2);
  683. if( t2.type != ttCloseBracket )
  684. {
  685. RewindTo(&t);
  686. return false;
  687. }
  688. }
  689. GetToken(&t2);
  690. }
  691. // There can be an ampersand if the function returns a reference
  692. if( t2.type == ttAmp )
  693. {
  694. RewindTo(&t);
  695. return true;
  696. }
  697. if( t2.type != ttIdentifier )
  698. {
  699. RewindTo(&t);
  700. return false;
  701. }
  702. GetToken(&t2);
  703. if( t2.type == ttOpenParanthesis )
  704. {
  705. // If the closing paranthesis is not followed by a
  706. // statement block then it is not a function.
  707. while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
  708. GetToken(&t2);
  709. if( t2.type == ttEnd )
  710. return false;
  711. else
  712. {
  713. if( isMethod )
  714. {
  715. // A class method can have a 'const' token after the parameter list
  716. GetToken(&t1);
  717. if( t1.type != ttConst )
  718. RewindTo(&t1);
  719. // A class method may also have any number of additional inheritance behavior specifiers
  720. for( ; ; )
  721. {
  722. GetToken(&t2);
  723. if( !IdentifierIs(t2, FINAL_TOKEN) && !IdentifierIs(t2, OVERRIDE_TOKEN) )
  724. {
  725. RewindTo(&t2);
  726. break;
  727. }
  728. }
  729. }
  730. GetToken(&t1);
  731. RewindTo(&t);
  732. if( t1.type == ttStartStatementBlock )
  733. return true;
  734. }
  735. RewindTo(&t);
  736. return false;
  737. }
  738. RewindTo(&t);
  739. return false;
  740. }
  741. asCScriptNode *asCParser::ParseFuncDef()
  742. {
  743. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFuncDef);
  744. sToken t1;
  745. GetToken(&t1);
  746. if( t1.type != ttFuncDef )
  747. {
  748. Error(asCTokenizer::GetDefinition(ttFuncDef), &t1);
  749. return node;
  750. }
  751. node->SetToken(&t1);
  752. node->AddChildLast(ParseType(true));
  753. if( isSyntaxError ) return node;
  754. node->AddChildLast(ParseTypeMod(false));
  755. if( isSyntaxError ) return node;
  756. node->AddChildLast(ParseIdentifier());
  757. if( isSyntaxError ) return node;
  758. node->AddChildLast(ParseParameterList());
  759. if( isSyntaxError ) return node;
  760. GetToken(&t1);
  761. if( t1.type != ttEndStatement )
  762. {
  763. Error(ExpectedToken(asCTokenizer::GetDefinition(ttEndStatement)).AddressOf(), &t1);
  764. return node;
  765. }
  766. node->UpdateSourcePos(t1.pos, t1.length);
  767. return node;
  768. }
  769. asCScriptNode *asCParser::ParseFunction(bool isMethod)
  770. {
  771. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
  772. sToken t1,t2;
  773. GetToken(&t1);
  774. GetToken(&t2);
  775. RewindTo(&t1);
  776. // A class method can start with private
  777. if( isMethod && t1.type == ttPrivate )
  778. {
  779. node->AddChildLast(ParseToken(ttPrivate));
  780. if( isSyntaxError ) return node;
  781. }
  782. // If it is a global function, or a method, except constructor and destructor, then the return type is parsed
  783. if( !isMethod || (t1.type != ttBitNot && t2.type != ttOpenParanthesis) )
  784. {
  785. node->AddChildLast(ParseType(true));
  786. if( isSyntaxError ) return node;
  787. node->AddChildLast(ParseTypeMod(false));
  788. if( isSyntaxError ) return node;
  789. }
  790. // If this is a class destructor then it starts with ~, and no return type is declared
  791. if( isMethod && t1.type == ttBitNot )
  792. {
  793. node->AddChildLast(ParseToken(ttBitNot));
  794. if( isSyntaxError ) return node;
  795. }
  796. node->AddChildLast(ParseIdentifier());
  797. if( isSyntaxError ) return node;
  798. node->AddChildLast(ParseParameterList());
  799. if( isSyntaxError ) return node;
  800. if( isMethod )
  801. {
  802. GetToken(&t1);
  803. RewindTo(&t1);
  804. // Is the method a const?
  805. if( t1.type == ttConst )
  806. node->AddChildLast(ParseToken(ttConst));
  807. ParseMethodOverrideBehaviors(node);
  808. if( isSyntaxError ) return node;
  809. }
  810. // We should just find the end of the statement block here. The statements
  811. // will be parsed on request by the compiler once it starts the compilation.
  812. node->AddChildLast(SuperficiallyParseStatementBlock());
  813. return node;
  814. }
  815. asCScriptNode *asCParser::ParseInterfaceMethod()
  816. {
  817. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunction);
  818. node->AddChildLast(ParseType(true));
  819. if( isSyntaxError ) return node;
  820. node->AddChildLast(ParseTypeMod(false));
  821. if( isSyntaxError ) return node;
  822. node->AddChildLast(ParseIdentifier());
  823. if( isSyntaxError ) return node;
  824. node->AddChildLast(ParseParameterList());
  825. if( isSyntaxError ) return node;
  826. // Parse an optional const after the method definition
  827. sToken t1;
  828. GetToken(&t1);
  829. RewindTo(&t1);
  830. if( t1.type == ttConst )
  831. node->AddChildLast(ParseToken(ttConst));
  832. GetToken(&t1);
  833. if( t1.type != ttEndStatement )
  834. {
  835. Error(ExpectedToken(";").AddressOf(), &t1);
  836. return node;
  837. }
  838. node->UpdateSourcePos(t1.pos, t1.length);
  839. return node;
  840. }
  841. asCScriptNode *asCParser::ParseVirtualPropertyDecl(bool isMethod, bool isInterface)
  842. {
  843. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVirtualProperty);
  844. sToken t1,t2;
  845. GetToken(&t1);
  846. GetToken(&t2);
  847. RewindTo(&t1);
  848. // A class method can start with private
  849. if( isMethod && t1.type == ttPrivate )
  850. {
  851. node->AddChildLast(ParseToken(ttPrivate));
  852. if( isSyntaxError ) return node;
  853. }
  854. node->AddChildLast(ParseType(true));
  855. if( isSyntaxError ) return node;
  856. node->AddChildLast(ParseTypeMod(false));
  857. if( isSyntaxError ) return node;
  858. node->AddChildLast(ParseIdentifier());
  859. if( isSyntaxError ) return node;
  860. GetToken(&t1);
  861. if( t1.type != ttStartStatementBlock )
  862. {
  863. Error(ExpectedToken("{").AddressOf(), &t1);
  864. return node;
  865. }
  866. for(;;)
  867. {
  868. GetToken(&t1);
  869. asCScriptNode *accessorNode = 0;
  870. if( IdentifierIs(t1, GET_TOKEN) || IdentifierIs(t1, SET_TOKEN) )
  871. {
  872. accessorNode = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVirtualProperty);
  873. node->AddChildLast(accessorNode);
  874. RewindTo(&t1);
  875. accessorNode->AddChildLast(ParseIdentifier());
  876. if( isMethod )
  877. {
  878. GetToken(&t1);
  879. RewindTo(&t1);
  880. if( t1.type == ttConst )
  881. accessorNode->AddChildLast(ParseToken(ttConst));
  882. if( !isInterface )
  883. {
  884. ParseMethodOverrideBehaviors(accessorNode);
  885. if( isSyntaxError ) return node;
  886. }
  887. }
  888. if( !isInterface )
  889. {
  890. GetToken(&t1);
  891. if( t1.type == ttStartStatementBlock )
  892. {
  893. RewindTo(&t1);
  894. accessorNode->AddChildLast(SuperficiallyParseStatementBlock());
  895. if( isSyntaxError ) return node;
  896. }
  897. else if( t1.type != ttEndStatement )
  898. {
  899. Error(ExpectedTokens(";", "{").AddressOf(), &t1);
  900. return node;
  901. }
  902. }
  903. else
  904. {
  905. GetToken(&t1);
  906. if( t1.type != ttEndStatement )
  907. {
  908. Error(ExpectedToken(";").AddressOf(), &t1);
  909. return node;
  910. }
  911. }
  912. }
  913. else if( t1.type == ttEndStatementBlock )
  914. {
  915. break;
  916. }
  917. else
  918. {
  919. const char *tokens[] = { GET_TOKEN, SET_TOKEN, asCTokenizer::GetDefinition(ttEndStatementBlock) };
  920. Error(ExpectedOneOf(tokens, 3).AddressOf(), &t1);
  921. return node;
  922. }
  923. }
  924. return node;
  925. }
  926. asCScriptNode *asCParser::ParseInterface()
  927. {
  928. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snInterface);
  929. sToken t;
  930. GetToken(&t);
  931. // Allow keyword 'shared' before 'interface'
  932. if( t.type == ttIdentifier )
  933. {
  934. asCString str;
  935. str.Assign(&script->code[t.pos], t.length);
  936. if( str != SHARED_TOKEN )
  937. {
  938. Error(ExpectedToken(SHARED_TOKEN).AddressOf(), &t);
  939. return node;
  940. }
  941. RewindTo(&t);
  942. node->AddChildLast(ParseIdentifier());
  943. GetToken(&t);
  944. }
  945. if( t.type != ttInterface )
  946. {
  947. Error(ExpectedToken("interface").AddressOf(), &t);
  948. return node;
  949. }
  950. node->SetToken(&t);
  951. node->AddChildLast(ParseIdentifier());
  952. GetToken(&t);
  953. if( t.type != ttStartStatementBlock )
  954. {
  955. Error(ExpectedToken("{").AddressOf(), &t);
  956. return node;
  957. }
  958. // Parse interface methods
  959. GetToken(&t);
  960. RewindTo(&t);
  961. while( t.type != ttEndStatementBlock && t.type != ttEnd )
  962. {
  963. if( IsVirtualPropertyDecl() )
  964. {
  965. node->AddChildLast(ParseVirtualPropertyDecl(true, true));
  966. }
  967. else
  968. {
  969. // Parse the method signature
  970. node->AddChildLast(ParseInterfaceMethod());
  971. }
  972. if( isSyntaxError ) return node;
  973. GetToken(&t);
  974. RewindTo(&t);
  975. }
  976. GetToken(&t);
  977. if( t.type != ttEndStatementBlock )
  978. {
  979. Error(ExpectedToken("}").AddressOf(), &t);
  980. return node;
  981. }
  982. node->UpdateSourcePos(t.pos, t.length);
  983. return node;
  984. }
  985. asCScriptNode *asCParser::ParseClass()
  986. {
  987. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snClass);
  988. sToken t;
  989. GetToken(&t);
  990. // Allow the keyword 'shared' before 'class'
  991. if( IdentifierIs(t, SHARED_TOKEN) )
  992. {
  993. RewindTo(&t);
  994. node->AddChildLast(ParseIdentifier());
  995. GetToken(&t);
  996. }
  997. if( IdentifierIs(t, FINAL_TOKEN) )
  998. {
  999. RewindTo(&t);
  1000. node->AddChildLast(ParseIdentifier());
  1001. GetToken(&t);
  1002. }
  1003. if( t.type != ttClass )
  1004. {
  1005. Error(ExpectedToken("class").AddressOf(), &t);
  1006. return node;
  1007. }
  1008. node->SetToken(&t);
  1009. if( engine->ep.allowImplicitHandleTypes )
  1010. {
  1011. // Parse 'implicit handle class' construct
  1012. GetToken(&t);
  1013. if ( t.type == ttHandle )
  1014. node->SetToken(&t);
  1015. else
  1016. RewindTo(&t);
  1017. }
  1018. node->AddChildLast(ParseIdentifier());
  1019. GetToken(&t);
  1020. // Optional list of interfaces that are being implemented and classes that are being inherited
  1021. if( t.type == ttColon )
  1022. {
  1023. node->AddChildLast(ParseIdentifier());
  1024. GetToken(&t);
  1025. while( t.type == ttListSeparator )
  1026. {
  1027. node->AddChildLast(ParseIdentifier());
  1028. GetToken(&t);
  1029. }
  1030. }
  1031. if( t.type != ttStartStatementBlock )
  1032. {
  1033. Error(ExpectedToken("{").AddressOf(), &t);
  1034. return node;
  1035. }
  1036. // Parse properties
  1037. GetToken(&t);
  1038. RewindTo(&t);
  1039. while( t.type != ttEndStatementBlock && t.type != ttEnd )
  1040. {
  1041. // Is it a property or a method?
  1042. if( IsFuncDecl(true) )
  1043. {
  1044. // Parse the method
  1045. node->AddChildLast(ParseFunction(true));
  1046. }
  1047. else if( IsVirtualPropertyDecl() )
  1048. {
  1049. node->AddChildLast(ParseVirtualPropertyDecl(true, false));
  1050. }
  1051. else if( IsVarDecl() )
  1052. {
  1053. // Parse a property declaration
  1054. asCScriptNode *prop = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
  1055. node->AddChildLast(prop);
  1056. // A variable declaration can be preceded by 'private'
  1057. if( t.type == ttPrivate )
  1058. prop->AddChildLast(ParseToken(ttPrivate));
  1059. prop->AddChildLast(ParseType(true));
  1060. if( isSyntaxError ) return node;
  1061. prop->AddChildLast(ParseIdentifier());
  1062. if( isSyntaxError ) return node;
  1063. GetToken(&t);
  1064. if( t.type != ttEndStatement )
  1065. {
  1066. Error(ExpectedToken(";").AddressOf(), &t);
  1067. return node;
  1068. }
  1069. prop->UpdateSourcePos(t.pos, t.length);
  1070. }
  1071. else
  1072. {
  1073. Error(TXT_EXPECTED_METHOD_OR_PROPERTY, &t);
  1074. return node;
  1075. }
  1076. GetToken(&t);
  1077. RewindTo(&t);
  1078. }
  1079. GetToken(&t);
  1080. if( t.type != ttEndStatementBlock )
  1081. {
  1082. Error(ExpectedToken("}").AddressOf(), &t);
  1083. return node;
  1084. }
  1085. node->UpdateSourcePos(t.pos, t.length);
  1086. return node;
  1087. }
  1088. asCScriptNode *asCParser::ParseGlobalVar()
  1089. {
  1090. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snGlobalVar);
  1091. // Parse data type
  1092. node->AddChildLast(ParseType(true));
  1093. if( isSyntaxError ) return node;
  1094. sToken t;
  1095. for(;;)
  1096. {
  1097. // Parse identifier
  1098. node->AddChildLast(ParseIdentifier());
  1099. if( isSyntaxError ) return node;
  1100. // Only superficially parse the initialization info for the variable
  1101. GetToken(&t);
  1102. RewindTo(&t);
  1103. if( t.type == ttAssignment || t.type == ttOpenParanthesis )
  1104. {
  1105. node->AddChildLast(SuperficiallyParseGlobalVarInit());
  1106. if( isSyntaxError ) return node;
  1107. }
  1108. // continue if list separator, else terminate with end statement
  1109. GetToken(&t);
  1110. if( t.type == ttListSeparator )
  1111. continue;
  1112. else if( t.type == ttEndStatement )
  1113. {
  1114. node->UpdateSourcePos(t.pos, t.length);
  1115. return node;
  1116. }
  1117. else
  1118. {
  1119. Error(ExpectedTokens(",", ";").AddressOf(), &t);
  1120. return node;
  1121. }
  1122. }
  1123. UNREACHABLE_RETURN;
  1124. }
  1125. int asCParser::ParseGlobalVarInit(asCScriptCode *script, asCScriptNode *init)
  1126. {
  1127. Reset();
  1128. // Tell the parser to validate the identifiers as valid types
  1129. checkValidTypes = true;
  1130. this->script = script;
  1131. sourcePos = init->tokenPos;
  1132. // If next token is assignment, parse expression
  1133. sToken t;
  1134. GetToken(&t);
  1135. if( t.type == ttAssignment )
  1136. {
  1137. GetToken(&t);
  1138. RewindTo(&t);
  1139. if( t.type == ttStartStatementBlock )
  1140. scriptNode = ParseInitList();
  1141. else
  1142. scriptNode = ParseAssignment();
  1143. }
  1144. else if( t.type == ttOpenParanthesis )
  1145. {
  1146. RewindTo(&t);
  1147. scriptNode = ParseArgList();
  1148. }
  1149. else
  1150. {
  1151. int tokens[] = {ttAssignment, ttOpenParanthesis};
  1152. Error(ExpectedOneOf(tokens, 2).AddressOf(), &t);
  1153. }
  1154. if( isSyntaxError || errorWhileParsing )
  1155. return -1;
  1156. return 0;
  1157. }
  1158. asCScriptNode *asCParser::SuperficiallyParseGlobalVarInit()
  1159. {
  1160. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snAssignment);
  1161. sToken t;
  1162. GetToken(&t);
  1163. node->UpdateSourcePos(t.pos, t.length);
  1164. if( t.type == ttAssignment )
  1165. {
  1166. GetToken(&t);
  1167. if( t.type == ttStartStatementBlock )
  1168. {
  1169. // Find the end of the initialization list
  1170. int indent = 1;
  1171. while( indent )
  1172. {
  1173. GetToken(&t);
  1174. if( t.type == ttStartStatementBlock )
  1175. indent++;
  1176. else if( t.type == ttEndStatementBlock )
  1177. indent--;
  1178. else if( t.type == ttEnd )
  1179. {
  1180. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  1181. break;
  1182. }
  1183. }
  1184. }
  1185. else
  1186. {
  1187. // Find the end of the expression
  1188. int indent = 0;
  1189. while( indent || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
  1190. {
  1191. if( t.type == ttOpenParanthesis )
  1192. indent++;
  1193. else if( t.type == ttCloseParanthesis )
  1194. indent--;
  1195. else if( t.type == ttEnd )
  1196. {
  1197. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  1198. break;
  1199. }
  1200. GetToken(&t);
  1201. }
  1202. // Rewind so that the next token read is the list separator, end statement, or end statement block
  1203. RewindTo(&t);
  1204. }
  1205. }
  1206. else if( t.type == ttOpenParanthesis )
  1207. {
  1208. // Find the end of the argument list
  1209. int indent = 1;
  1210. while( indent )
  1211. {
  1212. GetToken(&t);
  1213. if( t.type == ttOpenParanthesis )
  1214. indent++;
  1215. else if( t.type == ttCloseParanthesis )
  1216. indent--;
  1217. else if( t.type == ttEnd )
  1218. {
  1219. Error(TXT_UNEXPECTED_END_OF_FILE, &t);
  1220. break;
  1221. }
  1222. }
  1223. }
  1224. else
  1225. {
  1226. int tokens[] = {ttAssignment, ttOpenParanthesis};
  1227. Error(ExpectedOneOf(tokens, 2).AddressOf(), &t);
  1228. }
  1229. return node;
  1230. }
  1231. asCScriptNode *asCParser::ParseTypeMod(bool isParam)
  1232. {
  1233. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  1234. sToken t;
  1235. // Parse possible & token
  1236. GetToken(&t);
  1237. RewindTo(&t);
  1238. if( t.type == ttAmp )
  1239. {
  1240. node->AddChildLast(ParseToken(ttAmp));
  1241. if( isSyntaxError ) return node;
  1242. if( isParam )
  1243. {
  1244. GetToken(&t);
  1245. RewindTo(&t);
  1246. if( t.type == ttIn || t.type == ttOut || t.type == ttInOut )
  1247. {
  1248. int tokens[3] = {ttIn, ttOut, ttInOut};
  1249. node->AddChildLast(ParseOneOf(tokens, 3));
  1250. }
  1251. }
  1252. }
  1253. // Parse possible + token
  1254. GetToken(&t);
  1255. RewindTo(&t);
  1256. if( t.type == ttPlus )
  1257. {
  1258. node->AddChildLast(ParseToken(ttPlus));
  1259. if( isSyntaxError ) return node;
  1260. }
  1261. return node;
  1262. }
  1263. asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType)
  1264. {
  1265. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  1266. sToken t;
  1267. if( allowConst )
  1268. {
  1269. GetToken(&t);
  1270. RewindTo(&t);
  1271. if( t.type == ttConst )
  1272. {
  1273. node->AddChildLast(ParseToken(ttConst));
  1274. if( isSyntaxError ) return node;
  1275. }
  1276. }
  1277. node->AddChildLast(ParseDataType(allowVariableType));
  1278. // If the datatype is a template type, then parse the subtype within the < >
  1279. asCScriptNode *type = node->lastChild;
  1280. asCString typeName;
  1281. typeName.Assign(&script->code[type->tokenPos], type->tokenLength);
  1282. if( engine->IsTemplateType(typeName.AddressOf()) )
  1283. {
  1284. GetToken(&t);
  1285. if( t.type != ttLessThan )
  1286. {
  1287. Error(ExpectedToken(asCTokenizer::GetDefinition(ttLessThan)).AddressOf(), &t);
  1288. return node;
  1289. }
  1290. node->AddChildLast(ParseType(true, false));
  1291. if( isSyntaxError ) return node;
  1292. // Accept >> and >>> tokens too. But then force the tokenizer to move
  1293. // only 1 character ahead (thus splitting the token in two).
  1294. GetToken(&t);
  1295. if( script->code[t.pos] != '>' )
  1296. {
  1297. Error(ExpectedToken(asCTokenizer::GetDefinition(ttGreaterThan)).AddressOf(), &t);
  1298. return node;
  1299. }
  1300. else
  1301. {
  1302. // Break the token so that only the first > is parsed
  1303. sToken t2 = t;
  1304. t2.pos = t.pos + 1;
  1305. RewindTo(&t2);
  1306. }
  1307. }
  1308. // Parse [] and @
  1309. GetToken(&t);
  1310. RewindTo(&t);
  1311. while( t.type == ttOpenBracket || t.type == ttHandle)
  1312. {
  1313. if( t.type == ttOpenBracket )
  1314. {
  1315. node->AddChildLast(ParseToken(ttOpenBracket));
  1316. if( isSyntaxError ) return node;
  1317. GetToken(&t);
  1318. if( t.type != ttCloseBracket )
  1319. {
  1320. Error(ExpectedToken("]").AddressOf(), &t);
  1321. return node;
  1322. }
  1323. }
  1324. else
  1325. {
  1326. node->AddChildLast(ParseToken(ttHandle));
  1327. if( isSyntaxError ) return node;
  1328. }
  1329. GetToken(&t);
  1330. RewindTo(&t);
  1331. }
  1332. return node;
  1333. }
  1334. asCScriptNode *asCParser::ParseToken(int token)
  1335. {
  1336. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
  1337. sToken t1;
  1338. GetToken(&t1);
  1339. if( t1.type != token )
  1340. {
  1341. Error(ExpectedToken(asCTokenizer::GetDefinition(token)).AddressOf(), &t1);
  1342. return node;
  1343. }
  1344. node->SetToken(&t1);
  1345. node->UpdateSourcePos(t1.pos, t1.length);
  1346. return node;
  1347. }
  1348. asCScriptNode *asCParser::ParseOneOf(int *tokens, int count)
  1349. {
  1350. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined);
  1351. sToken t1;
  1352. GetToken(&t1);
  1353. int n;
  1354. for( n = 0; n < count; n++ )
  1355. {
  1356. if( tokens[n] == t1.type )
  1357. break;
  1358. }
  1359. if( n == count )
  1360. {
  1361. Error(ExpectedOneOf(tokens, count).AddressOf(), &t1);
  1362. return node;
  1363. }
  1364. node->SetToken(&t1);
  1365. node->UpdateSourcePos(t1.pos, t1.length);
  1366. return node;
  1367. }
  1368. asCScriptNode *asCParser::ParseDataType(bool allowVariableType)
  1369. {
  1370. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  1371. sToken t1;
  1372. GetToken(&t1);
  1373. if( !IsDataType(t1) && !(allowVariableType && t1.type == ttQuestion) )
  1374. {
  1375. if( t1.type == ttIdentifier )
  1376. {
  1377. asCString errMsg, Identifier;
  1378. Identifier.Assign(&script->code[t1.pos], t1.length);
  1379. errMsg.Format(TXT_IDENTIFIER_s_NOT_DATA_TYPE, Identifier.AddressOf());
  1380. Error(errMsg.AddressOf(), &t1);
  1381. }
  1382. else
  1383. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  1384. return node;
  1385. }
  1386. node->SetToken(&t1);
  1387. node->UpdateSourcePos(t1.pos, t1.length);
  1388. return node;
  1389. }
  1390. asCScriptNode *asCParser::ParseRealType()
  1391. {
  1392. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDataType);
  1393. sToken t1;
  1394. GetToken(&t1);
  1395. if( !IsRealType(t1.type) )
  1396. {
  1397. Error(TXT_EXPECTED_DATA_TYPE, &t1);
  1398. return node;
  1399. }
  1400. node->SetToken(&t1);
  1401. node->UpdateSourcePos(t1.pos, t1.length);
  1402. return node;
  1403. }
  1404. asCScriptNode *asCParser::ParseIdentifier()
  1405. {
  1406. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIdentifier);
  1407. sToken t1;
  1408. GetToken(&t1);
  1409. if( t1.type != ttIdentifier )
  1410. {
  1411. Error(TXT_EXPECTED_IDENTIFIER, &t1);
  1412. return node;
  1413. }
  1414. node->SetToken(&t1);
  1415. node->UpdateSourcePos(t1.pos, t1.length);
  1416. return node;
  1417. }
  1418. asCScriptNode *asCParser::ParseCast()
  1419. {
  1420. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCast);
  1421. sToken t1;
  1422. GetToken(&t1);
  1423. if( t1.type != ttCast )
  1424. {
  1425. Error(ExpectedToken("cast").AddressOf(), &t1);
  1426. return node;
  1427. }
  1428. node->UpdateSourcePos(t1.pos, t1.length);
  1429. GetToken(&t1);
  1430. if( t1.type != ttLessThan )
  1431. {
  1432. Error(ExpectedToken("<").AddressOf(), &t1);
  1433. return node;
  1434. }
  1435. // Parse the data type
  1436. node->AddChildLast(ParseType(true));
  1437. if( isSyntaxError ) return node;
  1438. node->AddChildLast(ParseTypeMod(false));
  1439. if( isSyntaxError ) return node;
  1440. GetToken(&t1);
  1441. if( t1.type != ttGreaterThan )
  1442. {
  1443. Error(ExpectedToken(">").AddressOf(), &t1);
  1444. return node;
  1445. }
  1446. GetToken(&t1);
  1447. if( t1.type != ttOpenParanthesis )
  1448. {
  1449. Error(ExpectedToken("(").AddressOf(), &t1);
  1450. return node;
  1451. }
  1452. node->AddChildLast(ParseAssignment());
  1453. if( isSyntaxError ) return node;
  1454. GetToken(&t1);
  1455. if( t1.type != ttCloseParanthesis )
  1456. {
  1457. Error(ExpectedToken(")").AddressOf(), &t1);
  1458. return node;
  1459. }
  1460. node->UpdateSourcePos(t1.pos, t1.length);
  1461. return node;
  1462. }
  1463. asCScriptNode *asCParser::ParseParameterList()
  1464. {
  1465. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snParameterList);
  1466. sToken t1;
  1467. GetToken(&t1);
  1468. if( t1.type != ttOpenParanthesis )
  1469. {
  1470. Error(ExpectedToken("(").AddressOf(), &t1);
  1471. return node;
  1472. }
  1473. node->UpdateSourcePos(t1.pos, t1.length);
  1474. GetToken(&t1);
  1475. if( t1.type == ttCloseParanthesis )
  1476. {
  1477. node->UpdateSourcePos(t1.pos, t1.length);
  1478. // Statement block is finished
  1479. return node;
  1480. }
  1481. else
  1482. {
  1483. // If the parameter list is just (void) then the void token should be ignored
  1484. if( t1.type == ttVoid )
  1485. {
  1486. sToken t2;
  1487. GetToken(&t2);
  1488. if( t2.type == ttCloseParanthesis )
  1489. {
  1490. node->UpdateSourcePos(t2.pos, t2.length);
  1491. return node;
  1492. }
  1493. }
  1494. RewindTo(&t1);
  1495. for(;;)
  1496. {
  1497. // Parse data type
  1498. node->AddChildLast(ParseType(true, isParsingAppInterface));
  1499. if( isSyntaxError ) return node;
  1500. node->AddChildLast(ParseTypeMod(true));
  1501. if( isSyntaxError ) return node;
  1502. // Parse identifier
  1503. GetToken(&t1);
  1504. if( t1.type == ttIdentifier )
  1505. {
  1506. RewindTo(&t1);
  1507. node->AddChildLast(ParseIdentifier());
  1508. if( isSyntaxError ) return node;
  1509. GetToken(&t1);
  1510. // Parse the expression for the default arg
  1511. if( t1.type == ttAssignment )
  1512. {
  1513. node->AddChildLast(ParseExpression());
  1514. if( isSyntaxError ) return node;
  1515. GetToken(&t1);
  1516. }
  1517. }
  1518. // Check if list continues
  1519. if( t1.type == ttCloseParanthesis )
  1520. {
  1521. node->UpdateSourcePos(t1.pos, t1.length);
  1522. return node;
  1523. }
  1524. else if( t1.type == ttListSeparator )
  1525. continue;
  1526. else
  1527. {
  1528. Error(ExpectedTokens(")", ",").AddressOf(), &t1);
  1529. return node;
  1530. }
  1531. }
  1532. }
  1533. UNREACHABLE_RETURN;
  1534. }
  1535. asCScriptNode *asCParser::ParseExprValue()
  1536. {
  1537. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprValue);
  1538. sToken t1, t2;
  1539. GetToken(&t1);
  1540. GetToken(&t2);
  1541. RewindTo(&t1);
  1542. // TODO: namespace: Datatypes can be defined in namespaces, thus types too must allow scope prefix
  1543. if( IsDataType(t1) && (t2.type == ttOpenParanthesis ||
  1544. t2.type == ttLessThan ||
  1545. t2.type == ttOpenBracket) )
  1546. node->AddChildLast(ParseConstructCall());
  1547. else if( t1.type == ttIdentifier || t1.type == ttScope )
  1548. {
  1549. if( IsFunctionCall() )
  1550. node->AddChildLast(ParseFunctionCall());
  1551. else
  1552. node->AddChildLast(ParseVariableAccess());
  1553. }
  1554. else if( t1.type == ttCast )
  1555. node->AddChildLast(ParseCast());
  1556. else if( IsConstant(t1.type) )
  1557. node->AddChildLast(ParseConstant());
  1558. else if( t1.type == ttOpenParanthesis )
  1559. {
  1560. GetToken(&t1);
  1561. node->UpdateSourcePos(t1.pos, t1.length);
  1562. node->AddChildLast(ParseAssignment());
  1563. if( isSyntaxError ) return node;
  1564. GetToken(&t1);
  1565. if( t1.type != ttCloseParanthesis )
  1566. Error(ExpectedToken(")").AddressOf(), &t1);
  1567. node->UpdateSourcePos(t1.pos, t1.length);
  1568. }
  1569. else
  1570. Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1);
  1571. return node;
  1572. }
  1573. asCScriptNode *asCParser::ParseConstant()
  1574. {
  1575. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
  1576. sToken t;
  1577. GetToken(&t);
  1578. if( !IsConstant(t.type) )
  1579. {
  1580. Error(TXT_EXPECTED_CONSTANT, &t);
  1581. return node;
  1582. }
  1583. node->SetToken(&t);
  1584. node->UpdateSourcePos(t.pos, t.length);
  1585. // We want to gather a list of string constants to concatenate as children
  1586. if( t.type == ttStringConstant || t.type == ttMultilineStringConstant || t.type == ttHeredocStringConstant )
  1587. RewindTo(&t);
  1588. while( t.type == ttStringConstant || t.type == ttMultilineStringConstant || t.type == ttHeredocStringConstant )
  1589. {
  1590. node->AddChildLast(ParseStringConstant());
  1591. GetToken(&t);
  1592. RewindTo(&t);
  1593. }
  1594. return node;
  1595. }
  1596. asCScriptNode *asCParser::ParseStringConstant()
  1597. {
  1598. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstant);
  1599. sToken t;
  1600. GetToken(&t);
  1601. if( t.type != ttStringConstant && t.type != ttMultilineStringConstant && t.type != ttHeredocStringConstant )
  1602. {
  1603. Error(TXT_EXPECTED_STRING, &t);
  1604. return node;
  1605. }
  1606. node->SetToken(&t);
  1607. node->UpdateSourcePos(t.pos, t.length);
  1608. return node;
  1609. }
  1610. asCScriptNode *asCParser::ParseFunctionCall()
  1611. {
  1612. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFunctionCall);
  1613. // Parse scope prefix
  1614. sToken t1, t2;
  1615. GetToken(&t1);
  1616. if( t1.type == ttScope )
  1617. {
  1618. RewindTo(&t1);
  1619. node->AddChildLast(ParseToken(ttScope));
  1620. GetToken(&t1);
  1621. }
  1622. GetToken(&t2);
  1623. while( t1.type == ttIdentifier && t2.type == ttScope )
  1624. {
  1625. RewindTo(&t1);
  1626. node->AddChildLast(ParseIdentifier());
  1627. node->AddChildLast(ParseToken(ttScope));
  1628. GetToken(&t1);
  1629. GetToken(&t2);
  1630. }
  1631. RewindTo(&t1);
  1632. // Parse the function name followed by the argument list
  1633. node->AddChildLast(ParseIdentifier());
  1634. if( isSyntaxError ) return node;
  1635. node->AddChildLast(ParseArgList());
  1636. return node;
  1637. }
  1638. asCScriptNode *asCParser::ParseVariableAccess()
  1639. {
  1640. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snVariableAccess);
  1641. // Parse scope prefix
  1642. sToken t1, t2;
  1643. GetToken(&t1);
  1644. if( t1.type == ttScope )
  1645. {
  1646. RewindTo(&t1);
  1647. node->AddChildLast(ParseToken(ttScope));
  1648. GetToken(&t1);
  1649. }
  1650. GetToken(&t2);
  1651. while( t1.type == ttIdentifier && t2.type == ttScope )
  1652. {
  1653. RewindTo(&t1);
  1654. node->AddChildLast(ParseIdentifier());
  1655. node->AddChildLast(ParseToken(ttScope));
  1656. GetToken(&t1);
  1657. GetToken(&t2);
  1658. }
  1659. RewindTo(&t1);
  1660. // Parse the variable name
  1661. node->AddChildLast(ParseIdentifier());
  1662. return node;
  1663. }
  1664. asCScriptNode *asCParser::ParseConstructCall()
  1665. {
  1666. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snConstructCall);
  1667. node->AddChildLast(ParseType(false));
  1668. if( isSyntaxError ) return node;
  1669. node->AddChildLast(ParseArgList());
  1670. return node;
  1671. }
  1672. asCScriptNode *asCParser::ParseArgList()
  1673. {
  1674. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snArgList);
  1675. sToken t1;
  1676. GetToken(&t1);
  1677. if( t1.type != ttOpenParanthesis )
  1678. {
  1679. Error(ExpectedToken("(").AddressOf(), &t1);
  1680. return node;
  1681. }
  1682. node->UpdateSourcePos(t1.pos, t1.length);
  1683. GetToken(&t1);
  1684. if( t1.type == ttCloseParanthesis )
  1685. {
  1686. node->UpdateSourcePos(t1.pos, t1.length);
  1687. // Statement block is finished
  1688. return node;
  1689. }
  1690. else
  1691. {
  1692. RewindTo(&t1);
  1693. for(;;)
  1694. {
  1695. node->AddChildLast(ParseAssignment());
  1696. if( isSyntaxError ) return node;
  1697. // Check if list continues
  1698. GetToken(&t1);
  1699. if( t1.type == ttCloseParanthesis )
  1700. {
  1701. node->UpdateSourcePos(t1.pos, t1.length);
  1702. return node;
  1703. }
  1704. else if( t1.type == ttListSeparator )
  1705. continue;
  1706. else
  1707. {
  1708. Error(ExpectedTokens(")", ",").AddressOf(), &t1);
  1709. return node;
  1710. }
  1711. }
  1712. }
  1713. return 0;
  1714. }
  1715. asCScriptNode *asCParser::SuperficiallyParseStatementBlock()
  1716. {
  1717. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snStatementBlock);
  1718. // This function will only superficially parse the statement block in order to find the end of it
  1719. sToken t1;
  1720. GetToken(&t1);
  1721. if( t1.type != ttStartStatementBlock )
  1722. {
  1723. Error(ExpectedToken("{").AddressOf(), &t1);
  1724. return node;
  1725. }
  1726. node->UpdateSourcePos(t1.pos, t1.length);
  1727. int level = 1;
  1728. while( level > 0 && !isSyntaxError )
  1729. {
  1730. GetToken(&t1);
  1731. if( t1.type == ttEndStatementBlock )
  1732. level--;
  1733. else if( t1.type == ttStartStatementBlock )
  1734. level++;
  1735. else if( t1.type == ttEnd )
  1736. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  1737. }
  1738. node->UpdateSourcePos(t1.pos, t1.length);
  1739. return node;
  1740. }
  1741. asCScriptNode *asCParser::ParseStatementBlock()
  1742. {
  1743. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snStatementBlock);
  1744. sToken t1;
  1745. GetToken(&t1);
  1746. if( t1.type != ttStartStatementBlock )
  1747. {
  1748. Error(ExpectedToken("{").AddressOf(), &t1);
  1749. return node;
  1750. }
  1751. node->UpdateSourcePos(t1.pos, t1.length);
  1752. for(;;)
  1753. {
  1754. while( !isSyntaxError )
  1755. {
  1756. GetToken(&t1);
  1757. if( t1.type == ttEndStatementBlock )
  1758. {
  1759. node->UpdateSourcePos(t1.pos, t1.length);
  1760. // Statement block is finished
  1761. return node;
  1762. }
  1763. else
  1764. {
  1765. RewindTo(&t1);
  1766. if( IsVarDecl() )
  1767. node->AddChildLast(ParseDeclaration());
  1768. else
  1769. node->AddChildLast(ParseStatement());
  1770. }
  1771. }
  1772. if( isSyntaxError )
  1773. {
  1774. // Search for either ';', '{', '}', or end
  1775. GetToken(&t1);
  1776. while( t1.type != ttEndStatement && t1.type != ttEnd &&
  1777. t1.type != ttStartStatementBlock && t1.type != ttEndStatementBlock )
  1778. {
  1779. GetToken(&t1);
  1780. }
  1781. // Skip this statement block
  1782. if( t1.type == ttStartStatementBlock )
  1783. {
  1784. // Find the end of the block and skip nested blocks
  1785. int level = 1;
  1786. while( level > 0 )
  1787. {
  1788. GetToken(&t1);
  1789. if( t1.type == ttStartStatementBlock ) level++;
  1790. if( t1.type == ttEndStatementBlock ) level--;
  1791. if( t1.type == ttEnd ) break;
  1792. }
  1793. }
  1794. else if( t1.type == ttEndStatementBlock )
  1795. {
  1796. RewindTo(&t1);
  1797. }
  1798. else if( t1.type == ttEnd )
  1799. {
  1800. Error(TXT_UNEXPECTED_END_OF_FILE, &t1);
  1801. return node;
  1802. }
  1803. isSyntaxError = false;
  1804. }
  1805. }
  1806. UNREACHABLE_RETURN;
  1807. }
  1808. asCScriptNode *asCParser::ParseInitList()
  1809. {
  1810. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snInitList);
  1811. sToken t1;
  1812. GetToken(&t1);
  1813. if( t1.type != ttStartStatementBlock )
  1814. {
  1815. Error(ExpectedToken("{").AddressOf(), &t1);
  1816. return node;
  1817. }
  1818. node->UpdateSourcePos(t1.pos, t1.length);
  1819. GetToken(&t1);
  1820. if( t1.type == ttEndStatementBlock )
  1821. {
  1822. node->UpdateSourcePos(t1.pos, t1.length);
  1823. // Statement block is finished
  1824. return node;
  1825. }
  1826. else
  1827. {
  1828. RewindTo(&t1);
  1829. for(;;)
  1830. {
  1831. GetToken(&t1);
  1832. if( t1.type == ttListSeparator )
  1833. {
  1834. // No expression
  1835. node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
  1836. GetToken(&t1);
  1837. if( t1.type == ttEndStatementBlock )
  1838. {
  1839. // No expression
  1840. node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
  1841. node->UpdateSourcePos(t1.pos, t1.length);
  1842. return node;
  1843. }
  1844. RewindTo(&t1);
  1845. }
  1846. else if( t1.type == ttEndStatementBlock )
  1847. {
  1848. // No expression
  1849. node->AddChildLast(new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snUndefined));
  1850. node->UpdateSourcePos(t1.pos, t1.length);
  1851. // Statement block is finished
  1852. return node;
  1853. }
  1854. else if( t1.type == ttStartStatementBlock )
  1855. {
  1856. RewindTo(&t1);
  1857. node->AddChildLast(ParseInitList());
  1858. if( isSyntaxError ) return node;
  1859. GetToken(&t1);
  1860. if( t1.type == ttListSeparator )
  1861. continue;
  1862. else if( t1.type == ttEndStatementBlock )
  1863. {
  1864. node->UpdateSourcePos(t1.pos, t1.length);
  1865. // Statement block is finished
  1866. return node;
  1867. }
  1868. else
  1869. {
  1870. Error(ExpectedTokens("}", ",").AddressOf(), &t1);
  1871. return node;
  1872. }
  1873. }
  1874. else
  1875. {
  1876. RewindTo(&t1);
  1877. node->AddChildLast(ParseAssignment());
  1878. if( isSyntaxError ) return node;
  1879. GetToken(&t1);
  1880. if( t1.type == ttListSeparator )
  1881. continue;
  1882. else if( t1.type == ttEndStatementBlock )
  1883. {
  1884. node->UpdateSourcePos(t1.pos, t1.length);
  1885. // Statement block is finished
  1886. return node;
  1887. }
  1888. else
  1889. {
  1890. Error(ExpectedTokens("}", ",").AddressOf(), &t1);
  1891. return node;
  1892. }
  1893. }
  1894. }
  1895. }
  1896. UNREACHABLE_RETURN;
  1897. }
  1898. bool asCParser::IsFunctionCall()
  1899. {
  1900. sToken s;
  1901. sToken t1, t2;
  1902. GetToken(&s);
  1903. t1 = s;
  1904. // A function call may be prefixed with scope resolution
  1905. if( t1.type == ttScope )
  1906. GetToken(&t1);
  1907. GetToken(&t2);
  1908. while( t1.type == ttIdentifier && t2.type == ttScope )
  1909. {
  1910. GetToken(&t1);
  1911. GetToken(&t2);
  1912. }
  1913. // A function call starts with an identifier followed by an argument list
  1914. if( t1.type != ttIdentifier || IsDataType(t1) )
  1915. {
  1916. RewindTo(&s);
  1917. return false;
  1918. }
  1919. if( t2.type == ttOpenParanthesis )
  1920. {
  1921. RewindTo(&s);
  1922. return true;
  1923. }
  1924. RewindTo(&s);
  1925. return false;
  1926. }
  1927. asCScriptNode *asCParser::ParseDeclaration()
  1928. {
  1929. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDeclaration);
  1930. // Parse data type
  1931. node->AddChildLast(ParseType(true));
  1932. if( isSyntaxError ) return node;
  1933. sToken t;
  1934. for(;;)
  1935. {
  1936. // Parse identifier
  1937. node->AddChildLast(ParseIdentifier());
  1938. if( isSyntaxError ) return node;
  1939. // If next token is assignment, parse expression
  1940. GetToken(&t);
  1941. if( t.type == ttOpenParanthesis )
  1942. {
  1943. RewindTo(&t);
  1944. node->AddChildLast(ParseArgList());
  1945. if( isSyntaxError ) return node;
  1946. }
  1947. else if( t.type == ttAssignment )
  1948. {
  1949. GetToken(&t);
  1950. RewindTo(&t);
  1951. if( t.type == ttStartStatementBlock )
  1952. {
  1953. node->AddChildLast(ParseInitList());
  1954. if( isSyntaxError ) return node;
  1955. }
  1956. else
  1957. {
  1958. node->AddChildLast(ParseAssignment());
  1959. if( isSyntaxError ) return node;
  1960. }
  1961. }
  1962. else
  1963. RewindTo(&t);
  1964. // continue if list separator, else terminate with end statement
  1965. GetToken(&t);
  1966. if( t.type == ttListSeparator )
  1967. continue;
  1968. else if( t.type == ttEndStatement )
  1969. {
  1970. node->UpdateSourcePos(t.pos, t.length);
  1971. return node;
  1972. }
  1973. else
  1974. {
  1975. Error(ExpectedTokens(",", ";").AddressOf(), &t);
  1976. return node;
  1977. }
  1978. }
  1979. UNREACHABLE_RETURN;
  1980. }
  1981. asCScriptNode *asCParser::ParseStatement()
  1982. {
  1983. sToken t1;
  1984. GetToken(&t1);
  1985. RewindTo(&t1);
  1986. if( t1.type == ttIf )
  1987. return ParseIf();
  1988. else if( t1.type == ttFor )
  1989. return ParseFor();
  1990. else if( t1.type == ttWhile )
  1991. return ParseWhile();
  1992. else if( t1.type == ttReturn )
  1993. return ParseReturn();
  1994. else if( t1.type == ttStartStatementBlock )
  1995. return ParseStatementBlock();
  1996. else if( t1.type == ttBreak )
  1997. return ParseBreak();
  1998. else if( t1.type == ttContinue )
  1999. return ParseContinue();
  2000. else if( t1.type == ttDo )
  2001. return ParseDoWhile();
  2002. else if( t1.type == ttSwitch )
  2003. return ParseSwitch();
  2004. else
  2005. return ParseExpressionStatement();
  2006. }
  2007. asCScriptNode *asCParser::ParseExpressionStatement()
  2008. {
  2009. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpressionStatement);
  2010. sToken t;
  2011. GetToken(&t);
  2012. if( t.type == ttEndStatement )
  2013. {
  2014. node->UpdateSourcePos(t.pos, t.length);
  2015. return node;
  2016. }
  2017. RewindTo(&t);
  2018. node->AddChildLast(ParseAssignment());
  2019. if( isSyntaxError ) return node;
  2020. GetToken(&t);
  2021. if( t.type != ttEndStatement )
  2022. {
  2023. Error(ExpectedToken(";").AddressOf(), &t);
  2024. return node;
  2025. }
  2026. node->UpdateSourcePos(t.pos, t.length);
  2027. return node;
  2028. }
  2029. asCScriptNode *asCParser::ParseSwitch()
  2030. {
  2031. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snSwitch);
  2032. sToken t;
  2033. GetToken(&t);
  2034. if( t.type != ttSwitch )
  2035. {
  2036. Error(ExpectedToken("switch").AddressOf(), &t);
  2037. return node;
  2038. }
  2039. node->UpdateSourcePos(t.pos, t.length);
  2040. GetToken(&t);
  2041. if( t.type != ttOpenParanthesis )
  2042. {
  2043. Error(ExpectedToken("(").AddressOf(), &t);
  2044. return node;
  2045. }
  2046. node->AddChildLast(ParseAssignment());
  2047. if( isSyntaxError ) return node;
  2048. GetToken(&t);
  2049. if( t.type != ttCloseParanthesis )
  2050. {
  2051. Error(ExpectedToken(")").AddressOf(), &t);
  2052. return node;
  2053. }
  2054. GetToken(&t);
  2055. if( t.type != ttStartStatementBlock )
  2056. {
  2057. Error(ExpectedToken("{").AddressOf(), &t);
  2058. return node;
  2059. }
  2060. while( !isSyntaxError )
  2061. {
  2062. GetToken(&t);
  2063. if( t.type == ttEndStatementBlock || t.type == ttDefault)
  2064. break;
  2065. RewindTo(&t);
  2066. if( t.type != ttCase )
  2067. {
  2068. Error(ExpectedToken("case").AddressOf(), &t);
  2069. return node;
  2070. }
  2071. node->AddChildLast(ParseCase());
  2072. if( isSyntaxError ) return node;
  2073. }
  2074. if( t.type == ttDefault)
  2075. {
  2076. RewindTo(&t);
  2077. node->AddChildLast(ParseCase());
  2078. if( isSyntaxError ) return node;
  2079. GetToken(&t);
  2080. }
  2081. if( t.type != ttEndStatementBlock )
  2082. {
  2083. Error(ExpectedToken("}").AddressOf(), &t);
  2084. return node;
  2085. }
  2086. return node;
  2087. }
  2088. asCScriptNode *asCParser::ParseCase()
  2089. {
  2090. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCase);
  2091. sToken t;
  2092. GetToken(&t);
  2093. if( t.type != ttCase && t.type != ttDefault )
  2094. {
  2095. Error(ExpectedTokens("case", "default").AddressOf(), &t);
  2096. return node;
  2097. }
  2098. node->UpdateSourcePos(t.pos, t.length);
  2099. if(t.type == ttCase)
  2100. {
  2101. node->AddChildLast(ParseExpression());
  2102. }
  2103. GetToken(&t);
  2104. if( t.type != ttColon )
  2105. {
  2106. Error(ExpectedToken(":").AddressOf(), &t);
  2107. return node;
  2108. }
  2109. // Parse statements until we find either of }, case, default, and break
  2110. GetToken(&t);
  2111. RewindTo(&t);
  2112. while( t.type != ttCase &&
  2113. t.type != ttDefault &&
  2114. t.type != ttEndStatementBlock &&
  2115. t.type != ttBreak )
  2116. {
  2117. if( IsVarDecl() )
  2118. // Variable declarations are not allowed, but we parse it anyway to give a good error message
  2119. node->AddChildLast(ParseDeclaration());
  2120. else
  2121. node->AddChildLast(ParseStatement());
  2122. if( isSyntaxError ) return node;
  2123. GetToken(&t);
  2124. RewindTo(&t);
  2125. }
  2126. // If the case was ended with a break statement, add it to the node
  2127. if( t.type == ttBreak )
  2128. node->AddChildLast(ParseBreak());
  2129. return node;
  2130. }
  2131. asCScriptNode *asCParser::ParseIf()
  2132. {
  2133. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snIf);
  2134. sToken t;
  2135. GetToken(&t);
  2136. if( t.type != ttIf )
  2137. {
  2138. Error(ExpectedToken("if").AddressOf(), &t);
  2139. return node;
  2140. }
  2141. node->UpdateSourcePos(t.pos, t.length);
  2142. GetToken(&t);
  2143. if( t.type != ttOpenParanthesis )
  2144. {
  2145. Error(ExpectedToken("(").AddressOf(), &t);
  2146. return node;
  2147. }
  2148. node->AddChildLast(ParseAssignment());
  2149. if( isSyntaxError ) return node;
  2150. GetToken(&t);
  2151. if( t.type != ttCloseParanthesis )
  2152. {
  2153. Error(ExpectedToken(")").AddressOf(), &t);
  2154. return node;
  2155. }
  2156. node->AddChildLast(ParseStatement());
  2157. if( isSyntaxError ) return node;
  2158. GetToken(&t);
  2159. if( t.type != ttElse )
  2160. {
  2161. // No else statement return already
  2162. RewindTo(&t);
  2163. return node;
  2164. }
  2165. node->AddChildLast(ParseStatement());
  2166. return node;
  2167. }
  2168. asCScriptNode *asCParser::ParseFor()
  2169. {
  2170. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snFor);
  2171. sToken t;
  2172. GetToken(&t);
  2173. if( t.type != ttFor )
  2174. {
  2175. Error(ExpectedToken("for").AddressOf(), &t);
  2176. return node;
  2177. }
  2178. node->UpdateSourcePos(t.pos, t.length);
  2179. GetToken(&t);
  2180. if( t.type != ttOpenParanthesis )
  2181. {
  2182. Error(ExpectedToken("(").AddressOf(), &t);
  2183. return node;
  2184. }
  2185. if( IsVarDecl() )
  2186. node->AddChildLast(ParseDeclaration());
  2187. else
  2188. node->AddChildLast(ParseExpressionStatement());
  2189. if( isSyntaxError ) return node;
  2190. node->AddChildLast(ParseExpressionStatement());
  2191. if( isSyntaxError ) return node;
  2192. GetToken(&t);
  2193. if( t.type != ttCloseParanthesis )
  2194. {
  2195. RewindTo(&t);
  2196. asCScriptNode *n = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpressionStatement);
  2197. node->AddChildLast(n);
  2198. n->AddChildLast(ParseAssignment());
  2199. if( isSyntaxError ) return node;
  2200. GetToken(&t);
  2201. if( t.type != ttCloseParanthesis )
  2202. {
  2203. Error(ExpectedToken(")").AddressOf(), &t);
  2204. return node;
  2205. }
  2206. }
  2207. node->AddChildLast(ParseStatement());
  2208. return node;
  2209. }
  2210. asCScriptNode *asCParser::ParseWhile()
  2211. {
  2212. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snWhile);
  2213. sToken t;
  2214. GetToken(&t);
  2215. if( t.type != ttWhile )
  2216. {
  2217. Error(ExpectedToken("while").AddressOf(), &t);
  2218. return node;
  2219. }
  2220. node->UpdateSourcePos(t.pos, t.length);
  2221. GetToken(&t);
  2222. if( t.type != ttOpenParanthesis )
  2223. {
  2224. Error(ExpectedToken("(").AddressOf(), &t);
  2225. return node;
  2226. }
  2227. node->AddChildLast(ParseAssignment());
  2228. if( isSyntaxError ) return node;
  2229. GetToken(&t);
  2230. if( t.type != ttCloseParanthesis )
  2231. {
  2232. Error(ExpectedToken(")").AddressOf(), &t);
  2233. return node;
  2234. }
  2235. node->AddChildLast(ParseStatement());
  2236. return node;
  2237. }
  2238. asCScriptNode *asCParser::ParseDoWhile()
  2239. {
  2240. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snDoWhile);
  2241. sToken t;
  2242. GetToken(&t);
  2243. if( t.type != ttDo )
  2244. {
  2245. Error(ExpectedToken("do").AddressOf(), &t);
  2246. return node;
  2247. }
  2248. node->UpdateSourcePos(t.pos, t.length);
  2249. node->AddChildLast(ParseStatement());
  2250. if( isSyntaxError ) return node;
  2251. GetToken(&t);
  2252. if( t.type != ttWhile )
  2253. {
  2254. Error(ExpectedToken("while").AddressOf(), &t);
  2255. return node;
  2256. }
  2257. GetToken(&t);
  2258. if( t.type != ttOpenParanthesis )
  2259. {
  2260. Error(ExpectedToken("(").AddressOf(), &t);
  2261. return node;
  2262. }
  2263. node->AddChildLast(ParseAssignment());
  2264. if( isSyntaxError ) return node;
  2265. GetToken(&t);
  2266. if( t.type != ttCloseParanthesis )
  2267. {
  2268. Error(ExpectedToken(")").AddressOf(), &t);
  2269. return node;
  2270. }
  2271. GetToken(&t);
  2272. if( t.type != ttEndStatement )
  2273. {
  2274. Error(ExpectedToken(";").AddressOf(), &t);
  2275. return node;
  2276. }
  2277. node->UpdateSourcePos(t.pos, t.length);
  2278. return node;
  2279. }
  2280. asCScriptNode *asCParser::ParseReturn()
  2281. {
  2282. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snReturn);
  2283. sToken t;
  2284. GetToken(&t);
  2285. if( t.type != ttReturn )
  2286. {
  2287. Error(ExpectedToken("return").AddressOf(), &t);
  2288. return node;
  2289. }
  2290. node->UpdateSourcePos(t.pos, t.length);
  2291. GetToken(&t);
  2292. if( t.type == ttEndStatement )
  2293. {
  2294. node->UpdateSourcePos(t.pos, t.length);
  2295. return node;
  2296. }
  2297. RewindTo(&t);
  2298. node->AddChildLast(ParseAssignment());
  2299. if( isSyntaxError ) return node;
  2300. GetToken(&t);
  2301. if( t.type != ttEndStatement )
  2302. {
  2303. Error(ExpectedToken(";").AddressOf(), &t);
  2304. return node;
  2305. }
  2306. node->UpdateSourcePos(t.pos, t.length);
  2307. return node;
  2308. }
  2309. asCScriptNode *asCParser::ParseBreak()
  2310. {
  2311. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snBreak);
  2312. sToken t;
  2313. GetToken(&t);
  2314. if( t.type != ttBreak )
  2315. {
  2316. Error(ExpectedToken("break").AddressOf(), &t);
  2317. return node;
  2318. }
  2319. node->UpdateSourcePos(t.pos, t.length);
  2320. GetToken(&t);
  2321. if( t.type != ttEndStatement )
  2322. Error(ExpectedToken(";").AddressOf(), &t);
  2323. node->UpdateSourcePos(t.pos, t.length);
  2324. return node;
  2325. }
  2326. asCScriptNode *asCParser::ParseContinue()
  2327. {
  2328. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snContinue);
  2329. sToken t;
  2330. GetToken(&t);
  2331. if( t.type != ttContinue )
  2332. {
  2333. Error(ExpectedToken("continue").AddressOf(), &t);
  2334. return node;
  2335. }
  2336. node->UpdateSourcePos(t.pos, t.length);
  2337. GetToken(&t);
  2338. if( t.type != ttEndStatement )
  2339. Error(ExpectedToken(";").AddressOf(), &t);
  2340. node->UpdateSourcePos(t.pos, t.length);
  2341. return node;
  2342. }
  2343. asCScriptNode *asCParser::ParseAssignment()
  2344. {
  2345. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snAssignment);
  2346. node->AddChildLast(ParseCondition());
  2347. if( isSyntaxError ) return node;
  2348. sToken t;
  2349. GetToken(&t);
  2350. RewindTo(&t);
  2351. if( IsAssignOperator(t.type) )
  2352. {
  2353. node->AddChildLast(ParseAssignOperator());
  2354. if( isSyntaxError ) return node;
  2355. node->AddChildLast(ParseAssignment());
  2356. if( isSyntaxError ) return node;
  2357. }
  2358. return node;
  2359. }
  2360. asCScriptNode *asCParser::ParseCondition()
  2361. {
  2362. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snCondition);
  2363. node->AddChildLast(ParseExpression());
  2364. if( isSyntaxError ) return node;
  2365. sToken t;
  2366. GetToken(&t);
  2367. if( t.type == ttQuestion )
  2368. {
  2369. node->AddChildLast(ParseAssignment());
  2370. if( isSyntaxError ) return node;
  2371. GetToken(&t);
  2372. if( t.type != ttColon )
  2373. {
  2374. Error(ExpectedToken(":").AddressOf(), &t);
  2375. return node;
  2376. }
  2377. node->AddChildLast(ParseAssignment());
  2378. if( isSyntaxError ) return node;
  2379. }
  2380. else
  2381. RewindTo(&t);
  2382. return node;
  2383. }
  2384. asCScriptNode *asCParser::ParseExpression()
  2385. {
  2386. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExpression);
  2387. node->AddChildLast(ParseExprTerm());
  2388. if( isSyntaxError ) return node;
  2389. for(;;)
  2390. {
  2391. sToken t;
  2392. GetToken(&t);
  2393. RewindTo(&t);
  2394. if( !IsOperator(t.type) )
  2395. return node;
  2396. node->AddChildLast(ParseExprOperator());
  2397. if( isSyntaxError ) return node;
  2398. node->AddChildLast(ParseExprTerm());
  2399. if( isSyntaxError ) return node;
  2400. }
  2401. UNREACHABLE_RETURN;
  2402. }
  2403. asCScriptNode *asCParser::ParseExprTerm()
  2404. {
  2405. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprTerm);
  2406. for(;;)
  2407. {
  2408. sToken t;
  2409. GetToken(&t);
  2410. RewindTo(&t);
  2411. if( !IsPreOperator(t.type) )
  2412. break;
  2413. node->AddChildLast(ParseExprPreOp());
  2414. if( isSyntaxError ) return node;
  2415. }
  2416. node->AddChildLast(ParseExprValue());
  2417. if( isSyntaxError ) return node;
  2418. for(;;)
  2419. {
  2420. sToken t;
  2421. GetToken(&t);
  2422. RewindTo(&t);
  2423. if( !IsPostOperator(t.type) )
  2424. return node;
  2425. node->AddChildLast(ParseExprPostOp());
  2426. if( isSyntaxError ) return node;
  2427. }
  2428. UNREACHABLE_RETURN;
  2429. }
  2430. asCScriptNode *asCParser::ParseExprPreOp()
  2431. {
  2432. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprPreOp);
  2433. sToken t;
  2434. GetToken(&t);
  2435. if( !IsPreOperator(t.type) )
  2436. {
  2437. Error(TXT_EXPECTED_PRE_OPERATOR, &t);
  2438. return node;
  2439. }
  2440. node->SetToken(&t);
  2441. node->UpdateSourcePos(t.pos, t.length);
  2442. return node;
  2443. }
  2444. asCScriptNode *asCParser::ParseExprPostOp()
  2445. {
  2446. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprPostOp);
  2447. sToken t;
  2448. GetToken(&t);
  2449. if( !IsPostOperator(t.type) )
  2450. {
  2451. Error(TXT_EXPECTED_POST_OPERATOR, &t);
  2452. return node;
  2453. }
  2454. node->SetToken(&t);
  2455. node->UpdateSourcePos(t.pos, t.length);
  2456. if( t.type == ttDot )
  2457. {
  2458. sToken t1, t2;
  2459. GetToken(&t1);
  2460. GetToken(&t2);
  2461. RewindTo(&t1);
  2462. if( t2.type == ttOpenParanthesis )
  2463. node->AddChildLast(ParseFunctionCall());
  2464. else
  2465. node->AddChildLast(ParseIdentifier());
  2466. }
  2467. else if( t.type == ttOpenBracket )
  2468. {
  2469. node->AddChildLast(ParseAssignment());
  2470. GetToken(&t);
  2471. if( t.type != ttCloseBracket )
  2472. {
  2473. Error(ExpectedToken("]").AddressOf(), &t);
  2474. return node;
  2475. }
  2476. node->UpdateSourcePos(t.pos, t.length);
  2477. }
  2478. return node;
  2479. }
  2480. asCScriptNode *asCParser::ParseExprOperator()
  2481. {
  2482. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprOperator);
  2483. sToken t;
  2484. GetToken(&t);
  2485. if( !IsOperator(t.type) )
  2486. {
  2487. Error(TXT_EXPECTED_OPERATOR, &t);
  2488. return node;
  2489. }
  2490. node->SetToken(&t);
  2491. node->UpdateSourcePos(t.pos, t.length);
  2492. return node;
  2493. }
  2494. asCScriptNode *asCParser::ParseAssignOperator()
  2495. {
  2496. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snExprOperator);
  2497. sToken t;
  2498. GetToken(&t);
  2499. if( !IsAssignOperator(t.type) )
  2500. {
  2501. Error(TXT_EXPECTED_OPERATOR, &t);
  2502. return node;
  2503. }
  2504. node->SetToken(&t);
  2505. node->UpdateSourcePos(t.pos, t.length);
  2506. return node;
  2507. }
  2508. void asCParser::GetToken(sToken *token)
  2509. {
  2510. size_t sourceLength = script->codeLength;
  2511. do
  2512. {
  2513. if( sourcePos >= sourceLength )
  2514. {
  2515. token->type = ttEnd;
  2516. token->length = 0;
  2517. }
  2518. else
  2519. token->type = engine->tok.GetToken(&script->code[sourcePos], sourceLength - sourcePos, &token->length);
  2520. token->pos = sourcePos;
  2521. // Update state
  2522. sourcePos += token->length;
  2523. }
  2524. // Filter out whitespace and comments
  2525. while( token->type == ttWhiteSpace ||
  2526. token->type == ttOnelineComment ||
  2527. token->type == ttMultilineComment );
  2528. }
  2529. void asCParser::RewindTo(const sToken *token)
  2530. {
  2531. sourcePos = token->pos;
  2532. }
  2533. void asCParser::Error(const char *text, sToken *token)
  2534. {
  2535. RewindTo(token);
  2536. isSyntaxError = true;
  2537. errorWhileParsing = true;
  2538. int row, col;
  2539. script->ConvertPosToRowCol(token->pos, &row, &col);
  2540. if( builder )
  2541. builder->WriteError(script->name.AddressOf(), text, row, col);
  2542. }
  2543. bool asCParser::IsRealType(int tokenType)
  2544. {
  2545. if( tokenType == ttVoid ||
  2546. tokenType == ttInt ||
  2547. tokenType == ttInt8 ||
  2548. tokenType == ttInt16 ||
  2549. tokenType == ttInt64 ||
  2550. tokenType == ttUInt ||
  2551. tokenType == ttUInt8 ||
  2552. tokenType == ttUInt16 ||
  2553. tokenType == ttUInt64 ||
  2554. tokenType == ttFloat ||
  2555. tokenType == ttBool ||
  2556. tokenType == ttDouble )
  2557. return true;
  2558. return false;
  2559. }
  2560. bool asCParser::IsDataType(const sToken &token)
  2561. {
  2562. if( token.type == ttIdentifier )
  2563. {
  2564. if( checkValidTypes )
  2565. {
  2566. // Check if this is a registered type
  2567. asCString str;
  2568. str.Assign(&script->code[token.pos], token.length);
  2569. if( !builder->GetObjectType(str.AddressOf()) && !builder->GetFuncDef(str.AddressOf()) )
  2570. return false;
  2571. }
  2572. return true;
  2573. }
  2574. if( IsRealType(token.type) )
  2575. return true;
  2576. return false;
  2577. }
  2578. bool asCParser::IsOperator(int tokenType)
  2579. {
  2580. if( tokenType == ttPlus ||
  2581. tokenType == ttMinus ||
  2582. tokenType == ttStar ||
  2583. tokenType == ttSlash ||
  2584. tokenType == ttPercent ||
  2585. tokenType == ttAnd ||
  2586. tokenType == ttOr ||
  2587. tokenType == ttXor ||
  2588. tokenType == ttEqual ||
  2589. tokenType == ttNotEqual ||
  2590. tokenType == ttLessThan ||
  2591. tokenType == ttLessThanOrEqual ||
  2592. tokenType == ttGreaterThan ||
  2593. tokenType == ttGreaterThanOrEqual ||
  2594. tokenType == ttAmp ||
  2595. tokenType == ttBitOr ||
  2596. tokenType == ttBitXor ||
  2597. tokenType == ttBitShiftLeft ||
  2598. tokenType == ttBitShiftRight ||
  2599. tokenType == ttBitShiftRightArith ||
  2600. tokenType == ttIs ||
  2601. tokenType == ttNotIs )
  2602. return true;
  2603. return false;
  2604. }
  2605. bool asCParser::IsAssignOperator(int tokenType)
  2606. {
  2607. if( tokenType == ttAssignment ||
  2608. tokenType == ttAddAssign ||
  2609. tokenType == ttSubAssign ||
  2610. tokenType == ttMulAssign ||
  2611. tokenType == ttDivAssign ||
  2612. tokenType == ttModAssign ||
  2613. tokenType == ttAndAssign ||
  2614. tokenType == ttOrAssign ||
  2615. tokenType == ttXorAssign ||
  2616. tokenType == ttShiftLeftAssign ||
  2617. tokenType == ttShiftRightLAssign ||
  2618. tokenType == ttShiftRightAAssign )
  2619. return true;
  2620. return false;
  2621. }
  2622. bool asCParser::IsPreOperator(int tokenType)
  2623. {
  2624. if( tokenType == ttMinus ||
  2625. tokenType == ttPlus ||
  2626. tokenType == ttNot ||
  2627. tokenType == ttInc ||
  2628. tokenType == ttDec ||
  2629. tokenType == ttBitNot ||
  2630. tokenType == ttHandle )
  2631. return true;
  2632. return false;
  2633. }
  2634. bool asCParser::IsPostOperator(int tokenType)
  2635. {
  2636. if( tokenType == ttInc ||
  2637. tokenType == ttDec ||
  2638. tokenType == ttDot ||
  2639. tokenType == ttOpenBracket )
  2640. return true;
  2641. return false;
  2642. }
  2643. bool asCParser::IsConstant(int tokenType)
  2644. {
  2645. if( tokenType == ttIntConstant ||
  2646. tokenType == ttFloatConstant ||
  2647. tokenType == ttDoubleConstant ||
  2648. tokenType == ttStringConstant ||
  2649. tokenType == ttMultilineStringConstant ||
  2650. tokenType == ttHeredocStringConstant ||
  2651. tokenType == ttTrue ||
  2652. tokenType == ttFalse ||
  2653. tokenType == ttBitsConstant ||
  2654. tokenType == ttNull )
  2655. return true;
  2656. return false;
  2657. }
  2658. asCString asCParser::ExpectedToken(const char *token)
  2659. {
  2660. asCString str;
  2661. str.Format(TXT_EXPECTED_s, token);
  2662. return str;
  2663. }
  2664. asCString asCParser::ExpectedTokens(const char *t1, const char *t2)
  2665. {
  2666. asCString str;
  2667. str.Format(TXT_EXPECTED_s_OR_s, t1, t2);
  2668. return str;
  2669. }
  2670. asCString asCParser::ExpectedOneOf(int *tokens, int count)
  2671. {
  2672. asCString str;
  2673. str = TXT_EXPECTED_ONE_OF;
  2674. for( int n = 0; n < count; n++ )
  2675. {
  2676. str += asCTokenizer::GetDefinition(tokens[n]);
  2677. if( n < count-1 )
  2678. str += ", ";
  2679. }
  2680. return str;
  2681. }
  2682. asCString asCParser::ExpectedOneOf(const char **tokens, int count)
  2683. {
  2684. asCString str;
  2685. str = TXT_EXPECTED_ONE_OF;
  2686. for( int n = 0; n < count; n++ )
  2687. {
  2688. str += tokens[n];
  2689. if( n < count-1 )
  2690. str += ", ";
  2691. }
  2692. return str;
  2693. }
  2694. // TODO: typedef: Typedefs should accept complex types as well
  2695. asCScriptNode *asCParser::ParseTypedef()
  2696. {
  2697. // Create the typedef node
  2698. asCScriptNode *node = new(engine->memoryMgr.AllocScriptNode()) asCScriptNode(snTypedef);
  2699. sToken token;
  2700. GetToken(&token);
  2701. if( token.type != ttTypedef)
  2702. {
  2703. Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)).AddressOf(), &token);
  2704. return node;
  2705. }
  2706. node->SetToken(&token);
  2707. node->UpdateSourcePos(token.pos, token.length);
  2708. // Parse the base type
  2709. GetToken(&token);
  2710. RewindTo(&token);
  2711. // Make sure it is a primitive type (except ttVoid)
  2712. if( !IsRealType(token.type) || token.type == ttVoid )
  2713. {
  2714. asCString str;
  2715. str.Format(TXT_UNEXPECTED_TOKEN_s, asCTokenizer::GetDefinition(token.type));
  2716. Error(str.AddressOf(), &token);
  2717. return node;
  2718. }
  2719. node->AddChildLast(ParseRealType());
  2720. node->AddChildLast(ParseIdentifier());
  2721. // Check for the end of the typedef
  2722. GetToken(&token);
  2723. if( token.type != ttEndStatement )
  2724. {
  2725. RewindTo(&token);
  2726. Error(ExpectedToken(asCTokenizer::GetDefinition(token.type)).AddressOf(), &token);
  2727. }
  2728. return node;
  2729. }
  2730. void asCParser::ParseMethodOverrideBehaviors(asCScriptNode *funcNode)
  2731. {
  2732. sToken t1;
  2733. for( ; ; )
  2734. {
  2735. GetToken(&t1);
  2736. RewindTo(&t1);
  2737. if( IdentifierIs(t1, FINAL_TOKEN) || IdentifierIs(t1, OVERRIDE_TOKEN) )
  2738. funcNode->AddChildLast(ParseIdentifier());
  2739. else
  2740. break;
  2741. }
  2742. }
  2743. END_AS_NAMESPACE