12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364 |
- #pragma warning(disable:4996)
- #include "BfParser.h"
- #include "BfReducer.h"
- #include "BfPrinter.h"
- #include "BfDefBuilder.h"
- #include "BfCompiler.h"
- #include "BfSourceClassifier.h"
- #include "BfSourcePositionFinder.h"
- #include <sstream>
- #include "BeefySysLib/util/PerfTimer.h"
- #include "BeefySysLib/util/BeefPerf.h"
- #include "BeefySysLib/util/UTF8.h"
- #include "BfAutoComplete.h"
- #include "BfResolvePass.h"
- #include "BfElementVisitor.h"
- #include "BeefySysLib/util/UTF8.h"
- extern "C"
- {
- #include "BeefySysLib/third_party/utf8proc/utf8proc.h"
- }
- #include "BeefySysLib/util/AllocDebug.h"
- USING_NS_BF;
- static bool IsWhitespace(char c)
- {
- return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
- }
- static bool IsWhitespaceOrPunctuation(char c)
- {
- switch (c)
- {
- case ',':
- case ';':
- case ':':
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- case '<':
- case '>':
- case '/':
- case '-':
- case '=':
- case '+':
- case '!':
- case '%':
- case '&':
- case '|':
- case '#':
- case '@':
- case '`':
- case '^':
- case '~':
- case '*':
- case '?':
- case '\n':
- case ' ':
- case '\t':
- case '\v':
- case '\f':
- case '\r':
- return true;
- default:
- return false;
- }
- }
- BfParser* BfParserData::ToParser()
- {
- if (mUniqueParser != NULL)
- {
- BF_ASSERT(mUniqueParser->mOrigSrcLength >= 0);
- BF_ASSERT((mUniqueParser->mCursorIdx >= -1) || (mUniqueParser->mCursorIdx <= mUniqueParser->mOrigSrcLength));
- }
- return mUniqueParser;
- }
- //////////////////////////////////////////////////////////////////////////
- /// raw_null_ostream - A raw_ostream that discards all output.
- /*class debug_ostream : public llvm::raw_ostream
- {
- /// write_impl - See raw_ostream::write_impl.
- void write_impl(const char *Ptr, size_t size) override
- {
- char str[256] = {0};
- memcpy(str, Ptr, std::min((int)size, 255));
- OutputDebugStr(str);
- }
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
- uint64_t current_pos() const override
- {
- return 0;
- }
- };*/
- //////////////////////////////////////////////////////////////////////////
- static CritSect gParseFileDataCrit;
- static Array<int> gFreeIds;
- static int gCurFreeId;
- int BfParseFileData::GetUniqueId(int idx)
- {
- AutoCrit autoCrit(gParseFileDataCrit);
- int* valuePtr = NULL;
- if (mUniqueIDList.TryAdd(idx, NULL, &valuePtr))
- {
- if (!gFreeIds.IsEmpty())
- {
- *valuePtr = gFreeIds.back();
- gFreeIds.pop_back();
- }
- else
- *valuePtr = gCurFreeId++;
- }
- return *valuePtr;
- }
- BfParseFileData::~BfParseFileData()
- {
- if (!mUniqueIDList.IsEmpty())
- {
- AutoCrit autoCrit(gParseFileDataCrit);
- for (auto kv : mUniqueIDList)
- gFreeIds.Add(kv.mValue);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- BfParserCache* Beefy::gBfParserCache = NULL;
- bool BfParserCache::DataEntry::operator==(const LookupEntry& lookup) const
- {
- if ((mParserData->mFileName == lookup.mFileName) &&
- (mParserData->mSrcLength == lookup.mSrcLength) &&
- (memcmp(mParserData->mSrc, lookup.mSrc, lookup.mSrcLength) == 0))
- {
- for (auto& setDefine : mParserData->mDefines_Def)
- if (!lookup.mProject->mPreprocessorMacros.Contains(setDefine))
- return false;
- for (auto& setDefine : mParserData->mDefines_NoDef)
- if (lookup.mProject->mPreprocessorMacros.Contains(setDefine))
- return false;
- return true;
- }
- return false;
- }
- BfParserCache::BfParserCache()
- {
- mRefCount = 0;
- }
- BfParserCache::~BfParserCache()
- {
- for (auto& entry : mEntries)
- {
- BF_ASSERT(entry.mParserData->mRefCount == 0);
- delete entry.mParserData;
- }
- }
- void BfParserCache::ReportMemory(MemReporter* memReporter)
- {
- int srcLen = 0;
- int allocBytesUsed = 0;
- int largeAllocs = 0;
- for (auto& entry : mEntries)
- {
- auto parserData = entry.mParserData;
- parserData->ReportMemory(memReporter);
- srcLen += parserData->mSrcLength;
- allocBytesUsed += (int)(parserData->mAlloc.mPages.size() * BfAstAllocManager::PAGE_SIZE);
- largeAllocs += parserData->mAlloc.mLargeAllocSizes;
- }
- int allocPages = 0;
- int usedPages = 0;
- mAstAllocManager.GetStats(allocPages, usedPages);
- OutputDebugStrF("Parsers: %d Chars: %d UsedAlloc: %dk BytesPerChar: %d SysAllocPages: %d SysUsedPages: %d (%dk) LargeAllocs: %dk\n", (int)mEntries.size(), srcLen, allocBytesUsed / 1024,
- allocBytesUsed / BF_MAX(1, srcLen), allocPages, usedPages, (usedPages * BfAstAllocManager::PAGE_SIZE) / 1024, largeAllocs / 1024);
- //memReporter->AddBumpAlloc("BumpAlloc", mAstAllocManager);
- }
- void BfParserData::ReportMemory(MemReporter* memReporter)
- {
- memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
- memReporter->Add("Source", mSrcLength);
- memReporter->AddBumpAlloc("AstAlloc", mAlloc);
- }
- static int DecodeInt(uint8* buf, int& idx)
- {
- int value = 0;
- int shift = 0;
- int curByte;
- do
- {
- curByte = buf[idx++];
- value |= ((curByte & 0x7f) << shift);
- shift += 7;
- } while (curByte >= 128);
- // Sign extend negative numbers.
- if (((curByte & 0x40) != 0) && (shift < 64))
- value |= ~0LL << shift;
- return value;
- }
- static int gCurDataId = 0;
- BfParserData::BfParserData()
- {
- mDataId = (int)BfpSystem_InterlockedExchangeAdd32((uint32*)&gCurDataId, 1) + 1;
- mHash = 0;
- mRefCount = -1;
- mJumpTable = NULL;
- mJumpTableSize = 0;
- mFailed = false;
- mCharIdData = NULL;
- mUniqueParser = NULL;
- mDidReduce = false;
- mParseFileData = NULL;
- }
- BfParserData::~BfParserData()
- {
- if (mParseFileData != NULL)
- {
- BF_ASSERT(mParseFileData->mRefCount >= 0);
- mParseFileData->mRefCount--;
- if (mParseFileData->mRefCount == 0)
- {
- delete mParseFileData;
- gBfParserCache->mParseFileDataMap.Remove(mFileName);
- }
- }
- delete[] mJumpTable;
- delete[] mCharIdData;
- }
- void BfParserData::InitFileData()
- {
- BF_ASSERT(mParseFileData == NULL);
- BfParseFileData** valuePtr = NULL;
- if (gBfParserCache->mParseFileDataMap.TryAdd(mFileName, NULL, &valuePtr))
- {
- *valuePtr = new BfParseFileData();
- }
- mParseFileData = *valuePtr;
- mParseFileData->mRefCount++;
- }
- int BfParserData::GetCharIdAtIndex(int findIndex)
- {
- if (mCharIdData == NULL)
- return findIndex;
- int encodeIdx = 0;
- int charId = 1;
- int charIdx = 0;
- while (true)
- {
- int cmd = DecodeInt(mCharIdData, encodeIdx);
- if (cmd > 0)
- charId = cmd;
- else
- {
- int spanSize = -cmd;
- if ((findIndex >= charIdx) && (findIndex < charIdx + spanSize))
- return charId + (findIndex - charIdx);
- charId += spanSize;
- charIdx += spanSize;
- if (cmd == 0)
- return -1;
- }
- }
- }
- void BfParserData::GetLineCharAtIdx(int idx, int& line, int& lineChar)
- {
- if (mJumpTableSize <= 0)
- {
- line = 0;
- lineChar = 0;
- return;
- }
- if (idx >= mSrcLength)
- idx = mSrcLength - 1;
- auto* jumpEntry = mJumpTable + (idx / PARSER_JUMPTABLE_DIVIDE);
- if (jumpEntry->mCharIdx > idx)
- jumpEntry--;
- line = jumpEntry->mLineNum;
- lineChar = 0;
- int curSrcPos = jumpEntry->mCharIdx;
- while (curSrcPos < idx)
- {
- if (mSrc[curSrcPos] == '\n')
- {
- line++;
- lineChar = 0;
- }
- else
- {
- lineChar++;
- }
- curSrcPos++;
- }
- }
- bool BfParserData::IsUnwarnedAt(BfAstNode* node)
- {
- if (mUnwarns.empty())
- return false;
- auto unwarnItr = mUnwarns.upper_bound(node->GetSrcStart());
- if (unwarnItr == mUnwarns.begin())
- return false;
- unwarnItr--;
- int unwarnIdx = *unwarnItr;
- int checkIdx = node->GetSrcStart();
- int lineCount = 0;
- while (checkIdx > 0)
- {
- checkIdx--;
- if (checkIdx < unwarnIdx)
- return true;
- if (mSrc[checkIdx] == '\n')
- {
- lineCount++;
- // #unwarn must be immediately preceding the start of the statement containing this node
- if (lineCount == 2)
- return false;
- }
- }
- return true;
- }
- bool BfParserData::IsWarningEnabledAtSrcIndex(int warningNumber, int srcIdx)
- {
- 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
- for (const auto& it : mWarningEnabledChanges)
- {
- if (it.mKey > srcIdx)
- break;
- if ((it.mValue.mWarningNumber == warningNumber) || (it.mValue.mWarningNumber == -1))
- {
- if (it.mValue.mEnable)
- enabled++;
- else
- enabled--;
- }
- }
- return enabled > 0;
- }
- void BfParserData::Deref()
- {
- mRefCount--;
- BF_ASSERT(mRefCount >= 0);
- if (mRefCount == 0)
- {
- AutoCrit autoCrit(gBfParserCache->mCritSect);
- BfParserCache::DataEntry dataEntry;
- dataEntry.mParserData = this;
- bool didRemove = gBfParserCache->mEntries.Remove(dataEntry);
- BF_ASSERT(didRemove);
- delete this;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- static int gParserCount = 0;
- BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem)
- {
- BfLogSys(bfSystem, "BfParser::BfParser %08X\n", this);
- gParserCount++;
- mTextVersion = -1;
- mEmbedKind = BfSourceEmbedKind_None;
- mUsingCache = false;
- mParserData = NULL;
- mAwaitingDelete = false;
- mScanOnly = false;
- mCompleteParse = false;
- mIsEmitted = false;
- mJumpTable = NULL;
- mProject = bfProject;
- mPassInstance = NULL;
- mSourceClassifier = NULL;
- mPrevRevision = NULL;
- mNextRevision = NULL;
- mOrigSrcLength = 0;
- mSrcAllocSize = -1;
- mSrcLength = 0;
- mSrcIdx = 0;
- mParserFlags = ParserFlag_None;
- mCursorIdx = -1;
- mCursorCheckIdx = -1;
- mLineStart = 0;
- //mCurToken = (BfSyntaxToken)0;
- mToken = BfToken_None;
- mSyntaxToken = BfSyntaxToken_None;
- mTokenStart = 0;
- mTokenEnd = 0;
- mLineNum = 0;
- mCompatMode = false;
- mQuickCompatMode = false;
- mLiteral.mWarnType = 0;
- mDataId = -1;
- mTriviaStart = 0;
- mParsingFailed = false;
- mInAsmBlock = false;
- mCurBlockId = 0;
- mPreprocessorIgnoredSectionNode = NULL;
- mPreprocessorIgnoreDepth = 0;
- mAddedDependsDefines = false;
- if (bfProject != NULL)
- {
- for (auto macro : bfProject->mPreprocessorMacros)
- mPreprocessorDefines[macro] = BfDefineState_FromProject;
- }
- }
- //static std::set<BfAstNode*> gFoundNodes;
- BfParser::~BfParser()
- {
- int parserCount = gParserCount--;
- if (mParserData == NULL)
- {
- }
- else if (mParserData->mRefCount == -1)
- {
- // Owned data, never intended for cache
- mParserData->mSrc = NULL; // Count on BfSource dtor to release strc
- delete mParserData;
- }
- else if (mParserData->mRefCount == 0)
- {
- // Just never got added to the cache
- delete mParserData;
- }
- else
- {
- mParserData->Deref();
- }
- mSourceData = NULL;
- BfLogSys(mSystem, "BfParser::~BfParser %p\n", this);
- }
- void BfParser::SetCursorIdx(int cursorIdx)
- {
- mCursorIdx = cursorIdx;
- mCursorCheckIdx = cursorIdx;
- int checkIdx = cursorIdx;
- while (checkIdx > 0)
- {
- char c = mSrc[checkIdx - 1];
- if (!IsWhitespace(c))
- {
- if (c == '.')
- mCursorCheckIdx = checkIdx;
- break;
- }
- checkIdx--;
- }
- }
- //static int gDeleteCount = 0;
- //static int gIndentCount = 0;
- void BfParser::GetLineCharAtIdx(int idx, int& line, int& lineChar)
- {
- mParserData->GetLineCharAtIdx(idx, line, lineChar);
- }
- int BfParser::GetIndexAtLine(int line)
- {
- if (line == 0)
- return 0;
- int curLine = 0;
- for (int i = 0; i < mSrcLength; i++)
- {
- char c = mSrc[i];
- if (c == '\n')
- {
- curLine++;
- if (line == curLine)
- return i + 1;
- }
- }
- return -1;
- }
- void BfParser::Fail(const StringImpl& error, int offset)
- {
- mPassInstance->FailAt(error, mSourceData, mSrcIdx + offset);
- }
- void BfParser::UnexpectedCharacter()
- {
- if (mPreprocessorIgnoredSectionNode != NULL)
- return;
- int startIdx = mTokenStart;
- int endIdx = startIdx;
- char32_t c = u8_nextchar((char*)mSrc, &endIdx);
- int charLen = endIdx - startIdx;
- String str = "Unexpected character '";
- for (int i = 0; i < charLen; i++)
- str += mSrc[startIdx + i];
- str += StrFormat("' (0x%0X)", (int)c);
- mPassInstance->FailAt(str, mSourceData, startIdx);
- mSrcIdx = endIdx;
- }
- void BfParser::TokenFail(const StringImpl& error, int offset)
- {
- if (mPreprocessorIgnoredSectionNode == NULL)
- Fail(error, offset);
- }
- void BfParser::Init(uint64 cacheHash)
- {
- BF_ASSERT(mParserData == NULL);
- mParserData = new BfParserData();
- mSourceData = mParserData;
- mParserData->mFileName = mFileName;
- mParserData->InitFileData();
- if (mDataId != -1)
- mParserData->mDataId = mDataId;
- else
- mDataId = mParserData->mDataId;
- mParserData->mAstAllocManager = &gBfParserCache->mAstAllocManager;
- mParserData->mSrc = mSrc;
- mParserData->mSrcLength = mSrcLength;
- if (cacheHash != 0)
- {
- BfLogSysM("Creating cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
- mParserData->mHash = cacheHash;
- mParserData->mRefCount = 0; // 0 means we want to EVENTUALLY write it to the cache
- mSrcAllocSize = -1;
- }
- else
- {
- BfLogSysM("Creating unique parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
- mParserData->mUniqueParser = this;
- }
- mJumpTableSize = ((mSrcLength + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
- mJumpTable = new BfLineStartEntry[mJumpTableSize];
- memset(mJumpTable, 0, mJumpTableSize * sizeof(BfLineStartEntry));
- mParserData->mJumpTable = mJumpTable;
- mParserData->mJumpTableSize = mJumpTableSize;
- mAlloc = &mParserData->mAlloc;
- mAlloc->mSourceData = mSourceData;
- }
- void BfParser::NewLine()
- {
- mLineStart = mSrcIdx;
- mLineNum++;
- if (mJumpTable == NULL)
- return;
- int idx = (mSrcIdx / PARSER_JUMPTABLE_DIVIDE);
- if (idx == 0)
- return;
- BF_ASSERT(idx < mJumpTableSize);
- BfLineStartEntry* jumpTableEntry = mJumpTable + idx;
- jumpTableEntry->mCharIdx = mSrcIdx;
- jumpTableEntry->mLineNum = mLineNum;
- }
- void BfParser::SetSource(const char* data, int length)
- {
- const int EXTRA_BUFFER_SIZE = 80; // Extra chars for a bit of AllocChars room
- //TODO: Check cache
- // Don't cache if we have a Cursorid set,
- // if mDataId != -1
- // if BfParerFlag != 0
- bool canCache = true;
- if (mDataId != -1)
- canCache = false;
- if (mParserFlags != 0)
- canCache = false;
- if (mCursorIdx != -1)
- canCache = false;
- if (mCompatMode)
- canCache = false;
- if (mQuickCompatMode)
- canCache = false;
- if (mFileName.IsEmpty())
- canCache = false;
- if (mProject == NULL)
- canCache = false;
- if (mIsEmitted)
- canCache = false;
- uint64 cacheHash = 0;
- if (canCache)
- {
- AutoCrit autoCrit(gBfParserCache->mCritSect);
- HashContext hashCtx;
- hashCtx.MixinStr(mFileName);
- hashCtx.Mixin(data, length);
- cacheHash = hashCtx.Finish64();
- BfParserCache::LookupEntry lookupEntry;
- lookupEntry.mFileName = mFileName;
- lookupEntry.mSrc = data;
- lookupEntry.mSrcLength = length;
- lookupEntry.mHash = cacheHash;
- lookupEntry.mProject = mProject;
- BfParserCache::DataEntry* dataEntryP;
- if (gBfParserCache->mEntries.TryGetWith(lookupEntry, &dataEntryP))
- {
- mUsingCache = true;
- mParserData = dataEntryP->mParserData;
- BF_ASSERT(mParserData->mDidReduce);
- BfLogSysM("Using cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
- mParserData->mRefCount++;
- mSourceData = mParserData;
- mSrc = mParserData->mSrc;
- mSrcLength = mParserData->mSrcLength;
- mOrigSrcLength = mParserData->mSrcLength;
- mSrcAllocSize = -1;
- mSrcIdx = 0;
- mJumpTable = mParserData->mJumpTable;
- mJumpTableSize = mParserData->mJumpTableSize;
- mAlloc = &mParserData->mAlloc;
- return;
- }
- }
- mSrcLength = length;
- mOrigSrcLength = length;
- mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/;
- char* ownedSrc = new char[mSrcAllocSize + 1];
- if (data != NULL)
- memcpy(ownedSrc, data, length);
- ownedSrc[length] = 0;
- mSrc = ownedSrc;
- mSrcIdx = 0;
- Init(cacheHash);
- }
- void BfParser::MoveSource(const char* data, int length) // Takes ownership of data ptr
- {
- mSrcLength = length;
- mOrigSrcLength = length;
- mSrcAllocSize = mSrcLength;
- mSrc = data;
- mSrcIdx = 0;
- Init();
- }
- void BfParser::RefSource(const char* data, int length)
- {
- mSrcLength = length;
- mOrigSrcLength = length;
- mSrcAllocSize = -1;
- mSrc = data;
- mSrcIdx = 0;
- Init();
- }
- bool BfParser::SrcPtrHasToken(const char* name)
- {
- const char* namePtr = name;
- int checkIdx = mSrcIdx - 1;
- while (*namePtr)
- {
- if (*(namePtr++) != mSrc[checkIdx])
- return false;
- checkIdx++;
- }
- if (!IsWhitespaceOrPunctuation(mSrc[checkIdx]))
- return false;
- mSrcIdx = checkIdx;
- mTokenEnd = checkIdx;
- return true;
- }
- void BfParser::AddErrorNode(int startIdx, int endIdx)
- {
- auto identifierNode = mAlloc->Alloc<BfIdentifierNode>();
- identifierNode->Init(mTriviaStart, startIdx, endIdx);
- //identifierNode->mSource = this;
- BfSource::AddErrorNode(identifierNode);
- }
- BfCommentKind BfParser::GetCommentKind(int startIdx)
- {
- if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<'))
- return BfCommentKind_Documentation_Block_Post;
- if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<'))
- return BfCommentKind_Documentation_Line_Post;
- if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/'))
- return BfCommentKind_Documentation_Block_Pre;
- if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/'))
- return BfCommentKind_Documentation_Line_Pre;
- if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*'))
- return BfCommentKind_Block;
- return BfCommentKind_Line;
- }
- bool BfParser::EvaluatePreprocessor(BfExpression* expr)
- {
- bool isInvalid = false;
- if (expr == NULL)
- return false;
- if (auto binaryOp = BfNodeDynCast<BfBinaryOperatorExpression>(expr))
- {
- switch (binaryOp->mOp)
- {
- case BfBinaryOp_ConditionalOr:
- return EvaluatePreprocessor(binaryOp->mLeft) || EvaluatePreprocessor(binaryOp->mRight);
- case BfBinaryOp_ConditionalAnd:
- return EvaluatePreprocessor(binaryOp->mLeft) && EvaluatePreprocessor(binaryOp->mRight);
- default: break;
- }
- }
- if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(expr))
- {
- switch (unaryOp->mOp)
- {
- case BfUnaryOp_Not:
- return !EvaluatePreprocessor(unaryOp->mExpression);
- default: break;
- }
- }
- if (auto identifier = BfNodeDynCast<BfIdentifierNode>(expr))
- {
- return HandleIfDef(identifier->ToString()) == MaybeBool_True;
- }
- if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
- {
- return EvaluatePreprocessor(parenExpr->mExpression);
- }
- if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(expr))
- {
- if (literalExpr->mValue.mTypeCode == BfTypeCode_Boolean)
- {
- return literalExpr->mValue.mBool;
- }
- }
- mPassInstance->Fail("Invalid preprocessor expression", expr);
- return false;
- }
- BfBlock* BfParser::ParseInlineBlock(int spaceIdx, int endIdx)
- {
- BfBlock* block = NULL;
- SizedArray<BfAstNode*, 8> childArr;
- mSrcIdx = spaceIdx;
- BfAstNode* startNode = NULL;
- int usedEndIdx = spaceIdx;
- int usedLineNum = mLineNum;
- int usedLineStart = mLineStart;
- while (true)
- {
- NextToken(endIdx + 1, false, true);
- if (mSyntaxToken == BfSyntaxToken_HIT_END_IDX)
- {
- mSrcIdx = usedEndIdx;
- mLineNum = usedLineNum;
- mLineStart = usedLineStart;
- auto lastNode = mSidechannelRootNode->GetLast();
- if (lastNode != NULL)
- mSrcIdx = std::max(mSrcIdx, lastNode->GetSrcEnd());
- break;
- }
- usedEndIdx = mSrcIdx;
- usedLineStart = mLineStart;
- usedLineNum = mLineNum;
- auto childNode = CreateNode();
- if (childNode == NULL)
- break;
- if ((childNode->IsA<BfCommentNode>()))
- {
- mSidechannelRootNode->Add(childNode);
- mPendingSideNodes.push_back(childNode);
- continue;
- }
- if (startNode == NULL)
- startNode = childNode;
- if (block == NULL)
- {
- block = mAlloc->Alloc<BfBlock>();
- block->mParserBlockId = ++mCurBlockId;
- }
- block->Add(childNode);
- childArr.push_back(childNode);
- //block->mChildArr.Add(childNode, &mAlloc);
- }
- if (block != NULL)
- block->Init(childArr, mAlloc);
- return block;
- }
- BfExpression* BfParser::CreateInlineExpressionFromNode(BfBlock* block)
- {
- BfReducer reducer;
- reducer.mPassInstance = mPassInstance;
- reducer.mAlloc = mAlloc;
- reducer.mCompatMode = mCompatMode;
- reducer.mVisitorPos = BfReducer::BfVisitorPos(block);
- reducer.mVisitorPos.MoveNext();
- auto startNode = reducer.mVisitorPos.GetCurrent();
- if (startNode == NULL)
- return NULL;
- auto paramExpression = reducer.CreateExpression(startNode);
- if ((paramExpression != NULL) && (reducer.mVisitorPos.GetNext() != NULL))
- mPassInstance->Fail("Expression parsing error", reducer.mVisitorPos.GetNext());
- return paramExpression;
- }
- void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block)
- {
- auto itr = block->begin();
- auto paramNode = *itr;
- if (paramNode->ToStringView() == "warning")
- {
- ++itr;
- //auto iterNode = paramNode->mNext;
- //BfAstNode* iterNode = parentNode->mChildArr.GetAs<BfAstNode*>(++curIdx);
- BfAstNode* iterNode = itr.Get();
- if (iterNode)
- {
- ++itr;
- bool enable;
- if (iterNode->ToStringView() == "disable")
- {
- enable = false;
- }
- else if (iterNode->ToStringView() == "restore")
- {
- enable = true;
- }
- else
- {
- enable = true;
- mPassInstance->FailAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
- }
- int srcStart = iterNode->GetSrcStart();
- int nodeCount = 0;
-
- iterNode = itr.Get();
- while (iterNode)
- {
- ++nodeCount;
- ++itr;
- auto tokenStr = iterNode->ToString();
- if (tokenStr != ",") // commas allowed between warning numbers but not required; we just ignore them
- {
- bool isNum = true;
- for (const auto it : tokenStr)
- {
- char c = it;
- if (c < '0' || c > '9')
- {
- isNum = false;
- break;
- }
- }
- int warningNum = atoi(tokenStr.c_str());
- if ((isNum) && (warningNum > 0))
- {
- BfParserWarningEnabledChange wec;
- wec.mEnable = enable;
- wec.mWarningNumber = warningNum;
- mParserData->mWarningEnabledChanges[iterNode->GetSrcStart()] = wec;
- }
- else
- {
- mPassInstance->FailAt("Expected decimal warning number", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
- }
- }
-
- iterNode = itr.Get();
- }
- if (nodeCount == 0)
- {
- BfParserWarningEnabledChange wec;
- wec.mEnable = enable;
- wec.mWarningNumber = -1;
- mParserData->mWarningEnabledChanges[srcStart] = wec;
- }
- }
- else
- {
- mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, paramNode->GetSrcEnd() - 1);
- }
- }
- else if (paramNode->ToStringView() == "format")
- {
- ++itr;
- BfAstNode* iterNode = itr.Get();
- if (iterNode)
- {
- if ((iterNode->ToStringView() != "disable") &&
- (iterNode->ToStringView() != "restore"))
- {
- mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"format\"", mSourceData, paramNode->GetSrcEnd() - 1);
- }
- }
- }
- else
- {
- mPassInstance->FailAt("Unknown #pragma directive", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
- }
- }
- void BfParser::HandleDefine(const StringImpl& name, BfAstNode* paramNode)
- {
- mPreprocessorDefines[name] = BfDefineState_ManualSet;
- }
- void BfParser::HandleUndefine(const StringImpl& name)
- {
- mPreprocessorDefines[name] = BfDefineState_ManualUnset;
- }
- MaybeBool BfParser::HandleIfDef(const StringImpl& name)
- {
- if ((!mAddedDependsDefines) && (mProject != NULL) && (name.StartsWith("BF_DEPENDS_")))
- {
- for (auto project : mProject->mDependencies)
- {
- StringT<64> def = "BF_DEPENDS_";
- def.Append(project->mName);
- MakeUpper(def);
- for (auto& c : def)
- {
- if (!isalnum((uint8)c))
- c = '_';
- }
- mPreprocessorDefines[def] = BfDefineState_FromProject;
- }
- mAddedDependsDefines = true;
- }
- BfDefineState defineState;
- if (mPreprocessorDefines.TryGetValue(name, &defineState))
- {
- if (defineState == BfDefineState_FromProject)
- {
- mParserData->mDefines_Def.Add(name);
- }
- return (defineState != BfDefineState_ManualUnset) ? MaybeBool_True : MaybeBool_False;
- }
- else
- {
- mParserData->mDefines_NoDef.Add(name);
- return MaybeBool_False;
- }
- }
- MaybeBool BfParser::HandleProcessorCondition(BfBlock* paramNode)
- {
- if (paramNode == NULL)
- return MaybeBool_False;
- bool found = false;
- auto paramExpression = CreateInlineExpressionFromNode(paramNode);
- if (paramExpression != NULL)
- {
- return EvaluatePreprocessor(paramExpression) ? MaybeBool_True : MaybeBool_False;
- }
- return MaybeBool_False;
- }
- void BfParser::HandleInclude(BfAstNode* paramNode)
- {
- }
- void BfParser::HandleIncludeNext(BfAstNode* paramNode)
- {
- }
- bool BfParser::HandlePreprocessor()
- {
- int triviaStart = mTriviaStart;
- int checkIdx = 0;
- for (int checkIdx = mLineStart; checkIdx < mSrcIdx - 1; checkIdx++)
- {
- if (!isspace((uint8)mSrc[checkIdx]))
- {
- if (mPreprocessorIgnoreDepth == 0)
- {
- if (mSrc[mSrcIdx - 1] != '#')
- return false;
- mPassInstance->FailAt("Preprocessor directives must appear as the first non-whitespace character on a line", mSourceData, checkIdx);
- break;
- }
- else
- continue; // Keep searching for #endif
- }
- }
- String pragma;
- String pragmaParam;
- switch (mSrc[mSrcIdx - 1])
- {
- case '<':
- if (mPreprocessorIgnoreDepth > 0)
- return false;
- pragma = "<<<";
- break;
- case '=':
- if (mPreprocessorIgnoreDepth > 0)
- return false;
- pragma = "===";
- break;
- case '>':
- if (mPreprocessorIgnoreDepth > 1)
- return false;
- pragma = ">>>";
- break;
- }
- bool atEnd = false;
- int startIdx = mSrcIdx - 1;
- int spaceIdx = -1;
- int charIdx = -1;
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if (c == '\n')
- {
- int checkIdx = mSrcIdx - 2;
- bool hadSlash = false;
- while (checkIdx >= startIdx)
- {
- char checkC = mSrc[checkIdx];
- if (checkC == '\\')
- {
- hadSlash = true;
- break;
- }
- if ((checkC != ' ') && (checkC != '\t'))
- break;
- checkIdx--;
- }
- if (!hadSlash)
- break;
- }
- if (c == '\0')
- {
- mSrcIdx--;
- break;
- }
- if (charIdx == -1)
- {
- if (!pragma.IsEmpty())
- {
- if (!IsWhitespace(c))
- charIdx = mSrcIdx - 1;
- }
- else
- {
- if (!IsWhitespaceOrPunctuation(c))
- charIdx = mSrcIdx - 1;
- }
- }
- else if ((IsWhitespaceOrPunctuation(c)) && (spaceIdx == -1))
- spaceIdx = mSrcIdx - 1;
- }
- if (charIdx == -1)
- {
- mPassInstance->FailAt("Preprocessor directive expected", mSourceData, startIdx);
- return true;
- }
- int endIdx = mSrcIdx - 1;
- while (endIdx >= startIdx)
- {
- if (!IsWhitespace(mSrc[endIdx]))
- break;
- endIdx--;
- }
- BfBlock* paramNode = NULL;
- if (pragma.IsEmpty())
- {
- if (spaceIdx != -1)
- {
- pragma = String(mSrc + charIdx, mSrc + spaceIdx);
- int breakIdx = spaceIdx;
- while (spaceIdx <= endIdx)
- {
- if (!isspace((uint8)mSrc[spaceIdx]))
- break;
- spaceIdx++;
- }
- if (spaceIdx <= endIdx)
- pragmaParam = String(mSrc + spaceIdx, mSrc + endIdx + 1);
- paramNode = ParseInlineBlock(breakIdx, endIdx);
- }
- else
- {
- pragma = String(mSrc + charIdx, mSrc + endIdx + 1);
- mSrcIdx = endIdx + 1;
- }
- }
- else
- {
- mSrcIdx--;
- }
- bool wantsSingleParam = true;
- bool addToPreprocessorAccept = false;
- bool addToPreprocessorAcceptResolved = true;
- bool wantedParam = false;
- if (mPreprocessorIgnoreDepth > 0)
- {
- BF_ASSERT(!mPreprocessorNodeStack.empty());
- int ignoreEnd = std::max(mPreprocessorIgnoredSectionNode->GetSrcStart(), mLineStart - 1);
- if ((pragma == "endif") || (pragma == ">>>"))
- {
- mPreprocessorIgnoreDepth--;
- if (mPreprocessorIgnoreDepth > 0)
- return true;
- mPreprocessorNodeStack.pop_back();
- mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
- mPreprocessorIgnoredSectionNode = NULL;
- triviaStart = ignoreEnd;
- }
- else if ((pragma == "if") ||
- ((mCompatMode) && (pragma == "ifdef")) ||
- ((mCompatMode) && (pragma == "ifndef")))
- {
- wantsSingleParam = false;
- wantedParam = true;
- mPreprocessorIgnoreDepth++;
- }
- else if (pragma == "else")
- {
- if (mCompatMode)
- {
- if (paramNode != NULL)
- {
- if (paramNode->ToString() == "if")
- {
- bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
- if (found)
- {
- addToPreprocessorAccept = true;
- mPreprocessorNodeStack.pop_back();
- mPreprocessorIgnoreDepth = 0;
- mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
- mPreprocessorIgnoredSectionNode = NULL;
- triviaStart = ignoreEnd;
- }
- else
- {
- mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
- }
- return true;
- }
- }
- }
- if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
- {
- addToPreprocessorAccept = true;
- mPreprocessorNodeStack.pop_back();
- mPreprocessorIgnoreDepth = 0;
- mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
- mPreprocessorIgnoredSectionNode = NULL;
- triviaStart = ignoreEnd;
- }
- }
- else if (pragma == "elif")
- {
- wantsSingleParam = false;
- if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
- {
- wantedParam = true;
- bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
- if (found)
- {
- addToPreprocessorAccept = true;
- mPreprocessorNodeStack.pop_back();
- mPreprocessorIgnoreDepth = 0;
- mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
- mPreprocessorIgnoredSectionNode = NULL;
- triviaStart = ignoreEnd;
- }
- else
- {
- mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
- }
- }
- }
- if (mPreprocessorIgnoreDepth > 0)
- return true;
- }
- else
- {
- if ((pragma == "if") || (pragma == "<<<") ||
- ((mCompatMode) && (pragma == "ifdef")) ||
- ((mCompatMode) && (pragma == "ifndef")))
- {
- wantsSingleParam = false;
- wantedParam = true;
- bool found = false;
- if (pragma == "<<<")
- {
- mPassInstance->FailAt("Conflict marker found", mSourceData, startIdx, endIdx - startIdx + 1);
- wantedParam = false;
- found = true;
- }
- else if (!mQuickCompatMode)
- {
- if (pragma == "if")
- found = HandleProcessorCondition(paramNode) != MaybeBool_False;
- else if (pragma == "ifdef")
- found = HandleIfDef(pragmaParam) != MaybeBool_False;
- else if (pragma == "ifndef")
- found = HandleIfDef(pragmaParam) != MaybeBool_True;
- }
- if (!found)
- mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
- addToPreprocessorAccept = true;
- if ((!found) && (!mQuickCompatMode) && (!mCompleteParse))
- {
- addToPreprocessorAcceptResolved = false;
- mPreprocessorIgnoreDepth = 1;
- }
- }
- else if ((pragma == "else") || (pragma == "==="))
- {
- if (!mQuickCompatMode && !mCompleteParse)
- {
- if (mPreprocessorNodeStack.empty())
- mPassInstance->FailAt("Unexpected #else", mSourceData, startIdx, mSrcIdx - startIdx);
- else
- {
- BF_ASSERT(mPreprocessorNodeStack.back().second);
- mPreprocessorIgnoreDepth = 1;
- }
- }
- }
- else if (pragma == "elif")
- {
- wantsSingleParam = false;
- if (!mQuickCompatMode && !mCompleteParse)
- {
- if (mPreprocessorNodeStack.empty())
- mPassInstance->FailAt("Unexpected #elif", mSourceData, startIdx, mSrcIdx - startIdx);
- else
- {
- BF_ASSERT(mPreprocessorNodeStack.back().second);
- mPreprocessorIgnoreDepth = 1;
- }
- }
- wantedParam = true;
- }
- else if (pragma == "endif")
- {
- if (mPreprocessorNodeStack.empty())
- mPassInstance->FailAt("Unexpected #endif", mSourceData, startIdx, mSrcIdx - startIdx);
- else
- mPreprocessorNodeStack.pop_back();
- }
- else if (pragma == "define")
- {
- if ((paramNode != NULL) && (!paramNode->mChildArr.IsEmpty()))
- HandleDefine(paramNode->mChildArr[0]->ToString(), paramNode);
- wantedParam = true;
- }
- else if (pragma == "undef")
- {
- if ((paramNode != NULL) && (!paramNode->mChildArr.IsEmpty()))
- HandleUndefine(paramNode->mChildArr[0]->ToString());
- wantedParam = true;
- }
- else if (pragma == "error")
- {
- wantsSingleParam = false;
- mPassInstance->FailAt(pragmaParam, mSourceData, startIdx, mSrcIdx - startIdx);
- wantedParam = true;
- }
- else if (pragma == "warning")
- {
- wantsSingleParam = false;
- mPassInstance->WarnAt(BfWarning_CS1030_PragmaWarning, pragmaParam, mSourceData, startIdx, mSrcIdx - startIdx);
- wantedParam = true;
- }
- else if (pragma == "region")
- {
- wantsSingleParam = false;
- wantedParam = true;
- }
- else if (pragma == "endregion")
- {
- wantsSingleParam = false;
- if (!pragmaParam.empty())
- wantedParam = true;
- }
- else if (pragma == "pragma")
- {
- wantsSingleParam = false;
- wantedParam = true;
- if (paramNode != NULL)
- HandlePragma(pragmaParam, paramNode);
- }
- else if (pragma == "unwarn")
- {
- mParserData->mUnwarns.insert(mSrcIdx);
- }
- else if ((mCompatMode) && (pragma == "include"))
- {
- HandleInclude(paramNode);
- wantedParam = true;
- }
- else if ((mCompatMode) && (pragma == "include_next"))
- {
- HandleIncludeNext(paramNode);
- wantedParam = true;
- }
- else
- {
- mPassInstance->FailAt("Unknown preprocessor directive", mSourceData, startIdx, mSrcIdx - startIdx);
- }
- }
- if ((wantsSingleParam) && (paramNode != NULL) && (paramNode->mChildArr.size() > 1))
- {
- mPassInstance->FailAt("Only one parameter expected", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
- }
- if ((wantedParam) && (paramNode == NULL))
- {
- mPassInstance->FailAt("Expected parameter", mSourceData, startIdx, mSrcIdx - startIdx);
- }
- else if ((!wantedParam) && (paramNode != NULL))
- {
- mPassInstance->FailAt("Parameter not expected", mSourceData, startIdx, mSrcIdx - startIdx);
- }
- mTokenStart = charIdx;
- mTokenEnd = charIdx + (int)pragma.length();
- mTriviaStart = -1;
- auto bfPreprocessorCmdNode = mAlloc->Alloc<BfIdentifierNode>();
- bfPreprocessorCmdNode->Init(this);
- mTriviaStart = triviaStart;
- auto bfPreprocessorNode = mAlloc->Alloc<BfPreprocessorNode>();
- mTokenStart = startIdx;
- mTokenEnd = mSrcIdx;
- bfPreprocessorNode->Init(this);
- bfPreprocessorNode->Add(bfPreprocessorCmdNode);
- bfPreprocessorNode->mCommand = bfPreprocessorCmdNode;
- if (paramNode != NULL)
- {
- int curIdx = 0;
- bfPreprocessorNode->mArgument = paramNode;
- }
- mPendingSideNodes.push_back(bfPreprocessorNode);
- mTokenStart = mSrcIdx;
- mTriviaStart = mSrcIdx;
- triviaStart = mSrcIdx;
- if (addToPreprocessorAccept)
- mPreprocessorNodeStack.push_back(std::pair<BfAstNode*, bool>(bfPreprocessorNode, addToPreprocessorAcceptResolved));
- if (mPreprocessorIgnoreDepth > 0)
- {
- mPreprocessorIgnoredSectionNode = mAlloc->Alloc<BfPreprocesorIgnoredSectionNode>();
- mPreprocessorIgnoredSectionNode->Init(this);
- mSidechannelRootNode->Add(mPreprocessorIgnoredSectionNode);
- mPendingSideNodes.push_back(mPreprocessorIgnoredSectionNode);
- }
- return true;
- }
- static int ValSign(int64 val)
- {
- if (val < 0)
- return -1;
- if (val > 0)
- return 1;
- return 0;
- }
- template <int Len>
- struct StrHashT
- {
- const static int HASH = 0;
- };
- template <>
- struct StrHashT<4>
- {
- template <const char* Str>
- struct DoHash
- {
- const static int HASH = (StrHashT<3>::HASH) ^ Str[4];
- };
- };
- // This is little endian only
- #define TOKEN_HASH(a, b, c, d) ((int)a << 0) | ((int)b << 8) | ((int)c << 16) | ((int)d << 24)
- const int text_const = (1 << 2);
- const int gClassConst = 0;
- uint32 BfParser::GetTokenHash()
- {
- char hashChars[4] = { 0 };
- int idx = 0;
- uint32 tokenHash = 0;
- int checkIdx = mSrcIdx - 1;
- while ((!IsWhitespaceOrPunctuation(mSrc[checkIdx])) && (idx < 4))
- {
- hashChars[idx++] = mSrc[checkIdx];
- checkIdx++;
- }
- return *((uint32*)hashChars);
- }
- double BfParser::ParseLiteralDouble()
- {
- char buf[256];
- int len = std::min(mTokenEnd - mTokenStart, 255);
- int outLen = 0;
- for (int i = 0; i < len; i++)
- {
- char c = mSrc[mTokenStart + i];
- if (c != '\'')
- buf[outLen++] = c;
- }
- char c = buf[outLen - 1];
- if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F'))
- buf[outLen - 1] = '\0';
- else
- buf[outLen] = '\0';
- return strtod(buf, NULL);
- }
- void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePreprocessor)
- {
- auto prevToken = mToken;
- mToken = BfToken_None;
- if (mSyntaxToken == BfSyntaxToken_EOF)
- Fail("Unexpected end of file");
- mTriviaStart = mSrcIdx;
- bool isLineStart = true;
- bool isVerbatim = false;
- int interpolateSetting = 0;
- int stringStart = -1;
- while (true)
- {
- bool setVerbatim = false;
- bool setInterpolate = false;
- uint32 checkTokenHash = 0;
- if ((endIdx != -1) && (mSrcIdx >= endIdx))
- {
- mSyntaxToken = BfSyntaxToken_HIT_END_IDX;
- return;
- }
- mTokenStart = mSrcIdx;
- mTokenEnd = mSrcIdx + 1;
- char c = mSrc[mSrcIdx++];
- if (outerIsInterpolate)
- {
- if (c == '"')
- {
- mSyntaxToken = BfSyntaxToken_StringQuote;
- return;
- }
- }
- if ((mPreprocessorIgnoreDepth > 0) && (endIdx == -1))
- {
- if (c == 0)
- {
- mSyntaxToken = BfSyntaxToken_EOF;
- mSrcIdx--;
- break;
- }
- if ((c == '>') && (mSrc[mSrcIdx] == '>') && (mSrc[mSrcIdx + 1] == '>'))
- {
- // Allow through
- }
- else if ((c != '#') || (!isLineStart))
- {
- if (c == '\n')
- {
- NewLine();
- isLineStart = true;
- continue;
- }
- if (IsWhitespace(c))
- continue;
- isLineStart = false;
- continue;
- }
- }
- switch (c)
- {
- case '!':
- if (mSrc[mSrcIdx] == '=')
- {
- if (mSrc[mSrcIdx + 1] == '=')
- {
- mToken = BfToken_CompareStrictNotEquals;
- ++mSrcIdx;
- mTokenEnd = ++mSrcIdx;
- }
- else
- {
- mToken = BfToken_CompareNotEquals;
- mTokenEnd = ++mSrcIdx;
- }
- }
- else
- mToken = BfToken_Bang;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '=':
- if (mSrc[mSrcIdx] == '=')
- {
- if (mSrc[mSrcIdx + 1] == '=')
- {
- if (mSrc[mSrcIdx + 2] == '=')
- {
- if (HandlePreprocessor())
- {
- // Conflict split
- break;
- }
- else
- {
- mToken = BfToken_CompareStrictEquals;
- ++mSrcIdx;
- mTokenEnd = ++mSrcIdx;
- }
- }
- else
- {
- mToken = BfToken_CompareStrictEquals;
- ++mSrcIdx;
- mTokenEnd = ++mSrcIdx;
- }
- }
- else
- {
- mToken = BfToken_CompareEquals;
- mTokenEnd = ++mSrcIdx;
- }
- }
- else if (mSrc[mSrcIdx] == '>')
- {
- mToken = BfToken_FatArrow;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_AssignEquals;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '+':
- if (mSrc[mSrcIdx] == '+')
- {
- mToken = BfToken_DblPlus;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_PlusEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Plus;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '^':
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_XorEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Carat;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '~':
- mToken = BfToken_Tilde;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '%':
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_ModulusEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Modulus;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '&':
- if (mSrc[mSrcIdx] == '&')
- {
- mToken = BfToken_DblAmpersand;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_AndEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '+')
- {
- if (mSrc[mSrcIdx + 1] == '=')
- {
- mToken = BfToken_AndPlusEquals;
- ++mSrcIdx;
- }
- else
- mToken = BfToken_AndPlus;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '-')
- {
- if (mSrc[mSrcIdx + 1] == '=')
- {
- mToken = BfToken_AndMinusEquals;
- ++mSrcIdx;
- }
- else
- mToken = BfToken_AndMinus;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '*')
- {
- if (mSrc[mSrcIdx + 1] == '=')
- {
- mToken = BfToken_AndStarEquals;
- ++mSrcIdx;
- }
- else
- mToken = BfToken_AndStar;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Ampersand;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '|':
- if (mSrc[mSrcIdx] == '|')
- {
- mToken = BfToken_DblBar;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_OrEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Bar;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '*':
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_MultiplyEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Star;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '?':
- if (mSrc[mSrcIdx] == '?')
- {
- mTokenEnd = ++mSrcIdx;
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_NullCoalsceEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_DblQuestion;
- }
- else if (mSrc[mSrcIdx] == '.')
- {
- mToken = BfToken_QuestionDot;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '[')
- {
- mToken = BfToken_QuestionLBracket;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_Question;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '<':
- if (mSrc[mSrcIdx] == '<')
- {
- mTokenEnd = ++mSrcIdx;
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_ShiftLeftEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '<')
- {
- mSrcIdx--;
- if (HandlePreprocessor())
- {
- // Conflict end
- break;
- }
- else
- {
- mSrcIdx++;
- mToken = BfToken_LDblChevron;
- }
- }
- else
- mToken = BfToken_LDblChevron;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- if (mSrc[mSrcIdx + 1] == '>')
- {
- mToken = BfToken_Spaceship;
- mSrcIdx += 2;
- mTokenEnd = mSrcIdx;
- }
- else
- {
- mToken = BfToken_LessEquals;
- mTokenEnd = ++mSrcIdx;
- }
- }
- else
- mToken = BfToken_LChevron;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '>':
- if (mSrc[mSrcIdx] == '>')
- {
- mTokenEnd = ++mSrcIdx;
- if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_ShiftRightEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else if (mSrc[mSrcIdx] == '>')
- {
- mSrcIdx--;
- if (HandlePreprocessor())
- {
- // Conflict start
- break;
- }
- else
- {
- mSrcIdx++;
- mToken = BfToken_RDblChevron;
- }
- }
- else
- mToken = BfToken_RDblChevron;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_GreaterEquals;
- mTokenEnd = ++mSrcIdx;
- }
- else
- mToken = BfToken_RChevron;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '@':
- setVerbatim = true;
- c = mSrc[mSrcIdx];
- if ((c == '\"') || (c == '$'))
- {
- setVerbatim = true;
- }
- else if (((c >= 'A') && (c <= 'a')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || (c == '@'))
- {
- setVerbatim = true;
- }
- else
- {
- mSyntaxToken = BfSyntaxToken_Identifier;
- return;
- }
- break;
- case '$':
- c = mSrc[mSrcIdx];
- if ((c == '\"') || (c == '@') || (c == '$'))
- {
- setInterpolate = true;
- }
- else if (!mCompatMode)
- Fail("Expected to precede string");
- break;
- case '"':
- case '\'':
- {
- SizedArray<BfUnscopedBlock*, 4> interpolateExpressions;
- String lineHeader;
- String strLiteral;
- char startChar = c;
- bool isMultiline = false;
- int triviaStart = mTriviaStart;
- if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"'))
- {
- isMultiline = true;
- mSrcIdx += 2;
- }
- int contentErrorStart = -1;
- int lineIdx = 0;
- int lineIndentIdx = -1;
- if (isMultiline)
- {
- int checkIdx = mSrcIdx;
- int lineStartIdx = checkIdx;
- while (true)
- {
- char c = mSrc[checkIdx++];
- if ((c == '"') && (mSrc[checkIdx] == '"') && (mSrc[checkIdx + 1] == '"'))
- {
- lineIndentIdx = lineStartIdx;
- for (int i = lineStartIdx; i < checkIdx - 1; i++)
- {
- char c = mSrc[i];
- if ((c != '\t') && (c != ' '))
- {
- mPassInstance->FailAt("Multi-line string literal closing delimiter must begin on a new line", mSourceData, i, checkIdx - i + 3);
- break;
- }
- lineHeader.Append(c);
- }
- break;
- }
- else if (c == '\n')
- {
- if (contentErrorStart != -1)
- {
- mPassInstance->FailAt("Multi-line string literal content must begin on a new line", mSourceData, contentErrorStart, checkIdx - contentErrorStart - 1);
- contentErrorStart = -1;
- }
- lineStartIdx = checkIdx;
- lineIdx++;
- }
- else if (c == '\0')
- break; // Will throw an error in next pass
- else if ((c == ' ') || (c == '\t') || (c == '\r'))
- {
- // Allow
- }
- else if (lineIdx == 0)
- {
- if (contentErrorStart == -1)
- contentErrorStart = checkIdx - 1;
- }
- }
- }
- int lineCount = lineIdx + 1;
- lineIdx = 0;
- int lineStart = mSrcIdx;
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if (c == '\0')
- {
- // Invalid file end
- mPassInstance->FailAt("String not terminated", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mSrcIdx--;
- break;
- }
- else if (c == '\n')
- {
- if (isMultiline)
- {
- lineIdx++;
- if ((lineIdx > 1) && (lineIdx < lineCount - 1))
- {
- strLiteral += "\n";
- }
- lineStart = mSrcIdx;
- for (int i = 0; i < lineHeader.GetLength(); i++)
- {
- char wantC = lineHeader[i];
- char c = mSrc[mSrcIdx];
- if (c == '\r')
- continue;
- if (c == '\n')
- break;
- if (wantC == c)
- {
- mSrcIdx++;
- }
- else
- {
- BfError* error = NULL;
- if (c == ' ')
- {
- error = mPassInstance->FailAt("Unexpected space in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
- }
- else if (c == '\t')
- {
- error = mPassInstance->FailAt("Unexpected tab in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
- }
- else
- {
- error = mPassInstance->FailAt("Insufficient indentation of line in multi-line string literal", mSourceData, lineStart, mSrcIdx - lineStart + 1, BfFailFlag_ShowSpaceChars);
- }
- if (error != NULL)
- {
- mPassInstance->MoreInfoAt("Change indentation of this line to match closing delimiter", mSourceData, lineIndentIdx, lineHeader.GetLength(), BfFailFlag_ShowSpaceChars);
- }
- break;
- }
- }
- NewLine();
- }
- else
- {
- mSrcIdx--;
- int errorIdx = mSrcIdx - 1;
- while ((errorIdx > 0) && (IsWhitespace(mSrc[errorIdx])))
- errorIdx--;
- mPassInstance->FailAfterAt("Newline not allowed in string", mSourceData, errorIdx);
- break;
- }
- }
- else if ((c == '"') && (c == startChar))
- {
- if (isMultiline)
- {
- if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"')) // Triple quote
- {
- // Done
- mSrcIdx += 2;
- break;
- }
- strLiteral += '"';
- }
- else
- {
- if (mSrc[mSrcIdx] == '"') // Double quote
- {
- strLiteral += '"';
- mSrcIdx++;
- }
- else
- break;
- }
- }
- else if ((c == '\'') && (c == startChar))
- {
- break;
- }
- else if ((c == '\\') && (!isVerbatim))
- {
- char c = mSrc[mSrcIdx++];
- switch (c)
- {
- case '0':
- strLiteral += '\0';
- break;
- case 'a':
- strLiteral += '\a';
- break;
- case 'b':
- strLiteral += '\b';
- break;
- case 'f':
- strLiteral += '\f';
- break;
- case 'n':
- strLiteral += '\n';
- break;
- case 'r':
- strLiteral += '\r';
- break;
- case 't':
- strLiteral += '\t';
- break;
- case 'v':
- strLiteral += '\v';
- break;
- case '\\':
- case '"':
- case '\'':
- strLiteral += c;
- break;
- case '{':
- case '}':
- strLiteral += c;
- if (interpolateSetting > 0)
- strLiteral += c;
- else
- Fail("Invalid escape sequence");
- break;
- case 'x':
- {
- int wantHexChars = 2;
- int hexVal = 0;
- int numHexChars = 0;
- while (true)
- {
- char c = mSrc[mSrcIdx];
- int hexChar = 0;
- if ((c >= '0') && (c <= '9'))
- hexChar = c - '0';
- else if ((c >= 'a') && (c <= 'f'))
- hexChar = c - 'a' + 0xa;
- else if ((c >= 'A') && (c <= 'F'))
- hexChar = c - 'A' + 0xA;
- else
- {
- Fail("Expected two hex characters");
- break;
- }
- mSrcIdx++;
- numHexChars++;
- hexVal = (hexVal * 0x10) + hexChar;
- if (numHexChars == wantHexChars)
- break;
- }
- strLiteral += (char)hexVal;
- }
- break;
- case 'u':
- {
- if (mSrc[mSrcIdx] != '{')
- {
- Fail("Expected hexadecimal code in braces after unicode escape");
- break;
- }
- mSrcIdx++;
- int hexStart = mSrcIdx;
- int hexVal = 0;
- int numHexChars = 0;
- while (true)
- {
- char c = mSrc[mSrcIdx];
- int hexChar = 0;
- if (c == '}')
- {
- if (numHexChars == 0)
- Fail("Unicode escape sequence expects hex digits");
- mSrcIdx++;
- break;
- }
- if ((c >= '0') && (c <= '9'))
- hexChar = c - '0';
- else if ((c >= 'a') && (c <= 'f'))
- hexChar = c - 'a' + 0xa;
- else if ((c >= 'A') && (c <= 'F'))
- hexChar = c - 'A' + 0xA;
- else
- {
- Fail("Hex encoding error");
- break;
- }
- mSrcIdx++;
- numHexChars++;
- if (numHexChars > 8)
- {
- Fail("Too many hex digits for an unicode scalar");
- }
- hexVal = (hexVal * 0x10) + hexChar;
- }
- char outStrUTF8[8];
- int size = u8_toutf8(outStrUTF8, 8, (uint32)hexVal);
- if (size == 0)
- {
- mPassInstance->FailAt("Invalid unicode scalar", mSourceData, hexStart, mSrcIdx - hexStart - 1);
- }
- strLiteral += outStrUTF8;
- }
- break;
- default:
- Fail("Unrecognized escape sequence");
- strLiteral += c;
- }
- }
- else
- {
- strLiteral += c;
- if (interpolateSetting > 0)
- {
- if (c == '{')
- {
- int braceCount = 1;
- while (mSrc[mSrcIdx] == '{')
- {
- braceCount++;
- mSrcIdx++;
- }
- int literalBraces = braceCount;
- if (((interpolateSetting == 1) && (braceCount % 2 == 1)) ||
- ((interpolateSetting > 1) && (braceCount >= interpolateSetting)))
- {
- BfUnscopedBlock* newBlock = mAlloc->Alloc<BfUnscopedBlock>();
- mTokenStart = mSrcIdx - interpolateSetting;
- mTriviaStart = mTokenStart;
- mTokenEnd = mTokenStart + 1;
- mToken = BfToken_LBrace;
- newBlock->mOpenBrace = (BfTokenNode*)CreateNode();
- newBlock->Init(this);
- ParseBlock(newBlock, 1, true);
- if (mToken == BfToken_RBrace)
- {
- newBlock->mCloseBrace = (BfTokenNode*)CreateNode();
- newBlock->SetSrcEnd(mSrcIdx);
- mSrcIdx--;
- }
- else if (mSyntaxToken == BfSyntaxToken_StringQuote)
- {
- mSrcIdx--;
- mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
- }
- mInAsmBlock = false;
- interpolateExpressions.Add(newBlock);
- }
- if (interpolateSetting == 1)
- {
- for (int i = 0; i < braceCount - 1; i++)
- strLiteral += '{';
- }
- else
- {
- if (braceCount >= interpolateSetting)
- {
- for (int i = 0; i < (braceCount - interpolateSetting) * 2; i++)
- strLiteral += '{';
- }
- else
- {
- for (int i = 0; i < braceCount * 2 - 1; i++)
- strLiteral += '{';
- }
- }
- }
- else if (c == '}')
- {
- int braceCount = 1;
- while (mSrc[mSrcIdx] == '}')
- {
- braceCount++;
- mSrcIdx++;
- }
- bool isClosingBrace = false;
- if (!interpolateExpressions.IsEmpty())
- {
- auto block = interpolateExpressions.back();
- if (block->mCloseBrace == NULL)
- {
- mTokenStart = mSrcIdx - 1;
- mTriviaStart = mTokenStart;
- mTokenEnd = mTokenStart + 1;
- mToken = BfToken_RBrace;
- block->mCloseBrace = (BfTokenNode*)CreateNode();
- block->SetSrcEnd(mSrcIdx);
- isClosingBrace = true;
- }
- else if (block->mCloseBrace->mSrcStart == mSrcIdx - braceCount)
- {
- block->mCloseBrace->mSrcEnd = mSrcIdx - braceCount + interpolateSetting;
- isClosingBrace = true;
- }
- }
- if (interpolateSetting == 1)
- {
- for (int i = 0; i < braceCount - 1; i++)
- strLiteral += '}';
- if ((((isClosingBrace) && (braceCount > 1) && (braceCount % 2 == 0)) || ((!isClosingBrace)) && (braceCount % 2 == 1)))
- {
- mPassInstance->FailAt("Unpaired closing brace.", mSourceData, mSrcIdx - 1, 1);
- }
- }
- else
- {
- if (isClosingBrace)
- {
- if (braceCount < interpolateSetting)
- Fail("Mismatched closing brace set");
- for (int i = 0; i < (braceCount - interpolateSetting) * 2; i++)
- strLiteral += '}';
- }
- else
- {
- for (int i = 0; i < braceCount * 2 - 1; i++)
- strLiteral += '}';
- }
- }
- }
- }
- }
- }
- if (stringStart != -1)
- {
- mTokenStart = stringStart;
- stringStart = -1;
- }
- mTriviaStart = triviaStart;
- mTokenEnd = mSrcIdx;
- mSyntaxToken = BfSyntaxToken_Literal;
- if (startChar == '\'')
- {
- mLiteral.mTypeCode = BfTypeCode_Char8;
- if (strLiteral.length() == 0)
- {
- if (mPreprocessorIgnoredSectionNode == NULL)
- mPassInstance->FailAt("Empty char literal", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- }
- else if (strLiteral.length() > 1)
- {
- int utf8Len = u8_seqlen((char*)strLiteral.c_str());
- if (utf8Len == (int)strLiteral.length())
- {
- mLiteral.mUInt64 = u8_toucs((char*)strLiteral.c_str(), (int)strLiteral.length());
- }
- else if (mPreprocessorIgnoredSectionNode == NULL)
- {
- bool isGraphemeCluster = false;
- // There's no explicit unicode limit to how many diacriticals a grapheme cluster can contain,
- // but we apply a limit for sanity for the purpose of this error
- if (strLiteral.length() < 64)
- {
- int numCodePoints;
- int numCombiningMarks;
- UTF8Categorize(strLiteral.c_str(), (int)strLiteral.length(), numCodePoints, numCombiningMarks);
- isGraphemeCluster = numCodePoints - numCombiningMarks <= 1;
- }
- if (isGraphemeCluster)
- mPassInstance->FailAt("Grapheme clusters cannot be used as character literals", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
- else
- mPassInstance->FailAt("Too many characters in character literal", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
- }
- }
- else
- {
- mLiteral.mInt64 = (uint8)strLiteral[0];
- }
- if (mLiteral.mInt64 >= 0x8000) // Use 0x8000 to remain UTF16-compatible
- mLiteral.mTypeCode = BfTypeCode_Char32;
- else if (mLiteral.mInt64 >= 0x80) // Use 0x80 to remain UTF8-compatible
- mLiteral.mTypeCode = BfTypeCode_Char16;
- }
- else
- {
- auto* strLiteralPtr = new String(std::move(strLiteral));
- mParserData->mStringLiterals.push_back(strLiteralPtr);
- mLiteral.mTypeCode = BfTypeCode_CharPtr;
- mLiteral.mString = strLiteralPtr;
- }
- if (interpolateSetting > 0)
- {
- if (mLiteral.mTypeCode == BfTypeCode_CharPtr)
- {
- auto interpolateExpr = mAlloc->Alloc<BfStringInterpolationExpression>();
- interpolateExpr->mString = mLiteral.mString;
- interpolateExpr->mTriviaStart = mTriviaStart;
- interpolateExpr->mSrcStart = mTokenStart;
- interpolateExpr->mSrcEnd = mSrcIdx;
- BfSizedArrayInitIndirect(interpolateExpr->mExpressions, interpolateExpressions, mAlloc);
- mGeneratedNode = interpolateExpr;
- mSyntaxToken = BfSyntaxToken_GeneratedNode;
- mToken = BfToken_None;
- }
- }
- return;
- }
- break;
- case '/':
- if (mSrc[mSrcIdx] == '/')
- {
- // Comment line
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if ((c == '\n') || (c == '\0'))
- {
- mSrcIdx--;
- break;
- }
- }
- mTokenEnd = mSrcIdx;
- if (mPreprocessorIgnoredSectionNode == NULL)
- {
- auto commentKind = GetCommentKind(mTokenStart);
- bool handled = false;
- if (!mPendingSideNodes.IsEmpty())
- {
- if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
- {
- // This is required for folding '///' style multi-line documentation into a single node
- if (prevComment->GetTriviaStart() == mTriviaStart)
- {
- auto prevCommentKind = GetCommentKind(prevComment->mSrcStart);
- if ((!BfIsCommentBlock(commentKind)) && (commentKind == prevCommentKind))
- {
- prevComment->SetSrcEnd(mSrcIdx);
- handled = true;
- }
- }
- }
- }
- if ((!handled) && (!disablePreprocessor))
- {
- auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
- bfCommentNode->Init(this);
- bfCommentNode->mCommentKind = commentKind;
- mSidechannelRootNode->Add(bfCommentNode);
- mPendingSideNodes.push_back(bfCommentNode);
- }
- }
- break;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_DivideEquals;
- mTokenEnd = ++mSrcIdx;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- }
- else if (mSrc[mSrcIdx] == '*')
- {
- // Comment block
- int nestCount = 1;
- mSrcIdx++;
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if (c == '\n')
- {
- NewLine();
- }
- else if ((c == '\0') || ((c == '*') && (mSrc[mSrcIdx] == '/')))
- {
- // Block ends
- if (c == '\0')
- {
- nestCount = 0;
- mSrcIdx--;
- }
- else
- {
- c = 0;
- nestCount--;
- mSrcIdx++;
- }
- if (nestCount == 0)
- {
- mTokenEnd = mSrcIdx;
- if (mPreprocessorIgnoredSectionNode == NULL)
- {
- bool handled = false;
- if (!mPendingSideNodes.IsEmpty())
- {
- if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
- {
- // This is required for folding documentation into a single node
- if (prevComment->GetTriviaStart() == mTriviaStart)
- {
- //TODO: Why did we allow merging BLOCKS of comments together? This messes up BfPrinter word wrapping on comments
- // if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
- // {
- // prevComment->SetSrcEnd(mSrcIdx);
- // handled = true;
- // }
- }
- }
- }
- if (!handled)
- {
- auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
- bfCommentNode->Init(this);
- bfCommentNode->mCommentKind = GetCommentKind(mTokenStart);
- mSidechannelRootNode->Add(bfCommentNode);
- mPendingSideNodes.push_back(bfCommentNode);
- }
- }
- break;
- }
- }
- else if ((!mCompatMode) && ((c == '/') && (mSrc[mSrcIdx] == '*') && (mSrc[mSrcIdx - 2] != '/')))
- {
- nestCount++;
- mSrcIdx++;
- }
- }
- }
- else
- {
- mToken = BfToken_ForwardSlash;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- }
- break;
- case '#':
- if (disablePreprocessor)
- {
- mTokenStart = mSrcIdx - 1;
- UnexpectedCharacter();
- continue;
- }
- else
- HandlePreprocessor();
- if (mSyntaxToken == BfSyntaxToken_EOF)
- return;
- break;
- case '.':
- if (mSrc[mSrcIdx] == '.')
- {
- if (mSrc[mSrcIdx + 1] == '.')
- {
- mSrcIdx += 2;
- mTokenEnd = mSrcIdx;
- mToken = BfToken_DotDotDot;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- else if (mSrc[mSrcIdx + 1] == '<')
- {
- mSrcIdx += 2;
- mTokenEnd = mSrcIdx;
- mToken = BfToken_DotDotLess;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- else
- {
- mSrcIdx++;
- mTokenEnd = mSrcIdx;
- mToken = BfToken_DotDot;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- }
- else
- {
- mToken = BfToken_Dot;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- return;
- case ',':
- mToken = BfToken_Comma;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case ';':
- if (mInAsmBlock)
- {
- mToken = BfToken_AsmNewline;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- else
- {
- mToken = BfToken_Semicolon;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- return;
- case ':':
- {
- if ((mCompatMode) && (mSrc[mSrcIdx] == ':'))
- {
- mSrcIdx++;
- mTokenEnd = mSrcIdx;
- mToken = BfToken_Dot;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- else if (mSrc[mSrcIdx] == ':')
- {
- mSrcIdx++;
- mTokenEnd = mSrcIdx;
- mToken = BfToken_ColonColon;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- else
- {
- mToken = BfToken_Colon;
- mSyntaxToken = BfSyntaxToken_Token;
- }
- }
- return;
- case '(':
- mToken = BfToken_LParen;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case ')':
- mToken = BfToken_RParen;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '{':
- mToken = BfToken_LBrace;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '}':
- mToken = BfToken_RBrace;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '[':
- mToken = BfToken_LBracket;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case ']':
- mToken = BfToken_RBracket;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case '\n':
- NewLine();
- if (!mInAsmBlock)
- continue;
- mToken = BfToken_AsmNewline;
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- case ' ':
- case '\t':
- case '\v':
- case '\f':
- case '\r':
- continue; // Whitespace
- case '\0':
- mSrcIdx--; // Stay on EOF marker
- mSyntaxToken = BfSyntaxToken_EOF;
- return;
- default:
- if (((c >= '0') && (c <= '9')) || (c == '-'))
- {
- bool prevIsDot = prevToken == BfToken_Dot;
- if (c == '-')
- {
- // Not a number!
- if (mSrc[mSrcIdx] == '-')
- {
- mToken = BfToken_DblMinus;
- mSrcIdx++;
- }
- else if (mSrc[mSrcIdx] == '=')
- {
- mToken = BfToken_MinusEquals;
- mSrcIdx++;
- }
- else if (mSrc[mSrcIdx] == '>')
- {
- if (mCompatMode)
- mToken = BfToken_Dot;
- else
- mToken = BfToken_Arrow;
- mSrcIdx++;
- }
- else
- mToken = BfToken_Minus;
- mSyntaxToken = BfSyntaxToken_Token;
- mTokenEnd = mSrcIdx;
- return;
- }
- bool hadOverflow = false;
- uint64 val = 0;
- int numberBase = 10;
- int expVal = 0;
- int expSign = 0;
- bool hasExp = false;
- bool hadSeps = false;
- bool hadLeadingHexSep = false;
- int hexDigits = 0;
- if (c == '-')
- {
- BF_FATAL("Parsing error");
- }
- val = c - '0';
- if (c == '0')
- {
- switch (mSrc[mSrcIdx])
- {
- case 'b':
- case 'B':
- numberBase = 2;
- mSrcIdx++;
- break;
- case 'o':
- case 'O':
- numberBase = 8;
- mSrcIdx++;
- break;
- case 'x':
- case 'X':
- numberBase = 16;
- mSrcIdx++;
- break;
- }
- }
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if (c == '\'')
- {
- hadSeps = true;
- if ((numberBase == 0x10) && (hexDigits == 0))
- hadLeadingHexSep = true;
- continue;
- }
- if ((numberBase == 10) && ((c == 'e') || (c == 'E')))
- {
- // Specifying exponent
- while (true)
- {
- c = mSrc[mSrcIdx++];
- if (c == '+')
- {
- if (expSign != 0)
- TokenFail("Format error");
- expSign = 1;
- }
- else if (c == '-')
- {
- if (expSign != 0)
- TokenFail("Format error");
- expSign = -1;
- }
- else if ((c >= '0') && (c <= '9'))
- {
- hasExp = true;
- expVal *= 10;
- expVal += c - '0';
- }
- else
- {
- if (expSign == -1)
- expVal = -expVal;
- mSrcIdx--;
- break;
- }
- }
- if (!hasExp)
- {
- TokenFail("Expected an exponent");
- }
- }
- bool endNumber = false;
- bool hasDot = c == '.';
- if ((hasDot) && (mSrc[mSrcIdx] == '.'))
- {
- // Skip float parsing if we have a double-dot `1..` case
- hasDot = false;
- }
- // The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float
- if (((hasDot) && (!prevIsDot)) || (hasExp))
- {
- // Switch to floating point mode
- //double dVal = val;
- //double dValScale = 0.1;
- //if (hasExp)
- //dVal *= pow(10, expVal);
- while (true)
- {
- char c = mSrc[mSrcIdx++];
- if (IsWhitespaceOrPunctuation(c))
- {
- mTokenEnd = mSrcIdx - 1;
- mSrcIdx--;
- mLiteral.mTypeCode = BfTypeCode_Double;
- mLiteral.mDouble = ParseLiteralDouble();//dVal;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- if ((c == 'e') || (c == 'E'))
- {
- // Specifying exponent
- if (hasExp)
- TokenFail("Format error");
- while (true)
- {
- c = mSrc[mSrcIdx++];
- if (c == '+')
- {
- if (expSign != 0)
- TokenFail("Format error");
- expSign = 1;
- }
- else if (c == '-')
- {
- if (expSign != 0)
- TokenFail("Format error");
- expSign = -1;
- }
- else if ((c >= '0') && (c <= '9'))
- {
- hasExp = true;
- expVal *= 10;
- expVal += c - '0';
- }
- else
- {
- if (expSign == -1)
- expVal = -expVal;
- mSrcIdx--;
- //dVal *= pow(10, expVal);
- break;
- }
- }
- if (!hasExp)
- {
- TokenFail("Expected an exponent");
- }
- continue;
- }
- if ((c == 'f') || (c == 'F'))
- {
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Float;
- mLiteral.mSingle = (float)ParseLiteralDouble();//(float)dVal;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else if ((c == 'd') || (c == 'D'))
- {
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Double;
- mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else if ((c >= '0') && (c <= '9'))
- {
- //dVal += (c - '0') * dValScale;
- //dValScale *= 0.1;
- }
- else if ((((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) &&
- (mSrc[mSrcIdx - 2] == '.'))
- {
- // This is actually a integer followed by an Int32 call (like 123.ToString)
- mSrcIdx -= 2;
- mTokenEnd = mSrcIdx;
- mLiteral.mUInt64 = val;
- mLiteral.mTypeCode = BfTypeCode_IntUnknown;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else
- {
- mSrcIdx--;
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Double;
- mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
- mSyntaxToken = BfSyntaxToken_Literal;
- TokenFail("Unexpected character while parsing number", 0);
- return;
- }
- }
- return;
- }
- else if (c == '.')
- endNumber = true;
- if (IsWhitespaceOrPunctuation(c))
- endNumber = true;
- if (endNumber)
- {
- mTokenEnd = mSrcIdx - 1;
- mSrcIdx--;
- if ((numberBase == 0x10) &&
- ((hexDigits >= 16) || ((hadSeps) && (hexDigits > 8)) || ((hadLeadingHexSep) && (hexDigits == 8))))
- {
- if (hexDigits > 16)
- mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mLiteral.mUInt64 = val;
- if (val >= 0x8000000000000000)
- mLiteral.mTypeCode = BfTypeCode_UInt64;
- else
- mLiteral.mTypeCode = BfTypeCode_Int64;
- }
- else
- {
- mLiteral.mUInt64 = val;
- mLiteral.mTypeCode = BfTypeCode_IntUnknown;
- if ((numberBase == 0x10) && (hexDigits == 7))
- mLiteral.mWarnType = BfWarning_BF4201_Only7Hex;
- if ((numberBase == 0x10) && (hexDigits == 9))
- mLiteral.mWarnType = BfWarning_BF4202_TooManyHexForInt;
- if (hadOverflow)
- {
- mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mLiteral.mTypeCode = BfTypeCode_Int64;
- }
- //else if ((val < -0x80000000LL) || (val > 0xFFFFFFFFLL))
- else if (val >= 0x8000000000000000)
- {
- mLiteral.mTypeCode = BfTypeCode_UInt64;
- }
- else if (val > 0xFFFFFFFFLL)
- {
- mLiteral.mTypeCode = BfTypeCode_Int64;
- }
- }
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- uint64 prevVal = val;
- if ((c >= '0') && (c <= '9') && (c < '0' + numberBase))
- {
- if (numberBase == 0x10)
- hexDigits++;
- val *= numberBase;
- val += c - '0';
- }
- else if ((numberBase == 0x10) && (c >= 'A') && (c <= 'F'))
- {
- hexDigits++;
- val *= numberBase;
- val += c - 'A' + 0xA;
- }
- else if ((numberBase == 0x10) && (c >= 'a') && (c <= 'f'))
- {
- hexDigits++;
- val *= numberBase;
- val += c - 'a' + 0xa;
- }
- else if ((c == 'u') || (c == 'U'))
- {
- if ((mSrc[mSrcIdx] == 'l') || (mSrc[mSrcIdx] == 'L'))
- {
- if (mSrc[mSrcIdx] == 'l')
- TokenFail("Uppercase 'L' required for int64");
- mSrcIdx++;
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_UInt64;
- mLiteral.mUInt64 = (uint64)val;
- if (hexDigits > 16)
- mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- else if (hadOverflow)
- mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_UIntPtr;
- mLiteral.mUInt32 = (uint32)val;
- if ((hadOverflow) || ((uint64)val != (uint64)mLiteral.mUInt32))
- mPassInstance->FailAt("Value doesn't fit into uint32", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else if ((c == 'l') || (c == 'L'))
- {
- if (c == 'l')
- TokenFail("Uppercase 'L' required for int64");
- if ((mSrc[mSrcIdx] == 'u') || (mSrc[mSrcIdx] == 'U'))
- {
- mSrcIdx++;
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_UInt64;
- mLiteral.mUInt64 = (uint64)val;
- if (hexDigits > 16)
- mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- else if (hadOverflow)
- mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Int64;
- mLiteral.mInt64 = (int64)val;
- if (val == 0x8000000000000000)
- mLiteral.mTypeCode = BfTypeCode_UInt64;
- else if (val >= 0x8000000000000000)
- hadOverflow = true;
- if (numberBase == 0x10)
- {
- if (hexDigits > 16)
- mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- }
- else if (hadOverflow)
- mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else if ((c == 'f') || (c == 'F'))
- {
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Float;
- mLiteral.mSingle = (float)ParseLiteralDouble();//(float)val;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else if ((c == 'd') || (c == 'D'))
- {
- mTokenEnd = mSrcIdx;
- mLiteral.mTypeCode = BfTypeCode_Double;
- mLiteral.mDouble = ParseLiteralDouble();//(double)val;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- else
- {
- mTokenEnd = mSrcIdx - 1;
- mSrcIdx--;
- mLiteral.mUInt64 = val;
- mLiteral.mTypeCode = BfTypeCode_IntUnknown;
- mSyntaxToken = BfSyntaxToken_Literal;
- TokenFail("Unexpected character while parsing number", 0);
- return;
- }
- if ((uint64)prevVal > (uint64)val)
- hadOverflow = true;
- }
- }
- else
- {
- if ((mCompatMode) && (c == '\\'))
- {
- int checkIdx = mSrcIdx;
- bool isAtLineEnd = true;
- while (true)
- {
- char checkC = mSrc[checkIdx];
- if ((checkC == '\r') || (checkC == '\n'))
- break;
- if ((checkC != ' ') && (checkC != '\t'))
- {
- isAtLineEnd = false;
- break;
- }
- checkIdx++;
- }
- if (isAtLineEnd)
- continue;
- }
- if (!isVerbatim)
- {
- switch (GetTokenHash())
- {
- case TOKEN_HASH('t', 'r', 'u', 'e'):
- if (SrcPtrHasToken("true"))
- {
- mLiteral.mTypeCode = BfTypeCode_Boolean;
- mLiteral.mInt64 = 1;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- break;
- case TOKEN_HASH('f', 'a', 'l', 's'):
- if (SrcPtrHasToken("false"))
- {
- mLiteral.mTypeCode = BfTypeCode_Boolean;
- mLiteral.mInt64 = 0;
- mSyntaxToken = BfSyntaxToken_Literal;
- return;
- }
- break;
- case TOKEN_HASH('a', 'b', 's', 't'):
- if ((!mCompatMode) && (SrcPtrHasToken("abstract")))
- mToken = BfToken_Abstract;
- break;
- case TOKEN_HASH('a', 'l', 'l', 'o'):
- if (SrcPtrHasToken("alloctype"))
- mToken = BfToken_AllocType;
- break;
- case TOKEN_HASH('a', 'l', 'i', 'g'):
- if (SrcPtrHasToken("alignof"))
- mToken = BfToken_AlignOf;
- break;
- case TOKEN_HASH('a', 'p', 'p', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("append")))
- mToken = BfToken_Append;
- break;
- case TOKEN_HASH('a', 's', 0, 0):
- if ((!mCompatMode) && (SrcPtrHasToken("as")))
- mToken = BfToken_As;
- break;
- case TOKEN_HASH('a', 's', 'm', 0):
- if (SrcPtrHasToken("asm"))
- mToken = BfToken_Asm;
- break;
- case TOKEN_HASH('b', 'a', 's', 'e'):
- if (SrcPtrHasToken("base"))
- mToken = BfToken_Base;
- break;
- case TOKEN_HASH('b', 'o', 'x', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("box")))
- mToken = BfToken_Box;
- break;
- case TOKEN_HASH('b', 'r', 'e', 'a'):
- if (SrcPtrHasToken("break"))
- mToken = BfToken_Break;
- break;
- case TOKEN_HASH('c', 'a', 's', 'e'):
- if (SrcPtrHasToken("case"))
- mToken = BfToken_Case;
- break;
- case TOKEN_HASH('c', 'a', 't', 'c'):
- if (SrcPtrHasToken("catch"))
- mToken = BfToken_Catch;
- break;
- case TOKEN_HASH('c', 'h', 'e', 'c'):
- if ((!mCompatMode) && (SrcPtrHasToken("checked")))
- mToken = BfToken_Checked;
- break;
- case TOKEN_HASH('c', 'l', 'a', 's'):
- if (SrcPtrHasToken("class"))
- mToken = BfToken_Class;
- break;
- case TOKEN_HASH('c', 'o', 'm', 'p'):
- if ((!mCompatMode) && (SrcPtrHasToken("comptype")))
- mToken = BfToken_Comptype;
- break;
- case TOKEN_HASH('c', 'o', 'n', 'c'):
- if ((!mCompatMode) && (SrcPtrHasToken("concrete")))
- mToken = BfToken_Concrete;
- break;
- case TOKEN_HASH('c', 'o', 'n', 's'):
- if (SrcPtrHasToken("const"))
- mToken = BfToken_Const;
- break;
- case TOKEN_HASH('c', 'o', 'n', 't'):
- if (SrcPtrHasToken("continue"))
- mToken = BfToken_Continue;
- break;
- case TOKEN_HASH('d', 'e', 'c', 'l'):
- if (SrcPtrHasToken("decltype"))
- mToken = BfToken_Decltype;
- break;
- case TOKEN_HASH('d', 'e', 'f', 'a'):
- if (SrcPtrHasToken("default"))
- mToken = BfToken_Default;
- break;
- case TOKEN_HASH('d', 'e', 'f', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("defer")))
- mToken = BfToken_Defer;
- break;
- case TOKEN_HASH('d', 'e', 'l', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("delegate")))
- mToken = BfToken_Delegate;
- else if (SrcPtrHasToken("delete"))
- mToken = BfToken_Delete;
- break;
- case TOKEN_HASH('d', 'o', 0, 0):
- if (SrcPtrHasToken("do"))
- mToken = BfToken_Do;
- break;
- break;
- case TOKEN_HASH('e', 'l', 's', 'e'):
- if (SrcPtrHasToken("else"))
- mToken = BfToken_Else;
- break;
- case TOKEN_HASH('e', 'n', 'u', 'm'):
- if (SrcPtrHasToken("enum"))
- mToken = BfToken_Enum;
- break;
- case TOKEN_HASH('e', 'x', 'p', 'l'):
- if ((!mCompatMode) && (SrcPtrHasToken("explicit")))
- mToken = BfToken_Explicit;
- break;
- case TOKEN_HASH('e', 'x', 't', 'e'):
- if (SrcPtrHasToken("extern"))
- mToken = BfToken_Extern;
- else if ((!mCompatMode) && (SrcPtrHasToken("extension")))
- mToken = BfToken_Extension;
- break;
- case TOKEN_HASH('f', 'a', 'l', 'l'):
- if ((!mCompatMode) && (SrcPtrHasToken("fallthrough")))
- mToken = BfToken_Fallthrough;
- break;
- case TOKEN_HASH('f', 'i', 'n', 'a'):
- if (SrcPtrHasToken("finally"))
- mToken = BfToken_Finally;
- break;
- case TOKEN_HASH('f', 'i', 'x', 'e'):
- if (SrcPtrHasToken("fixed"))
- mToken = BfToken_Fixed;
- break;
- case TOKEN_HASH('f', 'o', 'r', 0):
- if (SrcPtrHasToken("for"))
- mToken = BfToken_For;
- break;
- case TOKEN_HASH('f', 'o', 'r', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("foreach")))
- {
- mToken = BfToken_For;
- mPassInstance->WarnAt(0, "'foreach' should be renamed to 'for'", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
- }
- break;
- case TOKEN_HASH('f', 'u', 'n', 'c'):
- if ((!mCompatMode) && (SrcPtrHasToken("function")))
- mToken = BfToken_Function;
- break;
- case TOKEN_HASH('g', 'o', 't', 'o'):
- if (SrcPtrHasToken("goto"))
- mToken = BfToken_Goto;
- break;
- case TOKEN_HASH('i', 'f', 0, 0):
- if (SrcPtrHasToken("if"))
- mToken = BfToken_If;
- break;
- case TOKEN_HASH('i', 'm', 'p', 'l'):
- if ((!mCompatMode) && (SrcPtrHasToken("implicit")))
- mToken = BfToken_Implicit;
- break;
- case TOKEN_HASH('i', 'n', 0, 0):
- if ((!mCompatMode) && (SrcPtrHasToken("in")))
- mToken = BfToken_In;
- break;
- case TOKEN_HASH('i', 'n', 'l', 'i'):
- if ((!mCompatMode) && (SrcPtrHasToken("inline")))
- mToken = BfToken_Inline;
- break;
- case TOKEN_HASH('i', 'n', 't', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("interface")))
- mToken = BfToken_Interface;
- else if ((!mCompatMode) && (SrcPtrHasToken("internal")))
- mToken = BfToken_Internal;
- break;
- case TOKEN_HASH('i', 's', 0, 0):
- if ((!mCompatMode) && (SrcPtrHasToken("is")))
- mToken = BfToken_Is;
- break;
- case TOKEN_HASH('i', 's', 'c', 'o'):
- if ((!mCompatMode) && (SrcPtrHasToken("isconst")))
- mToken = BfToken_IsConst;
- break;
- case TOKEN_HASH('l', 'e', 't', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("let")))
- mToken = BfToken_Let;
- break;
- case TOKEN_HASH('m', 'i', 'x', 'i'):
- if ((!mCompatMode) && (SrcPtrHasToken("mixin")))
- mToken = BfToken_Mixin;
- break;
- case TOKEN_HASH('m', 'u', 't', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("mut")))
- mToken = BfToken_Mut;
- break;
- case TOKEN_HASH('n', 'a', 'm', 'e'):
- if (SrcPtrHasToken("namespace"))
- mToken = BfToken_Namespace;
- else if (SrcPtrHasToken("nameof"))
- mToken = BfToken_NameOf;
- break;
- case TOKEN_HASH('n', 'e', 'w', 0):
- if (SrcPtrHasToken("new"))
- mToken = BfToken_New;
- break;
- case TOKEN_HASH('n', 'u', 'l', 'l'):
- if (SrcPtrHasToken("null"))
- mToken = BfToken_Null;
- else if (SrcPtrHasToken("nullable"))
- mToken = BfToken_Nullable;
- break;
- case TOKEN_HASH('o', 'f', 'f', 's'):
- if (SrcPtrHasToken("offsetof"))
- mToken = BfToken_OffsetOf;
- break;
- case TOKEN_HASH('o', 'p', 'e', 'r'):
- if (SrcPtrHasToken("operator"))
- mToken = BfToken_Operator;
- break;
- case TOKEN_HASH('o', 'u', 't', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("out")))
- mToken = BfToken_Out;
- break;
- case TOKEN_HASH('o', 'v', 'e', 'r'):
- if (SrcPtrHasToken("override"))
- mToken = BfToken_Override;
- break;
- case TOKEN_HASH('p', 'a', 'r', 'a'):
- if ((!mCompatMode) && (SrcPtrHasToken("params")))
- mToken = BfToken_Params;
- break;
- case TOKEN_HASH('p', 'r', 'i', 'v'):
- if (SrcPtrHasToken("private"))
- mToken = BfToken_Private;
- break;
- case TOKEN_HASH('p', 'r', 'o', 't'):
- if (SrcPtrHasToken("protected"))
- mToken = BfToken_Protected;
- break;
- case TOKEN_HASH('p', 'u', 'b', 'l'):
- if (SrcPtrHasToken("public"))
- mToken = BfToken_Public;
- break;
- case TOKEN_HASH('r', 'e', 'a', 'd'):
- if ((!mCompatMode) && (SrcPtrHasToken("readonly")))
- mToken = BfToken_ReadOnly;
- break;
- case TOKEN_HASH('r', 'e', 'f', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("ref")))
- mToken = BfToken_Ref;
- break;
- case TOKEN_HASH('r', 'e', 'p', 'e'):
- if ((!mCompatMode) && (SrcPtrHasToken("repeat")))
- mToken = BfToken_Repeat;
- break;
- case TOKEN_HASH('r', 'e', 't', 't'):
- if ((!mCompatMode) && (SrcPtrHasToken("rettype")))
- mToken = BfToken_RetType;
- break;
- case TOKEN_HASH('r', 'e', 't', 'u'):
- if (SrcPtrHasToken("return"))
- mToken = BfToken_Return;
- break;
- case TOKEN_HASH('s', 'c', 'o', 'p'):
- if ((!mCompatMode) && (SrcPtrHasToken("scope")))
- mToken = BfToken_Scope;
- break;
- case TOKEN_HASH('s', 'e', 'a', 'l'):
- if ((!mCompatMode) && (SrcPtrHasToken("sealed")))
- mToken = BfToken_Sealed;
- break;
- case TOKEN_HASH('s', 'i', 'z', 'e'):
- if (SrcPtrHasToken("sizeof"))
- mToken = BfToken_SizeOf;
- break;
- case TOKEN_HASH('s', 't', 'a', 't'):
- if (SrcPtrHasToken("static"))
- mToken = BfToken_Static;
- break;
- case TOKEN_HASH('s', 't', 'r', 'i'):
- if (SrcPtrHasToken("strideof"))
- mToken = BfToken_StrideOf;
- break;
- case TOKEN_HASH('s', 't', 'r', 'u'):
- if (SrcPtrHasToken("struct"))
- mToken = BfToken_Struct;
- break;
- case TOKEN_HASH('s', 'w', 'i', 't'):
- if (SrcPtrHasToken("switch"))
- mToken = BfToken_Switch;
- break;
- case TOKEN_HASH('t', 'h', 'i', 's'):
- if (SrcPtrHasToken("this"))
- mToken = BfToken_This;
- break;
- case TOKEN_HASH('t', 'h', 'r', 'o'):
- if (SrcPtrHasToken("throw"))
- mToken = BfToken_Throw;
- break;
- case TOKEN_HASH('t', 'r', 'y', 0):
- if (SrcPtrHasToken("try"))
- mToken = BfToken_Try;
- break;
- case TOKEN_HASH('t', 'y', 'p', 'e'):
- if (SrcPtrHasToken("typeof"))
- mToken = BfToken_TypeOf;
- else if (SrcPtrHasToken("typealias"))
- mToken = BfToken_TypeAlias;
- break;
- case TOKEN_HASH('u', 'n', 'c', 'h'):
- if (SrcPtrHasToken("unchecked"))
- mToken = BfToken_Unchecked;
- break;
- case TOKEN_HASH('u', 'n', 's', 'i'):
- if (mCompatMode)
- {
- if (SrcPtrHasToken("unsigned"))
- mToken = BfToken_Unsigned;
- }
- break;
- case TOKEN_HASH('u', 's', 'i', 'n'):
- if (SrcPtrHasToken("using"))
- mToken = BfToken_Using;
- break;
- case TOKEN_HASH('v', 'a', 'r', 0):
- if ((!mCompatMode) && (SrcPtrHasToken("var")))
- mToken = BfToken_Var;
- break;
- case TOKEN_HASH('v', 'i', 'r', 't'):
- if (SrcPtrHasToken("virtual"))
- mToken = BfToken_Virtual;
- break;
- case TOKEN_HASH('v', 'o', 'l', 'a'):
- if (SrcPtrHasToken("volatile"))
- mToken = BfToken_Volatile;
- break;
- case TOKEN_HASH('w', 'h', 'e', 'n'):
- if (SrcPtrHasToken("when"))
- mToken = BfToken_When;
- break;
- case TOKEN_HASH('w', 'h', 'e', 'r'):
- if (SrcPtrHasToken("where"))
- mToken = BfToken_Where;
- break;
- case TOKEN_HASH('w', 'h', 'i', 'l'):
- if (SrcPtrHasToken("while"))
- mToken = BfToken_While;
- break;
- case TOKEN_HASH('y', 'i', 'e', 'l'):
- if ((!mCompatMode) && (SrcPtrHasToken("yield")))
- mToken = BfToken_Yield;
- break;
- }
- }
- if (mToken != BfToken_None)
- {
- mSyntaxToken = BfSyntaxToken_Token;
- return;
- }
- bool allowChar = false;
- if (mCompatMode)
- allowChar = (c == '$') || (c == '`');
- if ((uint8)c >= 0xC0)
- {
- int cLen = 0;
- mSrcIdx--;
- uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
- mSrcIdx += cLen;
- utf8proc_category_t cat = utf8proc_category(c32);
- switch (cat)
- {
- case UTF8PROC_CATEGORY_LU:
- case UTF8PROC_CATEGORY_LL:
- case UTF8PROC_CATEGORY_LT:
- case UTF8PROC_CATEGORY_LM:
- case UTF8PROC_CATEGORY_LO:
- case UTF8PROC_CATEGORY_NL:
- case UTF8PROC_CATEGORY_SM:
- case UTF8PROC_CATEGORY_SC:
- case UTF8PROC_CATEGORY_SK:
- case UTF8PROC_CATEGORY_SO:
- allowChar = true;
- default: break;
- }
- }
- if ((allowChar) ||
- ((c >= 'A') && (c <= 'Z')) ||
- ((c >= 'a') && (c <= 'z')) ||
- (c == '_'))
- {
- if (stringStart != -1)
- {
- mTokenStart = stringStart;
- stringStart = -1;
- }
- while (true)
- {
- int curSrcIdx = mSrcIdx;
- char c = mSrc[mSrcIdx++];
- bool isValidChar =
- (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || ((c >= '0') && (c <= '9')));
- if (mCompatMode)
- isValidChar |= (c == '$') || (c == '`') || (c == '\'');
- if ((uint8)c >= 0xC0)
- {
- int cLen = 0;
- mSrcIdx--;
- uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
- mSrcIdx += cLen;
- utf8proc_category_t cat = utf8proc_category(c32);
- switch (cat)
- {
- case UTF8PROC_CATEGORY_LU:
- case UTF8PROC_CATEGORY_LL:
- case UTF8PROC_CATEGORY_LT:
- case UTF8PROC_CATEGORY_LM:
- case UTF8PROC_CATEGORY_LO:
- case UTF8PROC_CATEGORY_NL:
- case UTF8PROC_CATEGORY_SM:
- case UTF8PROC_CATEGORY_SC:
- case UTF8PROC_CATEGORY_SK:
- case UTF8PROC_CATEGORY_SO:
- case UTF8PROC_CATEGORY_MN:
- case UTF8PROC_CATEGORY_MC:
- case UTF8PROC_CATEGORY_ND:
- case UTF8PROC_CATEGORY_PC:
- case UTF8PROC_CATEGORY_CF:
- isValidChar = true;
- default: break;
- }
- }
- if (!isValidChar)
- {
- mTokenEnd = curSrcIdx;
- mSrcIdx = curSrcIdx;
- mSyntaxToken = BfSyntaxToken_Identifier;
- return;
- }
- }
- mSyntaxToken = BfSyntaxToken_Identifier;
- return;
- }
- else
- {
- AddErrorNode(mTokenStart, mSrcIdx);
- mTriviaStart = mSrcIdx;
- UnexpectedCharacter();
- continue;
- }
- }
- return;
- }
- if ((setVerbatim) && (!isVerbatim))
- {
- isVerbatim = true;
- stringStart = mTokenStart;
- }
- if (setInterpolate)
- {
- if (interpolateSetting == 0)
- stringStart = mTokenStart;
- interpolateSetting++;
- }
- }
- }
- static int gParseBlockIdx = 0;
- static int gParseMemberIdx = 0;
- void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate)
- {
- gParseBlockIdx++;
- int startParseBlockIdx = gParseBlockIdx;
- bool isAsmBlock = false;
- bool isTernary = false;
- bool forceAllowNext = false;
- SizedArray<BfAstNode*, 32> childArr;
- int parenDepth = 0;
- int bracketDepth = 0;
- while (true)
- {
- if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_Asm))
- {
- if (isAsmBlock || mInAsmBlock)
- mPassInstance->Fail("Already inside an 'asm' block", astNode);
- else
- isAsmBlock = true;
- }
- NextToken(-1, isInterpolate && (parenDepth == 0) && (bracketDepth == 0) && (!forceAllowNext));
- forceAllowNext = false;
- if (mPreprocessorIgnoredSectionNode != NULL)
- {
- if (mSyntaxToken != BfSyntaxToken_EOF)
- continue;
- mPreprocessorIgnoredSectionNode->SetSrcEnd(mSrcIdx);
- }
- if (mScanOnly)
- {
- if (mSyntaxToken == BfSyntaxToken_EOF)
- break;
- continue;
- }
- gParseMemberIdx++;
- int memberIdx = gParseMemberIdx;
- auto childNode = CreateNode();
- if (childNode == NULL)
- break;
- if (mSyntaxToken == BfSyntaxToken_EOF)
- {
- if (astNode != 0)
- Fail("Unexpected end of file");
- break;
- }
- if (mToken == BfToken_LBrace)
- {
- BfBlock* newBlock;
- BfInlineAsmStatement* asmBlock = nullptr;
- BfBlock* genBlock = nullptr;
- /*if (isAsmBlock)
- {
- asmBlock = mAlloc->Alloc<BfInlineAsmStatement>();
- asmBlock->mOpenBrace = (BfTokenNode*)CreateNode();
- newBlock = asmBlock;
- mInAsmBlock = true;
- isAsmBlock = false;
- }
- else*/
- {
- genBlock = mAlloc->Alloc<BfBlock>();
- genBlock->mParserBlockId = ++mCurBlockId;
- genBlock->mOpenBrace = (BfTokenNode*)CreateNode();
- newBlock = genBlock;
- }
- newBlock->Init(this);
- ParseBlock(newBlock, depth + 1);
- if (mToken == BfToken_RBrace)
- {
- if (genBlock)
- genBlock->mCloseBrace = (BfTokenNode*)CreateNode();
- else if (asmBlock)
- asmBlock->mCloseBrace = (BfTokenNode*)CreateNode();
- newBlock->SetSrcEnd(mSrcIdx);
- }
- else
- {
- if (mSyntaxToken == BfSyntaxToken_EOF)
- mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
- }
- mInAsmBlock = false;
- astNode->Add(newBlock);
- childArr.push_back(newBlock);
- }
- else if (mToken == BfToken_RBrace)
- {
- if (depth == 0)
- Fail("Unexpected ending brace");
- break;
- }
- else if (mToken == BfToken_Case)
- {
- if (childArr.mSize > 0)
- {
- auto prevNode = childArr[childArr.mSize - 1];
- if (auto prevIdentifier = BfNodeDynCastExact<BfIdentifierNode>(prevNode))
- {
- if (prevIdentifier->Equals("not"))
- {
- auto bfTokenNode = mAlloc->Alloc<BfTokenNode>();
- bfTokenNode->Init(prevIdentifier->mTriviaStart, prevIdentifier->mSrcStart, prevIdentifier->mSrcEnd);
- bfTokenNode->SetToken(BfToken_Not);
- childArr[childArr.mSize - 1] = bfTokenNode;
- }
- }
- }
- astNode->Add(childNode);
- childArr.Add(childNode);
- }
- else
- {
- if (mToken == BfToken_LParen)
- parenDepth++;
- else if (mToken == BfToken_RParen)
- parenDepth--;
- if (mToken == BfToken_LBracket)
- bracketDepth++;
- else if (mToken == BfToken_RBracket)
- bracketDepth--;
- if ((isInterpolate) && (parenDepth == 0) && (bracketDepth == 0))
- {
- if (mToken == BfToken_Question)
- {
- isTernary = true;
- forceAllowNext = true;
- }
- bool endNow = false;
- if (mToken == BfToken_Colon)
- {
- endNow = true;
- if (!childArr.IsEmpty())
- {
- if (auto prevToken = BfNodeDynCast<BfTokenNode>(childArr.back()))
- {
- if ((prevToken->mToken == BfToken_Scope) || (prevToken->mToken == BfToken_New) || (prevToken->mToken == BfToken_Bang) ||
- (prevToken->mToken == BfToken_Colon))
- endNow = false;
- }
- }
- if ((endNow) && (isTernary))
- {
- forceAllowNext = true;
- isTernary = false;
- endNow = false;
- }
- }
- if (mToken == BfToken_Comma)
- endNow = true;
- if (endNow)
- {
- mSrcIdx = mTokenStart;
- break;
- }
- }
- astNode->Add(childNode);
- childArr.Add(childNode);
- if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_RBrace))
- break;
- }
- }
- astNode->Init(childArr, mAlloc);
- }
- const char* BfNodeToString(BfAstNode* node)
- {
- static char str[256] = { 0 };
- strncpy(str, node->GetSourceData()->mSrc + node->GetSrcStart(), node->GetSrcLength());
- return str;
- }
- BfAstNode* BfParser::CreateNode()
- {
- switch (mSyntaxToken)
- {
- case BfSyntaxToken_Token:
- {
- auto bfTokenNode = mAlloc->Alloc<BfTokenNode>();
- bfTokenNode->Init(this);
- bfTokenNode->SetToken(mToken);
- return bfTokenNode;
- }
- case BfSyntaxToken_Identifier:
- {
- //auto bfIdentifierNode = new BfIdentifierNode();
- auto bfIdentifierNode = mAlloc->Alloc<BfIdentifierNode>();
- bfIdentifierNode->Init(this);
- return bfIdentifierNode;
- }
- case BfSyntaxToken_Literal:
- {
- auto bfLiteralExpression = mAlloc->Alloc<BfLiteralExpression>();
- bfLiteralExpression->Init(this);
- bfLiteralExpression->mValue = mLiteral;
- mLiteral.mTypeCode = BfTypeCode_None;
- mLiteral.mWarnType = 0;
- return bfLiteralExpression;
- }
- case BfSyntaxToken_GeneratedNode:
- return mGeneratedNode;
- default: break;
- }
- return NULL;
- }
- void BfParser::Parse(BfPassInstance* passInstance)
- {
- BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
- mSyntaxToken = BfSyntaxToken_None;
- mPassInstance = passInstance;
- int startIdx = mSrcIdx;
- if (mUsingCache)
- {
- mRootNode = mParserData->mRootNode;
- mSidechannelRootNode = mParserData->mSidechannelRootNode;
- mErrorRootNode = mParserData->mErrorRootNode;
- return;
- }
- mRootNode = mAlloc->Alloc<BfRootNode>();
- mRootNode->Init(this);
- mParserData->mRootNode = mRootNode;
- mSidechannelRootNode = mAlloc->Alloc<BfRootNode>();
- mSidechannelRootNode->Init(this);
- mParserData->mSidechannelRootNode = mSidechannelRootNode;
- mErrorRootNode = mAlloc->Alloc<BfRootNode>();
- mErrorRootNode->Init(this);
- mParserData->mErrorRootNode = mErrorRootNode;
- ParseBlock(mRootNode, 0);
- if (mPreprocessorNodeStack.size() > 0)
- {
- mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
- }
- if (mJumpTable != NULL)
- {
- for (int i = (startIdx / PARSER_JUMPTABLE_DIVIDE) + 1; i < mJumpTableSize; i++)
- if (mJumpTable[i].mCharIdx == 0)
- mJumpTable[i] = mJumpTable[i - 1];
- }
- if (mPassInstance->HasFailed())
- mParsingFailed = true;
- if ((mPassInstance->HasMessages()) || (mParsingFailed))
- {
- mParserData->mFailed = true; // Don't reuse cache if there were errors or warnings
- }
- mPassInstance = NULL;
- }
- int BfParser::GetCharIdAtIndex(int findIndex)
- {
- return mParserData->GetCharIdAtIndex(findIndex);
- }
- void BfParser::Close()
- {
- BfSource::Close();
- BfLogSys(mSystem, "Parser %p closing. RefCount:%d Failed:%d\n", this, mParserData->mRefCount, mParserData->mFailed);
- if ((mParserData->mRefCount == 0) && (!mParserData->mFailed))
- {
- BF_ASSERT(mParserData->mDidReduce);
- AutoCrit autoCrit(gBfParserCache->mCritSect);
- BfParserCache::DataEntry dataEntry;
- dataEntry.mParserData = mParserData;
- if (gBfParserCache->mEntries.Add(dataEntry))
- {
- BfLogSys(mSystem, "Parser %p added to cache\n", this);
- mParserData->mRefCount++;
- }
- else
- {
- // It's possible two of the same entries were being parsed at the same time on different threads.
- // Just let the loser be deleted in the dtor
- BfLogSys(mSystem, "Duplicate parser %p not added to cache\n", this);
- }
- }
- }
- void BfParser::HadSrcRealloc()
- {
- int jumpTableSize = ((mSrcAllocSize + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
- if (jumpTableSize > mJumpTableSize)
- {
- auto jumpTable = new BfLineStartEntry[jumpTableSize];
- memset(jumpTable, 0, jumpTableSize * sizeof(BfLineStartEntry));
- memcpy(jumpTable, mJumpTable, mJumpTableSize * sizeof(BfLineStartEntry));
- delete [] mJumpTable;
- mJumpTable = jumpTable;
- mJumpTableSize = jumpTableSize;
- mParserData->mJumpTable = mJumpTable;
- mParserData->mJumpTableSize = mJumpTableSize;
- }
- }
- void BfParser::GenerateAutoCompleteFrom(int srcPosition)
- {
- BfSourcePositionFinder posFinder(this, srcPosition);
- posFinder.Visit(mRootNode);
- if (posFinder.mClosestElement != NULL)
- {
- }
- }
- void BfParser::ReportMemory(MemReporter* memReporter)
- {
- //memReporter->Add("SmallAstAlloc", (int)mAlloc->mPages.size() * BfAstAllocManager::PAGE_SIZE);
- //memReporter->Add("LargeAstAlloc", mAlloc->mLargeAllocSizes);
- // if (!mUsingCache)
- // memReporter->AddBumpAlloc("AstAlloc", *mAlloc);
- //
- // memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
- memReporter->Add(sizeof(BfParser));
- if (mParserData->mRefCount <= 0)
- mParserData->ReportMemory(memReporter);
- // if (mSrcAllocSize > 0)
- // memReporter->Add("Source", mSrcAllocSize);
- }
- class BfInnermostFinder : public BfElementVisitor
- {
- public:
- int mCursorIdx;
- BfAstNode* mFoundNode;
- BfInnermostFinder(int cursorIdx)
- {
- mFoundNode = NULL;
- mCursorIdx = cursorIdx;
- }
- virtual void Visit(BfAstNode* node) override
- {
- if ((node->Contains(mCursorIdx)) && (!node->IsA<BfBlock>()))
- {
- if ((mFoundNode == NULL) || ((node->GetSrcLength()) <= (mFoundNode->GetSrcLength())))
- mFoundNode = node;
- }
- }
- virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override
- {
- BfElementVisitor::Visit(memberRefExpr);
- if (mFoundNode == memberRefExpr->mMemberName)
- {
- mFoundNode = memberRefExpr;
- }
- }
- virtual void Visit(BfAttributedIdentifierNode* identifierNode) override
- {
- BfElementVisitor::Visit(identifierNode);
- if (mFoundNode == identifierNode->mIdentifier)
- {
- mFoundNode = identifierNode;
- }
- }
- virtual void Visit(BfQualifiedNameNode* qualifiedNameNode) override
- {
- BfElementVisitor::Visit(qualifiedNameNode);
- if (mFoundNode == qualifiedNameNode->mRight)
- {
- mFoundNode = qualifiedNameNode;
- }
- }
- virtual void Visit(BfBinaryOperatorExpression* binaryOpExpr) override
- {
- BfElementVisitor::Visit(binaryOpExpr);
- if (mFoundNode == binaryOpExpr->mOpToken)
- {
- mFoundNode = binaryOpExpr;
- }
- }
- virtual void Visit(BfPreprocessorNode* preprocNode) override
- {
- if (preprocNode->mArgument != NULL)
- {
- for (auto arg : preprocNode->mArgument->mChildArr)
- {
- Visit((BfAstNode*)arg);
- if (mFoundNode == arg)
- {
- mFoundNode = preprocNode;
- }
- }
- }
- }
- };
- static BfAstNode* FindDebugExpressionNode(BfAstNode* checkNode, int cursorIdx)
- {
- BfInnermostFinder innermostFinder(cursorIdx);
- innermostFinder.VisitChild(checkNode);
- BfAstNode* exprNode = innermostFinder.mFoundNode;
- return exprNode;
- }
- //////////////////////////////////////////////////////////////////////////
- BF_EXPORT void BF_CALLTYPE BfParser_SetSource(BfParser* bfParser, const char* data, int length, const char* fileName, int textVersion)
- {
- bfParser->mFileName = fileName;
- bfParser->mTextVersion = textVersion;
- bfParser->SetSource(data, length);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetCharIdData(BfParser* bfParser, uint8* data, int length)
- {
- delete bfParser->mParserData->mCharIdData;
- bfParser->mParserData->mCharIdData = new uint8[length];
- memcpy(bfParser->mParserData->mCharIdData, data, length);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetHashMD5(BfParser* bfParser, Val128* md5Hash)
- {
- if (md5Hash != NULL)
- bfParser->mParserData->mMD5Hash = *md5Hash;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_Delete(BfParser* bfParser)
- {
- if (bfParser->mNextRevision != NULL)
- bfParser->mNextRevision->mPrevRevision = NULL;
- auto itr = std::find(bfParser->mSystem->mParsers.begin(), bfParser->mSystem->mParsers.end(), bfParser);
- bfParser->mSystem->mParsers.erase(itr);
- delete bfParser;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetNextRevision(BfParser* bfParser, BfParser* nextRevision)
- {
- BF_ASSERT(bfParser->mNextRevision == NULL);
- BF_ASSERT(nextRevision->mPrevRevision == NULL);
- bfParser->mNextRevision = nextRevision;
- nextRevision->mPrevRevision = bfParser;
- nextRevision->mDataId = bfParser->mDataId;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetCursorIdx(BfParser* bfParser, int cursorIdx)
- {
- bfParser->SetCursorIdx(cursorIdx);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetIsClassifying(BfParser* bfParser)
- {
- bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Classifying);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetEmbedKind(BfParser* bfParser, BfSourceEmbedKind embedKind)
- {
- bfParser->mEmbedKind = embedKind;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetAutocomplete(BfParser* bfParser, int cursorIdx)
- {
- BF_ASSERT(bfParser->mParserData->mRefCount == -1);
- bfParser->SetCursorIdx(cursorIdx);
- bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Autocomplete | ParserFlag_Classifying);
- }
- PerfManager* BfGetPerfManager(BfParser* bfParser)
- {
- if (bfParser == NULL)
- return NULL;
- if (bfParser->mCursorIdx != -1)
- return gPerfManager;
- return NULL;
- }
- BF_EXPORT bool BF_CALLTYPE BfParser_Parse(BfParser* bfParser, BfPassInstance* bfPassInstance, bool compatMode)
- {
- BP_ZONE("BfParser_Parse");
- int startFailIdx = bfPassInstance->mFailedIdx;
- bfParser->mCompatMode = compatMode;
- bfParser->mQuickCompatMode = compatMode;
- bfParser->Parse(bfPassInstance);
- return startFailIdx == bfPassInstance->mFailedIdx;
- }
- BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* bfPassInstance)
- {
- BP_ZONE("BfParser_Reduce");
- if (bfParser->mUsingCache)
- return true; // Already reduced
- bfParser->FinishSideNodes();
- int startFailIdx = bfPassInstance->mFailedIdx;
- int startWarningCount = bfPassInstance->mWarningCount;
- BfReducer bfReducer;
- bfReducer.mSource = bfParser;
- bfReducer.mCompatMode = bfParser->mCompatMode;
- bfReducer.mPassInstance = bfPassInstance;
- bfReducer.HandleRoot(bfParser->mRootNode);
- if ((startFailIdx != bfPassInstance->mFailedIdx) ||
- (startWarningCount != bfPassInstance->mWarningCount))
- bfParser->mParserData->mFailed = true;
- bfParser->mParserData->mDidReduce = true;
- bfParser->Close();
- return startFailIdx == bfPassInstance->mFailedIdx;
- }
- static Array<int> gCharMapping;
- BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping, int maxCol, int tabSize, bool wantsTabsAsSpaces,
- bool indentCaseLabels)
- {
- BP_ZONE("BfParser_Reduce");
- String& outString = *gTLStrReturn.Get();
- outString.clear();
- gCharMapping.Clear();
- BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
- bfPrinter.mMaxCol = maxCol;
- bfPrinter.mTabSize = tabSize;
- bfPrinter.mWantsTabsAsSpaces = wantsTabsAsSpaces;
- bfPrinter.mIndentCaseLabels = indentCaseLabels;
- bfPrinter.mFormatStart = formatStart;
- bfPrinter.mFormatEnd = formatEnd;
- bfPrinter.mCharMapping = &gCharMapping;
- bfPrinter.Visit(bfParser->mRootNode);
- outString = bfPrinter.mOutString;
- *outCharMapping = &gCharMapping[0];
- return outString.c_str();
- }
- BF_EXPORT const char* BF_CALLTYPE BfParser_DocPrep(BfParser* bfParser)
- {
- BP_ZONE("BfParser_Reduce");
- String& outString = *gTLStrReturn.Get();
- outString.clear();
- gCharMapping.Clear();
- BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
- bfPrinter.mFormatStart = -1;
- bfPrinter.mFormatEnd = -1;
- bfPrinter.mCharMapping = &gCharMapping;
- bfPrinter.mDocPrep = true;
- bfPrinter.Visit(bfParser->mRootNode);
- outString = bfPrinter.mOutString;
- return outString.c_str();
- }
- BF_EXPORT const char* BF_CALLTYPE BfParser_GetDebugExpressionAt(BfParser* bfParser, int cursorIdx)
- {
- BP_ZONE("BfParser_Reduce");
- String& outString = *gTLStrReturn.Get();
- outString.clear();
- BfAstNode* exprNode = FindDebugExpressionNode(bfParser->mRootNode, cursorIdx);
- if (exprNode == NULL)
- exprNode = FindDebugExpressionNode(bfParser->mSidechannelRootNode, cursorIdx);
- if (exprNode == NULL)
- return NULL;
- if ((exprNode->IsA<BfMethodDeclaration>()) ||
- (exprNode->IsA<BfBlock>()) ||
- (exprNode->IsA<BfStatement>()) ||
- (exprNode->IsA<BfTokenNode>())
- )
- {
- return NULL;
- }
- BfPrinter bfPrinter(bfParser->mRootNode, NULL, NULL);
- bfPrinter.mReformatting = true;
- bfPrinter.mIgnoreTrivia = true;
- bfPrinter.VisitChild(exprNode);
- outString = bfPrinter.mOutString;
- if (auto preprocessorNode = BfNodeDynCast<BfPreprocessorNode>(exprNode))
- {
- auto firstStr = preprocessorNode->mArgument->mChildArr[0]->ToString();
- if (firstStr == "warning")
- {
- String warningNumStr = preprocessorNode->mArgument->mChildArr.back()->ToString();
- int warningNum = atoi(warningNumStr.c_str());
- String warningStr;
- switch (warningNum)
- {
- case BfWarning_CS0108_MemberHidesInherited:
- warningStr = "CS0108: Derived member hides inherited member";
- break;
- case BfWarning_CS0114_MethodHidesInherited:
- warningStr = "CS0114: Derived method hides inherited member";
- break;
- case BfWarning_CS0162_UnreachableCode:
- warningStr = "CS0162: Unreachable code";
- break;
- case BfWarning_CS0168_VariableDeclaredButNeverUsed:
- warningStr = "CS0168: Variable declared but never used";
- break;
- case BfWarning_CS0472_ValueTypeNullCompare:
- warningStr = "CS0472: ValueType compared to null";
- break;
- case BfWarning_CS1030_PragmaWarning:
- warningStr = "CS1030: Pragma warning";
- break;
- }
- if (!warningStr.empty())
- outString = "`" + warningStr;
- }
- }
- return outString.c_str();
- }
- BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser* bfParser, BfResolveType resolveType, bool doFuzzyAutoComplete)
- {
- auto bfResolvePassData = new BfResolvePassData();
- bfResolvePassData->mResolveType = resolveType;
- if (bfParser != NULL)
- bfResolvePassData->mParsers.Add(bfParser);
- if ((bfParser != NULL) && ((bfParser->mParserFlags & ParserFlag_Autocomplete) != 0))
- bfResolvePassData->mAutoComplete = new BfAutoComplete(resolveType, doFuzzyAutoComplete);
- return bfResolvePassData;
- }
- BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh)
- {
- if (bfParser->mCursorIdx != -1)
- resolvePassData->mHasCursorIdx = true;
- BP_ZONE("BfParser_BuildDefs");
- int startFailIdx = bfPassInstance->mFailedIdx;
- BfDefBuilder defBuilder(bfParser->mSystem);
- defBuilder.mResolvePassData = resolvePassData;
- defBuilder.Process(bfPassInstance, bfParser, fullRefresh);
- return startFailIdx == bfPassInstance->mFailedIdx;;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_RemoveDefs(BfParser* bfParser)
- {
- }
- BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceClassifier::CharData* charData, bool preserveFlags)
- {
- if (!bfParser->mIsClosed)
- bfParser->Close();
- BfSourceClassifier bfSourceClassifier(bfParser, charData);
- bfSourceClassifier.mPreserveFlags = preserveFlags;
- bfSourceClassifier.Visit(bfParser->mRootNode);
- bfSourceClassifier.mIsSideChannel = false; //? false or true?
- bfSourceClassifier.Visit(bfParser->mErrorRootNode);
- bfSourceClassifier.mIsSideChannel = true;
- bfSourceClassifier.Visit(bfParser->mSidechannelRootNode);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_CreateClassifier(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, BfSourceClassifier::CharData* charData)
- {
- resolvePassData->mIsClassifying = true;
- bfParser->mSourceClassifier = new BfSourceClassifier(bfParser, charData);
- bfParser->mSourceClassifier->mClassifierPassId = bfPassInstance->mClassifierPassId;
- if ((resolvePassData->mParsers.IsEmpty()) || (bfParser != resolvePassData->mParsers[0]))
- resolvePassData->mParsers.Add(bfParser);
- bool doClassifyPass = (charData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
- bfParser->mSourceClassifier->mEnabled = doClassifyPass;
- bfParser->mSourceClassifier->mSkipMethodInternals = true;
- bfParser->mSourceClassifier->mSkipTypeDeclarations = true;
- if (charData != NULL)
- {
- if ((doClassifyPass) && (bfParser->mRootNode != NULL))
- bfParser->mSourceClassifier->Visit(bfParser->mRootNode);
- }
- bfParser->mSourceClassifier->mSkipTypeDeclarations = false;
- bfParser->mSourceClassifier->mSkipMethodInternals = false;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_FinishClassifier(BfParser* bfParser, BfResolvePassData* resolvePassData)
- {
- if (bfParser->mSourceClassifier == NULL)
- return;
- bool doClassifyPass = (bfParser->mSourceClassifier->mCharData != NULL) && (resolvePassData->mResolveType <= BfResolveType_Autocomplete_HighPri);
- if (doClassifyPass)
- {
- bfParser->mSourceClassifier->mIsSideChannel = false;
- if (bfParser->mErrorRootNode != NULL)
- bfParser->mSourceClassifier->Visit(bfParser->mErrorRootNode);
- bfParser->mSourceClassifier->mIsSideChannel = true;
- if (bfParser->mSidechannelRootNode != NULL)
- bfParser->mSourceClassifier->Visit(bfParser->mSidechannelRootNode);
- }
- delete bfParser->mSourceClassifier;
- bfParser->mSourceClassifier = NULL;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParser, int srcPosition)
- {
- BP_ZONE("BfParser_GenerateAutoCompletionFrom");
- bfParser->GenerateAutoCompleteFrom(srcPosition);
- }
- BF_EXPORT void BF_CALLTYPE BfParser_SetCompleteParse(BfParser* bfParser)
- {
- bfParser->mCompleteParse = true;
- }
- BF_EXPORT void BF_CALLTYPE BfParser_GetLineCharAtIdx(BfParser* bfParser, int idx, int* line, int* lineChar)
- {
- int _line, _lineChar;
- bfParser->GetLineCharAtIdx(idx, _line, _lineChar);
- *line = _line;
- *lineChar = _lineChar;
- }
- BF_EXPORT int BF_CALLTYPE BfParser_GetIndexAtLine(BfParser* bfParser, int line)
- {
- return bfParser->GetIndexAtLine(line);
- }
|