BfParser.cpp 106 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364
  1. #pragma warning(disable:4996)
  2. #include "BfParser.h"
  3. #include "BfReducer.h"
  4. #include "BfPrinter.h"
  5. #include "BfDefBuilder.h"
  6. #include "BfCompiler.h"
  7. #include "BfSourceClassifier.h"
  8. #include "BfSourcePositionFinder.h"
  9. #include <sstream>
  10. #include "BeefySysLib/util/PerfTimer.h"
  11. #include "BeefySysLib/util/BeefPerf.h"
  12. #include "BeefySysLib/util/UTF8.h"
  13. #include "BfAutoComplete.h"
  14. #include "BfResolvePass.h"
  15. #include "BfElementVisitor.h"
  16. #include "BeefySysLib/util/UTF8.h"
  17. extern "C"
  18. {
  19. #include "BeefySysLib/third_party/utf8proc/utf8proc.h"
  20. }
  21. #include "BeefySysLib/util/AllocDebug.h"
  22. USING_NS_BF;
  23. static bool IsWhitespace(char c)
  24. {
  25. return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
  26. }
  27. static bool IsWhitespaceOrPunctuation(char c)
  28. {
  29. switch (c)
  30. {
  31. case ',':
  32. case ';':
  33. case ':':
  34. case '(':
  35. case ')':
  36. case '[':
  37. case ']':
  38. case '{':
  39. case '}':
  40. case '<':
  41. case '>':
  42. case '/':
  43. case '-':
  44. case '=':
  45. case '+':
  46. case '!':
  47. case '%':
  48. case '&':
  49. case '|':
  50. case '#':
  51. case '@':
  52. case '`':
  53. case '^':
  54. case '~':
  55. case '*':
  56. case '?':
  57. case '\n':
  58. case ' ':
  59. case '\t':
  60. case '\v':
  61. case '\f':
  62. case '\r':
  63. return true;
  64. default:
  65. return false;
  66. }
  67. }
  68. BfParser* BfParserData::ToParser()
  69. {
  70. if (mUniqueParser != NULL)
  71. {
  72. BF_ASSERT(mUniqueParser->mOrigSrcLength >= 0);
  73. BF_ASSERT((mUniqueParser->mCursorIdx >= -1) || (mUniqueParser->mCursorIdx <= mUniqueParser->mOrigSrcLength));
  74. }
  75. return mUniqueParser;
  76. }
  77. //////////////////////////////////////////////////////////////////////////
  78. /// raw_null_ostream - A raw_ostream that discards all output.
  79. /*class debug_ostream : public llvm::raw_ostream
  80. {
  81. /// write_impl - See raw_ostream::write_impl.
  82. void write_impl(const char *Ptr, size_t size) override
  83. {
  84. char str[256] = {0};
  85. memcpy(str, Ptr, std::min((int)size, 255));
  86. OutputDebugStr(str);
  87. }
  88. /// current_pos - Return the current position within the stream, not
  89. /// counting the bytes currently in the buffer.
  90. uint64_t current_pos() const override
  91. {
  92. return 0;
  93. }
  94. };*/
  95. //////////////////////////////////////////////////////////////////////////
  96. static CritSect gParseFileDataCrit;
  97. static Array<int> gFreeIds;
  98. static int gCurFreeId;
  99. int BfParseFileData::GetUniqueId(int idx)
  100. {
  101. AutoCrit autoCrit(gParseFileDataCrit);
  102. int* valuePtr = NULL;
  103. if (mUniqueIDList.TryAdd(idx, NULL, &valuePtr))
  104. {
  105. if (!gFreeIds.IsEmpty())
  106. {
  107. *valuePtr = gFreeIds.back();
  108. gFreeIds.pop_back();
  109. }
  110. else
  111. *valuePtr = gCurFreeId++;
  112. }
  113. return *valuePtr;
  114. }
  115. BfParseFileData::~BfParseFileData()
  116. {
  117. if (!mUniqueIDList.IsEmpty())
  118. {
  119. AutoCrit autoCrit(gParseFileDataCrit);
  120. for (auto kv : mUniqueIDList)
  121. gFreeIds.Add(kv.mValue);
  122. }
  123. }
  124. //////////////////////////////////////////////////////////////////////////
  125. BfParserCache* Beefy::gBfParserCache = NULL;
  126. bool BfParserCache::DataEntry::operator==(const LookupEntry& lookup) const
  127. {
  128. if ((mParserData->mFileName == lookup.mFileName) &&
  129. (mParserData->mSrcLength == lookup.mSrcLength) &&
  130. (memcmp(mParserData->mSrc, lookup.mSrc, lookup.mSrcLength) == 0))
  131. {
  132. for (auto& setDefine : mParserData->mDefines_Def)
  133. if (!lookup.mProject->mPreprocessorMacros.Contains(setDefine))
  134. return false;
  135. for (auto& setDefine : mParserData->mDefines_NoDef)
  136. if (lookup.mProject->mPreprocessorMacros.Contains(setDefine))
  137. return false;
  138. return true;
  139. }
  140. return false;
  141. }
  142. BfParserCache::BfParserCache()
  143. {
  144. mRefCount = 0;
  145. }
  146. BfParserCache::~BfParserCache()
  147. {
  148. for (auto& entry : mEntries)
  149. {
  150. BF_ASSERT(entry.mParserData->mRefCount == 0);
  151. delete entry.mParserData;
  152. }
  153. }
  154. void BfParserCache::ReportMemory(MemReporter* memReporter)
  155. {
  156. int srcLen = 0;
  157. int allocBytesUsed = 0;
  158. int largeAllocs = 0;
  159. for (auto& entry : mEntries)
  160. {
  161. auto parserData = entry.mParserData;
  162. parserData->ReportMemory(memReporter);
  163. srcLen += parserData->mSrcLength;
  164. allocBytesUsed += (int)(parserData->mAlloc.mPages.size() * BfAstAllocManager::PAGE_SIZE);
  165. largeAllocs += parserData->mAlloc.mLargeAllocSizes;
  166. }
  167. int allocPages = 0;
  168. int usedPages = 0;
  169. mAstAllocManager.GetStats(allocPages, usedPages);
  170. OutputDebugStrF("Parsers: %d Chars: %d UsedAlloc: %dk BytesPerChar: %d SysAllocPages: %d SysUsedPages: %d (%dk) LargeAllocs: %dk\n", (int)mEntries.size(), srcLen, allocBytesUsed / 1024,
  171. allocBytesUsed / BF_MAX(1, srcLen), allocPages, usedPages, (usedPages * BfAstAllocManager::PAGE_SIZE) / 1024, largeAllocs / 1024);
  172. //memReporter->AddBumpAlloc("BumpAlloc", mAstAllocManager);
  173. }
  174. void BfParserData::ReportMemory(MemReporter* memReporter)
  175. {
  176. memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
  177. memReporter->Add("Source", mSrcLength);
  178. memReporter->AddBumpAlloc("AstAlloc", mAlloc);
  179. }
  180. static int DecodeInt(uint8* buf, int& idx)
  181. {
  182. int value = 0;
  183. int shift = 0;
  184. int curByte;
  185. do
  186. {
  187. curByte = buf[idx++];
  188. value |= ((curByte & 0x7f) << shift);
  189. shift += 7;
  190. } while (curByte >= 128);
  191. // Sign extend negative numbers.
  192. if (((curByte & 0x40) != 0) && (shift < 64))
  193. value |= ~0LL << shift;
  194. return value;
  195. }
  196. static int gCurDataId = 0;
  197. BfParserData::BfParserData()
  198. {
  199. mDataId = (int)BfpSystem_InterlockedExchangeAdd32((uint32*)&gCurDataId, 1) + 1;
  200. mHash = 0;
  201. mRefCount = -1;
  202. mJumpTable = NULL;
  203. mJumpTableSize = 0;
  204. mFailed = false;
  205. mCharIdData = NULL;
  206. mUniqueParser = NULL;
  207. mDidReduce = false;
  208. mParseFileData = NULL;
  209. }
  210. BfParserData::~BfParserData()
  211. {
  212. if (mParseFileData != NULL)
  213. {
  214. BF_ASSERT(mParseFileData->mRefCount >= 0);
  215. mParseFileData->mRefCount--;
  216. if (mParseFileData->mRefCount == 0)
  217. {
  218. delete mParseFileData;
  219. gBfParserCache->mParseFileDataMap.Remove(mFileName);
  220. }
  221. }
  222. delete[] mJumpTable;
  223. delete[] mCharIdData;
  224. }
  225. void BfParserData::InitFileData()
  226. {
  227. BF_ASSERT(mParseFileData == NULL);
  228. BfParseFileData** valuePtr = NULL;
  229. if (gBfParserCache->mParseFileDataMap.TryAdd(mFileName, NULL, &valuePtr))
  230. {
  231. *valuePtr = new BfParseFileData();
  232. }
  233. mParseFileData = *valuePtr;
  234. mParseFileData->mRefCount++;
  235. }
  236. int BfParserData::GetCharIdAtIndex(int findIndex)
  237. {
  238. if (mCharIdData == NULL)
  239. return findIndex;
  240. int encodeIdx = 0;
  241. int charId = 1;
  242. int charIdx = 0;
  243. while (true)
  244. {
  245. int cmd = DecodeInt(mCharIdData, encodeIdx);
  246. if (cmd > 0)
  247. charId = cmd;
  248. else
  249. {
  250. int spanSize = -cmd;
  251. if ((findIndex >= charIdx) && (findIndex < charIdx + spanSize))
  252. return charId + (findIndex - charIdx);
  253. charId += spanSize;
  254. charIdx += spanSize;
  255. if (cmd == 0)
  256. return -1;
  257. }
  258. }
  259. }
  260. void BfParserData::GetLineCharAtIdx(int idx, int& line, int& lineChar)
  261. {
  262. if (mJumpTableSize <= 0)
  263. {
  264. line = 0;
  265. lineChar = 0;
  266. return;
  267. }
  268. if (idx >= mSrcLength)
  269. idx = mSrcLength - 1;
  270. auto* jumpEntry = mJumpTable + (idx / PARSER_JUMPTABLE_DIVIDE);
  271. if (jumpEntry->mCharIdx > idx)
  272. jumpEntry--;
  273. line = jumpEntry->mLineNum;
  274. lineChar = 0;
  275. int curSrcPos = jumpEntry->mCharIdx;
  276. while (curSrcPos < idx)
  277. {
  278. if (mSrc[curSrcPos] == '\n')
  279. {
  280. line++;
  281. lineChar = 0;
  282. }
  283. else
  284. {
  285. lineChar++;
  286. }
  287. curSrcPos++;
  288. }
  289. }
  290. bool BfParserData::IsUnwarnedAt(BfAstNode* node)
  291. {
  292. if (mUnwarns.empty())
  293. return false;
  294. auto unwarnItr = mUnwarns.upper_bound(node->GetSrcStart());
  295. if (unwarnItr == mUnwarns.begin())
  296. return false;
  297. unwarnItr--;
  298. int unwarnIdx = *unwarnItr;
  299. int checkIdx = node->GetSrcStart();
  300. int lineCount = 0;
  301. while (checkIdx > 0)
  302. {
  303. checkIdx--;
  304. if (checkIdx < unwarnIdx)
  305. return true;
  306. if (mSrc[checkIdx] == '\n')
  307. {
  308. lineCount++;
  309. // #unwarn must be immediately preceding the start of the statement containing this node
  310. if (lineCount == 2)
  311. return false;
  312. }
  313. }
  314. return true;
  315. }
  316. bool BfParserData::IsWarningEnabledAtSrcIndex(int warningNumber, int srcIdx)
  317. {
  318. int enabled = 1; //CDH TODO if/when we add warning level support, this default will change based on the warning number and the general project warning level setting
  319. for (const auto& it : mWarningEnabledChanges)
  320. {
  321. if (it.mKey > srcIdx)
  322. break;
  323. if ((it.mValue.mWarningNumber == warningNumber) || (it.mValue.mWarningNumber == -1))
  324. {
  325. if (it.mValue.mEnable)
  326. enabled++;
  327. else
  328. enabled--;
  329. }
  330. }
  331. return enabled > 0;
  332. }
  333. void BfParserData::Deref()
  334. {
  335. mRefCount--;
  336. BF_ASSERT(mRefCount >= 0);
  337. if (mRefCount == 0)
  338. {
  339. AutoCrit autoCrit(gBfParserCache->mCritSect);
  340. BfParserCache::DataEntry dataEntry;
  341. dataEntry.mParserData = this;
  342. bool didRemove = gBfParserCache->mEntries.Remove(dataEntry);
  343. BF_ASSERT(didRemove);
  344. delete this;
  345. }
  346. }
  347. //////////////////////////////////////////////////////////////////////////
  348. static int gParserCount = 0;
  349. BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem)
  350. {
  351. BfLogSys(bfSystem, "BfParser::BfParser %08X\n", this);
  352. gParserCount++;
  353. mTextVersion = -1;
  354. mEmbedKind = BfSourceEmbedKind_None;
  355. mUsingCache = false;
  356. mParserData = NULL;
  357. mAwaitingDelete = false;
  358. mScanOnly = false;
  359. mCompleteParse = false;
  360. mIsEmitted = false;
  361. mJumpTable = NULL;
  362. mProject = bfProject;
  363. mPassInstance = NULL;
  364. mSourceClassifier = NULL;
  365. mPrevRevision = NULL;
  366. mNextRevision = NULL;
  367. mOrigSrcLength = 0;
  368. mSrcAllocSize = -1;
  369. mSrcLength = 0;
  370. mSrcIdx = 0;
  371. mParserFlags = ParserFlag_None;
  372. mCursorIdx = -1;
  373. mCursorCheckIdx = -1;
  374. mLineStart = 0;
  375. //mCurToken = (BfSyntaxToken)0;
  376. mToken = BfToken_None;
  377. mSyntaxToken = BfSyntaxToken_None;
  378. mTokenStart = 0;
  379. mTokenEnd = 0;
  380. mLineNum = 0;
  381. mCompatMode = false;
  382. mQuickCompatMode = false;
  383. mLiteral.mWarnType = 0;
  384. mDataId = -1;
  385. mTriviaStart = 0;
  386. mParsingFailed = false;
  387. mInAsmBlock = false;
  388. mCurBlockId = 0;
  389. mPreprocessorIgnoredSectionNode = NULL;
  390. mPreprocessorIgnoreDepth = 0;
  391. mAddedDependsDefines = false;
  392. if (bfProject != NULL)
  393. {
  394. for (auto macro : bfProject->mPreprocessorMacros)
  395. mPreprocessorDefines[macro] = BfDefineState_FromProject;
  396. }
  397. }
  398. //static std::set<BfAstNode*> gFoundNodes;
  399. BfParser::~BfParser()
  400. {
  401. int parserCount = gParserCount--;
  402. if (mParserData == NULL)
  403. {
  404. }
  405. else if (mParserData->mRefCount == -1)
  406. {
  407. // Owned data, never intended for cache
  408. mParserData->mSrc = NULL; // Count on BfSource dtor to release strc
  409. delete mParserData;
  410. }
  411. else if (mParserData->mRefCount == 0)
  412. {
  413. // Just never got added to the cache
  414. delete mParserData;
  415. }
  416. else
  417. {
  418. mParserData->Deref();
  419. }
  420. mSourceData = NULL;
  421. BfLogSys(mSystem, "BfParser::~BfParser %p\n", this);
  422. }
  423. void BfParser::SetCursorIdx(int cursorIdx)
  424. {
  425. mCursorIdx = cursorIdx;
  426. mCursorCheckIdx = cursorIdx;
  427. int checkIdx = cursorIdx;
  428. while (checkIdx > 0)
  429. {
  430. char c = mSrc[checkIdx - 1];
  431. if (!IsWhitespace(c))
  432. {
  433. if (c == '.')
  434. mCursorCheckIdx = checkIdx;
  435. break;
  436. }
  437. checkIdx--;
  438. }
  439. }
  440. //static int gDeleteCount = 0;
  441. //static int gIndentCount = 0;
  442. void BfParser::GetLineCharAtIdx(int idx, int& line, int& lineChar)
  443. {
  444. mParserData->GetLineCharAtIdx(idx, line, lineChar);
  445. }
  446. int BfParser::GetIndexAtLine(int line)
  447. {
  448. if (line == 0)
  449. return 0;
  450. int curLine = 0;
  451. for (int i = 0; i < mSrcLength; i++)
  452. {
  453. char c = mSrc[i];
  454. if (c == '\n')
  455. {
  456. curLine++;
  457. if (line == curLine)
  458. return i + 1;
  459. }
  460. }
  461. return -1;
  462. }
  463. void BfParser::Fail(const StringImpl& error, int offset)
  464. {
  465. mPassInstance->FailAt(error, mSourceData, mSrcIdx + offset);
  466. }
  467. void BfParser::UnexpectedCharacter()
  468. {
  469. if (mPreprocessorIgnoredSectionNode != NULL)
  470. return;
  471. int startIdx = mTokenStart;
  472. int endIdx = startIdx;
  473. char32_t c = u8_nextchar((char*)mSrc, &endIdx);
  474. int charLen = endIdx - startIdx;
  475. String str = "Unexpected character '";
  476. for (int i = 0; i < charLen; i++)
  477. str += mSrc[startIdx + i];
  478. str += StrFormat("' (0x%0X)", (int)c);
  479. mPassInstance->FailAt(str, mSourceData, startIdx);
  480. mSrcIdx = endIdx;
  481. }
  482. void BfParser::TokenFail(const StringImpl& error, int offset)
  483. {
  484. if (mPreprocessorIgnoredSectionNode == NULL)
  485. Fail(error, offset);
  486. }
  487. void BfParser::Init(uint64 cacheHash)
  488. {
  489. BF_ASSERT(mParserData == NULL);
  490. mParserData = new BfParserData();
  491. mSourceData = mParserData;
  492. mParserData->mFileName = mFileName;
  493. mParserData->InitFileData();
  494. if (mDataId != -1)
  495. mParserData->mDataId = mDataId;
  496. else
  497. mDataId = mParserData->mDataId;
  498. mParserData->mAstAllocManager = &gBfParserCache->mAstAllocManager;
  499. mParserData->mSrc = mSrc;
  500. mParserData->mSrcLength = mSrcLength;
  501. if (cacheHash != 0)
  502. {
  503. BfLogSysM("Creating cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  504. mParserData->mHash = cacheHash;
  505. mParserData->mRefCount = 0; // 0 means we want to EVENTUALLY write it to the cache
  506. mSrcAllocSize = -1;
  507. }
  508. else
  509. {
  510. BfLogSysM("Creating unique parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  511. mParserData->mUniqueParser = this;
  512. }
  513. mJumpTableSize = ((mSrcLength + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
  514. mJumpTable = new BfLineStartEntry[mJumpTableSize];
  515. memset(mJumpTable, 0, mJumpTableSize * sizeof(BfLineStartEntry));
  516. mParserData->mJumpTable = mJumpTable;
  517. mParserData->mJumpTableSize = mJumpTableSize;
  518. mAlloc = &mParserData->mAlloc;
  519. mAlloc->mSourceData = mSourceData;
  520. }
  521. void BfParser::NewLine()
  522. {
  523. mLineStart = mSrcIdx;
  524. mLineNum++;
  525. if (mJumpTable == NULL)
  526. return;
  527. int idx = (mSrcIdx / PARSER_JUMPTABLE_DIVIDE);
  528. if (idx == 0)
  529. return;
  530. BF_ASSERT(idx < mJumpTableSize);
  531. BfLineStartEntry* jumpTableEntry = mJumpTable + idx;
  532. jumpTableEntry->mCharIdx = mSrcIdx;
  533. jumpTableEntry->mLineNum = mLineNum;
  534. }
  535. void BfParser::SetSource(const char* data, int length)
  536. {
  537. const int EXTRA_BUFFER_SIZE = 80; // Extra chars for a bit of AllocChars room
  538. //TODO: Check cache
  539. // Don't cache if we have a Cursorid set,
  540. // if mDataId != -1
  541. // if BfParerFlag != 0
  542. bool canCache = true;
  543. if (mDataId != -1)
  544. canCache = false;
  545. if (mParserFlags != 0)
  546. canCache = false;
  547. if (mCursorIdx != -1)
  548. canCache = false;
  549. if (mCompatMode)
  550. canCache = false;
  551. if (mQuickCompatMode)
  552. canCache = false;
  553. if (mFileName.IsEmpty())
  554. canCache = false;
  555. if (mProject == NULL)
  556. canCache = false;
  557. if (mIsEmitted)
  558. canCache = false;
  559. uint64 cacheHash = 0;
  560. if (canCache)
  561. {
  562. AutoCrit autoCrit(gBfParserCache->mCritSect);
  563. HashContext hashCtx;
  564. hashCtx.MixinStr(mFileName);
  565. hashCtx.Mixin(data, length);
  566. cacheHash = hashCtx.Finish64();
  567. BfParserCache::LookupEntry lookupEntry;
  568. lookupEntry.mFileName = mFileName;
  569. lookupEntry.mSrc = data;
  570. lookupEntry.mSrcLength = length;
  571. lookupEntry.mHash = cacheHash;
  572. lookupEntry.mProject = mProject;
  573. BfParserCache::DataEntry* dataEntryP;
  574. if (gBfParserCache->mEntries.TryGetWith(lookupEntry, &dataEntryP))
  575. {
  576. mUsingCache = true;
  577. mParserData = dataEntryP->mParserData;
  578. BF_ASSERT(mParserData->mDidReduce);
  579. BfLogSysM("Using cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  580. mParserData->mRefCount++;
  581. mSourceData = mParserData;
  582. mSrc = mParserData->mSrc;
  583. mSrcLength = mParserData->mSrcLength;
  584. mOrigSrcLength = mParserData->mSrcLength;
  585. mSrcAllocSize = -1;
  586. mSrcIdx = 0;
  587. mJumpTable = mParserData->mJumpTable;
  588. mJumpTableSize = mParserData->mJumpTableSize;
  589. mAlloc = &mParserData->mAlloc;
  590. return;
  591. }
  592. }
  593. mSrcLength = length;
  594. mOrigSrcLength = length;
  595. mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/;
  596. char* ownedSrc = new char[mSrcAllocSize + 1];
  597. if (data != NULL)
  598. memcpy(ownedSrc, data, length);
  599. ownedSrc[length] = 0;
  600. mSrc = ownedSrc;
  601. mSrcIdx = 0;
  602. Init(cacheHash);
  603. }
  604. void BfParser::MoveSource(const char* data, int length) // Takes ownership of data ptr
  605. {
  606. mSrcLength = length;
  607. mOrigSrcLength = length;
  608. mSrcAllocSize = mSrcLength;
  609. mSrc = data;
  610. mSrcIdx = 0;
  611. Init();
  612. }
  613. void BfParser::RefSource(const char* data, int length)
  614. {
  615. mSrcLength = length;
  616. mOrigSrcLength = length;
  617. mSrcAllocSize = -1;
  618. mSrc = data;
  619. mSrcIdx = 0;
  620. Init();
  621. }
  622. bool BfParser::SrcPtrHasToken(const char* name)
  623. {
  624. const char* namePtr = name;
  625. int checkIdx = mSrcIdx - 1;
  626. while (*namePtr)
  627. {
  628. if (*(namePtr++) != mSrc[checkIdx])
  629. return false;
  630. checkIdx++;
  631. }
  632. if (!IsWhitespaceOrPunctuation(mSrc[checkIdx]))
  633. return false;
  634. mSrcIdx = checkIdx;
  635. mTokenEnd = checkIdx;
  636. return true;
  637. }
  638. void BfParser::AddErrorNode(int startIdx, int endIdx)
  639. {
  640. auto identifierNode = mAlloc->Alloc<BfIdentifierNode>();
  641. identifierNode->Init(mTriviaStart, startIdx, endIdx);
  642. //identifierNode->mSource = this;
  643. BfSource::AddErrorNode(identifierNode);
  644. }
  645. BfCommentKind BfParser::GetCommentKind(int startIdx)
  646. {
  647. if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<'))
  648. return BfCommentKind_Documentation_Block_Post;
  649. if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<'))
  650. return BfCommentKind_Documentation_Line_Post;
  651. if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/'))
  652. return BfCommentKind_Documentation_Block_Pre;
  653. if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/'))
  654. return BfCommentKind_Documentation_Line_Pre;
  655. if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*'))
  656. return BfCommentKind_Block;
  657. return BfCommentKind_Line;
  658. }
  659. bool BfParser::EvaluatePreprocessor(BfExpression* expr)
  660. {
  661. bool isInvalid = false;
  662. if (expr == NULL)
  663. return false;
  664. if (auto binaryOp = BfNodeDynCast<BfBinaryOperatorExpression>(expr))
  665. {
  666. switch (binaryOp->mOp)
  667. {
  668. case BfBinaryOp_ConditionalOr:
  669. return EvaluatePreprocessor(binaryOp->mLeft) || EvaluatePreprocessor(binaryOp->mRight);
  670. case BfBinaryOp_ConditionalAnd:
  671. return EvaluatePreprocessor(binaryOp->mLeft) && EvaluatePreprocessor(binaryOp->mRight);
  672. default: break;
  673. }
  674. }
  675. if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(expr))
  676. {
  677. switch (unaryOp->mOp)
  678. {
  679. case BfUnaryOp_Not:
  680. return !EvaluatePreprocessor(unaryOp->mExpression);
  681. default: break;
  682. }
  683. }
  684. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(expr))
  685. {
  686. return HandleIfDef(identifier->ToString()) == MaybeBool_True;
  687. }
  688. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  689. {
  690. return EvaluatePreprocessor(parenExpr->mExpression);
  691. }
  692. if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(expr))
  693. {
  694. if (literalExpr->mValue.mTypeCode == BfTypeCode_Boolean)
  695. {
  696. return literalExpr->mValue.mBool;
  697. }
  698. }
  699. mPassInstance->Fail("Invalid preprocessor expression", expr);
  700. return false;
  701. }
  702. BfBlock* BfParser::ParseInlineBlock(int spaceIdx, int endIdx)
  703. {
  704. BfBlock* block = NULL;
  705. SizedArray<BfAstNode*, 8> childArr;
  706. mSrcIdx = spaceIdx;
  707. BfAstNode* startNode = NULL;
  708. int usedEndIdx = spaceIdx;
  709. int usedLineNum = mLineNum;
  710. int usedLineStart = mLineStart;
  711. while (true)
  712. {
  713. NextToken(endIdx + 1, false, true);
  714. if (mSyntaxToken == BfSyntaxToken_HIT_END_IDX)
  715. {
  716. mSrcIdx = usedEndIdx;
  717. mLineNum = usedLineNum;
  718. mLineStart = usedLineStart;
  719. auto lastNode = mSidechannelRootNode->GetLast();
  720. if (lastNode != NULL)
  721. mSrcIdx = std::max(mSrcIdx, lastNode->GetSrcEnd());
  722. break;
  723. }
  724. usedEndIdx = mSrcIdx;
  725. usedLineStart = mLineStart;
  726. usedLineNum = mLineNum;
  727. auto childNode = CreateNode();
  728. if (childNode == NULL)
  729. break;
  730. if ((childNode->IsA<BfCommentNode>()))
  731. {
  732. mSidechannelRootNode->Add(childNode);
  733. mPendingSideNodes.push_back(childNode);
  734. continue;
  735. }
  736. if (startNode == NULL)
  737. startNode = childNode;
  738. if (block == NULL)
  739. {
  740. block = mAlloc->Alloc<BfBlock>();
  741. block->mParserBlockId = ++mCurBlockId;
  742. }
  743. block->Add(childNode);
  744. childArr.push_back(childNode);
  745. //block->mChildArr.Add(childNode, &mAlloc);
  746. }
  747. if (block != NULL)
  748. block->Init(childArr, mAlloc);
  749. return block;
  750. }
  751. BfExpression* BfParser::CreateInlineExpressionFromNode(BfBlock* block)
  752. {
  753. BfReducer reducer;
  754. reducer.mPassInstance = mPassInstance;
  755. reducer.mAlloc = mAlloc;
  756. reducer.mCompatMode = mCompatMode;
  757. reducer.mVisitorPos = BfReducer::BfVisitorPos(block);
  758. reducer.mVisitorPos.MoveNext();
  759. auto startNode = reducer.mVisitorPos.GetCurrent();
  760. if (startNode == NULL)
  761. return NULL;
  762. auto paramExpression = reducer.CreateExpression(startNode);
  763. if ((paramExpression != NULL) && (reducer.mVisitorPos.GetNext() != NULL))
  764. mPassInstance->Fail("Expression parsing error", reducer.mVisitorPos.GetNext());
  765. return paramExpression;
  766. }
  767. void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block)
  768. {
  769. auto itr = block->begin();
  770. auto paramNode = *itr;
  771. if (paramNode->ToStringView() == "warning")
  772. {
  773. ++itr;
  774. //auto iterNode = paramNode->mNext;
  775. //BfAstNode* iterNode = parentNode->mChildArr.GetAs<BfAstNode*>(++curIdx);
  776. BfAstNode* iterNode = itr.Get();
  777. if (iterNode)
  778. {
  779. ++itr;
  780. bool enable;
  781. if (iterNode->ToStringView() == "disable")
  782. {
  783. enable = false;
  784. }
  785. else if (iterNode->ToStringView() == "restore")
  786. {
  787. enable = true;
  788. }
  789. else
  790. {
  791. enable = true;
  792. mPassInstance->FailAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
  793. }
  794. int srcStart = iterNode->GetSrcStart();
  795. int nodeCount = 0;
  796. iterNode = itr.Get();
  797. while (iterNode)
  798. {
  799. ++nodeCount;
  800. ++itr;
  801. auto tokenStr = iterNode->ToString();
  802. if (tokenStr != ",") // commas allowed between warning numbers but not required; we just ignore them
  803. {
  804. bool isNum = true;
  805. for (const auto it : tokenStr)
  806. {
  807. char c = it;
  808. if (c < '0' || c > '9')
  809. {
  810. isNum = false;
  811. break;
  812. }
  813. }
  814. int warningNum = atoi(tokenStr.c_str());
  815. if ((isNum) && (warningNum > 0))
  816. {
  817. BfParserWarningEnabledChange wec;
  818. wec.mEnable = enable;
  819. wec.mWarningNumber = warningNum;
  820. mParserData->mWarningEnabledChanges[iterNode->GetSrcStart()] = wec;
  821. }
  822. else
  823. {
  824. mPassInstance->FailAt("Expected decimal warning number", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
  825. }
  826. }
  827. iterNode = itr.Get();
  828. }
  829. if (nodeCount == 0)
  830. {
  831. BfParserWarningEnabledChange wec;
  832. wec.mEnable = enable;
  833. wec.mWarningNumber = -1;
  834. mParserData->mWarningEnabledChanges[srcStart] = wec;
  835. }
  836. }
  837. else
  838. {
  839. mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, paramNode->GetSrcEnd() - 1);
  840. }
  841. }
  842. else if (paramNode->ToStringView() == "format")
  843. {
  844. ++itr;
  845. BfAstNode* iterNode = itr.Get();
  846. if (iterNode)
  847. {
  848. if ((iterNode->ToStringView() != "disable") &&
  849. (iterNode->ToStringView() != "restore"))
  850. {
  851. mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"format\"", mSourceData, paramNode->GetSrcEnd() - 1);
  852. }
  853. }
  854. }
  855. else
  856. {
  857. mPassInstance->FailAt("Unknown #pragma directive", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
  858. }
  859. }
  860. void BfParser::HandleDefine(const StringImpl& name, BfAstNode* paramNode)
  861. {
  862. mPreprocessorDefines[name] = BfDefineState_ManualSet;
  863. }
  864. void BfParser::HandleUndefine(const StringImpl& name)
  865. {
  866. mPreprocessorDefines[name] = BfDefineState_ManualUnset;
  867. }
  868. MaybeBool BfParser::HandleIfDef(const StringImpl& name)
  869. {
  870. if ((!mAddedDependsDefines) && (mProject != NULL) && (name.StartsWith("BF_DEPENDS_")))
  871. {
  872. for (auto project : mProject->mDependencies)
  873. {
  874. StringT<64> def = "BF_DEPENDS_";
  875. def.Append(project->mName);
  876. MakeUpper(def);
  877. for (auto& c : def)
  878. {
  879. if (!isalnum((uint8)c))
  880. c = '_';
  881. }
  882. mPreprocessorDefines[def] = BfDefineState_FromProject;
  883. }
  884. mAddedDependsDefines = true;
  885. }
  886. BfDefineState defineState;
  887. if (mPreprocessorDefines.TryGetValue(name, &defineState))
  888. {
  889. if (defineState == BfDefineState_FromProject)
  890. {
  891. mParserData->mDefines_Def.Add(name);
  892. }
  893. return (defineState != BfDefineState_ManualUnset) ? MaybeBool_True : MaybeBool_False;
  894. }
  895. else
  896. {
  897. mParserData->mDefines_NoDef.Add(name);
  898. return MaybeBool_False;
  899. }
  900. }
  901. MaybeBool BfParser::HandleProcessorCondition(BfBlock* paramNode)
  902. {
  903. if (paramNode == NULL)
  904. return MaybeBool_False;
  905. bool found = false;
  906. auto paramExpression = CreateInlineExpressionFromNode(paramNode);
  907. if (paramExpression != NULL)
  908. {
  909. return EvaluatePreprocessor(paramExpression) ? MaybeBool_True : MaybeBool_False;
  910. }
  911. return MaybeBool_False;
  912. }
  913. void BfParser::HandleInclude(BfAstNode* paramNode)
  914. {
  915. }
  916. void BfParser::HandleIncludeNext(BfAstNode* paramNode)
  917. {
  918. }
  919. bool BfParser::HandlePreprocessor()
  920. {
  921. int triviaStart = mTriviaStart;
  922. int checkIdx = 0;
  923. for (int checkIdx = mLineStart; checkIdx < mSrcIdx - 1; checkIdx++)
  924. {
  925. if (!isspace((uint8)mSrc[checkIdx]))
  926. {
  927. if (mPreprocessorIgnoreDepth == 0)
  928. {
  929. if (mSrc[mSrcIdx - 1] != '#')
  930. return false;
  931. mPassInstance->FailAt("Preprocessor directives must appear as the first non-whitespace character on a line", mSourceData, checkIdx);
  932. break;
  933. }
  934. else
  935. continue; // Keep searching for #endif
  936. }
  937. }
  938. String pragma;
  939. String pragmaParam;
  940. switch (mSrc[mSrcIdx - 1])
  941. {
  942. case '<':
  943. if (mPreprocessorIgnoreDepth > 0)
  944. return false;
  945. pragma = "<<<";
  946. break;
  947. case '=':
  948. if (mPreprocessorIgnoreDepth > 0)
  949. return false;
  950. pragma = "===";
  951. break;
  952. case '>':
  953. if (mPreprocessorIgnoreDepth > 1)
  954. return false;
  955. pragma = ">>>";
  956. break;
  957. }
  958. bool atEnd = false;
  959. int startIdx = mSrcIdx - 1;
  960. int spaceIdx = -1;
  961. int charIdx = -1;
  962. while (true)
  963. {
  964. char c = mSrc[mSrcIdx++];
  965. if (c == '\n')
  966. {
  967. int checkIdx = mSrcIdx - 2;
  968. bool hadSlash = false;
  969. while (checkIdx >= startIdx)
  970. {
  971. char checkC = mSrc[checkIdx];
  972. if (checkC == '\\')
  973. {
  974. hadSlash = true;
  975. break;
  976. }
  977. if ((checkC != ' ') && (checkC != '\t'))
  978. break;
  979. checkIdx--;
  980. }
  981. if (!hadSlash)
  982. break;
  983. }
  984. if (c == '\0')
  985. {
  986. mSrcIdx--;
  987. break;
  988. }
  989. if (charIdx == -1)
  990. {
  991. if (!pragma.IsEmpty())
  992. {
  993. if (!IsWhitespace(c))
  994. charIdx = mSrcIdx - 1;
  995. }
  996. else
  997. {
  998. if (!IsWhitespaceOrPunctuation(c))
  999. charIdx = mSrcIdx - 1;
  1000. }
  1001. }
  1002. else if ((IsWhitespaceOrPunctuation(c)) && (spaceIdx == -1))
  1003. spaceIdx = mSrcIdx - 1;
  1004. }
  1005. if (charIdx == -1)
  1006. {
  1007. mPassInstance->FailAt("Preprocessor directive expected", mSourceData, startIdx);
  1008. return true;
  1009. }
  1010. int endIdx = mSrcIdx - 1;
  1011. while (endIdx >= startIdx)
  1012. {
  1013. if (!IsWhitespace(mSrc[endIdx]))
  1014. break;
  1015. endIdx--;
  1016. }
  1017. BfBlock* paramNode = NULL;
  1018. if (pragma.IsEmpty())
  1019. {
  1020. if (spaceIdx != -1)
  1021. {
  1022. pragma = String(mSrc + charIdx, mSrc + spaceIdx);
  1023. int breakIdx = spaceIdx;
  1024. while (spaceIdx <= endIdx)
  1025. {
  1026. if (!isspace((uint8)mSrc[spaceIdx]))
  1027. break;
  1028. spaceIdx++;
  1029. }
  1030. if (spaceIdx <= endIdx)
  1031. pragmaParam = String(mSrc + spaceIdx, mSrc + endIdx + 1);
  1032. paramNode = ParseInlineBlock(breakIdx, endIdx);
  1033. }
  1034. else
  1035. {
  1036. pragma = String(mSrc + charIdx, mSrc + endIdx + 1);
  1037. mSrcIdx = endIdx + 1;
  1038. }
  1039. }
  1040. else
  1041. {
  1042. mSrcIdx--;
  1043. }
  1044. bool wantsSingleParam = true;
  1045. bool addToPreprocessorAccept = false;
  1046. bool addToPreprocessorAcceptResolved = true;
  1047. bool wantedParam = false;
  1048. if (mPreprocessorIgnoreDepth > 0)
  1049. {
  1050. BF_ASSERT(!mPreprocessorNodeStack.empty());
  1051. int ignoreEnd = std::max(mPreprocessorIgnoredSectionNode->GetSrcStart(), mLineStart - 1);
  1052. if ((pragma == "endif") || (pragma == ">>>"))
  1053. {
  1054. mPreprocessorIgnoreDepth--;
  1055. if (mPreprocessorIgnoreDepth > 0)
  1056. return true;
  1057. mPreprocessorNodeStack.pop_back();
  1058. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  1059. mPreprocessorIgnoredSectionNode = NULL;
  1060. triviaStart = ignoreEnd;
  1061. }
  1062. else if ((pragma == "if") ||
  1063. ((mCompatMode) && (pragma == "ifdef")) ||
  1064. ((mCompatMode) && (pragma == "ifndef")))
  1065. {
  1066. wantsSingleParam = false;
  1067. wantedParam = true;
  1068. mPreprocessorIgnoreDepth++;
  1069. }
  1070. else if (pragma == "else")
  1071. {
  1072. if (mCompatMode)
  1073. {
  1074. if (paramNode != NULL)
  1075. {
  1076. if (paramNode->ToString() == "if")
  1077. {
  1078. bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  1079. if (found)
  1080. {
  1081. addToPreprocessorAccept = true;
  1082. mPreprocessorNodeStack.pop_back();
  1083. mPreprocessorIgnoreDepth = 0;
  1084. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  1085. mPreprocessorIgnoredSectionNode = NULL;
  1086. triviaStart = ignoreEnd;
  1087. }
  1088. else
  1089. {
  1090. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  1091. }
  1092. return true;
  1093. }
  1094. }
  1095. }
  1096. if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
  1097. {
  1098. addToPreprocessorAccept = true;
  1099. mPreprocessorNodeStack.pop_back();
  1100. mPreprocessorIgnoreDepth = 0;
  1101. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  1102. mPreprocessorIgnoredSectionNode = NULL;
  1103. triviaStart = ignoreEnd;
  1104. }
  1105. }
  1106. else if (pragma == "elif")
  1107. {
  1108. wantsSingleParam = false;
  1109. if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
  1110. {
  1111. wantedParam = true;
  1112. bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  1113. if (found)
  1114. {
  1115. addToPreprocessorAccept = true;
  1116. mPreprocessorNodeStack.pop_back();
  1117. mPreprocessorIgnoreDepth = 0;
  1118. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  1119. mPreprocessorIgnoredSectionNode = NULL;
  1120. triviaStart = ignoreEnd;
  1121. }
  1122. else
  1123. {
  1124. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  1125. }
  1126. }
  1127. }
  1128. if (mPreprocessorIgnoreDepth > 0)
  1129. return true;
  1130. }
  1131. else
  1132. {
  1133. if ((pragma == "if") || (pragma == "<<<") ||
  1134. ((mCompatMode) && (pragma == "ifdef")) ||
  1135. ((mCompatMode) && (pragma == "ifndef")))
  1136. {
  1137. wantsSingleParam = false;
  1138. wantedParam = true;
  1139. bool found = false;
  1140. if (pragma == "<<<")
  1141. {
  1142. mPassInstance->FailAt("Conflict marker found", mSourceData, startIdx, endIdx - startIdx + 1);
  1143. wantedParam = false;
  1144. found = true;
  1145. }
  1146. else if (!mQuickCompatMode)
  1147. {
  1148. if (pragma == "if")
  1149. found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  1150. else if (pragma == "ifdef")
  1151. found = HandleIfDef(pragmaParam) != MaybeBool_False;
  1152. else if (pragma == "ifndef")
  1153. found = HandleIfDef(pragmaParam) != MaybeBool_True;
  1154. }
  1155. if (!found)
  1156. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  1157. addToPreprocessorAccept = true;
  1158. if ((!found) && (!mQuickCompatMode) && (!mCompleteParse))
  1159. {
  1160. addToPreprocessorAcceptResolved = false;
  1161. mPreprocessorIgnoreDepth = 1;
  1162. }
  1163. }
  1164. else if ((pragma == "else") || (pragma == "==="))
  1165. {
  1166. if (!mQuickCompatMode && !mCompleteParse)
  1167. {
  1168. if (mPreprocessorNodeStack.empty())
  1169. mPassInstance->FailAt("Unexpected #else", mSourceData, startIdx, mSrcIdx - startIdx);
  1170. else
  1171. {
  1172. BF_ASSERT(mPreprocessorNodeStack.back().second);
  1173. mPreprocessorIgnoreDepth = 1;
  1174. }
  1175. }
  1176. }
  1177. else if (pragma == "elif")
  1178. {
  1179. wantsSingleParam = false;
  1180. if (!mQuickCompatMode && !mCompleteParse)
  1181. {
  1182. if (mPreprocessorNodeStack.empty())
  1183. mPassInstance->FailAt("Unexpected #elif", mSourceData, startIdx, mSrcIdx - startIdx);
  1184. else
  1185. {
  1186. BF_ASSERT(mPreprocessorNodeStack.back().second);
  1187. mPreprocessorIgnoreDepth = 1;
  1188. }
  1189. }
  1190. wantedParam = true;
  1191. }
  1192. else if (pragma == "endif")
  1193. {
  1194. if (mPreprocessorNodeStack.empty())
  1195. mPassInstance->FailAt("Unexpected #endif", mSourceData, startIdx, mSrcIdx - startIdx);
  1196. else
  1197. mPreprocessorNodeStack.pop_back();
  1198. }
  1199. else if (pragma == "define")
  1200. {
  1201. if ((paramNode != NULL) && (!paramNode->mChildArr.IsEmpty()))
  1202. HandleDefine(paramNode->mChildArr[0]->ToString(), paramNode);
  1203. wantedParam = true;
  1204. }
  1205. else if (pragma == "undef")
  1206. {
  1207. if ((paramNode != NULL) && (!paramNode->mChildArr.IsEmpty()))
  1208. HandleUndefine(paramNode->mChildArr[0]->ToString());
  1209. wantedParam = true;
  1210. }
  1211. else if (pragma == "error")
  1212. {
  1213. wantsSingleParam = false;
  1214. mPassInstance->FailAt(pragmaParam, mSourceData, startIdx, mSrcIdx - startIdx);
  1215. wantedParam = true;
  1216. }
  1217. else if (pragma == "warning")
  1218. {
  1219. wantsSingleParam = false;
  1220. mPassInstance->WarnAt(BfWarning_CS1030_PragmaWarning, pragmaParam, mSourceData, startIdx, mSrcIdx - startIdx);
  1221. wantedParam = true;
  1222. }
  1223. else if (pragma == "region")
  1224. {
  1225. wantsSingleParam = false;
  1226. wantedParam = true;
  1227. }
  1228. else if (pragma == "endregion")
  1229. {
  1230. wantsSingleParam = false;
  1231. if (!pragmaParam.empty())
  1232. wantedParam = true;
  1233. }
  1234. else if (pragma == "pragma")
  1235. {
  1236. wantsSingleParam = false;
  1237. wantedParam = true;
  1238. if (paramNode != NULL)
  1239. HandlePragma(pragmaParam, paramNode);
  1240. }
  1241. else if (pragma == "unwarn")
  1242. {
  1243. mParserData->mUnwarns.insert(mSrcIdx);
  1244. }
  1245. else if ((mCompatMode) && (pragma == "include"))
  1246. {
  1247. HandleInclude(paramNode);
  1248. wantedParam = true;
  1249. }
  1250. else if ((mCompatMode) && (pragma == "include_next"))
  1251. {
  1252. HandleIncludeNext(paramNode);
  1253. wantedParam = true;
  1254. }
  1255. else
  1256. {
  1257. mPassInstance->FailAt("Unknown preprocessor directive", mSourceData, startIdx, mSrcIdx - startIdx);
  1258. }
  1259. }
  1260. if ((wantsSingleParam) && (paramNode != NULL) && (paramNode->mChildArr.size() > 1))
  1261. {
  1262. mPassInstance->FailAt("Only one parameter expected", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
  1263. }
  1264. if ((wantedParam) && (paramNode == NULL))
  1265. {
  1266. mPassInstance->FailAt("Expected parameter", mSourceData, startIdx, mSrcIdx - startIdx);
  1267. }
  1268. else if ((!wantedParam) && (paramNode != NULL))
  1269. {
  1270. mPassInstance->FailAt("Parameter not expected", mSourceData, startIdx, mSrcIdx - startIdx);
  1271. }
  1272. mTokenStart = charIdx;
  1273. mTokenEnd = charIdx + (int)pragma.length();
  1274. mTriviaStart = -1;
  1275. auto bfPreprocessorCmdNode = mAlloc->Alloc<BfIdentifierNode>();
  1276. bfPreprocessorCmdNode->Init(this);
  1277. mTriviaStart = triviaStart;
  1278. auto bfPreprocessorNode = mAlloc->Alloc<BfPreprocessorNode>();
  1279. mTokenStart = startIdx;
  1280. mTokenEnd = mSrcIdx;
  1281. bfPreprocessorNode->Init(this);
  1282. bfPreprocessorNode->Add(bfPreprocessorCmdNode);
  1283. bfPreprocessorNode->mCommand = bfPreprocessorCmdNode;
  1284. if (paramNode != NULL)
  1285. {
  1286. int curIdx = 0;
  1287. bfPreprocessorNode->mArgument = paramNode;
  1288. }
  1289. mPendingSideNodes.push_back(bfPreprocessorNode);
  1290. mTokenStart = mSrcIdx;
  1291. mTriviaStart = mSrcIdx;
  1292. triviaStart = mSrcIdx;
  1293. if (addToPreprocessorAccept)
  1294. mPreprocessorNodeStack.push_back(std::pair<BfAstNode*, bool>(bfPreprocessorNode, addToPreprocessorAcceptResolved));
  1295. if (mPreprocessorIgnoreDepth > 0)
  1296. {
  1297. mPreprocessorIgnoredSectionNode = mAlloc->Alloc<BfPreprocesorIgnoredSectionNode>();
  1298. mPreprocessorIgnoredSectionNode->Init(this);
  1299. mSidechannelRootNode->Add(mPreprocessorIgnoredSectionNode);
  1300. mPendingSideNodes.push_back(mPreprocessorIgnoredSectionNode);
  1301. }
  1302. return true;
  1303. }
  1304. static int ValSign(int64 val)
  1305. {
  1306. if (val < 0)
  1307. return -1;
  1308. if (val > 0)
  1309. return 1;
  1310. return 0;
  1311. }
  1312. template <int Len>
  1313. struct StrHashT
  1314. {
  1315. const static int HASH = 0;
  1316. };
  1317. template <>
  1318. struct StrHashT<4>
  1319. {
  1320. template <const char* Str>
  1321. struct DoHash
  1322. {
  1323. const static int HASH = (StrHashT<3>::HASH) ^ Str[4];
  1324. };
  1325. };
  1326. // This is little endian only
  1327. #define TOKEN_HASH(a, b, c, d) ((int)a << 0) | ((int)b << 8) | ((int)c << 16) | ((int)d << 24)
  1328. const int text_const = (1 << 2);
  1329. const int gClassConst = 0;
  1330. uint32 BfParser::GetTokenHash()
  1331. {
  1332. char hashChars[4] = { 0 };
  1333. int idx = 0;
  1334. uint32 tokenHash = 0;
  1335. int checkIdx = mSrcIdx - 1;
  1336. while ((!IsWhitespaceOrPunctuation(mSrc[checkIdx])) && (idx < 4))
  1337. {
  1338. hashChars[idx++] = mSrc[checkIdx];
  1339. checkIdx++;
  1340. }
  1341. return *((uint32*)hashChars);
  1342. }
  1343. double BfParser::ParseLiteralDouble()
  1344. {
  1345. char buf[256];
  1346. int len = std::min(mTokenEnd - mTokenStart, 255);
  1347. int outLen = 0;
  1348. for (int i = 0; i < len; i++)
  1349. {
  1350. char c = mSrc[mTokenStart + i];
  1351. if (c != '\'')
  1352. buf[outLen++] = c;
  1353. }
  1354. char c = buf[outLen - 1];
  1355. if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F'))
  1356. buf[outLen - 1] = '\0';
  1357. else
  1358. buf[outLen] = '\0';
  1359. return strtod(buf, NULL);
  1360. }
  1361. void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePreprocessor)
  1362. {
  1363. auto prevToken = mToken;
  1364. mToken = BfToken_None;
  1365. if (mSyntaxToken == BfSyntaxToken_EOF)
  1366. Fail("Unexpected end of file");
  1367. mTriviaStart = mSrcIdx;
  1368. bool isLineStart = true;
  1369. bool isVerbatim = false;
  1370. int interpolateSetting = 0;
  1371. int stringStart = -1;
  1372. while (true)
  1373. {
  1374. bool setVerbatim = false;
  1375. bool setInterpolate = false;
  1376. uint32 checkTokenHash = 0;
  1377. if ((endIdx != -1) && (mSrcIdx >= endIdx))
  1378. {
  1379. mSyntaxToken = BfSyntaxToken_HIT_END_IDX;
  1380. return;
  1381. }
  1382. mTokenStart = mSrcIdx;
  1383. mTokenEnd = mSrcIdx + 1;
  1384. char c = mSrc[mSrcIdx++];
  1385. if (outerIsInterpolate)
  1386. {
  1387. if (c == '"')
  1388. {
  1389. mSyntaxToken = BfSyntaxToken_StringQuote;
  1390. return;
  1391. }
  1392. }
  1393. if ((mPreprocessorIgnoreDepth > 0) && (endIdx == -1))
  1394. {
  1395. if (c == 0)
  1396. {
  1397. mSyntaxToken = BfSyntaxToken_EOF;
  1398. mSrcIdx--;
  1399. break;
  1400. }
  1401. if ((c == '>') && (mSrc[mSrcIdx] == '>') && (mSrc[mSrcIdx + 1] == '>'))
  1402. {
  1403. // Allow through
  1404. }
  1405. else if ((c != '#') || (!isLineStart))
  1406. {
  1407. if (c == '\n')
  1408. {
  1409. NewLine();
  1410. isLineStart = true;
  1411. continue;
  1412. }
  1413. if (IsWhitespace(c))
  1414. continue;
  1415. isLineStart = false;
  1416. continue;
  1417. }
  1418. }
  1419. switch (c)
  1420. {
  1421. case '!':
  1422. if (mSrc[mSrcIdx] == '=')
  1423. {
  1424. if (mSrc[mSrcIdx + 1] == '=')
  1425. {
  1426. mToken = BfToken_CompareStrictNotEquals;
  1427. ++mSrcIdx;
  1428. mTokenEnd = ++mSrcIdx;
  1429. }
  1430. else
  1431. {
  1432. mToken = BfToken_CompareNotEquals;
  1433. mTokenEnd = ++mSrcIdx;
  1434. }
  1435. }
  1436. else
  1437. mToken = BfToken_Bang;
  1438. mSyntaxToken = BfSyntaxToken_Token;
  1439. return;
  1440. case '=':
  1441. if (mSrc[mSrcIdx] == '=')
  1442. {
  1443. if (mSrc[mSrcIdx + 1] == '=')
  1444. {
  1445. if (mSrc[mSrcIdx + 2] == '=')
  1446. {
  1447. if (HandlePreprocessor())
  1448. {
  1449. // Conflict split
  1450. break;
  1451. }
  1452. else
  1453. {
  1454. mToken = BfToken_CompareStrictEquals;
  1455. ++mSrcIdx;
  1456. mTokenEnd = ++mSrcIdx;
  1457. }
  1458. }
  1459. else
  1460. {
  1461. mToken = BfToken_CompareStrictEquals;
  1462. ++mSrcIdx;
  1463. mTokenEnd = ++mSrcIdx;
  1464. }
  1465. }
  1466. else
  1467. {
  1468. mToken = BfToken_CompareEquals;
  1469. mTokenEnd = ++mSrcIdx;
  1470. }
  1471. }
  1472. else if (mSrc[mSrcIdx] == '>')
  1473. {
  1474. mToken = BfToken_FatArrow;
  1475. mTokenEnd = ++mSrcIdx;
  1476. }
  1477. else
  1478. mToken = BfToken_AssignEquals;
  1479. mSyntaxToken = BfSyntaxToken_Token;
  1480. return;
  1481. case '+':
  1482. if (mSrc[mSrcIdx] == '+')
  1483. {
  1484. mToken = BfToken_DblPlus;
  1485. mTokenEnd = ++mSrcIdx;
  1486. }
  1487. else if (mSrc[mSrcIdx] == '=')
  1488. {
  1489. mToken = BfToken_PlusEquals;
  1490. mTokenEnd = ++mSrcIdx;
  1491. }
  1492. else
  1493. mToken = BfToken_Plus;
  1494. mSyntaxToken = BfSyntaxToken_Token;
  1495. return;
  1496. case '^':
  1497. if (mSrc[mSrcIdx] == '=')
  1498. {
  1499. mToken = BfToken_XorEquals;
  1500. mTokenEnd = ++mSrcIdx;
  1501. }
  1502. else
  1503. mToken = BfToken_Carat;
  1504. mSyntaxToken = BfSyntaxToken_Token;
  1505. return;
  1506. case '~':
  1507. mToken = BfToken_Tilde;
  1508. mSyntaxToken = BfSyntaxToken_Token;
  1509. return;
  1510. case '%':
  1511. if (mSrc[mSrcIdx] == '=')
  1512. {
  1513. mToken = BfToken_ModulusEquals;
  1514. mTokenEnd = ++mSrcIdx;
  1515. }
  1516. else
  1517. mToken = BfToken_Modulus;
  1518. mSyntaxToken = BfSyntaxToken_Token;
  1519. return;
  1520. case '&':
  1521. if (mSrc[mSrcIdx] == '&')
  1522. {
  1523. mToken = BfToken_DblAmpersand;
  1524. mTokenEnd = ++mSrcIdx;
  1525. }
  1526. else if (mSrc[mSrcIdx] == '=')
  1527. {
  1528. mToken = BfToken_AndEquals;
  1529. mTokenEnd = ++mSrcIdx;
  1530. }
  1531. else if (mSrc[mSrcIdx] == '+')
  1532. {
  1533. if (mSrc[mSrcIdx + 1] == '=')
  1534. {
  1535. mToken = BfToken_AndPlusEquals;
  1536. ++mSrcIdx;
  1537. }
  1538. else
  1539. mToken = BfToken_AndPlus;
  1540. mTokenEnd = ++mSrcIdx;
  1541. }
  1542. else if (mSrc[mSrcIdx] == '-')
  1543. {
  1544. if (mSrc[mSrcIdx + 1] == '=')
  1545. {
  1546. mToken = BfToken_AndMinusEquals;
  1547. ++mSrcIdx;
  1548. }
  1549. else
  1550. mToken = BfToken_AndMinus;
  1551. mTokenEnd = ++mSrcIdx;
  1552. }
  1553. else if (mSrc[mSrcIdx] == '*')
  1554. {
  1555. if (mSrc[mSrcIdx + 1] == '=')
  1556. {
  1557. mToken = BfToken_AndStarEquals;
  1558. ++mSrcIdx;
  1559. }
  1560. else
  1561. mToken = BfToken_AndStar;
  1562. mTokenEnd = ++mSrcIdx;
  1563. }
  1564. else
  1565. mToken = BfToken_Ampersand;
  1566. mSyntaxToken = BfSyntaxToken_Token;
  1567. return;
  1568. case '|':
  1569. if (mSrc[mSrcIdx] == '|')
  1570. {
  1571. mToken = BfToken_DblBar;
  1572. mTokenEnd = ++mSrcIdx;
  1573. }
  1574. else if (mSrc[mSrcIdx] == '=')
  1575. {
  1576. mToken = BfToken_OrEquals;
  1577. mTokenEnd = ++mSrcIdx;
  1578. }
  1579. else
  1580. mToken = BfToken_Bar;
  1581. mSyntaxToken = BfSyntaxToken_Token;
  1582. return;
  1583. case '*':
  1584. if (mSrc[mSrcIdx] == '=')
  1585. {
  1586. mToken = BfToken_MultiplyEquals;
  1587. mTokenEnd = ++mSrcIdx;
  1588. }
  1589. else
  1590. mToken = BfToken_Star;
  1591. mSyntaxToken = BfSyntaxToken_Token;
  1592. return;
  1593. case '?':
  1594. if (mSrc[mSrcIdx] == '?')
  1595. {
  1596. mTokenEnd = ++mSrcIdx;
  1597. if (mSrc[mSrcIdx] == '=')
  1598. {
  1599. mToken = BfToken_NullCoalsceEquals;
  1600. mTokenEnd = ++mSrcIdx;
  1601. }
  1602. else
  1603. mToken = BfToken_DblQuestion;
  1604. }
  1605. else if (mSrc[mSrcIdx] == '.')
  1606. {
  1607. mToken = BfToken_QuestionDot;
  1608. mTokenEnd = ++mSrcIdx;
  1609. }
  1610. else if (mSrc[mSrcIdx] == '[')
  1611. {
  1612. mToken = BfToken_QuestionLBracket;
  1613. mTokenEnd = ++mSrcIdx;
  1614. }
  1615. else
  1616. mToken = BfToken_Question;
  1617. mSyntaxToken = BfSyntaxToken_Token;
  1618. return;
  1619. case '<':
  1620. if (mSrc[mSrcIdx] == '<')
  1621. {
  1622. mTokenEnd = ++mSrcIdx;
  1623. if (mSrc[mSrcIdx] == '=')
  1624. {
  1625. mToken = BfToken_ShiftLeftEquals;
  1626. mTokenEnd = ++mSrcIdx;
  1627. }
  1628. else if (mSrc[mSrcIdx] == '<')
  1629. {
  1630. mSrcIdx--;
  1631. if (HandlePreprocessor())
  1632. {
  1633. // Conflict end
  1634. break;
  1635. }
  1636. else
  1637. {
  1638. mSrcIdx++;
  1639. mToken = BfToken_LDblChevron;
  1640. }
  1641. }
  1642. else
  1643. mToken = BfToken_LDblChevron;
  1644. }
  1645. else if (mSrc[mSrcIdx] == '=')
  1646. {
  1647. if (mSrc[mSrcIdx + 1] == '>')
  1648. {
  1649. mToken = BfToken_Spaceship;
  1650. mSrcIdx += 2;
  1651. mTokenEnd = mSrcIdx;
  1652. }
  1653. else
  1654. {
  1655. mToken = BfToken_LessEquals;
  1656. mTokenEnd = ++mSrcIdx;
  1657. }
  1658. }
  1659. else
  1660. mToken = BfToken_LChevron;
  1661. mSyntaxToken = BfSyntaxToken_Token;
  1662. return;
  1663. case '>':
  1664. if (mSrc[mSrcIdx] == '>')
  1665. {
  1666. mTokenEnd = ++mSrcIdx;
  1667. if (mSrc[mSrcIdx] == '=')
  1668. {
  1669. mToken = BfToken_ShiftRightEquals;
  1670. mTokenEnd = ++mSrcIdx;
  1671. }
  1672. else if (mSrc[mSrcIdx] == '>')
  1673. {
  1674. mSrcIdx--;
  1675. if (HandlePreprocessor())
  1676. {
  1677. // Conflict start
  1678. break;
  1679. }
  1680. else
  1681. {
  1682. mSrcIdx++;
  1683. mToken = BfToken_RDblChevron;
  1684. }
  1685. }
  1686. else
  1687. mToken = BfToken_RDblChevron;
  1688. }
  1689. else if (mSrc[mSrcIdx] == '=')
  1690. {
  1691. mToken = BfToken_GreaterEquals;
  1692. mTokenEnd = ++mSrcIdx;
  1693. }
  1694. else
  1695. mToken = BfToken_RChevron;
  1696. mSyntaxToken = BfSyntaxToken_Token;
  1697. return;
  1698. case '@':
  1699. setVerbatim = true;
  1700. c = mSrc[mSrcIdx];
  1701. if ((c == '\"') || (c == '$'))
  1702. {
  1703. setVerbatim = true;
  1704. }
  1705. else if (((c >= 'A') && (c <= 'a')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || (c == '@'))
  1706. {
  1707. setVerbatim = true;
  1708. }
  1709. else
  1710. {
  1711. mSyntaxToken = BfSyntaxToken_Identifier;
  1712. return;
  1713. }
  1714. break;
  1715. case '$':
  1716. c = mSrc[mSrcIdx];
  1717. if ((c == '\"') || (c == '@') || (c == '$'))
  1718. {
  1719. setInterpolate = true;
  1720. }
  1721. else if (!mCompatMode)
  1722. Fail("Expected to precede string");
  1723. break;
  1724. case '"':
  1725. case '\'':
  1726. {
  1727. SizedArray<BfUnscopedBlock*, 4> interpolateExpressions;
  1728. String lineHeader;
  1729. String strLiteral;
  1730. char startChar = c;
  1731. bool isMultiline = false;
  1732. int triviaStart = mTriviaStart;
  1733. if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"'))
  1734. {
  1735. isMultiline = true;
  1736. mSrcIdx += 2;
  1737. }
  1738. int contentErrorStart = -1;
  1739. int lineIdx = 0;
  1740. int lineIndentIdx = -1;
  1741. if (isMultiline)
  1742. {
  1743. int checkIdx = mSrcIdx;
  1744. int lineStartIdx = checkIdx;
  1745. while (true)
  1746. {
  1747. char c = mSrc[checkIdx++];
  1748. if ((c == '"') && (mSrc[checkIdx] == '"') && (mSrc[checkIdx + 1] == '"'))
  1749. {
  1750. lineIndentIdx = lineStartIdx;
  1751. for (int i = lineStartIdx; i < checkIdx - 1; i++)
  1752. {
  1753. char c = mSrc[i];
  1754. if ((c != '\t') && (c != ' '))
  1755. {
  1756. mPassInstance->FailAt("Multi-line string literal closing delimiter must begin on a new line", mSourceData, i, checkIdx - i + 3);
  1757. break;
  1758. }
  1759. lineHeader.Append(c);
  1760. }
  1761. break;
  1762. }
  1763. else if (c == '\n')
  1764. {
  1765. if (contentErrorStart != -1)
  1766. {
  1767. mPassInstance->FailAt("Multi-line string literal content must begin on a new line", mSourceData, contentErrorStart, checkIdx - contentErrorStart - 1);
  1768. contentErrorStart = -1;
  1769. }
  1770. lineStartIdx = checkIdx;
  1771. lineIdx++;
  1772. }
  1773. else if (c == '\0')
  1774. break; // Will throw an error in next pass
  1775. else if ((c == ' ') || (c == '\t') || (c == '\r'))
  1776. {
  1777. // Allow
  1778. }
  1779. else if (lineIdx == 0)
  1780. {
  1781. if (contentErrorStart == -1)
  1782. contentErrorStart = checkIdx - 1;
  1783. }
  1784. }
  1785. }
  1786. int lineCount = lineIdx + 1;
  1787. lineIdx = 0;
  1788. int lineStart = mSrcIdx;
  1789. while (true)
  1790. {
  1791. char c = mSrc[mSrcIdx++];
  1792. if (c == '\0')
  1793. {
  1794. // Invalid file end
  1795. mPassInstance->FailAt("String not terminated", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  1796. mSrcIdx--;
  1797. break;
  1798. }
  1799. else if (c == '\n')
  1800. {
  1801. if (isMultiline)
  1802. {
  1803. lineIdx++;
  1804. if ((lineIdx > 1) && (lineIdx < lineCount - 1))
  1805. {
  1806. strLiteral += "\n";
  1807. }
  1808. lineStart = mSrcIdx;
  1809. for (int i = 0; i < lineHeader.GetLength(); i++)
  1810. {
  1811. char wantC = lineHeader[i];
  1812. char c = mSrc[mSrcIdx];
  1813. if (c == '\r')
  1814. continue;
  1815. if (c == '\n')
  1816. break;
  1817. if (wantC == c)
  1818. {
  1819. mSrcIdx++;
  1820. }
  1821. else
  1822. {
  1823. BfError* error = NULL;
  1824. if (c == ' ')
  1825. {
  1826. error = mPassInstance->FailAt("Unexpected space in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
  1827. }
  1828. else if (c == '\t')
  1829. {
  1830. error = mPassInstance->FailAt("Unexpected tab in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
  1831. }
  1832. else
  1833. {
  1834. error = mPassInstance->FailAt("Insufficient indentation of line in multi-line string literal", mSourceData, lineStart, mSrcIdx - lineStart + 1, BfFailFlag_ShowSpaceChars);
  1835. }
  1836. if (error != NULL)
  1837. {
  1838. mPassInstance->MoreInfoAt("Change indentation of this line to match closing delimiter", mSourceData, lineIndentIdx, lineHeader.GetLength(), BfFailFlag_ShowSpaceChars);
  1839. }
  1840. break;
  1841. }
  1842. }
  1843. NewLine();
  1844. }
  1845. else
  1846. {
  1847. mSrcIdx--;
  1848. int errorIdx = mSrcIdx - 1;
  1849. while ((errorIdx > 0) && (IsWhitespace(mSrc[errorIdx])))
  1850. errorIdx--;
  1851. mPassInstance->FailAfterAt("Newline not allowed in string", mSourceData, errorIdx);
  1852. break;
  1853. }
  1854. }
  1855. else if ((c == '"') && (c == startChar))
  1856. {
  1857. if (isMultiline)
  1858. {
  1859. if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"')) // Triple quote
  1860. {
  1861. // Done
  1862. mSrcIdx += 2;
  1863. break;
  1864. }
  1865. strLiteral += '"';
  1866. }
  1867. else
  1868. {
  1869. if (mSrc[mSrcIdx] == '"') // Double quote
  1870. {
  1871. strLiteral += '"';
  1872. mSrcIdx++;
  1873. }
  1874. else
  1875. break;
  1876. }
  1877. }
  1878. else if ((c == '\'') && (c == startChar))
  1879. {
  1880. break;
  1881. }
  1882. else if ((c == '\\') && (!isVerbatim))
  1883. {
  1884. char c = mSrc[mSrcIdx++];
  1885. switch (c)
  1886. {
  1887. case '0':
  1888. strLiteral += '\0';
  1889. break;
  1890. case 'a':
  1891. strLiteral += '\a';
  1892. break;
  1893. case 'b':
  1894. strLiteral += '\b';
  1895. break;
  1896. case 'f':
  1897. strLiteral += '\f';
  1898. break;
  1899. case 'n':
  1900. strLiteral += '\n';
  1901. break;
  1902. case 'r':
  1903. strLiteral += '\r';
  1904. break;
  1905. case 't':
  1906. strLiteral += '\t';
  1907. break;
  1908. case 'v':
  1909. strLiteral += '\v';
  1910. break;
  1911. case '\\':
  1912. case '"':
  1913. case '\'':
  1914. strLiteral += c;
  1915. break;
  1916. case '{':
  1917. case '}':
  1918. strLiteral += c;
  1919. if (interpolateSetting > 0)
  1920. strLiteral += c;
  1921. else
  1922. Fail("Invalid escape sequence");
  1923. break;
  1924. case 'x':
  1925. {
  1926. int wantHexChars = 2;
  1927. int hexVal = 0;
  1928. int numHexChars = 0;
  1929. while (true)
  1930. {
  1931. char c = mSrc[mSrcIdx];
  1932. int hexChar = 0;
  1933. if ((c >= '0') && (c <= '9'))
  1934. hexChar = c - '0';
  1935. else if ((c >= 'a') && (c <= 'f'))
  1936. hexChar = c - 'a' + 0xa;
  1937. else if ((c >= 'A') && (c <= 'F'))
  1938. hexChar = c - 'A' + 0xA;
  1939. else
  1940. {
  1941. Fail("Expected two hex characters");
  1942. break;
  1943. }
  1944. mSrcIdx++;
  1945. numHexChars++;
  1946. hexVal = (hexVal * 0x10) + hexChar;
  1947. if (numHexChars == wantHexChars)
  1948. break;
  1949. }
  1950. strLiteral += (char)hexVal;
  1951. }
  1952. break;
  1953. case 'u':
  1954. {
  1955. if (mSrc[mSrcIdx] != '{')
  1956. {
  1957. Fail("Expected hexadecimal code in braces after unicode escape");
  1958. break;
  1959. }
  1960. mSrcIdx++;
  1961. int hexStart = mSrcIdx;
  1962. int hexVal = 0;
  1963. int numHexChars = 0;
  1964. while (true)
  1965. {
  1966. char c = mSrc[mSrcIdx];
  1967. int hexChar = 0;
  1968. if (c == '}')
  1969. {
  1970. if (numHexChars == 0)
  1971. Fail("Unicode escape sequence expects hex digits");
  1972. mSrcIdx++;
  1973. break;
  1974. }
  1975. if ((c >= '0') && (c <= '9'))
  1976. hexChar = c - '0';
  1977. else if ((c >= 'a') && (c <= 'f'))
  1978. hexChar = c - 'a' + 0xa;
  1979. else if ((c >= 'A') && (c <= 'F'))
  1980. hexChar = c - 'A' + 0xA;
  1981. else
  1982. {
  1983. Fail("Hex encoding error");
  1984. break;
  1985. }
  1986. mSrcIdx++;
  1987. numHexChars++;
  1988. if (numHexChars > 8)
  1989. {
  1990. Fail("Too many hex digits for an unicode scalar");
  1991. }
  1992. hexVal = (hexVal * 0x10) + hexChar;
  1993. }
  1994. char outStrUTF8[8];
  1995. int size = u8_toutf8(outStrUTF8, 8, (uint32)hexVal);
  1996. if (size == 0)
  1997. {
  1998. mPassInstance->FailAt("Invalid unicode scalar", mSourceData, hexStart, mSrcIdx - hexStart - 1);
  1999. }
  2000. strLiteral += outStrUTF8;
  2001. }
  2002. break;
  2003. default:
  2004. Fail("Unrecognized escape sequence");
  2005. strLiteral += c;
  2006. }
  2007. }
  2008. else
  2009. {
  2010. strLiteral += c;
  2011. if (interpolateSetting > 0)
  2012. {
  2013. if (c == '{')
  2014. {
  2015. int braceCount = 1;
  2016. while (mSrc[mSrcIdx] == '{')
  2017. {
  2018. braceCount++;
  2019. mSrcIdx++;
  2020. }
  2021. int literalBraces = braceCount;
  2022. if (((interpolateSetting == 1) && (braceCount % 2 == 1)) ||
  2023. ((interpolateSetting > 1) && (braceCount >= interpolateSetting)))
  2024. {
  2025. BfUnscopedBlock* newBlock = mAlloc->Alloc<BfUnscopedBlock>();
  2026. mTokenStart = mSrcIdx - interpolateSetting;
  2027. mTriviaStart = mTokenStart;
  2028. mTokenEnd = mTokenStart + 1;
  2029. mToken = BfToken_LBrace;
  2030. newBlock->mOpenBrace = (BfTokenNode*)CreateNode();
  2031. newBlock->Init(this);
  2032. ParseBlock(newBlock, 1, true);
  2033. if (mToken == BfToken_RBrace)
  2034. {
  2035. newBlock->mCloseBrace = (BfTokenNode*)CreateNode();
  2036. newBlock->SetSrcEnd(mSrcIdx);
  2037. mSrcIdx--;
  2038. }
  2039. else if (mSyntaxToken == BfSyntaxToken_StringQuote)
  2040. {
  2041. mSrcIdx--;
  2042. mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
  2043. }
  2044. mInAsmBlock = false;
  2045. interpolateExpressions.Add(newBlock);
  2046. }
  2047. if (interpolateSetting == 1)
  2048. {
  2049. for (int i = 0; i < braceCount - 1; i++)
  2050. strLiteral += '{';
  2051. }
  2052. else
  2053. {
  2054. if (braceCount >= interpolateSetting)
  2055. {
  2056. for (int i = 0; i < (braceCount - interpolateSetting) * 2; i++)
  2057. strLiteral += '{';
  2058. }
  2059. else
  2060. {
  2061. for (int i = 0; i < braceCount * 2 - 1; i++)
  2062. strLiteral += '{';
  2063. }
  2064. }
  2065. }
  2066. else if (c == '}')
  2067. {
  2068. int braceCount = 1;
  2069. while (mSrc[mSrcIdx] == '}')
  2070. {
  2071. braceCount++;
  2072. mSrcIdx++;
  2073. }
  2074. bool isClosingBrace = false;
  2075. if (!interpolateExpressions.IsEmpty())
  2076. {
  2077. auto block = interpolateExpressions.back();
  2078. if (block->mCloseBrace == NULL)
  2079. {
  2080. mTokenStart = mSrcIdx - 1;
  2081. mTriviaStart = mTokenStart;
  2082. mTokenEnd = mTokenStart + 1;
  2083. mToken = BfToken_RBrace;
  2084. block->mCloseBrace = (BfTokenNode*)CreateNode();
  2085. block->SetSrcEnd(mSrcIdx);
  2086. isClosingBrace = true;
  2087. }
  2088. else if (block->mCloseBrace->mSrcStart == mSrcIdx - braceCount)
  2089. {
  2090. block->mCloseBrace->mSrcEnd = mSrcIdx - braceCount + interpolateSetting;
  2091. isClosingBrace = true;
  2092. }
  2093. }
  2094. if (interpolateSetting == 1)
  2095. {
  2096. for (int i = 0; i < braceCount - 1; i++)
  2097. strLiteral += '}';
  2098. if ((((isClosingBrace) && (braceCount > 1) && (braceCount % 2 == 0)) || ((!isClosingBrace)) && (braceCount % 2 == 1)))
  2099. {
  2100. mPassInstance->FailAt("Unpaired closing brace.", mSourceData, mSrcIdx - 1, 1);
  2101. }
  2102. }
  2103. else
  2104. {
  2105. if (isClosingBrace)
  2106. {
  2107. if (braceCount < interpolateSetting)
  2108. Fail("Mismatched closing brace set");
  2109. for (int i = 0; i < (braceCount - interpolateSetting) * 2; i++)
  2110. strLiteral += '}';
  2111. }
  2112. else
  2113. {
  2114. for (int i = 0; i < braceCount * 2 - 1; i++)
  2115. strLiteral += '}';
  2116. }
  2117. }
  2118. }
  2119. }
  2120. }
  2121. }
  2122. if (stringStart != -1)
  2123. {
  2124. mTokenStart = stringStart;
  2125. stringStart = -1;
  2126. }
  2127. mTriviaStart = triviaStart;
  2128. mTokenEnd = mSrcIdx;
  2129. mSyntaxToken = BfSyntaxToken_Literal;
  2130. if (startChar == '\'')
  2131. {
  2132. mLiteral.mTypeCode = BfTypeCode_Char8;
  2133. if (strLiteral.length() == 0)
  2134. {
  2135. if (mPreprocessorIgnoredSectionNode == NULL)
  2136. mPassInstance->FailAt("Empty char literal", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2137. }
  2138. else if (strLiteral.length() > 1)
  2139. {
  2140. int utf8Len = u8_seqlen((char*)strLiteral.c_str());
  2141. if (utf8Len == (int)strLiteral.length())
  2142. {
  2143. mLiteral.mUInt64 = u8_toucs((char*)strLiteral.c_str(), (int)strLiteral.length());
  2144. }
  2145. else if (mPreprocessorIgnoredSectionNode == NULL)
  2146. {
  2147. bool isGraphemeCluster = false;
  2148. // There's no explicit unicode limit to how many diacriticals a grapheme cluster can contain,
  2149. // but we apply a limit for sanity for the purpose of this error
  2150. if (strLiteral.length() < 64)
  2151. {
  2152. int numCodePoints;
  2153. int numCombiningMarks;
  2154. UTF8Categorize(strLiteral.c_str(), (int)strLiteral.length(), numCodePoints, numCombiningMarks);
  2155. isGraphemeCluster = numCodePoints - numCombiningMarks <= 1;
  2156. }
  2157. if (isGraphemeCluster)
  2158. mPassInstance->FailAt("Grapheme clusters cannot be used as character literals", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
  2159. else
  2160. mPassInstance->FailAt("Too many characters in character literal", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
  2161. }
  2162. }
  2163. else
  2164. {
  2165. mLiteral.mInt64 = (uint8)strLiteral[0];
  2166. }
  2167. if (mLiteral.mInt64 >= 0x8000) // Use 0x8000 to remain UTF16-compatible
  2168. mLiteral.mTypeCode = BfTypeCode_Char32;
  2169. else if (mLiteral.mInt64 >= 0x80) // Use 0x80 to remain UTF8-compatible
  2170. mLiteral.mTypeCode = BfTypeCode_Char16;
  2171. }
  2172. else
  2173. {
  2174. auto* strLiteralPtr = new String(std::move(strLiteral));
  2175. mParserData->mStringLiterals.push_back(strLiteralPtr);
  2176. mLiteral.mTypeCode = BfTypeCode_CharPtr;
  2177. mLiteral.mString = strLiteralPtr;
  2178. }
  2179. if (interpolateSetting > 0)
  2180. {
  2181. if (mLiteral.mTypeCode == BfTypeCode_CharPtr)
  2182. {
  2183. auto interpolateExpr = mAlloc->Alloc<BfStringInterpolationExpression>();
  2184. interpolateExpr->mString = mLiteral.mString;
  2185. interpolateExpr->mTriviaStart = mTriviaStart;
  2186. interpolateExpr->mSrcStart = mTokenStart;
  2187. interpolateExpr->mSrcEnd = mSrcIdx;
  2188. BfSizedArrayInitIndirect(interpolateExpr->mExpressions, interpolateExpressions, mAlloc);
  2189. mGeneratedNode = interpolateExpr;
  2190. mSyntaxToken = BfSyntaxToken_GeneratedNode;
  2191. mToken = BfToken_None;
  2192. }
  2193. }
  2194. return;
  2195. }
  2196. break;
  2197. case '/':
  2198. if (mSrc[mSrcIdx] == '/')
  2199. {
  2200. // Comment line
  2201. while (true)
  2202. {
  2203. char c = mSrc[mSrcIdx++];
  2204. if ((c == '\n') || (c == '\0'))
  2205. {
  2206. mSrcIdx--;
  2207. break;
  2208. }
  2209. }
  2210. mTokenEnd = mSrcIdx;
  2211. if (mPreprocessorIgnoredSectionNode == NULL)
  2212. {
  2213. auto commentKind = GetCommentKind(mTokenStart);
  2214. bool handled = false;
  2215. if (!mPendingSideNodes.IsEmpty())
  2216. {
  2217. if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
  2218. {
  2219. // This is required for folding '///' style multi-line documentation into a single node
  2220. if (prevComment->GetTriviaStart() == mTriviaStart)
  2221. {
  2222. auto prevCommentKind = GetCommentKind(prevComment->mSrcStart);
  2223. if ((!BfIsCommentBlock(commentKind)) && (commentKind == prevCommentKind))
  2224. {
  2225. prevComment->SetSrcEnd(mSrcIdx);
  2226. handled = true;
  2227. }
  2228. }
  2229. }
  2230. }
  2231. if ((!handled) && (!disablePreprocessor))
  2232. {
  2233. auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
  2234. bfCommentNode->Init(this);
  2235. bfCommentNode->mCommentKind = commentKind;
  2236. mSidechannelRootNode->Add(bfCommentNode);
  2237. mPendingSideNodes.push_back(bfCommentNode);
  2238. }
  2239. }
  2240. break;
  2241. }
  2242. else if (mSrc[mSrcIdx] == '=')
  2243. {
  2244. mToken = BfToken_DivideEquals;
  2245. mTokenEnd = ++mSrcIdx;
  2246. mSyntaxToken = BfSyntaxToken_Token;
  2247. return;
  2248. }
  2249. else if (mSrc[mSrcIdx] == '*')
  2250. {
  2251. // Comment block
  2252. int nestCount = 1;
  2253. mSrcIdx++;
  2254. while (true)
  2255. {
  2256. char c = mSrc[mSrcIdx++];
  2257. if (c == '\n')
  2258. {
  2259. NewLine();
  2260. }
  2261. else if ((c == '\0') || ((c == '*') && (mSrc[mSrcIdx] == '/')))
  2262. {
  2263. // Block ends
  2264. if (c == '\0')
  2265. {
  2266. nestCount = 0;
  2267. mSrcIdx--;
  2268. }
  2269. else
  2270. {
  2271. c = 0;
  2272. nestCount--;
  2273. mSrcIdx++;
  2274. }
  2275. if (nestCount == 0)
  2276. {
  2277. mTokenEnd = mSrcIdx;
  2278. if (mPreprocessorIgnoredSectionNode == NULL)
  2279. {
  2280. bool handled = false;
  2281. if (!mPendingSideNodes.IsEmpty())
  2282. {
  2283. if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
  2284. {
  2285. // This is required for folding documentation into a single node
  2286. if (prevComment->GetTriviaStart() == mTriviaStart)
  2287. {
  2288. //TODO: Why did we allow merging BLOCKS of comments together? This messes up BfPrinter word wrapping on comments
  2289. // if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
  2290. // {
  2291. // prevComment->SetSrcEnd(mSrcIdx);
  2292. // handled = true;
  2293. // }
  2294. }
  2295. }
  2296. }
  2297. if (!handled)
  2298. {
  2299. auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
  2300. bfCommentNode->Init(this);
  2301. bfCommentNode->mCommentKind = GetCommentKind(mTokenStart);
  2302. mSidechannelRootNode->Add(bfCommentNode);
  2303. mPendingSideNodes.push_back(bfCommentNode);
  2304. }
  2305. }
  2306. break;
  2307. }
  2308. }
  2309. else if ((!mCompatMode) && ((c == '/') && (mSrc[mSrcIdx] == '*') && (mSrc[mSrcIdx - 2] != '/')))
  2310. {
  2311. nestCount++;
  2312. mSrcIdx++;
  2313. }
  2314. }
  2315. }
  2316. else
  2317. {
  2318. mToken = BfToken_ForwardSlash;
  2319. mSyntaxToken = BfSyntaxToken_Token;
  2320. return;
  2321. }
  2322. break;
  2323. case '#':
  2324. if (disablePreprocessor)
  2325. {
  2326. mTokenStart = mSrcIdx - 1;
  2327. UnexpectedCharacter();
  2328. continue;
  2329. }
  2330. else
  2331. HandlePreprocessor();
  2332. if (mSyntaxToken == BfSyntaxToken_EOF)
  2333. return;
  2334. break;
  2335. case '.':
  2336. if (mSrc[mSrcIdx] == '.')
  2337. {
  2338. if (mSrc[mSrcIdx + 1] == '.')
  2339. {
  2340. mSrcIdx += 2;
  2341. mTokenEnd = mSrcIdx;
  2342. mToken = BfToken_DotDotDot;
  2343. mSyntaxToken = BfSyntaxToken_Token;
  2344. }
  2345. else if (mSrc[mSrcIdx + 1] == '<')
  2346. {
  2347. mSrcIdx += 2;
  2348. mTokenEnd = mSrcIdx;
  2349. mToken = BfToken_DotDotLess;
  2350. mSyntaxToken = BfSyntaxToken_Token;
  2351. }
  2352. else
  2353. {
  2354. mSrcIdx++;
  2355. mTokenEnd = mSrcIdx;
  2356. mToken = BfToken_DotDot;
  2357. mSyntaxToken = BfSyntaxToken_Token;
  2358. }
  2359. }
  2360. else
  2361. {
  2362. mToken = BfToken_Dot;
  2363. mSyntaxToken = BfSyntaxToken_Token;
  2364. }
  2365. return;
  2366. case ',':
  2367. mToken = BfToken_Comma;
  2368. mSyntaxToken = BfSyntaxToken_Token;
  2369. return;
  2370. case ';':
  2371. if (mInAsmBlock)
  2372. {
  2373. mToken = BfToken_AsmNewline;
  2374. mSyntaxToken = BfSyntaxToken_Token;
  2375. }
  2376. else
  2377. {
  2378. mToken = BfToken_Semicolon;
  2379. mSyntaxToken = BfSyntaxToken_Token;
  2380. }
  2381. return;
  2382. case ':':
  2383. {
  2384. if ((mCompatMode) && (mSrc[mSrcIdx] == ':'))
  2385. {
  2386. mSrcIdx++;
  2387. mTokenEnd = mSrcIdx;
  2388. mToken = BfToken_Dot;
  2389. mSyntaxToken = BfSyntaxToken_Token;
  2390. }
  2391. else if (mSrc[mSrcIdx] == ':')
  2392. {
  2393. mSrcIdx++;
  2394. mTokenEnd = mSrcIdx;
  2395. mToken = BfToken_ColonColon;
  2396. mSyntaxToken = BfSyntaxToken_Token;
  2397. }
  2398. else
  2399. {
  2400. mToken = BfToken_Colon;
  2401. mSyntaxToken = BfSyntaxToken_Token;
  2402. }
  2403. }
  2404. return;
  2405. case '(':
  2406. mToken = BfToken_LParen;
  2407. mSyntaxToken = BfSyntaxToken_Token;
  2408. return;
  2409. case ')':
  2410. mToken = BfToken_RParen;
  2411. mSyntaxToken = BfSyntaxToken_Token;
  2412. return;
  2413. case '{':
  2414. mToken = BfToken_LBrace;
  2415. mSyntaxToken = BfSyntaxToken_Token;
  2416. return;
  2417. case '}':
  2418. mToken = BfToken_RBrace;
  2419. mSyntaxToken = BfSyntaxToken_Token;
  2420. return;
  2421. case '[':
  2422. mToken = BfToken_LBracket;
  2423. mSyntaxToken = BfSyntaxToken_Token;
  2424. return;
  2425. case ']':
  2426. mToken = BfToken_RBracket;
  2427. mSyntaxToken = BfSyntaxToken_Token;
  2428. return;
  2429. case '\n':
  2430. NewLine();
  2431. if (!mInAsmBlock)
  2432. continue;
  2433. mToken = BfToken_AsmNewline;
  2434. mSyntaxToken = BfSyntaxToken_Token;
  2435. return;
  2436. case ' ':
  2437. case '\t':
  2438. case '\v':
  2439. case '\f':
  2440. case '\r':
  2441. continue; // Whitespace
  2442. case '\0':
  2443. mSrcIdx--; // Stay on EOF marker
  2444. mSyntaxToken = BfSyntaxToken_EOF;
  2445. return;
  2446. default:
  2447. if (((c >= '0') && (c <= '9')) || (c == '-'))
  2448. {
  2449. bool prevIsDot = prevToken == BfToken_Dot;
  2450. if (c == '-')
  2451. {
  2452. // Not a number!
  2453. if (mSrc[mSrcIdx] == '-')
  2454. {
  2455. mToken = BfToken_DblMinus;
  2456. mSrcIdx++;
  2457. }
  2458. else if (mSrc[mSrcIdx] == '=')
  2459. {
  2460. mToken = BfToken_MinusEquals;
  2461. mSrcIdx++;
  2462. }
  2463. else if (mSrc[mSrcIdx] == '>')
  2464. {
  2465. if (mCompatMode)
  2466. mToken = BfToken_Dot;
  2467. else
  2468. mToken = BfToken_Arrow;
  2469. mSrcIdx++;
  2470. }
  2471. else
  2472. mToken = BfToken_Minus;
  2473. mSyntaxToken = BfSyntaxToken_Token;
  2474. mTokenEnd = mSrcIdx;
  2475. return;
  2476. }
  2477. bool hadOverflow = false;
  2478. uint64 val = 0;
  2479. int numberBase = 10;
  2480. int expVal = 0;
  2481. int expSign = 0;
  2482. bool hasExp = false;
  2483. bool hadSeps = false;
  2484. bool hadLeadingHexSep = false;
  2485. int hexDigits = 0;
  2486. if (c == '-')
  2487. {
  2488. BF_FATAL("Parsing error");
  2489. }
  2490. val = c - '0';
  2491. if (c == '0')
  2492. {
  2493. switch (mSrc[mSrcIdx])
  2494. {
  2495. case 'b':
  2496. case 'B':
  2497. numberBase = 2;
  2498. mSrcIdx++;
  2499. break;
  2500. case 'o':
  2501. case 'O':
  2502. numberBase = 8;
  2503. mSrcIdx++;
  2504. break;
  2505. case 'x':
  2506. case 'X':
  2507. numberBase = 16;
  2508. mSrcIdx++;
  2509. break;
  2510. }
  2511. }
  2512. while (true)
  2513. {
  2514. char c = mSrc[mSrcIdx++];
  2515. if (c == '\'')
  2516. {
  2517. hadSeps = true;
  2518. if ((numberBase == 0x10) && (hexDigits == 0))
  2519. hadLeadingHexSep = true;
  2520. continue;
  2521. }
  2522. if ((numberBase == 10) && ((c == 'e') || (c == 'E')))
  2523. {
  2524. // Specifying exponent
  2525. while (true)
  2526. {
  2527. c = mSrc[mSrcIdx++];
  2528. if (c == '+')
  2529. {
  2530. if (expSign != 0)
  2531. TokenFail("Format error");
  2532. expSign = 1;
  2533. }
  2534. else if (c == '-')
  2535. {
  2536. if (expSign != 0)
  2537. TokenFail("Format error");
  2538. expSign = -1;
  2539. }
  2540. else if ((c >= '0') && (c <= '9'))
  2541. {
  2542. hasExp = true;
  2543. expVal *= 10;
  2544. expVal += c - '0';
  2545. }
  2546. else
  2547. {
  2548. if (expSign == -1)
  2549. expVal = -expVal;
  2550. mSrcIdx--;
  2551. break;
  2552. }
  2553. }
  2554. if (!hasExp)
  2555. {
  2556. TokenFail("Expected an exponent");
  2557. }
  2558. }
  2559. bool endNumber = false;
  2560. bool hasDot = c == '.';
  2561. if ((hasDot) && (mSrc[mSrcIdx] == '.'))
  2562. {
  2563. // Skip float parsing if we have a double-dot `1..` case
  2564. hasDot = false;
  2565. }
  2566. // The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float
  2567. if (((hasDot) && (!prevIsDot)) || (hasExp))
  2568. {
  2569. // Switch to floating point mode
  2570. //double dVal = val;
  2571. //double dValScale = 0.1;
  2572. //if (hasExp)
  2573. //dVal *= pow(10, expVal);
  2574. while (true)
  2575. {
  2576. char c = mSrc[mSrcIdx++];
  2577. if (IsWhitespaceOrPunctuation(c))
  2578. {
  2579. mTokenEnd = mSrcIdx - 1;
  2580. mSrcIdx--;
  2581. mLiteral.mTypeCode = BfTypeCode_Double;
  2582. mLiteral.mDouble = ParseLiteralDouble();//dVal;
  2583. mSyntaxToken = BfSyntaxToken_Literal;
  2584. return;
  2585. }
  2586. if ((c == 'e') || (c == 'E'))
  2587. {
  2588. // Specifying exponent
  2589. if (hasExp)
  2590. TokenFail("Format error");
  2591. while (true)
  2592. {
  2593. c = mSrc[mSrcIdx++];
  2594. if (c == '+')
  2595. {
  2596. if (expSign != 0)
  2597. TokenFail("Format error");
  2598. expSign = 1;
  2599. }
  2600. else if (c == '-')
  2601. {
  2602. if (expSign != 0)
  2603. TokenFail("Format error");
  2604. expSign = -1;
  2605. }
  2606. else if ((c >= '0') && (c <= '9'))
  2607. {
  2608. hasExp = true;
  2609. expVal *= 10;
  2610. expVal += c - '0';
  2611. }
  2612. else
  2613. {
  2614. if (expSign == -1)
  2615. expVal = -expVal;
  2616. mSrcIdx--;
  2617. //dVal *= pow(10, expVal);
  2618. break;
  2619. }
  2620. }
  2621. if (!hasExp)
  2622. {
  2623. TokenFail("Expected an exponent");
  2624. }
  2625. continue;
  2626. }
  2627. if ((c == 'f') || (c == 'F'))
  2628. {
  2629. mTokenEnd = mSrcIdx;
  2630. mLiteral.mTypeCode = BfTypeCode_Float;
  2631. mLiteral.mSingle = (float)ParseLiteralDouble();//(float)dVal;
  2632. mSyntaxToken = BfSyntaxToken_Literal;
  2633. return;
  2634. }
  2635. else if ((c == 'd') || (c == 'D'))
  2636. {
  2637. mTokenEnd = mSrcIdx;
  2638. mLiteral.mTypeCode = BfTypeCode_Double;
  2639. mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
  2640. mSyntaxToken = BfSyntaxToken_Literal;
  2641. return;
  2642. }
  2643. else if ((c >= '0') && (c <= '9'))
  2644. {
  2645. //dVal += (c - '0') * dValScale;
  2646. //dValScale *= 0.1;
  2647. }
  2648. else if ((((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) &&
  2649. (mSrc[mSrcIdx - 2] == '.'))
  2650. {
  2651. // This is actually a integer followed by an Int32 call (like 123.ToString)
  2652. mSrcIdx -= 2;
  2653. mTokenEnd = mSrcIdx;
  2654. mLiteral.mUInt64 = val;
  2655. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2656. mSyntaxToken = BfSyntaxToken_Literal;
  2657. return;
  2658. }
  2659. else
  2660. {
  2661. mSrcIdx--;
  2662. mTokenEnd = mSrcIdx;
  2663. mLiteral.mTypeCode = BfTypeCode_Double;
  2664. mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
  2665. mSyntaxToken = BfSyntaxToken_Literal;
  2666. TokenFail("Unexpected character while parsing number", 0);
  2667. return;
  2668. }
  2669. }
  2670. return;
  2671. }
  2672. else if (c == '.')
  2673. endNumber = true;
  2674. if (IsWhitespaceOrPunctuation(c))
  2675. endNumber = true;
  2676. if (endNumber)
  2677. {
  2678. mTokenEnd = mSrcIdx - 1;
  2679. mSrcIdx--;
  2680. if ((numberBase == 0x10) &&
  2681. ((hexDigits >= 16) || ((hadSeps) && (hexDigits > 8)) || ((hadLeadingHexSep) && (hexDigits == 8))))
  2682. {
  2683. if (hexDigits > 16)
  2684. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2685. mLiteral.mUInt64 = val;
  2686. if (val >= 0x8000000000000000)
  2687. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2688. else
  2689. mLiteral.mTypeCode = BfTypeCode_Int64;
  2690. }
  2691. else
  2692. {
  2693. mLiteral.mUInt64 = val;
  2694. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2695. if ((numberBase == 0x10) && (hexDigits == 7))
  2696. mLiteral.mWarnType = BfWarning_BF4201_Only7Hex;
  2697. if ((numberBase == 0x10) && (hexDigits == 9))
  2698. mLiteral.mWarnType = BfWarning_BF4202_TooManyHexForInt;
  2699. if (hadOverflow)
  2700. {
  2701. mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2702. mLiteral.mTypeCode = BfTypeCode_Int64;
  2703. }
  2704. //else if ((val < -0x80000000LL) || (val > 0xFFFFFFFFLL))
  2705. else if (val >= 0x8000000000000000)
  2706. {
  2707. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2708. }
  2709. else if (val > 0xFFFFFFFFLL)
  2710. {
  2711. mLiteral.mTypeCode = BfTypeCode_Int64;
  2712. }
  2713. }
  2714. mSyntaxToken = BfSyntaxToken_Literal;
  2715. return;
  2716. }
  2717. uint64 prevVal = val;
  2718. if ((c >= '0') && (c <= '9') && (c < '0' + numberBase))
  2719. {
  2720. if (numberBase == 0x10)
  2721. hexDigits++;
  2722. val *= numberBase;
  2723. val += c - '0';
  2724. }
  2725. else if ((numberBase == 0x10) && (c >= 'A') && (c <= 'F'))
  2726. {
  2727. hexDigits++;
  2728. val *= numberBase;
  2729. val += c - 'A' + 0xA;
  2730. }
  2731. else if ((numberBase == 0x10) && (c >= 'a') && (c <= 'f'))
  2732. {
  2733. hexDigits++;
  2734. val *= numberBase;
  2735. val += c - 'a' + 0xa;
  2736. }
  2737. else if ((c == 'u') || (c == 'U'))
  2738. {
  2739. if ((mSrc[mSrcIdx] == 'l') || (mSrc[mSrcIdx] == 'L'))
  2740. {
  2741. if (mSrc[mSrcIdx] == 'l')
  2742. TokenFail("Uppercase 'L' required for int64");
  2743. mSrcIdx++;
  2744. mTokenEnd = mSrcIdx;
  2745. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2746. mLiteral.mUInt64 = (uint64)val;
  2747. if (hexDigits > 16)
  2748. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2749. else if (hadOverflow)
  2750. mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2751. mSyntaxToken = BfSyntaxToken_Literal;
  2752. return;
  2753. }
  2754. mTokenEnd = mSrcIdx;
  2755. mLiteral.mTypeCode = BfTypeCode_UIntPtr;
  2756. mLiteral.mUInt32 = (uint32)val;
  2757. if ((hadOverflow) || ((uint64)val != (uint64)mLiteral.mUInt32))
  2758. mPassInstance->FailAt("Value doesn't fit into uint32", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2759. mSyntaxToken = BfSyntaxToken_Literal;
  2760. return;
  2761. }
  2762. else if ((c == 'l') || (c == 'L'))
  2763. {
  2764. if (c == 'l')
  2765. TokenFail("Uppercase 'L' required for int64");
  2766. if ((mSrc[mSrcIdx] == 'u') || (mSrc[mSrcIdx] == 'U'))
  2767. {
  2768. mSrcIdx++;
  2769. mTokenEnd = mSrcIdx;
  2770. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2771. mLiteral.mUInt64 = (uint64)val;
  2772. if (hexDigits > 16)
  2773. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2774. else if (hadOverflow)
  2775. mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2776. mSyntaxToken = BfSyntaxToken_Literal;
  2777. return;
  2778. }
  2779. mTokenEnd = mSrcIdx;
  2780. mLiteral.mTypeCode = BfTypeCode_Int64;
  2781. mLiteral.mInt64 = (int64)val;
  2782. if (val == 0x8000000000000000)
  2783. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2784. else if (val >= 0x8000000000000000)
  2785. hadOverflow = true;
  2786. if (numberBase == 0x10)
  2787. {
  2788. if (hexDigits > 16)
  2789. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2790. }
  2791. else if (hadOverflow)
  2792. mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2793. mSyntaxToken = BfSyntaxToken_Literal;
  2794. return;
  2795. }
  2796. else if ((c == 'f') || (c == 'F'))
  2797. {
  2798. mTokenEnd = mSrcIdx;
  2799. mLiteral.mTypeCode = BfTypeCode_Float;
  2800. mLiteral.mSingle = (float)ParseLiteralDouble();//(float)val;
  2801. mSyntaxToken = BfSyntaxToken_Literal;
  2802. return;
  2803. }
  2804. else if ((c == 'd') || (c == 'D'))
  2805. {
  2806. mTokenEnd = mSrcIdx;
  2807. mLiteral.mTypeCode = BfTypeCode_Double;
  2808. mLiteral.mDouble = ParseLiteralDouble();//(double)val;
  2809. mSyntaxToken = BfSyntaxToken_Literal;
  2810. return;
  2811. }
  2812. else
  2813. {
  2814. mTokenEnd = mSrcIdx - 1;
  2815. mSrcIdx--;
  2816. mLiteral.mUInt64 = val;
  2817. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2818. mSyntaxToken = BfSyntaxToken_Literal;
  2819. TokenFail("Unexpected character while parsing number", 0);
  2820. return;
  2821. }
  2822. if ((uint64)prevVal > (uint64)val)
  2823. hadOverflow = true;
  2824. }
  2825. }
  2826. else
  2827. {
  2828. if ((mCompatMode) && (c == '\\'))
  2829. {
  2830. int checkIdx = mSrcIdx;
  2831. bool isAtLineEnd = true;
  2832. while (true)
  2833. {
  2834. char checkC = mSrc[checkIdx];
  2835. if ((checkC == '\r') || (checkC == '\n'))
  2836. break;
  2837. if ((checkC != ' ') && (checkC != '\t'))
  2838. {
  2839. isAtLineEnd = false;
  2840. break;
  2841. }
  2842. checkIdx++;
  2843. }
  2844. if (isAtLineEnd)
  2845. continue;
  2846. }
  2847. if (!isVerbatim)
  2848. {
  2849. switch (GetTokenHash())
  2850. {
  2851. case TOKEN_HASH('t', 'r', 'u', 'e'):
  2852. if (SrcPtrHasToken("true"))
  2853. {
  2854. mLiteral.mTypeCode = BfTypeCode_Boolean;
  2855. mLiteral.mInt64 = 1;
  2856. mSyntaxToken = BfSyntaxToken_Literal;
  2857. return;
  2858. }
  2859. break;
  2860. case TOKEN_HASH('f', 'a', 'l', 's'):
  2861. if (SrcPtrHasToken("false"))
  2862. {
  2863. mLiteral.mTypeCode = BfTypeCode_Boolean;
  2864. mLiteral.mInt64 = 0;
  2865. mSyntaxToken = BfSyntaxToken_Literal;
  2866. return;
  2867. }
  2868. break;
  2869. case TOKEN_HASH('a', 'b', 's', 't'):
  2870. if ((!mCompatMode) && (SrcPtrHasToken("abstract")))
  2871. mToken = BfToken_Abstract;
  2872. break;
  2873. case TOKEN_HASH('a', 'l', 'l', 'o'):
  2874. if (SrcPtrHasToken("alloctype"))
  2875. mToken = BfToken_AllocType;
  2876. break;
  2877. case TOKEN_HASH('a', 'l', 'i', 'g'):
  2878. if (SrcPtrHasToken("alignof"))
  2879. mToken = BfToken_AlignOf;
  2880. break;
  2881. case TOKEN_HASH('a', 'p', 'p', 'e'):
  2882. if ((!mCompatMode) && (SrcPtrHasToken("append")))
  2883. mToken = BfToken_Append;
  2884. break;
  2885. case TOKEN_HASH('a', 's', 0, 0):
  2886. if ((!mCompatMode) && (SrcPtrHasToken("as")))
  2887. mToken = BfToken_As;
  2888. break;
  2889. case TOKEN_HASH('a', 's', 'm', 0):
  2890. if (SrcPtrHasToken("asm"))
  2891. mToken = BfToken_Asm;
  2892. break;
  2893. case TOKEN_HASH('b', 'a', 's', 'e'):
  2894. if (SrcPtrHasToken("base"))
  2895. mToken = BfToken_Base;
  2896. break;
  2897. case TOKEN_HASH('b', 'o', 'x', 0):
  2898. if ((!mCompatMode) && (SrcPtrHasToken("box")))
  2899. mToken = BfToken_Box;
  2900. break;
  2901. case TOKEN_HASH('b', 'r', 'e', 'a'):
  2902. if (SrcPtrHasToken("break"))
  2903. mToken = BfToken_Break;
  2904. break;
  2905. case TOKEN_HASH('c', 'a', 's', 'e'):
  2906. if (SrcPtrHasToken("case"))
  2907. mToken = BfToken_Case;
  2908. break;
  2909. case TOKEN_HASH('c', 'a', 't', 'c'):
  2910. if (SrcPtrHasToken("catch"))
  2911. mToken = BfToken_Catch;
  2912. break;
  2913. case TOKEN_HASH('c', 'h', 'e', 'c'):
  2914. if ((!mCompatMode) && (SrcPtrHasToken("checked")))
  2915. mToken = BfToken_Checked;
  2916. break;
  2917. case TOKEN_HASH('c', 'l', 'a', 's'):
  2918. if (SrcPtrHasToken("class"))
  2919. mToken = BfToken_Class;
  2920. break;
  2921. case TOKEN_HASH('c', 'o', 'm', 'p'):
  2922. if ((!mCompatMode) && (SrcPtrHasToken("comptype")))
  2923. mToken = BfToken_Comptype;
  2924. break;
  2925. case TOKEN_HASH('c', 'o', 'n', 'c'):
  2926. if ((!mCompatMode) && (SrcPtrHasToken("concrete")))
  2927. mToken = BfToken_Concrete;
  2928. break;
  2929. case TOKEN_HASH('c', 'o', 'n', 's'):
  2930. if (SrcPtrHasToken("const"))
  2931. mToken = BfToken_Const;
  2932. break;
  2933. case TOKEN_HASH('c', 'o', 'n', 't'):
  2934. if (SrcPtrHasToken("continue"))
  2935. mToken = BfToken_Continue;
  2936. break;
  2937. case TOKEN_HASH('d', 'e', 'c', 'l'):
  2938. if (SrcPtrHasToken("decltype"))
  2939. mToken = BfToken_Decltype;
  2940. break;
  2941. case TOKEN_HASH('d', 'e', 'f', 'a'):
  2942. if (SrcPtrHasToken("default"))
  2943. mToken = BfToken_Default;
  2944. break;
  2945. case TOKEN_HASH('d', 'e', 'f', 'e'):
  2946. if ((!mCompatMode) && (SrcPtrHasToken("defer")))
  2947. mToken = BfToken_Defer;
  2948. break;
  2949. case TOKEN_HASH('d', 'e', 'l', 'e'):
  2950. if ((!mCompatMode) && (SrcPtrHasToken("delegate")))
  2951. mToken = BfToken_Delegate;
  2952. else if (SrcPtrHasToken("delete"))
  2953. mToken = BfToken_Delete;
  2954. break;
  2955. case TOKEN_HASH('d', 'o', 0, 0):
  2956. if (SrcPtrHasToken("do"))
  2957. mToken = BfToken_Do;
  2958. break;
  2959. break;
  2960. case TOKEN_HASH('e', 'l', 's', 'e'):
  2961. if (SrcPtrHasToken("else"))
  2962. mToken = BfToken_Else;
  2963. break;
  2964. case TOKEN_HASH('e', 'n', 'u', 'm'):
  2965. if (SrcPtrHasToken("enum"))
  2966. mToken = BfToken_Enum;
  2967. break;
  2968. case TOKEN_HASH('e', 'x', 'p', 'l'):
  2969. if ((!mCompatMode) && (SrcPtrHasToken("explicit")))
  2970. mToken = BfToken_Explicit;
  2971. break;
  2972. case TOKEN_HASH('e', 'x', 't', 'e'):
  2973. if (SrcPtrHasToken("extern"))
  2974. mToken = BfToken_Extern;
  2975. else if ((!mCompatMode) && (SrcPtrHasToken("extension")))
  2976. mToken = BfToken_Extension;
  2977. break;
  2978. case TOKEN_HASH('f', 'a', 'l', 'l'):
  2979. if ((!mCompatMode) && (SrcPtrHasToken("fallthrough")))
  2980. mToken = BfToken_Fallthrough;
  2981. break;
  2982. case TOKEN_HASH('f', 'i', 'n', 'a'):
  2983. if (SrcPtrHasToken("finally"))
  2984. mToken = BfToken_Finally;
  2985. break;
  2986. case TOKEN_HASH('f', 'i', 'x', 'e'):
  2987. if (SrcPtrHasToken("fixed"))
  2988. mToken = BfToken_Fixed;
  2989. break;
  2990. case TOKEN_HASH('f', 'o', 'r', 0):
  2991. if (SrcPtrHasToken("for"))
  2992. mToken = BfToken_For;
  2993. break;
  2994. case TOKEN_HASH('f', 'o', 'r', 'e'):
  2995. if ((!mCompatMode) && (SrcPtrHasToken("foreach")))
  2996. {
  2997. mToken = BfToken_For;
  2998. mPassInstance->WarnAt(0, "'foreach' should be renamed to 'for'", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2999. }
  3000. break;
  3001. case TOKEN_HASH('f', 'u', 'n', 'c'):
  3002. if ((!mCompatMode) && (SrcPtrHasToken("function")))
  3003. mToken = BfToken_Function;
  3004. break;
  3005. case TOKEN_HASH('g', 'o', 't', 'o'):
  3006. if (SrcPtrHasToken("goto"))
  3007. mToken = BfToken_Goto;
  3008. break;
  3009. case TOKEN_HASH('i', 'f', 0, 0):
  3010. if (SrcPtrHasToken("if"))
  3011. mToken = BfToken_If;
  3012. break;
  3013. case TOKEN_HASH('i', 'm', 'p', 'l'):
  3014. if ((!mCompatMode) && (SrcPtrHasToken("implicit")))
  3015. mToken = BfToken_Implicit;
  3016. break;
  3017. case TOKEN_HASH('i', 'n', 0, 0):
  3018. if ((!mCompatMode) && (SrcPtrHasToken("in")))
  3019. mToken = BfToken_In;
  3020. break;
  3021. case TOKEN_HASH('i', 'n', 'l', 'i'):
  3022. if ((!mCompatMode) && (SrcPtrHasToken("inline")))
  3023. mToken = BfToken_Inline;
  3024. break;
  3025. case TOKEN_HASH('i', 'n', 't', 'e'):
  3026. if ((!mCompatMode) && (SrcPtrHasToken("interface")))
  3027. mToken = BfToken_Interface;
  3028. else if ((!mCompatMode) && (SrcPtrHasToken("internal")))
  3029. mToken = BfToken_Internal;
  3030. break;
  3031. case TOKEN_HASH('i', 's', 0, 0):
  3032. if ((!mCompatMode) && (SrcPtrHasToken("is")))
  3033. mToken = BfToken_Is;
  3034. break;
  3035. case TOKEN_HASH('i', 's', 'c', 'o'):
  3036. if ((!mCompatMode) && (SrcPtrHasToken("isconst")))
  3037. mToken = BfToken_IsConst;
  3038. break;
  3039. case TOKEN_HASH('l', 'e', 't', 0):
  3040. if ((!mCompatMode) && (SrcPtrHasToken("let")))
  3041. mToken = BfToken_Let;
  3042. break;
  3043. case TOKEN_HASH('m', 'i', 'x', 'i'):
  3044. if ((!mCompatMode) && (SrcPtrHasToken("mixin")))
  3045. mToken = BfToken_Mixin;
  3046. break;
  3047. case TOKEN_HASH('m', 'u', 't', 0):
  3048. if ((!mCompatMode) && (SrcPtrHasToken("mut")))
  3049. mToken = BfToken_Mut;
  3050. break;
  3051. case TOKEN_HASH('n', 'a', 'm', 'e'):
  3052. if (SrcPtrHasToken("namespace"))
  3053. mToken = BfToken_Namespace;
  3054. else if (SrcPtrHasToken("nameof"))
  3055. mToken = BfToken_NameOf;
  3056. break;
  3057. case TOKEN_HASH('n', 'e', 'w', 0):
  3058. if (SrcPtrHasToken("new"))
  3059. mToken = BfToken_New;
  3060. break;
  3061. case TOKEN_HASH('n', 'u', 'l', 'l'):
  3062. if (SrcPtrHasToken("null"))
  3063. mToken = BfToken_Null;
  3064. else if (SrcPtrHasToken("nullable"))
  3065. mToken = BfToken_Nullable;
  3066. break;
  3067. case TOKEN_HASH('o', 'f', 'f', 's'):
  3068. if (SrcPtrHasToken("offsetof"))
  3069. mToken = BfToken_OffsetOf;
  3070. break;
  3071. case TOKEN_HASH('o', 'p', 'e', 'r'):
  3072. if (SrcPtrHasToken("operator"))
  3073. mToken = BfToken_Operator;
  3074. break;
  3075. case TOKEN_HASH('o', 'u', 't', 0):
  3076. if ((!mCompatMode) && (SrcPtrHasToken("out")))
  3077. mToken = BfToken_Out;
  3078. break;
  3079. case TOKEN_HASH('o', 'v', 'e', 'r'):
  3080. if (SrcPtrHasToken("override"))
  3081. mToken = BfToken_Override;
  3082. break;
  3083. case TOKEN_HASH('p', 'a', 'r', 'a'):
  3084. if ((!mCompatMode) && (SrcPtrHasToken("params")))
  3085. mToken = BfToken_Params;
  3086. break;
  3087. case TOKEN_HASH('p', 'r', 'i', 'v'):
  3088. if (SrcPtrHasToken("private"))
  3089. mToken = BfToken_Private;
  3090. break;
  3091. case TOKEN_HASH('p', 'r', 'o', 't'):
  3092. if (SrcPtrHasToken("protected"))
  3093. mToken = BfToken_Protected;
  3094. break;
  3095. case TOKEN_HASH('p', 'u', 'b', 'l'):
  3096. if (SrcPtrHasToken("public"))
  3097. mToken = BfToken_Public;
  3098. break;
  3099. case TOKEN_HASH('r', 'e', 'a', 'd'):
  3100. if ((!mCompatMode) && (SrcPtrHasToken("readonly")))
  3101. mToken = BfToken_ReadOnly;
  3102. break;
  3103. case TOKEN_HASH('r', 'e', 'f', 0):
  3104. if ((!mCompatMode) && (SrcPtrHasToken("ref")))
  3105. mToken = BfToken_Ref;
  3106. break;
  3107. case TOKEN_HASH('r', 'e', 'p', 'e'):
  3108. if ((!mCompatMode) && (SrcPtrHasToken("repeat")))
  3109. mToken = BfToken_Repeat;
  3110. break;
  3111. case TOKEN_HASH('r', 'e', 't', 't'):
  3112. if ((!mCompatMode) && (SrcPtrHasToken("rettype")))
  3113. mToken = BfToken_RetType;
  3114. break;
  3115. case TOKEN_HASH('r', 'e', 't', 'u'):
  3116. if (SrcPtrHasToken("return"))
  3117. mToken = BfToken_Return;
  3118. break;
  3119. case TOKEN_HASH('s', 'c', 'o', 'p'):
  3120. if ((!mCompatMode) && (SrcPtrHasToken("scope")))
  3121. mToken = BfToken_Scope;
  3122. break;
  3123. case TOKEN_HASH('s', 'e', 'a', 'l'):
  3124. if ((!mCompatMode) && (SrcPtrHasToken("sealed")))
  3125. mToken = BfToken_Sealed;
  3126. break;
  3127. case TOKEN_HASH('s', 'i', 'z', 'e'):
  3128. if (SrcPtrHasToken("sizeof"))
  3129. mToken = BfToken_SizeOf;
  3130. break;
  3131. case TOKEN_HASH('s', 't', 'a', 't'):
  3132. if (SrcPtrHasToken("static"))
  3133. mToken = BfToken_Static;
  3134. break;
  3135. case TOKEN_HASH('s', 't', 'r', 'i'):
  3136. if (SrcPtrHasToken("strideof"))
  3137. mToken = BfToken_StrideOf;
  3138. break;
  3139. case TOKEN_HASH('s', 't', 'r', 'u'):
  3140. if (SrcPtrHasToken("struct"))
  3141. mToken = BfToken_Struct;
  3142. break;
  3143. case TOKEN_HASH('s', 'w', 'i', 't'):
  3144. if (SrcPtrHasToken("switch"))
  3145. mToken = BfToken_Switch;
  3146. break;
  3147. case TOKEN_HASH('t', 'h', 'i', 's'):
  3148. if (SrcPtrHasToken("this"))
  3149. mToken = BfToken_This;
  3150. break;
  3151. case TOKEN_HASH('t', 'h', 'r', 'o'):
  3152. if (SrcPtrHasToken("throw"))
  3153. mToken = BfToken_Throw;
  3154. break;
  3155. case TOKEN_HASH('t', 'r', 'y', 0):
  3156. if (SrcPtrHasToken("try"))
  3157. mToken = BfToken_Try;
  3158. break;
  3159. case TOKEN_HASH('t', 'y', 'p', 'e'):
  3160. if (SrcPtrHasToken("typeof"))
  3161. mToken = BfToken_TypeOf;
  3162. else if (SrcPtrHasToken("typealias"))
  3163. mToken = BfToken_TypeAlias;
  3164. break;
  3165. case TOKEN_HASH('u', 'n', 'c', 'h'):
  3166. if (SrcPtrHasToken("unchecked"))
  3167. mToken = BfToken_Unchecked;
  3168. break;
  3169. case TOKEN_HASH('u', 'n', 's', 'i'):
  3170. if (mCompatMode)
  3171. {
  3172. if (SrcPtrHasToken("unsigned"))
  3173. mToken = BfToken_Unsigned;
  3174. }
  3175. break;
  3176. case TOKEN_HASH('u', 's', 'i', 'n'):
  3177. if (SrcPtrHasToken("using"))
  3178. mToken = BfToken_Using;
  3179. break;
  3180. case TOKEN_HASH('v', 'a', 'r', 0):
  3181. if ((!mCompatMode) && (SrcPtrHasToken("var")))
  3182. mToken = BfToken_Var;
  3183. break;
  3184. case TOKEN_HASH('v', 'i', 'r', 't'):
  3185. if (SrcPtrHasToken("virtual"))
  3186. mToken = BfToken_Virtual;
  3187. break;
  3188. case TOKEN_HASH('v', 'o', 'l', 'a'):
  3189. if (SrcPtrHasToken("volatile"))
  3190. mToken = BfToken_Volatile;
  3191. break;
  3192. case TOKEN_HASH('w', 'h', 'e', 'n'):
  3193. if (SrcPtrHasToken("when"))
  3194. mToken = BfToken_When;
  3195. break;
  3196. case TOKEN_HASH('w', 'h', 'e', 'r'):
  3197. if (SrcPtrHasToken("where"))
  3198. mToken = BfToken_Where;
  3199. break;
  3200. case TOKEN_HASH('w', 'h', 'i', 'l'):
  3201. if (SrcPtrHasToken("while"))
  3202. mToken = BfToken_While;
  3203. break;
  3204. case TOKEN_HASH('y', 'i', 'e', 'l'):
  3205. if ((!mCompatMode) && (SrcPtrHasToken("yield")))
  3206. mToken = BfToken_Yield;
  3207. break;
  3208. }
  3209. }
  3210. if (mToken != BfToken_None)
  3211. {
  3212. mSyntaxToken = BfSyntaxToken_Token;
  3213. return;
  3214. }
  3215. bool allowChar = false;
  3216. if (mCompatMode)
  3217. allowChar = (c == '$') || (c == '`');
  3218. if ((uint8)c >= 0xC0)
  3219. {
  3220. int cLen = 0;
  3221. mSrcIdx--;
  3222. uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
  3223. mSrcIdx += cLen;
  3224. utf8proc_category_t cat = utf8proc_category(c32);
  3225. switch (cat)
  3226. {
  3227. case UTF8PROC_CATEGORY_LU:
  3228. case UTF8PROC_CATEGORY_LL:
  3229. case UTF8PROC_CATEGORY_LT:
  3230. case UTF8PROC_CATEGORY_LM:
  3231. case UTF8PROC_CATEGORY_LO:
  3232. case UTF8PROC_CATEGORY_NL:
  3233. case UTF8PROC_CATEGORY_SM:
  3234. case UTF8PROC_CATEGORY_SC:
  3235. case UTF8PROC_CATEGORY_SK:
  3236. case UTF8PROC_CATEGORY_SO:
  3237. allowChar = true;
  3238. default: break;
  3239. }
  3240. }
  3241. if ((allowChar) ||
  3242. ((c >= 'A') && (c <= 'Z')) ||
  3243. ((c >= 'a') && (c <= 'z')) ||
  3244. (c == '_'))
  3245. {
  3246. if (stringStart != -1)
  3247. {
  3248. mTokenStart = stringStart;
  3249. stringStart = -1;
  3250. }
  3251. while (true)
  3252. {
  3253. int curSrcIdx = mSrcIdx;
  3254. char c = mSrc[mSrcIdx++];
  3255. bool isValidChar =
  3256. (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || ((c >= '0') && (c <= '9')));
  3257. if (mCompatMode)
  3258. isValidChar |= (c == '$') || (c == '`') || (c == '\'');
  3259. if ((uint8)c >= 0xC0)
  3260. {
  3261. int cLen = 0;
  3262. mSrcIdx--;
  3263. uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
  3264. mSrcIdx += cLen;
  3265. utf8proc_category_t cat = utf8proc_category(c32);
  3266. switch (cat)
  3267. {
  3268. case UTF8PROC_CATEGORY_LU:
  3269. case UTF8PROC_CATEGORY_LL:
  3270. case UTF8PROC_CATEGORY_LT:
  3271. case UTF8PROC_CATEGORY_LM:
  3272. case UTF8PROC_CATEGORY_LO:
  3273. case UTF8PROC_CATEGORY_NL:
  3274. case UTF8PROC_CATEGORY_SM:
  3275. case UTF8PROC_CATEGORY_SC:
  3276. case UTF8PROC_CATEGORY_SK:
  3277. case UTF8PROC_CATEGORY_SO:
  3278. case UTF8PROC_CATEGORY_MN:
  3279. case UTF8PROC_CATEGORY_MC:
  3280. case UTF8PROC_CATEGORY_ND:
  3281. case UTF8PROC_CATEGORY_PC:
  3282. case UTF8PROC_CATEGORY_CF:
  3283. isValidChar = true;
  3284. default: break;
  3285. }
  3286. }
  3287. if (!isValidChar)
  3288. {
  3289. mTokenEnd = curSrcIdx;
  3290. mSrcIdx = curSrcIdx;
  3291. mSyntaxToken = BfSyntaxToken_Identifier;
  3292. return;
  3293. }
  3294. }
  3295. mSyntaxToken = BfSyntaxToken_Identifier;
  3296. return;
  3297. }
  3298. else
  3299. {
  3300. AddErrorNode(mTokenStart, mSrcIdx);
  3301. mTriviaStart = mSrcIdx;
  3302. UnexpectedCharacter();
  3303. continue;
  3304. }
  3305. }
  3306. return;
  3307. }
  3308. if ((setVerbatim) && (!isVerbatim))
  3309. {
  3310. isVerbatim = true;
  3311. stringStart = mTokenStart;
  3312. }
  3313. if (setInterpolate)
  3314. {
  3315. if (interpolateSetting == 0)
  3316. stringStart = mTokenStart;
  3317. interpolateSetting++;
  3318. }
  3319. }
  3320. }
  3321. static int gParseBlockIdx = 0;
  3322. static int gParseMemberIdx = 0;
  3323. void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate)
  3324. {
  3325. gParseBlockIdx++;
  3326. int startParseBlockIdx = gParseBlockIdx;
  3327. bool isAsmBlock = false;
  3328. bool isTernary = false;
  3329. bool forceAllowNext = false;
  3330. SizedArray<BfAstNode*, 32> childArr;
  3331. int parenDepth = 0;
  3332. int bracketDepth = 0;
  3333. while (true)
  3334. {
  3335. if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_Asm))
  3336. {
  3337. if (isAsmBlock || mInAsmBlock)
  3338. mPassInstance->Fail("Already inside an 'asm' block", astNode);
  3339. else
  3340. isAsmBlock = true;
  3341. }
  3342. NextToken(-1, isInterpolate && (parenDepth == 0) && (bracketDepth == 0) && (!forceAllowNext));
  3343. forceAllowNext = false;
  3344. if (mPreprocessorIgnoredSectionNode != NULL)
  3345. {
  3346. if (mSyntaxToken != BfSyntaxToken_EOF)
  3347. continue;
  3348. mPreprocessorIgnoredSectionNode->SetSrcEnd(mSrcIdx);
  3349. }
  3350. if (mScanOnly)
  3351. {
  3352. if (mSyntaxToken == BfSyntaxToken_EOF)
  3353. break;
  3354. continue;
  3355. }
  3356. gParseMemberIdx++;
  3357. int memberIdx = gParseMemberIdx;
  3358. auto childNode = CreateNode();
  3359. if (childNode == NULL)
  3360. break;
  3361. if (mSyntaxToken == BfSyntaxToken_EOF)
  3362. {
  3363. if (astNode != 0)
  3364. Fail("Unexpected end of file");
  3365. break;
  3366. }
  3367. if (mToken == BfToken_LBrace)
  3368. {
  3369. BfBlock* newBlock;
  3370. BfInlineAsmStatement* asmBlock = nullptr;
  3371. BfBlock* genBlock = nullptr;
  3372. /*if (isAsmBlock)
  3373. {
  3374. asmBlock = mAlloc->Alloc<BfInlineAsmStatement>();
  3375. asmBlock->mOpenBrace = (BfTokenNode*)CreateNode();
  3376. newBlock = asmBlock;
  3377. mInAsmBlock = true;
  3378. isAsmBlock = false;
  3379. }
  3380. else*/
  3381. {
  3382. genBlock = mAlloc->Alloc<BfBlock>();
  3383. genBlock->mParserBlockId = ++mCurBlockId;
  3384. genBlock->mOpenBrace = (BfTokenNode*)CreateNode();
  3385. newBlock = genBlock;
  3386. }
  3387. newBlock->Init(this);
  3388. ParseBlock(newBlock, depth + 1);
  3389. if (mToken == BfToken_RBrace)
  3390. {
  3391. if (genBlock)
  3392. genBlock->mCloseBrace = (BfTokenNode*)CreateNode();
  3393. else if (asmBlock)
  3394. asmBlock->mCloseBrace = (BfTokenNode*)CreateNode();
  3395. newBlock->SetSrcEnd(mSrcIdx);
  3396. }
  3397. else
  3398. {
  3399. if (mSyntaxToken == BfSyntaxToken_EOF)
  3400. mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
  3401. }
  3402. mInAsmBlock = false;
  3403. astNode->Add(newBlock);
  3404. childArr.push_back(newBlock);
  3405. }
  3406. else if (mToken == BfToken_RBrace)
  3407. {
  3408. if (depth == 0)
  3409. Fail("Unexpected ending brace");
  3410. break;
  3411. }
  3412. else if (mToken == BfToken_Case)
  3413. {
  3414. if (childArr.mSize > 0)
  3415. {
  3416. auto prevNode = childArr[childArr.mSize - 1];
  3417. if (auto prevIdentifier = BfNodeDynCastExact<BfIdentifierNode>(prevNode))
  3418. {
  3419. if (prevIdentifier->Equals("not"))
  3420. {
  3421. auto bfTokenNode = mAlloc->Alloc<BfTokenNode>();
  3422. bfTokenNode->Init(prevIdentifier->mTriviaStart, prevIdentifier->mSrcStart, prevIdentifier->mSrcEnd);
  3423. bfTokenNode->SetToken(BfToken_Not);
  3424. childArr[childArr.mSize - 1] = bfTokenNode;
  3425. }
  3426. }
  3427. }
  3428. astNode->Add(childNode);
  3429. childArr.Add(childNode);
  3430. }
  3431. else
  3432. {
  3433. if (mToken == BfToken_LParen)
  3434. parenDepth++;
  3435. else if (mToken == BfToken_RParen)
  3436. parenDepth--;
  3437. if (mToken == BfToken_LBracket)
  3438. bracketDepth++;
  3439. else if (mToken == BfToken_RBracket)
  3440. bracketDepth--;
  3441. if ((isInterpolate) && (parenDepth == 0) && (bracketDepth == 0))
  3442. {
  3443. if (mToken == BfToken_Question)
  3444. {
  3445. isTernary = true;
  3446. forceAllowNext = true;
  3447. }
  3448. bool endNow = false;
  3449. if (mToken == BfToken_Colon)
  3450. {
  3451. endNow = true;
  3452. if (!childArr.IsEmpty())
  3453. {
  3454. if (auto prevToken = BfNodeDynCast<BfTokenNode>(childArr.back()))
  3455. {
  3456. if ((prevToken->mToken == BfToken_Scope) || (prevToken->mToken == BfToken_New) || (prevToken->mToken == BfToken_Bang) ||
  3457. (prevToken->mToken == BfToken_Colon))
  3458. endNow = false;
  3459. }
  3460. }
  3461. if ((endNow) && (isTernary))
  3462. {
  3463. forceAllowNext = true;
  3464. isTernary = false;
  3465. endNow = false;
  3466. }
  3467. }
  3468. if (mToken == BfToken_Comma)
  3469. endNow = true;
  3470. if (endNow)
  3471. {
  3472. mSrcIdx = mTokenStart;
  3473. break;
  3474. }
  3475. }
  3476. astNode->Add(childNode);
  3477. childArr.Add(childNode);
  3478. if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_RBrace))
  3479. break;
  3480. }
  3481. }
  3482. astNode->Init(childArr, mAlloc);
  3483. }
  3484. const char* BfNodeToString(BfAstNode* node)
  3485. {
  3486. static char str[256] = { 0 };
  3487. strncpy(str, node->GetSourceData()->mSrc + node->GetSrcStart(), node->GetSrcLength());
  3488. return str;
  3489. }
  3490. BfAstNode* BfParser::CreateNode()
  3491. {
  3492. switch (mSyntaxToken)
  3493. {
  3494. case BfSyntaxToken_Token:
  3495. {
  3496. auto bfTokenNode = mAlloc->Alloc<BfTokenNode>();
  3497. bfTokenNode->Init(this);
  3498. bfTokenNode->SetToken(mToken);
  3499. return bfTokenNode;
  3500. }
  3501. case BfSyntaxToken_Identifier:
  3502. {
  3503. //auto bfIdentifierNode = new BfIdentifierNode();
  3504. auto bfIdentifierNode = mAlloc->Alloc<BfIdentifierNode>();
  3505. bfIdentifierNode->Init(this);
  3506. return bfIdentifierNode;
  3507. }
  3508. case BfSyntaxToken_Literal:
  3509. {
  3510. auto bfLiteralExpression = mAlloc->Alloc<BfLiteralExpression>();
  3511. bfLiteralExpression->Init(this);
  3512. bfLiteralExpression->mValue = mLiteral;
  3513. mLiteral.mTypeCode = BfTypeCode_None;
  3514. mLiteral.mWarnType = 0;
  3515. return bfLiteralExpression;
  3516. }
  3517. case BfSyntaxToken_GeneratedNode:
  3518. return mGeneratedNode;
  3519. default: break;
  3520. }
  3521. return NULL;
  3522. }
  3523. void BfParser::Parse(BfPassInstance* passInstance)
  3524. {
  3525. BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
  3526. mSyntaxToken = BfSyntaxToken_None;
  3527. mPassInstance = passInstance;
  3528. int startIdx = mSrcIdx;
  3529. if (mUsingCache)
  3530. {
  3531. mRootNode = mParserData->mRootNode;
  3532. mSidechannelRootNode = mParserData->mSidechannelRootNode;
  3533. mErrorRootNode = mParserData->mErrorRootNode;
  3534. return;
  3535. }
  3536. mRootNode = mAlloc->Alloc<BfRootNode>();
  3537. mRootNode->Init(this);
  3538. mParserData->mRootNode = mRootNode;
  3539. mSidechannelRootNode = mAlloc->Alloc<BfRootNode>();
  3540. mSidechannelRootNode->Init(this);
  3541. mParserData->mSidechannelRootNode = mSidechannelRootNode;
  3542. mErrorRootNode = mAlloc->Alloc<BfRootNode>();
  3543. mErrorRootNode->Init(this);
  3544. mParserData->mErrorRootNode = mErrorRootNode;
  3545. ParseBlock(mRootNode, 0);
  3546. if (mPreprocessorNodeStack.size() > 0)
  3547. {
  3548. mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
  3549. }
  3550. if (mJumpTable != NULL)
  3551. {
  3552. for (int i = (startIdx / PARSER_JUMPTABLE_DIVIDE) + 1; i < mJumpTableSize; i++)
  3553. if (mJumpTable[i].mCharIdx == 0)
  3554. mJumpTable[i] = mJumpTable[i - 1];
  3555. }
  3556. if (mPassInstance->HasFailed())
  3557. mParsingFailed = true;
  3558. if ((mPassInstance->HasMessages()) || (mParsingFailed))
  3559. {
  3560. mParserData->mFailed = true; // Don't reuse cache if there were errors or warnings
  3561. }
  3562. mPassInstance = NULL;
  3563. }
  3564. int BfParser::GetCharIdAtIndex(int findIndex)
  3565. {
  3566. return mParserData->GetCharIdAtIndex(findIndex);
  3567. }
  3568. void BfParser::Close()
  3569. {
  3570. BfSource::Close();
  3571. BfLogSys(mSystem, "Parser %p closing. RefCount:%d Failed:%d\n", this, mParserData->mRefCount, mParserData->mFailed);
  3572. if ((mParserData->mRefCount == 0) && (!mParserData->mFailed))
  3573. {
  3574. BF_ASSERT(mParserData->mDidReduce);
  3575. AutoCrit autoCrit(gBfParserCache->mCritSect);
  3576. BfParserCache::DataEntry dataEntry;
  3577. dataEntry.mParserData = mParserData;
  3578. if (gBfParserCache->mEntries.Add(dataEntry))
  3579. {
  3580. BfLogSys(mSystem, "Parser %p added to cache\n", this);
  3581. mParserData->mRefCount++;
  3582. }
  3583. else
  3584. {
  3585. // It's possible two of the same entries were being parsed at the same time on different threads.
  3586. // Just let the loser be deleted in the dtor
  3587. BfLogSys(mSystem, "Duplicate parser %p not added to cache\n", this);
  3588. }
  3589. }
  3590. }
  3591. void BfParser::HadSrcRealloc()
  3592. {
  3593. int jumpTableSize = ((mSrcAllocSize + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
  3594. if (jumpTableSize > mJumpTableSize)
  3595. {
  3596. auto jumpTable = new BfLineStartEntry[jumpTableSize];
  3597. memset(jumpTable, 0, jumpTableSize * sizeof(BfLineStartEntry));
  3598. memcpy(jumpTable, mJumpTable, mJumpTableSize * sizeof(BfLineStartEntry));
  3599. delete [] mJumpTable;
  3600. mJumpTable = jumpTable;
  3601. mJumpTableSize = jumpTableSize;
  3602. mParserData->mJumpTable = mJumpTable;
  3603. mParserData->mJumpTableSize = mJumpTableSize;
  3604. }
  3605. }
  3606. void BfParser::GenerateAutoCompleteFrom(int srcPosition)
  3607. {
  3608. BfSourcePositionFinder posFinder(this, srcPosition);
  3609. posFinder.Visit(mRootNode);
  3610. if (posFinder.mClosestElement != NULL)
  3611. {
  3612. }
  3613. }
  3614. void BfParser::ReportMemory(MemReporter* memReporter)
  3615. {
  3616. //memReporter->Add("SmallAstAlloc", (int)mAlloc->mPages.size() * BfAstAllocManager::PAGE_SIZE);
  3617. //memReporter->Add("LargeAstAlloc", mAlloc->mLargeAllocSizes);
  3618. // if (!mUsingCache)
  3619. // memReporter->AddBumpAlloc("AstAlloc", *mAlloc);
  3620. //
  3621. // memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
  3622. memReporter->Add(sizeof(BfParser));
  3623. if (mParserData->mRefCount <= 0)
  3624. mParserData->ReportMemory(memReporter);
  3625. // if (mSrcAllocSize > 0)
  3626. // memReporter->Add("Source", mSrcAllocSize);
  3627. }
  3628. class BfInnermostFinder : public BfElementVisitor
  3629. {
  3630. public:
  3631. int mCursorIdx;
  3632. BfAstNode* mFoundNode;
  3633. BfInnermostFinder(int cursorIdx)
  3634. {
  3635. mFoundNode = NULL;
  3636. mCursorIdx = cursorIdx;
  3637. }
  3638. virtual void Visit(BfAstNode* node) override
  3639. {
  3640. if ((node->Contains(mCursorIdx)) && (!node->IsA<BfBlock>()))
  3641. {
  3642. if ((mFoundNode == NULL) || ((node->GetSrcLength()) <= (mFoundNode->GetSrcLength())))
  3643. mFoundNode = node;
  3644. }
  3645. }
  3646. virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override
  3647. {
  3648. BfElementVisitor::Visit(memberRefExpr);
  3649. if (mFoundNode == memberRefExpr->mMemberName)
  3650. {
  3651. mFoundNode = memberRefExpr;
  3652. }
  3653. }
  3654. virtual void Visit(BfAttributedIdentifierNode* identifierNode) override
  3655. {
  3656. BfElementVisitor::Visit(identifierNode);
  3657. if (mFoundNode == identifierNode->mIdentifier)
  3658. {
  3659. mFoundNode = identifierNode;
  3660. }
  3661. }
  3662. virtual void Visit(BfQualifiedNameNode* qualifiedNameNode) override
  3663. {
  3664. BfElementVisitor::Visit(qualifiedNameNode);
  3665. if (mFoundNode == qualifiedNameNode->mRight)
  3666. {
  3667. mFoundNode = qualifiedNameNode;
  3668. }
  3669. }
  3670. virtual void Visit(BfBinaryOperatorExpression* binaryOpExpr) override
  3671. {
  3672. BfElementVisitor::Visit(binaryOpExpr);
  3673. if (mFoundNode == binaryOpExpr->mOpToken)
  3674. {
  3675. mFoundNode = binaryOpExpr;
  3676. }
  3677. }
  3678. virtual void Visit(BfPreprocessorNode* preprocNode) override
  3679. {
  3680. if (preprocNode->mArgument != NULL)
  3681. {
  3682. for (auto arg : preprocNode->mArgument->mChildArr)
  3683. {
  3684. Visit((BfAstNode*)arg);
  3685. if (mFoundNode == arg)
  3686. {
  3687. mFoundNode = preprocNode;
  3688. }
  3689. }
  3690. }
  3691. }
  3692. };
  3693. static BfAstNode* FindDebugExpressionNode(BfAstNode* checkNode, int cursorIdx)
  3694. {
  3695. BfInnermostFinder innermostFinder(cursorIdx);
  3696. innermostFinder.VisitChild(checkNode);
  3697. BfAstNode* exprNode = innermostFinder.mFoundNode;
  3698. return exprNode;
  3699. }
  3700. //////////////////////////////////////////////////////////////////////////
  3701. BF_EXPORT void BF_CALLTYPE BfParser_SetSource(BfParser* bfParser, const char* data, int length, const char* fileName, int textVersion)
  3702. {
  3703. bfParser->mFileName = fileName;
  3704. bfParser->mTextVersion = textVersion;
  3705. bfParser->SetSource(data, length);
  3706. }
  3707. BF_EXPORT void BF_CALLTYPE BfParser_SetCharIdData(BfParser* bfParser, uint8* data, int length)
  3708. {
  3709. delete bfParser->mParserData->mCharIdData;
  3710. bfParser->mParserData->mCharIdData = new uint8[length];
  3711. memcpy(bfParser->mParserData->mCharIdData, data, length);
  3712. }
  3713. BF_EXPORT void BF_CALLTYPE BfParser_SetHashMD5(BfParser* bfParser, Val128* md5Hash)
  3714. {
  3715. if (md5Hash != NULL)
  3716. bfParser->mParserData->mMD5Hash = *md5Hash;
  3717. }
  3718. BF_EXPORT void BF_CALLTYPE BfParser_Delete(BfParser* bfParser)
  3719. {
  3720. if (bfParser->mNextRevision != NULL)
  3721. bfParser->mNextRevision->mPrevRevision = NULL;
  3722. auto itr = std::find(bfParser->mSystem->mParsers.begin(), bfParser->mSystem->mParsers.end(), bfParser);
  3723. bfParser->mSystem->mParsers.erase(itr);
  3724. delete bfParser;
  3725. }
  3726. BF_EXPORT void BF_CALLTYPE BfParser_SetNextRevision(BfParser* bfParser, BfParser* nextRevision)
  3727. {
  3728. BF_ASSERT(bfParser->mNextRevision == NULL);
  3729. BF_ASSERT(nextRevision->mPrevRevision == NULL);
  3730. bfParser->mNextRevision = nextRevision;
  3731. nextRevision->mPrevRevision = bfParser;
  3732. nextRevision->mDataId = bfParser->mDataId;
  3733. }
  3734. BF_EXPORT void BF_CALLTYPE BfParser_SetCursorIdx(BfParser* bfParser, int cursorIdx)
  3735. {
  3736. bfParser->SetCursorIdx(cursorIdx);
  3737. }
  3738. BF_EXPORT void BF_CALLTYPE BfParser_SetIsClassifying(BfParser* bfParser)
  3739. {
  3740. bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Classifying);
  3741. }
  3742. BF_EXPORT void BF_CALLTYPE BfParser_SetEmbedKind(BfParser* bfParser, BfSourceEmbedKind embedKind)
  3743. {
  3744. bfParser->mEmbedKind = embedKind;
  3745. }
  3746. BF_EXPORT void BF_CALLTYPE BfParser_SetAutocomplete(BfParser* bfParser, int cursorIdx)
  3747. {
  3748. BF_ASSERT(bfParser->mParserData->mRefCount == -1);
  3749. bfParser->SetCursorIdx(cursorIdx);
  3750. bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Autocomplete | ParserFlag_Classifying);
  3751. }
  3752. PerfManager* BfGetPerfManager(BfParser* bfParser)
  3753. {
  3754. if (bfParser == NULL)
  3755. return NULL;
  3756. if (bfParser->mCursorIdx != -1)
  3757. return gPerfManager;
  3758. return NULL;
  3759. }
  3760. BF_EXPORT bool BF_CALLTYPE BfParser_Parse(BfParser* bfParser, BfPassInstance* bfPassInstance, bool compatMode)
  3761. {
  3762. BP_ZONE("BfParser_Parse");
  3763. int startFailIdx = bfPassInstance->mFailedIdx;
  3764. bfParser->mCompatMode = compatMode;
  3765. bfParser->mQuickCompatMode = compatMode;
  3766. bfParser->Parse(bfPassInstance);
  3767. return startFailIdx == bfPassInstance->mFailedIdx;
  3768. }
  3769. BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* bfPassInstance)
  3770. {
  3771. BP_ZONE("BfParser_Reduce");
  3772. if (bfParser->mUsingCache)
  3773. return true; // Already reduced
  3774. bfParser->FinishSideNodes();
  3775. int startFailIdx = bfPassInstance->mFailedIdx;
  3776. int startWarningCount = bfPassInstance->mWarningCount;
  3777. BfReducer bfReducer;
  3778. bfReducer.mSource = bfParser;
  3779. bfReducer.mCompatMode = bfParser->mCompatMode;
  3780. bfReducer.mPassInstance = bfPassInstance;
  3781. bfReducer.HandleRoot(bfParser->mRootNode);
  3782. if ((startFailIdx != bfPassInstance->mFailedIdx) ||
  3783. (startWarningCount != bfPassInstance->mWarningCount))
  3784. bfParser->mParserData->mFailed = true;
  3785. bfParser->mParserData->mDidReduce = true;
  3786. bfParser->Close();
  3787. return startFailIdx == bfPassInstance->mFailedIdx;
  3788. }
  3789. static Array<int> gCharMapping;
  3790. BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping, int maxCol, int tabSize, bool wantsTabsAsSpaces,
  3791. bool indentCaseLabels)
  3792. {
  3793. BP_ZONE("BfParser_Reduce");
  3794. String& outString = *gTLStrReturn.Get();
  3795. outString.clear();
  3796. gCharMapping.Clear();
  3797. BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
  3798. bfPrinter.mMaxCol = maxCol;
  3799. bfPrinter.mTabSize = tabSize;
  3800. bfPrinter.mWantsTabsAsSpaces = wantsTabsAsSpaces;
  3801. bfPrinter.mIndentCaseLabels = indentCaseLabels;
  3802. bfPrinter.mFormatStart = formatStart;
  3803. bfPrinter.mFormatEnd = formatEnd;
  3804. bfPrinter.mCharMapping = &gCharMapping;
  3805. bfPrinter.Visit(bfParser->mRootNode);
  3806. outString = bfPrinter.mOutString;
  3807. *outCharMapping = &gCharMapping[0];
  3808. return outString.c_str();
  3809. }
  3810. BF_EXPORT const char* BF_CALLTYPE BfParser_DocPrep(BfParser* bfParser)
  3811. {
  3812. BP_ZONE("BfParser_Reduce");
  3813. String& outString = *gTLStrReturn.Get();
  3814. outString.clear();
  3815. gCharMapping.Clear();
  3816. BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
  3817. bfPrinter.mFormatStart = -1;
  3818. bfPrinter.mFormatEnd = -1;
  3819. bfPrinter.mCharMapping = &gCharMapping;
  3820. bfPrinter.mDocPrep = true;
  3821. bfPrinter.Visit(bfParser->mRootNode);
  3822. outString = bfPrinter.mOutString;
  3823. return outString.c_str();
  3824. }
  3825. BF_EXPORT const char* BF_CALLTYPE BfParser_GetDebugExpressionAt(BfParser* bfParser, int cursorIdx)
  3826. {
  3827. BP_ZONE("BfParser_Reduce");
  3828. String& outString = *gTLStrReturn.Get();
  3829. outString.clear();
  3830. BfAstNode* exprNode = FindDebugExpressionNode(bfParser->mRootNode, cursorIdx);
  3831. if (exprNode == NULL)
  3832. exprNode = FindDebugExpressionNode(bfParser->mSidechannelRootNode, cursorIdx);
  3833. if (exprNode == NULL)
  3834. return NULL;
  3835. if ((exprNode->IsA<BfMethodDeclaration>()) ||
  3836. (exprNode->IsA<BfBlock>()) ||
  3837. (exprNode->IsA<BfStatement>()) ||
  3838. (exprNode->IsA<BfTokenNode>())
  3839. )
  3840. {
  3841. return NULL;
  3842. }
  3843. BfPrinter bfPrinter(bfParser->mRootNode, NULL, NULL);
  3844. bfPrinter.mReformatting = true;
  3845. bfPrinter.mIgnoreTrivia = true;
  3846. bfPrinter.VisitChild(exprNode);
  3847. outString = bfPrinter.mOutString;
  3848. if (auto preprocessorNode = BfNodeDynCast<BfPreprocessorNode>(exprNode))
  3849. {
  3850. auto firstStr = preprocessorNode->mArgument->mChildArr[0]->ToString();
  3851. if (firstStr == "warning")
  3852. {
  3853. String warningNumStr = preprocessorNode->mArgument->mChildArr.back()->ToString();
  3854. int warningNum = atoi(warningNumStr.c_str());
  3855. String warningStr;
  3856. switch (warningNum)
  3857. {
  3858. case BfWarning_CS0108_MemberHidesInherited:
  3859. warningStr = "CS0108: Derived member hides inherited member";
  3860. break;
  3861. case BfWarning_CS0114_MethodHidesInherited:
  3862. warningStr = "CS0114: Derived method hides inherited member";
  3863. break;
  3864. case BfWarning_CS0162_UnreachableCode:
  3865. warningStr = "CS0162: Unreachable code";
  3866. break;
  3867. case BfWarning_CS0168_VariableDeclaredButNeverUsed:
  3868. warningStr = "CS0168: Variable declared but never used";
  3869. break;
  3870. case BfWarning_CS0472_ValueTypeNullCompare:
  3871. warningStr = "CS0472: ValueType compared to null";
  3872. break;
  3873. case BfWarning_CS1030_PragmaWarning:
  3874. warningStr = "CS1030: Pragma warning";
  3875. break;
  3876. }
  3877. if (!warningStr.empty())
  3878. outString = "`" + warningStr;
  3879. }
  3880. }
  3881. return outString.c_str();
  3882. }
  3883. BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser* bfParser, BfResolveType resolveType, bool doFuzzyAutoComplete)
  3884. {
  3885. auto bfResolvePassData = new BfResolvePassData();
  3886. bfResolvePassData->mResolveType = resolveType;
  3887. if (bfParser != NULL)
  3888. bfResolvePassData->mParsers.Add(bfParser);
  3889. if ((bfParser != NULL) && ((bfParser->mParserFlags & ParserFlag_Autocomplete) != 0))
  3890. bfResolvePassData->mAutoComplete = new BfAutoComplete(resolveType, doFuzzyAutoComplete);
  3891. return bfResolvePassData;
  3892. }
  3893. BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh)
  3894. {
  3895. if (bfParser->mCursorIdx != -1)
  3896. resolvePassData->mHasCursorIdx = true;
  3897. BP_ZONE("BfParser_BuildDefs");
  3898. int startFailIdx = bfPassInstance->mFailedIdx;
  3899. BfDefBuilder defBuilder(bfParser->mSystem);
  3900. defBuilder.mResolvePassData = resolvePassData;
  3901. defBuilder.Process(bfPassInstance, bfParser, fullRefresh);
  3902. return startFailIdx == bfPassInstance->mFailedIdx;;
  3903. }
  3904. BF_EXPORT void BF_CALLTYPE BfParser_RemoveDefs(BfParser* bfParser)
  3905. {
  3906. }
  3907. BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceClassifier::CharData* charData, bool preserveFlags)
  3908. {
  3909. if (!bfParser->mIsClosed)
  3910. bfParser->Close();
  3911. BfSourceClassifier bfSourceClassifier(bfParser, charData);
  3912. bfSourceClassifier.mPreserveFlags = preserveFlags;
  3913. bfSourceClassifier.Visit(bfParser->mRootNode);
  3914. bfSourceClassifier.mIsSideChannel = false; //? false or true?
  3915. bfSourceClassifier.Visit(bfParser->mErrorRootNode);
  3916. bfSourceClassifier.mIsSideChannel = true;
  3917. bfSourceClassifier.Visit(bfParser->mSidechannelRootNode);
  3918. }
  3919. BF_EXPORT void BF_CALLTYPE BfParser_CreateClassifier(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, BfSourceClassifier::CharData* charData)
  3920. {
  3921. resolvePassData->mIsClassifying = true;
  3922. bfParser->mSourceClassifier = new BfSourceClassifier(bfParser, charData);
  3923. bfParser->mSourceClassifier->mClassifierPassId = bfPassInstance->mClassifierPassId;
  3924. if ((resolvePassData->mParsers.IsEmpty()) || (bfParser != resolvePassData->mParsers[0]))
  3925. resolvePassData->mParsers.Add(bfParser);
  3926. bool doClassifyPass = (charData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
  3927. bfParser->mSourceClassifier->mEnabled = doClassifyPass;
  3928. bfParser->mSourceClassifier->mSkipMethodInternals = true;
  3929. bfParser->mSourceClassifier->mSkipTypeDeclarations = true;
  3930. if (charData != NULL)
  3931. {
  3932. if ((doClassifyPass) && (bfParser->mRootNode != NULL))
  3933. bfParser->mSourceClassifier->Visit(bfParser->mRootNode);
  3934. }
  3935. bfParser->mSourceClassifier->mSkipTypeDeclarations = false;
  3936. bfParser->mSourceClassifier->mSkipMethodInternals = false;
  3937. }
  3938. BF_EXPORT void BF_CALLTYPE BfParser_FinishClassifier(BfParser* bfParser, BfResolvePassData* resolvePassData)
  3939. {
  3940. if (bfParser->mSourceClassifier == NULL)
  3941. return;
  3942. bool doClassifyPass = (bfParser->mSourceClassifier->mCharData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
  3943. if (doClassifyPass)
  3944. {
  3945. bfParser->mSourceClassifier->mIsSideChannel = false;
  3946. if (bfParser->mErrorRootNode != NULL)
  3947. bfParser->mSourceClassifier->Visit(bfParser->mErrorRootNode);
  3948. bfParser->mSourceClassifier->mIsSideChannel = true;
  3949. if (bfParser->mSidechannelRootNode != NULL)
  3950. bfParser->mSourceClassifier->Visit(bfParser->mSidechannelRootNode);
  3951. }
  3952. delete bfParser->mSourceClassifier;
  3953. bfParser->mSourceClassifier = NULL;
  3954. }
  3955. BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParser, int srcPosition)
  3956. {
  3957. BP_ZONE("BfParser_GenerateAutoCompletionFrom");
  3958. bfParser->GenerateAutoCompleteFrom(srcPosition);
  3959. }
  3960. BF_EXPORT void BF_CALLTYPE BfParser_SetCompleteParse(BfParser* bfParser)
  3961. {
  3962. bfParser->mCompleteParse = true;
  3963. }
  3964. BF_EXPORT void BF_CALLTYPE BfParser_GetLineCharAtIdx(BfParser* bfParser, int idx, int* line, int* lineChar)
  3965. {
  3966. int _line, _lineChar;
  3967. bfParser->GetLineCharAtIdx(idx, _line, _lineChar);
  3968. *line = _line;
  3969. *lineChar = _lineChar;
  3970. }
  3971. BF_EXPORT int BF_CALLTYPE BfParser_GetIndexAtLine(BfParser* bfParser, int line)
  3972. {
  3973. return bfParser->GetIndexAtLine(line);
  3974. }