pasresolveeval.pas 189 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944
  1. {
  2. This file is part of the Free Component Library
  3. Pascal source parser
  4. Copyright (c) 2017 by Mattias Gaertner, [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************
  11. Abstract:
  12. Evaluation of Pascal constants.
  13. Works:
  14. - Emitting range check warnings
  15. - Error on overflow
  16. - bool:
  17. - not, =, <>, and, or, xor, low(), high(), pred(), succ(), ord()
  18. - boolean(0), boolean(1)
  19. - int/uint
  20. - unary +, -
  21. - binary: +, -, *, div, mod, ^^, =, <>, <, >, <=, >=, and, or, xor, not, shl, shr
  22. - Low(), High(), Pred(), Succ(), Ord(), Lo(), Hi()
  23. - typecast longint(-1), word(-2), intsingle(-1), uintsingle(1)
  24. - float:
  25. - typecast single(double), double(single), float(integer)
  26. - +, -, /, *, =, <>, <, >, <=, >=
  27. - string:
  28. - #65, '', 'a', 'ab'
  29. - +, =, <>, <, >, <=, >=
  30. - pred(), succ(), chr(), ord(), low(char), high(char)
  31. - s[]
  32. - length(string)
  33. - #$DC00
  34. - unicodestring
  35. - enum
  36. - ord(), low(), high(), pred(), succ()
  37. - typecast enumtype(integer)
  38. - set of enum, set of char, set of bool, set of int
  39. - [a,b,c..d]
  40. - +, -, *, ><, =, <>, >=, <=, in
  41. - error on duplicate in const set
  42. - arrays
  43. - length()
  44. - array of int, charm enum, bool
  45. ToDo:
  46. - arrays
  47. - [], [a..b], multi dim [a,b], concat with +
  48. - array of record
  49. - array of string
  50. - error on: array[1..2] of longint = (1,2,3);
  51. - anonymous enum range: type f=(a,b,c,d); g=b..c;
  52. }
  53. unit PasResolveEval;
  54. {$mode objfpc}{$H+}
  55. {$ifdef fpc}
  56. {$define UsePChar}
  57. {$endif}
  58. {$IFOPT Q+}{$DEFINE OverflowCheckOn}{$ENDIF}
  59. {$IFOPT R+}{$DEFINE RangeCheckOn}{$ENDIF}
  60. interface
  61. uses
  62. Sysutils, Math, PasTree, PScanner;
  63. // message numbers
  64. const
  65. nIdentifierNotFound = 3001;
  66. nNotYetImplemented = 3002;
  67. nIllegalQualifier = 3003;
  68. nSyntaxErrorExpectedButFound = 3004;
  69. nWrongNumberOfParametersForCallTo = 3005;
  70. nIncompatibleTypeArgNo = 3006;
  71. nIncompatibleTypeArgNoVarParamMustMatchExactly = 3007;
  72. nVariableIdentifierExpected = 3008;
  73. nDuplicateIdentifier = 3009;
  74. nXExpectedButYFound = 3010;
  75. nAncestorCycleDetected = 3011;
  76. nCantUseForwardDeclarationAsAncestor = 3012;
  77. nCantDetermineWhichOverloadedFunctionToCall = 3013;
  78. nForwardTypeNotResolved = 3014;
  79. nForwardProcNotResolved = 3015;
  80. nInvalidXModifierY = 3016;
  81. nAbstractMethodsMustNotHaveImplementation = 3017;
  82. nCallingConventionMismatch = 3018;
  83. nResultTypeMismatchExpectedButFound = 3019;
  84. nFunctionHeaderMismatchForwardVarName = 3020;
  85. nFunctionHidesIdentifier_NonVirtualMethod = 3021;
  86. nNoMethodInAncestorToOverride = 3022;
  87. nInheritedOnlyWorksInMethods = 3023;
  88. nInheritedNeedsAncestor = 3024;
  89. nNoPropertyFoundToOverride = 3025;
  90. nExprTypeMustBeClassOrRecordTypeGot = 3026;
  91. nPropertyNotWritable = 3027;
  92. nIncompatibleTypesGotExpected = 3028;
  93. nTypesAreNotRelatedXY = 3029;
  94. nAbstractMethodsCannotBeCalledDirectly = 3030;
  95. nMissingParameterX = 3031;
  96. nCannotAccessThisMemberFromAX = 3032;
  97. nInOperatorExpectsSetElementButGot = 3033;
  98. nWrongNumberOfParametersForTypeCast = 3034;
  99. nIllegalTypeConversionTo = 3035;
  100. nConstantExpressionExpected = 3036;
  101. nLeftSideOfIsOperatorExpectsAClassButGot = 3037;
  102. nNotReadable = 3038;
  103. nClassPropertyAccessorMustBeStatic = 3039;
  104. nClassPropertyAccessorMustNotBeStatic = 3040;
  105. nOnlyOneDefaultPropertyIsAllowed = 3041;
  106. nWrongNumberOfParametersForArray = 3042;
  107. nCantAssignValuesToAnAddress = 3043;
  108. nIllegalExpression = 3044;
  109. nCantAccessXMember = 3045;
  110. nMustBeInsideALoop = 3046;
  111. nExpectXArrayElementsButFoundY = 3047;
  112. nCannotCreateADescendantOfTheSealedXY = 3048;
  113. nAncestorIsNotExternal = 3049;
  114. nPropertyMustHaveReadOrWrite = 3050;
  115. nExternalClassInstanceCannotAccessStaticX = 3051;
  116. nXModifierMismatchY = 3052;
  117. nSymbolCannotBePublished = 3053;
  118. nCannotTypecastAType = 3054;
  119. nTypeIdentifierExpected = 3055;
  120. nCannotNestAnonymousX = 3056;
  121. nFoundCallCandidateX = 3057;
  122. nTextAfterFinalIgnored = 3058;
  123. nNoMemberIsProvidedToAccessProperty = 3059;
  124. nTheUseOfXisNotAllowedInARecord = 3060;
  125. nParameterlessConstructorsNotAllowedInRecords = 3061;
  126. nMultipleXinTypeYNameZCAandB = 3062;
  127. nXCannotHaveParameters = 3063;
  128. nRangeCheckError = 3064;
  129. nHighRangeLimitLTLowRangeLimit = 3065;
  130. nRangeCheckEvaluatingConstantsVMinMax = 3066;
  131. nIllegalChar = 3067;
  132. nOverflowInArithmeticOperation = 3068;
  133. nDivByZero = 3069;
  134. nRangeCheckInSetConstructor = 3070;
  135. nIncompatibleTypesGotParametersExpected = 3071;
  136. nAddingIndexSpecifierRequiresNewX = 3072;
  137. nCantFindUnitX = 3073;
  138. nCannotFindEnumeratorForType = 3074;
  139. nPreviousDeclMissesOverload = 3075;
  140. nOverloadedProcMissesOverload = 3076;
  141. nMethodHidesMethodOfBaseType = 3077;
  142. nContextExpectedXButFoundY = 3078;
  143. nContextXInvalidY = 3079;
  144. nIdentifierXIsNotAnInstanceField = 3080;
  145. nXIsNotSupported = 3081;
  146. nOperatorIsNotOverloadedAOpB = 3082;
  147. nIllegalQualifierAfter = 3084;
  148. nIllegalQualifierInFrontOf = 3085;
  149. nIllegalQualifierWithin = 3086;
  150. nClassXNotFoundInThisModule = 3087;
  151. nClassMethodsMustBeStaticInX = 3088;
  152. nCannotMixMethodResolutionAndDelegationAtX = 3089;
  153. nImplementsDoesNotSupportArrayProperty = 3101;
  154. nImplementsDoesNotSupportIndex = 3102;
  155. nImplementsUsedOnUnimplIntf = 3103;
  156. nDuplicateImplementsForIntf = 3103;
  157. nImplPropMustHaveReadSpec = 3104;
  158. nDoesNotImplementInterface = 3105;
  159. nTypeCycleFound = 3106;
  160. nTypeXIsNotYetCompletelyDefined = 3107;
  161. nDuplicateCaseValueXatY = 3108;
  162. nMissingFieldsX = 3109;
  163. nCantAssignValuesToConstVariable = 3110;
  164. nIllegalAssignmentToForLoopVar = 3111;
  165. nFunctionHidesIdentifier_NonProc = 3112;
  166. nTypeXCannotBeExtendedByATypeHelper = 3113;
  167. nTypeXCannotBeExtendedByARecordHelper = 3114;
  168. nDerivedXMustExtendASubClassY = 3115;
  169. nDefaultPropertyNotAllowedInHelperForX = 3116;
  170. nHelpersCannotBeUsedAsTypes = 3117;
  171. nMessageHandlersInvalidParams = 3118;
  172. nImplictConversionUnicodeToAnsi = 3119;
  173. nWrongTypeXInArrayConstructor = 3120;
  174. nUnknownCustomAttributeX = 3121;
  175. nAttributeIgnoredBecauseAbstractX = 3122;
  176. nCreatingAnInstanceOfAbstractClassY = 3123;
  177. nIllegalExpressionAfterX = 3124;
  178. nMethodHidesNonVirtualMethodExactly = 3125;
  179. nDuplicatePublishedMethodXAtY = 3126;
  180. nConstraintXSpecifiedMoreThanOnce = 3127;
  181. nConstraintXAndConstraintYCannotBeTogether = 3128;
  182. nXIsNotAValidConstraint = 3129;
  183. nWrongNumberOfParametersForGenericType = 3130;
  184. nGenericsWithoutSpecializationAsType = 3131;
  185. nDeclOfXDiffersFromPrevAtY = 3132;
  186. nTypeParamXIsMissingConstraintY = 3133;
  187. nTypeParamXIsNotCompatibleWithY = 3134;
  188. nTypeParamXMustSupportIntfY = 3135;
  189. nTypeParamsNotAllowedOnX = 3136;
  190. // using same IDs as FPC
  191. nVirtualMethodXHasLowerVisibility = 3250; // was 3050
  192. nConstructingClassXWithAbstractMethodY = 4046; // was 3080
  193. nNoMatchingImplForIntfMethodXFound = 5042; // was 3088
  194. nSymbolXIsDeprecated = 5043; // was 3062
  195. nSymbolXBelongsToALibrary = 5065; // was 3061
  196. nSymbolXIsDeprecatedY = 5066; // 3063
  197. nSymbolXIsNotPortable = 5076; // was 3058
  198. nSymbolXIsNotImplemented = 5078; // was 3060
  199. nSymbolXIsExperimental = 5079; // was 3059
  200. // resourcestring patterns of messages
  201. resourcestring
  202. sIdentifierNotFound = 'identifier not found "%s"';
  203. sNotYetImplemented = 'not yet implemented: %s';
  204. sIllegalQualifier = 'illegal qualifier "%s"';
  205. sSyntaxErrorExpectedButFound = 'Syntax error, "%s" expected but "%s" found';
  206. sWrongNumberOfParametersForCallTo = 'Wrong number of parameters specified for call to "%s"';
  207. sIncompatibleTypeArgNo = 'Incompatible type arg no. %s: Got "%s", expected "%s"';
  208. sIncompatibleTypeArgNoVarParamMustMatchExactly = 'Incompatible type arg no. %s: Got "%s", expected "%s". Var param must match exactly.';
  209. sVariableIdentifierExpected = 'Variable identifier expected';
  210. sDuplicateIdentifier = 'Duplicate identifier "%s" at %s';
  211. sXExpectedButYFound = '%s expected, but %s found';
  212. sAncestorCycleDetected = 'Ancestor cycle detected';
  213. sCantUseForwardDeclarationAsAncestor = 'Can''t use forward declaration "%s" as ancestor';
  214. sCantDetermineWhichOverloadedFunctionToCall = 'Can''t determine which overloaded function to call';
  215. sForwardTypeNotResolved = 'Forward type not resolved "%s"';
  216. sForwardProcNotResolved = 'Forward %s not resolved "%s"';
  217. sInvalidXModifierY = 'Invalid %s modifier %s';
  218. sAbstractMethodsMustNotHaveImplementation = 'Abstract method must not have an implementation.';
  219. sCallingConventionMismatch = 'Calling convention mismatch';
  220. sResultTypeMismatchExpectedButFound = 'Result type mismatch, expected %s, but found %s';
  221. sFunctionHeaderMismatchForwardVarName = 'function header "%s" doesn''t match forward : var name changes %s => %s';
  222. sFunctionHidesIdentifier = 'function hides identifier at "%s". Use overload or reintroduce';
  223. sNoMethodInAncestorToOverride = 'There is no method in an ancestor class to be overridden "%s"';
  224. sInheritedOnlyWorksInMethods = 'Inherited works only in methods';
  225. sInheritedNeedsAncestor = 'inherited needs an ancestor';
  226. sNoPropertyFoundToOverride = 'No property found to override';
  227. sExprTypeMustBeClassOrRecordTypeGot = 'Expression type must be class or record type, got %s';
  228. sPropertyNotWritable = 'No member is provided to access property';
  229. sIncompatibleTypesGotExpected = 'Incompatible types: got "%s" expected "%s"';
  230. sTypesAreNotRelatedXY = 'Types are not related: "%s" and "%s"';
  231. sAbstractMethodsCannotBeCalledDirectly = 'Abstract methods cannot be called directly';
  232. sMissingParameterX = 'Missing parameter %s';
  233. sCannotAccessThisMemberFromAX = 'Cannot access this member from a %s';
  234. sInOperatorExpectsSetElementButGot = 'the in-operator expects a set element, but got %s';
  235. sWrongNumberOfParametersForTypeCast = 'wrong number of parameters for type cast to %s';
  236. sIllegalTypeConversionTo = 'Illegal type conversion: "%s" to "%s"';
  237. sConstantExpressionExpected = 'Constant expression expected';
  238. sLeftSideOfIsOperatorExpectsAClassButGot = 'left side of is-operator expects a class, but got "%s"';
  239. sNotReadable = 'not readable';
  240. sClassPropertyAccessorMustBeStatic = 'class property accessor must be static';
  241. sClassPropertyAccessorMustNotBeStatic = 'class property accessor must not be static';
  242. sOnlyOneDefaultPropertyIsAllowed = 'Only one default property is allowed';
  243. sWrongNumberOfParametersForArray = 'Wrong number of parameters for array';
  244. sCantAssignValuesToAnAddress = 'Can''t assign values to an address';
  245. sIllegalExpression = 'Illegal expression';
  246. sCantAccessXMember = 'Can''t access %s member %s';
  247. sMustBeInsideALoop = '%s must be inside a loop';
  248. sExpectXArrayElementsButFoundY = 'Expect %s array elements, but found %s';
  249. sCannotCreateADescendantOfTheSealedXY = 'Cannot create a descendant of the sealed %s "%s"';
  250. sAncestorIsNotExternal = 'Ancestor "%s" is not external';
  251. sPropertyMustHaveReadOrWrite = 'Property must have read or write accessor';
  252. sVirtualMethodXHasLowerVisibility = 'Virtual method "%s" has a lower visibility (%s) than parent class %s (%s)';
  253. sExternalClassInstanceCannotAccessStaticX = 'External class instance cannot access static %s';
  254. sXModifierMismatchY = '%s modifier "%s" mismatch';
  255. sSymbolCannotBePublished = 'Symbol cannot be published';
  256. sCannotTypecastAType = 'Cannot type cast a type';
  257. sTypeIdentifierExpected = 'Type identifier expected';
  258. sCannotNestAnonymousX = 'Cannot nest anonymous %s';
  259. sFoundCallCandidateX = 'Found call candidate %s';
  260. sTextAfterFinalIgnored = 'Text after final ''end.''. ignored by compiler';
  261. sNoMemberIsProvidedToAccessProperty = 'No member is provided to access property';
  262. sTheUseOfXisNotAllowedInARecord = 'The use of "%s" is not allowed in a record';
  263. sParameterlessConstructorsNotAllowedInRecords = 'Parameterless constructors are not allowed in records or record/type helpers';
  264. sMultipleXinTypeYNameZCAandB = 'Multiple %s in %s %s: %s and %s';
  265. sXCannotHaveParameters = '%s cannot have parameters';
  266. sSymbolXIsNotPortable = 'Symbol "%s" is not portable';
  267. sSymbolXIsExperimental = 'Symbol "%s" is experimental';
  268. sSymbolXIsNotImplemented = 'Symbol "%s" is not implemented';
  269. sSymbolXBelongsToALibrary = 'Symbol "%s" belongs to a library';
  270. sSymbolXIsDeprecated = 'Symbol "%s" is deprecated';
  271. sSymbolXIsDeprecatedY = 'Symbol "%s" is deprecated: %s';
  272. sRangeCheckError = 'Range check error';
  273. sHighRangeLimitLTLowRangeLimit = 'High range limit < low range limit';
  274. sRangeCheckEvaluatingConstantsVMinMax = 'range check error while evaluating constants (%s is not between %s and %s)';
  275. sIllegalChar = 'Illegal character';
  276. sOverflowInArithmeticOperation = 'Overflow in arithmetic operation';
  277. sDivByZero = 'Division by zero';
  278. sRangeCheckInSetConstructor = 'range check error in set constructor or duplicate set element';
  279. sIncompatibleTypesGotParametersExpected = 'Incompatible types, got %s parameters, expected %s';
  280. sAddingIndexSpecifierRequiresNewX = 'adding index specifier requires new "%s" specifier';
  281. sCantFindUnitX = 'can''t find unit "%s"';
  282. sCannotFindEnumeratorForType = 'Cannot find an enumerator for the type "%s"';
  283. sPreviousDeclMissesOverload = 'Previous declaration of "%s" at %s was not marked with "overload" directive';
  284. sOverloadedProcMissesOverload = 'Overloaded procedure misses "overload" directive. Previous declaration is at %s';
  285. sMethodHidesMethodOfBaseType = 'Method "%s" hides method of base type "%s" at %s';
  286. sContextExpectedXButFoundY = '%s: expected "%s", but found "%s"';
  287. sContextXInvalidY = '%s: invalid %s';
  288. sIdentifierXIsNotAnInstanceField = 'Identifier "%s" is not an instance field';
  289. sConstructingClassXWithAbstractMethodY = 'Constructing a class "%s" with abstract method "%s"';
  290. sXIsNotSupported = '%s is not supported';
  291. sOperatorIsNotOverloadedAOpB = 'Operator is not overloaded: "%s" %s "%s"';
  292. sIllegalQualifierAfter = 'illegal qualifier "%s" after "%s"';
  293. sIllegalQualifierInFrontOf = 'illegal qualifier "%s" in front of "%s"';
  294. sIllegalQualifierWithin = 'illegal qualifier "%s" within "%s"';
  295. sClassXNotFoundInThisModule = 'class "%s" not found in this module';
  296. sNoMatchingImplForIntfMethodXFound = 'No matching implementation for interface method "%s" found';
  297. sClassMethodsMustBeStaticInX = 'Class methods must be static in %s';
  298. sCannotMixMethodResolutionAndDelegationAtX = 'Cannot mix method resolution and delegation at %s';
  299. sImplementsDoesNotSupportArrayProperty = '"implements" does dot support array property';
  300. sImplementsDoesNotSupportIndex = '"implements" does not support "index"';
  301. sImplementsUsedOnUnimplIntf = 'Implements-property used on unimplemented interface: "%"';
  302. sDuplicateImplementsForIntf = 'Duplicate implements for interface "%s" at %s';
  303. sImplPropMustHaveReadSpec = 'Implements-property must have read specifier';
  304. sDoesNotImplementInterface = '"%s" does not implement interface "%s"';
  305. sTypeCycleFound = 'Type cycle found';
  306. sTypeXIsNotYetCompletelyDefined = 'type "%s" is not yet completely defined';
  307. sDuplicateCaseValueXatY = 'Duplicate case value "%s", other at %s';
  308. sMissingFieldsX = 'Missing fields: "%s"';
  309. sCantAssignValuesToConstVariable = 'Can''t assign values to const variable';
  310. sIllegalAssignmentToForLoopVar = 'Illegal assignment to for-loop variable "%s"';
  311. sTypeXCannotBeExtendedByATypeHelper = 'Type "%s" cannot be extended by a type helper';
  312. sTypeXCannotBeExtendedByARecordHelper = 'Type "%s" cannot be extended by a record helper';
  313. sDerivedXMustExtendASubClassY = 'Derived %s must extend a subclass of "%s" or the class itself';
  314. sDefaultPropertyNotAllowedInHelperForX = 'Default property not allowed in helper for %s';
  315. sHelpersCannotBeUsedAsTypes = 'helpers cannot be used as types';
  316. sMessageHandlersInvalidParams = 'Message handlers can take only one call by ref. parameter';
  317. sImplictConversionUnicodeToAnsi = 'Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"';
  318. sWrongTypeXInArrayConstructor = 'Wrong type "%s" in array constructor';
  319. sUnknownCustomAttributeX = 'Unknown custom attribute "%s"';
  320. sAttributeIgnoredBecauseAbstractX = 'attribute ignored because abstract %s';
  321. sCreatingAnInstanceOfAbstractClassY = 'Creating an instance of abstract class "%s"';
  322. sIllegalExpressionAfterX = 'illegal expression after %s';
  323. sMethodHidesNonVirtualMethodExactly = 'method hides identifier at "%s". Use reintroduce';
  324. sDuplicatePublishedMethodXAtY = 'Duplicate published method "%s" at %s';
  325. sConstraintXSpecifiedMoreThanOnce = 'Constraint "%s" specified more than once';
  326. sConstraintXAndConstraintYCannotBeTogether = '"%s" constraint and "%s" constraint cannot be specified together';
  327. sXIsNotAValidConstraint = '"%s" is not a valid constraint';
  328. sWrongNumberOfParametersForGenericType = 'wrong number of parameters for generic type %s';
  329. sGenericsWithoutSpecializationAsType = 'Generics without specialization cannot be used as a type for a %s';
  330. sDeclOfXDiffersFromPrevAtY = 'Declaration of "%s" differs from previous declaration at %s';
  331. sTypeParamXIsMissingConstraintY = 'Type parameter "%s" is missing constraint "%s"';
  332. sTypeParamXIsNotCompatibleWithY = 'Type parameter "%s" is not compatible with type "%s"';
  333. sTypeParamXMustSupportIntfY = 'Type parameter "%s" must support interface "%s"';
  334. sTypeParamsNotAllowedOnX = 'Type parameters not allowed on %s';
  335. type
  336. { TResolveData - base class for data stored in TPasElement.CustomData }
  337. TResolveData = Class(TPasElementBase)
  338. private
  339. FElement: TPasElement;
  340. procedure SetElement(AValue: TPasElement);
  341. public
  342. Owner: TObject; // e.g. a TPasResolver
  343. Next: TResolveData; // TPasResolver uses this for its memory chain
  344. constructor Create; virtual;
  345. destructor Destroy; override;
  346. property Element: TPasElement read FElement write SetElement;// Element.CustomData=Self
  347. end;
  348. TResolveDataClass = class of TResolveData;
  349. type
  350. {$ifdef pas2js}
  351. TMaxPrecInt = nativeint;
  352. TMaxPrecUInt = NativeUInt;
  353. TMaxPrecFloat = double;
  354. {$else}
  355. TMaxPrecInt = int64;
  356. TMaxPrecUInt = qword;
  357. TMaxPrecFloat = extended;
  358. {$endif}
  359. TMaxPrecCurrency = currency;
  360. {$ifdef fpc}
  361. PMaxPrecInt = ^TMaxPrecInt;
  362. PMaxPrecUInt = ^TMaxPrecUInt;
  363. PMaxPrecFloat = ^TMaxPrecFloat;
  364. PMaxPrecCurrency = ^TMaxPrecCurrency;
  365. {$endif}
  366. const
  367. // Note: when FPC compares int64 with qword it converts the qword to an int64,
  368. // possibly resulting in a range check error -> using a qword const instead
  369. HighIntAsUInt = TMaxPrecUInt(High(TMaxPrecInt));
  370. const
  371. MinSafeIntCurrency = -922337203685477; // .5808
  372. MaxSafeIntCurrency = 922337203685477; // .5807
  373. MinSafeIntSingle = -16777216;
  374. MaxSafeIntSingle = 16777216;
  375. MaskUIntSingle = $3fffff;
  376. MinSafeIntDouble = -$1fffffffffffff; // -9007199254740991 54 bits (52 plus signed bit plus implicit highest bit)
  377. MaxSafeIntDouble = $1fffffffffffff; // 9007199254740991
  378. MaskUIntDouble = $1fffffffffffff;
  379. type
  380. { TResEvalValue }
  381. TREVKind = (
  382. revkNone,
  383. revkCustom,
  384. revkNil, // TResEvalValue
  385. revkBool, // TResEvalBool
  386. revkInt, // TResEvalInt
  387. revkUInt, // TResEvalUInt
  388. revkFloat, // TResEvalFloat
  389. revkCurrency, // TResEvalCurrency
  390. {$ifdef FPC_HAS_CPSTRING}
  391. revkString, // TResEvalString rawbytestring
  392. {$endif}
  393. revkUnicodeString, // TResEvalUTF16
  394. revkEnum, // TResEvalEnum
  395. revkRangeInt, // TResEvalRangeInt: range of enum, int, char, widechar, e.g. 1..2
  396. revkRangeUInt, // TResEvalRangeUInt: range of uint, e.g. 1..2
  397. revkSetOfInt, // set of enum, int, char, widechar, e.g. [1,2..3]
  398. revkExternal // TResEvalExternal: an external const
  399. );
  400. const
  401. revkAllStrings = [{$ifdef FPC_HAS_CPSTRING}revkString,{$endif}revkUnicodeString];
  402. type
  403. TResEvalValue = class(TResolveData)
  404. public
  405. Kind: TREVKind;
  406. IdentEl: TPasElement;
  407. // Note: "Element" is used when the TResEvalValue is stored as CustomData of an Element
  408. constructor CreateKind(const aKind: TREVKind);
  409. function Clone: TResEvalValue; virtual;
  410. function AsDebugString: string; virtual;
  411. function AsString: string; virtual;
  412. end;
  413. TResEvalValueClass = class of TResEvalValue;
  414. { TResEvalBool }
  415. TResEvalBool = class(TResEvalValue)
  416. public
  417. B: boolean;
  418. constructor Create; override;
  419. constructor CreateValue(const aValue: boolean);
  420. function Clone: TResEvalValue; override;
  421. function AsString: string; override;
  422. end;
  423. TResEvalTypedInt = (
  424. reitNone,
  425. reitByte,
  426. reitShortInt,
  427. reitWord,
  428. reitSmallInt,
  429. reitUIntSingle,
  430. reitIntSingle,
  431. reitLongWord,
  432. reitLongInt,
  433. reitUIntDouble,
  434. reitIntDouble);
  435. TResEvalTypedInts = set of TResEvalTypedInt;
  436. const
  437. reitDefaults = [reitNone,reitByte,reitShortInt,reitWord,reitSmallInt,reitLongWord,reitLongInt];
  438. reitAllSigned = [reitNone,reitShortInt,reitSmallInt,reitIntSingle,reitLongInt,reitIntDouble];
  439. reitAllUnsigned = [reitByte,reitWord,reitUIntSingle,reitLongWord,reitUIntDouble];
  440. reitLow: array[TResEvalTypedInt] of TMaxPrecInt = (
  441. low(TMaxPrecInt), // reitNone,
  442. low(Byte), // reitByte,
  443. low(ShortInt), // reitShortInt,
  444. low(Word), // reitWord,
  445. low(SmallInt), // reitSmallInt,
  446. 0, // reitUIntSingle,
  447. MinSafeIntSingle, // reitIntSingle,
  448. low(LongWord), // reitLongWord,
  449. low(LongInt), // reitLongInt,
  450. 0, // reitUIntDouble,
  451. MinSafeIntDouble // reitIntDouble)
  452. );
  453. reitHigh: array[TResEvalTypedInt] of TMaxPrecInt = (
  454. high(TMaxPrecInt), // reitNone,
  455. high(Byte), // reitByte,
  456. high(ShortInt), // reitShortInt,
  457. high(Word), // reitWord,
  458. high(SmallInt), // reitSmallInt,
  459. MaxSafeIntSingle, // reitUIntSingle,
  460. MaxSafeIntSingle, // reitIntSingle,
  461. high(LongWord), // reitLongWord,
  462. high(LongInt), // reitLongInt,
  463. MaxSafeIntDouble, // reitUIntDouble,
  464. MaxSafeIntDouble // reitIntDouble)
  465. );
  466. type
  467. { TResEvalInt }
  468. TResEvalInt = class(TResEvalValue)
  469. public
  470. Int: TMaxPrecInt;
  471. Typed: TResEvalTypedInt;
  472. constructor Create; override;
  473. constructor CreateValue(const aValue: TMaxPrecInt);
  474. constructor CreateValue(const aValue: TMaxPrecInt; aTyped: TResEvalTypedInt);
  475. function Clone: TResEvalValue; override;
  476. function AsString: string; override;
  477. function AsDebugString: string; override;
  478. end;
  479. { TResEvalUInt }
  480. TResEvalUInt = class(TResEvalValue)
  481. public
  482. UInt: TMaxPrecUInt;
  483. constructor Create; override;
  484. constructor CreateValue(const aValue: TMaxPrecUInt);
  485. function Clone: TResEvalValue; override;
  486. function AsString: string; override;
  487. end;
  488. { TResEvalFloat }
  489. TResEvalFloat = class(TResEvalValue)
  490. public
  491. FloatValue: TMaxPrecFloat;
  492. constructor Create; override;
  493. constructor CreateValue(const aValue: TMaxPrecFloat);
  494. function Clone: TResEvalValue; override;
  495. function AsString: string; override;
  496. function IsInt(out Int: TMaxPrecInt): boolean;
  497. end;
  498. { TResEvalCurrency }
  499. TResEvalCurrency = class(TResEvalValue)
  500. public
  501. Value: TMaxPrecCurrency;
  502. constructor Create; override;
  503. constructor CreateValue(const aValue: TMaxPrecCurrency);
  504. function Clone: TResEvalValue; override;
  505. function AsString: string; override;
  506. function IsInt(out Int: TMaxPrecInt): boolean;
  507. function AsInt: TMaxPrecInt; // value * 10.000
  508. end;
  509. {$ifdef FPC_HAS_CPSTRING}
  510. { TResEvalString - Kind=revkString }
  511. TResEvalString = class(TResEvalValue)
  512. public
  513. S: RawByteString;
  514. constructor Create; override;
  515. constructor CreateValue(const aValue: RawByteString);
  516. function Clone: TResEvalValue; override;
  517. function AsString: string; override;
  518. end;
  519. {$endif}
  520. { TResEvalUTF16 - Kind=revkUnicodeString }
  521. TResEvalUTF16 = class(TResEvalValue)
  522. public
  523. S: UnicodeString;
  524. constructor Create; override;
  525. constructor CreateValue(const aValue: UnicodeString);
  526. function Clone: TResEvalValue; override;
  527. function AsString: string; override;
  528. end;
  529. { TResEvalEnum - Kind=revkEnum, Value.Int }
  530. TResEvalEnum = class(TResEvalValue)
  531. public
  532. Index: integer; // Beware: might be outside TPasEnumType
  533. ElType: TPasEnumType; // TPasEnumType
  534. constructor Create; override;
  535. constructor CreateValue(const aValue: integer; aIdentEl: TPasEnumValue);
  536. function GetEnumValue: TPasEnumValue;
  537. function GetEnumName: String;
  538. function Clone: TResEvalValue; override;
  539. function AsDebugString: string; override;
  540. function AsString: string; override;
  541. end;
  542. TRESetElKind = (
  543. revskNone,
  544. revskEnum, // ElType is TPasEnumType
  545. revskInt,
  546. revskChar,
  547. revskBool
  548. );
  549. { TResEvalRangeInt - Kind=revkRangeInt }
  550. TResEvalRangeInt = class(TResEvalValue)
  551. public
  552. ElKind: TRESetElKind;
  553. RangeStart, RangeEnd: TMaxPrecInt;
  554. ElType: TPasType; // revskEnum: TPasEnumType
  555. constructor Create; override;
  556. constructor CreateValue(const aElKind: TRESetElKind; aElType: TPasType;
  557. const aRangeStart, aRangeEnd: TMaxPrecInt); virtual;
  558. function Clone: TResEvalValue; override;
  559. function AsString: string; override;
  560. function AsDebugString: string; override;
  561. function ElementAsString(El: TMaxPrecInt): string; virtual;
  562. end;
  563. { TResEvalRangeUInt }
  564. TResEvalRangeUInt = class(TResEvalValue)
  565. public
  566. RangeStart, RangeEnd: TMaxPrecUInt;
  567. constructor Create; override;
  568. constructor CreateValue(const aRangeStart, aRangeEnd: TMaxPrecUInt);
  569. function Clone: TResEvalValue; override;
  570. function AsString: string; override;
  571. end;
  572. { TResEvalSet - Kind=revkSetOfInt }
  573. TResEvalSet = class(TResEvalRangeInt)
  574. public
  575. const MaxCount = $ffff;
  576. type
  577. TItem = record
  578. RangeStart, RangeEnd: TMaxPrecInt;
  579. end;
  580. TItems = array of TItem;
  581. public
  582. Ranges: TItems; // disjunct, sorted ascending
  583. constructor Create; override;
  584. constructor CreateEmpty(const aElKind: TRESetElKind; aElType: TPasType = nil);
  585. constructor CreateEmptySameKind(aSet: TResEvalSet);
  586. constructor CreateValue(const aElKind: TRESetElKind; aElType: TPasType;
  587. const aRangeStart, aRangeEnd: TMaxPrecInt); override;
  588. function Clone: TResEvalValue; override;
  589. function AsString: string; override;
  590. function Add(aRangeStart, aRangeEnd: TMaxPrecInt): boolean; // false if duplicate ignored
  591. function IndexOfRange(Index: TMaxPrecInt; FindInsertPos: boolean = false): integer;
  592. function Intersects(aRangeStart, aRangeEnd: TMaxPrecInt): integer; // returns index of first intersecting range
  593. procedure ConsistencyCheck;
  594. end;
  595. { TResEvalExternal }
  596. TResEvalExternal = class(TResEvalValue)
  597. public
  598. constructor Create; override;
  599. function Clone: TResEvalValue; override;
  600. function AsString: string; override;
  601. end;
  602. TResEvalFlag = (
  603. refConst, // computing a const, error if a value is not const
  604. refConstExt, // as refConst, except allow external const
  605. refAutoConst, // set refConst if in a const
  606. refAutoConstExt // set refConstExt if in a const
  607. );
  608. TResEvalFlags = set of TResEvalFlag;
  609. TResExprEvaluator = class;
  610. TPasResEvalLogHandler = procedure(Sender: TResExprEvaluator; const id: TMaxPrecInt;
  611. MsgType: TMessageType; MsgNumber: integer;
  612. const Fmt: String; Args: Array of {$ifdef pas2js}jsvalue{$else}const{$endif}; PosEl: TPasElement) of object;
  613. TPasResEvalIdentHandler = function(Sender: TResExprEvaluator;
  614. Expr: TPrimitiveExpr; Flags: TResEvalFlags): TResEvalValue of object;
  615. TPasResEvalParamsHandler = function(Sender: TResExprEvaluator;
  616. Params: TParamsExpr; Flags: TResEvalFlags): TResEvalValue of object;
  617. TPasResEvalRangeCheckElHandler = procedure(Sender: TResExprEvaluator;
  618. El: TPasElement; var MsgType: TMessageType) of object;
  619. { TResExprEvaluator }
  620. TResExprEvaluator = class
  621. private
  622. FAllowedInts: TResEvalTypedInts;
  623. {$ifdef FPC_HAS_CPSTRING}
  624. FDefaultEncoding: TSystemCodePage;
  625. {$endif}
  626. FOnEvalIdentifier: TPasResEvalIdentHandler;
  627. FOnEvalParams: TPasResEvalParamsHandler;
  628. FOnLog: TPasResEvalLogHandler;
  629. FOnRangeCheckEl: TPasResEvalRangeCheckElHandler;
  630. protected
  631. procedure LogMsg(const id: TMaxPrecInt; MsgType: TMessageType; MsgNumber: integer;
  632. const Fmt: String; Args: Array of {$ifdef pas2js}jsvalue{$else}const{$endif}; PosEl: TPasElement); overload;
  633. procedure RaiseMsg(const Id: TMaxPrecInt; MsgNumber: integer; const Fmt: String;
  634. Args: Array of {$ifdef pas2js}jsvalue{$else}const{$endif}; ErrorPosEl: TPasElement);
  635. procedure RaiseNotYetImplemented(id: TMaxPrecInt; El: TPasElement; Msg: string = ''); virtual;
  636. procedure RaiseInternalError(id: TMaxPrecInt; const Msg: string = '');
  637. procedure RaiseConstantExprExp(id: TMaxPrecInt; ErrorEl: TPasElement);
  638. procedure RaiseRangeCheck(id: TMaxPrecInt; ErrorEl: TPasElement);
  639. procedure RaiseOverflowArithmetic(id: TMaxPrecInt; ErrorEl: TPasElement);
  640. procedure RaiseDivByZero(id: TMaxPrecInt; ErrorEl: TPasElement);
  641. function EvalUnaryExpr(Expr: TUnaryExpr; Flags: TResEvalFlags): TResEvalValue;
  642. function EvalBinaryExpr(Expr: TBinaryExpr; Flags: TResEvalFlags): TResEvalValue;
  643. function EvalBinaryRangeExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  644. function EvalBinaryAddExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  645. function EvalBinarySubExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  646. function EvalBinaryMulExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  647. function EvalBinaryDivideExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  648. function EvalBinaryDivExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  649. function EvalBinaryModExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  650. function EvalBinaryPowerExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  651. function EvalBinaryShiftExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  652. function EvalBinaryBoolOpExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  653. function EvalBinaryNEqualExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  654. function EvalBinaryLessGreaterExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  655. function EvalBinaryInExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  656. function EvalBinarySymmetricaldifferenceExpr(Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  657. function EvalParamsExpr(Expr: TParamsExpr; Flags: TResEvalFlags): TResEvalValue;
  658. function EvalArrayParamsExpr(Expr: TParamsExpr; Flags: TResEvalFlags): TResEvalValue;
  659. function EvalSetParamsExpr(Expr: TParamsExpr; Flags: TResEvalFlags): TResEvalSet;
  660. function EvalSetExpr(Expr: TPasExpr; ExprArray: TPasExprArray; Flags: TResEvalFlags): TResEvalSet;
  661. function EvalArrayValuesExpr(Expr: TArrayValues; Flags: TResEvalFlags): TResEvalSet;
  662. function EvalPrimitiveExprString(Expr: TPrimitiveExpr): TResEvalValue; virtual;
  663. procedure PredBool(Value: TResEvalBool; ErrorEl: TPasElement);
  664. procedure SuccBool(Value: TResEvalBool; ErrorEl: TPasElement);
  665. procedure PredInt(Value: TResEvalInt; ErrorEl: TPasElement);
  666. procedure SuccInt(Value: TResEvalInt; ErrorEl: TPasElement);
  667. procedure PredUInt(Value: TResEvalUInt; ErrorEl: TPasElement);
  668. procedure SuccUInt(Value: TResEvalUInt; ErrorEl: TPasElement);
  669. {$ifdef FPC_HAS_CPSTRING}
  670. procedure PredString(Value: TResEvalString; ErrorEl: TPasElement);
  671. procedure SuccString(Value: TResEvalString; ErrorEl: TPasElement);
  672. {$endif}
  673. procedure PredUnicodeString(Value: TResEvalUTF16; ErrorEl: TPasElement);
  674. procedure SuccUnicodeString(Value: TResEvalUTF16; ErrorEl: TPasElement);
  675. procedure PredEnum(Value: TResEvalEnum; ErrorEl: TPasElement);
  676. procedure SuccEnum(Value: TResEvalEnum; ErrorEl: TPasElement);
  677. function CreateResEvalInt(UInt: TMaxPrecUInt): TResEvalValue; virtual;
  678. public
  679. constructor Create;
  680. function Eval(Expr: TPasExpr; Flags: TResEvalFlags): TResEvalValue;
  681. function IsInRange(Expr, RangeExpr: TPasExpr; EmitHints: boolean): boolean;
  682. function IsInRange(Value: TResEvalValue; ValueExpr: TPasExpr;
  683. RangeValue: TResEvalValue; RangeExpr: TPasExpr; EmitHints: boolean): boolean;
  684. function IsSetCompatible(Value: TResEvalValue; ValueExpr: TPasExpr;
  685. RangeValue: TResEvalValue; EmitHints: boolean): boolean;
  686. function IsConst(Expr: TPasExpr): boolean;
  687. function IsSimpleExpr(Expr: TPasExpr): boolean; // true = no need to store result
  688. procedure EmitRangeCheckConst(id: TMaxPrecInt; const aValue, MinVal, MaxVal: String;
  689. PosEl: TPasElement; MsgType: TMessageType = mtWarning); virtual;
  690. procedure EmitRangeCheckConst(id: TMaxPrecInt; const aValue: String;
  691. MinVal, MaxVal: TMaxPrecInt; PosEl: TPasElement; MsgType: TMessageType = mtWarning);
  692. function ChrValue(Value: TResEvalValue; ErrorEl: TPasElement): TResEvalValue; virtual;
  693. function OrdValue(Value: TResEvalValue; ErrorEl: TPasElement): TResEvalValue; virtual;
  694. function StringToOrd(Value: TResEvalValue; PosEl: TPasElement): longword; virtual;
  695. procedure PredValue(Value: TResEvalValue; ErrorEl: TPasElement); virtual;
  696. procedure SuccValue(Value: TResEvalValue; ErrorEl: TPasElement); virtual;
  697. function EvalStrFunc(Params: TParamsExpr; Flags: TResEvalFlags): TResEvalValue; virtual;
  698. function EvalStringAddExpr(Expr, LeftExpr, RightExpr: TPasExpr;
  699. LeftValue, RightValue: TResEvalValue): TResEvalValue; virtual;
  700. function LoHiValue(Value: TResEvalValue; ShiftSize: Integer; Mask: LongWord;
  701. ErrorEl: TPasElement): TResEvalValue; virtual;
  702. function EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
  703. Flags: TResEvalFlags): TResEvalEnum; virtual;
  704. {$ifdef FPC_HAS_CPSTRING}
  705. function CheckValidUTF8(const s: RawByteString; ErrorEl: TPasElement): boolean;
  706. function GetCodePage(const s: RawByteString): TSystemCodePage;
  707. function GetRawByteString(const s: UnicodeString; CodePage: TSystemCodePage; ErrorEl: TPasElement): RawByteString;
  708. function GetUTF8Str(const s: RawByteString; ErrorEl: TPasElement): String;
  709. function GetUnicodeStr(const s: RawByteString; ErrorEl: TPasElement): UnicodeString;
  710. function GetWideChar(const s: RawByteString; out w: WideChar): boolean;
  711. {$endif}
  712. property OnLog: TPasResEvalLogHandler read FOnLog write FOnLog;
  713. property OnEvalIdentifier: TPasResEvalIdentHandler read FOnEvalIdentifier write FOnEvalIdentifier;
  714. property OnEvalParams: TPasResEvalParamsHandler read FOnEvalParams write FOnEvalParams;
  715. property OnRangeCheckEl: TPasResEvalRangeCheckElHandler read FOnRangeCheckEl write FOnRangeCheckEl;
  716. property AllowedInts: TResEvalTypedInts read FAllowedInts write FAllowedInts;
  717. {$ifdef FPC_HAS_CPSTRING}
  718. property DefaultStringCodePage: TSystemCodePage read FDefaultEncoding write FDefaultEncoding;
  719. {$endif}
  720. end;
  721. TResExprEvaluatorClass = class of TResExprEvaluator;
  722. procedure ReleaseEvalValue(var Value: TResEvalValue);
  723. function NumberIsFloat(const Value: string): boolean;
  724. {$ifdef FPC_HAS_CPSTRING}
  725. function RawStrToCaption(const r: RawByteString; MaxLength: integer): string;
  726. {$endif}
  727. function UnicodeStrToCaption(const u: UnicodeString; MaxLength: integer): Unicodestring;
  728. function CodePointToString(CodePoint: longword): String;
  729. function CodePointToUnicodeString(u: longword): UnicodeString;
  730. function GetObjName(o: TObject): string;
  731. function GetObjPath(o: TObject): string;
  732. function GetTypeParamCommas(Cnt: integer): string;
  733. function dbgs(const Flags: TResEvalFlags): string; overload;
  734. function dbgs(v: TResEvalValue): string; overload;
  735. implementation
  736. procedure ReleaseEvalValue(var Value: TResEvalValue);
  737. begin
  738. if Value=nil then exit;
  739. if Value.Element<>nil then exit;
  740. Value.{$ifdef pas2js}Destroy{$else}Free{$endif};
  741. Value:=nil;
  742. end;
  743. function NumberIsFloat(const Value: string): boolean;
  744. var
  745. i: Integer;
  746. begin
  747. if Value='' then exit(false);
  748. if Value[1] in ['$','%','&'] then exit(false);
  749. for i:=2 to length(Value) do
  750. if Value[i] in ['.','E','e'] then exit(true);
  751. Result:=false;
  752. end;
  753. {$ifdef FPC_HAS_CPSTRING}
  754. function RawStrToCaption(const r: RawByteString; MaxLength: integer): string;
  755. var
  756. s: RawByteString;
  757. p: PAnsiChar;
  758. InLit: boolean;
  759. Len: integer;
  760. procedure AddHash(o: integer);
  761. var
  762. h: String;
  763. begin
  764. if (Result<>'') and InLit then
  765. begin
  766. Result:=Result+'''';
  767. inc(Len);
  768. InLit:=false;
  769. end;
  770. h:='#'+IntToStr(o);
  771. inc(Len,length(h));
  772. if Len<=MaxLength then
  773. Result:=Result+h;
  774. end;
  775. procedure AddLit(const Lit: string; CaptionLen: integer);
  776. begin
  777. if not InLit then
  778. begin
  779. Result:=Result+'''';
  780. inc(Len);
  781. InLit:=true;
  782. end;
  783. Result:=Result+Lit;
  784. inc(Len,CaptionLen);
  785. end;
  786. var
  787. l: SizeInt;
  788. CP: TSystemCodePage;
  789. EndP: PAnsiChar;
  790. begin
  791. Result:='';
  792. s:=r;
  793. CP:=StringCodePage(s);
  794. if (CP<>CP_ACP) and (CP<>CP_UTF8) then
  795. SetCodePage(s, CP_ACP, true);
  796. p:=PAnsiChar(s);
  797. EndP:=p+length(s);
  798. Len:=0;
  799. InLit:=false;
  800. while Len<MaxLength do
  801. case p^ of
  802. #0:
  803. begin
  804. if p-PAnsiChar(s)=length(s) then
  805. break;
  806. AddHash(0);
  807. inc(p);
  808. end;
  809. '''':
  810. begin
  811. AddLit('''''',2);
  812. inc(p);
  813. end;
  814. #1..#31,#127..#192:
  815. begin
  816. AddHash(ord(p^));
  817. inc(p);
  818. end
  819. else
  820. begin
  821. l:=Utf8CodePointLen(p,EndP-p,true);
  822. if l<=0 then
  823. begin
  824. // invalid
  825. AddHash(ord(p^));
  826. inc(p);
  827. end
  828. else
  829. begin
  830. AddLit(copy(s,p-PAnsiChar(s)+1,l),1);
  831. inc(p,l);
  832. end;
  833. end;
  834. end;
  835. if InLit then
  836. Result:=Result+'''';
  837. end;
  838. {$endif}
  839. function UnicodeStrToCaption(const u: UnicodeString; MaxLength: integer
  840. ): Unicodestring;
  841. var
  842. InLit: boolean;
  843. Len: integer;
  844. procedure AddHash(o: integer);
  845. var
  846. h: UnicodeString;
  847. begin
  848. if (Result<>'') and InLit then
  849. begin
  850. Result:=Result+'''';
  851. inc(Len);
  852. InLit:=false;
  853. end;
  854. h:='#'+UnicodeString(IntToStr(o));
  855. inc(Len,length(h));
  856. if Len<=MaxLength then
  857. Result:=Result+h;
  858. end;
  859. procedure AddLit(const Lit: Unicodestring; CaptionLen: integer);
  860. begin
  861. if not InLit then
  862. begin
  863. Result:=Result+'''';
  864. inc(Len);
  865. InLit:=true;
  866. end;
  867. Result:=Result+Lit;
  868. inc(Len,CaptionLen);
  869. end;
  870. var
  871. p: integer;
  872. begin
  873. Result:='';
  874. p:=1;
  875. Len:=0;
  876. InLit:=false;
  877. while (Len<MaxLength) and (p<=length(u)) do
  878. case u[p] of
  879. '''':
  880. begin
  881. AddLit('''''',2);
  882. inc(p);
  883. end;
  884. #0..#31,#127..#255,#$D800..#$ffff:
  885. begin
  886. AddHash(ord(u[p]));
  887. inc(p);
  888. end
  889. else
  890. begin
  891. AddLit(u[p],1);
  892. inc(p);
  893. end;
  894. end;
  895. if InLit then
  896. Result:=Result+'''';
  897. end;
  898. function CodePointToString(CodePoint: longword): String;
  899. begin
  900. case CodePoint of
  901. 0..$7f:
  902. begin
  903. Result:=char(byte(CodePoint));
  904. end;
  905. $80..$7ff:
  906. begin
  907. Result:=char(byte($c0 or (CodePoint shr 6)))
  908. +char(byte($80 or (CodePoint and $3f)));
  909. end;
  910. $800..$ffff:
  911. begin
  912. Result:=char(byte($e0 or (CodePoint shr 12)))
  913. +char(byte((CodePoint shr 6) and $3f) or $80)
  914. +char(byte(CodePoint and $3f) or $80);
  915. end;
  916. $10000..$10ffff:
  917. begin
  918. Result:=char(byte($f0 or (CodePoint shr 18)))
  919. +char(byte((CodePoint shr 12) and $3f) or $80)
  920. +char(byte((CodePoint shr 6) and $3f) or $80)
  921. +char(byte(CodePoint and $3f) or $80);
  922. end;
  923. else
  924. Result:='';
  925. end;
  926. end;
  927. function CodePointToUnicodeString(u: longword): UnicodeString;
  928. begin
  929. if u < $10000 then
  930. // Note: codepoints $D800 - $DFFF are reserved
  931. Result:=WideChar(u)
  932. else
  933. Result:=WideChar($D800+((u - $10000) shr 10))+WideChar($DC00+((u - $10000) and $3ff));
  934. end;
  935. function GetObjName(o: TObject): string;
  936. var
  937. GenType: TPasGenericType;
  938. begin
  939. if o=nil then
  940. Result:='nil'
  941. else if o is TPasElement then
  942. begin
  943. Result:=TPasElement(o).Name;
  944. if o is TPasGenericType then
  945. begin
  946. GenType:=TPasGenericType(o);
  947. if (GenType.GenericTemplateTypes<>nil)
  948. and (GenType.GenericTemplateTypes.Count>0) then
  949. Result:=Result+GetTypeParamCommas(GenType.GenericTemplateTypes.Count);
  950. end;
  951. Result:=Result+':'+o.ClassName;
  952. end
  953. else
  954. Result:=o.ClassName;
  955. end;
  956. function GetObjPath(o: TObject): string;
  957. var
  958. El: TPasElement;
  959. GenType: TPasGenericType;
  960. begin
  961. if o is TPasElement then
  962. begin
  963. El:=TPasElement(o);
  964. Result:=':'+El.ClassName;
  965. while El<>nil do
  966. begin
  967. if El<>o then
  968. Result:='.'+Result;
  969. if El is TPasGenericType then
  970. begin
  971. GenType:=TPasGenericType(El);
  972. if (GenType.GenericTemplateTypes<>nil)
  973. and (GenType.GenericTemplateTypes.Count>0) then
  974. Result:=GetTypeParamCommas(GenType.GenericTemplateTypes.Count)+Result;
  975. end;
  976. if El.Name<>'' then
  977. begin
  978. if IsValidIdent(El.Name) then
  979. Result:=El.Name+Result
  980. else
  981. Result:='"'+El.Name+'"'+Result;
  982. end
  983. else
  984. Result:='['+El.ClassName+']'+Result;
  985. El:=El.Parent;
  986. end;
  987. end
  988. else
  989. Result:=GetObjName(o);
  990. end;
  991. function GetTypeParamCommas(Cnt: integer): string;
  992. begin
  993. if Cnt<=0 then
  994. Result:=''
  995. else
  996. Result:='<'+StringOfChar(',',Cnt-1)+'>';
  997. end;
  998. function dbgs(const Flags: TResEvalFlags): string;
  999. var
  1000. s: string;
  1001. f: TResEvalFlag;
  1002. begin
  1003. Result:='';
  1004. for f in Flags do
  1005. if f in Flags then
  1006. begin
  1007. if Result<>'' then Result:=Result+',';
  1008. str(f,s);
  1009. Result:=Result+s;
  1010. end;
  1011. Result:='['+Result+']';
  1012. end;
  1013. function dbgs(v: TResEvalValue): string;
  1014. begin
  1015. if v=nil then
  1016. Result:='nil'
  1017. else
  1018. Result:=v.AsDebugString;
  1019. end;
  1020. { TResEvalExternal }
  1021. constructor TResEvalExternal.Create;
  1022. begin
  1023. inherited Create;
  1024. Kind:=revkExternal;
  1025. end;
  1026. function TResEvalExternal.Clone: TResEvalValue;
  1027. begin
  1028. Result:=inherited Clone;
  1029. end;
  1030. function TResEvalExternal.AsString: string;
  1031. begin
  1032. Result:=inherited AsString;
  1033. end;
  1034. { TResEvalCurrency }
  1035. constructor TResEvalCurrency.Create;
  1036. begin
  1037. inherited Create;
  1038. Kind:=revkCurrency;
  1039. end;
  1040. constructor TResEvalCurrency.CreateValue(const aValue: TMaxPrecCurrency);
  1041. begin
  1042. Create;
  1043. Value:=aValue;
  1044. end;
  1045. function TResEvalCurrency.Clone: TResEvalValue;
  1046. begin
  1047. Result:=inherited Clone;
  1048. TResEvalCurrency(Result).Value:=Value;
  1049. end;
  1050. function TResEvalCurrency.AsString: string;
  1051. begin
  1052. str(Value,Result);
  1053. end;
  1054. function TResEvalCurrency.IsInt(out Int: TMaxPrecInt): boolean;
  1055. var
  1056. i: TMaxPrecInt;
  1057. begin
  1058. i:=AsInt;
  1059. Result:=(i mod 10000)=0;
  1060. Int:=i div 10000;
  1061. end;
  1062. function TResEvalCurrency.AsInt: TMaxPrecInt;
  1063. begin
  1064. {$ifdef pas2js}
  1065. Result:=NativeInt(Value); // pas2js stores currency as a double with factor 10.000
  1066. {$else}
  1067. Result:=PInt64(@Value)^; // fpc stores currency as an int64 with factor 10.000
  1068. {$endif};
  1069. end;
  1070. { TResEvalBool }
  1071. constructor TResEvalBool.Create;
  1072. begin
  1073. inherited Create;
  1074. Kind:=revkBool;
  1075. end;
  1076. constructor TResEvalBool.CreateValue(const aValue: boolean);
  1077. begin
  1078. Create;
  1079. B:=aValue;
  1080. end;
  1081. function TResEvalBool.Clone: TResEvalValue;
  1082. begin
  1083. Result:=inherited Clone;
  1084. TResEvalBool(Result).B:=B;
  1085. end;
  1086. function TResEvalBool.AsString: string;
  1087. begin
  1088. if B then
  1089. Result:='true'
  1090. else
  1091. Result:='false';
  1092. end;
  1093. { TResEvalRangeUInt }
  1094. constructor TResEvalRangeUInt.Create;
  1095. begin
  1096. inherited Create;
  1097. Kind:=revkRangeInt;
  1098. end;
  1099. constructor TResEvalRangeUInt.CreateValue(const aRangeStart,
  1100. aRangeEnd: TMaxPrecUInt);
  1101. begin
  1102. Create;
  1103. RangeStart:=aRangeStart;
  1104. RangeEnd:=aRangeEnd;
  1105. end;
  1106. function TResEvalRangeUInt.Clone: TResEvalValue;
  1107. begin
  1108. Result:=inherited Clone;
  1109. TResEvalRangeUInt(Result).RangeStart:=RangeStart;
  1110. TResEvalRangeUInt(Result).RangeEnd:=RangeEnd;
  1111. end;
  1112. function TResEvalRangeUInt.AsString: string;
  1113. begin
  1114. Result:=IntToStr(RangeStart)+'..'+IntToStr(RangeEnd);
  1115. end;
  1116. { TResExprEvaluator }
  1117. procedure TResExprEvaluator.LogMsg(const id: TMaxPrecInt; MsgType: TMessageType;
  1118. MsgNumber: integer; const Fmt: String;
  1119. Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif};
  1120. PosEl: TPasElement);
  1121. begin
  1122. OnLog(Self,id,MsgType,MsgNumber,Fmt,Args,PosEl);
  1123. end;
  1124. procedure TResExprEvaluator.RaiseMsg(const Id: TMaxPrecInt; MsgNumber: integer;
  1125. const Fmt: String; Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif};
  1126. ErrorPosEl: TPasElement);
  1127. begin
  1128. LogMsg(id,mtError,MsgNumber,Fmt,Args,ErrorPosEl);
  1129. raise Exception.Create('['+IntToStr(id)+'] ('+IntToStr(MsgNumber)+') '+SafeFormat(Fmt,Args));
  1130. end;
  1131. procedure TResExprEvaluator.RaiseNotYetImplemented(id: TMaxPrecInt; El: TPasElement;
  1132. Msg: string);
  1133. var
  1134. s: String;
  1135. begin
  1136. s:=sNotYetImplemented+' ['+IntToStr(id)+']';
  1137. if Msg<>'' then
  1138. s:=s+' '+Msg;
  1139. {$IFDEF VerbosePasResolver}
  1140. writeln('TResExprEvaluator.RaiseNotYetImplemented s="',s,'" El=',GetObjName(El));
  1141. {$ENDIF}
  1142. RaiseMsg(id,nNotYetImplemented,s,[GetObjName(El)],El);
  1143. end;
  1144. procedure TResExprEvaluator.RaiseInternalError(id: TMaxPrecInt; const Msg: string);
  1145. begin
  1146. raise Exception.Create('Internal error: ['+IntToStr(id)+'] '+Msg);
  1147. end;
  1148. procedure TResExprEvaluator.RaiseConstantExprExp(id: TMaxPrecInt; ErrorEl: TPasElement
  1149. );
  1150. begin
  1151. RaiseMsg(id,nConstantExpressionExpected,sConstantExpressionExpected,[],ErrorEl);
  1152. end;
  1153. procedure TResExprEvaluator.RaiseRangeCheck(id: TMaxPrecInt; ErrorEl: TPasElement);
  1154. begin
  1155. RaiseMsg(id,nRangeCheckError,sRangeCheckError,[],ErrorEl);
  1156. end;
  1157. procedure TResExprEvaluator.RaiseOverflowArithmetic(id: TMaxPrecInt;
  1158. ErrorEl: TPasElement);
  1159. begin
  1160. RaiseMsg(id,nOverflowInArithmeticOperation,sOverflowInArithmeticOperation,[],ErrorEl);
  1161. end;
  1162. procedure TResExprEvaluator.RaiseDivByZero(id: TMaxPrecInt; ErrorEl: TPasElement);
  1163. begin
  1164. RaiseMsg(id,nDivByZero,sDivByZero,[],ErrorEl);
  1165. end;
  1166. function TResExprEvaluator.EvalUnaryExpr(Expr: TUnaryExpr; Flags: TResEvalFlags
  1167. ): TResEvalValue;
  1168. var
  1169. Int: TMaxPrecInt;
  1170. UInt: TMaxPrecUInt;
  1171. begin
  1172. Result:=Eval(Expr.Operand,Flags);
  1173. if Result=nil then exit;
  1174. {$IFDEF VerbosePasResEval}
  1175. writeln('TResExprEvaluator.EvalUnaryExpr ',OpcodeStrings[Expr.OpCode],' Value=',Result.AsDebugString);
  1176. {$ENDIF}
  1177. case Expr.OpCode of
  1178. eopAdd: ;
  1179. eopSubtract:
  1180. case Result.Kind of
  1181. revkInt:
  1182. begin
  1183. Int:=TResEvalInt(Result).Int;
  1184. if Int=0 then exit;
  1185. if Result.Element<>nil then
  1186. Result:=Result.Clone;
  1187. if (TResEvalInt(Result).Typed in reitAllSigned) then
  1188. begin
  1189. if Int=reitLow[TResEvalInt(Result).Typed] then
  1190. begin
  1191. // need higher precision
  1192. if TResEvalInt(Result).Typed<>reitNone then
  1193. // unsigned -> switch to untyped
  1194. TResEvalInt(Result).Typed:=reitNone
  1195. else
  1196. begin
  1197. // switch to float
  1198. ReleaseEvalValue(Result);
  1199. Result:=TResEvalFloat.CreateValue(-TMaxPrecFloat(low(TMaxPrecInt)));
  1200. exit;
  1201. end;
  1202. end;
  1203. end
  1204. else
  1205. begin
  1206. // unsigned -> switch to untyped
  1207. TResEvalInt(Result).Typed:=reitNone;
  1208. end ;
  1209. // negate
  1210. TResEvalInt(Result).Int:=-Int;
  1211. end;
  1212. revkUInt:
  1213. begin
  1214. UInt:=TResEvalUInt(Result).UInt;
  1215. if UInt=0 then exit;
  1216. if UInt<=High(TMaxPrecInt) then
  1217. begin
  1218. ReleaseEvalValue(Result);
  1219. Result:=TResEvalInt.CreateValue(-TMaxPrecInt(UInt));
  1220. end
  1221. else
  1222. begin
  1223. // switch to float
  1224. ReleaseEvalValue(Result);
  1225. Result:=TResEvalFloat.CreateValue(-TMaxPrecFloat(UInt));
  1226. end;
  1227. end;
  1228. revkFloat:
  1229. begin
  1230. if TResEvalFloat(Result).FloatValue=0 then exit;
  1231. if Result.Element<>nil then
  1232. Result:=Result.Clone;
  1233. TResEvalFloat(Result).FloatValue:=-TResEvalFloat(Result).FloatValue;
  1234. end;
  1235. revkCurrency:
  1236. begin
  1237. if TResEvalCurrency(Result).Value=0 then exit;
  1238. if Result.Element<>nil then
  1239. Result:=Result.Clone;
  1240. TResEvalCurrency(Result).Value:=-TResEvalCurrency(Result).Value;
  1241. end;
  1242. revkExternal:
  1243. exit;
  1244. else
  1245. begin
  1246. if Result.Element=nil then
  1247. Result.Free;
  1248. RaiseNotYetImplemented(20170518230738,Expr);
  1249. end;
  1250. end;
  1251. eopNot:
  1252. case Result.Kind of
  1253. revkBool:
  1254. begin
  1255. if Result.Element<>nil then
  1256. Result:=Result.Clone;
  1257. TResEvalBool(Result).B:=not TResEvalBool(Result).B;
  1258. end;
  1259. revkInt:
  1260. begin
  1261. if Result.Element<>nil then
  1262. Result:=Result.Clone;
  1263. case TResEvalInt(Result).Typed of
  1264. reitByte: TResEvalInt(Result).Int:=not byte(TResEvalInt(Result).Int);
  1265. reitShortInt: TResEvalInt(Result).Int:=not shortint(TResEvalInt(Result).Int);
  1266. reitWord: TResEvalInt(Result).Int:=not word(TResEvalInt(Result).Int);
  1267. reitSmallInt: TResEvalInt(Result).Int:=not smallint(TResEvalInt(Result).Int);
  1268. reitUIntSingle: TResEvalInt(Result).Int:=(not TResEvalInt(Result).Int) and $3fffff;
  1269. reitIntSingle: TResEvalInt(Result).Int:=(not TResEvalInt(Result).Int) and $7fffff;
  1270. reitLongWord: TResEvalInt(Result).Int:=not longword(TResEvalInt(Result).Int);
  1271. reitLongInt: TResEvalInt(Result).Int:=not longint(TResEvalInt(Result).Int);
  1272. reitUIntDouble: TResEvalInt(Result).Int:=(not TResEvalInt(Result).Int) and $fffffffffffff;
  1273. reitIntDouble: {$ifdef fpc}TResEvalInt(Result).Int:=(not TResEvalInt(Result).Int) and $1fffffffffffff{$endif};
  1274. else TResEvalInt(Result).Int:=not TResEvalInt(Result).Int;
  1275. end;
  1276. end;
  1277. revkUInt:
  1278. begin
  1279. if Result.Element<>nil then
  1280. Result:=Result.Clone;
  1281. TResEvalUInt(Result).UInt:=not TResEvalUInt(Result).UInt;
  1282. end;
  1283. revkExternal:
  1284. exit;
  1285. else
  1286. begin
  1287. if Result.Element=nil then
  1288. Result.Free;
  1289. RaiseNotYetImplemented(20170518232804,Expr);
  1290. end;
  1291. end;
  1292. eopAddress:
  1293. begin
  1294. if Result.Element=nil then
  1295. Result.Free;
  1296. // @ operator requires a compiler (not just a resolver) -> return nil
  1297. Result:=TResEvalValue.CreateKind(revkNil);
  1298. end
  1299. else
  1300. RaiseNotYetImplemented(20170518232823,Expr,'operator='+OpcodeStrings[Expr.OpCode]);
  1301. end;
  1302. end;
  1303. function TResExprEvaluator.EvalBinaryExpr(Expr: TBinaryExpr;
  1304. Flags: TResEvalFlags): TResEvalValue;
  1305. var
  1306. LeftValue, RightValue: TResEvalValue;
  1307. begin
  1308. Result:=nil;
  1309. if (Expr.Kind=pekBinary) and (Expr.OpCode=eopSubIdent) then
  1310. begin
  1311. Result:=Eval(Expr.right,Flags);
  1312. exit;
  1313. end;
  1314. LeftValue:=nil;
  1315. RightValue:=nil;
  1316. try
  1317. LeftValue:=Eval(Expr.left,Flags);
  1318. if LeftValue=nil then exit;
  1319. RightValue:=Eval(Expr.right,Flags);
  1320. if RightValue=nil then exit;
  1321. if LeftValue.Kind=revkExternal then
  1322. begin
  1323. if [refConst,refConstExt]*Flags=[refConst] then
  1324. RaiseConstantExprExp(20181024134508,Expr.left);
  1325. Result:=LeftValue;
  1326. LeftValue:=nil;
  1327. exit;
  1328. end;
  1329. if RightValue.Kind=revkExternal then
  1330. begin
  1331. if [refConst,refConstExt]*Flags=[refConst] then
  1332. RaiseConstantExprExp(20181024134545,Expr.right);
  1333. Result:=RightValue;
  1334. RightValue:=nil;
  1335. exit;
  1336. end;
  1337. case Expr.Kind of
  1338. pekRange:
  1339. // leftvalue..rightvalue
  1340. Result:=EvalBinaryRangeExpr(Expr,LeftValue,RightValue);
  1341. pekBinary:
  1342. case Expr.OpCode of
  1343. eopAdd:
  1344. Result:=EvalBinaryAddExpr(Expr,LeftValue,RightValue);
  1345. eopSubtract:
  1346. Result:=EvalBinarySubExpr(Expr,LeftValue,RightValue);
  1347. eopMultiply:
  1348. Result:=EvalBinaryMulExpr(Expr,LeftValue,RightValue);
  1349. eopDivide:
  1350. Result:=EvalBinaryDivideExpr(Expr,LeftValue,RightValue);
  1351. eopDiv:
  1352. Result:=EvalBinaryDivExpr(Expr,LeftValue,RightValue);
  1353. eopMod:
  1354. Result:=EvalBinaryModExpr(Expr,LeftValue,RightValue);
  1355. eopPower:
  1356. Result:=EvalBinaryPowerExpr(Expr,LeftValue,RightValue);
  1357. eopShl,eopShr:
  1358. Result:=EvalBinaryShiftExpr(Expr,LeftValue,RightValue);
  1359. eopAnd,eopOr,eopXor:
  1360. Result:=EvalBinaryBoolOpExpr(Expr,LeftValue,RightValue);
  1361. eopEqual,eopNotEqual:
  1362. Result:=EvalBinaryNEqualExpr(Expr,LeftValue,RightValue);
  1363. eopLessThan,eopGreaterThan, eopLessthanEqual,eopGreaterThanEqual:
  1364. Result:=EvalBinaryLessGreaterExpr(Expr,LeftValue,RightValue);
  1365. eopIn:
  1366. Result:=EvalBinaryInExpr(Expr,LeftValue,RightValue);
  1367. eopSymmetricaldifference:
  1368. Result:=EvalBinarySymmetricaldifferenceExpr(Expr,LeftValue,RightValue);
  1369. else
  1370. {$IFDEF VerbosePasResolver}
  1371. writeln('TResExprEvaluator.EvalBinaryExpr Kind=',Expr.Kind,' Opcode=',OpcodeStrings[Expr.OpCode],' Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1372. {$ENDIF}
  1373. RaiseNotYetImplemented(20170530100823,Expr);
  1374. end;
  1375. else
  1376. {$IFDEF VerbosePasResolver}
  1377. writeln('TResExprEvaluator.EvalBinaryExpr Kind=',Expr.Kind,' Opcode=',OpcodeStrings[Expr.OpCode]);
  1378. {$ENDIF}
  1379. RaiseNotYetImplemented(20170530100827,Expr);
  1380. end;
  1381. {$IFDEF VerbosePasResEval}
  1382. {AllowWriteln}
  1383. if Result<>nil then
  1384. writeln('TResExprEvaluator.EvalBinaryExpr Left=',LeftValue.AsDebugString,' Opcode=',OpcodeStrings[Expr.OpCode],' Right=',RightValue.AsDebugString,' Result=',Result.AsDebugString)
  1385. else
  1386. writeln('TResExprEvaluator.EvalBinaryExpr Left=',LeftValue.AsDebugString,' Opcode=',OpcodeStrings[Expr.OpCode],' Right=',RightValue.AsDebugString,' Result not set');
  1387. {AllowWriteln-}
  1388. {$ENDIF}
  1389. finally
  1390. ReleaseEvalValue(LeftValue);
  1391. ReleaseEvalValue(RightValue);
  1392. end;
  1393. end;
  1394. function TResExprEvaluator.EvalBinaryRangeExpr(Expr: TBinaryExpr; LeftValue,
  1395. RightValue: TResEvalValue): TResEvalValue;
  1396. // LeftValue..RightValue
  1397. var
  1398. LeftInt, RightInt: TMaxPrecInt;
  1399. begin
  1400. case LeftValue.Kind of
  1401. revkBool:
  1402. if RightValue.Kind<>revkBool then
  1403. RaiseRangeCheck(20170714133017,Expr.Right)
  1404. else
  1405. begin
  1406. LeftInt:=ord(TResEvalBool(LeftValue).B);
  1407. RightInt:=ord(TResEvalBool(RightValue).B);
  1408. if LeftInt>RightInt then
  1409. RaiseMsg(20170714133540,nHighRangeLimitLTLowRangeLimit,
  1410. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1411. Result:=TResEvalRangeInt.CreateValue(revskBool,nil,LeftInt,RightInt);
  1412. exit;
  1413. end;
  1414. revkInt:
  1415. if RightValue.Kind=revkInt then
  1416. begin
  1417. LeftInt:=TResEvalInt(LeftValue).Int;
  1418. RightInt:=TResEvalInt(RightValue).Int;
  1419. if LeftInt>RightInt then
  1420. RaiseMsg(20170518222939,nHighRangeLimitLTLowRangeLimit,
  1421. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1422. Result:=TResEvalRangeInt.CreateValue(revskInt,nil,LeftInt,RightInt);
  1423. exit;
  1424. end
  1425. else if RightValue.Kind=revkUInt then
  1426. begin
  1427. // Note: when FPC compares int64 with qword it converts the qword to an int64
  1428. if TResEvalUInt(RightValue).UInt<=HighIntAsUInt then
  1429. begin
  1430. if TResEvalInt(LeftValue).Int>TResEvalUInt(RightValue).UInt then
  1431. RaiseMsg(20170519000235,nHighRangeLimitLTLowRangeLimit,
  1432. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1433. Result:=TResEvalRangeInt.CreateValue(revskInt,nil,
  1434. TResEvalInt(LeftValue).Int,TMaxPrecInt(TResEvalUInt(RightValue).UInt));
  1435. exit;
  1436. end
  1437. else if TResEvalInt(LeftValue).Int<0 then
  1438. RaiseRangeCheck(20170522151629,Expr.Right)
  1439. else if TMaxPrecUInt(TResEvalInt(LeftValue).Int)>TResEvalUInt(RightValue).UInt then
  1440. RaiseMsg(20170522151708,nHighRangeLimitLTLowRangeLimit,
  1441. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1442. Result:=TResEvalRangeUInt.CreateValue(TMaxPrecUInt(TResEvalInt(LeftValue).Int),
  1443. TResEvalUInt(RightValue).UInt);
  1444. exit;
  1445. end
  1446. else
  1447. RaiseRangeCheck(20170518222812,Expr.Right);
  1448. revkUInt:
  1449. if RightValue.Kind=revkInt then
  1450. begin
  1451. // Note: when FPC compares int64 with qword it converts the qword to an int64
  1452. if TResEvalUInt(LeftValue).UInt>HighIntAsUInt then
  1453. begin
  1454. if TResEvalInt(RightValue).Int<0 then
  1455. RaiseRangeCheck(20170522152608,Expr.Right)
  1456. else if TResEvalUInt(LeftValue).UInt>TMaxPrecUInt(TResEvalInt(RightValue).Int) then
  1457. RaiseMsg(20170522152648,nHighRangeLimitLTLowRangeLimit,
  1458. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1459. Result:=TResEvalRangeUInt.CreateValue(TResEvalUInt(LeftValue).UInt,
  1460. TMaxPrecUInt(TResEvalInt(RightValue).Int));
  1461. exit;
  1462. end
  1463. else if TResEvalUInt(LeftValue).UInt>TResEvalInt(RightValue).Int then
  1464. RaiseMsg(20170522152804,nHighRangeLimitLTLowRangeLimit,
  1465. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1466. Result:=TResEvalRangeInt.CreateValue(revskInt,nil,
  1467. TMaxPrecInt(TResEvalUInt(LeftValue).UInt),TResEvalInt(RightValue).Int);
  1468. exit;
  1469. end
  1470. else if RightValue.Kind=revkUInt then
  1471. begin
  1472. if TResEvalUInt(LeftValue).UInt>TResEvalUInt(RightValue).UInt then
  1473. RaiseMsg(20170519000240,nHighRangeLimitLTLowRangeLimit,
  1474. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1475. Result:=TResEvalRangeUInt.CreateValue(TResEvalUInt(LeftValue).UInt,
  1476. TResEvalUInt(RightValue).UInt);
  1477. exit;
  1478. end
  1479. else
  1480. RaiseRangeCheck(20170522123106,Expr.Right);
  1481. revkEnum:
  1482. if (RightValue.Kind<>revkEnum) then
  1483. RaiseRangeCheck(20170522153003,Expr.Right)
  1484. else if (TResEvalEnum(LeftValue).ElType<>TResEvalEnum(RightValue).ElType) then
  1485. begin
  1486. {$IFDEF VerbosePasResolver}
  1487. writeln('TResExprEvaluator.EvalBinaryRangeExpr LeftValue=',dbgs(LeftValue),',',GetObjName(TResEvalEnum(LeftValue).ElType),' RightValue=',dbgs(RightValue),',',GetObjName(TResEvalEnum(RightValue).ElType));
  1488. {$ENDIF}
  1489. RaiseRangeCheck(20170522123241,Expr.Right) // mismatch enumtype
  1490. end
  1491. else if TResEvalEnum(LeftValue).Index>TResEvalEnum(RightValue).Index then
  1492. RaiseMsg(20170522123320,nHighRangeLimitLTLowRangeLimit,
  1493. sHighRangeLimitLTLowRangeLimit,[],Expr.Right)
  1494. else
  1495. begin
  1496. Result:=TResEvalRangeInt.CreateValue(revskEnum,
  1497. TResEvalEnum(LeftValue).ElType as TPasEnumType,
  1498. TResEvalEnum(LeftValue).Index,TResEvalEnum(RightValue).Index);
  1499. exit;
  1500. end;
  1501. {$ifdef FPC_HAS_CPSTRING}
  1502. revkString,
  1503. {$endif}
  1504. revkUnicodeString:
  1505. begin
  1506. LeftInt:=StringToOrd(LeftValue,Expr.left);
  1507. if RightValue.Kind in revkAllStrings then
  1508. begin
  1509. RightInt:=StringToOrd(RightValue,Expr.right);
  1510. if LeftInt>RightInt then
  1511. RaiseMsg(20170523151508,nHighRangeLimitLTLowRangeLimit,
  1512. sHighRangeLimitLTLowRangeLimit,[],Expr.Right);
  1513. Result:=TResEvalRangeInt.CreateValue(revskChar,nil,LeftInt,RightInt);
  1514. exit;
  1515. end
  1516. else
  1517. RaiseRangeCheck(20170522123106,Expr.Right);
  1518. end
  1519. else
  1520. {$IFDEF VerbosePasResolver}
  1521. writeln('TResExprEvaluator.EvalBinaryRangeExpr Left=',GetObjName(Expr.Left),' LeftValue.Kind=',LeftValue.Kind);
  1522. RaiseNotYetImplemented(20170518221103,Expr.Left);
  1523. {$ENDIF}
  1524. end;
  1525. end;
  1526. function TResExprEvaluator.EvalBinaryAddExpr(Expr: TBinaryExpr; LeftValue,
  1527. RightValue: TResEvalValue): TResEvalValue;
  1528. procedure IntAddUInt(const i: TMaxPrecInt; const u: TMaxPrecUInt);
  1529. var
  1530. Int: TMaxPrecInt;
  1531. UInt: TMaxPrecUInt;
  1532. begin
  1533. if (i>=0) then
  1534. begin
  1535. UInt:=TMaxPrecUInt(i)+u;
  1536. Result:=CreateResEvalInt(UInt);
  1537. end
  1538. else if u<=HighIntAsUInt then
  1539. begin
  1540. Int:=i + TMaxPrecInt(u);
  1541. Result:=TResEvalInt.CreateValue(Int);
  1542. end
  1543. else
  1544. RaiseRangeCheck(20170601140523,Expr);
  1545. end;
  1546. var
  1547. Int: TMaxPrecInt;
  1548. UInt: TMaxPrecUInt;
  1549. Flo: TMaxPrecFloat;
  1550. aCurrency: TMaxPrecCurrency;
  1551. LeftSet, RightSet: TResEvalSet;
  1552. i: Integer;
  1553. begin
  1554. Result:=nil;
  1555. try
  1556. {$Q+} // enable overflow and range checks
  1557. {$R+}
  1558. case LeftValue.Kind of
  1559. revkInt:
  1560. begin
  1561. Int:=TResEvalInt(LeftValue).Int;
  1562. case RightValue.Kind of
  1563. revkInt: // int + int
  1564. if (Int>0) and (TResEvalInt(RightValue).Int>0) then
  1565. begin
  1566. UInt:=TMaxPrecUInt(Int)+TMaxPrecUInt(TResEvalInt(RightValue).Int);
  1567. Result:=CreateResEvalInt(UInt);
  1568. end
  1569. else
  1570. begin
  1571. Int:=Int + TResEvalInt(RightValue).Int;
  1572. Result:=TResEvalInt.CreateValue(Int);
  1573. end;
  1574. revkUInt: // int + uint
  1575. IntAddUInt(Int,TResEvalUInt(RightValue).UInt);
  1576. revkFloat: // int + float
  1577. Result:=TResEvalFloat.CreateValue(Int + TResEvalFloat(RightValue).FloatValue);
  1578. revkCurrency: // int + currency
  1579. Result:=TResEvalCurrency.CreateValue(Int + TResEvalCurrency(RightValue).Value);
  1580. else
  1581. {$IFDEF VerbosePasResolver}
  1582. writeln('TResExprEvaluator.EvalBinaryAddExpr int+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1583. {$ENDIF}
  1584. RaiseNotYetImplemented(20170525115537,Expr);
  1585. end;
  1586. end;
  1587. revkUInt:
  1588. begin
  1589. UInt:=TResEvalUInt(LeftValue).UInt;
  1590. case RightValue.Kind of
  1591. revkInt: // uint + int
  1592. IntAddUInt(UInt,TResEvalInt(RightValue).Int);
  1593. revkUInt: // uint + uint
  1594. begin
  1595. UInt:=UInt+TResEvalUInt(RightValue).UInt;
  1596. Result:=TResEvalUInt.CreateValue(UInt);
  1597. end;
  1598. revkFloat: // uint + float
  1599. Result:=TResEvalFloat.CreateValue(UInt + TResEvalFloat(RightValue).FloatValue);
  1600. revkCurrency: // uint + currency
  1601. Result:=TResEvalCurrency.CreateValue(UInt + TResEvalCurrency(RightValue).Value);
  1602. else
  1603. {$IFDEF VerbosePasResolver}
  1604. writeln('TResExprEvaluator.EvalBinaryAddExpr uint+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1605. {$ENDIF}
  1606. RaiseNotYetImplemented(20170601141031,Expr);
  1607. end;
  1608. end;
  1609. revkFloat:
  1610. begin
  1611. Flo:=TResEvalFloat(LeftValue).FloatValue;
  1612. case RightValue.Kind of
  1613. revkInt: // float + int
  1614. Result:=TResEvalFloat.CreateValue(Flo + TResEvalInt(RightValue).Int);
  1615. revkUInt: // float + uint
  1616. Result:=TResEvalFloat.CreateValue(Flo + TResEvalUInt(RightValue).UInt);
  1617. revkFloat: // float + float
  1618. Result:=TResEvalFloat.CreateValue(Flo + TResEvalFloat(RightValue).FloatValue);
  1619. revkCurrency: // float + Currency
  1620. Result:=TResEvalCurrency.CreateValue(Flo + TResEvalCurrency(RightValue).Value);
  1621. else
  1622. {$IFDEF VerbosePasResolver}
  1623. writeln('TResExprEvaluator.EvalBinaryAddExpr float+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1624. {$ENDIF}
  1625. RaiseNotYetImplemented(20170711145637,Expr);
  1626. end;
  1627. end;
  1628. revkCurrency:
  1629. begin
  1630. aCurrency:=TResEvalCurrency(LeftValue).Value;
  1631. case RightValue.Kind of
  1632. revkInt: // currency + int
  1633. Result:=TResEvalFloat.CreateValue(aCurrency + TResEvalInt(RightValue).Int);
  1634. revkUInt: // currency + uint
  1635. Result:=TResEvalFloat.CreateValue(aCurrency + TResEvalUInt(RightValue).UInt);
  1636. revkFloat: // currency + float
  1637. Result:=TResEvalFloat.CreateValue(aCurrency + TResEvalFloat(RightValue).FloatValue);
  1638. revkCurrency: // currency + currency
  1639. Result:=TResEvalCurrency.CreateValue(aCurrency + TResEvalCurrency(RightValue).Value);
  1640. else
  1641. {$IFDEF VerbosePasResolver}
  1642. writeln('TResExprEvaluator.EvalBinaryAddExpr currency+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1643. {$ENDIF}
  1644. RaiseNotYetImplemented(20180421163819,Expr);
  1645. end;
  1646. end;
  1647. {$ifdef FPC_HAS_CPSTRING}
  1648. revkString,
  1649. {$endif}
  1650. revkUnicodeString:
  1651. Result:=EvalStringAddExpr(Expr,Expr.left,Expr.right,LeftValue,RightValue);
  1652. revkSetOfInt:
  1653. case RightValue.Kind of
  1654. revkSetOfInt:
  1655. begin
  1656. // union
  1657. LeftSet:=TResEvalSet(LeftValue);
  1658. RightSet:=TResEvalSet(RightValue);
  1659. if LeftSet.ElKind=revskNone then
  1660. Result:=RightSet.Clone
  1661. else if RightSet.ElKind=revskNone then
  1662. Result:=LeftSet.Clone
  1663. else
  1664. begin
  1665. Result:=RightSet.Clone;
  1666. // add elements of left
  1667. for i:=0 to length(LeftSet.Ranges)-1 do
  1668. begin
  1669. Int:=LeftSet.Ranges[i].RangeStart;
  1670. while Int<=LeftSet.Ranges[i].RangeEnd do
  1671. begin
  1672. TResEvalSet(Result).Add(Int,Int);
  1673. inc(Int);
  1674. end;
  1675. end;
  1676. end;
  1677. end;
  1678. else
  1679. {$IFDEF VerbosePasResolver}
  1680. writeln('TResExprEvaluator.EvalBinaryMulExpr add set+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1681. {$ENDIF}
  1682. RaiseNotYetImplemented(20170714114055,Expr);
  1683. end
  1684. else
  1685. {$IFDEF VerbosePasResolver}
  1686. writeln('TResExprEvaluator.EvalBinaryAddExpr ?+ Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1687. {$ENDIF}
  1688. RaiseNotYetImplemented(20170525115548,Expr);
  1689. end;
  1690. except
  1691. on EOverflow do
  1692. RaiseOverflowArithmetic(20170601140130,Expr);
  1693. on ERangeError do
  1694. RaiseRangeCheck(20170601140132,Expr);
  1695. end;
  1696. end;
  1697. function TResExprEvaluator.EvalBinarySubExpr(Expr: TBinaryExpr; LeftValue,
  1698. RightValue: TResEvalValue): TResEvalValue;
  1699. var
  1700. Int: TMaxPrecInt;
  1701. UInt: TMaxPrecUInt;
  1702. Flo: TMaxPrecFloat;
  1703. aCurrency: TMaxPrecCurrency;
  1704. LeftSet, RightSet: TResEvalSet;
  1705. i: Integer;
  1706. begin
  1707. Result:=nil;
  1708. case LeftValue.Kind of
  1709. revkInt:
  1710. begin
  1711. Int:=TResEvalInt(LeftValue).Int;
  1712. case RightValue.Kind of
  1713. revkInt:
  1714. // int - int
  1715. try
  1716. {$Q+}
  1717. Int:=Int - TResEvalInt(RightValue).Int;
  1718. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1719. Result:=TResEvalInt.CreateValue(Int);
  1720. except
  1721. on E: EOverflow do
  1722. if (Int>0) and (TResEvalInt(RightValue).Int<0) then
  1723. begin
  1724. UInt:=TMaxPrecUInt(Int)+TMaxPrecUInt(-TResEvalInt(RightValue).Int);
  1725. Result:=CreateResEvalInt(UInt);
  1726. end
  1727. else
  1728. RaiseOverflowArithmetic(20170525230247,Expr);
  1729. end;
  1730. revkUInt:
  1731. // int - uint
  1732. try
  1733. {$Q+}
  1734. Int:=Int - TResEvalUInt(RightValue).UInt;
  1735. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1736. Result:=TResEvalInt.CreateValue(Int);
  1737. except
  1738. on E: EOverflow do
  1739. RaiseOverflowArithmetic(20170711151201,Expr);
  1740. end;
  1741. revkFloat:
  1742. // int - float
  1743. try
  1744. {$Q+}
  1745. Flo:=TMaxPrecFloat(Int) - TResEvalFloat(RightValue).FloatValue;
  1746. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1747. Result:=TResEvalFloat.CreateValue(Flo);
  1748. except
  1749. on E: EOverflow do
  1750. RaiseOverflowArithmetic(20170711151313,Expr);
  1751. end;
  1752. revkCurrency:
  1753. // int - currency
  1754. try
  1755. {$Q+}
  1756. aCurrency:=TMaxPrecCurrency(Int) - TResEvalCurrency(RightValue).Value;
  1757. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1758. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1759. except
  1760. on E: EOverflow do
  1761. RaiseOverflowArithmetic(20180421164011,Expr);
  1762. end;
  1763. else
  1764. {$IFDEF VerbosePasResolver}
  1765. writeln('TResExprEvaluator.EvalBinarySubExpr sub int-? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1766. {$ENDIF}
  1767. RaiseNotYetImplemented(20170525230028,Expr);
  1768. end;
  1769. end;
  1770. revkUInt:
  1771. begin
  1772. UInt:=TResEvalUInt(LeftValue).UInt;
  1773. case RightValue.Kind of
  1774. revkInt:
  1775. // uint - int
  1776. try
  1777. {$Q+}
  1778. UInt:=UInt - TResEvalInt(RightValue).Int;
  1779. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1780. Result:=TResEvalUInt.CreateValue(UInt);
  1781. except
  1782. on E: EOverflow do
  1783. RaiseOverflowArithmetic(20170711151405,Expr);
  1784. end;
  1785. revkUInt:
  1786. // uint - uint
  1787. try
  1788. {$Q+}
  1789. UInt:=UInt - TResEvalUInt(RightValue).UInt;
  1790. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1791. Result:=TResEvalUInt.CreateValue(UInt);
  1792. except
  1793. on E: EOverflow do
  1794. RaiseOverflowArithmetic(20170711151419,Expr);
  1795. end;
  1796. revkFloat:
  1797. // uint - float
  1798. try
  1799. {$Q+}
  1800. Flo:=TMaxPrecFloat(UInt) - TResEvalFloat(RightValue).FloatValue;
  1801. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1802. Result:=TResEvalFloat.CreateValue(Flo);
  1803. except
  1804. on E: EOverflow do
  1805. RaiseOverflowArithmetic(20170711151428,Expr);
  1806. end;
  1807. revkCurrency:
  1808. // uint - currency
  1809. try
  1810. {$Q+}
  1811. aCurrency:=TMaxPrecCurrency(UInt) - TResEvalCurrency(RightValue).Value;
  1812. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1813. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1814. except
  1815. on E: EOverflow do
  1816. RaiseOverflowArithmetic(20180421164005,Expr);
  1817. end;
  1818. else
  1819. {$IFDEF VerbosePasResolver}
  1820. writeln('TResExprEvaluator.EvalBinarySubExpr sub uint-? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1821. {$ENDIF}
  1822. RaiseNotYetImplemented(20170711151435,Expr);
  1823. end;
  1824. end;
  1825. revkFloat:
  1826. begin
  1827. Flo:=TResEvalFloat(LeftValue).FloatValue;
  1828. case RightValue.Kind of
  1829. revkInt:
  1830. // float - int
  1831. try
  1832. {$Q+}
  1833. Flo:=Flo - TResEvalInt(RightValue).Int;
  1834. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1835. Result:=TResEvalFloat.CreateValue(Flo);
  1836. except
  1837. on E: EOverflow do
  1838. RaiseOverflowArithmetic(20170711151519,Expr);
  1839. end;
  1840. revkUInt:
  1841. // float - uint
  1842. try
  1843. {$Q+}
  1844. Flo:=Flo - TResEvalUInt(RightValue).UInt;
  1845. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1846. Result:=TResEvalFloat.CreateValue(Flo);
  1847. except
  1848. on E: EOverflow do
  1849. RaiseOverflowArithmetic(20170711151538,Expr);
  1850. end;
  1851. revkFloat:
  1852. // float - float
  1853. try
  1854. {$Q+}
  1855. Flo:=Flo - TResEvalFloat(RightValue).FloatValue;
  1856. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1857. Result:=TResEvalFloat.CreateValue(Flo);
  1858. except
  1859. on E: EOverflow do
  1860. RaiseOverflowArithmetic(20170711151552,Expr);
  1861. end;
  1862. revkCurrency:
  1863. // float - currency
  1864. try
  1865. {$Q+}
  1866. aCurrency:=Flo - TResEvalCurrency(RightValue).Value;
  1867. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1868. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1869. except
  1870. on E: EOverflow do
  1871. RaiseOverflowArithmetic(20180421164054,Expr);
  1872. end;
  1873. else
  1874. {$IFDEF VerbosePasResolver}
  1875. writeln('TResExprEvaluator.EvalBinarySubExpr sub float-? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1876. {$ENDIF}
  1877. RaiseNotYetImplemented(20170711151600,Expr);
  1878. end;
  1879. end;
  1880. revkCurrency:
  1881. begin
  1882. aCurrency:=TResEvalCurrency(LeftValue).Value;
  1883. case RightValue.Kind of
  1884. revkInt:
  1885. // currency - int
  1886. try
  1887. {$Q+}
  1888. aCurrency:=aCurrency - TResEvalInt(RightValue).Int;
  1889. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1890. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1891. except
  1892. on E: EOverflow do
  1893. RaiseOverflowArithmetic(20180421164200,Expr);
  1894. end;
  1895. revkUInt:
  1896. // currency - uint
  1897. try
  1898. {$Q+}
  1899. aCurrency:=aCurrency - TResEvalUInt(RightValue).UInt;
  1900. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1901. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1902. except
  1903. on E: EOverflow do
  1904. RaiseOverflowArithmetic(20180421164218,Expr);
  1905. end;
  1906. revkFloat:
  1907. // currency - float
  1908. try
  1909. {$Q+}
  1910. aCurrency:=aCurrency - TResEvalFloat(RightValue).FloatValue;
  1911. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1912. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1913. except
  1914. on E: EOverflow do
  1915. RaiseOverflowArithmetic(20180421164250,Expr);
  1916. end;
  1917. revkCurrency:
  1918. // currency - currency
  1919. try
  1920. {$Q+}
  1921. aCurrency:=aCurrency - TResEvalCurrency(RightValue).Value;
  1922. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1923. Result:=TResEvalCurrency.CreateValue(aCurrency);
  1924. except
  1925. on E: EOverflow do
  1926. RaiseOverflowArithmetic(20180421164258,Expr);
  1927. end;
  1928. else
  1929. {$IFDEF VerbosePasResolver}
  1930. writeln('TResExprEvaluator.EvalBinarySubExpr sub currency-? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1931. {$ENDIF}
  1932. RaiseNotYetImplemented(20180421164312,Expr);
  1933. end;
  1934. end;
  1935. revkSetOfInt:
  1936. case RightValue.Kind of
  1937. revkSetOfInt:
  1938. begin
  1939. // difference
  1940. LeftSet:=TResEvalSet(LeftValue);
  1941. RightSet:=TResEvalSet(RightValue);
  1942. if LeftSet.ElKind=revskNone then
  1943. Result:=TResEvalSet.CreateEmptySameKind(RightSet)
  1944. else
  1945. begin
  1946. Result:=TResEvalSet.CreateEmptySameKind(LeftSet);
  1947. // add elements, which exists only in LeftSet
  1948. for i:=0 to length(LeftSet.Ranges)-1 do
  1949. begin
  1950. Int:=LeftSet.Ranges[i].RangeStart;
  1951. while Int<=LeftSet.Ranges[i].RangeEnd do
  1952. begin
  1953. if RightSet.IndexOfRange(Int)<0 then
  1954. TResEvalSet(Result).Add(Int,Int);
  1955. inc(Int);
  1956. end;
  1957. end;
  1958. end;
  1959. end;
  1960. else
  1961. {$IFDEF VerbosePasResolver}
  1962. writeln('TResExprEvaluator.EvalBinarySubExpr sub set-? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1963. {$ENDIF}
  1964. RaiseNotYetImplemented(20170714114101,Expr);
  1965. end;
  1966. else
  1967. {$IFDEF VerbosePasResolver}
  1968. writeln('TResExprEvaluator.EvalBinarySubExpr sub ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  1969. {$ENDIF}
  1970. RaiseNotYetImplemented(20170525225946,Expr);
  1971. end;
  1972. end;
  1973. function TResExprEvaluator.EvalBinaryMulExpr(Expr: TBinaryExpr; LeftValue,
  1974. RightValue: TResEvalValue): TResEvalValue;
  1975. var
  1976. Int: TMaxPrecInt;
  1977. UInt: TMaxPrecUInt;
  1978. Flo: TMaxPrecFloat;
  1979. aCurrency: TMaxPrecCurrency;
  1980. LeftSet, RightSet: TResEvalSet;
  1981. i: Integer;
  1982. begin
  1983. Result:=nil;
  1984. case LeftValue.Kind of
  1985. revkInt:
  1986. begin
  1987. Int:=TResEvalInt(LeftValue).Int;
  1988. case RightValue.Kind of
  1989. revkInt:
  1990. // int * int
  1991. try
  1992. {$Q+}
  1993. Int:=Int * TResEvalInt(RightValue).Int;
  1994. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  1995. Result:=TResEvalInt.CreateValue(Int);
  1996. except
  1997. on E: EOverflow do
  1998. if (Int>0) and (TResEvalInt(RightValue).Int>0) then
  1999. try
  2000. // try uint*uint
  2001. {$Q+}
  2002. UInt:=TMaxPrecUInt(Int) * TMaxPrecUInt(TResEvalInt(RightValue).Int);
  2003. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2004. Result:=CreateResEvalInt(UInt);
  2005. except
  2006. on E: EOverflow do
  2007. RaiseOverflowArithmetic(20170530101616,Expr);
  2008. end
  2009. else
  2010. RaiseOverflowArithmetic(20170525230247,Expr);
  2011. end;
  2012. revkUInt:
  2013. // int * uint
  2014. try
  2015. {$Q+}
  2016. Int:=Int * TResEvalUInt(RightValue).UInt;
  2017. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2018. Result:=TResEvalInt.CreateValue(Int);
  2019. except
  2020. RaiseOverflowArithmetic(20170711164445,Expr);
  2021. end;
  2022. revkFloat:
  2023. // int * float
  2024. try
  2025. {$Q+}
  2026. Flo:=Int * TResEvalFloat(RightValue).FloatValue;
  2027. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2028. Result:=TResEvalFloat.CreateValue(Flo);
  2029. except
  2030. RaiseOverflowArithmetic(20170711164541,Expr);
  2031. end;
  2032. revkCurrency:
  2033. // int * currency
  2034. try
  2035. {$Q+}
  2036. aCurrency:=Int * TResEvalCurrency(RightValue).Value;
  2037. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2038. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2039. except
  2040. RaiseOverflowArithmetic(20180421164426,Expr);
  2041. end;
  2042. else
  2043. {$IFDEF VerbosePasResolver}
  2044. writeln('TResExprEvaluator.EvalBinaryMulExpr mul int*? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2045. {$ENDIF}
  2046. RaiseNotYetImplemented(20170525230028,Expr);
  2047. end;
  2048. end;
  2049. revkUInt:
  2050. begin
  2051. UInt:=TResEvalUInt(LeftValue).UInt;
  2052. case RightValue.Kind of
  2053. revkInt:
  2054. // uint * int
  2055. if TResEvalInt(RightValue).Int>=0 then
  2056. try
  2057. {$Q+}
  2058. UInt:=UInt * TResEvalInt(RightValue).Int;
  2059. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2060. Result:=TResEvalUInt.CreateValue(UInt);
  2061. except
  2062. on E: EOverflow do
  2063. RaiseOverflowArithmetic(20170711164714,Expr);
  2064. end
  2065. else
  2066. try
  2067. {$Q+}
  2068. Int:=UInt * TResEvalInt(RightValue).Int;
  2069. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2070. Result:=TResEvalInt.CreateValue(Int);
  2071. except
  2072. on E: EOverflow do
  2073. RaiseOverflowArithmetic(20170711164736,Expr);
  2074. end;
  2075. revkUInt:
  2076. // uint * uint
  2077. try
  2078. {$Q+}
  2079. UInt:=UInt * TResEvalUInt(RightValue).UInt;
  2080. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2081. Result:=TResEvalUInt.CreateValue(UInt);
  2082. except
  2083. RaiseOverflowArithmetic(20170711164751,Expr);
  2084. end;
  2085. revkFloat:
  2086. // uint * float
  2087. try
  2088. {$Q+}
  2089. Flo:=UInt * TResEvalFloat(RightValue).FloatValue;
  2090. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2091. Result:=TResEvalFloat.CreateValue(Flo);
  2092. except
  2093. RaiseOverflowArithmetic(20170711164800,Expr);
  2094. end;
  2095. revkCurrency:
  2096. // uint * currency
  2097. try
  2098. {$Q+}
  2099. aCurrency:=UInt * TResEvalCurrency(RightValue).Value;
  2100. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2101. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2102. except
  2103. RaiseOverflowArithmetic(20180421164500,Expr);
  2104. end;
  2105. else
  2106. {$IFDEF VerbosePasResolver}
  2107. writeln('TResExprEvaluator.EvalBinaryMulExpr mul uint*? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2108. {$ENDIF}
  2109. RaiseNotYetImplemented(20170711164810,Expr);
  2110. end;
  2111. end;
  2112. revkFloat:
  2113. begin
  2114. Flo:=TResEvalFloat(LeftValue).FloatValue;
  2115. case RightValue.Kind of
  2116. revkInt:
  2117. // float * int
  2118. try
  2119. {$Q+}
  2120. Flo:=Flo * TResEvalInt(RightValue).Int;
  2121. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2122. Result:=TResEvalFloat.CreateValue(Flo);
  2123. except
  2124. on E: EOverflow do
  2125. RaiseOverflowArithmetic(20170711164920,Expr);
  2126. end;
  2127. revkUInt:
  2128. // float * uint
  2129. try
  2130. {$Q+}
  2131. Flo:=Flo * TResEvalUInt(RightValue).UInt;
  2132. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2133. Result:=TResEvalFloat.CreateValue(Flo);
  2134. except
  2135. RaiseOverflowArithmetic(20170711164940,Expr);
  2136. end;
  2137. revkFloat:
  2138. // float * float
  2139. try
  2140. {$Q+}
  2141. Flo:=Flo * TResEvalFloat(RightValue).FloatValue;
  2142. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2143. Result:=TResEvalFloat.CreateValue(Flo);
  2144. except
  2145. RaiseOverflowArithmetic(20170711164955,Expr);
  2146. end;
  2147. revkCurrency:
  2148. // float * currency
  2149. try
  2150. {$Q+}
  2151. Flo:=Flo * TResEvalCurrency(RightValue).Value;
  2152. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2153. Result:=TResEvalFloat.CreateValue(Flo);
  2154. except
  2155. RaiseOverflowArithmetic(20180421164542,Expr);
  2156. end;
  2157. else
  2158. {$IFDEF VerbosePasResolver}
  2159. writeln('TResExprEvaluator.EvalBinaryMulExpr mul float*? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2160. {$ENDIF}
  2161. RaiseNotYetImplemented(20170711165004,Expr);
  2162. end;
  2163. end;
  2164. revkCurrency:
  2165. begin
  2166. aCurrency:=TResEvalCurrency(LeftValue).Value;
  2167. case RightValue.Kind of
  2168. revkInt:
  2169. // currency * int
  2170. try
  2171. {$Q+}
  2172. aCurrency:=aCurrency * TResEvalInt(RightValue).Int;
  2173. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2174. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2175. except
  2176. on E: EOverflow do
  2177. RaiseOverflowArithmetic(20180421164636,Expr);
  2178. end;
  2179. revkUInt:
  2180. // currency * uint
  2181. try
  2182. {$Q+}
  2183. aCurrency:=aCurrency * TResEvalUInt(RightValue).UInt;
  2184. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2185. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2186. except
  2187. RaiseOverflowArithmetic(20180421164654,Expr);
  2188. end;
  2189. revkFloat:
  2190. // currency * float
  2191. try
  2192. {$Q+}
  2193. Flo:=aCurrency * TResEvalFloat(RightValue).FloatValue;
  2194. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2195. Result:=TResEvalFloat.CreateValue(Flo);
  2196. except
  2197. RaiseOverflowArithmetic(20180421164718,Expr);
  2198. end;
  2199. revkCurrency:
  2200. // currency * currency
  2201. try
  2202. {$Q+}
  2203. aCurrency:=aCurrency * TResEvalCurrency(RightValue).Value;
  2204. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2205. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2206. except
  2207. RaiseOverflowArithmetic(20180421164806,Expr);
  2208. end;
  2209. else
  2210. {$IFDEF VerbosePasResolver}
  2211. writeln('TResExprEvaluator.EvalBinaryMulExpr mul currency*? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2212. {$ENDIF}
  2213. RaiseNotYetImplemented(20180421164817,Expr);
  2214. end;
  2215. end;
  2216. revkSetOfInt:
  2217. case RightValue.Kind of
  2218. revkSetOfInt:
  2219. begin
  2220. // intersect
  2221. LeftSet:=TResEvalSet(LeftValue);
  2222. RightSet:=TResEvalSet(RightValue);
  2223. if LeftSet.ElKind=revskNone then
  2224. Result:=TResEvalSet.CreateEmptySameKind(RightSet)
  2225. else
  2226. begin
  2227. Result:=TResEvalSet.CreateEmptySameKind(LeftSet);
  2228. // add elements, which exists in both
  2229. for i:=0 to length(LeftSet.Ranges)-1 do
  2230. begin
  2231. Int:=LeftSet.Ranges[i].RangeStart;
  2232. while Int<=LeftSet.Ranges[i].RangeEnd do
  2233. begin
  2234. if RightSet.IndexOfRange(Int)>=0 then
  2235. TResEvalSet(Result).Add(Int,Int);
  2236. inc(Int);
  2237. end;
  2238. end;
  2239. end;
  2240. end;
  2241. else
  2242. {$IFDEF VerbosePasResolver}
  2243. writeln('TResExprEvaluator.EvalBinaryMulExpr mul set*? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2244. {$ENDIF}
  2245. RaiseNotYetImplemented(20170714110420,Expr);
  2246. end
  2247. else
  2248. {$IFDEF VerbosePasResolver}
  2249. writeln('TResExprEvaluator.EvalBinaryMulExpr mul ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2250. {$ENDIF}
  2251. RaiseNotYetImplemented(20170525225946,Expr);
  2252. end;
  2253. end;
  2254. function TResExprEvaluator.EvalBinaryDivideExpr(Expr: TBinaryExpr; LeftValue,
  2255. RightValue: TResEvalValue): TResEvalValue;
  2256. var
  2257. Int: TMaxPrecInt;
  2258. UInt: TMaxPrecUInt;
  2259. Flo: TMaxPrecFloat;
  2260. aCurrency: TMaxPrecCurrency;
  2261. begin
  2262. Result:=nil;
  2263. case LeftValue.Kind of
  2264. revkInt:
  2265. begin
  2266. Int:=TResEvalInt(LeftValue).Int;
  2267. case RightValue.Kind of
  2268. revkInt:
  2269. // int / int
  2270. if TResEvalInt(RightValue).Int=0 then
  2271. RaiseDivByZero(20170711143925,Expr)
  2272. else
  2273. Result:=TResEvalFloat.CreateValue(Int / TResEvalInt(RightValue).Int);
  2274. revkUInt:
  2275. // int / uint
  2276. if TResEvalUInt(RightValue).UInt=0 then
  2277. RaiseDivByZero(20170711144013,Expr)
  2278. else
  2279. Result:=TResEvalFloat.CreateValue(Int / TResEvalUInt(RightValue).UInt);
  2280. revkFloat:
  2281. begin
  2282. // int / float
  2283. try
  2284. Flo:=Int / TResEvalFloat(RightValue).FloatValue;
  2285. except
  2286. RaiseMsg(20170711144525,nDivByZero,sDivByZero,[],Expr);
  2287. end;
  2288. Result:=TResEvalFloat.CreateValue(Flo);
  2289. end;
  2290. revkCurrency:
  2291. begin
  2292. // int / currency
  2293. try
  2294. aCurrency:=Int / TResEvalCurrency(RightValue).Value;
  2295. except
  2296. RaiseMsg(20180421164915,nDivByZero,sDivByZero,[],Expr);
  2297. end;
  2298. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2299. end;
  2300. else
  2301. {$IFDEF VerbosePasResolver}
  2302. writeln('TResExprEvaluator.EvalBinaryDivideExpr int / ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2303. {$ENDIF}
  2304. RaiseNotYetImplemented(20170711144057,Expr);
  2305. end;
  2306. end;
  2307. revkUInt:
  2308. begin
  2309. UInt:=TResEvalUInt(LeftValue).UInt;
  2310. case RightValue.Kind of
  2311. revkInt:
  2312. // uint / int
  2313. if TResEvalInt(RightValue).Int=0 then
  2314. RaiseDivByZero(20170711144103,Expr)
  2315. else
  2316. Result:=TResEvalFloat.CreateValue(UInt / TResEvalInt(RightValue).Int);
  2317. revkUInt:
  2318. // uint / uint
  2319. if TResEvalUInt(RightValue).UInt=0 then
  2320. RaiseDivByZero(20170711144203,Expr)
  2321. else
  2322. Result:=TResEvalFloat.CreateValue(UInt / TResEvalUInt(RightValue).UInt);
  2323. revkFloat:
  2324. begin
  2325. // uint / float
  2326. try
  2327. Flo:=UInt / TResEvalFloat(RightValue).FloatValue;
  2328. except
  2329. RaiseMsg(20170711144912,nDivByZero,sDivByZero,[],Expr);
  2330. end;
  2331. Result:=TResEvalFloat.CreateValue(Flo);
  2332. end;
  2333. revkCurrency:
  2334. begin
  2335. // uint / currency
  2336. try
  2337. aCurrency:=UInt / TResEvalCurrency(RightValue).Value;
  2338. except
  2339. RaiseMsg(20180421164959,nDivByZero,sDivByZero,[],Expr);
  2340. end;
  2341. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2342. end;
  2343. else
  2344. {$IFDEF VerbosePasResolver}
  2345. writeln('TResExprEvaluator.EvalBinaryDivideExpr uint / ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2346. {$ENDIF}
  2347. RaiseNotYetImplemented(20170711144239,Expr);
  2348. end;
  2349. end;
  2350. revkFloat:
  2351. begin
  2352. Flo:=TResEvalFloat(LeftValue).FloatValue;
  2353. case RightValue.Kind of
  2354. revkInt:
  2355. // float / int
  2356. if TResEvalInt(RightValue).Int=0 then
  2357. RaiseDivByZero(20170711144954,Expr)
  2358. else
  2359. Result:=TResEvalFloat.CreateValue(Flo / TResEvalInt(RightValue).Int);
  2360. revkUInt:
  2361. // float / uint
  2362. if TResEvalUInt(RightValue).UInt=0 then
  2363. RaiseDivByZero(20170711145023,Expr)
  2364. else
  2365. Result:=TResEvalFloat.CreateValue(Flo / TResEvalUInt(RightValue).UInt);
  2366. revkFloat:
  2367. begin
  2368. // float / float
  2369. try
  2370. Flo:=Flo / TResEvalFloat(RightValue).FloatValue;
  2371. except
  2372. RaiseMsg(20170711145040,nDivByZero,sDivByZero,[],Expr);
  2373. end;
  2374. Result:=TResEvalFloat.CreateValue(Flo);
  2375. end;
  2376. revkCurrency:
  2377. begin
  2378. // float / currency
  2379. try
  2380. aCurrency:=Flo / TResEvalCurrency(RightValue).Value;
  2381. except
  2382. RaiseMsg(20180421165058,nDivByZero,sDivByZero,[],Expr);
  2383. end;
  2384. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2385. end;
  2386. else
  2387. {$IFDEF VerbosePasResolver}
  2388. writeln('TResExprEvaluator.EvalBinaryDivideExpr float / ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2389. {$ENDIF}
  2390. RaiseNotYetImplemented(20170711145050,Expr);
  2391. end;
  2392. end;
  2393. revkCurrency:
  2394. begin
  2395. aCurrency:=TResEvalCurrency(LeftValue).Value;
  2396. case RightValue.Kind of
  2397. revkInt:
  2398. // currency / int
  2399. if TResEvalInt(RightValue).Int=0 then
  2400. RaiseDivByZero(20180421165154,Expr)
  2401. else
  2402. Result:=TResEvalCurrency.CreateValue(aCurrency / TResEvalInt(RightValue).Int);
  2403. revkUInt:
  2404. // currency / uint
  2405. if TResEvalUInt(RightValue).UInt=0 then
  2406. RaiseDivByZero(20180421165205,Expr)
  2407. else
  2408. Result:=TResEvalCurrency.CreateValue(aCurrency / TResEvalUInt(RightValue).UInt);
  2409. revkFloat:
  2410. begin
  2411. // currency / float
  2412. try
  2413. aCurrency:=aCurrency / TResEvalFloat(RightValue).FloatValue;
  2414. except
  2415. RaiseMsg(20180421165237,nDivByZero,sDivByZero,[],Expr);
  2416. end;
  2417. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2418. end;
  2419. revkCurrency:
  2420. begin
  2421. // currency / currency
  2422. try
  2423. aCurrency:=aCurrency / TResEvalCurrency(RightValue).Value;
  2424. except
  2425. RaiseMsg(20180421165252,nDivByZero,sDivByZero,[],Expr);
  2426. end;
  2427. Result:=TResEvalCurrency.CreateValue(aCurrency);
  2428. end;
  2429. else
  2430. {$IFDEF VerbosePasResolver}
  2431. writeln('TResExprEvaluator.EvalBinaryDivideExpr currency / ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2432. {$ENDIF}
  2433. RaiseNotYetImplemented(20180421165301,Expr);
  2434. end;
  2435. end;
  2436. else
  2437. {$IFDEF VerbosePasResolver}
  2438. writeln('TResExprEvaluator.EvalBinaryDivExpr div ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2439. {$ENDIF}
  2440. RaiseNotYetImplemented(20170530102352,Expr);
  2441. end;
  2442. end;
  2443. function TResExprEvaluator.EvalBinaryDivExpr(Expr: TBinaryExpr; LeftValue,
  2444. RightValue: TResEvalValue): TResEvalValue;
  2445. var
  2446. Int: TMaxPrecInt;
  2447. UInt: TMaxPrecUInt;
  2448. begin
  2449. Result:=nil;
  2450. case LeftValue.Kind of
  2451. revkInt:
  2452. case RightValue.Kind of
  2453. revkInt:
  2454. // int div int
  2455. if TResEvalInt(RightValue).Int=0 then
  2456. RaiseDivByZero(20170530102619,Expr)
  2457. else
  2458. begin
  2459. Int:=TResEvalInt(LeftValue).Int div TResEvalInt(RightValue).Int;
  2460. Result:=TResEvalInt.CreateValue(Int);
  2461. end;
  2462. revkUInt:
  2463. // int div uint
  2464. if TResEvalUInt(RightValue).UInt=0 then
  2465. RaiseDivByZero(20170530102745,Expr)
  2466. else
  2467. begin
  2468. if TResEvalUInt(RightValue).UInt>HighIntAsUInt then
  2469. Int:=0
  2470. else
  2471. Int:=TResEvalInt(LeftValue).Int div TResEvalUInt(RightValue).UInt;
  2472. Result:=TResEvalInt.CreateValue(Int);
  2473. end;
  2474. else
  2475. {$IFDEF VerbosePasResolver}
  2476. writeln('TResExprEvaluator.EvalBinaryDivExpr int div ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2477. {$ENDIF}
  2478. RaiseNotYetImplemented(20170530102403,Expr);
  2479. end;
  2480. revkUInt:
  2481. case RightValue.Kind of
  2482. revkInt:
  2483. // uint div int
  2484. if TResEvalInt(RightValue).Int=0 then
  2485. RaiseDivByZero(20170530103026,Expr)
  2486. else if TResEvalUInt(LeftValue).UInt<=HighIntAsUInt then
  2487. begin
  2488. Int:=TMaxPrecInt(TResEvalUInt(LeftValue).UInt) div TResEvalInt(RightValue).Int;
  2489. Result:=TResEvalInt.CreateValue(Int);
  2490. end
  2491. else if TResEvalInt(RightValue).Int>0 then
  2492. begin
  2493. UInt:=TResEvalUInt(LeftValue).UInt div TMaxPrecUInt(TResEvalInt(RightValue).Int);
  2494. Result:=CreateResEvalInt(UInt);
  2495. end
  2496. else
  2497. RaiseOverflowArithmetic(20170530104315,Expr);
  2498. revkUInt:
  2499. // uint div uint
  2500. if TResEvalInt(RightValue).Int=0 then
  2501. RaiseDivByZero(20170530103026,Expr)
  2502. else
  2503. begin
  2504. UInt:=TResEvalUInt(LeftValue).UInt div TResEvalUInt(RightValue).UInt;
  2505. Result:=CreateResEvalInt(UInt);
  2506. end;
  2507. else
  2508. {$IFDEF VerbosePasResolver}
  2509. writeln('TResExprEvaluator.EvalBinaryDivExpr uint div ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2510. {$ENDIF}
  2511. RaiseNotYetImplemented(20170530102403,Expr);
  2512. end;
  2513. else
  2514. {$IFDEF VerbosePasResolver}
  2515. writeln('TResExprEvaluator.EvalBinaryDivExpr div ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2516. {$ENDIF}
  2517. RaiseNotYetImplemented(20170530102352,Expr);
  2518. end;
  2519. end;
  2520. function TResExprEvaluator.EvalBinaryModExpr(Expr: TBinaryExpr; LeftValue,
  2521. RightValue: TResEvalValue): TResEvalValue;
  2522. var
  2523. Int: TMaxPrecInt;
  2524. UInt: TMaxPrecUInt;
  2525. begin
  2526. Result:=nil;
  2527. case LeftValue.Kind of
  2528. revkInt:
  2529. case RightValue.Kind of
  2530. revkInt:
  2531. // int mod int
  2532. if TResEvalInt(RightValue).Int=0 then
  2533. RaiseDivByZero(20170530104638,Expr)
  2534. else
  2535. begin
  2536. Int:=TResEvalInt(LeftValue).Int mod TResEvalInt(RightValue).Int;
  2537. Result:=TResEvalInt.CreateValue(Int);
  2538. end;
  2539. revkUInt:
  2540. // int mod uint
  2541. if TResEvalUInt(RightValue).UInt=0 then
  2542. RaiseDivByZero(20170530104758,Expr)
  2543. else
  2544. begin
  2545. if TResEvalInt(LeftValue).Int<0 then
  2546. UInt:=TMaxPrecUInt(-TResEvalInt(LeftValue).Int) mod TResEvalUInt(RightValue).UInt
  2547. else
  2548. UInt:=TMaxPrecUInt(TResEvalInt(LeftValue).Int) mod TResEvalUInt(RightValue).UInt;
  2549. Result:=CreateResEvalInt(UInt);
  2550. end;
  2551. else
  2552. {$IFDEF VerbosePasResolver}
  2553. writeln('TResExprEvaluator.EvalBinaryModExpr int mod ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2554. {$ENDIF}
  2555. RaiseNotYetImplemented(20170530110057,Expr);
  2556. end;
  2557. revkUInt:
  2558. case RightValue.Kind of
  2559. revkInt:
  2560. // uint mod int
  2561. if TResEvalInt(RightValue).Int=0 then
  2562. RaiseDivByZero(20170530110110,Expr)
  2563. else if TResEvalUInt(LeftValue).UInt<=HighIntAsUInt then
  2564. begin
  2565. Int:=TMaxPrecInt(TResEvalUInt(LeftValue).UInt) mod TResEvalInt(RightValue).Int;
  2566. Result:=TResEvalInt.CreateValue(Int);
  2567. end
  2568. else if TResEvalInt(RightValue).Int>0 then
  2569. begin
  2570. UInt:=TResEvalUInt(LeftValue).UInt mod TMaxPrecUInt(TResEvalInt(RightValue).Int);
  2571. Result:=CreateResEvalInt(UInt);
  2572. end
  2573. else
  2574. RaiseOverflowArithmetic(20170530110602,Expr);
  2575. revkUInt:
  2576. // uint div uint
  2577. if TResEvalInt(RightValue).Int=0 then
  2578. RaiseDivByZero(20170530110609,Expr)
  2579. else
  2580. begin
  2581. UInt:=TResEvalUInt(LeftValue).UInt mod TResEvalUInt(RightValue).UInt;
  2582. Result:=CreateResEvalInt(UInt);
  2583. end;
  2584. else
  2585. {$IFDEF VerbosePasResolver}
  2586. writeln('TResExprEvaluator.EvalBinaryModExpr uint mod ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2587. {$ENDIF}
  2588. RaiseNotYetImplemented(20170530110633,Expr);
  2589. end;
  2590. else
  2591. {$IFDEF VerbosePasResolver}
  2592. writeln('TResExprEvaluator.EvalBinaryModExpr mod ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2593. {$ENDIF}
  2594. RaiseNotYetImplemented(20170530110644,Expr);
  2595. end;
  2596. end;
  2597. function TResExprEvaluator.EvalBinaryShiftExpr(Expr: TBinaryExpr; LeftValue,
  2598. RightValue: TResEvalValue): TResEvalValue;
  2599. var
  2600. Int: TMaxPrecInt;
  2601. UInt: TMaxPrecUInt;
  2602. ShiftLeft: Boolean;
  2603. begin
  2604. Result:=nil;
  2605. ShiftLeft:=Expr.OpCode=eopShl;
  2606. case LeftValue.Kind of
  2607. revkInt:
  2608. case RightValue.Kind of
  2609. revkInt:
  2610. // int shl int
  2611. begin
  2612. if (TResEvalInt(RightValue).Int<0) or (TResEvalInt(RightValue).Int>63) then
  2613. EmitRangeCheckConst(20170530203840,IntToStr(TResEvalInt(RightValue).Int),0,63,Expr);
  2614. if ShiftLeft then
  2615. Int:=TResEvalInt(LeftValue).Int shl byte(TResEvalInt(RightValue).Int)
  2616. else
  2617. Int:=TResEvalInt(LeftValue).Int shr byte(TResEvalInt(RightValue).Int);
  2618. Result:=TResEvalInt.CreateValue(Int);
  2619. end;
  2620. revkUInt:
  2621. // int shl uint
  2622. begin
  2623. if (TResEvalUInt(RightValue).UInt>63) then
  2624. EmitRangeCheckConst(20170530203840,IntToStr(TResEvalUInt(RightValue).UInt),0,63,Expr);
  2625. if ShiftLeft then
  2626. Int:=TResEvalInt(LeftValue).Int shl byte(TResEvalUInt(RightValue).UInt)
  2627. else
  2628. Int:=TResEvalInt(LeftValue).Int shr byte(TResEvalUInt(RightValue).UInt);
  2629. Result:=TResEvalInt.CreateValue(Int);
  2630. end;
  2631. else
  2632. {$IFDEF VerbosePasResolver}
  2633. writeln('TResExprEvaluator.EvalBinaryModExpr int shl/shr ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2634. {$ENDIF}
  2635. RaiseNotYetImplemented(20170530205332,Expr);
  2636. end;
  2637. revkUInt:
  2638. case RightValue.Kind of
  2639. revkInt:
  2640. // uint shl int
  2641. begin
  2642. if (TResEvalInt(RightValue).Int<0) or (TResEvalInt(RightValue).Int>63) then
  2643. EmitRangeCheckConst(20170530205414,IntToStr(TResEvalInt(RightValue).Int),0,63,Expr);
  2644. if ShiftLeft then
  2645. UInt:=TResEvalUInt(LeftValue).UInt shl byte(TResEvalInt(RightValue).Int)
  2646. else
  2647. UInt:=TResEvalUInt(LeftValue).UInt shr byte(TResEvalInt(RightValue).Int);
  2648. Result:=CreateResEvalInt(UInt);
  2649. end;
  2650. revkUInt:
  2651. // uint shl uint
  2652. begin
  2653. if (TResEvalUInt(RightValue).UInt>63) then
  2654. EmitRangeCheckConst(20170530205601,IntToStr(TResEvalUInt(RightValue).UInt),0,63,Expr);
  2655. if ShiftLeft then
  2656. UInt:=TResEvalUInt(LeftValue).UInt shl byte(TResEvalUInt(RightValue).UInt)
  2657. else
  2658. UInt:=TResEvalUInt(LeftValue).UInt shr byte(TResEvalUInt(RightValue).UInt);
  2659. Result:=CreateResEvalInt(UInt);
  2660. end;
  2661. else
  2662. {$IFDEF VerbosePasResolver}
  2663. writeln('TResExprEvaluator.EvalBinaryShiftExpr uint shl/shr ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2664. {$ENDIF}
  2665. RaiseNotYetImplemented(20170530205640,Expr);
  2666. end;
  2667. else
  2668. {$IFDEF VerbosePasResolver}
  2669. writeln('TResExprEvaluator.EvalBinaryShiftExpr shl/shr ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2670. {$ENDIF}
  2671. RaiseNotYetImplemented(20170530205646,Expr);
  2672. end;
  2673. end;
  2674. function TResExprEvaluator.EvalBinaryBoolOpExpr(Expr: TBinaryExpr; LeftValue,
  2675. RightValue: TResEvalValue): TResEvalValue;
  2676. // AND, OR, XOR
  2677. begin
  2678. Result:=nil;
  2679. case LeftValue.Kind of
  2680. revkBool:
  2681. case RightValue.Kind of
  2682. revkBool:
  2683. begin
  2684. // logical and/or/xor
  2685. Result:=TResEvalBool.Create;
  2686. case Expr.OpCode of
  2687. eopAnd: TResEvalBool(Result).B:=TResEvalBool(LeftValue).B and TResEvalBool(RightValue).B;
  2688. eopOr: TResEvalBool(Result).B:=TResEvalBool(LeftValue).B or TResEvalBool(RightValue).B;
  2689. eopXor: TResEvalBool(Result).B:=TResEvalBool(LeftValue).B xor TResEvalBool(RightValue).B;
  2690. end;
  2691. end;
  2692. else
  2693. {$IFDEF VerbosePasResolver}
  2694. writeln('TResExprEvaluator.EvalBinaryBoolOpExpr bool ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2695. {$ENDIF}
  2696. RaiseNotYetImplemented(20170531011502,Expr);
  2697. end;
  2698. revkInt:
  2699. case RightValue.Kind of
  2700. revkInt:
  2701. begin
  2702. // bitwise and/or/xor
  2703. Result:=TResEvalInt.Create;
  2704. case Expr.OpCode of
  2705. eopAnd: TResEvalInt(Result).Int:=TResEvalInt(LeftValue).Int and TResEvalInt(RightValue).Int;
  2706. eopOr: TResEvalInt(Result).Int:=TResEvalInt(LeftValue).Int or TResEvalInt(RightValue).Int;
  2707. eopXor: TResEvalInt(Result).Int:=TResEvalInt(LeftValue).Int xor TResEvalInt(RightValue).Int;
  2708. end;
  2709. end;
  2710. else
  2711. {$IFDEF VerbosePasResolver}
  2712. writeln('TResExprEvaluator.EvalBinaryBoolOpExpr int ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2713. {$ENDIF}
  2714. RaiseNotYetImplemented(20170530211140,Expr);
  2715. end;
  2716. revkUInt:
  2717. case RightValue.Kind of
  2718. revkUInt:
  2719. begin
  2720. // bitwise and/or/xor
  2721. Result:=TResEvalUInt.Create;
  2722. case Expr.OpCode of
  2723. eopAnd: TResEvalUInt(Result).UInt:=TResEvalUInt(LeftValue).UInt and TResEvalUInt(RightValue).UInt;
  2724. eopOr: TResEvalUInt(Result).UInt:=TResEvalUInt(LeftValue).UInt or TResEvalUInt(RightValue).UInt;
  2725. eopXor: TResEvalUInt(Result).UInt:=TResEvalUInt(LeftValue).UInt xor TResEvalUInt(RightValue).UInt;
  2726. end;
  2727. end;
  2728. else
  2729. {$IFDEF VerbosePasResolver}
  2730. writeln('TResExprEvaluator.EvalBinaryBoolOpExpr int ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2731. {$ENDIF}
  2732. RaiseNotYetImplemented(20170530211140,Expr);
  2733. end;
  2734. else
  2735. {$IFDEF VerbosePasResolver}
  2736. writeln('TResExprEvaluator.EvalBinaryBoolOpExpr ',Expr.OpCode,' ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2737. {$ENDIF}
  2738. RaiseNotYetImplemented(20170530205938,Expr);
  2739. end;
  2740. end;
  2741. function TResExprEvaluator.EvalBinaryNEqualExpr(Expr: TBinaryExpr; LeftValue,
  2742. RightValue: TResEvalValue): TResEvalValue;
  2743. var
  2744. UInt: TMaxPrecUInt;
  2745. LeftSet, RightSet: TResEvalSet;
  2746. i: Integer;
  2747. begin
  2748. Result:=TResEvalBool.Create;
  2749. try
  2750. {$Q+}
  2751. {$R+}
  2752. case LeftValue.Kind of
  2753. revkBool:
  2754. case RightValue.Kind of
  2755. revkBool:
  2756. TResEvalBool(Result).B:=TResEvalBool(LeftValue).B=TResEvalBool(RightValue).B;
  2757. else
  2758. {$IFDEF VerbosePasResolver}
  2759. writeln('TResExprEvaluator.EvalBinaryNEqualExpr bool ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2760. {$ENDIF}
  2761. Result.Free;
  2762. RaiseNotYetImplemented(20170531011937,Expr);
  2763. end;
  2764. revkInt:
  2765. case RightValue.Kind of
  2766. revkInt:
  2767. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int=TResEvalInt(RightValue).Int;
  2768. revkUInt:
  2769. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int=TResEvalUInt(RightValue).UInt;
  2770. revkFloat:
  2771. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int=TResEvalFloat(RightValue).FloatValue;
  2772. revkCurrency:
  2773. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int=TResEvalCurrency(RightValue).Value;
  2774. else
  2775. {$IFDEF VerbosePasResolver}
  2776. writeln('TResExprEvaluator.EvalBinaryNEqualExpr int ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2777. {$ENDIF}
  2778. Result.Free;
  2779. RaiseNotYetImplemented(20170531012412,Expr);
  2780. end;
  2781. revkUInt:
  2782. begin
  2783. UInt:=TResEvalUInt(LeftValue).UInt;
  2784. case RightValue.Kind of
  2785. revkInt:
  2786. TResEvalBool(Result).B:=(UInt<=HighIntAsUInt)
  2787. and (TMaxPrecInt(UInt)=TResEvalInt(RightValue).Int);
  2788. revkUInt:
  2789. TResEvalBool(Result).B:=UInt=TResEvalUInt(RightValue).UInt;
  2790. revkFloat:
  2791. TResEvalBool(Result).B:=UInt=TResEvalFloat(RightValue).FloatValue;
  2792. revkCurrency:
  2793. TResEvalBool(Result).B:=UInt=TResEvalCurrency(RightValue).Value;
  2794. else
  2795. {$IFDEF VerbosePasResolver}
  2796. writeln('TResExprEvaluator.EvalBinaryNEqualExpr uint ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2797. {$ENDIF}
  2798. Result.Free;
  2799. RaiseNotYetImplemented(20170601122803,Expr);
  2800. end;
  2801. end;
  2802. revkFloat:
  2803. case RightValue.Kind of
  2804. revkInt:
  2805. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue=TResEvalInt(RightValue).Int;
  2806. revkUInt:
  2807. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue=TResEvalUInt(RightValue).UInt;
  2808. revkFloat:
  2809. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue=TResEvalFloat(RightValue).FloatValue;
  2810. revkCurrency:
  2811. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue=TResEvalCurrency(RightValue).Value;
  2812. else
  2813. {$IFDEF VerbosePasResolver}
  2814. writeln('TResExprEvaluator.EvalBinaryNEqualExpr float ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2815. {$ENDIF}
  2816. Result.Free;
  2817. RaiseNotYetImplemented(20170601122806,Expr);
  2818. end;
  2819. revkCurrency:
  2820. case RightValue.Kind of
  2821. revkInt:
  2822. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value=TResEvalInt(RightValue).Int;
  2823. revkUInt:
  2824. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value=TResEvalUInt(RightValue).UInt;
  2825. revkFloat:
  2826. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value=TResEvalFloat(RightValue).FloatValue;
  2827. revkCurrency:
  2828. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value=TResEvalCurrency(RightValue).Value;
  2829. else
  2830. {$IFDEF VerbosePasResolver}
  2831. writeln('TResExprEvaluator.EvalBinaryNEqualExpr currency ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2832. {$ENDIF}
  2833. Result.Free;
  2834. RaiseNotYetImplemented(20180421165438,Expr);
  2835. end;
  2836. {$ifdef FPC_HAS_CPSTRING}
  2837. revkString:
  2838. case RightValue.Kind of
  2839. revkString:
  2840. if GetCodePage(TResEvalString(LeftValue).S)=GetCodePage(TResEvalString(RightValue).S) then
  2841. TResEvalBool(Result).B:=TResEvalString(LeftValue).S=TResEvalString(RightValue).S
  2842. else
  2843. TResEvalBool(Result).B:=GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left)
  2844. =GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
  2845. revkUnicodeString:
  2846. TResEvalBool(Result).B:=GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left)
  2847. =TResEvalUTF16(RightValue).S;
  2848. else
  2849. {$IFDEF VerbosePasResolver}
  2850. writeln('TResExprEvaluator.EvalBinaryNEqualExpr string ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2851. {$ENDIF}
  2852. Result.Free;
  2853. RaiseNotYetImplemented(20170711175409,Expr);
  2854. end;
  2855. {$endif}
  2856. revkUnicodeString:
  2857. case RightValue.Kind of
  2858. {$ifdef FPC_HAS_CPSTRING}
  2859. revkString:
  2860. TResEvalBool(Result).B:=TResEvalUTF16(LeftValue).S
  2861. =GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
  2862. {$endif}
  2863. revkUnicodeString:
  2864. TResEvalBool(Result).B:=TResEvalUTF16(LeftValue).S
  2865. =TResEvalUTF16(RightValue).S;
  2866. else
  2867. {$IFDEF VerbosePasResolver}
  2868. writeln('TResExprEvaluator.EvalBinaryNEqualExpr string ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2869. {$ENDIF}
  2870. Result.Free;
  2871. RaiseNotYetImplemented(20170711175409,Expr);
  2872. end;
  2873. revkSetOfInt:
  2874. case RightValue.Kind of
  2875. revkSetOfInt:
  2876. begin
  2877. LeftSet:=TResEvalSet(LeftValue);
  2878. RightSet:=TResEvalSet(RightValue);
  2879. if LeftSet.ElKind=revskNone then
  2880. TResEvalBool(Result).B:=length(RightSet.Ranges)=0
  2881. else if RightSet.ElKind=revskNone then
  2882. TResEvalBool(Result).B:=length(LeftSet.Ranges)=0
  2883. else if length(LeftSet.Ranges)<>length(RightSet.Ranges) then
  2884. TResEvalBool(Result).B:=false
  2885. else
  2886. begin
  2887. TResEvalBool(Result).B:=true;
  2888. for i:=0 to length(LeftSet.Ranges)-1 do
  2889. if (LeftSet.Ranges[i].RangeStart<>RightSet.Ranges[i].RangeStart)
  2890. or (LeftSet.Ranges[i].RangeEnd<>RightSet.Ranges[i].RangeEnd) then
  2891. begin
  2892. TResEvalBool(Result).B:=false;
  2893. break;
  2894. end;
  2895. end;
  2896. end;
  2897. else
  2898. {$IFDEF VerbosePasResolver}
  2899. writeln('TResExprEvaluator.EvalBinaryNEqualExpr ',Expr.OpCode,' set=? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2900. {$ENDIF}
  2901. RaiseNotYetImplemented(20170714120756,Expr);
  2902. end;
  2903. else
  2904. {$IFDEF VerbosePasResolver}
  2905. writeln('TResExprEvaluator.EvalBinaryNEqualExpr ',Expr.OpCode,' ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2906. {$ENDIF}
  2907. Result.Free;
  2908. RaiseNotYetImplemented(20170531011931,Expr);
  2909. end;
  2910. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  2911. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  2912. except
  2913. on EOverflow do
  2914. RaiseOverflowArithmetic(20170601132729,Expr);
  2915. on ERangeError do
  2916. RaiseRangeCheck(20170601132740,Expr);
  2917. end;
  2918. if Expr.OpCode=eopNotEqual then
  2919. TResEvalBool(Result).B:=not TResEvalBool(Result).B;
  2920. end;
  2921. function TResExprEvaluator.EvalBinaryLessGreaterExpr(Expr: TBinaryExpr;
  2922. LeftValue, RightValue: TResEvalValue): TResEvalValue;
  2923. procedure CmpUnicode(const LeftUnicode, RightUnicode: UnicodeString);
  2924. begin
  2925. case Expr.OpCode of
  2926. eopLessThan:
  2927. TResEvalBool(Result).B:=LeftUnicode < RightUnicode;
  2928. eopGreaterThan:
  2929. TResEvalBool(Result).B:=LeftUnicode > RightUnicode;
  2930. eopLessthanEqual:
  2931. TResEvalBool(Result).B:=LeftUnicode <= RightUnicode;
  2932. eopGreaterThanEqual:
  2933. TResEvalBool(Result).B:=LeftUnicode >= RightUnicode;
  2934. end;
  2935. end;
  2936. var
  2937. LeftSet, RightSet: TResEvalSet;
  2938. i: Integer;
  2939. Int: TMaxPrecInt;
  2940. begin
  2941. Result:=TResEvalBool.Create;
  2942. try
  2943. {$Q+}
  2944. {$R+}
  2945. case LeftValue.Kind of
  2946. revkInt:
  2947. case RightValue.Kind of
  2948. revkInt:
  2949. case Expr.OpCode of
  2950. eopLessThan:
  2951. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int < TResEvalInt(RightValue).Int;
  2952. eopGreaterThan:
  2953. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int > TResEvalInt(RightValue).Int;
  2954. eopLessthanEqual:
  2955. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int <= TResEvalInt(RightValue).Int;
  2956. eopGreaterThanEqual:
  2957. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int >= TResEvalInt(RightValue).Int;
  2958. end;
  2959. revkUInt:
  2960. case Expr.OpCode of
  2961. eopLessThan:
  2962. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int < TResEvalUInt(RightValue).UInt;
  2963. eopGreaterThan:
  2964. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int > TResEvalUInt(RightValue).UInt;
  2965. eopLessthanEqual:
  2966. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int <= TResEvalUInt(RightValue).UInt;
  2967. eopGreaterThanEqual:
  2968. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int >= TResEvalUInt(RightValue).UInt;
  2969. end;
  2970. revkFloat:
  2971. case Expr.OpCode of
  2972. eopLessThan:
  2973. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int < TResEvalFloat(RightValue).FloatValue;
  2974. eopGreaterThan:
  2975. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int > TResEvalFloat(RightValue).FloatValue;
  2976. eopLessthanEqual:
  2977. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int <= TResEvalFloat(RightValue).FloatValue;
  2978. eopGreaterThanEqual:
  2979. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int >= TResEvalFloat(RightValue).FloatValue;
  2980. end;
  2981. revkCurrency:
  2982. case Expr.OpCode of
  2983. eopLessThan:
  2984. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int < TResEvalCurrency(RightValue).Value;
  2985. eopGreaterThan:
  2986. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int > TResEvalCurrency(RightValue).Value;
  2987. eopLessthanEqual:
  2988. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int <= TResEvalCurrency(RightValue).Value;
  2989. eopGreaterThanEqual:
  2990. TResEvalBool(Result).B:=TResEvalInt(LeftValue).Int >= TResEvalCurrency(RightValue).Value;
  2991. end;
  2992. else
  2993. {$IFDEF VerbosePasResolver}
  2994. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr int ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  2995. {$ENDIF}
  2996. Result.Free;
  2997. RaiseNotYetImplemented(20170601122512,Expr);
  2998. end;
  2999. revkUInt:
  3000. case RightValue.Kind of
  3001. revkInt:
  3002. case Expr.OpCode of
  3003. eopLessThan:
  3004. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt < TResEvalInt(RightValue).Int;
  3005. eopGreaterThan:
  3006. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt > TResEvalInt(RightValue).Int;
  3007. eopLessthanEqual:
  3008. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt <= TResEvalInt(RightValue).Int;
  3009. eopGreaterThanEqual:
  3010. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt >= TResEvalInt(RightValue).Int;
  3011. end;
  3012. revkUInt:
  3013. case Expr.OpCode of
  3014. eopLessThan:
  3015. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt < TResEvalUInt(RightValue).UInt;
  3016. eopGreaterThan:
  3017. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt > TResEvalUInt(RightValue).UInt;
  3018. eopLessthanEqual:
  3019. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt <= TResEvalUInt(RightValue).UInt;
  3020. eopGreaterThanEqual:
  3021. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt >= TResEvalUInt(RightValue).UInt;
  3022. end;
  3023. revkFloat:
  3024. case Expr.OpCode of
  3025. eopLessThan:
  3026. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt < TResEvalFloat(RightValue).FloatValue;
  3027. eopGreaterThan:
  3028. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt > TResEvalFloat(RightValue).FloatValue;
  3029. eopLessthanEqual:
  3030. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt <= TResEvalFloat(RightValue).FloatValue;
  3031. eopGreaterThanEqual:
  3032. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt >= TResEvalFloat(RightValue).FloatValue;
  3033. end;
  3034. revkCurrency:
  3035. case Expr.OpCode of
  3036. eopLessThan:
  3037. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt < TResEvalCurrency(RightValue).Value;
  3038. eopGreaterThan:
  3039. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt > TResEvalCurrency(RightValue).Value;
  3040. eopLessthanEqual:
  3041. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt <= TResEvalCurrency(RightValue).Value;
  3042. eopGreaterThanEqual:
  3043. TResEvalBool(Result).B:=TResEvalUInt(LeftValue).UInt >= TResEvalCurrency(RightValue).Value;
  3044. end;
  3045. else
  3046. {$IFDEF VerbosePasResolver}
  3047. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr uint ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3048. {$ENDIF}
  3049. Result.Free;
  3050. RaiseNotYetImplemented(20170601133222,Expr);
  3051. end;
  3052. revkFloat:
  3053. case RightValue.Kind of
  3054. revkInt:
  3055. case Expr.OpCode of
  3056. eopLessThan:
  3057. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue < TResEvalInt(RightValue).Int;
  3058. eopGreaterThan:
  3059. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue > TResEvalInt(RightValue).Int;
  3060. eopLessthanEqual:
  3061. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue <= TResEvalInt(RightValue).Int;
  3062. eopGreaterThanEqual:
  3063. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue >= TResEvalInt(RightValue).Int;
  3064. end;
  3065. revkUInt:
  3066. case Expr.OpCode of
  3067. eopLessThan:
  3068. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue < TResEvalUInt(RightValue).UInt;
  3069. eopGreaterThan:
  3070. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue > TResEvalUInt(RightValue).UInt;
  3071. eopLessthanEqual:
  3072. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue <= TResEvalUInt(RightValue).UInt;
  3073. eopGreaterThanEqual:
  3074. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue >= TResEvalUInt(RightValue).UInt;
  3075. end;
  3076. revkFloat:
  3077. case Expr.OpCode of
  3078. eopLessThan:
  3079. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue < TResEvalFloat(RightValue).FloatValue;
  3080. eopGreaterThan:
  3081. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue > TResEvalFloat(RightValue).FloatValue;
  3082. eopLessthanEqual:
  3083. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue <= TResEvalFloat(RightValue).FloatValue;
  3084. eopGreaterThanEqual:
  3085. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue >= TResEvalFloat(RightValue).FloatValue;
  3086. end;
  3087. revkCurrency:
  3088. case Expr.OpCode of
  3089. eopLessThan:
  3090. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue < TResEvalCurrency(RightValue).Value;
  3091. eopGreaterThan:
  3092. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue > TResEvalCurrency(RightValue).Value;
  3093. eopLessthanEqual:
  3094. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue <= TResEvalCurrency(RightValue).Value;
  3095. eopGreaterThanEqual:
  3096. TResEvalBool(Result).B:=TResEvalFloat(LeftValue).FloatValue >= TResEvalCurrency(RightValue).Value;
  3097. end;
  3098. else
  3099. {$IFDEF VerbosePasResolver}
  3100. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr float ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3101. {$ENDIF}
  3102. Result.Free;
  3103. RaiseNotYetImplemented(20170601133421,Expr);
  3104. end;
  3105. revkCurrency:
  3106. case RightValue.Kind of
  3107. revkInt:
  3108. case Expr.OpCode of
  3109. eopLessThan:
  3110. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value < TResEvalInt(RightValue).Int;
  3111. eopGreaterThan:
  3112. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value > TResEvalInt(RightValue).Int;
  3113. eopLessthanEqual:
  3114. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value <= TResEvalInt(RightValue).Int;
  3115. eopGreaterThanEqual:
  3116. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value >= TResEvalInt(RightValue).Int;
  3117. end;
  3118. revkUInt:
  3119. case Expr.OpCode of
  3120. eopLessThan:
  3121. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value < TResEvalUInt(RightValue).UInt;
  3122. eopGreaterThan:
  3123. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value > TResEvalUInt(RightValue).UInt;
  3124. eopLessthanEqual:
  3125. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value <= TResEvalUInt(RightValue).UInt;
  3126. eopGreaterThanEqual:
  3127. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value >= TResEvalUInt(RightValue).UInt;
  3128. end;
  3129. revkFloat:
  3130. case Expr.OpCode of
  3131. eopLessThan:
  3132. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value < TResEvalFloat(RightValue).FloatValue;
  3133. eopGreaterThan:
  3134. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value > TResEvalFloat(RightValue).FloatValue;
  3135. eopLessthanEqual:
  3136. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value <= TResEvalFloat(RightValue).FloatValue;
  3137. eopGreaterThanEqual:
  3138. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value >= TResEvalFloat(RightValue).FloatValue;
  3139. end;
  3140. revkCurrency:
  3141. case Expr.OpCode of
  3142. eopLessThan:
  3143. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value < TResEvalCurrency(RightValue).Value;
  3144. eopGreaterThan:
  3145. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value > TResEvalCurrency(RightValue).Value;
  3146. eopLessthanEqual:
  3147. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value <= TResEvalCurrency(RightValue).Value;
  3148. eopGreaterThanEqual:
  3149. TResEvalBool(Result).B:=TResEvalCurrency(LeftValue).Value >= TResEvalCurrency(RightValue).Value;
  3150. end;
  3151. else
  3152. {$IFDEF VerbosePasResolver}
  3153. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr currency ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3154. {$ENDIF}
  3155. Result.Free;
  3156. RaiseNotYetImplemented(20180421165752,Expr);
  3157. end;
  3158. {$ifdef FPC_HAS_CPSTRING}
  3159. revkString:
  3160. case RightValue.Kind of
  3161. revkString:
  3162. if GetCodePage(TResEvalString(LeftValue).S)=GetCodePage(TResEvalString(RightValue).S) then
  3163. case Expr.OpCode of
  3164. eopLessThan:
  3165. TResEvalBool(Result).B:=TResEvalString(LeftValue).S < TResEvalString(RightValue).S;
  3166. eopGreaterThan:
  3167. TResEvalBool(Result).B:=TResEvalString(LeftValue).S > TResEvalString(RightValue).S;
  3168. eopLessthanEqual:
  3169. TResEvalBool(Result).B:=TResEvalString(LeftValue).S <= TResEvalString(RightValue).S;
  3170. eopGreaterThanEqual:
  3171. TResEvalBool(Result).B:=TResEvalString(LeftValue).S >= TResEvalString(RightValue).S;
  3172. end
  3173. else
  3174. CmpUnicode(GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left),
  3175. GetUnicodeStr(TResEvalString(RightValue).S,Expr.right));
  3176. revkUnicodeString:
  3177. CmpUnicode(GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left),
  3178. TResEvalUTF16(RightValue).S);
  3179. else
  3180. {$IFDEF VerbosePasResolver}
  3181. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr string ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3182. {$ENDIF}
  3183. Result.Free;
  3184. RaiseNotYetImplemented(20170711175629,Expr);
  3185. end;
  3186. {$endif}
  3187. revkUnicodeString:
  3188. case RightValue.Kind of
  3189. {$ifdef FPC_HAS_CPSTRING}
  3190. revkString:
  3191. CmpUnicode(TResEvalUTF16(LeftValue).S,
  3192. GetUnicodeStr(TResEvalString(RightValue).S,Expr.right));
  3193. {$endif}
  3194. revkUnicodeString:
  3195. CmpUnicode(TResEvalUTF16(LeftValue).S,TResEvalUTF16(RightValue).S);
  3196. else
  3197. {$IFDEF VerbosePasResolver}
  3198. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr unicodestring ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3199. {$ENDIF}
  3200. Result.Free;
  3201. RaiseNotYetImplemented(20170711210730,Expr);
  3202. end;
  3203. revkSetOfInt:
  3204. case RightValue.Kind of
  3205. revkSetOfInt:
  3206. begin
  3207. LeftSet:=TResEvalSet(LeftValue);
  3208. RightSet:=TResEvalSet(RightValue);
  3209. case Expr.OpCode of
  3210. eopGreaterThanEqual:
  3211. begin
  3212. // >= -> true if all elements of RightSet are in LeftSet
  3213. TResEvalBool(Result).B:=true;
  3214. for i:=0 to length(RightSet.Ranges)-1 do
  3215. begin
  3216. Int:=RightSet.Ranges[i].RangeStart;
  3217. while Int<=RightSet.Ranges[i].RangeEnd do
  3218. begin
  3219. if LeftSet.IndexOfRange(Int)<0 then
  3220. begin
  3221. TResEvalBool(Result).B:=false;
  3222. break;
  3223. end;
  3224. inc(Int);
  3225. end;
  3226. end;
  3227. end;
  3228. eopLessthanEqual:
  3229. begin
  3230. // <= -> true if all elements of LeftSet are in RightSet
  3231. TResEvalBool(Result).B:=true;
  3232. for i:=0 to length(LeftSet.Ranges)-1 do
  3233. begin
  3234. Int:=LeftSet.Ranges[i].RangeStart;
  3235. while Int<=LeftSet.Ranges[i].RangeEnd do
  3236. begin
  3237. if RightSet.IndexOfRange(Int)<0 then
  3238. begin
  3239. TResEvalBool(Result).B:=false;
  3240. break;
  3241. end;
  3242. inc(Int);
  3243. end;
  3244. end;
  3245. end
  3246. else
  3247. {$IFDEF VerbosePasResolver}
  3248. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr set ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3249. {$ENDIF}
  3250. Result.Free;
  3251. RaiseNotYetImplemented(20170714122121,Expr);
  3252. end;
  3253. end;
  3254. else
  3255. {$IFDEF VerbosePasResolver}
  3256. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr set ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3257. {$ENDIF}
  3258. Result.Free;
  3259. RaiseNotYetImplemented(20170714121925,Expr);
  3260. end;
  3261. else
  3262. {$IFDEF VerbosePasResolver}
  3263. writeln('TResExprEvaluator.EvalBinaryLowerGreaterExpr ? ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3264. {$ENDIF}
  3265. Result.Free;
  3266. RaiseNotYetImplemented(20170601122529,Expr);
  3267. end;
  3268. except
  3269. on EOverflow do
  3270. RaiseOverflowArithmetic(20170601132956,Expr);
  3271. on ERangeError do
  3272. RaiseRangeCheck(20170601132958,Expr);
  3273. end;
  3274. end;
  3275. function TResExprEvaluator.EvalBinaryInExpr(Expr: TBinaryExpr; LeftValue,
  3276. RightValue: TResEvalValue): TResEvalValue;
  3277. var
  3278. RightSet: TResEvalSet;
  3279. Int: TMaxPrecInt;
  3280. begin
  3281. Result:=nil;
  3282. case RightValue.Kind of
  3283. revkSetOfInt:
  3284. begin
  3285. RightSet:=TResEvalSet(RightValue);
  3286. case LeftValue.Kind of
  3287. revkBool:
  3288. Int:=ord(TResEvalBool(LeftValue).B);
  3289. revkInt:
  3290. Int:=TResEvalInt(LeftValue).Int;
  3291. revkUInt:
  3292. // Note: when FPC compares int64 with qword it converts the qword to an int64
  3293. if TResEvalUInt(LeftValue).UInt>HighIntAsUInt then
  3294. RaiseMsg(20170714123700,nRangeCheckError,sRangeCheckError,[],Expr)
  3295. else
  3296. Int:=TResEvalUInt(LeftValue).UInt;
  3297. {$ifdef FPC_HAS_CPSTRING}
  3298. revkString,
  3299. {$endif}
  3300. revkUnicodeString:
  3301. Int:=StringToOrd(LeftValue,Expr);
  3302. revkEnum:
  3303. Int:=TResEvalEnum(LeftValue).Index;
  3304. else
  3305. {$IFDEF VerbosePasResolver}
  3306. writeln('TResExprEvaluator.EvalBinaryInExpr ? in Set Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3307. {$ENDIF}
  3308. RaiseNotYetImplemented(20170714123412,Expr);
  3309. end;
  3310. Result:=TResEvalBool.CreateValue(RightSet.IndexOfRange(Int)>=0);
  3311. end;
  3312. else
  3313. {$IFDEF VerbosePasResolver}
  3314. writeln('TResExprEvaluator.EvalBinaryInExpr ? ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3315. {$ENDIF}
  3316. RaiseNotYetImplemented(20170714123409,Expr);
  3317. end;
  3318. end;
  3319. function TResExprEvaluator.EvalBinarySymmetricaldifferenceExpr(
  3320. Expr: TBinaryExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  3321. var
  3322. LeftSet, RightSet: TResEvalSet;
  3323. i: Integer;
  3324. Int: TMaxPrecInt;
  3325. begin
  3326. case LeftValue.Kind of
  3327. revkSetOfInt:
  3328. case RightValue.Kind of
  3329. revkSetOfInt:
  3330. begin
  3331. // sym diff
  3332. LeftSet:=TResEvalSet(LeftValue);
  3333. RightSet:=TResEvalSet(RightValue);
  3334. // elements, which exists in either, but not both
  3335. if LeftSet.ElKind=revskNone then
  3336. Result:=RightSet.Clone
  3337. else
  3338. begin
  3339. Result:=TResEvalSet.CreateEmptySameKind(LeftSet);
  3340. for i:=0 to length(LeftSet.Ranges)-1 do
  3341. begin
  3342. Int:=LeftSet.Ranges[i].RangeStart;
  3343. while Int<=LeftSet.Ranges[i].RangeEnd do
  3344. begin
  3345. if RightSet.IndexOfRange(Int)<0 then
  3346. TResEvalSet(Result).Add(Int,Int);
  3347. inc(Int);
  3348. end;
  3349. end;
  3350. for i:=0 to length(RightSet.Ranges)-1 do
  3351. begin
  3352. Int:=RightSet.Ranges[i].RangeStart;
  3353. while Int<=RightSet.Ranges[i].RangeEnd do
  3354. begin
  3355. if LeftSet.IndexOfRange(Int)<0 then
  3356. TResEvalSet(Result).Add(Int,Int);
  3357. inc(Int);
  3358. end;
  3359. end;
  3360. end;
  3361. end
  3362. else
  3363. {$IFDEF VerbosePasResolver}
  3364. writeln('TResExprEvaluator.EvalBinarySymmetricaldifferenceExpr Set><? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3365. {$ENDIF}
  3366. RaiseNotYetImplemented(20170714114144,Expr);
  3367. end;
  3368. else
  3369. {$IFDEF VerbosePasResolver}
  3370. writeln('TResExprEvaluator.EvalBinarySymmetricaldifferenceExpr ? ',Expr.OpCode,' ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3371. {$ENDIF}
  3372. RaiseNotYetImplemented(20170714114119,Expr);
  3373. end;
  3374. end;
  3375. function TResExprEvaluator.EvalParamsExpr(Expr: TParamsExpr;
  3376. Flags: TResEvalFlags): TResEvalValue;
  3377. begin
  3378. Result:=OnEvalParams(Self,Expr,Flags);
  3379. if Result<>nil then exit;
  3380. case Expr.Kind of
  3381. pekArrayParams: Result:=EvalArrayParamsExpr(Expr,Flags);
  3382. pekSet: Result:=EvalSetParamsExpr(Expr,Flags);
  3383. end;
  3384. if Result=nil then
  3385. begin
  3386. if [refConst,refConstExt]*Flags<>[] then
  3387. RaiseConstantExprExp(20170713124038,Expr);
  3388. exit;
  3389. end;
  3390. end;
  3391. function TResExprEvaluator.EvalArrayParamsExpr(Expr: TParamsExpr;
  3392. Flags: TResEvalFlags): TResEvalValue;
  3393. var
  3394. ArrayValue, IndexValue: TResEvalValue;
  3395. Int: TMaxPrecInt;
  3396. Param0: TPasExpr;
  3397. MaxIndex: Integer;
  3398. begin
  3399. Result:=nil;
  3400. ArrayValue:=Eval(Expr.Value,Flags);
  3401. if ArrayValue=nil then
  3402. begin
  3403. if [refConst,refConstExt]*Flags<>[] then
  3404. RaiseConstantExprExp(20170711181321,Expr.Value);
  3405. exit;
  3406. end;
  3407. IndexValue:=nil;
  3408. try
  3409. case ArrayValue.Kind of
  3410. {$ifdef FPC_HAS_CPSTRING}
  3411. revkString,
  3412. {$endif}
  3413. revkUnicodeString:
  3414. begin
  3415. // string[index]
  3416. Param0:=Expr.Params[0];
  3417. IndexValue:=Eval(Param0,Flags);
  3418. if IndexValue=nil then
  3419. begin
  3420. if [refConst,refConstExt]*Flags<>[] then
  3421. RaiseConstantExprExp(20170711181603,Param0);
  3422. exit;
  3423. end;
  3424. case IndexValue.Kind of
  3425. revkInt: Int:=TResEvalInt(IndexValue).Int;
  3426. revkUInt:
  3427. // Note: when FPC compares int64 with qword it converts the qword to an int64
  3428. if TResEvalUInt(IndexValue).UInt>HighIntAsUInt then
  3429. RaiseRangeCheck(20170711182006,Param0)
  3430. else
  3431. Int:=TResEvalUInt(IndexValue).UInt;
  3432. else
  3433. {$IFDEF VerbosePasResolver}
  3434. writeln('TResExprEvaluator.EvalParamsExpr string[',IndexValue.AsDebugString,']');
  3435. {$ENDIF}
  3436. RaiseNotYetImplemented(20170711182100,Expr);
  3437. end;
  3438. {$ifdef FPC_HAS_CPSTRING}
  3439. if ArrayValue.Kind=revkString then
  3440. MaxIndex:=length(TResEvalString(ArrayValue).S)
  3441. else
  3442. {$endif}
  3443. MaxIndex:=length(TResEvalUTF16(ArrayValue).S);
  3444. if (Int<1) or (Int>MaxIndex) then
  3445. EmitRangeCheckConst(20170711183058,IntToStr(Int),'1',IntToStr(MaxIndex),Param0,mtError);
  3446. {$ifdef FPC_HAS_CPSTRING}
  3447. if ArrayValue.Kind=revkString then
  3448. Result:=TResEvalString.CreateValue(TResEvalString(ArrayValue).S[Int])
  3449. else
  3450. {$endif}
  3451. Result:=TResEvalUTF16.CreateValue(TResEvalUTF16(ArrayValue).S[Int]);
  3452. exit;
  3453. end;
  3454. else
  3455. {$IFDEF VerbosePasResolver}
  3456. writeln('TResExprEvaluator.EvalParamsExpr Array=',ArrayValue.AsDebugString);
  3457. {$ENDIF}
  3458. RaiseNotYetImplemented(20170711181507,Expr);
  3459. end;
  3460. if [refConst,refConstExt]*Flags<>[] then
  3461. RaiseConstantExprExp(20170522173150,Expr);
  3462. finally
  3463. ReleaseEvalValue(ArrayValue);
  3464. ReleaseEvalValue(IndexValue);
  3465. end;
  3466. end;
  3467. function TResExprEvaluator.EvalSetParamsExpr(Expr: TParamsExpr;
  3468. Flags: TResEvalFlags): TResEvalSet;
  3469. begin
  3470. {$IFDEF VerbosePasResEval}
  3471. writeln('TResExprEvaluator.EvalSetParamsExpr length(Expr.Params)=',length(Expr.Params));
  3472. {$ENDIF}
  3473. Result:=EvalSetExpr(Expr,Expr.Params,Flags);
  3474. end;
  3475. function TResExprEvaluator.EvalSetExpr(Expr: TPasExpr;
  3476. ExprArray: TPasExprArray; Flags: TResEvalFlags): TResEvalSet;
  3477. var
  3478. i: Integer;
  3479. RangeStart, RangeEnd: TMaxPrecInt;
  3480. Value: TResEvalValue;
  3481. ok, OnlyConstElements: Boolean;
  3482. El: TPasExpr;
  3483. begin
  3484. {$IFDEF VerbosePasResEval}
  3485. writeln('TResExprEvaluator.EvalSetExpr Expr=',GetObjName(Expr),' length(ExprArray)=',length(ExprArray));
  3486. {$ENDIF}
  3487. Result:=TResEvalSet.Create;
  3488. if Expr=nil then ;
  3489. Value:=nil;
  3490. OnlyConstElements:=true;
  3491. ok:=false;
  3492. try
  3493. for i:=0 to length(ExprArray)-1 do
  3494. begin
  3495. El:=ExprArray[i];
  3496. {$IFDEF VerbosePasResEval}
  3497. writeln('TResExprEvaluator.EvalSetExpr ',i,' of ',length(ExprArray),' El=',GetObjName(El));
  3498. {$ENDIF}
  3499. Value:=Eval(El,Flags);
  3500. if Value=nil then
  3501. begin
  3502. // element is not a const -> the set is not a const
  3503. OnlyConstElements:=false;
  3504. continue;
  3505. end;
  3506. {$IFDEF VerbosePasResEval}
  3507. //writeln('TResExprEvaluator.EvalSetExpr ',i,' of ',length(ExprArray),' Value=',Value.AsDebugString);
  3508. {$ENDIF}
  3509. case Value.Kind of
  3510. revkBool:
  3511. begin
  3512. if Result.ElKind=revskNone then
  3513. Result.ElKind:=revskBool
  3514. else if Result.ElKind<>revskBool then
  3515. RaiseNotYetImplemented(20170714132843,El);
  3516. RangeStart:=ord(TResEvalBool(Value).B);
  3517. RangeEnd:=RangeStart;
  3518. end;
  3519. revkInt:
  3520. begin
  3521. if Result.ElKind=revskNone then
  3522. Result.ElKind:=revskInt
  3523. else if Result.ElKind<>revskInt then
  3524. RaiseNotYetImplemented(20170713201208,El);
  3525. RangeStart:=TResEvalInt(Value).Int;
  3526. RangeEnd:=RangeStart;
  3527. end;
  3528. revkUInt:
  3529. begin
  3530. if Result.ElKind=revskNone then
  3531. Result.ElKind:=revskInt
  3532. else if Result.ElKind<>revskInt then
  3533. RaiseNotYetImplemented(20170713201230,El)
  3534. // Note: when FPC compares int64 with qword it converts the qword to an int64
  3535. else if TResEvalUInt(Value).UInt>HighIntAsUInt then
  3536. EmitRangeCheckConst(20170713201306,Value.AsString,
  3537. '0',IntToStr(High(TMaxPrecInt)),El,mtError);
  3538. RangeStart:=TResEvalUInt(Value).UInt;
  3539. RangeEnd:=RangeStart;
  3540. end;
  3541. {$ifdef FPC_HAS_CPSTRING}
  3542. revkString:
  3543. begin
  3544. if Result.ElKind=revskNone then
  3545. Result.ElKind:=revskChar
  3546. else if Result.ElKind<>revskChar then
  3547. RaiseNotYetImplemented(20170713201456,El);
  3548. RangeStart:=StringToOrd(Value,nil);
  3549. if RangeStart>$ffff then
  3550. begin
  3551. // set of string (not of char)
  3552. ReleaseEvalValue(TResEvalValue(Result));
  3553. exit;
  3554. end;
  3555. RangeEnd:=RangeStart;
  3556. end;
  3557. {$endif}
  3558. revkUnicodeString:
  3559. begin
  3560. if Result.ElKind=revskNone then
  3561. Result.ElKind:=revskChar
  3562. else if Result.ElKind<>revskChar then
  3563. RaiseNotYetImplemented(20170713201516,El);
  3564. if length(TResEvalUTF16(Value).S)<>1 then
  3565. begin
  3566. // set of string (not of char)
  3567. ReleaseEvalValue(TResEvalValue(Result));
  3568. exit;
  3569. end;
  3570. RangeStart:=ord(TResEvalUTF16(Value).S[1]);
  3571. RangeEnd:=RangeStart;
  3572. end;
  3573. revkEnum:
  3574. begin
  3575. if Result.ElKind=revskNone then
  3576. begin
  3577. Result.ElKind:=revskEnum;
  3578. Result.ElType:=Value.IdentEl.Parent as TPasEnumType;
  3579. end
  3580. else if Result.ElKind<>revskEnum then
  3581. RaiseNotYetImplemented(20170713143559,El)
  3582. else if Result.ElType<>TResEvalEnum(Value).ElType then
  3583. RaiseNotYetImplemented(20170713201021,El);
  3584. RangeStart:=TResEvalEnum(Value).Index;
  3585. RangeEnd:=RangeStart;
  3586. end;
  3587. revkRangeInt:
  3588. begin
  3589. if Result.ElKind=revskNone then
  3590. begin
  3591. Result.ElKind:=TResEvalRangeInt(Value).ElKind;
  3592. if Result.ElKind=revskEnum then
  3593. Result.ElType:=TResEvalRangeInt(Value).ElType;
  3594. end
  3595. else if Result.ElKind<>TResEvalRangeInt(Value).ElKind then
  3596. RaiseNotYetImplemented(20170714101910,El);
  3597. RangeStart:=TResEvalRangeInt(Value).RangeStart;
  3598. RangeEnd:=TResEvalRangeInt(Value).RangeEnd;
  3599. end;
  3600. revkRangeUInt:
  3601. begin
  3602. if Result.ElKind=revskNone then
  3603. Result.ElKind:=revskInt
  3604. else if Result.ElKind<>revskInt then
  3605. RaiseNotYetImplemented(20170713202934,El)
  3606. // Note: when FPC compares int64 with qword it converts the qword to an int64
  3607. else if TResEvalRangeUInt(Value).RangeEnd>HighIntAsUInt then
  3608. EmitRangeCheckConst(20170713203034,Value.AsString,
  3609. '0',IntToStr(High(TMaxPrecInt)),El,mtError);
  3610. RangeStart:=TResEvalRangeUInt(Value).RangeStart;
  3611. RangeEnd:=TResEvalRangeUInt(Value).RangeEnd;
  3612. end
  3613. else
  3614. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  3615. writeln('TResExprEvaluator.EvalSetExpr Result.ElKind=',Result.ElKind,' Value.Kind=',Value.Kind);
  3616. {$ENDIF}
  3617. RaiseNotYetImplemented(20170713143422,El);
  3618. end;
  3619. if Result.Intersects(RangeStart,RangeEnd)>=0 then
  3620. begin
  3621. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  3622. writeln('TResExprEvaluator.EvalSetExpr Value=',Value.AsDebugString,' Range=',RangeStart,'..',RangeEnd,' Result=',Result.AsDebugString);
  3623. {$ENDIF}
  3624. RaiseMsg(20170714141326,nRangeCheckInSetConstructor,
  3625. sRangeCheckInSetConstructor,[],El);
  3626. end;
  3627. Result.Add(RangeStart,RangeEnd);
  3628. ReleaseEvalValue(Value);
  3629. end;
  3630. ok:=OnlyConstElements;
  3631. finally
  3632. ReleaseEvalValue(Value);
  3633. if not ok then
  3634. ReleaseEvalValue(TResEvalValue(Result));
  3635. end;
  3636. end;
  3637. function TResExprEvaluator.EvalArrayValuesExpr(Expr: TArrayValues;
  3638. Flags: TResEvalFlags): TResEvalSet;
  3639. begin
  3640. {$IFDEF VerbosePasResEval}
  3641. writeln('TResExprEvaluator.EvalArrayValuesExpr length(Expr.Values)=',length(Expr.Values));
  3642. {$ENDIF}
  3643. Result:=EvalSetExpr(Expr,Expr.Values,Flags);
  3644. end;
  3645. function TResExprEvaluator.EvalBinaryPowerExpr(Expr: TBinaryExpr; LeftValue,
  3646. RightValue: TResEvalValue): TResEvalValue;
  3647. var
  3648. Int: TMaxPrecInt;
  3649. Flo: TMaxPrecFloat;
  3650. aCurrency: TMaxPrecCurrency;
  3651. begin
  3652. Result:=nil;
  3653. case LeftValue.Kind of
  3654. revkInt:
  3655. case RightValue.Kind of
  3656. revkInt:
  3657. // int^^int
  3658. try
  3659. {$Q+}{$R+}
  3660. Int:=trunc(Math.power(TResEvalInt(LeftValue).Int,TResEvalInt(RightValue).Int));
  3661. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3662. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3663. Result:=TResEvalInt.CreateValue(Int);
  3664. except
  3665. RaiseOverflowArithmetic(20170530210533,Expr);
  3666. end;
  3667. revkUInt:
  3668. // int^^uint
  3669. try
  3670. {$Q+}{$R+}
  3671. Int:=trunc(Math.power(TResEvalInt(LeftValue).Int,TResEvalUInt(RightValue).UInt));
  3672. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3673. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3674. Result:=TResEvalInt.CreateValue(Int);
  3675. except
  3676. RaiseOverflowArithmetic(20170530211028,Expr);
  3677. end;
  3678. revkFloat:
  3679. // int^^float
  3680. try
  3681. {$Q+}{$R+}
  3682. Flo:=Math.power(TResEvalInt(LeftValue).Int,TResEvalFloat(RightValue).FloatValue);
  3683. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3684. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3685. Result:=TResEvalFloat.CreateValue(Flo);
  3686. except
  3687. RaiseOverflowArithmetic(20170816154223,Expr);
  3688. end;
  3689. revkCurrency:
  3690. // int^^currency
  3691. try
  3692. {$Q+}{$R+}
  3693. Flo:=Math.power(TResEvalInt(LeftValue).Int,TResEvalCurrency(RightValue).Value);
  3694. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3695. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3696. Result:=TResEvalFloat.CreateValue(Flo);
  3697. except
  3698. RaiseOverflowArithmetic(20180421165906,Expr);
  3699. end;
  3700. else
  3701. {$IFDEF VerbosePasResolver}
  3702. writeln('TResExprEvaluator.EvalBinaryPowerExpr int ^^ ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3703. {$ENDIF}
  3704. RaiseNotYetImplemented(20170530205640,Expr);
  3705. end;
  3706. revkUInt:
  3707. case RightValue.Kind of
  3708. revkInt:
  3709. // uint^^int
  3710. try
  3711. {$Q+}{$R+}
  3712. Int:=trunc(Math.power(TResEvalUInt(LeftValue).UInt,TResEvalInt(RightValue).Int));
  3713. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3714. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3715. Result:=TResEvalInt.CreateValue(Int);
  3716. except
  3717. RaiseOverflowArithmetic(20170530211102,Expr);
  3718. end;
  3719. revkUInt:
  3720. // uint^^uint
  3721. try
  3722. {$Q+}{$R+}
  3723. Int:=trunc(Math.power(TResEvalUInt(LeftValue).UInt,TResEvalUInt(RightValue).UInt));
  3724. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3725. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3726. Result:=TResEvalInt.CreateValue(Int);
  3727. except
  3728. RaiseOverflowArithmetic(20170530211121,Expr);
  3729. end;
  3730. revkFloat:
  3731. // uint^^float
  3732. try
  3733. {$Q+}{$R+}
  3734. Flo:=Math.power(TResEvalUInt(LeftValue).UInt,TResEvalFloat(RightValue).FloatValue);
  3735. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3736. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3737. Result:=TResEvalFloat.CreateValue(Flo);
  3738. except
  3739. RaiseOverflowArithmetic(20170816154241,Expr);
  3740. end;
  3741. revkCurrency:
  3742. // uint^^currency
  3743. try
  3744. {$Q+}{$R+}
  3745. Flo:=Math.power(TResEvalUInt(LeftValue).UInt,TResEvalCurrency(RightValue).Value);
  3746. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3747. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3748. Result:=TResEvalFloat.CreateValue(Flo);
  3749. except
  3750. RaiseOverflowArithmetic(20180421165948,Expr);
  3751. end;
  3752. else
  3753. {$IFDEF VerbosePasResolver}
  3754. writeln('TResExprEvaluator.EvalBinaryPowerExpr uint ^^ ? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3755. {$ENDIF}
  3756. RaiseNotYetImplemented(20170530211140,Expr);
  3757. end;
  3758. revkFloat:
  3759. case RightValue.Kind of
  3760. revkInt:
  3761. // float ^^ int
  3762. try
  3763. {$Q+}{$R+}
  3764. Flo:=Math.power(TResEvalFloat(LeftValue).FloatValue,TResEvalInt(RightValue).Int);
  3765. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3766. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3767. Result:=TResEvalFloat.CreateValue(Flo);
  3768. except
  3769. RaiseOverflowArithmetic(20170816153950,Expr);
  3770. end;
  3771. revkUInt:
  3772. // float ^^ uint
  3773. try
  3774. {$Q+}{$R+}
  3775. Flo:=Math.power(TResEvalFloat(LeftValue).FloatValue,TResEvalUInt(RightValue).UInt);
  3776. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3777. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3778. Result:=TResEvalFloat.CreateValue(Flo);
  3779. except
  3780. RaiseOverflowArithmetic(20170816154012,Expr);
  3781. end;
  3782. revkFloat:
  3783. // float ^^ float
  3784. try
  3785. {$Q+}{$R+}
  3786. Flo:=Math.power(TResEvalFloat(LeftValue).FloatValue,TResEvalFloat(RightValue).FloatValue);
  3787. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3788. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3789. Result:=TResEvalFloat.CreateValue(Flo);
  3790. except
  3791. RaiseOverflowArithmetic(20170816154012,Expr);
  3792. end;
  3793. revkCurrency:
  3794. // float ^^ currency
  3795. try
  3796. {$Q+}{$R+}
  3797. Flo:=Math.power(TResEvalFloat(LeftValue).FloatValue,TResEvalCurrency(RightValue).Value);
  3798. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3799. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3800. Result:=TResEvalFloat.CreateValue(Flo);
  3801. except
  3802. RaiseOverflowArithmetic(20180421170016,Expr);
  3803. end;
  3804. end;
  3805. revkCurrency:
  3806. case RightValue.Kind of
  3807. revkInt:
  3808. // currency ^^ int
  3809. try
  3810. {$Q+}{$R+}
  3811. aCurrency:=Math.power(TResEvalCurrency(LeftValue).Value,TResEvalInt(RightValue).Int);
  3812. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3813. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3814. Result:=TResEvalCurrency.CreateValue(aCurrency);
  3815. except
  3816. RaiseOverflowArithmetic(20180421170235,Expr);
  3817. end;
  3818. revkUInt:
  3819. // currency ^^ uint
  3820. try
  3821. {$Q+}{$R+}
  3822. aCurrency:=Math.power(TResEvalCurrency(LeftValue).Value,TResEvalUInt(RightValue).UInt);
  3823. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3824. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3825. Result:=TResEvalCurrency.CreateValue(aCurrency);
  3826. except
  3827. RaiseOverflowArithmetic(20180421170240,Expr);
  3828. end;
  3829. revkFloat:
  3830. // currency ^^ float
  3831. try
  3832. {$Q+}{$R+}
  3833. aCurrency:=Math.power(TResEvalCurrency(LeftValue).Value,TResEvalFloat(RightValue).FloatValue);
  3834. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3835. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3836. Result:=TResEvalCurrency.CreateValue(aCurrency);
  3837. except
  3838. RaiseOverflowArithmetic(20180421170254,Expr);
  3839. end;
  3840. revkCurrency:
  3841. // currency ^^ currency
  3842. try
  3843. {$Q+}{$R+}
  3844. aCurrency:=Math.power(TResEvalCurrency(LeftValue).Value,TResEvalCurrency(RightValue).Value);
  3845. {$IFNDEF OverflowCheckOn}{$Q-}{$ENDIF}
  3846. {$IFNDEF RangeCheckOn}{$R-}{$ENDIF}
  3847. Result:=TResEvalCurrency.CreateValue(aCurrency);
  3848. except
  3849. RaiseOverflowArithmetic(20180421170311,Expr);
  3850. end;
  3851. end;
  3852. else
  3853. {$IFDEF VerbosePasResolver}
  3854. writeln('TResExprEvaluator.EvalBinaryPowerExpr ^^ ?- Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  3855. {$ENDIF}
  3856. RaiseNotYetImplemented(20170816153813,Expr);
  3857. end;
  3858. end;
  3859. function TResExprEvaluator.StringToOrd(Value: TResEvalValue;
  3860. PosEl: TPasElement): longword;
  3861. const
  3862. Invalid = $12345678; // bigger than $ffff and smaller than $8000000
  3863. var
  3864. {$ifdef FPC_HAS_CPSTRING}
  3865. S: RawByteString;
  3866. {$endif}
  3867. U: UnicodeString;
  3868. begin
  3869. case Value.Kind of
  3870. {$ifdef FPC_HAS_CPSTRING}
  3871. revkString:
  3872. begin
  3873. // ord(ansichar)
  3874. S:=TResEvalString(Value).S;
  3875. if length(S)=1 then
  3876. Result:=ord(S[1])
  3877. else if (length(S)=0) or (length(S)>4) then
  3878. begin
  3879. if PosEl<>nil then
  3880. RaiseMsg(20170522221143,nXExpectedButYFound,sXExpectedButYFound,
  3881. ['char','string'],PosEl)
  3882. else
  3883. exit(Invalid);
  3884. end
  3885. else
  3886. begin
  3887. U:=GetUnicodeStr(S,nil);
  3888. if length(U)<>1 then
  3889. begin
  3890. if PosEl<>nil then
  3891. RaiseMsg(20190124180407,nXExpectedButYFound,sXExpectedButYFound,
  3892. ['char','string'],PosEl)
  3893. else
  3894. exit(Invalid);
  3895. end;
  3896. Result:=ord(U[1]);
  3897. end;
  3898. end;
  3899. {$endif}
  3900. revkUnicodeString:
  3901. begin
  3902. // ord(widechar)
  3903. U:=TResEvalUTF16(Value).S;
  3904. if length(U)<>1 then
  3905. begin
  3906. if PosEl<>nil then
  3907. RaiseMsg(20170522221358,nXExpectedButYFound,sXExpectedButYFound,
  3908. ['char','string'],PosEl)
  3909. else
  3910. exit(Invalid);
  3911. end
  3912. else
  3913. Result:=ord(U[1]);
  3914. end;
  3915. else
  3916. RaiseNotYetImplemented(20170522220959,PosEl);
  3917. end;
  3918. end;
  3919. function TResExprEvaluator.EvalPrimitiveExprString(Expr: TPrimitiveExpr
  3920. ): TResEvalValue;
  3921. { Extracts the value from a Pascal string literal
  3922. S is a Pascal string literal e.g. 'Line'#10
  3923. '' empty string
  3924. '''' => "'"
  3925. #decimal
  3926. #$hex
  3927. ^l l is a letter a-z
  3928. }
  3929. procedure RangeError(id: TMaxPrecInt);
  3930. begin
  3931. Result.Free;
  3932. RaiseRangeCheck(id,Expr);
  3933. end;
  3934. procedure Add(h: String);
  3935. begin
  3936. {$ifdef FPC_HAS_CPSTRING}
  3937. if Result.Kind=revkString then
  3938. TResEvalString(Result).S:=TResEvalString(Result).S+h
  3939. else
  3940. TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+GetUnicodeStr(h,Expr);
  3941. {$else}
  3942. TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+h;
  3943. {$endif}
  3944. end;
  3945. procedure AddHash(u: longword; ForceUTF16: boolean);
  3946. {$ifdef FPC_HAS_CPSTRING}
  3947. var
  3948. h: RawByteString;
  3949. begin
  3950. if ((u>255) or (ForceUTF16)) and (Result.Kind=revkString) then
  3951. begin
  3952. // switch to unicodestring
  3953. h:=TResEvalString(Result).S;
  3954. Result.Free;
  3955. Result:=nil; // in case of exception in GetUnicodeStr
  3956. Result:=TResEvalUTF16.CreateValue(GetUnicodeStr(h,Expr));
  3957. end;
  3958. if Result.Kind=revkString then
  3959. TResEvalString(Result).S:=TResEvalString(Result).S+Chr(u)
  3960. else
  3961. TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+WideChar(u);
  3962. end;
  3963. {$else}
  3964. begin
  3965. TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+WideChar(u);
  3966. if ForceUTF16 then ;
  3967. end;
  3968. {$endif}
  3969. var
  3970. p, StartP, l: integer;
  3971. c: Char;
  3972. u: longword;
  3973. S: String;
  3974. begin
  3975. Result:=nil;
  3976. S:=Expr.Value;
  3977. {$IFDEF VerbosePasResEval}
  3978. //writeln('TResExprEvaluator.EvalPrimitiveExprString (',S,')');
  3979. {$ENDIF}
  3980. l:=length(S);
  3981. if l=0 then
  3982. RaiseInternalError(20170523113809);
  3983. {$ifdef FPC_HAS_CPSTRING}
  3984. Result:=TResEvalString.Create;
  3985. {$else}
  3986. Result:=TResEvalUTF16.Create;
  3987. {$endif}
  3988. p:=1;
  3989. while p<=l do
  3990. case S[p] of
  3991. {$ifdef UsePChar}
  3992. #0: break;
  3993. {$endif}
  3994. '''':
  3995. begin
  3996. inc(p);
  3997. StartP:=p;
  3998. repeat
  3999. if p>l then
  4000. RaiseInternalError(20170523113938);
  4001. c:=S[p];
  4002. case c of
  4003. '''':
  4004. begin
  4005. if p>StartP then
  4006. Add(copy(S,StartP,p-StartP));
  4007. inc(p);
  4008. StartP:=p;
  4009. if (p>l) or (S[p]<>'''') then
  4010. break;
  4011. Add('''');
  4012. inc(p);
  4013. StartP:=p;
  4014. end;
  4015. else
  4016. inc(p);
  4017. end;
  4018. until false;
  4019. if p>StartP then
  4020. Add(copy(S,StartP,p-StartP));
  4021. end;
  4022. '#':
  4023. begin
  4024. inc(p);
  4025. if p>l then
  4026. RaiseInternalError(20181016121354);
  4027. if S[p]='$' then
  4028. begin
  4029. // #$hexnumber
  4030. inc(p);
  4031. StartP:=p;
  4032. u:=0;
  4033. while p<=l do
  4034. begin
  4035. c:=S[p];
  4036. case c of
  4037. '0'..'9': u:=u*16+longword(ord(c)-ord('0'));
  4038. 'a'..'f': u:=u*16+longword(ord(c)-ord('a'))+10;
  4039. 'A'..'F': u:=u*16+longword(ord(c)-ord('A'))+10;
  4040. else break;
  4041. end;
  4042. if u>$10FFFF then
  4043. RangeError(20170523115712);
  4044. inc(p);
  4045. end;
  4046. if p=StartP then
  4047. RaiseInternalError(20170207164956);
  4048. if u>$ffff then
  4049. begin
  4050. // split into two
  4051. dec(u,$10000);
  4052. AddHash($D800+(u shr 10),true);
  4053. AddHash($DC00+(u and $3ff),true);
  4054. end
  4055. else
  4056. AddHash(u,p-StartP>2);
  4057. end
  4058. else
  4059. begin
  4060. // #decimalnumber
  4061. StartP:=p;
  4062. u:=0;
  4063. while p<=l do
  4064. begin
  4065. c:=S[p];
  4066. case c of
  4067. '0'..'9': u:=u*10+longword(ord(c)-ord('0'));
  4068. else break;
  4069. end;
  4070. if u>$ffff then
  4071. RangeError(20170523123137);
  4072. inc(p);
  4073. end;
  4074. if p=StartP then
  4075. RaiseInternalError(20170523123806);
  4076. AddHash(u,false);
  4077. end;
  4078. end;
  4079. '^':
  4080. begin
  4081. // ^A is #1
  4082. inc(p);
  4083. if p>l then
  4084. RaiseInternalError(20181016121520);
  4085. c:=S[p];
  4086. case c of
  4087. 'a'..'z': AddHash(ord(c)-ord('a')+1,false);
  4088. 'A'..'Z': AddHash(ord(c)-ord('A')+1,false);
  4089. else RaiseInternalError(20170523123809);
  4090. end;
  4091. inc(p);
  4092. end;
  4093. else
  4094. RaiseNotYetImplemented(20170523123815,Expr,'ord='+IntToStr(ord(S[p])));
  4095. end;
  4096. {$IFDEF VerbosePasResEval}
  4097. //writeln('TResExprEvaluator.EvalPrimitiveExprString Result=',Result.AsString);
  4098. {$ENDIF}
  4099. end;
  4100. function TResExprEvaluator.CreateResEvalInt(UInt: TMaxPrecUInt): TResEvalValue;
  4101. begin
  4102. if UInt<=HighIntAsUInt then
  4103. Result:=TResEvalInt.CreateValue(TMaxPrecInt(UInt))
  4104. else
  4105. Result:=TResEvalUInt.CreateValue(UInt);
  4106. end;
  4107. constructor TResExprEvaluator.Create;
  4108. begin
  4109. inherited Create;
  4110. FAllowedInts:=ReitDefaults;
  4111. {$ifdef FPC_HAS_CPSTRING}
  4112. FDefaultEncoding:=CP_ACP;
  4113. {$endif}
  4114. end;
  4115. function TResExprEvaluator.Eval(Expr: TPasExpr; Flags: TResEvalFlags
  4116. ): TResEvalValue;
  4117. var
  4118. C: TClass;
  4119. Code: integer;
  4120. Int: TMaxPrecInt;
  4121. UInt: TMaxPrecUInt;
  4122. Flo: TMaxPrecFloat;
  4123. begin
  4124. Result:=nil;
  4125. if Expr.CustomData is TResEvalValue then
  4126. begin
  4127. Result:=TResEvalValue(Expr.CustomData);
  4128. exit;
  4129. end;
  4130. {$IFDEF VerbosePasResEval}
  4131. writeln('TResExprEvaluator.Eval Expr=',GetObjName(Expr),' Flags=',dbgs(Flags));
  4132. {$ENDIF}
  4133. if refAutoConst in Flags then
  4134. begin
  4135. Exclude(Flags,refAutoConst);
  4136. if IsConst(Expr) then
  4137. Include(Flags,refConst);
  4138. end;
  4139. if refAutoConstExt in Flags then
  4140. begin
  4141. Exclude(Flags,refAutoConstExt);
  4142. if IsConst(Expr) then
  4143. Include(Flags,refConstExt);
  4144. end;
  4145. C:=Expr.ClassType;
  4146. if C=TPrimitiveExpr then
  4147. begin
  4148. case TPrimitiveExpr(Expr).Kind of
  4149. pekIdent:
  4150. begin
  4151. Result:=OnEvalIdentifier(Self,TPrimitiveExpr(Expr),Flags);
  4152. //writeln('TResExprEvaluator.Eval primitiv result=',Result<>nil,' ',dbgs(Result));
  4153. end;
  4154. pekNumber:
  4155. begin
  4156. // try TMaxPrecInt
  4157. val(TPrimitiveExpr(Expr).Value,Int,Code);
  4158. if Code=0 then
  4159. begin
  4160. {$IFDEF VerbosePasResEval}
  4161. writeln('TResExprEvaluator.Eval Int=',Int,' Value="',TPrimitiveExpr(Expr).Value,'"');
  4162. {$ENDIF}
  4163. if (Int<0) and (Pos('-',TPrimitiveExpr(Expr).Value)<1) then
  4164. // FPC str() converts $8000000000000000 to a negative int64 -> ignore
  4165. else
  4166. begin
  4167. Result:=TResEvalInt.CreateValue(Int);
  4168. exit;
  4169. end;
  4170. end;
  4171. // try TMaxPrecUInt
  4172. val(TPrimitiveExpr(Expr).Value,UInt,Code);
  4173. if Code=0 then
  4174. begin
  4175. Result:=TResEvalUInt.CreateValue(UInt);
  4176. {$IFDEF VerbosePasResEval}
  4177. writeln('TResExprEvaluator.Eval UInt=',UInt,' Value="',TPrimitiveExpr(Expr).Value,'"');
  4178. {$ENDIF}
  4179. exit;
  4180. end;
  4181. // try TMaxPrecFloat
  4182. val(TPrimitiveExpr(Expr).Value,Flo,Code);
  4183. if Code=0 then
  4184. begin
  4185. Result:=TResEvalFloat.CreateValue(Flo);
  4186. {$IFDEF VerbosePasResEval}
  4187. writeln('TResExprEvaluator.Eval Float=',Flo,' Value="',TPrimitiveExpr(Expr).Value,'"');
  4188. {$ENDIF}
  4189. exit;
  4190. end;
  4191. {$IFDEF VerbosePasResEval}
  4192. writeln('TResExprEvaluator.Eval Value="',TPrimitiveExpr(Expr).Value,'"');
  4193. {$ENDIF}
  4194. RaiseRangeCheck(20170518202252,Expr);
  4195. end;
  4196. pekString:
  4197. begin
  4198. Result:=EvalPrimitiveExprString(TPrimitiveExpr(Expr));
  4199. exit;
  4200. end;
  4201. else
  4202. RaiseNotYetImplemented(20170518200951,Expr);
  4203. end;
  4204. {$IFDEF VerbosePasResEval}
  4205. writeln('TResExprEvaluator.Eval primitiv end result=',Result<>nil,' ',dbgs(Result));
  4206. {$ENDIF}
  4207. end
  4208. else if C=TNilExpr then
  4209. Result:=TResEvalValue.CreateKind(revkNil)
  4210. else if C=TBoolConstExpr then
  4211. Result:=TResEvalBool.CreateValue(TBoolConstExpr(Expr).Value)
  4212. else if C=TUnaryExpr then
  4213. Result:=EvalUnaryExpr(TUnaryExpr(Expr),Flags)
  4214. else if C=TBinaryExpr then
  4215. Result:=EvalBinaryExpr(TBinaryExpr(Expr),Flags)
  4216. else if C=TParamsExpr then
  4217. Result:=EvalParamsExpr(TParamsExpr(Expr),Flags)
  4218. else if C=TArrayValues then
  4219. Result:=EvalArrayValuesExpr(TArrayValues(Expr),Flags)
  4220. else if [refConst,refConstExt]*Flags<>[] then
  4221. RaiseConstantExprExp(20170518213800,Expr);
  4222. {$IFDEF VerbosePasResEval}
  4223. writeln('TResExprEvaluator.Eval END ',Expr.ClassName,' result=',Result<>nil,' ',dbgs(Result));
  4224. {$ENDIF}
  4225. end;
  4226. function TResExprEvaluator.IsInRange(Expr, RangeExpr: TPasExpr;
  4227. EmitHints: boolean): boolean;
  4228. var
  4229. Value, RangeValue: TResEvalValue;
  4230. begin
  4231. Value:=Eval(Expr,[refAutoConst]);
  4232. if Value=nil then
  4233. exit(true); // a variable -> ok
  4234. RangeValue:=nil;
  4235. try
  4236. RangeValue:=Eval(RangeExpr,[]);
  4237. if RangeValue=nil then
  4238. RaiseNotYetImplemented(20170522171226,RangeExpr);
  4239. Result:=IsInRange(Value,Expr,RangeValue,RangeExpr,EmitHints);
  4240. finally
  4241. ReleaseEvalValue(Value);
  4242. ReleaseEvalValue(RangeValue);
  4243. end;
  4244. end;
  4245. function TResExprEvaluator.IsInRange(Value: TResEvalValue; ValueExpr: TPasExpr;
  4246. RangeValue: TResEvalValue; RangeExpr: TPasExpr; EmitHints: boolean): boolean;
  4247. var
  4248. RgInt: TResEvalRangeInt;
  4249. RgUInt: TResEvalRangeUInt;
  4250. CharIndex: LongWord;
  4251. begin
  4252. Result:=false;
  4253. {$IFDEF VerbosePasResEval}
  4254. //writeln('TResExprEvaluator.IsInRange Value=',dbgs(Value),' RangeValue=',dbgs(RangeValue));
  4255. {$ENDIF}
  4256. case RangeValue.Kind of
  4257. revkRangeInt:
  4258. begin
  4259. RgInt:=TResEvalRangeInt(RangeValue);
  4260. case RgInt.ElKind of
  4261. revskBool:
  4262. if Value.Kind=revkBool then
  4263. exit(true)
  4264. else
  4265. RaiseNotYetImplemented(20170522220104,ValueExpr);
  4266. revskEnum:
  4267. begin
  4268. if Value.Kind<>revkEnum then
  4269. RaiseInternalError(20170522172754)
  4270. else if TResEvalEnum(Value).ElType<>RgInt.ElType then
  4271. RaiseInternalError(20170522174028)
  4272. else if (TResEvalEnum(Value).Index<RgInt.RangeStart)
  4273. or (TResEvalEnum(Value).Index>RgInt.RangeEnd) then
  4274. begin
  4275. if EmitHints then
  4276. EmitRangeCheckConst(20170522174406,Value.AsString,
  4277. RgInt.ElementAsString(RgInt.RangeStart),
  4278. RgInt.ElementAsString(RgInt.RangeEnd),
  4279. ValueExpr);
  4280. exit(false);
  4281. end
  4282. else
  4283. exit(true);
  4284. end;
  4285. revskInt: // int..int
  4286. if Value.Kind=revkInt then
  4287. begin
  4288. // int in int..int
  4289. if (TResEvalInt(Value).Int<RgInt.RangeStart)
  4290. or (TResEvalInt(Value).Int>RgInt.RangeEnd) then
  4291. begin
  4292. if EmitHints then
  4293. EmitRangeCheckConst(20170522174958,Value.AsString,
  4294. RgInt.ElementAsString(RgInt.RangeStart),
  4295. RgInt.ElementAsString(RgInt.RangeEnd),
  4296. ValueExpr);
  4297. exit(false);
  4298. end
  4299. else
  4300. exit(true);
  4301. end
  4302. else if Value.Kind=revkUInt then
  4303. begin
  4304. // uint in int..int
  4305. if (TResEvalUInt(Value).UInt>HighIntAsUInt)
  4306. or (TMaxPrecInt(TResEvalUInt(Value).UInt)<RgInt.RangeStart)
  4307. or (TMaxPrecInt(TResEvalUInt(Value).UInt)>RgInt.RangeEnd) then
  4308. begin
  4309. if EmitHints then
  4310. EmitRangeCheckConst(20170522215852,Value.AsString,
  4311. RgInt.ElementAsString(RgInt.RangeStart),
  4312. RgInt.ElementAsString(RgInt.RangeEnd),
  4313. ValueExpr);
  4314. exit(false);
  4315. end
  4316. else
  4317. exit(true);
  4318. end
  4319. else
  4320. begin
  4321. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  4322. writeln('TResExprEvaluator.IsInRange Kind=',Value.Kind,' ',Value.AsDebugString);
  4323. {$ENDIF}
  4324. RaiseNotYetImplemented(20170522215906,ValueExpr);
  4325. end;
  4326. revskChar:
  4327. if Value.Kind in revkAllStrings then
  4328. begin
  4329. // string in char..char
  4330. CharIndex:=StringToOrd(Value,ValueExpr);
  4331. if (CharIndex<RgInt.RangeStart) or (CharIndex>RgInt.RangeEnd) then
  4332. begin
  4333. if EmitHints then
  4334. EmitRangeCheckConst(20170522221709,Value.AsString,
  4335. RgInt.ElementAsString(RgInt.RangeStart),
  4336. RgInt.ElementAsString(RgInt.RangeEnd),
  4337. ValueExpr);
  4338. exit(false);
  4339. end
  4340. else
  4341. exit(true);
  4342. end
  4343. else
  4344. RaiseNotYetImplemented(20170522220210,ValueExpr);
  4345. else
  4346. RaiseInternalError(20170522172630);
  4347. end;
  4348. end;
  4349. revkRangeUInt:
  4350. if Value.Kind=revkInt then
  4351. begin
  4352. // int in uint..uint
  4353. RgUInt:=TResEvalRangeUInt(RangeValue);
  4354. if (TResEvalInt(Value).Int<0)
  4355. or (TMaxPrecUInt(TResEvalInt(Value).Int)<RgUInt.RangeStart)
  4356. or (TMaxPrecUInt(TResEvalInt(Value).Int)>RgUInt.RangeEnd) then
  4357. begin
  4358. if EmitHints then
  4359. EmitRangeCheckConst(20170522172250,Value.AsString,
  4360. IntToStr(RgUInt.RangeStart),
  4361. IntToStr(RgUInt.RangeEnd),ValueExpr);
  4362. exit(false);
  4363. end
  4364. else
  4365. exit(true);
  4366. end
  4367. else if Value.Kind=revkUInt then
  4368. begin
  4369. // uint in uint..uint
  4370. RgUInt:=TResEvalRangeUInt(RangeValue);
  4371. if (TResEvalUInt(Value).UInt<RgUInt.RangeStart)
  4372. or (TResEvalUInt(Value).UInt>RgUInt.RangeEnd) then
  4373. begin
  4374. if EmitHints then
  4375. EmitRangeCheckConst(20170522172544,IntToStr(TResEvalUInt(Value).UInt),
  4376. IntToStr(RgUInt.RangeStart),
  4377. IntToStr(RgUInt.RangeEnd),ValueExpr);
  4378. exit(false);
  4379. end
  4380. else
  4381. exit(true);
  4382. end
  4383. else
  4384. begin
  4385. {$IFDEF VerbosePasResEval}
  4386. writeln('TResExprEvaluator.IsInRange Value=',dbgs(Value),' RangeValue=',dbgs(RangeValue));
  4387. {$ENDIF}
  4388. RaiseNotYetImplemented(20170522171551,ValueExpr);
  4389. end;
  4390. else
  4391. {$IFDEF VerbosePasResEval}
  4392. writeln('TResExprEvaluator.IsInRange Value=',dbgs(Value),' RangeValue=',dbgs(RangeValue));
  4393. {$ENDIF}
  4394. RaiseNotYetImplemented(20170522171307,RangeExpr);
  4395. end;
  4396. end;
  4397. function TResExprEvaluator.IsSetCompatible(Value: TResEvalValue;
  4398. ValueExpr: TPasExpr; RangeValue: TResEvalValue; EmitHints: boolean): boolean;
  4399. // checks if Value fits into a set of RangeValue
  4400. var
  4401. RightSet: TResEvalSet;
  4402. LeftRange: TResEvalRangeInt;
  4403. MinVal, MaxVal: TMaxPrecInt;
  4404. begin
  4405. Result:=true;
  4406. case Value.Kind of
  4407. revkSetOfInt:
  4408. begin
  4409. RightSet:=TResEvalSet(Value);
  4410. if RightSet.ElKind=revskNone then
  4411. exit(true); // empty set always fits
  4412. case RangeValue.Kind of
  4413. revkRangeInt:
  4414. begin
  4415. LeftRange:=TResEvalRangeInt(RangeValue);
  4416. if (LeftRange.ElKind<>RightSet.ElKind)
  4417. or (LeftRange.ElType<>RightSet.ElType) then
  4418. begin
  4419. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  4420. writeln('TResExprEvaluator.IsSetCompatible Value=',dbgs(Value),' RangeValue=',dbgs(RangeValue));
  4421. {$ENDIF}
  4422. RaiseNotYetImplemented(20170714201425,ValueExpr);
  4423. end;
  4424. if length(RightSet.Ranges)=0 then
  4425. exit(true); // empty typed set fits
  4426. MinVal:=RightSet.Ranges[0].RangeStart;
  4427. MaxVal:=RightSet.Ranges[length(RightSet.Ranges)-1].RangeEnd;
  4428. {$IFDEF VerbosePasResEval}
  4429. writeln('TResExprEvaluator.IsSetCompatible Value=',dbgs(Value),' MinVal=',MinVal,' MaxVal=',MaxVal,' RangeValue=',dbgs(RangeValue));
  4430. {$ENDIF}
  4431. if (MinVal<LeftRange.RangeStart) then
  4432. if EmitHints then
  4433. EmitRangeCheckConst(20170714202813,RightSet.ElementAsString(MinVal),
  4434. LeftRange.ElementAsString(LeftRange.RangeStart),
  4435. LeftRange.ElementAsString(LeftRange.RangeEnd),ValueExpr,mtError)
  4436. else
  4437. exit(false);
  4438. if (MaxVal>LeftRange.RangeEnd) then
  4439. if EmitHints then
  4440. EmitRangeCheckConst(20170714203134,RightSet.ElementAsString(MaxVal),
  4441. LeftRange.ElementAsString(LeftRange.RangeStart),
  4442. LeftRange.ElementAsString(LeftRange.RangeEnd),ValueExpr,mtError)
  4443. else
  4444. exit(false);
  4445. end;
  4446. else
  4447. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  4448. writeln('TResExprEvaluator.IsSetCompatible Value=',dbgs(Value),' RangeValue=',dbgs(RangeValue));
  4449. {$ENDIF}
  4450. RaiseNotYetImplemented(20170714201121,ValueExpr);
  4451. end;
  4452. end
  4453. else
  4454. {$IF defined(VerbosePasResEval) or defined(VerbosePasResolver)}
  4455. writeln('TResExprEvaluator.IsSetCompatible Value=',Value.Kind,' ',dbgs(RangeValue));
  4456. {$ENDIF}
  4457. RaiseNotYetImplemented(20170714195815,ValueExpr);
  4458. end;
  4459. end;
  4460. function TResExprEvaluator.IsConst(Expr: TPasExpr): boolean;
  4461. var
  4462. El: TPasElement;
  4463. C: TClass;
  4464. begin
  4465. El:=Expr;
  4466. while El<>nil do
  4467. begin
  4468. C:=El.ClassType;
  4469. if C.InheritsFrom(TPasProcedure) then exit(true);
  4470. if C.InheritsFrom(TPasImplBlock) then exit(false);
  4471. El:=El.Parent;
  4472. end;
  4473. Result:=true;
  4474. end;
  4475. function TResExprEvaluator.IsSimpleExpr(Expr: TPasExpr): boolean;
  4476. var
  4477. C: TClass;
  4478. begin
  4479. C:=Expr.ClassType;
  4480. Result:=(C=TNilExpr)
  4481. or (C=TBoolConstExpr)
  4482. or (C=TPrimitiveExpr);
  4483. end;
  4484. procedure TResExprEvaluator.EmitRangeCheckConst(id: TMaxPrecInt; const aValue,
  4485. MinVal, MaxVal: String; PosEl: TPasElement; MsgType: TMessageType);
  4486. begin
  4487. if Assigned(OnRangeCheckEl) then
  4488. OnRangeCheckEl(Self,PosEl,MsgType);
  4489. LogMsg(id,MsgType,nRangeCheckEvaluatingConstantsVMinMax,
  4490. sRangeCheckEvaluatingConstantsVMinMax,[aValue,MinVal,MaxVal],PosEl);
  4491. end;
  4492. procedure TResExprEvaluator.EmitRangeCheckConst(id: TMaxPrecInt;
  4493. const aValue: String; MinVal, MaxVal: TMaxPrecInt; PosEl: TPasElement;
  4494. MsgType: TMessageType);
  4495. begin
  4496. EmitRangeCheckConst(id,aValue,IntToStr(MinVal),IntToStr(MaxVal),PosEl,MsgType);
  4497. end;
  4498. function TResExprEvaluator.ChrValue(Value: TResEvalValue; ErrorEl: TPasElement
  4499. ): TResEvalValue;
  4500. var
  4501. Int: TMaxPrecInt;
  4502. begin
  4503. Result:=nil;
  4504. case Value.Kind of
  4505. revkInt,revkUInt:
  4506. begin
  4507. if Value.Kind=revkUInt then
  4508. begin
  4509. if TResEvalUInt(Value).UInt>$ffff then
  4510. EmitRangeCheckConst(20170711195605,Value.AsString,0,$ffff,ErrorEl,mtError)
  4511. else
  4512. Int:=TResEvalUInt(Value).UInt;
  4513. end
  4514. else
  4515. Int:=TResEvalInt(Value).Int;
  4516. if (Int<0) or (Int>$ffff) then
  4517. EmitRangeCheckConst(20170711195747,Value.AsString,0,$ffff,ErrorEl,mtError);
  4518. {$ifdef FPC_HAS_CPSTRING}
  4519. if Int<=$ff then
  4520. Result:=TResEvalString.CreateValue(chr(Int))
  4521. else
  4522. {$endif}
  4523. Result:=TResEvalUTF16.CreateValue(WideChar(Int))
  4524. end;
  4525. else
  4526. {$IFDEF VerbosePasResEval}
  4527. writeln('TResExprEvaluator.ChrValue ',Value.AsDebugString);
  4528. {$ENDIF}
  4529. RaiseNotYetImplemented(20170711195440,ErrorEl);
  4530. end;
  4531. end;
  4532. function TResExprEvaluator.OrdValue(Value: TResEvalValue; ErrorEl: TPasElement
  4533. ): TResEvalValue;
  4534. var
  4535. v: longword;
  4536. begin
  4537. Result:=nil;
  4538. v:=0;
  4539. case Value.Kind of
  4540. revkBool:
  4541. if TResEvalBool(Value).B then
  4542. v:=1
  4543. else
  4544. v:=0;
  4545. revkInt,revkUInt:
  4546. exit(Value);
  4547. {$ifdef FPC_HAS_CPSTRING}
  4548. revkString,
  4549. {$endif}
  4550. revkUnicodeString:
  4551. v:=StringToOrd(Value,ErrorEl);
  4552. revkEnum:
  4553. v:=TResEvalEnum(Value).Index;
  4554. else
  4555. {$IFDEF VerbosePasResEval}
  4556. writeln('TResExprEvaluator.OrdValue ',Value.AsDebugString);
  4557. {$ENDIF}
  4558. RaiseNotYetImplemented(20170624155932,ErrorEl);
  4559. end;
  4560. if v>$ffff then exit;
  4561. Result:=TResEvalInt.CreateValue(v);
  4562. end;
  4563. procedure TResExprEvaluator.PredValue(Value: TResEvalValue; ErrorEl: TPasElement
  4564. );
  4565. begin
  4566. case Value.Kind of
  4567. revkBool:
  4568. PredBool(TResEvalBool(Value),ErrorEl);
  4569. revkInt:
  4570. PredInt(TResEvalInt(Value),ErrorEl);
  4571. revkUInt:
  4572. PredUInt(TResEvalUInt(Value),ErrorEl);
  4573. {$ifdef FPC_HAS_CPSTRING}
  4574. revkString:
  4575. PredString(TResEvalString(Value),ErrorEl);
  4576. {$endif}
  4577. revkUnicodeString:
  4578. PredUnicodeString(TResEvalUTF16(Value),ErrorEl);
  4579. revkEnum:
  4580. PredEnum(TResEvalEnum(Value),ErrorEl);
  4581. else
  4582. {$IFDEF VerbosePasResEval}
  4583. writeln('TResExprEvaluator.PredValue ',Value.AsDebugString);
  4584. {$ENDIF}
  4585. ReleaseEvalValue(Value);
  4586. RaiseNotYetImplemented(20170624135738,ErrorEl);
  4587. end;
  4588. end;
  4589. procedure TResExprEvaluator.SuccValue(Value: TResEvalValue; ErrorEl: TPasElement
  4590. );
  4591. begin
  4592. case Value.Kind of
  4593. revkBool:
  4594. SuccBool(TResEvalBool(Value),ErrorEl);
  4595. revkInt:
  4596. SuccInt(TResEvalInt(Value),ErrorEl);
  4597. revkUInt:
  4598. SuccUInt(TResEvalUInt(Value),ErrorEl);
  4599. {$ifdef FPC_HAS_CPSTRING}
  4600. revkString:
  4601. SuccString(TResEvalString(Value),ErrorEl);
  4602. {$endif}
  4603. revkUnicodeString:
  4604. SuccUnicodeString(TResEvalUTF16(Value),ErrorEl);
  4605. revkEnum:
  4606. SuccEnum(TResEvalEnum(Value),ErrorEl);
  4607. else
  4608. {$IFDEF VerbosePasResEval}
  4609. writeln('TResExprEvaluator.SuccValue ',Value.AsDebugString);
  4610. {$ENDIF}
  4611. ReleaseEvalValue(Value);
  4612. RaiseNotYetImplemented(20170624151252,ErrorEl);
  4613. end;
  4614. end;
  4615. function TResExprEvaluator.EvalStrFunc(Params: TParamsExpr; Flags: TResEvalFlags
  4616. ): TResEvalValue;
  4617. var
  4618. AllConst: Boolean;
  4619. function EvalFormat(Expr: TPasExpr; MinVal, MaxVal: TMaxPrecInt): TMaxPrecInt;
  4620. var
  4621. Value: TResEvalValue;
  4622. begin
  4623. Value:=Eval(Expr,Flags);
  4624. if Value=nil then
  4625. begin
  4626. AllConst:=false;
  4627. exit(-1);
  4628. end;
  4629. if Value.Kind<>revkInt then
  4630. RaiseNotYetImplemented(20170717144010,Expr);
  4631. Result:=TResEvalInt(Value).Int;
  4632. if (Result<MinVal) or (Result>MaxVal) then
  4633. EmitRangeCheckConst(20170717144609,IntToStr(Result),MinVal,MaxVal,Expr,mtError);
  4634. end;
  4635. var
  4636. i: Integer;
  4637. Param: TPasExpr;
  4638. S, ValStr: String;
  4639. Value: TResEvalValue;
  4640. Format1, Format2: TMaxPrecInt;
  4641. begin
  4642. Result:=nil;
  4643. Value:=nil;
  4644. AllConst:=true;
  4645. S:='';
  4646. for i:=0 to length(Params.Params)-1 do
  4647. begin
  4648. Param:=Params.Params[i];
  4649. {$IFDEF VerbosePasResEval}
  4650. writeln('TPasResolver.BI_StrFunc_OnEval i=',i,' of ',length(Params.Params),' Param=',GetObjName(Param));
  4651. {$ENDIF}
  4652. Value:=Eval(Param,Flags);
  4653. if Value=nil then
  4654. begin
  4655. AllConst:=false;
  4656. continue;
  4657. end;
  4658. Format1:=-1;
  4659. Format2:=-1;
  4660. try
  4661. ValStr:='';
  4662. if Param.format1<>nil then
  4663. begin
  4664. Format1:=EvalFormat(Param.format1,1,255);
  4665. if Format1<0 then
  4666. continue;
  4667. if Param.format2<>nil then
  4668. begin
  4669. Format2:=EvalFormat(Param.format2,0,255);
  4670. if Format2<0 then
  4671. continue;
  4672. end;
  4673. end;
  4674. case Value.Kind of
  4675. revkBool:
  4676. if Format1<0 then
  4677. str(TResEvalBool(Value).B,ValStr)
  4678. else
  4679. str(TResEvalBool(Value).B:Format1,ValStr);
  4680. revkInt:
  4681. if Format1<0 then
  4682. str(TResEvalInt(Value).Int,ValStr)
  4683. else
  4684. str(TResEvalInt(Value).Int:Format1,ValStr);
  4685. revkUInt:
  4686. if Format1<0 then
  4687. str(TResEvalUInt(Value).UInt,ValStr)
  4688. else
  4689. str(TResEvalUInt(Value).UInt:Format1,ValStr);
  4690. revkFloat:
  4691. if Format1<0 then
  4692. str(TResEvalFloat(Value).FloatValue,ValStr)
  4693. else if Format2<0 then
  4694. str(TResEvalFloat(Value).FloatValue:Format1,ValStr)
  4695. else
  4696. str(TResEvalFloat(Value).FloatValue:Format1:Format2,ValStr);
  4697. revkCurrency:
  4698. if Format1<0 then
  4699. str(TResEvalCurrency(Value).Value,ValStr)
  4700. else if Format2<0 then
  4701. str(TResEvalCurrency(Value).Value:Format1,ValStr)
  4702. else
  4703. str(TResEvalCurrency(Value).Value:Format1:Format2,ValStr);
  4704. revkEnum:
  4705. begin
  4706. ValStr:=TResEvalEnum(Value).AsString;
  4707. if Format1>0 then
  4708. ValStr:=StringOfChar(' ',Format1)+ValStr;
  4709. end;
  4710. else
  4711. AllConst:=false;
  4712. continue;
  4713. end;
  4714. finally
  4715. ReleaseEvalValue(Value);
  4716. ReleaseEvalValue(Value);
  4717. ReleaseEvalValue(Value);
  4718. end;
  4719. S:=S+ValStr;
  4720. end;
  4721. if AllConst then
  4722. {$ifdef FPC_HAS_CPSTRING}
  4723. Result:=TResEvalString.CreateValue(S);
  4724. {$else}
  4725. Result:=TResEvalUTF16.CreateValue(S);
  4726. {$endif}
  4727. end;
  4728. function TResExprEvaluator.EvalStringAddExpr(Expr, LeftExpr,
  4729. RightExpr: TPasExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
  4730. {$ifdef FPC_HAS_CPSTRING}
  4731. var
  4732. LeftCP, RightCP: TSystemCodePage;
  4733. {$endif}
  4734. begin
  4735. case LeftValue.Kind of
  4736. {$ifdef FPC_HAS_CPSTRING}
  4737. revkString:
  4738. case RightValue.Kind of
  4739. revkString:
  4740. begin
  4741. LeftCP:=GetCodePage(TResEvalString(LeftValue).S);
  4742. RightCP:=GetCodePage(TResEvalString(RightValue).S);
  4743. if (LeftCP=RightCP) then
  4744. begin
  4745. Result:=TResEvalString.Create;
  4746. TResEvalString(Result).S:=TResEvalString(LeftValue).S+TResEvalString(RightValue).S;
  4747. end
  4748. else
  4749. begin
  4750. Result:=TResEvalUTF16.Create;
  4751. TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,LeftExpr)
  4752. +GetUnicodeStr(TResEvalString(RightValue).S,RightExpr);
  4753. end;
  4754. end;
  4755. revkUnicodeString:
  4756. begin
  4757. Result:=TResEvalUTF16.Create;
  4758. TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,LeftExpr)
  4759. +TResEvalUTF16(RightValue).S;
  4760. end;
  4761. else
  4762. {$IFDEF VerbosePasResolver}
  4763. writeln('TResExprEvaluator.EvalBinaryAddExpr string+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  4764. {$ENDIF}
  4765. RaiseNotYetImplemented(20170601141834,Expr);
  4766. end;
  4767. {$endif}
  4768. revkUnicodeString:
  4769. case RightValue.Kind of
  4770. {$ifdef FPC_HAS_CPSTRING}
  4771. revkString:
  4772. begin
  4773. Result:=TResEvalUTF16.Create;
  4774. TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S
  4775. +GetUnicodeStr(TResEvalString(RightValue).S,RightExpr);
  4776. end;
  4777. {$endif}
  4778. revkUnicodeString:
  4779. begin
  4780. Result:=TResEvalUTF16.Create;
  4781. TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S+TResEvalUTF16(RightValue).S;
  4782. end;
  4783. else
  4784. {$IFDEF VerbosePasResolver}
  4785. writeln('TResExprEvaluator.EvalBinaryAddExpr utf16+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
  4786. {$ENDIF}
  4787. RaiseNotYetImplemented(20170601141811,Expr);
  4788. end;
  4789. else
  4790. {$ifndef FPC_HAS_CPSTRING}
  4791. if LeftExpr=nil then ; // no Parameter "LeftExpr" not used
  4792. if RightExpr=nil then ; // no Parameter "RightExpr" not used
  4793. {$endif}
  4794. RaiseNotYetImplemented(20181219233139,Expr);
  4795. end;
  4796. end;
  4797. function TResExprEvaluator.LoHiValue(Value: TResEvalValue; ShiftSize: Integer;
  4798. Mask: LongWord; ErrorEl: TPasElement): TResEvalValue;
  4799. var
  4800. uint: LongWord;
  4801. begin
  4802. case Value.Kind of
  4803. revkInt:
  4804. {$IFDEF Pas2js}
  4805. if ShiftSize=32 then
  4806. uint := longword(TResEvalInt(Value).Int div $100000000)
  4807. else
  4808. {$ENDIF}
  4809. uint := (TResEvalInt(Value).Int shr ShiftSize) and Mask;
  4810. revkUInt:
  4811. {$IFDEF Pas2js}
  4812. if ShiftSize=32 then
  4813. uint := longword(TResEvalUInt(Value).UInt div $100000000)
  4814. else
  4815. {$ENDIF}
  4816. uint := (TResEvalUInt(Value).UInt shr ShiftSize) and Mask;
  4817. else
  4818. {$IFDEF VerbosePasResEval}
  4819. writeln('TResExprEvaluator.LoHiValue ',Value.AsDebugString);
  4820. {$ENDIF}
  4821. RaiseNotYetImplemented(20190129012100,ErrorEl);
  4822. end;
  4823. Result := TResEvalInt.CreateValue(uint);
  4824. end;
  4825. function TResExprEvaluator.EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
  4826. Flags: TResEvalFlags): TResEvalEnum;
  4827. var
  4828. Value: TResEvalValue;
  4829. MaxIndex, Index: Integer;
  4830. begin
  4831. Result:=nil;
  4832. Value:=Eval(Expr,Flags);
  4833. if Value=nil then exit;
  4834. try
  4835. MaxIndex:=EnumType.Values.Count-1;
  4836. case Value.Kind of
  4837. revkInt:
  4838. if TResEvalInt(Value).Int>High(Index) then
  4839. EmitRangeCheckConst(20170713105944,
  4840. IntToStr(TResEvalInt(Value).Int),'0',IntToStr(MaxIndex),Expr,mtError)
  4841. else
  4842. Index:=TResEvalInt(Value).Int;
  4843. revkUInt:
  4844. if TResEvalUInt(Value).UInt>MaxIndex then
  4845. EmitRangeCheckConst(20170713105944,
  4846. IntToStr(TResEvalUInt(Value).UInt),'0',IntToStr(MaxIndex),Expr,mtError)
  4847. else
  4848. Index:=TResEvalUInt(Value).UInt;
  4849. else
  4850. RaiseNotYetImplemented(20170713105625,Expr);
  4851. end;
  4852. if (Index<0) or (Index>MaxIndex) then
  4853. EmitRangeCheckConst(20170713110232,
  4854. IntToStr(Index),'0',IntToStr(MaxIndex),Expr,mtError);
  4855. Result:=TResEvalEnum.CreateValue(Index,TPasEnumValue(EnumType.Values[Index]));
  4856. finally
  4857. ReleaseEvalValue(Value);
  4858. end;
  4859. end;
  4860. {$ifdef FPC_HAS_CPSTRING}
  4861. function TResExprEvaluator.CheckValidUTF8(const s: RawByteString;
  4862. ErrorEl: TPasElement): boolean;
  4863. var
  4864. p, EndP: PChar;
  4865. l: SizeInt;
  4866. begin
  4867. p:=PChar(s);
  4868. EndP:=p+length(s);
  4869. while p<EndP do
  4870. begin
  4871. l:=Utf8CodePointLen(p,EndP-p,false);
  4872. if l<=0 then
  4873. if ErrorEl<>nil then
  4874. RaiseMsg(20170711211841,nIllegalChar,sIllegalChar,[],ErrorEl)
  4875. else
  4876. exit(false);
  4877. inc(p,l);
  4878. end;
  4879. Result:=true;
  4880. end;
  4881. function TResExprEvaluator.GetCodePage(const s: RawByteString): TSystemCodePage;
  4882. begin
  4883. if s='' then exit(DefaultStringCodePage);
  4884. Result:=StringCodePage(s);
  4885. if (Result=CP_ACP) or (Result=CP_NONE) then
  4886. begin
  4887. Result:=DefaultStringCodePage;
  4888. if (Result=CP_ACP) or (Result=CP_NONE) then
  4889. begin
  4890. Result:=System.DefaultSystemCodePage;
  4891. if Result=CP_NONE then
  4892. Result:=CP_ACP;
  4893. end;
  4894. end;
  4895. end;
  4896. function TResExprEvaluator.GetRawByteString(const s: UnicodeString;
  4897. CodePage: TSystemCodePage; ErrorEl: TPasElement): RawByteString;
  4898. var
  4899. ok: Boolean;
  4900. begin
  4901. Result:=UTF8Encode(s);
  4902. if (CodePage=CP_UTF8)
  4903. or ((DefaultSystemCodePage=CP_UTF8) and ((CodePage=CP_ACP) or (CodePage=CP_NONE))) then
  4904. begin
  4905. // to UTF-8
  4906. SetCodePage(Result,CodePage,false);
  4907. end
  4908. else
  4909. begin
  4910. // to non UTF-8 -> possible loss
  4911. ok:=false;
  4912. try
  4913. SetCodePage(Result,CodePage,true);
  4914. ok:=true;
  4915. except
  4916. end;
  4917. if (not ok) or (GetUnicodeStr(Result,ErrorEl)<>s) then
  4918. LogMsg(20190204165110,mtWarning,nImplictConversionUnicodeToAnsi,
  4919. sImplictConversionUnicodeToAnsi,[],ErrorEl);
  4920. end;
  4921. end;
  4922. function TResExprEvaluator.GetUTF8Str(const s: RawByteString;
  4923. ErrorEl: TPasElement): String;
  4924. var
  4925. CP: TSystemCodePage;
  4926. begin
  4927. if s='' then exit('');
  4928. CP:=GetCodePage(s);
  4929. if CP=CP_UTF8 then
  4930. begin
  4931. if ErrorEl<>nil then
  4932. CheckValidUTF8(s,ErrorEl);
  4933. Result:=s;
  4934. end
  4935. else
  4936. // use default conversion
  4937. Result:=UTF8Encode(UnicodeString(s));
  4938. end;
  4939. function TResExprEvaluator.GetUnicodeStr(const s: RawByteString;
  4940. ErrorEl: TPasElement): UnicodeString;
  4941. var
  4942. CP: TSystemCodePage;
  4943. begin
  4944. if s='' then exit('');
  4945. CP:=GetCodePage(s);
  4946. if CP=CP_UTF8 then
  4947. begin
  4948. if ErrorEl<>nil then
  4949. CheckValidUTF8(s,ErrorEl);
  4950. Result:=UTF8Decode(s);
  4951. end
  4952. else
  4953. // use default conversion
  4954. Result:=UnicodeString(s);
  4955. end;
  4956. function TResExprEvaluator.GetWideChar(const s: RawByteString; out w: WideChar
  4957. ): boolean;
  4958. var
  4959. CP: TSystemCodePage;
  4960. u: UnicodeString;
  4961. begin
  4962. w:=#0;
  4963. Result:=false;
  4964. if s='' then exit;
  4965. CP:=GetCodePage(s);
  4966. if CP=CP_UTF8 then
  4967. begin
  4968. if length(s)>4 then exit;
  4969. u:=UTF8Decode(s);
  4970. if length(u)<>1 then exit;
  4971. w:=u[1];
  4972. Result:=true;
  4973. end
  4974. else if length(s)=1 then
  4975. begin
  4976. w:=s[1];
  4977. Result:=true;
  4978. end;
  4979. end;
  4980. {$endif}
  4981. procedure TResExprEvaluator.PredBool(Value: TResEvalBool; ErrorEl: TPasElement);
  4982. begin
  4983. if Value.B=false then
  4984. EmitRangeCheckConst(20170624140251,Value.AsString,
  4985. 'true','true',ErrorEl);
  4986. Value.B:=not Value.B;
  4987. end;
  4988. procedure TResExprEvaluator.SuccBool(Value: TResEvalBool; ErrorEl: TPasElement);
  4989. begin
  4990. if Value.B=true then
  4991. EmitRangeCheckConst(20170624142316,Value.AsString,
  4992. 'false','false',ErrorEl);
  4993. Value.B:=not Value.B;
  4994. end;
  4995. procedure TResExprEvaluator.PredInt(Value: TResEvalInt; ErrorEl: TPasElement);
  4996. begin
  4997. if Value.Int=low(TMaxPrecInt) then
  4998. begin
  4999. EmitRangeCheckConst(20170624142511,IntToStr(Value.Int),
  5000. IntToStr(succ(low(TMaxPrecInt))),IntToStr(high(TMaxPrecInt)),ErrorEl);
  5001. Value.Int:=high(Value.Int);
  5002. end
  5003. else
  5004. dec(Value.Int);
  5005. end;
  5006. procedure TResExprEvaluator.SuccInt(Value: TResEvalInt; ErrorEl: TPasElement);
  5007. begin
  5008. if Value.Int=high(TMaxPrecInt) then
  5009. begin
  5010. EmitRangeCheckConst(20170624142920,IntToStr(Value.Int),
  5011. IntToStr(low(TMaxPrecInt)),IntToStr(pred(high(TMaxPrecInt))),ErrorEl);
  5012. Value.Int:=low(Value.Int);
  5013. end
  5014. else
  5015. inc(Value.Int);
  5016. end;
  5017. procedure TResExprEvaluator.PredUInt(Value: TResEvalUInt; ErrorEl: TPasElement);
  5018. begin
  5019. if Value.UInt=low(TMaxPrecUInt) then
  5020. begin
  5021. EmitRangeCheckConst(20170624143122,IntToStr(Value.UInt),
  5022. IntToStr(succ(low(TMaxPrecUInt))),IntToStr(high(TMaxPrecUInt)),ErrorEl);
  5023. Value.UInt:=high(Value.UInt);
  5024. end
  5025. else
  5026. dec(Value.UInt);
  5027. end;
  5028. procedure TResExprEvaluator.SuccUInt(Value: TResEvalUInt; ErrorEl: TPasElement);
  5029. begin
  5030. // Note: when FPC compares int64 with qword it converts the qword to an int64
  5031. if Value.UInt=HighIntAsUInt then
  5032. begin
  5033. EmitRangeCheckConst(20170624142921,IntToStr(Value.UInt),
  5034. IntToStr(low(TMaxPrecUInt)),IntToStr(pred(high(TMaxPrecUInt))),ErrorEl);
  5035. Value.UInt:=low(Value.UInt);
  5036. end
  5037. else
  5038. inc(Value.UInt);
  5039. end;
  5040. {$ifdef FPC_HAS_CPSTRING}
  5041. procedure TResExprEvaluator.PredString(Value: TResEvalString;
  5042. ErrorEl: TPasElement);
  5043. begin
  5044. if length(Value.S)<>1 then
  5045. RaiseRangeCheck(20170624150138,ErrorEl);
  5046. if Value.S[1]=#0 then
  5047. begin
  5048. EmitRangeCheckConst(20170624150220,Value.AsString,'#1','#255',ErrorEl);
  5049. Value.S:=#255;
  5050. end
  5051. else
  5052. Value.S:=pred(Value.S[1]);
  5053. end;
  5054. procedure TResExprEvaluator.SuccString(Value: TResEvalString;
  5055. ErrorEl: TPasElement);
  5056. begin
  5057. if length(Value.S)<>1 then
  5058. RaiseRangeCheck(20170624150432,ErrorEl);
  5059. if Value.S[1]=#255 then
  5060. begin
  5061. EmitRangeCheckConst(20170624150441,Value.AsString,'#0','#254',ErrorEl);
  5062. Value.S:=#0;
  5063. end
  5064. else
  5065. Value.S:=succ(Value.S[1]);
  5066. end;
  5067. {$endif}
  5068. procedure TResExprEvaluator.PredUnicodeString(Value: TResEvalUTF16;
  5069. ErrorEl: TPasElement);
  5070. begin
  5071. if length(Value.S)<>1 then
  5072. RaiseRangeCheck(20170624150703,ErrorEl);
  5073. if Value.S[1]=#0 then
  5074. begin
  5075. EmitRangeCheckConst(20170624150710,Value.AsString,'#1','#65535',ErrorEl);
  5076. Value.S:=WideChar(#65535);
  5077. end
  5078. else
  5079. Value.S:=pred(Value.S[1]);
  5080. end;
  5081. procedure TResExprEvaluator.SuccUnicodeString(Value: TResEvalUTF16;
  5082. ErrorEl: TPasElement);
  5083. begin
  5084. if length(Value.S)<>1 then
  5085. RaiseRangeCheck(20170624150849,ErrorEl);
  5086. if Value.S[1]=#65535 then
  5087. begin
  5088. EmitRangeCheckConst(20170624150910,Value.AsString,'#0','#65534',ErrorEl);
  5089. Value.S:=#0;
  5090. end
  5091. else
  5092. Value.S:=succ(Value.S[1]);
  5093. end;
  5094. procedure TResExprEvaluator.PredEnum(Value: TResEvalEnum; ErrorEl: TPasElement);
  5095. var
  5096. EnumType: TPasEnumType;
  5097. begin
  5098. EnumType:=Value.ElType as TPasEnumType;
  5099. if EnumType=nil then
  5100. RaiseInternalError(20170821174038,dbgs(Value));
  5101. if Value.Index<=0 then
  5102. begin
  5103. EmitRangeCheckConst(20170624144332,Value.AsString,
  5104. TPasEnumValue(EnumType.Values[Min(1,EnumType.Values.Count-1)]).Name,
  5105. TPasEnumValue(EnumType.Values[EnumType.Values.Count-1]).Name,ErrorEl);
  5106. Value.Index:=EnumType.Values.Count-1;
  5107. end
  5108. else
  5109. dec(Value.Index);
  5110. Value.IdentEl:=TPasEnumValue(EnumType.Values[Value.Index]);
  5111. end;
  5112. procedure TResExprEvaluator.SuccEnum(Value: TResEvalEnum; ErrorEl: TPasElement);
  5113. var
  5114. EnumType: TPasEnumType;
  5115. begin
  5116. EnumType:=Value.ElType as TPasEnumType;
  5117. if EnumType=nil then
  5118. RaiseInternalError(20170821174058,dbgs(Value));
  5119. if Value.Index>=EnumType.Values.Count-1 then
  5120. begin
  5121. EmitRangeCheckConst(20170624145013,Value.AsString,
  5122. TPasEnumValue(EnumType.Values[0]).Name,
  5123. TPasEnumValue(EnumType.Values[Max(0,EnumType.Values.Count-2)]).Name,ErrorEl);
  5124. Value.Index:=0;
  5125. end
  5126. else
  5127. inc(Value.Index);
  5128. Value.IdentEl:=TPasEnumValue(EnumType.Values[Value.Index]);
  5129. end;
  5130. { TResolveData }
  5131. procedure TResolveData.SetElement(AValue: TPasElement);
  5132. begin
  5133. if FElement=AValue then Exit;
  5134. if Element<>nil then
  5135. Element.Release{$IFDEF CheckPasTreeRefCount}(ClassName+'.SetElement'){$ENDIF};
  5136. FElement:=AValue;
  5137. if Element<>nil then
  5138. Element.AddRef{$IFDEF CheckPasTreeRefCount}(ClassName+'.SetElement'){$ENDIF};
  5139. end;
  5140. constructor TResolveData.Create;
  5141. begin
  5142. end;
  5143. destructor TResolveData.Destroy;
  5144. begin
  5145. {$IFDEF VerbosePasResolverMem}
  5146. writeln('TResolveData.Destroy START ',ClassName);
  5147. {$ENDIF}
  5148. Element:=nil;
  5149. Owner:=nil;
  5150. Next:=nil;
  5151. inherited Destroy;
  5152. {$IFDEF VerbosePasResolverMem}
  5153. writeln('TResolveData.Destroy END ',ClassName);
  5154. {$ENDIF}
  5155. end;
  5156. { TResEvalValue }
  5157. constructor TResEvalValue.CreateKind(const aKind: TREVKind);
  5158. begin
  5159. Create;
  5160. Kind:=aKind;
  5161. end;
  5162. function TResEvalValue.Clone: TResEvalValue;
  5163. begin
  5164. Result:=TResEvalValueClass(ClassType).Create;
  5165. Result.Kind:=Kind;
  5166. Result.IdentEl:=IdentEl;
  5167. end;
  5168. function TResEvalValue.AsDebugString: string;
  5169. begin
  5170. str(Kind,Result);
  5171. Result:=Result+'='+AsString;
  5172. end;
  5173. function TResEvalValue.AsString: string;
  5174. begin
  5175. case Kind of
  5176. revkNone: Result:='<None>';
  5177. revkNil: Result:='nil';
  5178. else
  5179. str(Kind,Result);
  5180. end;
  5181. end;
  5182. { TResEvalUInt }
  5183. constructor TResEvalUInt.Create;
  5184. begin
  5185. inherited Create;
  5186. Kind:=revkUInt;
  5187. end;
  5188. constructor TResEvalUInt.CreateValue(const aValue: TMaxPrecUInt);
  5189. begin
  5190. Create;
  5191. UInt:=aValue;
  5192. end;
  5193. function TResEvalUInt.Clone: TResEvalValue;
  5194. begin
  5195. Result:=inherited Clone;
  5196. TResEvalUInt(Result).UInt:=UInt;
  5197. end;
  5198. function TResEvalUInt.AsString: string;
  5199. begin
  5200. Result:=IntToStr(UInt);
  5201. end;
  5202. { TResEvalInt }
  5203. constructor TResEvalInt.Create;
  5204. begin
  5205. inherited Create;
  5206. Kind:=revkInt;
  5207. end;
  5208. constructor TResEvalInt.CreateValue(const aValue: TMaxPrecInt);
  5209. begin
  5210. Create;
  5211. Int:=aValue;
  5212. end;
  5213. constructor TResEvalInt.CreateValue(const aValue: TMaxPrecInt; aTyped: TResEvalTypedInt
  5214. );
  5215. begin
  5216. Create;
  5217. Int:=aValue;
  5218. Typed:=aTyped;
  5219. end;
  5220. function TResEvalInt.Clone: TResEvalValue;
  5221. begin
  5222. Result:=inherited Clone;
  5223. TResEvalInt(Result).Int:=Int;
  5224. TResEvalInt(Result).Typed:=Typed;
  5225. end;
  5226. function TResEvalInt.AsString: string;
  5227. begin
  5228. Result:=IntToStr(Int);
  5229. end;
  5230. function TResEvalInt.AsDebugString: string;
  5231. begin
  5232. if Typed=reitNone then
  5233. Result:=inherited AsDebugString
  5234. else
  5235. begin
  5236. str(Kind,Result);
  5237. case Typed of
  5238. reitByte: Result:=Result+':byte';
  5239. reitShortInt: Result:=Result+':shortint';
  5240. reitWord: Result:=Result+':word';
  5241. reitSmallInt: Result:=Result+':smallint';
  5242. reitUIntSingle: Result:=Result+':uintsingle';
  5243. reitIntSingle: Result:=Result+':intsingle';
  5244. reitLongWord: Result:=Result+':longword';
  5245. reitLongInt: Result:=Result+':longint';
  5246. reitUIntDouble: Result:=Result+':uintdouble';
  5247. reitIntDouble: Result:=Result+':intdouble';
  5248. end;
  5249. Result:=Result+'='+AsString;
  5250. end;
  5251. end;
  5252. { TResEvalFloat }
  5253. constructor TResEvalFloat.Create;
  5254. begin
  5255. inherited Create;
  5256. Kind:=revkFloat;
  5257. end;
  5258. constructor TResEvalFloat.CreateValue(const aValue: TMaxPrecFloat);
  5259. begin
  5260. Create;
  5261. FloatValue:=aValue;
  5262. end;
  5263. function TResEvalFloat.Clone: TResEvalValue;
  5264. begin
  5265. Result:=inherited Clone;
  5266. TResEvalFloat(Result).FloatValue:=FloatValue;
  5267. end;
  5268. function TResEvalFloat.AsString: string;
  5269. begin
  5270. str(FloatValue,Result);
  5271. end;
  5272. function TResEvalFloat.IsInt(out Int: TMaxPrecInt): boolean;
  5273. begin
  5274. Int:=0;
  5275. if Frac(FloatValue)<>0 then exit(false);
  5276. if FloatValue<TMaxPrecFloat(low(TMaxPrecInt)) then exit(false);
  5277. if FloatValue>TMaxPrecFloat(high(TMaxPrecInt)) then exit(false);
  5278. Int:=Trunc(FloatValue);
  5279. Result:=true;
  5280. end;
  5281. {$ifdef FPC_HAS_CPSTRING}
  5282. { TResEvalString }
  5283. constructor TResEvalString.Create;
  5284. begin
  5285. inherited Create;
  5286. Kind:=revkString;
  5287. end;
  5288. constructor TResEvalString.CreateValue(const aValue: RawByteString);
  5289. begin
  5290. Create;
  5291. S:=aValue;
  5292. end;
  5293. function TResEvalString.Clone: TResEvalValue;
  5294. begin
  5295. Result:=inherited Clone;
  5296. TResEvalString(Result).S:=S;
  5297. end;
  5298. function TResEvalString.AsString: string;
  5299. begin
  5300. Result:=RawStrToCaption(S,60);
  5301. end;
  5302. {$endif}
  5303. { TResEvalUTF16 }
  5304. constructor TResEvalUTF16.Create;
  5305. begin
  5306. inherited Create;
  5307. Kind:=revkUnicodeString;
  5308. end;
  5309. constructor TResEvalUTF16.CreateValue(const aValue: UnicodeString);
  5310. begin
  5311. Create;
  5312. S:=aValue;
  5313. end;
  5314. function TResEvalUTF16.Clone: TResEvalValue;
  5315. begin
  5316. Result:=inherited Clone;
  5317. TResEvalUTF16(Result).S:=S;
  5318. end;
  5319. function TResEvalUTF16.AsString: string;
  5320. begin
  5321. Result:=String(UnicodeStrToCaption(S,60));
  5322. end;
  5323. { TResEvalEnum }
  5324. constructor TResEvalEnum.Create;
  5325. begin
  5326. inherited Create;
  5327. Kind:=revkEnum;
  5328. end;
  5329. constructor TResEvalEnum.CreateValue(const aValue: integer;
  5330. aIdentEl: TPasEnumValue);
  5331. begin
  5332. Create;
  5333. Index:=aValue;
  5334. IdentEl:=aIdentEl;
  5335. ElType:=IdentEl.Parent as TPasEnumType;
  5336. if ElType=nil then
  5337. raise Exception.Create('');
  5338. end;
  5339. function TResEvalEnum.GetEnumValue: TPasEnumValue;
  5340. begin
  5341. Result:=nil;
  5342. if ElType<>nil then
  5343. if (Index>=0) and (Index<ElType.Values.Count) then
  5344. Result:=TObject(ElType.Values[Index]) as TPasEnumValue;
  5345. end;
  5346. function TResEvalEnum.GetEnumName: String;
  5347. var
  5348. V: TPasEnumValue;
  5349. begin
  5350. V:=GetEnumValue;
  5351. if V<>nil then
  5352. Result:=V.Name
  5353. else
  5354. Result:='';
  5355. end;
  5356. function TResEvalEnum.Clone: TResEvalValue;
  5357. begin
  5358. Result:=inherited Clone;
  5359. TResEvalEnum(Result).Index:=Index;
  5360. TResEvalEnum(Result).ElType:=ElType;
  5361. end;
  5362. function TResEvalEnum.AsDebugString: string;
  5363. begin
  5364. str(Kind,Result);
  5365. Result:=Result+'='+AsString+'='+IntToStr(Index);
  5366. end;
  5367. function TResEvalEnum.AsString: string;
  5368. begin
  5369. if IdentEl<>nil then
  5370. begin
  5371. Result:=IdentEl.Name;
  5372. if Result<>'' then exit;
  5373. end;
  5374. Result:=GetEnumName;
  5375. if Result<>'' then exit;
  5376. Result:=ElType.Name+'('+IntToStr(Index)+')';
  5377. end;
  5378. { TResEvalRangeInt }
  5379. constructor TResEvalRangeInt.Create;
  5380. begin
  5381. inherited Create;
  5382. Kind:=revkRangeInt;
  5383. end;
  5384. constructor TResEvalRangeInt.CreateValue(const aElKind: TRESetElKind;
  5385. aElType: TPasType; const aRangeStart, aRangeEnd: TMaxPrecInt);
  5386. begin
  5387. Create;
  5388. ElKind:=aElKind;
  5389. ElType:=aElType;
  5390. RangeStart:=aRangeStart;
  5391. RangeEnd:=aRangeEnd;
  5392. end;
  5393. function TResEvalRangeInt.Clone: TResEvalValue;
  5394. begin
  5395. Result:=inherited Clone;
  5396. TResEvalRangeInt(Result).ElKind:=ElKind;
  5397. TResEvalRangeInt(Result).RangeStart:=RangeStart;
  5398. TResEvalRangeInt(Result).RangeEnd:=RangeEnd;
  5399. end;
  5400. function TResEvalRangeInt.AsString: string;
  5401. begin
  5402. Result:=ElementAsString(RangeStart)+'..'+ElementAsString(RangeEnd);
  5403. end;
  5404. function TResEvalRangeInt.AsDebugString: string;
  5405. var
  5406. s: string;
  5407. begin
  5408. str(Kind,Result);
  5409. str(ElKind,s);
  5410. Result:=Result+'/'+s+':'+GetObjName(ElType)+'='+AsString;
  5411. end;
  5412. function TResEvalRangeInt.ElementAsString(El: TMaxPrecInt): string;
  5413. var
  5414. EnumValue: TPasEnumValue;
  5415. EnumType: TPasEnumType;
  5416. begin
  5417. case ElKind of
  5418. revskBool:
  5419. if El=0 then
  5420. Result:='false'
  5421. else
  5422. Result:='true';
  5423. revskEnum:
  5424. begin
  5425. EnumType:=ElType as TPasEnumType;
  5426. if (El>=0) and (El<EnumType.Values.Count) then
  5427. begin
  5428. EnumValue:=TPasEnumValue(EnumType.Values[El]);
  5429. Result:=EnumValue.Name;
  5430. end
  5431. else
  5432. Result:=ElType.Name+'('+IntToStr(El)+')';
  5433. end;
  5434. revskInt: Result:=IntToStr(El);
  5435. revskChar:
  5436. if ((El>=32) and (El<=38)) or ((El>=40) and (El<=126)) then
  5437. Result:=''''+Chr(El)+''''
  5438. else
  5439. Result:='#'+IntToStr(El);
  5440. end;
  5441. end;
  5442. { TResEvalSet }
  5443. constructor TResEvalSet.Create;
  5444. begin
  5445. inherited Create;
  5446. Kind:=revkSetOfInt;
  5447. end;
  5448. constructor TResEvalSet.CreateEmpty(const aElKind: TRESetElKind;
  5449. aElType: TPasType);
  5450. begin
  5451. Create;
  5452. ElKind:=aElKind;
  5453. ElType:=aElType;
  5454. end;
  5455. constructor TResEvalSet.CreateEmptySameKind(aSet: TResEvalSet);
  5456. begin
  5457. Create;
  5458. IdentEl:=aSet.IdentEl;
  5459. ElKind:=aSet.ElKind;
  5460. ElType:=aSet.ElType;
  5461. end;
  5462. constructor TResEvalSet.CreateValue(const aElKind: TRESetElKind;
  5463. aElType: TPasType; const aRangeStart, aRangeEnd: TMaxPrecInt);
  5464. begin
  5465. inherited CreateValue(aElKind, aElType, aRangeStart, aRangeEnd);
  5466. Add(aRangeStart,aRangeEnd);
  5467. end;
  5468. function TResEvalSet.Clone: TResEvalValue;
  5469. var
  5470. RS: TResEvalSet;
  5471. i: Integer;
  5472. begin
  5473. Result:=inherited Clone;
  5474. RS:=TResEvalSet(Result);
  5475. RS.ElKind:=ElKind;
  5476. RS.ElType:=ElType;
  5477. SetLength(RS.Ranges,length(Ranges));
  5478. for i:=0 to length(Ranges)-1 do
  5479. RS.Ranges[i]:=Ranges[i];
  5480. end;
  5481. function TResEvalSet.AsString: string;
  5482. var
  5483. i: Integer;
  5484. begin
  5485. Result:='[';
  5486. for i:=0 to length(Ranges)-1 do
  5487. begin
  5488. if i>0 then Result:=Result+',';
  5489. Result:=Result+ElementAsString(Ranges[i].RangeStart);
  5490. if Ranges[i].RangeStart<>Ranges[i].RangeEnd then
  5491. Result:=Result+'..'+ElementAsString(Ranges[i].RangeEnd);
  5492. end;
  5493. Result:=Result+']';
  5494. end;
  5495. function TResEvalSet.Add(aRangeStart, aRangeEnd: TMaxPrecInt): boolean;
  5496. {$IF FPC_FULLVERSION<30101}
  5497. procedure Insert(const Item: TItem; var Items: TItems; Index: integer);
  5498. var
  5499. i: Integer;
  5500. begin
  5501. Setlength(Items,length(Items)+1);
  5502. for i:=length(Items)-1 downto Index+1 do
  5503. Items[i]:=Items[i-1];
  5504. Items[Index]:=Item;
  5505. end;
  5506. procedure Delete(var Items: TItems; Start, Size: integer);
  5507. var
  5508. i: Integer;
  5509. begin
  5510. if Size=0 then exit;
  5511. for i:=Start+Size to length(Items)-1 do
  5512. Items[i-Size]:=Items[i];
  5513. Setlength(Items,length(Items)-Size);
  5514. end;
  5515. {$ENDIF}
  5516. var
  5517. StartIndex, l, EndIndex: Integer;
  5518. Item: TItem;
  5519. begin
  5520. Result:=false;
  5521. {$IFDEF VerbosePasResEval}
  5522. writeln('TResEvalSetInt.Add ',aRangeStart,'..',aRangeEnd);
  5523. {$ENDIF}
  5524. if aRangeStart>aRangeEnd then
  5525. raise Exception.Create('');
  5526. if ElKind=revskNone then
  5527. raise Exception.Create('');
  5528. l:=length(Ranges);
  5529. if l=0 then
  5530. begin
  5531. // first range
  5532. RangeStart:=aRangeStart;
  5533. RangeEnd:=aRangeEnd;
  5534. SetLength(Ranges,1);
  5535. Ranges[0].RangeStart:=aRangeStart;
  5536. Ranges[0].RangeEnd:=aRangeEnd;
  5537. exit(true);
  5538. end;
  5539. if RangeStart>aRangeStart then
  5540. RangeStart:=aRangeStart;
  5541. if RangeEnd<aRangeEnd then
  5542. RangeEnd:=aRangeEnd;
  5543. // find insert position
  5544. StartIndex:=IndexOfRange(aRangeStart,true);
  5545. if (StartIndex>0) and (Ranges[StartIndex-1].RangeEnd=aRangeStart-1) then
  5546. dec(StartIndex);
  5547. if StartIndex=l then
  5548. begin
  5549. // add new range
  5550. Item.RangeStart:=aRangeStart;
  5551. Item.RangeEnd:=aRangeEnd;
  5552. Insert(Item,Ranges,StartIndex);
  5553. Result:=true;
  5554. end
  5555. else
  5556. begin
  5557. // StartIndex is now the first affected range
  5558. EndIndex:=IndexOfRange(aRangeEnd,true);
  5559. if (EndIndex>StartIndex) then
  5560. if (EndIndex=l) or (Ranges[EndIndex].RangeStart>aRangeEnd+1) then
  5561. dec(EndIndex);
  5562. // EndIndex is now the last affected range
  5563. if StartIndex>EndIndex then
  5564. raise Exception.Create('');
  5565. if StartIndex=EndIndex then
  5566. begin
  5567. if (Ranges[StartIndex].RangeStart>aRangeEnd) then
  5568. begin
  5569. // range in front
  5570. if (Ranges[StartIndex].RangeStart>aRangeEnd+1) then
  5571. begin
  5572. // insert new range
  5573. Item.RangeStart:=aRangeStart;
  5574. Item.RangeEnd:=aRangeEnd;
  5575. Insert(Item,Ranges,StartIndex);
  5576. Result:=true;
  5577. end
  5578. else
  5579. begin
  5580. // enlarge range at its start
  5581. Ranges[StartIndex].RangeStart:=aRangeStart;
  5582. Result:=true;
  5583. end;
  5584. end
  5585. else if Ranges[StartIndex].RangeEnd<aRangeStart then
  5586. begin
  5587. // range behind
  5588. if Ranges[StartIndex].RangeEnd+1<aRangeStart then
  5589. begin
  5590. // insert new range
  5591. Item.RangeStart:=aRangeStart;
  5592. Item.RangeEnd:=aRangeEnd;
  5593. Insert(Item,Ranges,StartIndex+1);
  5594. Result:=true;
  5595. end
  5596. else
  5597. begin
  5598. // enlarge range at its end
  5599. Ranges[StartIndex].RangeEnd:=aRangeEnd;
  5600. Result:=true;
  5601. end;
  5602. end
  5603. else
  5604. begin
  5605. // intersection -> enlarge to union range
  5606. Result:=false;
  5607. if (Ranges[StartIndex].RangeStart>aRangeStart) then
  5608. Ranges[StartIndex].RangeStart:=aRangeStart;
  5609. if (Ranges[StartIndex].RangeEnd<aRangeEnd) then
  5610. Ranges[StartIndex].RangeEnd:=aRangeEnd;
  5611. end;
  5612. end
  5613. else
  5614. begin
  5615. // multiple ranges are merged to one
  5616. Result:=false;
  5617. if Ranges[StartIndex].RangeStart>aRangeStart then
  5618. Ranges[StartIndex].RangeStart:=aRangeStart;
  5619. if aRangeEnd<Ranges[EndIndex].RangeEnd then
  5620. aRangeEnd:=Ranges[EndIndex].RangeEnd;
  5621. Ranges[StartIndex].RangeEnd:=aRangeEnd;
  5622. Delete(Ranges,StartIndex+1,EndIndex-StartIndex);
  5623. end;
  5624. end;
  5625. {$IFDEF VerbosePasResEval}
  5626. writeln('TResEvalSetInt.Add END ',AsDebugString);
  5627. ConsistencyCheck;
  5628. {$ENDIF}
  5629. end;
  5630. function TResEvalSet.IndexOfRange(Index: TMaxPrecInt; FindInsertPos: boolean
  5631. ): integer;
  5632. var
  5633. l, r, m: Integer;
  5634. begin
  5635. l:=0;
  5636. r:=length(Ranges)-1;
  5637. while l<=r do
  5638. begin
  5639. m:=(l+r) div 2;
  5640. if Ranges[m].RangeStart>Index then
  5641. r:=m-1
  5642. else if Ranges[m].RangeEnd<Index then
  5643. l:=m+1
  5644. else
  5645. exit(m);
  5646. end;
  5647. if not FindInsertPos then
  5648. exit(-1);
  5649. // find insert position
  5650. if length(Ranges)=0 then
  5651. exit(0)
  5652. else if l>m then
  5653. exit(l)
  5654. else
  5655. exit(m);
  5656. Result:=-1;
  5657. end;
  5658. function TResEvalSet.Intersects(aRangeStart, aRangeEnd: TMaxPrecInt): integer;
  5659. var
  5660. Index: Integer;
  5661. begin
  5662. Index:=IndexOfRange(aRangeStart,true);
  5663. if (Index=length(Ranges)) or (Ranges[Index].RangeStart>aRangeEnd) then
  5664. Result:=-1
  5665. else
  5666. Result:=Index;
  5667. end;
  5668. procedure TResEvalSet.ConsistencyCheck;
  5669. procedure E(Msg: string);
  5670. begin
  5671. raise Exception.Create(Msg);
  5672. end;
  5673. var
  5674. i: Integer;
  5675. begin
  5676. if (ElKind=revskNone) and (length(Ranges)>0) then
  5677. E('');
  5678. for i:=0 to length(Ranges)-1 do
  5679. begin
  5680. if Ranges[i].RangeStart>Ranges[i].RangeEnd then
  5681. E('');
  5682. if (i>0) and (Ranges[i-1].RangeEnd+1>=Ranges[i].RangeStart) then
  5683. E('missing gap');
  5684. if RangeStart>Ranges[i].RangeStart then
  5685. E('wrong RangeStart='+IntToStr(RangeStart));
  5686. if RangeEnd<Ranges[i].RangeEnd then
  5687. E('wrong RangeEnd='+IntToStr(RangeEnd));
  5688. end;
  5689. end;
  5690. end.