12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463 |
- {
- This file is part of the Free Component Library (FCL)
- Copyright (c) 2008 Michael Van Canneyt.
- Expression parser, supports variables, functions and
- float/integer/string/boolean/datetime operations.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- {$h+}
- unit fpexprpars;
- interface
- uses
- Classes, SysUtils, contnrs;
- Type
- // tokens
- TTokenType = (ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
- ttMod, ttMul, ttLeft, ttRight, ttLessThanEqual,
- ttLargerThanEqual, ttunequal, ttNumber, ttString, ttIdentifier,
- ttComma, ttAnd, ttOr, ttXor, ttTrue, ttFalse, ttNot, ttif,
- ttCase, ttPower, ttEOF); // keep ttEOF last
- TExprFloat = Double;
- Const
- ttDelimiters = [ttPlus, ttMinus, ttLessThan, ttLargerThan, ttEqual, ttDiv,
- ttMul, ttLeft, ttRight, ttLessThanEqual, ttLargerThanEqual,
- ttunequal, ttPower];
- ttComparisons = [ttLargerThan,ttLessthan,
- ttLargerThanEqual,ttLessthanEqual,
- ttEqual,ttUnequal];
- Type
- TFPExpressionParser = Class;
- TExprBuiltInManager = Class;
- TFPExprFunction = Class;
- TFPExprFunctionClass = Class of TFPExprFunction;
- TNumberKind = (nkDecimal, nkHex, nkOctal, nkBinary);
- { TFPExpressionScanner }
- TFPExpressionScanner = Class(TObject)
- FSource : String;
- LSource,
- FPos : Integer;
- FChar : Char;
- FToken : String;
- FTokenType : TTokenType;
- private
- function GetCurrentChar: Char;
- procedure ScanError(Msg: String);
- protected
- procedure SetSource(const AValue: String); virtual;
- function DoIdentifier: TTokenType;
- function DoNumber(AKind: TNumberKind): TTokenType;
- function DoDelimiter: TTokenType;
- function DoString: TTokenType;
- Function NextPos : Char; // inline;
- procedure SkipWhiteSpace; // inline;
- function IsWordDelim(C : Char) : Boolean; // inline;
- function IsDelim(C : Char) : Boolean; // inline;
- function IsDigit(C : Char; AKind: TNumberKind) : Boolean; // inline;
- function IsAlpha(C : Char) : Boolean; // inline;
- public
- Constructor Create;
- Function GetToken : TTokenType;
- Property Token : String Read FToken;
- Property TokenType : TTokenType Read FTokenType;
- Property Source : String Read FSource Write SetSource;
- Property Pos : Integer Read FPos;
- Property CurrentChar : Char Read GetCurrentChar;
- end;
- EExprScanner = Class(Exception);
- TResultType = (rtBoolean,rtInteger,rtFloat,rtDateTime,rtString,rtCurrency);
- TResultTypes = set of TResultType;
- TFPExpressionResult = record
- ResultType : TResultType;
- resValue : JSValue;
- end;
- PFPExpressionResult = ^TFPExpressionResult;
- TExprParameterArray = Array of TFPExpressionResult;
- { TFPExprNode }
- TFPExprNode = Class(TObject)
- Protected
- Procedure CheckNodeType(Anode : TFPExprNode; Allowed : TResultTypes);
- // A procedure with var saves an implicit try/finally in each node
- // A marked difference in execution speed.
- Function GetNodeValue : TFPExpressionResult; virtual; abstract;
- Public
- Procedure Check; virtual; abstract;
- Procedure InitAggregate; virtual;
- Procedure UpdateAggregate; virtual;
- Class Function IsAggregate : Boolean; virtual;
- Function HasAggregate : Boolean; virtual;
- Function NodeType : TResultType; virtual; abstract;
- Function NodeValue : TFPExpressionResult;
- Function AsString : string; virtual; abstract;
- end;
- TExprArgumentArray = Array of TFPExprNode;
- { TFPBinaryOperation }
- TFPBinaryOperation = Class(TFPExprNode)
- private
- FLeft: TFPExprNode;
- FRight: TFPExprNode;
- Protected
- Procedure CheckSameNodeTypes;
- Public
- Constructor Create(ALeft,ARight : TFPExprNode);
- Destructor Destroy; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- Function HasAggregate : Boolean; override;
- Procedure Check; override;
- Property left : TFPExprNode Read FLeft;
- Property Right : TFPExprNode Read FRight;
- end;
- TFPBinaryOperationClass = Class of TFPBinaryOperation;
- { TFPBooleanOperation }
- TFPBooleanOperation = Class(TFPBinaryOperation)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- end;
- { TFPBinaryAndOperation }
- TFPBinaryAndOperation = Class(TFPBooleanOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPBinaryOrOperation }
- TFPBinaryOrOperation = Class(TFPBooleanOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPBinaryXOrOperation }
- TFPBinaryXOrOperation = Class(TFPBooleanOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPBooleanResultOperation }
- TFPBooleanResultOperation = Class(TFPBinaryOperation)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- end;
- TFPBooleanResultOperationClass = Class of TFPBooleanResultOperation;
- { TFPEqualOperation }
- TFPEqualOperation = Class(TFPBooleanResultOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPUnequalOperation }
- TFPUnequalOperation = Class(TFPEqualOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPOrderingOperation }
- TFPOrderingOperation = Class(TFPBooleanResultOperation)
- Public
- Procedure Check; override;
- end;
- { TFPLessThanOperation }
- TFPLessThanOperation = Class(TFPOrderingOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPGreaterThanOperation }
- TFPGreaterThanOperation = Class(TFPOrderingOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPLessThanEqualOperation }
- TFPLessThanEqualOperation = Class(TFPGreaterThanOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPGreaterThanEqualOperation }
- TFPGreaterThanEqualOperation = Class(TFPLessThanOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TIfOperation }
- TIfOperation = Class(TFPBinaryOperation)
- private
- FCondition: TFPExprNode;
- protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Procedure Check; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- Function HasAggregate : Boolean; override;
- Function NodeType : TResultType; override;
- Constructor Create(ACondition,ALeft,ARight : TFPExprNode);
- Destructor destroy; override;
- Function AsString : string ; override;
- Property Condition : TFPExprNode Read FCondition;
- end;
- { TCaseOperation }
- TCaseOperation = Class(TFPExprNode)
- private
- FArgs : TExprArgumentArray;
- FCondition: TFPExprNode;
- protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Procedure Check; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- function HasAggregate: Boolean; override;
- Function NodeType : TResultType; override;
- Constructor Create(Args : TExprArgumentArray);
- Destructor destroy; override;
- Function AsString : string ; override;
- Property Condition : TFPExprNode Read FCondition;
- end;
- { TMathOperation }
- TMathOperation = Class(TFPBinaryOperation)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- end;
- { TFPAddOperation }
- TFPAddOperation = Class(TMathOperation)
- Protected
- Function GetNodeValue : TFPExpressionResult; override;
- Public
- Function AsString : string ; override;
- end;
- { TFPSubtractOperation }
- TFPSubtractOperation = Class(TMathOperation)
- Public
- Procedure Check; override;
- Function GetNodeValue : TFPExpressionResult; override;
- Function AsString : string ; override;
- end;
- { TFPMultiplyOperation }
- TFPMultiplyOperation = Class(TMathOperation)
- Public
- Procedure check; override;
- Function AsString : string ; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFPDivideOperation }
- TFPDivideOperation = Class(TMathOperation)
- Public
- Procedure Check; override;
- Function AsString : string ; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFPModuloOperation }
- TFPModuloOperation = Class(TMathOperation)
- Public
- Procedure Check; override;
- Function AsString : string ; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFPPowerOperation }
- TFPPowerOperation = class(TMathOperation)
- public
- Procedure Check; override;
- Function AsString : string ; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFPUnaryOperator }
- TFPUnaryOperator = Class(TFPExprNode)
- private
- FOperand: TFPExprNode;
- Public
- Constructor Create(AOperand : TFPExprNode);
- Destructor Destroy; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- Function HasAggregate : Boolean; override;
- Procedure Check; override;
- Property Operand : TFPExprNode Read FOperand;
- end;
- { TFPConvertNode }
- TFPConvertNode = Class(TFPUnaryOperator)
- Function AsString : String; override;
- end;
- { TFPNotNode }
- TFPNotNode = Class(TFPUnaryOperator)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- Function AsString : String; override;
- end;
- TIntConvertNode = Class(TFPConvertNode)
- Public
- Procedure Check; override;
- end;
- { TIntToFloatNode }
- TIntToFloatNode = Class(TIntConvertNode)
- Public
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TIntToCurrencyNode }
- TIntToCurrencyNode = Class(TIntConvertNode)
- Public
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TIntToDateTimeNode }
- TIntToDateTimeNode = Class(TIntConvertNode)
- Public
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFloatToDateTimeNode }
- TFloatToDateTimeNode = Class(TFPConvertNode)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFloatToCurrencyNode }
- TFloatToCurrencyNode = Class(TFPConvertNode)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TCurrencyToDateTimeNode }
- TCurrencyToDateTimeNode = Class(TFPConvertNode)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TCurrencyToFloatNode }
- TCurrencyToFloatNode = Class(TFPConvertNode)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TFPNegateOperation }
- TFPNegateOperation = Class(TFPUnaryOperator)
- Public
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- Function AsString : String; override;
- end;
- { TFPConstExpression }
- TFPConstExpression = Class(TFPExprnode)
- private
- FValue : TFPExpressionResult;
- public
- Constructor CreateString(AValue : String);
- Constructor CreateInteger(AValue : NativeInt);
- Constructor CreateDateTime(AValue : TDateTime);
- Constructor CreateFloat(AValue : TExprFloat);
- Constructor CreateBoolean(AValue : Boolean);
- constructor CreateCurrency(AValue: Currency);
- Procedure Check; override;
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- Function AsString : string ; override;
- // For inspection
- Property ConstValue : TFPExpressionResult read FValue;
- end;
- TIdentifierType = (itVariable,itFunctionHandler,itFunctionNode);
- TFPExprFunctionEvent = reference to Function (Const Args : TExprParameterArray) : TFPExpressionResult ;
- TFPExprVariableEvent = Reference to Function (Const AName : String) : TFPExpressionResult;
- { TFPExprIdentifierDef }
- TFPExprIdentifierDef = Class(TCollectionItem)
- private
- FNodeType: TFPExprFunctionClass;
- FOnGetVarValue: TFPExprVariableEvent;
- FStringValue : String;
- FValue : TFPExpressionResult;
- FArgumentTypes: String;
- FIDType: TIdentifierType;
- FName: string;
- FOnGetValue: TFPExprFunctionEvent;
- function GetAsBoolean: Boolean;
- function GetAsDateTime: TDateTime;
- function GetAsFloat: TExprFloat;
- function GetAsCurrency : Currency;
- function GetAsInteger: NativeInt;
- function GetAsString: String;
- function GetResultType: TResultType;
- function GetValue: String;
- procedure SetArgumentTypes(const AValue: String);
- procedure SetAsBoolean(const AValue: Boolean);
- procedure SetAsDateTime(const AValue: TDateTime);
- procedure SetAsFloat(const AValue: TExprFloat);
- procedure SetAsCurrency(const AValue: Currency);
- procedure SetAsInteger(const AValue: NativeInt);
- procedure SetAsString(const AValue: String);
- procedure SetName(const AValue: string);
- procedure SetResultType(const AValue: TResultType);
- procedure SetValue(const AValue: String);
- Protected
- Procedure CheckResultType(Const AType : TResultType);
- Procedure CheckVariable;
- Procedure FetchValue;
- Public
- Function ArgumentCount : Integer;
- Procedure Assign(Source : TPersistent); override;
- Function EventBasedVariable : Boolean; Inline;
- Property AsFloat : TExprFloat Read GetAsFloat Write SetAsFloat;
- Property AsCurrency : Currency Read GetAsCurrency Write SetAsCurrency;
- Property AsInteger : NativeInt Read GetAsInteger Write SetAsInteger;
- Property AsString : String Read GetAsString Write SetAsString;
- Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean;
- Property AsDateTime : TDateTime Read GetAsDateTime Write SetAsDateTime;
- Published
- Property IdentifierType : TIdentifierType Read FIDType Write FIDType;
- Property Name : string Read FName Write SetName;
- Property Value : String Read GetValue Write SetValue;
- Property ParameterTypes : String Read FArgumentTypes Write SetArgumentTypes;
- Property ResultType : TResultType Read GetResultType Write SetResultType;
- Property OnGetFunctionValue : TFPExprFunctionEvent Read FOnGetValue Write FOnGetValue;
- Property OnGetVariableValue : TFPExprVariableEvent Read FOnGetVarValue Write FOnGetVarValue;
- Property NodeType : TFPExprFunctionClass Read FNodeType Write FNodeType;
- end;
- TBuiltInCategory = (bcStrings,bcDateTime,bcMath,bcBoolean,bcConversion,bcData,bcVaria,bcUser,bcAggregate);
- TBuiltInCategories = Set of TBuiltInCategory;
- { TFPBuiltInExprIdentifierDef }
- TFPBuiltInExprIdentifierDef = Class(TFPExprIdentifierDef)
- private
- FCategory: TBuiltInCategory;
- Public
- Procedure Assign(Source : TPersistent); override;
- Published
- Property Category : TBuiltInCategory Read FCategory Write FCategory;
- end;
- { TFPExprIdentifierDefs }
- TFPExprIdentifierDefs = Class(TCollection)
- private
- FParser: TFPExpressionParser;
- function GetI(AIndex : Integer): TFPExprIdentifierDef;
- procedure SetI(AIndex : Integer; const AValue: TFPExprIdentifierDef);
- Protected
- procedure Update(Item: TCollectionItem); override;
- Property Parser: TFPExpressionParser Read FParser;
- Public
- Function IndexOfIdentifier(Const AName : string) : Integer;
- Function FindIdentifier(Const AName : string) : TFPExprIdentifierDef;
- Function IdentifierByName(Const AName : string) : TFPExprIdentifierDef;
- Function AddVariable(Const AName : string; AResultType : TResultType; ACallback : TFPExprVariableEvent) : TFPExprIdentifierDef;
- Function AddVariable(Const AName : string; AResultType : TResultType; AValue : String) : TFPExprIdentifierDef;
- Function AddBooleanVariable(Const AName : string; AValue : Boolean) : TFPExprIdentifierDef;
- Function AddIntegerVariable(Const AName : string; AValue : Integer) : TFPExprIdentifierDef;
- Function AddFloatVariable(Const AName : string; AValue : TExprFloat) : TFPExprIdentifierDef;
- Function AddCurrencyVariable(Const AName : string; AValue : Currency) : TFPExprIdentifierDef;
- Function AddStringVariable(Const AName : string; AValue : String) : TFPExprIdentifierDef;
- Function AddDateTimeVariable(Const AName : string; AValue : TDateTime) : TFPExprIdentifierDef;
- Function AddFunction(Const AName : string; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionEvent) : TFPExprIdentifierDef;
- Function AddFunction(Const AName : string; Const AResultType : Char; Const AParamTypes : String; ANodeClass : TFPExprFunctionClass) : TFPExprIdentifierDef;
- property Identifiers[AIndex : Integer] : TFPExprIdentifierDef Read GetI Write SetI; Default;
- end;
- { TFPExprIdentifierNode }
- TFPExprIdentifierNode = Class(TFPExprNode)
- Private
- FID : TFPExprIdentifierDef;
- PResult : PFPExpressionResult;
- FResultType : TResultType;
- public
- Constructor CreateIdentifier(AID : TFPExprIdentifierDef);
- Function NodeType : TResultType; override;
- Function GetNodeValue : TFPExpressionResult; override;
- Property Identifier : TFPExprIdentifierDef Read FID;
- end;
- { TFPExprVariable }
- TFPExprVariable = Class(TFPExprIdentifierNode)
- Procedure Check; override;
- function AsString: string; override;
- end;
- { TFPExprFunction }
- TFPExprFunction = Class(TFPExprIdentifierNode)
- private
- FArgumentNodes : TExprArgumentArray;
- FargumentParams : TExprParameterArray;
- Protected
- Procedure CalcParams;
- function ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode; virtual;
- Public
- Procedure Check; override;
- Constructor CreateFunction(AID : TFPExprIdentifierDef; Const Args : TExprArgumentArray); virtual;
- Destructor Destroy; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- Function HasAggregate : Boolean; override;
- Property ArgumentNodes : TExprArgumentArray Read FArgumentNodes;
- Property ArgumentParams : TExprParameterArray Read FArgumentParams;
- Function AsString : String; override;
- end;
- { TAggregateExpr }
- TAggregateExpr = Class(TFPExprFunction)
- Protected
- FResult : TFPExpressionResult;
- public
- Class Function IsAggregate : Boolean; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TAggregateMin }
- TAggregateMin = Class(TAggregateExpr)
- Public
- FFirst: Boolean;
- Public
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- end;
- { TAggregateMax }
- TAggregateMax = Class(TAggregateExpr)
- Public
- FFirst: Boolean;
- Public
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- end;
- { TAggregateSum }
- TAggregateSum = Class(TAggregateExpr)
- Public
- function ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode; override;
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- end;
- { TAggregateAvg }
- TAggregateAvg = Class(TAggregateSum)
- Protected
- FCount : Integer;
- Public
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- Function GetNodeValue : TFPExpressionResult; override;
- end;
- { TAggregateCount }
- TAggregateCount = Class(TAggregateExpr)
- Public
- Procedure InitAggregate; override;
- Procedure UpdateAggregate; override;
- end;
- { TFPFunctionEventHandler }
- TFPFunctionEventHandler = Class(TFPExprFunction)
- Private
- FCallBack : TFPExprFunctionEvent;
- Public
- Constructor CreateFunction(AID : TFPExprIdentifierDef; Const Args : TExprArgumentArray); override;
- Function GetNodeValue : TFPExpressionResult; override;
- Property CallBack : TFPExprFunctionEvent Read FCallBack;
- end;
- { TFPExpressionParser }
- TFPExpressionParser = class(TComponent)
- private
- FBuiltIns: TBuiltInCategories;
- FExpression: String;
- FScanner : TFPExpressionScanner;
- FExprNode : TFPExprNode;
- FIdentifiers : TFPExprIdentifierDefs;
- FHashList : TFPObjectHashTable;
- FDirty : Boolean;
- procedure CheckEOF;
- function GetAsBoolean: Boolean;
- function GetAsDateTime: TDateTime;
- function GetAsFloat: TExprFloat;
- function GetAsCurrency: Currency;
- function GetAsInteger: NativeInt;
- function GetAsString: String;
- function MatchNodes(Todo, Match: TFPExprNode): TFPExprNode;
- procedure CheckNodes(var Left, Right: TFPExprNode);
- procedure SetBuiltIns(const AValue: TBuiltInCategories);
- procedure SetIdentifiers(const AValue: TFPExprIdentifierDefs);
- Protected
- procedure ParserError(Msg: String);
- procedure SetExpression(const AValue: String); virtual;
- Procedure CheckResultType(Const Res :TFPExpressionResult; AType : TResultType); inline;
- Procedure CheckResultTypes(Const Res :TFPExpressionResult; ATypes : TResultTypes); inline;
- Class function ConvertNode(Todo: TFPExprNode; ToType: TResultType): TFPExprNode;
- class Function BuiltinsManager : TExprBuiltInManager;
- Function Level1 : TFPExprNode;
- Function Level2 : TFPExprNode;
- Function Level3 : TFPExprNode;
- Function Level4 : TFPExprNode;
- Function Level5 : TFPExprNode;
- Function Level6 : TFPExprNode;
- Function Level7 : TFPExprNode;
- Function Primitive : TFPExprNode;
- function GetToken: TTokenType;
- Function TokenType : TTokenType;
- Function CurrentToken : String;
- Procedure CreateHashList;
- Property Scanner : TFPExpressionScanner Read FScanner;
- Property ExprNode : TFPExprNode Read FExprNode;
- Property Dirty : Boolean Read FDirty;
- public
- Constructor Create(AOwner :TComponent); override;
- Destructor Destroy; override;
- Function IdentifierByName(const AName : string) : TFPExprIdentifierDef; virtual;
- Procedure Clear;
- Class function Evaluate(aExpression : String): TFPExpressionResult; overload;
- Procedure EvaluateExpression(Out Result : TFPExpressionResult);
- function ExtractNode(var N: TFPExprNode): Boolean;
- Function Evaluate : TFPExpressionResult;overload;
- Function ResultType : TResultType;
- Function HasAggregate : Boolean;
- Procedure InitAggregate;
- Procedure UpdateAggregate;
- Property AsFloat : TExprFloat Read GetAsFloat;
- Property AsCurrency : Currency Read GetAsCurrency;
- Property AsInteger : NativeInt Read GetAsInteger;
- Property AsString : String Read GetAsString;
- Property AsBoolean : Boolean Read GetAsBoolean;
- Property AsDateTime : TDateTime Read GetAsDateTime;
- Published
- // The Expression to parse
- property Expression : String read FExpression write SetExpression;
- Property Identifiers : TFPExprIdentifierDefs Read FIdentifiers Write SetIdentifiers;
- Property BuiltIns : TBuiltInCategories Read FBuiltIns Write SetBuiltIns;
- end;
- TFPExpressionParserClass = Class of TFPExpressionParser;
- { TExprBuiltInManager }
- TExprBuiltInManager = Class(TComponent)
- Private
- FDefs : TFPExprIdentifierDefs;
- function GetCount: Integer;
- function GetI(AIndex : Integer): TFPBuiltInExprIdentifierDef;
- protected
- Property Defs : TFPExprIdentifierDefs Read FDefs;
- Public
- Constructor Create(AOwner : TComponent); override;
- Destructor Destroy; override;
- Function IndexOfIdentifier(Const AName : string) : Integer;
- Function FindIdentifier(Const AName : string) : TFPBuiltinExprIdentifierDef;
- Function IdentifierByName(Const AName : string) : TFPBuiltinExprIdentifierDef;
- Function AddVariable(Const ACategory : TBuiltInCategory; Const AName : string; AResultType : TResultType; AValue : String) : TFPBuiltInExprIdentifierDef;
- Function AddBooleanVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : Boolean) : TFPBuiltInExprIdentifierDef;
- Function AddIntegerVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : Integer) : TFPBuiltInExprIdentifierDef;
- Function AddFloatVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : TExprFloat) : TFPBuiltInExprIdentifierDef;
- Function AddCurrencyVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : Currency) : TFPBuiltInExprIdentifierDef;
- Function AddStringVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : String) : TFPBuiltInExprIdentifierDef;
- Function AddDateTimeVariable(Const ACategory : TBuiltInCategory; Const AName : string; AValue : TDateTime) : TFPBuiltInExprIdentifierDef;
- Function AddFunction(Const ACategory : TBuiltInCategory; Const AName : string; Const AResultType : Char; Const AParamTypes : String; ACallBack : TFPExprFunctionEvent) : TFPBuiltInExprIdentifierDef;
- Function AddFunction(Const ACategory : TBuiltInCategory; Const AName : string; Const AResultType : Char; Const AParamTypes : String; ANodeClass : TFPExprFunctionClass) : TFPBuiltInExprIdentifierDef;
- Property IdentifierCount : Integer Read GetCount;
- Property Identifiers[AIndex : Integer] :TFPBuiltInExprIdentifierDef Read GetI;
- end;
- EExprParser = Class(Exception);
- Const
- AllBuiltIns = [bcStrings,bcDateTime,bcMath,bcBoolean,bcConversion,bcData,bcVaria,bcUser,bcAggregate];
- Function TokenName (AToken : TTokenType) : String;
- Function ResultTypeName (AResult : TResultType) : String;
- Function CharToResultType(C : Char) : TResultType;
- Function BuiltinIdentifiers : TExprBuiltInManager;
- Procedure RegisterStdBuiltins(AManager : TExprBuiltInManager; Categories : TBuiltInCategories = AllBuiltIns);
- function ArgToFloat(Arg: TFPExpressionResult): TExprFloat;
- implementation
- uses typinfo;
- { TFPExpressionParser }
- const
- cNull=#0;
- cSingleQuote = '''';
- cHexIdentifier = '$';
- cOctalIdentifier = '&';
- cBinaryIdentifier = '%';
- Digits = ['0'..'9','.'];
- HexDigits = ['0'..'9', 'A'..'F', 'a'..'f'];
- OctalDigits = ['0'..'7'];
- BinaryDigits = ['0', '1'];
- WhiteSpace = [' ',#13,#10,#9];
- Operators = ['+','-','<','>','=','/','*','^'];
- Delimiters = Operators+[',','(',')'];
- Symbols = ['%']+Delimiters;
- WordDelimiters = WhiteSpace + Symbols;
- var
- FileFormatSettings: TFormatSettings;
- Resourcestring
- SBadQuotes = 'Unterminated string';
- SUnknownDelimiter = 'Unknown delimiter character: "%s"';
- SErrUnknownCharacter = 'Unknown character at pos %d: "%s"';
- SErrUnexpectedEndOfExpression = 'Unexpected end of expression';
- SErrUnknownComparison = 'Internal error: Unknown comparison';
- SErrUnknownBooleanOp = 'Internal error: Unknown boolean operation';
- SErrBracketExpected = 'Expected ) bracket at position %d, but got %s';
- SerrUnknownTokenAtPos = 'Unknown token at pos %d : %s';
- SErrLeftBracketExpected = 'Expected ( bracket at position %d, but got %s';
- SErrInvalidFloat = '%s is not a valid floating-point value';
- SErrUnknownIdentifier = 'Unknown identifier: %s';
- SErrInExpression = 'Cannot evaluate: error in expression';
- SErrInExpressionEmpty = 'Cannot evaluate: empty expression';
- SErrCommaExpected = 'Expected comma (,) at position %d, but got %s';
- SErrInvalidNumberChar = 'Unexpected character in number : %s';
- SErrInvalidNumber = 'Invalid numerical value : %s';
- SErrUnterminatedIdentifier = 'Unterminated quoted identifier: %s';
- SErrNoOperand = 'No operand for unary operation %s';
- SErrNoleftOperand = 'No left operand for binary operation %s';
- SErrNoRightOperand = 'No right operand for binary operation %s';
- SErrNoNegation = 'Cannot negate expression of type %s : %s';
- SErrNoNOTOperation = 'Cannot perform "not" on expression of type %s: %s';
- SErrTypesDoNotMatch = 'Type mismatch: %s<>%s for expressions "%s" and "%s".';
- SErrNoNodeToCheck = 'Internal error: No node to check !';
- SInvalidNodeType = 'Node type (%s) not in allowed types (%s) for expression: %s';
- SErrUnterminatedExpression = 'Badly terminated expression. Found token at position %d : %s';
- SErrDuplicateIdentifier = 'An identifier with name "%s" already exists.';
- SErrInvalidResultCharacter = '"%s" is not a valid return type indicator';
- ErrInvalidArgumentCount = 'Invalid argument count for function %s';
- SErrInvalidArgumentType = 'Invalid type for argument %d: Expected %s, got %s';
- SErrInvalidResultType = 'Invalid result type: %s';
- SErrNotVariable = 'Identifier %s is not a variable';
- SErrIFNeedsBoolean = 'First argument to IF must be of type boolean: %s';
- SErrCaseNeeds3 = 'Case statement needs to have at least 4 arguments';
- SErrCaseEvenCount = 'Case statement needs to have an even number of arguments';
- SErrCaseLabelNotAConst = 'Case label %d "%s" is not a constant expression';
- SErrCaseLabelType = 'Case label %d "%s" needs type %s, but has type %s';
- SErrCaseValueType = 'Case value %d "%s" needs type %s, but has type %s';
- { ---------------------------------------------------------------------
- Auxiliary functions
- ---------------------------------------------------------------------}
- Procedure RaiseParserError(Msg : String);
- begin
- Raise EExprParser.Create(Msg);
- end;
- Procedure RaiseParserError(Fmt : String; Args : Array of Const);
- begin
- Raise EExprParser.CreateFmt(Fmt,Args);
- end;
- function TokenName(AToken: TTokenType): String;
- begin
- Result:=GetEnumName(TypeInfo(TTokenType),Ord(AToken));
- end;
- function ResultTypeName(AResult: TResultType): String;
- begin
- Result:=GetEnumName(TypeInfo(TResultType),Ord(AResult));
- end;
- function CharToResultType(C: Char): TResultType;
- begin
- Case Upcase(C) of
- 'S' : Result:=rtString;
- 'D' : Result:=rtDateTime;
- 'B' : Result:=rtBoolean;
- 'I' : Result:=rtInteger;
- 'F' : Result:=rtFloat;
- 'C' : Result:=rtCurrency;
- else
- RaiseParserError(SErrInvalidResultCharacter,[C]);
- end;
- end;
- Var
- BuiltIns : TExprBuiltInManager;
- function BuiltinIdentifiers: TExprBuiltInManager;
- begin
- If (BuiltIns=Nil) then
- BuiltIns:=TExprBuiltInManager.Create(Nil);
- Result:=BuiltIns;
- end;
- { TFloatToCurrencyNode }
- procedure TFloatToCurrencyNode.Check;
- begin
- CheckNodeType(Operand,[rtFloat]);
- end;
- function TFloatToCurrencyNode.NodeType: TResultType;
- begin
- Result:=rtCurrency;
- end;
- Function TFloatToCurrencyNode.GetNodeValue: TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.ResultType:=rtCurrency;
- Result.resValue:=Result.resValue;
- end;
- { TIntToCurrencyNode }
- function TIntToCurrencyNode.NodeType: TResultType;
- begin
- Result:=rtCurrency;
- end;
- Function TIntToCurrencyNode.GetNodeValue: TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.resValue:=Result.resValue;
- Result.ResultType:=rtCurrency;
- end;
- { TFPModuloOperation }
- procedure TFPModuloOperation.Check;
- begin
- CheckNodeType(Left,[rtInteger]);
- CheckNodeType(Right,[rtInteger]);
- inherited Check;
- end;
- function TFPModuloOperation.AsString: string;
- begin
- Result:=Left.AsString+' mod '+Right.asString;
- end;
- function TFPModuloOperation.NodeType: TResultType;
- begin
- Result:=rtInteger;
- end;
- function TFPModuloOperation.GetNodeValue: TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Result.resValue:=NativeInt(Result.resValue) mod NativeInt(RRes.resValue);
- Result.ResultType:=rtInteger;
- end;
- { TAggregateMax }
- procedure TAggregateMax.InitAggregate;
- begin
- inherited InitAggregate;
- FFirst:=True;
- FResult.ResultType:=FArgumentNodes[0].NodeType;
- Case FResult.ResultType of
- rtFloat : FResult.resValue:=0.0;
- rtCurrency : FResult.resValue:=0.0;
- rtInteger : FResult.resValue:=0;
- end;
- end;
- procedure TAggregateMax.UpdateAggregate;
- Var
- OK : Boolean;
- N : TFPExpressionResult;
- begin
- N:=FArgumentNodes[0].GetNodeValue;
- if FFirst then
- begin
- FResult.ResultType:=N.ResultType;
- FFirst:=False;
- OK:=True;
- end
- else
- Case N.ResultType of
- rtFloat: OK:=TExprFloat(N.resValue)>TExprFloat(FResult.resValue);
- rtCurrency: OK:=Currency(N.resValue)>Currency(FResult.resValue);
- rtinteger: OK:=NativeInt(N.resValue)>NativeInt(FResult.resValue);
- end;
- if OK then
- Case N.ResultType of
- rtFloat: FResult.resValue:=N.resValue;
- rtinteger: FResult.resValue:=N.resValue;
- rtCurrency: FResult.resValue:=N.resValue;
- end;
- end;
- { TAggregateMin }
- procedure TAggregateMin.InitAggregate;
- begin
- inherited InitAggregate;
- FFirst:=True;
- FResult.ResultType:=FArgumentNodes[0].NodeType;
- Case FResult.ResultType of
- rtFloat : FResult.resValue:=0.0;
- rtCurrency : FResult.resValue:=0.0;
- rtInteger : FResult.resValue:=0;
- end;
- end;
- procedure TAggregateMin.UpdateAggregate;
- Var
- OK : Boolean;
- N : TFPExpressionResult;
- begin
- N:=FArgumentNodes[0].GetNodeValue;
- if FFirst then
- begin
- FFirst:=False;
- OK:=True;
- end
- else
- Case N.ResultType of
- rtFloat: OK:=TExprFloat(N.resValue)<TExprFloat(FResult.resValue);
- rtCurrency: OK:=Currency(N.resValue)<Currency(FResult.resValue);
- rtinteger: OK:=NativeInt(N.resValue)<NativeInt(FResult.resValue);
- end;
- if OK then
- Case FResult.ResultType of
- rtFloat: FResult.resValue:=N.resValue;
- rtCurrency: FResult.resValue:=N.resValue;
- rtinteger: FResult.resValue:=N.resValue;
- end;
- inherited UpdateAggregate;
- end;
- { TAggregateAvg }
- procedure TAggregateAvg.InitAggregate;
- begin
- inherited InitAggregate;
- end;
- procedure TAggregateAvg.UpdateAggregate;
- begin
- inherited UpdateAggregate;
- Inc(FCount);
- end;
- Function TAggregateAvg.GetNodeValue: TFPExpressionResult;
- begin
- Result:=inherited GetNodeValue;
- Result.ResultType:=FResult.ResultType;
- if FCount=0 then
- Case FResult.ResultType of
- rtInteger:
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=0.0;
- end;
- rtFloat:
- Result.resValue:=0.0;
- rtCurrency:
- Result.resValue:=0.0;
- end
- else
- Case FResult.ResultType of
- rtInteger:
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=NativeInt(FResult.resValue)/FCount;
- end;
- rtFloat:
- Result.resValue:=TExprFloat(FResult.resValue)/FCount;
- rtCurrency:
- Result.resValue:=Currency(FResult.resValue)/FCount;
- end;
- end;
- { TAggregateCount }
- procedure TAggregateCount.InitAggregate;
- begin
- FResult.ResultType:=rtInteger;
- FResult.resValue:=0;
- end;
- procedure TAggregateCount.UpdateAggregate;
- begin
- FResult.resValue:=NativeInt(FResult.resValue)+1;
- end;
- { TAggregateExpr }
- class function TAggregateExpr.IsAggregate: Boolean;
- begin
- Result:=True;
- end;
- Function TAggregateExpr.GetNodeValue: TFPExpressionResult;
- begin
- Result:=FResult;
- end;
- { TAggregateSum }
- function TAggregateSum.ConvertArgument(aIndex: Integer; aNode: TFPExprNode; aType: TResultType): TFPExprNode;
- begin
- if not (aNode.NodeType in [rtFloat,rtInteger,rtCurrency]) then
- RaiseParserError(SErrInvalidArgumentType,[aIndex,ResultTypeName(aType),ResultTypeName(aNode.NodeType)]);
- Result:=aNode;
- end;
- procedure TAggregateSum.InitAggregate;
- begin
- FResult.ResultType:=FArgumentNodes[0].NodeType;
- Case FResult.ResultType of
- rtFloat: FResult.resValue:=0.0;
- rtCurrency : FResult.resValue:=0.0;
- rtinteger: FResult.resValue:=0;
- end;
- end;
- procedure TAggregateSum.UpdateAggregate;
- Var
- R : TFPExpressionResult;
- begin
- R:=FArgumentNodes[0].GetNodeValue;
- Case FResult.ResultType of
- rtFloat: FResult.resValue:=TExprFloat(FResult.resValue)+TExprFloat(R.resValue);
- rtCurrency: FResult.resValue:=Currency(FResult.resValue)+Currency(R.resValue);
- rtinteger: FResult.resValue:=NativeInt(FResult.resValue)+NativeInt(R.resValue);
- end;
- end;
- { ---------------------------------------------------------------------
- TFPExpressionScanner
- ---------------------------------------------------------------------}
- function TFPExpressionScanner.IsAlpha(C: Char): Boolean;
- begin
- Result := C in ['A'..'Z', 'a'..'z'];
- end;
- constructor TFPExpressionScanner.Create;
- begin
- Source:='';
- end;
- procedure TFPExpressionScanner.SetSource(const AValue: String);
- begin
- FSource:=AValue;
- LSource:=Length(FSource);
- FTokenType:=ttEOF;
- If LSource=0 then
- begin
- FPos:=0;
- FChar:=cNull;
- end
- else
- begin
- FPos:=1;
- FChar:=FSource[1];
- end;
- FToken:='';
- end;
- function TFPExpressionScanner.NextPos: Char;
- begin
- Inc(FPos);
- if FPos>Length(FSource) then
- FChar:=cNull
- else
- FChar:=FSource[FPos];
- Result:=FChar;
- end;
- function TFPExpressionScanner.IsWordDelim(C: Char): Boolean;
- begin
- Result:=C in WordDelimiters;
- end;
- function TFPExpressionScanner.IsDelim(C: Char): Boolean;
- begin
- Result:=C in Delimiters;
- end;
- function TFPExpressionScanner.IsDigit(C: Char; AKind: TNumberKind): Boolean;
- begin
- case AKind of
- nkDecimal: Result := C in Digits;
- nkHex : Result := C in HexDigits;
- nkOctal : Result := C in OctalDigits;
- nkBinary : Result := C in BinaryDigits;
- end;
- end;
- Procedure TFPExpressionScanner.SkipWhiteSpace;
- begin
- While (FChar in WhiteSpace) and (FPos<=LSource) do
- NextPos;
- end;
- Function TFPExpressionScanner.DoDelimiter : TTokenType;
- Var
- B : Boolean;
- C,D : Char;
- begin
- C:=FChar;
- FToken:=C;
- B:=C in ['<','>'];
- D:=C;
- C:=NextPos;
- if B and (C in ['=','>']) then
- begin
- FToken:=FToken+C;
- NextPos;
- If (D='>') then
- Result:=ttLargerThanEqual
- else if (C='>') then
- Result:=ttUnequal
- else
- Result:=ttLessThanEqual;
- end
- else
- Case D of
- '+' : Result := ttPlus;
- '-' : Result := ttMinus;
- '<' : Result := ttLessThan;
- '>' : Result := ttLargerThan;
- '=' : Result := ttEqual;
- '/' : Result := ttDiv;
- '*' : Result := ttMul;
- '(' : Result := ttLeft;
- ')' : Result := ttRight;
- ',' : Result := ttComma;
- '^' : Result := ttPower;
- else
- ScanError(Format(SUnknownDelimiter,[D]));
- end;
- end;
- Procedure TFPExpressionScanner.ScanError(Msg : String);
- begin
- Raise EExprScanner.Create(Msg)
- end;
- Function TFPExpressionScanner.DoString : TTokenType;
- Function TerminatingChar(C : Char) : boolean;
- begin
- Result:=(C=cNull) or
- ((C=cSingleQuote) and
- Not ((FPos<LSource) and (FSource[FPos+1]=cSingleQuote)));
- end;
- Var
- C : Char;
- begin
- FToken := '';
- C:=NextPos;
- while not TerminatingChar(C) do
- begin
- FToken:=FToken+C;
- If C=cSingleQuote then
- NextPos;
- C:=NextPos;
- end;
- if (C=cNull) then
- ScanError(SBadQuotes);
- Result := ttString;
- FTokenType:=Result;
- NextPos;
- end;
- function TFPExpressionScanner.GetCurrentChar: Char;
- begin
- Result:=FChar;
- end;
- {$ifndef pas2js}
- procedure Val(const S: string; out V: TExprFloat; out Code: Integer); overload;
- var
- L64: NativeInt;
- begin
- if (S <> '') and (S[1] in ['&', '$', '%']) then
- begin
- System.Val(S, L64, Code);
- if Code = 0 then
- V := L64
- end
- else
- System.Val(S, V, Code);
- end;
- {$endif}
- Function TFPExpressionScanner.DoNumber(AKind: TNumberKind) : TTokenType;
- Var
- C : Char;
- X : TExprFloat;
- I : Integer;
- prevC: Char;
- function ValidDigit(C: Char; AKind: TNumberKind): Boolean;
- begin
- Result := IsDigit(C, AKind);
- if (not Result) then
- case AKind of
- nkDecimal:
- Result := ((FToken <> '') and (UpCase(C)='E')) or
- ((FToken <> '') and (C in ['+','-']) and (prevC='E'));
- nkHex:
- Result := (C = cHexIdentifier) and (prevC = #0);
- nkOctal:
- Result := (C = cOctalIdentifier) and (prevC = #0);
- nkBinary:
- Result := (C = cBinaryIdentifier) and (prevC = #0);
- end;
- end;
- begin
- C:=CurrentChar;
- prevC := #0;
- while (C <> cNull) do
- begin
- if IsWordDelim(C) then
- case AKind of
- nkDecimal:
- if not (prevC in ['E','-','+']) then break;
- nkHex, nkOctal:
- break;
- nkBinary:
- if (prevC <> #0) then break; // allow '%' as first char
- end;
- if not ValidDigit(C, AKind) then
- ScanError(Format(SErrInvalidNumberChar,[C]));
- FToken := FToken+C;
- prevC := Upcase(C);
- C:=NextPos;
- end;
- Val(FToken,X,I);
- If (I<>0) then
- ScanError(Format(SErrInvalidNumber,[FToken]));
- Result:=ttNumber;
- end;
- Function TFPExpressionScanner.DoIdentifier : TTokenType;
- Var
- C : Char;
- S : String;
- begin
- C:=CurrentChar;
- while (not IsWordDelim(C)) and (C<>cNull) do
- begin
- if (C<>'"') then
- FToken:=FToken+C
- else
- begin
- C:=NextPos;
- While Not (C in [cNull,'"']) do
- begin
- FToken:=FToken+C;
- C:=NextPos;
- end;
- if (C<>'"') then
- ScanError(Format(SErrUnterminatedIdentifier,[FToken]));
- end;
- C:=NextPos;
- end;
- S:=LowerCase(Token);
- If (S='or') then
- Result:=ttOr
- else if (S='xor') then
- Result:=ttXOr
- else if (S='and') then
- Result:=ttAnd
- else if (S='true') then
- Result:=ttTrue
- else if (S='false') then
- Result:=ttFalse
- else if (S='not') then
- Result:=ttnot
- else if (S='if') then
- Result:=ttif
- else if (S='case') then
- Result:=ttcase
- else if (S='mod') then
- Result:=ttMod
- else
- Result:=ttIdentifier;
- end;
- Function TFPExpressionScanner.GetToken : TTokenType;
- Var
- C : Char;
- begin
- FToken := '';
- SkipWhiteSpace;
- C:=FChar;
- if c=cNull then
- Result:=ttEOF
- else if IsDelim(C) then
- Result:=DoDelimiter
- else if (C=cSingleQuote) then
- Result:=DoString
- else if (C=cHexIdentifier) then
- Result := DoNumber(nkHex)
- else if (C=cOctalIdentifier) then
- Result := DoNumber(nkOctal)
- else if (C=cBinaryIdentifier) then
- Result := DoNumber(nkBinary)
- else if IsDigit(C, nkDecimal) then
- Result:=DoNumber(nkDecimal)
- else if IsAlpha(C) or (C='"') then
- Result:=DoIdentifier
- else
- ScanError(Format(SErrUnknownCharacter,[FPos,C])) ;
- FTokenType:=Result;
- end;
- { ---------------------------------------------------------------------
- TFPExpressionParser
- ---------------------------------------------------------------------}
- function TFPExpressionParser.TokenType: TTokenType;
- begin
- Result:=FScanner.TokenType;
- end;
- function TFPExpressionParser.CurrentToken: String;
- begin
- Result:=FScanner.Token;
- end;
- procedure TFPExpressionParser.CreateHashList;
- Var
- ID : TFPExpridentifierDef;
- BID : TFPBuiltinExpridentifierDef;
- I : Integer;
- M : TExprBuiltinManager;
- begin
- FHashList.Clear;
- // Builtins
- M:=BuiltinsManager;
- If (FBuiltins<>[]) and Assigned(M) then
- For I:=0 to M.IdentifierCount-1 do
- begin
- BID:=M.Identifiers[I];
- If BID.Category in FBuiltins then
- FHashList.Add(LowerCase(BID.Name),BID);
- end;
- // User
- For I:=0 to FIdentifiers.Count-1 do
- begin
- ID:=FIdentifiers[i];
- FHashList.Add(LowerCase(ID.Name),ID);
- end;
- FDirty:=False;
- end;
- function TFPExpressionParser.IdentifierByName(const AName: string): TFPExprIdentifierDef;
- begin
- If FDirty then
- CreateHashList;
- Result:=TFPExprIdentifierDef(FHashList[LowerCase(AName)]);
- end;
- procedure TFPExpressionParser.Clear;
- begin
- FExpression:='';
- FHashList.Clear;
- FExprNode.Free;
- end;
- class function TFPExpressionParser.Evaluate(aExpression: String): TFPExpressionResult;
- Var
- F : TFPExpressionParser;
- begin
- F:=TFPExpressionParser.Create(Nil);
- try
- F.Expression:=aExpression;
- Result:=F.Evaluate;
- finally
- F.Free;
- end;
- end;
- constructor TFPExpressionParser.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FIdentifiers:=TFPExprIdentifierDefs.Create(TFPExprIdentifierDef);
- FIdentifiers.FParser:=Self;
- FScanner:=TFPExpressionScanner.Create;
- FHashList:=TFPObjectHashTable.Create(False);
- end;
- destructor TFPExpressionParser.Destroy;
- begin
- FreeAndNil(FHashList);
- FreeAndNil(FExprNode);
- FreeAndNil(FIdentifiers);
- FreeAndNil(FScanner);
- inherited Destroy;
- end;
- function TFPExpressionParser.GetToken: TTokenType;
- begin
- Result:=FScanner.GetToken;
- end;
- procedure TFPExpressionParser.CheckEOF;
- begin
- If (TokenType=ttEOF) then
- ParserError(SErrUnexpectedEndOfExpression);
- end;
- procedure TFPExpressionParser.SetIdentifiers(const AValue: TFPExprIdentifierDefs
- );
- begin
- FIdentifiers.Assign(AValue)
- end;
- function TFPExpressionParser.Evaluate: TFPExpressionResult;
- begin
- If (FExpression='') then
- ParserError(SErrInExpressionEmpty);
- if not Assigned(FExprNode) then
- ParserError(SErrInExpression);
- Result:=FExprNode.GetNodeValue;
- end;
- procedure TFPExpressionParser.EvaluateExpression(Out Result: TFPExpressionResult);
- begin
- Result:=Evaluate;
- end;
- function TFPExpressionParser.ExtractNode(Var N : TFPExprNode) : Boolean;
- begin
- Result:=Assigned(FExprNode);
- if Result then
- begin
- N:=FExprNode;
- FExprNode:=Nil;
- FExpression:='';
- end;
- end;
- procedure TFPExpressionParser.ParserError(Msg: String);
- begin
- Raise EExprParser.Create(Msg);
- end;
- Class function TFPExpressionParser.ConvertNode(Todo : TFPExprNode; ToType : TResultType): TFPExprNode;
- begin
- Result:=ToDo;
- Case ToDo.NodeType of
- rtInteger :
- Case ToType of
- rtFloat : Result:=TIntToFloatNode.Create(Result);
- rtCurrency : Result:=TIntToCurrencyNode.Create(Result);
- rtDateTime : Result:=TIntToDateTimeNode.Create(Result);
- end;
- rtFloat :
- Case ToType of
- rtCurrency : Result:=TFloatToCurrencyNode.Create(Result);
- rtDateTime : Result:=TFloatToDateTimeNode.Create(Result);
- end;
- rtCurrency :
- Case ToType of
- rtFloat : Result:=TCurrencyToFloatNode.Create(Result);
- rtDateTime : Result:=TCurrencyToDateTimeNode.Create(Result);
- end;
- end;
- end;
- function TFPExpressionParser.GetAsBoolean: Boolean;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultType(Res,rtBoolean);
- Result:=Boolean(Res.resValue);
- end;
- function TFPExpressionParser.GetAsDateTime: TDateTime;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultType(Res,rtDateTime);
- Result:=TDateTime(Res.resValue);
- end;
- function TFPExpressionParser.GetAsFloat: TExprFloat;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultTypes(Res,[rtFloat,rtCurrency,rtInteger]);
- case Res.ResultType of
- rtInteger : Result:=NativeInt(Res.resValue);
- rtFloat : Result:=TExprFloat(Res.resValue);
- rtCurrency : Result:=Currency(res.resValue);
- end;
- end;
- function TFPExpressionParser.GetAsCurrency: Currency;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultTypes(Res,[rtFloat,rtCurrency,rtInteger]);
- case Res.ResultType of
- rtInteger : Result:=NativeInt(Res.resValue);
- rtFloat : Result:=TExprFloat(Res.resValue);
- rtCurrency : Result:=Currency(res.resValue);
- end;
- end;
- function TFPExpressionParser.GetAsInteger: NativeInt;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultType(Res,rtInteger);
- Result:=NativeInt(Res.resValue);
- end;
- function TFPExpressionParser.GetAsString: String;
- var
- Res: TFPExpressionResult;
- begin
- EvaluateExpression(Res);
- CheckResultType(Res,rtString);
- Result:=String(Res.resValue);
- end;
- {
- Checks types of todo and match. If ToDO can be converted to it matches
- the type of match, then a node is inserted.
- For binary operations, this function is called for both operands.
- }
- function TFPExpressionParser.MatchNodes(Todo,Match : TFPExprNode): TFPExprNode;
- Var
- FromType,ToType : TResultType;
- begin
- Result:=Todo;
- FromType:=Todo.NodeType;
- ToType:=Match.NodeType;
- If (FromType<>ToType) then
- Case FromType of
- rtInteger:
- if (ToType in [rtFloat,rtCurrency,rtDateTime]) then
- Result:=ConvertNode(Todo,toType);
- rtFloat:
- if (ToType in [rtCurrency,rtDateTime]) then
- Result:=ConvertNode(Todo,toType);
- rtCurrency:
- if (ToType in [rtFloat,rtDateTime]) then
- Result:=ConvertNode(Todo,toType);
- end;
- end;
- {
- if the result types differ, they are converted to a common type if possible.
- }
- procedure TFPExpressionParser.CheckNodes(var Left, Right: TFPExprNode);
- begin
- Left:=MatchNodes(Left,Right);
- Right:=MatchNodes(Right,Left);
- end;
- procedure TFPExpressionParser.SetBuiltIns(const AValue: TBuiltInCategories);
- begin
- if FBuiltIns=AValue then exit;
- FBuiltIns:=AValue;
- FDirty:=True;
- end;
- function TFPExpressionParser.Level1: TFPExprNode;
- var
- tt: TTokenType;
- Right : TFPExprNode;
- begin
- {$ifdef debugexpr}Writeln('Level 1 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- if TokenType = ttNot then
- begin
- GetToken;
- CheckEOF;
- Right:=Level2;
- Result:=TFPNotNode.Create(Right);
- end
- else
- Result:=Level2;
- Try
- while (TokenType in [ttAnd,ttOr,ttXor]) do
- begin
- tt:=TokenType;
- GetToken;
- CheckEOF;
- Right:=Level2;
- Case tt of
- ttOr : Result:=TFPBinaryOrOperation.Create(Result,Right);
- ttAnd : Result:=TFPBinaryAndOperation.Create(Result,Right);
- ttXor : Result:=TFPBinaryXorOperation.Create(Result,Right);
- Else
- ParserError(SErrUnknownBooleanOp)
- end;
- end;
- Except
- Result.Free;
- Raise;
- end;
- end;
- function TFPExpressionParser.Level2: TFPExprNode;
- var
- Right : TFPExprNode;
- tt : TTokenType;
- C : TFPBinaryOperationClass;
- begin
- {$ifdef debugexpr} Writeln('Level 2 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- Result:=Level3;
- try
- if (TokenType in ttComparisons) then
- begin
- tt:=TokenType;
- GetToken;
- CheckEOF;
- Right:=Level3;
- CheckNodes(Result,Right);
- Case tt of
- ttLessthan : C:=TFPLessThanOperation;
- ttLessthanEqual : C:=TFPLessThanEqualOperation;
- ttLargerThan : C:=TFPGreaterThanOperation;
- ttLargerThanEqual : C:=TFPGreaterThanEqualOperation;
- ttEqual : C:=TFPEqualOperation;
- ttUnequal : C:=TFPUnequalOperation;
- Else
- ParserError(SErrUnknownComparison)
- end;
- Result:=C.Create(Result,Right);
- end;
- Except
- Result.Free;
- Raise;
- end;
- end;
- function TFPExpressionParser.Level3: TFPExprNode;
- var
- tt : TTokenType;
- right : TFPExprNode;
- begin
- {$ifdef debugexpr} Writeln('Level 3 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- Result:=Level4;
- try
- while TokenType in [ttPlus,ttMinus] do
- begin
- tt:=TokenType;
- GetToken;
- CheckEOF;
- Right:=Level4;
- CheckNodes(Result,Right);
- Case tt of
- ttPlus : Result:=TFPAddOperation.Create(Result,Right);
- ttMinus : Result:=TFPSubtractOperation.Create(Result,Right);
- end;
- end;
- Except
- Result.Free;
- Raise;
- end;
- end;
- function TFPExpressionParser.Level4: TFPExprNode;
- var
- tt : TTokenType;
- right : TFPExprNode;
- begin
- {$ifdef debugexpr} Writeln('Level 4 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- Result:=Level5;
- try
- while (TokenType in [ttMul,ttDiv,ttMod]) do
- begin
- tt:=TokenType;
- GetToken;
- Right:=Level5;
- CheckNodes(Result,Right);
- Case tt of
- ttMul : Result:=TFPMultiplyOperation.Create(Result,Right);
- ttDiv : Result:=TFPDivideOperation.Create(Result,Right);
- ttMod : Result:=TFPModuloOperation.Create(Result,Right);
- end;
- end;
- Except
- Result.Free;
- Raise;
- end;
- end;
- function TFPExpressionParser.Level5: TFPExprNode;
- Var
- B : Boolean;
- begin
- {$ifdef debugexpr} Writeln('Level 5 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- B:=False;
- if (TokenType in [ttPlus,ttMinus]) then
- begin
- B:=TokenType=ttMinus;
- GetToken;
- end;
- Result:=Level6;
- If B then
- Result:=TFPNegateOperation.Create(Result);
- end;
- function TFPExpressionParser.Level6: TFPExprNode;
- var
- right: TFPExprNode;
- begin
- {$ifdef debugexpr} Writeln('Level 6 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- Result := Level7;
- try
- while (TokenType = ttPower) do
- begin
- GetToken;
- right := Level5; // Accept '(', unary '+', '-' as next tokens
- CheckNodes(Result, right);
- Result := TFPPowerOperation.Create(Result, right);
- end;
- except
- Result.Free;
- Raise;
- end;
- end;
- function TFPExpressionParser.Level7: TFPExprNode;
- begin
- {$ifdef debugexpr} Writeln('Level 7 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- if (TokenType=ttLeft) then
- begin
- GetToken;
- Result:=Level1;
- try
- if (TokenType<>ttRight) then
- ParserError(Format(SErrBracketExpected,[SCanner.Pos,CurrentToken]));
- GetToken;
- Except
- Result.Free;
- Raise;
- end;
- end
- else
- Result:=Primitive;
- end;
- function TFPExpressionParser.Primitive: TFPExprNode;
- Var
- I : NativeInt;
- C : Integer;
- X : TExprFloat;
- ACount : Integer;
- IFF : Boolean;
- IFC : Boolean;
- ID : TFPExprIdentifierDef;
- Args : TExprArgumentArray;
- AI : Integer;
- begin
- {$ifdef debugexpr} Writeln('Primitive : ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
- SetLength(Args,0);
- if (TokenType=ttNumber) then
- begin
- if TryStrToInt64(CurrentToken,I) then
- Result:=TFPConstExpression.CreateInteger(I)
- else
- begin
- Val(CurrentToken,X,C);
- If (C=0) then
- Result:=TFPConstExpression.CreateFloat(X)
- else
- ParserError(Format(SErrInvalidFloat,[CurrentToken]));
- end;
- end
- else if (TokenType=ttString) then
- Result:=TFPConstExpression.CreateString(CurrentToken)
- else if (TokenType in [ttTrue,ttFalse]) then
- Result:=TFPConstExpression.CreateBoolean(TokenType=ttTrue)
- else if Not (TokenType in [ttIdentifier,ttIf,ttcase]) then
- ParserError(Format(SerrUnknownTokenAtPos,[Scanner.Pos,CurrentToken]))
- else
- begin
- IFF:=TokenType=ttIf;
- IFC:=TokenType=ttCase;
- if Not (IFF or IFC) then
- begin
- ID:=self.IdentifierByName(CurrentToken);
- If (ID=Nil) then
- ParserError(Format(SErrUnknownIdentifier,[CurrentToken]))
- end;
- // Determine number of arguments
- if Iff then
- ACount:=3
- else if IfC then
- ACount:=-4
- else if (ID.IdentifierType in [itFunctionHandler,itFunctionNode]) then
- ACount:=ID.ArgumentCount
- else
- ACount:=0;
- // Parse arguments.
- // Negative is for variable number of arguments, where Abs(value) is the minimum number of arguments
- If (ACount<>0) then
- begin
- GetToken;
- If (TokenType<>ttLeft) then
- ParserError(Format(SErrLeftBracketExpected,[Scanner.Pos,CurrentToken]));
- SetLength(Args,Abs(ACount));
- AI:=0;
- Try
- Repeat
- GetToken;
- // Check if we must enlarge the argument array
- If (ACount<0) and (AI=Length(Args)) then
- begin
- SetLength(Args,AI+1);
- Args[AI]:=Nil;
- end;
- Args[AI]:=Level1;
- Inc(AI);
- If (TokenType<>ttComma) then
- If (AI<Abs(ACount)) then
- ParserError(Format(SErrCommaExpected,[Scanner.Pos,CurrentToken]))
- Until (AI=ACount) or ((ACount<0) and (TokenType=ttRight));
- If TokenType<>ttRight then
- ParserError(Format(SErrBracketExpected,[Scanner.Pos,CurrentToken]));
- except
- On E : Exception do
- begin
- Dec(AI);
- While (AI>=0) do
- begin
- FreeAndNil(Args[Ai]);
- Dec(AI);
- end;
- Raise;
- end;
- end;
- end;
- If Iff then
- Result:=TIfOperation.Create(Args[0],Args[1],Args[2])
- else If IfC then
- Result:=TCaseOperation.Create(Args)
- else
- Case ID.IdentifierType of
- itVariable : Result:= TFPExprVariable.CreateIdentifier(ID);
- itFunctionHandler : Result:= TFPFunctionEventHandler.CreateFunction(ID,Args);
- itFunctionNode : Result:= ID.NodeType.CreateFunction(ID,Args);
- end;
- end;
- GetToken;
- end;
- procedure TFPExpressionParser.SetExpression(const AValue: String);
- begin
- if FExpression=AValue then exit;
- FExpression:=AValue;
- FScanner.Source:=AValue;
- If Assigned(FExprNode) then
- FreeAndNil(FExprNode);
- If (FExpression<>'') then
- begin
- GetToken;
- FExprNode:=Level1;
- If (TokenType<>ttEOF) then
- ParserError(Format(SErrUnterminatedExpression,[Scanner.Pos,CurrentToken]));
- FExprNode.Check;
- end
- else
- FExprNode:=Nil;
- end;
- procedure TFPExpressionParser.CheckResultType(const Res: TFPExpressionResult;
- AType: TResultType); inline;
- begin
- If (Res.ResultType<>AType) then
- RaiseParserError(SErrInvalidResultType,[ResultTypeName(Res.ResultType)]);
- end;
- procedure TFPExpressionParser.CheckResultTypes(const Res: TFPExpressionResult; ATypes: TResultTypes);
- begin
- If Not (Res.ResultType in ATypes) then
- RaiseParserError(SErrInvalidResultType,[ResultTypeName(Res.ResultType)]);
- end;
- class function TFPExpressionParser.BuiltinsManager: TExprBuiltInManager;
- begin
- Result:=BuiltinIdentifiers;
- end;
- function TFPExpressionParser.ResultType: TResultType;
- begin
- if not Assigned(FExprNode) then
- ParserError(SErrInExpression);
- Result:=FExprNode.NodeType;
- end;
- function TFPExpressionParser.HasAggregate: Boolean;
- begin
- Result:=Assigned(FExprNode) and FExprNode.HasAggregate;
- end;
- procedure TFPExpressionParser.InitAggregate;
- begin
- If Assigned(FExprNode) then
- FExprNode.InitAggregate;
- end;
- procedure TFPExpressionParser.UpdateAggregate;
- begin
- If Assigned(FExprNode) then
- FExprNode.UpdateAggregate;
- end;
- { ---------------------------------------------------------------------
- TFPExprIdentifierDefs
- ---------------------------------------------------------------------}
- function TFPExprIdentifierDefs.GetI(AIndex : Integer): TFPExprIdentifierDef;
- begin
- Result:=TFPExprIdentifierDef(Items[AIndex]);
- end;
- procedure TFPExprIdentifierDefs.SetI(AIndex : Integer;
- const AValue: TFPExprIdentifierDef);
- begin
- Items[AIndex]:=AValue;
- end;
- procedure TFPExprIdentifierDefs.Update(Item: TCollectionItem);
- begin
- Inherited Update(Item);
- If Assigned(FParser) then
- FParser.FDirty:=True;
- end;
- function TFPExprIdentifierDefs.IndexOfIdentifier(const AName: string
- ): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) And (CompareText(GetI(Result).Name,AName)<>0) do
- Dec(Result);
- end;
- function TFPExprIdentifierDefs.FindIdentifier(const AName: string
- ): TFPExprIdentifierDef;
- Var
- I : Integer;
- begin
- I:=IndexOfIdentifier(AName);
- If (I=-1) then
- Result:=Nil
- else
- Result:=GetI(I);
- end;
- function TFPExprIdentifierDefs.IdentifierByName(const AName: string
- ): TFPExprIdentifierDef;
- begin
- Result:=FindIdentifier(AName);
- if (Result=Nil) then
- RaiseParserError(SErrUnknownIdentifier,[AName]);
- end;
- function TFPExprIdentifierDefs.AddVariable(const AName: string;
- AResultType: TResultType; ACallback: TFPExprVariableEvent
- ): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=AResultType;
- Result.OnGetVariableValue:=ACallBack
- end;
- function TFPExprIdentifierDefs.AddVariable(const AName: string;
- AResultType: TResultType; AValue: String): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=AResultType;
- Result.Value:=AValue;
- end;
- function TFPExprIdentifierDefs.AddBooleanVariable(const AName: string;
- AValue: Boolean): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtBoolean;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddIntegerVariable(const AName: string;
- AValue: Integer): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtInteger;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddFloatVariable(const AName: string;
- AValue: TExprFloat): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtFloat;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddCurrencyVariable(const AName: string; AValue: Currency): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtCurrency;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddStringVariable(const AName: string;
- AValue: String): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtString;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddDateTimeVariable(const AName: string;
- AValue: TDateTime): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.IdentifierType:=itVariable;
- Result.Name:=AName;
- Result.ResultType:=rtDateTime;
- Result.FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDefs.AddFunction(const AName: string;
- const AResultType: Char; const AParamTypes: String;
- ACallBack: TFPExprFunctionEvent): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.Name:=Aname;
- Result.IdentifierType:=itFunctionHandler;
- Result.ParameterTypes:=AParamTypes;
- Result.ResultType:=CharToResultType(AResultType);
- Result.FOnGetValue:=ACallBack;
- end;
- function TFPExprIdentifierDefs.AddFunction(const AName: string;
- const AResultType: Char; const AParamTypes: String;
- ANodeClass: TFPExprFunctionClass): TFPExprIdentifierDef;
- begin
- Result:=Add as TFPExprIdentifierDef;
- Result.Name:=Aname;
- Result.IdentifierType:=itFunctionNode;
- Result.ParameterTypes:=AParamTypes;
- Result.ResultType:=CharToResultType(AResultType);
- Result.FNodeType:=ANodeClass;
- end;
- { ---------------------------------------------------------------------
- TFPExprIdentifierDef
- ---------------------------------------------------------------------}
- procedure TFPExprIdentifierDef.SetName(const AValue: string);
- begin
- if FName=AValue then exit;
- If (AValue<>'') then
- If Assigned(Collection) and (TFPExprIdentifierDefs(Collection).IndexOfIdentifier(AValue)<>-1) then
- RaiseParserError(SErrDuplicateIdentifier,[AValue]);
- FName:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetResultType(const AValue: TResultType);
- begin
- If AValue<>FValue.ResultType then
- begin
- FValue.ResultType:=AValue;
- SetValue(FStringValue);
- end;
- end;
- procedure TFPExprIdentifierDef.SetValue(const AValue: String);
- begin
- FStringValue:=AValue;
- If (AValue<>'') then
- Case FValue.ResultType of
- rtBoolean : FValue.resValue:=FStringValue='True';
- rtInteger : FValue.resValue:=StrToInt(AValue);
- rtFloat : FValue.resValue:=StrToFloat(AValue);
- rtCurrency : FValue.resValue:=StrToCurr(AValue);
- rtDateTime : FValue.resValue:=StrToDateTime(AValue);
- rtString : FValue.resValue:=AValue;
- end
- else
- Case FValue.ResultType of
- rtBoolean : FValue.resValue:=False;
- rtInteger : FValue.resValue:=0;
- rtFloat : FValue.resValue:=0.0;
- rtCurrency : FValue.resValue:=0.0;
- rtDateTime : FValue.resValue:=0;
- rtString : FValue.resValue:='';
- end
- end;
- procedure TFPExprIdentifierDef.CheckResultType(const AType: TResultType);
- begin
- If FValue.ResultType<>AType then
- RaiseParserError(SErrInvalidResultType,[ResultTypeName(AType)])
- end;
- procedure TFPExprIdentifierDef.CheckVariable;
- begin
- If Identifiertype<>itvariable then
- RaiseParserError(SErrNotVariable,[Name]);
- if EventBasedVariable then
- FetchValue;
- end;
- function TFPExprIdentifierDef.ArgumentCount: Integer;
- begin
- Result:=Length(FArgumentTypes);
- end;
- procedure TFPExprIdentifierDef.Assign(Source: TPersistent);
- Var
- EID : TFPExprIdentifierDef;
- begin
- if (Source is TFPExprIdentifierDef) then
- begin
- EID:=Source as TFPExprIdentifierDef;
- FStringValue:=EID.FStringValue;
- FValue:=EID.FValue;
- FArgumentTypes:=EID.FArgumentTypes;
- FIDType:=EID.FIDType;
- FName:=EID.FName;
- FOnGetValue:=EID.FOnGetValue;
- FOnGetVarValue:=EID.FOnGetVarValue;
- end
- else
- inherited Assign(Source);
- end;
- procedure TFPExprIdentifierDef.SetArgumentTypes(const AValue: String);
- Var
- I : integer;
- begin
- if FArgumentTypes=AValue then exit;
- For I:=1 to Length(AValue) do
- CharToResultType(AValue[i]);
- FArgumentTypes:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsBoolean(const AValue: Boolean);
- begin
- CheckVariable;
- CheckResultType(rtBoolean);
- FValue.resValue:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsDateTime(const AValue: TDateTime);
- begin
- CheckVariable;
- CheckResultType(rtDateTime);
- FValue.resValue:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsFloat(const AValue: TExprFloat);
- begin
- CheckVariable;
- CheckResultType(rtFloat);
- FValue.resValue:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsCurrency(const AValue: Currency);
- begin
- CheckVariable;
- CheckResultType(rtCurrency);
- FValue.resValue:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsInteger(const AValue: NativeInt);
- begin
- CheckVariable;
- CheckResultType(rtInteger);
- FValue.resValue:=AValue;
- end;
- procedure TFPExprIdentifierDef.SetAsString(const AValue: String);
- begin
- CheckVariable;
- CheckResultType(rtString);
- FValue.resValue:=AValue;
- end;
- function TFPExprIdentifierDef.GetValue: String;
- begin
- Case FValue.ResultType of
- rtBoolean : If FValue.resValue then
- Result:='True'
- else
- Result:='False';
- rtInteger : Result:=IntToStr(NativeInt(FValue.resValue));
- rtFloat : Result:=FloatToStr(TExprFloat(FValue.resValue));
- rtCurrency : Result:=CurrToStr(Currency(FValue.resValue));
- rtDateTime : Result:=FormatDateTime('cccc',TExprFloat(FValue.resValue));
- rtString : Result:=String(FValue.resValue);
- end;
- end;
- procedure TFPExprIdentifierDef.FetchValue;
- Var
- RT,RT2 : TResultType;
- I : Integer;
- begin
- RT:=ResultType;
- if Assigned(FOnGetVarValue) then
- FValue:=FOnGetVarValue(FName);
- RT2:=FValue.ResultType;
- if RT2<>RT then
- begin
- // Automatically convert integer to float.
- if (rt2=rtInteger) and (rt=rtFloat) then
- begin
- FValue.ResultType:=RT;
- I:=NativeInt(FValue.resValue);
- FValue.resValue:=I;
- end
- else
- begin
- // Restore
- FValue.ResultType:=RT;
- Raise EExprParser.CreateFmt('Value handler for variable %s returned wrong type, expected "%s", got "%s"',[
- FName,
- GetEnumName(TypeInfo(TResultType),Ord(rt)),
- GetEnumName(TypeInfo(TResultType),Ord(rt2))
- ]);
- end;
- end;
- end;
- function TFPExprIdentifierDef.EventBasedVariable: Boolean;
- begin
- Result:=Assigned(FOnGetVarValue);
- end;
- function TFPExprIdentifierDef.GetResultType: TResultType;
- begin
- Result:=FValue.ResultType;
- end;
- function TFPExprIdentifierDef.GetAsFloat: TExprFloat;
- begin
- CheckResultType(rtFloat);
- CheckVariable;
- Result:=TExprFloat(FValue.resValue);
- end;
- function TFPExprIdentifierDef.GetAsCurrency: Currency;
- begin
- CheckResultType(rtCurrency);
- CheckVariable;
- Result:=Currency(FValue.resValue);
- end;
- function TFPExprIdentifierDef.GetAsBoolean: Boolean;
- begin
- CheckResultType(rtBoolean);
- CheckVariable;
- Result:=Boolean(FValue.resValue);
- end;
- function TFPExprIdentifierDef.GetAsDateTime: TDateTime;
- begin
- CheckResultType(rtDateTime);
- CheckVariable;
- Result:=TDateTime(FValue.resValue);
- end;
- function TFPExprIdentifierDef.GetAsInteger: NativeInt;
- begin
- CheckResultType(rtInteger);
- CheckVariable;
- Result:=NativeInt(FValue.resValue);
- end;
- function TFPExprIdentifierDef.GetAsString: String;
- begin
- CheckResultType(rtString);
- CheckVariable;
- Result:=String(FValue.resValue);
- end;
- { ---------------------------------------------------------------------
- TExprBuiltInManager
- ---------------------------------------------------------------------}
- function TExprBuiltInManager.GetCount: Integer;
- begin
- Result:=FDefs.Count;
- end;
- function TExprBuiltInManager.GetI(AIndex : Integer
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs[Aindex])
- end;
- constructor TExprBuiltInManager.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FDefs:=TFPExprIdentifierDefs.Create(TFPBuiltInExprIdentifierDef)
- end;
- destructor TExprBuiltInManager.Destroy;
- begin
- FreeAndNil(FDefs);
- inherited Destroy;
- end;
- function TExprBuiltInManager.IndexOfIdentifier(const AName: string
- ): Integer;
- begin
- Result:=FDefs.IndexOfIdentifier(AName);
- end;
- function TExprBuiltInManager.FindIdentifier(const AName: string
- ): TFPBuiltinExprIdentifierDef;
- begin
- Result:=TFPBuiltinExprIdentifierDef(FDefs.FindIdentifier(AName));
- end;
- function TExprBuiltInManager.IdentifierByName(const AName: string
- ): TFPBuiltinExprIdentifierDef;
- begin
- Result:=TFPBuiltinExprIdentifierDef(FDefs.IdentifierByName(AName));
- end;
- function TExprBuiltInManager.AddVariable(const ACategory: TBuiltInCategory;
- const AName: string; AResultType: TResultType; AValue: String
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.Addvariable(AName,AResultType,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddBooleanVariable(
- const ACategory: TBuiltInCategory; const AName: string; AValue: Boolean
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddBooleanvariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddIntegerVariable(
- const ACategory: TBuiltInCategory; const AName: string; AValue: Integer
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddIntegerVariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddFloatVariable(
- const ACategory: TBuiltInCategory; const AName: string;
- AValue: TExprFloat): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddFloatVariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddCurrencyVariable(const ACategory: TBuiltInCategory; const AName: string; AValue: Currency
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddCurrencyVariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddStringVariable(
- const ACategory: TBuiltInCategory; const AName: string; AValue: String
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddStringVariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddDateTimeVariable(
- const ACategory: TBuiltInCategory; const AName: string; AValue: TDateTime
- ): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddDateTimeVariable(AName,AValue));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddFunction(const ACategory: TBuiltInCategory;
- const AName: string; const AResultType: Char; const AParamTypes: String;
- ACallBack: TFPExprFunctionEvent): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddFunction(AName,AResultType,AParamTypes,ACallBack));
- Result.Category:=ACategory;
- end;
- function TExprBuiltInManager.AddFunction(const ACategory: TBuiltInCategory;
- const AName: string; const AResultType: Char; const AParamTypes: String;
- ANodeClass: TFPExprFunctionClass): TFPBuiltInExprIdentifierDef;
- begin
- Result:=TFPBuiltInExprIdentifierDef(FDefs.AddFunction(AName,AResultType,AParamTypes,ANodeClass));
- Result. Category:=ACategory;
- end;
- { ---------------------------------------------------------------------
- Various Nodes
- ---------------------------------------------------------------------}
- { TFPBinaryOperation }
- procedure TFPBinaryOperation.CheckSameNodeTypes;
- Var
- LT,RT : TResultType;
- begin
- LT:=Left.NodeType;
- RT:=Right.NodeType;
- if (RT<>LT) then
- RaiseParserError(SErrTypesDoNotMatch,[ResultTypeName(LT),ResultTypeName(RT),Left.AsString,Right.AsString])
- end;
- constructor TFPBinaryOperation.Create(ALeft, ARight: TFPExprNode);
- begin
- FLeft:=ALeft;
- FRight:=ARight;
- end;
- destructor TFPBinaryOperation.Destroy;
- begin
- FreeAndNil(FLeft);
- FreeAndNil(FRight);
- inherited Destroy;
- end;
- procedure TFPBinaryOperation.InitAggregate;
- begin
- inherited InitAggregate;
- if Assigned(Left) then
- Left.InitAggregate;
- if Assigned(Right) then
- Right.InitAggregate;
- end;
- procedure TFPBinaryOperation.UpdateAggregate;
- begin
- inherited UpdateAggregate;
- if Assigned(Left) then
- Left.UpdateAggregate;
- if Assigned(Right) then
- Right.UpdateAggregate;
- end;
- function TFPBinaryOperation.HasAggregate: Boolean;
- begin
- Result:=inherited HasAggregate;
- if Assigned(Left) then
- Result:=Result or Left.HasAggregate;
- if Assigned(Right) then
- Result:=Result or Right.HasAggregate;
- end;
- procedure TFPBinaryOperation.Check;
- begin
- If Not Assigned(Left) then
- RaiseParserError(SErrNoLeftOperand,[classname]);
- If Not Assigned(Right) then
- RaiseParserError(SErrNoRightOperand,[classname]);
- end;
- { TFPUnaryOperator }
- constructor TFPUnaryOperator.Create(AOperand: TFPExprNode);
- begin
- FOperand:=AOperand;
- end;
- destructor TFPUnaryOperator.Destroy;
- begin
- FreeAndNil(FOperand);
- inherited Destroy;
- end;
- procedure TFPUnaryOperator.InitAggregate;
- begin
- inherited InitAggregate;
- if Assigned(FOperand) then
- FOperand.InitAggregate;
- end;
- procedure TFPUnaryOperator.UpdateAggregate;
- begin
- inherited UpdateAggregate;
- if Assigned(FOperand) then
- FOperand.UpdateAggregate;
- end;
- function TFPUnaryOperator.HasAggregate: Boolean;
- begin
- Result:=inherited HasAggregate;
- if Assigned(FOperand) then
- Result:=Result or FOperand.HasAggregate;
- end;
- procedure TFPUnaryOperator.Check;
- begin
- If Not Assigned(Operand) then
- RaiseParserError(SErrNoOperand,[Self.className]);
- end;
- { TFPConstExpression }
- constructor TFPConstExpression.CreateString(AValue: String);
- begin
- FValue.ResultType:=rtString;
- FValue.resValue:=AValue;
- end;
- constructor TFPConstExpression.CreateInteger(AValue: NativeInt);
- begin
- FValue.ResultType:=rtInteger;
- FValue.resValue:=AValue;
- end;
- constructor TFPConstExpression.CreateDateTime(AValue: TDateTime);
- begin
- FValue.ResultType:=rtDateTime;
- FValue.resValue:=AValue;
- end;
- constructor TFPConstExpression.CreateFloat(AValue: TExprFloat);
- begin
- Inherited create;
- FValue.ResultType:=rtFloat;
- FValue.resValue:=AValue;
- end;
- constructor TFPConstExpression.CreateCurrency(AValue: Currency);
- begin
- Inherited create;
- FValue.ResultType:=rtCurrency;
- FValue.resValue:=AValue;
- end;
- constructor TFPConstExpression.CreateBoolean(AValue: Boolean);
- begin
- FValue.ResultType:=rtBoolean;
- FValue.resValue:=AValue;
- end;
- procedure TFPConstExpression.Check;
- begin
- // Nothing to check;
- end;
- function TFPConstExpression.NodeType: TResultType;
- begin
- Result:=FValue.ResultType;
- end;
- Function TFPConstExpression.GetNodeValue : TFPExpressionResult;
- begin
- Result:=FValue;
- end;
- function TFPConstExpression.AsString: string ;
- begin
- Case NodeType of
- rtString : Result:=''''+String(FValue.resValue)+'''';
- rtInteger : Result:=IntToStr(NativeInt(FValue.resValue));
- rtDateTime : Result:=''''+FormatDateTime('cccc',TDateTime(FValue.resValue))+'''';
- rtBoolean : If Boolean(FValue.resValue) then Result:='True' else Result:='False';
- rtFloat : Str(TExprFloat(FValue.resValue),Result);
- rtCurrency : Str(Currency(FValue.resValue),Result);
- end;
- end;
- { TFPNegateOperation }
- procedure TFPNegateOperation.Check;
- begin
- Inherited;
- If Not (Operand.NodeType in [rtInteger,rtFloat,rtCurrency]) then
- RaiseParserError(SErrNoNegation,[ResultTypeName(Operand.NodeType),Operand.AsString])
- end;
- function TFPNegateOperation.NodeType: TResultType;
- begin
- Result:=Operand.NodeType;
- end;
- Function TFPNegateOperation.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Case Result.ResultType of
- rtInteger : Result.resValue:=-NativeInt(Result.resValue);
- rtFloat : Result.resValue:=-TExprFloat(Result.resValue);
- rtCurrency : Result.resValue:=-Currency(Result.resValue);
- end;
- end;
- function TFPNegateOperation.AsString: String;
- begin
- Result:='-'+TrimLeft(Operand.AsString);
- end;
- { TFPBinaryAndOperation }
- procedure TFPBooleanOperation.Check;
- begin
- inherited Check;
- CheckNodeType(Left,[rtInteger,rtBoolean]);
- CheckNodeType(Right,[rtInteger,rtBoolean]);
- CheckSameNodeTypes;
- end;
- function TFPBooleanOperation.NodeType: TResultType;
- begin
- Result:=Left.NodeType;
- end;
- Function TFPBinaryAndOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Case Result.ResultType of
- rtBoolean : Result.resValue:=Boolean(Result.resValue) and Boolean(RRes.resValue);
- rtInteger : Result.resValue:=NativeInt(Result.resValue) and NativeInt(RRes.resValue);
- end;
- end;
- function TFPBinaryAndOperation.AsString: string;
- begin
- Result:=Left.AsString+' and '+Right.AsString;
- end;
- { TFPExprNode }
- procedure TFPExprNode.CheckNodeType(Anode: TFPExprNode; Allowed: TResultTypes);
- Var
- S : String;
- A : TResultType;
- begin
- If (Anode=Nil) then
- RaiseParserError(SErrNoNodeToCheck);
- If Not (ANode.NodeType in Allowed) then
- begin
- S:='';
- For A:=Low(TResultType) to High(TResultType) do
- If A in Allowed then
- begin
- If S<>'' then
- S:=S+',';
- S:=S+ResultTypeName(A);
- end;
- RaiseParserError(SInvalidNodeType,[ResultTypeName(ANode.NodeType),S,ANode.AsString]);
- end;
- end;
- procedure TFPExprNode.InitAggregate;
- begin
- // Do nothing
- end;
- procedure TFPExprNode.UpdateAggregate;
- begin
- // Do nothing
- end;
- function TFPExprNode.HasAggregate: Boolean;
- begin
- Result:=IsAggregate;
- end;
- class function TFPExprNode.IsAggregate: Boolean;
- begin
- Result:=False;
- end;
- function TFPExprNode.NodeValue: TFPExpressionResult;
- begin
- Result:=GetNodeValue;
- end;
- { TFPBinaryOrOperation }
- function TFPBinaryOrOperation.AsString: string;
- begin
- Result:=Left.AsString+' or '+Right.AsString;
- end;
- Function TFPBinaryOrOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Case Result.ResultType of
- rtBoolean : Result.resValue:=Boolean(Result.resValue) or Boolean(RRes.resValue);
- rtInteger : Result.resValue:=NativeInt(Result.resValue) or NativeInt(RRes.resValue);
- end;
- end;
- { TFPBinaryXOrOperation }
- function TFPBinaryXOrOperation.AsString: string;
- begin
- Result:=Left.AsString+' xor '+Right.AsString;
- end;
- Function TFPBinaryXOrOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Case Result.ResultType of
- rtBoolean : Result.resValue:=Boolean(Result.resValue) xor Boolean(RRes.resValue);
- rtInteger : Result.resValue:=NativeInt(Result.resValue) xor NativeInt(RRes.resValue);
- end;
- end;
- { TFPNotNode }
- procedure TFPNotNode.Check;
- begin
- If Not (Operand.NodeType in [rtInteger,rtBoolean]) then
- RaiseParserError(SErrNoNotOperation,[ResultTypeName(Operand.NodeType),Operand.AsString])
- end;
- function TFPNotNode.NodeType: TResultType;
- begin
- Result:=Operand.NodeType;
- end;
- Function TFPNotNode.GetNodeValue: TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Case result.ResultType of
- rtInteger : Result.resValue:=Not Result.resValue;
- rtBoolean : Result.resValue:=Not Result.resValue;
- end
- end;
- function TFPNotNode.AsString: String;
- begin
- Result:='not '+Operand.AsString;
- end;
- { TIfOperation }
- constructor TIfOperation.Create(ACondition, ALeft, ARight: TFPExprNode);
- begin
- Inherited Create(ALeft,ARight);
- FCondition:=ACondition;
- end;
- destructor TIfOperation.destroy;
- begin
- FreeAndNil(FCondition);
- inherited destroy;
- end;
- Function TIfOperation.GetNodeValue: TFPExpressionResult;
- begin
- Result:=FCondition.GetNodeValue;
- If Boolean(Result.resValue) then
- Result:=Left.GetNodeValue
- else
- Result:=Right.GetNodeValue;
- end;
- procedure TIfOperation.Check;
- begin
- inherited Check;
- if (Condition.NodeType<>rtBoolean) then
- RaiseParserError(SErrIFNeedsBoolean,[Condition.AsString]);
- CheckSameNodeTypes;
- end;
- procedure TIfOperation.InitAggregate;
- begin
- inherited InitAggregate;
- If Assigned(FCondition) then
- fCondition.InitAggregate;
- end;
- procedure TIfOperation.UpdateAggregate;
- begin
- inherited UpdateAggregate;
- If Assigned(FCondition) then
- FCondition.UpdateAggregate;
- end;
- function TIfOperation.HasAggregate: Boolean;
- begin
- Result:=inherited HasAggregate;
- if Assigned(Condition) then
- Result:=Result or Condition.HasAggregate;
- end;
- function TIfOperation.NodeType: TResultType;
- begin
- Result:=Left.NodeType;
- end;
- function TIfOperation.AsString: string;
- begin
- Result:=Format('if(%s , %s , %s)',[Condition.AsString,Left.AsString,Right.AsString]);
- end;
- { TCaseOperation }
- Function TCaseOperation.GetNodeValue: TFPExpressionResult;
- Var
- I,L : Integer;
- B : Boolean;
- RT,RV : TFPExpressionResult;
- begin
- RT:=FArgs[0].GetNodeValue;
- L:=Length(FArgs);
- I:=2;
- B:=False;
- While (Not B) and (I<L) do
- begin
- Result:=FArgs[i].GetNodeValue;
- Case RT.ResultType of
- rtBoolean : B:=RT.resValue=RV.resValue;
- rtInteger : B:=RT.resValue=RV.resValue;
- rtFloat : B:=RT.resValue=RV.resValue;
- rtCurrency : B:=RT.resValue=RV.resValue;
- rtDateTime : B:=RT.resValue=RV.resValue;
- rtString : B:=RT.resValue=RV.resValue;
- end;
- If Not B then
- Inc(I,2);
- end;
- // Set result type.
- Result.ResultType:=FArgs[1].NodeType;
- If B then
- Result:=FArgs[I+1].GetNodeValue
- else if ((L mod 2)=0) then
- Result:=FArgs[1].GetNodeValue;
- end;
- procedure TCaseOperation.Check;
- Var
- T,V : TResultType;
- I : Integer;
- N : TFPExprNode;
- begin
- If (Length(FArgs)<3) then
- RaiseParserError(SErrCaseNeeds3);
- If ((Length(FArgs) mod 2)=1) then
- RaiseParserError(SErrCaseEvenCount);
- T:=FArgs[0].NodeType;
- V:=FArgs[1].NodeType;
- For I:=2 to Length(Fargs)-1 do
- begin
- N:=FArgs[I];
- // Even argument types (labels) must equal tag.
- If ((I mod 2)=0) then
- begin
- If Not (N is TFPConstExpression) then
- RaiseParserError(SErrCaseLabelNotAConst,[I div 2,N.AsString]);
- If (N.NodeType<>T) then
- RaiseParserError(SErrCaseLabelType,[I div 2,N.AsString,ResultTypeName(T),ResultTypeName(N.NodeType)]);
- end
- else // Odd argument types (values) must match first.
- begin
- If (N.NodeType<>V) then
- RaiseParserError(SErrCaseValueType,[(I-1)div 2,N.AsString,ResultTypeName(V),ResultTypeName(N.NodeType)]);
- end
- end;
- end;
- procedure TCaseOperation.InitAggregate;
- Var
- I : Integer;
- begin
- inherited InitAggregate;
- if Assigned(FCondition) then
- FCondition.InitAggregate;
- For I:=0 to Length(Fargs)-1 do
- FArgs[i].InitAggregate;
- end;
- procedure TCaseOperation.UpdateAggregate;
- Var
- I : Integer;
- begin
- inherited UpdateAggregate;
- if Assigned(FCondition) then
- FCondition.UpdateAggregate;
- For I:=0 to Length(Fargs)-1 do
- FArgs[i].InitAggregate;
- end;
- Function TCaseOperation.HasAggregate : Boolean;
- Var
- I,L : Integer;
- begin
- Result:=inherited HasAggregate;
- L:=Length(Fargs);
- I:=0;
- While (Not Result) and (I<L) do
- begin
- Result:=Result or FArgs[i].HasAggregate;
- Inc(I)
- end;
- end;
- function TCaseOperation.NodeType: TResultType;
- begin
- Result:=FArgs[1].NodeType;
- end;
- constructor TCaseOperation.Create(Args: TExprArgumentArray);
- begin
- Fargs:=Args;
- end;
- destructor TCaseOperation.destroy;
- Var
- I : Integer;
- begin
- For I:=0 to Length(FArgs)-1 do
- FreeAndNil(Fargs[I]);
- inherited destroy;
- end;
- function TCaseOperation.AsString: string;
- Var
- I : integer;
- begin
- Result:='';
- For I:=0 to Length(FArgs)-1 do
- begin
- If (Result<>'') then
- Result:=Result+', ';
- Result:=Result+FArgs[i].AsString;
- end;
- Result:='Case('+Result+')';
- end;
- { TFPBooleanResultOperation }
- procedure TFPBooleanResultOperation.Check;
- begin
- inherited Check;
- CheckSameNodeTypes;
- end;
- function TFPBooleanResultOperation.NodeType: TResultType;
- begin
- Result:=rtBoolean;
- end;
- { TFPEqualOperation }
- function TFPEqualOperation.AsString: string;
- begin
- Result:=Left.AsString+' = '+Right.AsString;
- end;
- Function TFPEqualOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Result.resValue:=Result.resValue=RRes.resValue;
- Result.ResultType:=rtBoolean;
- end;
- { TFPUnequalOperation }
- function TFPUnequalOperation.AsString: string;
- begin
- Result:=Left.AsString+' <> '+Right.AsString;
- end;
- Function TFPUnequalOperation.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Inherited GetNodeValue;
- Result.resValue:=Not Result.resValue;
- end;
- { TFPLessThanOperation }
- function TFPLessThanOperation.AsString: string;
- begin
- Result:=Left.AsString+' < '+Right.AsString;
- end;
- Function TFPLessThanOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Case Result.ResultType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)<NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)<TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=Currency(Result.resValue)<Currency(RRes.resValue);
- rtDateTime : Result.resValue:=TDateTime(Result.resValue)<TDateTime(RRes.resValue);
- rtString : Result.resValue:=String(Result.resValue)<String(RRes.resValue);
- end;
- Result.ResultType:=rtBoolean;
- end;
- { TFPGreaterThanOperation }
- function TFPGreaterThanOperation.AsString: string;
- begin
- Result:=Left.AsString+' > '+Right.AsString;
- end;
- Function TFPGreaterThanOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Case Result.ResultType of
- rtInteger : case Right.NodeType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)>NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=NativeInt(Result.resValue)>TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=NativeINt(Result.resValue)>Currency(RRes.resValue);
- end;
- rtFloat : case Right.NodeType of
- rtInteger : Result.resValue:=TExprFloat(Result.resValue)>NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)>TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=TExprFloat(Result.resValue)>Currency(RRes.resValue);
- end;
- rtCurrency : case Right.NodeType of
- rtInteger : Result.resValue:=Currency(Result.resValue)>NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=Currency(Result.resValue)>TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=Currency(Result.resValue)>Currency(RRes.resValue);
- end;
- rtDateTime : Result.resValue:=TDateTime(Result.resValue)>TDateTime(RRes.resValue);
- rtString : Result.resValue:=String(Result.resValue)>String(RRes.resValue);
- end;
- Result.ResultType:=rtBoolean;
- end;
- { TFPGreaterThanEqualOperation }
- function TFPGreaterThanEqualOperation.AsString: string;
- begin
- Result:=Left.AsString+' >= '+Right.AsString;
- end;
- Function TFPGreaterThanEqualOperation.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Inherited GetNodeValue;
- Result.resValue:=Not Result.resValue;
- end;
- { TFPLessThanEqualOperation }
- function TFPLessThanEqualOperation.AsString: string;
- begin
- Result:=Left.AsString+' <= '+Right.AsString;
- end;
- Function TFPLessThanEqualOperation.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Inherited GetNodeValue;
- Result.resValue:=Not Result.resValue;
- end;
- { TFPOrderingOperation }
- procedure TFPOrderingOperation.Check;
- Const
- AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime,rtString];
- begin
- CheckNodeType(Left,AllowedTypes);
- CheckNodeType(Right,AllowedTypes);
- inherited Check;
- end;
- { TMathOperation }
- procedure TMathOperation.Check;
- Const
- AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime,rtString];
- begin
- inherited Check;
- CheckNodeType(Left,AllowedTypes);
- CheckNodeType(Right,AllowedTypes);
- CheckSameNodeTypes;
- end;
- function TMathOperation.NodeType: TResultType;
- begin
- Result:=Left.NodeType;
- end;
- { TFPAddOperation }
- function TFPAddOperation.AsString: string;
- begin
- Result:=Left.AsString+' + '+Right.asString;
- end;
- Function TFPAddOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- case Result.ResultType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)+NativeInt(RRes.resValue);
- rtString : Result.resValue:=String(Result.resValue)+String(RRes.resValue);
- rtDateTime : Result.resValue:=TDateTime(Result.resValue)+TDateTime(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)+TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=Currency(Result.resValue)+Currency(RRes.resValue);
- end;
- Result.ResultType:=NodeType;
- end;
- { TFPSubtractOperation }
- procedure TFPSubtractOperation.check;
- Const
- AllowedTypes =[rtInteger,rtfloat,rtCurrency,rtDateTime];
- begin
- CheckNodeType(Left,AllowedTypes);
- CheckNodeType(Right,AllowedTypes);
- inherited check;
- end;
- function TFPSubtractOperation.AsString: string;
- begin
- Result:=Left.AsString+' - '+Right.asString;
- end;
- Function TFPSubtractOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- case Result.ResultType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)-NativeInt(RRes.resValue);
- rtDateTime : Result.resValue:=TDateTime(Result.resValue)-TDateTime(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)-TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=Currency(Result.resValue)-Currency(RRes.resValue);
- end;
- end;
- { TFPMultiplyOperation }
- procedure TFPMultiplyOperation.check;
- Const
- AllowedTypes =[rtInteger,rtCurrency,rtfloat];
- begin
- CheckNodeType(Left,AllowedTypes);
- CheckNodeType(Right,AllowedTypes);
- Inherited;
- end;
- function TFPMultiplyOperation.AsString: string;
- begin
- Result:=Left.AsString+' * '+Right.asString;
- end;
- Function TFPMultiplyOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- case Result.ResultType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)*NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)*TExprFloat(RRes.resValue);
- rtCurrency : Result.resValue:=Currency(Result.resValue)*Currency(RRes.resValue);
- end;
- end;
- { TFPDivideOperation }
- procedure TFPDivideOperation.check;
- Const
- AllowedTypes =[rtInteger,rtCurrency,rtfloat];
- begin
- CheckNodeType(Left,AllowedTypes);
- CheckNodeType(Right,AllowedTypes);
- inherited check;
- end;
- function TFPDivideOperation.AsString: string;
- begin
- Result:=Left.AsString+' / '+Right.asString;
- end;
- function TFPDivideOperation.NodeType: TResultType;
- begin
- if (Left.NodeType=rtCurrency) and (Right.NodeType=rtCurrency) then
- Result:=rtCurrency
- else
- Result:=rtFloat;
- end;
- Function TFPDivideOperation.GetNodeValue : TFPExpressionResult;
- Var
- RRes : TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- case Result.ResultType of
- rtInteger : Result.resValue:=NativeInt(Result.resValue)/NativeInt(RRes.resValue);
- rtFloat : Result.resValue:=TExprFloat(Result.resValue)/TExprFloat(RRes.resValue);
- rtCurrency :
- if NodeType=rtCurrency then
- Result.resValue:=Currency(Result.resValue)/Currency(RRes.resValue)
- else
- Result.resValue:=TExprFloat(Result.resValue)/TExprFloat(RRes.resValue);
- end;
- Result.ResultType:=NodeType;
- end;
- { TFPPowerOperation }
- procedure TFPPowerOperation.Check;
- const
- AllowedTypes = [rtInteger, rtCurrency, rtFloat];
- begin
- CheckNodeType(Left, AllowedTypes);
- CheckNodeType(Right, AllowedTypes);
- end;
- function TFPPowerOperation.AsString: String;
- begin
- Result := Left.AsString + '^' + Right.AsString;
- end;
- function TFPPowerOperation.NodeType: TResultType;
- begin
- Result := rtFloat;
- end;
- function power(base,exponent: TExprFloat): TExprFloat;
- // Adapted from unit "math"
- var
- ex: Integer;
- begin
- if Exponent = 0.0 then
- result := 1.0
- else if (base = 0.0) and (exponent > 0.0) then
- result := 0.0
- else if (base < 0.0) and (frac(exponent) = 0.0) then
- begin
- ex := round(exponent);
- result := exp( exponent * ln(-base));
- if odd(ex) then result := -result;
- end
- else
- result := exp( exponent * ln(base) );
- end;
- Function TFPPowerOperation.GetNodeValue: TFPExpressionResult;
- var
- RRes: TFPExpressionResult;
- begin
- Result:=Left.GetNodeValue;
- RRes:=Right.GetNodeValue;
- Result.resValue := power(ArgToFloat(Result), ArgToFloat(RRes));
- Result.ResultType := rtFloat;
- end;
- { TFPConvertNode }
- function TFPConvertNode.AsString: String;
- begin
- Result:=Operand.AsString;
- end;
- { TIntToFloatNode }
- procedure TIntConvertNode.Check;
- begin
- inherited Check;
- CheckNodeType(Operand,[rtInteger])
- end;
- function TIntToFloatNode.NodeType: TResultType;
- begin
- Result:=rtFloat;
- end;
- Function TIntToFloatNode.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.resValue:=Result.resValue;
- Result.ResultType:=rtFloat;
- end;
- { TIntToDateTimeNode }
- function TIntToDateTimeNode.NodeType: TResultType;
- begin
- Result:=rtDatetime;
- end;
- Function TIntToDateTimeNode.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.ResultType:=rtDateTime;
- end;
- { TFloatToDateTimeNode }
- procedure TFloatToDateTimeNode.Check;
- begin
- inherited Check;
- CheckNodeType(Operand,[rtFloat]);
- end;
- function TFloatToDateTimeNode.NodeType: TResultType;
- begin
- Result:=rtDateTime;
- end;
- Function TFloatToDateTimeNode.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.ResultType:=rtDateTime;
- end;
- { TCurrencyToDateTimeNode }
- procedure TCurrencyToDateTimeNode.Check;
- begin
- inherited Check;
- CheckNodeType(Operand,[rtCurrency]);
- end;
- function TCurrencyToDateTimeNode.NodeType: TResultType;
- begin
- Result:=rtDateTime;
- end;
- Function TCurrencyToDateTimeNode.GetNodeValue : TFPExpressionResult;
- Var
- R : TFPExpressionResult;
- begin
- R:=Operand.GetNodeValue;
- Result.resValue:=Currency(R.resValue);
- Result.ResultType:=rtDateTime;
- end;
- { TCurrencyToFloatNode }
- procedure TCurrencyToFloatNode.Check;
- begin
- inherited Check;
- CheckNodeType(Operand,[rtCurrency]);
- end;
- function TCurrencyToFloatNode.NodeType: TResultType;
- begin
- Result:=rtFloat;
- end;
- Function TCurrencyToFloatNode.GetNodeValue : TFPExpressionResult;
- begin
- Result:=Operand.GetNodeValue;
- Result.resValue:=Currency(Result.resValue);
- Result.ResultType:=rtFloat;
- end;
- { TFPExprIdentifierNode }
- constructor TFPExprIdentifierNode.CreateIdentifier(AID: TFPExprIdentifierDef);
- begin
- Inherited Create;
- FID:=AID;
- PResult:[email protected];
- FResultType:=FID.ResultType;
- end;
- function TFPExprIdentifierNode.NodeType: TResultType;
- begin
- Result:=FResultType;
- end;
- Function TFPExprIdentifierNode.GetNodeValue : TFPExpressionResult;
- begin
- if Identifier.EventBasedVariable then
- begin
- Identifier.FetchValue;
- PResult:[email protected];
- end;
- Result:=PResult^;
- Result.ResultType:=FResultType;
- end;
- { TFPExprVariable }
- procedure TFPExprVariable.Check;
- begin
- // Do nothing;
- end;
- function TFPExprVariable.AsString: string;
- begin
- Result:=FID.Name;
- end;
- { TFPExprFunction }
- procedure TFPExprFunction.CalcParams;
- Var
- I : Integer;
- begin
- For I:=0 to Length(FArgumentParams)-1 do
- begin
- FArgumentParams[i]:=FArgumentNodes[i].GetNodeValue;
- end;
- end;
- Function TFPExprFunction.ConvertArgument(aIndex : Integer; aNode : TFPExprNode; aType : TResultType) : TFPExprNode;
- Var
- N : TFPExprNode;
- begin
- // Automatically convert integers to floats for float/currency parameters
- N:=TFPExpressionParser.ConvertNode(aNode,aType);
- if (aNode=N) then
- // No conversion was performed, raise error
- RaiseParserError(SErrInvalidArgumentType,[aIndex,ResultTypeName(aType),ResultTypeName(aNode.NodeType)]);
- Result:=N;
- end;
- function TFPExprFunction.HasAggregate: Boolean;
- var
- I: Integer;
- begin
- Result := true;
- if IsAggregate then
- exit;
- For I:=0 to Length(FArgumentNodes)-1 do
- if FArgumentNodes[I].HasAggregate then
- exit;
- Result := false;
- end;
- procedure TFPExprFunction.Check;
- Var
- I : Integer;
- rtp,rta : TResultType;
- begin
- If Length(FArgumentNodes)<>FID.ArgumentCount then
- RaiseParserError(ErrInvalidArgumentCount,[FID.Name]);
- For I:=0 to Length(FArgumentNodes)-1 do
- begin
- rtp:=CharToResultType(FID.ParameterTypes[i+1]);
- rta:=FArgumentNodes[i].NodeType;
- If (rtp<>rta) then
- FArgumentNodes[i]:=ConvertArgument(I+1,FArgumentNodes[i],rtp);
- end;
- end;
- constructor TFPExprFunction.CreateFunction(AID: TFPExprIdentifierDef; const Args: TExprArgumentArray);
- begin
- Inherited CreateIdentifier(AID);
- FArgumentNodes:=Args;
- SetLength(FArgumentParams,Length(Args));
- end;
- destructor TFPExprFunction.Destroy;
- Var
- I : Integer;
- begin
- For I:=0 to Length(FArgumentNodes)-1 do
- FreeAndNil(FArgumentNodes[I]);
- inherited Destroy;
- end;
- procedure TFPExprFunction.InitAggregate;
- var
- I: Integer;
- begin
- For I:=0 to Length(FArgumentNodes)-1 do
- FArgumentNodes[i].InitAggregate;
- end;
- procedure TFPExprFunction.UpdateAggregate;
- var
- I: Integer;
- begin
- For I:=0 to Length(FArgumentNodes)-1 do
- FArgumentNodes[i].UpdateAggregate;
- end;
- function TFPExprFunction.AsString: String;
- Var
- S : String;
- I : Integer;
- begin
- S:='';
- For I:=0 to length(FArgumentNodes)-1 do
- begin
- If (S<>'') then
- S:=S+',';
- S:=S+FArgumentNodes[I].AsString;
- end;
- If (S<>'') then
- S:='('+S+')';
- Result:=FID.Name+S;
- end;
- { TFPFunctionEventHandler }
- constructor TFPFunctionEventHandler.CreateFunction(AID: TFPExprIdentifierDef;
- Const Args : TExprArgumentArray);
- begin
- Inherited;
- FCallBack:=AID.OnGetFunctionValue;
- end;
- Function TFPFunctionEventHandler.GetNodeValue : TFPExpressionResult;
- begin
- If Length(FArgumentParams)>0 then
- CalcParams;
- Result:=FCallBack(FArgumentParams);
- Result.ResultType:=NodeType;
- end;
- { ---------------------------------------------------------------------
- Standard Builtins support
- ---------------------------------------------------------------------}
- { Template for builtin.
- Procedure MyCallback (Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
- begin
- end;
- }
- function ArgToFloat(Arg: TFPExpressionResult): TExprFloat;
- // Utility function for the built-in math functions. Accepts also integers
- // in place of the floating point arguments. To be called in builtins or
- // user-defined callbacks having float results.
- begin
- if Arg.ResultType = rtInteger then
- result := NativeInt(Arg.resValue)
- else if Arg.ResultType = rtCurrency then
- result := Currency(Arg.resValue)
- else
- result := TExprFloat(Arg.resValue);
- end;
- // Math builtins
- Function BuiltInCos(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Cos(ArgToFloat(Args[0]));
- end;
- Function BuiltInSin(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Sin(ArgToFloat(Args[0]));
- end;
- (*
- Function BuiltInArcTan(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- // Result.resValue:=Arctan(ArgToFloat(Args[0]));
- end;
- *)
- Function BuiltInAbs(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Abs(ArgToFloat(Args[0]));
- end;
- Function BuiltInSqr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Sqr(ArgToFloat(Args[0]));
- end;
- Function BuiltInSqrt(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Sqrt(ArgToFloat(Args[0]));
- end;
- Function BuiltInExp(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Exp(ArgToFloat(Args[0]));
- end;
- Function BuiltInLn(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Ln(ArgToFloat(Args[0]));
- end;
- Var
- L10 : TExprFloat;
- Function BuiltInLog(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=Ln(ArgToFloat(Args[0]))/L10;
- end;
- Function BuiltInRound(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=Round(ArgToFloat(Args[0]));
- end;
- Function BuiltInTrunc(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=Trunc(ArgToFloat(Args[0]));
- end;
- Function BuiltInInt(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=Int(ArgToFloat(Args[0]));
- end;
- Function BuiltInFrac(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=frac(ArgToFloat(Args[0]));
- end;
- // String builtins
- Function BuiltInLength(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=Length(String(Args[0].resValue));
- end;
- Function BuiltInCopy(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=Copy(String(Args[0].resValue),NativeInt(Args[1].resValue),NativeInt(Args[2].resValue));
- end;
- Function BuiltInDelete(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- S : String;
- begin
- Result.ResultType:=rtString;
- S:=String(Args[0].resValue);
- Delete(S,NativeInt(Args[1].resValue),NativeInt(Args[2].resValue));
- Result.resValue:=S;
- end;
- Function BuiltInPos(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- result.ResultType:=rtInteger;
- Result.resValue:=Pos(String(Args[0].resValue),String(Args[1].resValue));
- end;
- Function BuiltInUppercase(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=Uppercase(String(Args[0].resValue));
- end;
- Function BuiltInLowercase(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=Lowercase(String(Args[0].resValue));
- end;
- Function BuiltInStringReplace(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- F : TReplaceFlags;
- begin
- Result.ResultType:=rtString;
- F:=[];
- If Boolean(Args[3].resValue) then
- Include(F,rfReplaceAll);
- If Boolean(Args[4].resValue) then
- Include(F,rfIgnoreCase);
- Result.resValue:=StringReplace(String(Args[0].resValue),String(Args[1].resValue),String(Args[2].resValue),f);
- end;
- Function BuiltInCompareText(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=CompareText(String(Args[0].resValue),String(Args[1].resValue));
- end;
- // Date/Time builtins
- Function BuiltInDate(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- if Args=nil then ;
- Result.ResultType:=rtDateTime;
- Result.resValue:=Date;
- end;
- Function BuiltInTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- if Args=nil then ;
- Result.ResultType:=rtDateTime;
- Result.resValue:=Time;
- end;
- Function BuiltInNow(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- if Args=nil then ;
- Result.ResultType:=rtDateTime;
- Result.resValue:=Now;
- end;
- Function BuiltInDayofWeek(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=DayOfWeek(TDateTime(Args[0].resValue));
- end;
- Function BuiltInExtractYear(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- Y,M,D : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeDate(TDateTime(Args[0].resValue),Y,M,D);
- Result.resValue:=Y;
- end;
- Function BuiltInExtractMonth(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- Y,M,D : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeDate(TDateTime(Args[0].resValue),Y,M,D);
- Result.resValue:=M;
- end;
- Function BuiltInExtractDay(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- Y,M,D : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeDate(TDateTime(Args[0].resValue),Y,M,D);
- Result.resValue:=D;
- end;
- Function BuiltInExtractHour(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- H,M,S,MS : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeTime(TDateTime(Args[0].resValue),H,M,S,MS);
- Result.resValue:=H;
- end;
- Function BuiltInExtractMin(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- H,M,S,MS : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeTime(TDateTime(Args[0].resValue),H,M,S,MS);
- Result.resValue:=M;
- end;
- Function BuiltInExtractSec(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- H,M,S,MS : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeTime(TdateTime(Args[0].resValue),H,M,S,MS);
- Result.resValue:=S;
- end;
- Function BuiltInExtractMSec(Const Args : TExprParameterArray) : TFPExpressionResult;
- Var
- H,M,S,MS : Word;
- begin
- Result.ResultType:=rtInteger;
- DecodeTime(TDateTime(Args[0].resValue),H,M,S,MS);
- Result.resValue:=MS;
- end;
- Function BuiltInEncodedate(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=Encodedate(NativeInt(Args[0].resValue),NativeInt(Args[1].resValue),NativeInt(Args[2].resValue));
- end;
- Function BuiltInEncodeTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=EncodeTime(NativeInt(Args[0].resValue),NativeInt(Args[1].resValue),NativeInt(Args[2].resValue),NativeInt(Args[3].resValue));
- end;
- Function BuiltInEncodeDateTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=EncodeDate(NativeInt(Args[0].resValue),NativeInt(Args[1].resValue),NativeInt(Args[2].resValue))
- +EncodeTime(NativeInt(Args[3].resValue),NativeInt(Args[4].resValue),NativeInt(Args[5].resValue),NativeInt(Args[6].resValue));
- end;
- Function BuiltInShortDayName(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=FormatSettings.ShortDayNames[NativeInt(Args[0].resValue)];
- end;
- Function BuiltInShortMonthName(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=FormatSettings.ShortMonthNames[NativeInt(Args[0].resValue)];
- end;
- Function BuiltInLongDayName(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.resValue:=FormatSettings.LongDayNames[NativeInt(Args[0].resValue)];
- end;
- Function BuiltInLongMonthName(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=FormatSettings.LongMonthNames[NativeInt(Args[0].resValue)];
- end;
- Function BuiltInFormatDateTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=FormatDateTime(String(Args[0].resValue),TDateTime(Args[1].resValue));
- end;
- // Conversion
- Function BuiltInIntToStr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=IntToStr(NativeInt(Args[0].resValue));
- end;
- Function BuiltInStrToInt(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=StrToInt(String(Args[0].resValue));
- end;
- Function BuiltInStrToIntDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtInteger;
- Result.resValue:=StrToIntDef(String(Args[0].resValue),NativeInt(Args[1].resValue));
- end;
- Function BuiltInFloatToStr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=FloatToStr(TExprFloat(Args[0].resValue));
- end;
- Function BuiltInStrToFloat(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=StrToFloat(String(Args[0].resValue));
- end;
- Function BuiltInStrToFloatDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- Result.resValue:=StrToFloatDef(String(Args[0].resValue),TExprFloat(Args[1].resValue));
- end;
- Function BuiltInDateToStr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=DateToStr(TDateTime(Args[0].resValue));
- end;
- Function BuiltInTimeToStr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=TimeToStr(TDateTime(Args[0].resValue));
- end;
- Function BuiltInStrToDate(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToDate(String(Args[0].resValue));
- end;
- Function BuiltInStrToDateDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToDateDef(String(Args[0].resValue),TDateTime(Args[1].resValue));
- end;
- Function BuiltInStrToTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToTime(String(Args[0].resValue));
- end;
- Function BuiltInStrToTimeDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToTimeDef(String(Args[0].resValue),TDateTime(Args[1].resValue));
- end;
- Function BuiltInStrToDateTime(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToDateTime(String(Args[0].resValue));
- end;
- Function BuiltInStrToDateTimeDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- Result.resValue:=StrToDateTimeDef(String(Args[0].resValue),TDateTime(Args[1].resValue));
- end;
- Function BuiltInFormatFloat(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- result.resValue := FormatFloat(String(Args[0].resValue), TExprFloat(Args[1].resValue));
- end;
- Function BuiltInBoolToStr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- Result.resValue:=BoolToStr(Boolean(Args[0].resValue));
- end;
- Function BuiltInStrToBool(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtBoolean;
- Result.resValue:=StrToBool(String(Args[0].resValue));
- end;
- Function BuiltInStrToBoolDef(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.resValue:=StrToBoolDef(String(Args[0].resValue),Boolean(Args[1].resValue));
- Result.ResultType:=rtBoolean;
- end;
- // Boolean
- Function BuiltInShl(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtinteger;
- Result.resValue:=NativeInt(Args[0].resValue) shl NativeInt(Args[1].resValue);
- end;
- Function BuiltInShr(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtinteger;
- Result.resValue:=NativeInt(Args[0].resValue) shr NativeInt(Args[1].resValue);
- end;
- Function BuiltinIFS(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtString;
- If Boolean(Args[0].resValue) then
- Result.resValue:=Args[1].resValue
- else
- Result.resValue:=Args[2].resValue
- end;
- Function BuiltinIFI(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtinteger;
- If Boolean(Args[0].resValue) then
- Result.resValue:=Args[1].resValue
- else
- Result.resValue:=Args[2].resValue
- end;
- Function BuiltinIFF(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtFloat;
- If Boolean(Args[0].resValue) then
- Result.resValue:=Args[1].resValue
- else
- Result.resValue:=Args[2].resValue
- end;
- Function BuiltinIFD(Const Args : TExprParameterArray) : TFPExpressionResult;
- begin
- Result.ResultType:=rtDateTime;
- If Boolean(Args[0].resValue) then
- Result.resValue:=Args[1].resValue
- else
- Result.resValue:=Args[2].resValue
- end;
- procedure RegisterStdBuiltins(AManager: TExprBuiltInManager; Categories: TBuiltInCategories = AllBuiltIns);
- begin
- With AManager do
- begin
- if bcMath in Categories then
- begin
- AddFloatVariable(bcMath,'pi',Pi);
- // Math functions
- AddFunction(bcMath,'cos','F','F',@BuiltinCos);
- AddFunction(bcMath,'sin','F','F',@BuiltinSin);
- // AddFunction(bcMath,'arctan','F','F',@BuiltinArctan);
- AddFunction(bcMath,'abs','F','F',@BuiltinAbs);
- AddFunction(bcMath,'sqr','F','F',@BuiltinSqr);
- AddFunction(bcMath,'sqrt','F','F',@BuiltinSqrt);
- AddFunction(bcMath,'exp','F','F',@BuiltinExp);
- AddFunction(bcMath,'ln','F','F',@BuiltinLn);
- AddFunction(bcMath,'log','F','F',@BuiltinLog);
- AddFunction(bcMath,'frac','F','F',@BuiltinFrac);
- AddFunction(bcMath,'int','F','F',@BuiltinInt);
- AddFunction(bcMath,'round','I','F',@BuiltinRound);
- AddFunction(bcMath,'trunc','I','F',@BuiltinTrunc);
- end;
- if bcStrings in Categories then
- begin
- // String
- AddFunction(bcStrings,'length','I','S',@BuiltinLength);
- AddFunction(bcStrings,'copy','S','SII',@BuiltinCopy);
- AddFunction(bcStrings,'delete','S','SII',@BuiltinDelete);
- AddFunction(bcStrings,'pos','I','SS',@BuiltinPos);
- AddFunction(bcStrings,'lowercase','S','S',@BuiltinLowercase);
- AddFunction(bcStrings,'uppercase','S','S',@BuiltinUppercase);
- AddFunction(bcStrings,'stringreplace','S','SSSBB',@BuiltinStringReplace);
- AddFunction(bcStrings,'comparetext','I','SS',@BuiltinCompareText);
- end;
- if bcDateTime in Categories then
- begin
- // Date/Time
- AddFunction(bcDateTime,'date','D','',@BuiltinDate);
- AddFunction(bcDateTime,'time','D','',@BuiltinTime);
- AddFunction(bcDateTime,'now','D','',@BuiltinNow);
- AddFunction(bcDateTime,'dayofweek','I','D',@BuiltinDayofweek);
- AddFunction(bcDateTime,'extractyear','I','D',@BuiltinExtractYear);
- AddFunction(bcDateTime,'extractmonth','I','D',@BuiltinExtractMonth);
- AddFunction(bcDateTime,'extractday','I','D',@BuiltinExtractDay);
- AddFunction(bcDateTime,'extracthour','I','D',@BuiltinExtractHour);
- AddFunction(bcDateTime,'extractmin','I','D',@BuiltinExtractMin);
- AddFunction(bcDateTime,'extractsec','I','D',@BuiltinExtractSec);
- AddFunction(bcDateTime,'extractmsec','I','D',@BuiltinExtractMSec);
- AddFunction(bcDateTime,'encodedate','D','III',@BuiltinEncodedate);
- AddFunction(bcDateTime,'encodetime','D','IIII',@BuiltinEncodeTime);
- AddFunction(bcDateTime,'encodedatetime','D','IIIIIII',@BuiltinEncodeDateTime);
- AddFunction(bcDateTime,'shortdayname','S','I',@BuiltinShortDayName);
- AddFunction(bcDateTime,'shortmonthname','S','I',@BuiltinShortMonthName);
- AddFunction(bcDateTime,'longdayname','S','I',@BuiltinLongDayName);
- AddFunction(bcDateTime,'longmonthname','S','I',@BuiltinLongMonthName);
- end;
- if bcBoolean in Categories then
- begin
- // Boolean
- AddFunction(bcBoolean,'shl','I','II',@BuiltinShl);
- AddFunction(bcBoolean,'shr','I','II',@BuiltinShr);
- AddFunction(bcBoolean,'IFS','S','BSS',@BuiltinIFS);
- AddFunction(bcBoolean,'IFF','F','BFF',@BuiltinIFF);
- AddFunction(bcBoolean,'IFD','D','BDD',@BuiltinIFD);
- AddFunction(bcBoolean,'IFI','I','BII',@BuiltinIFI);
- end;
- if (bcConversion in Categories) then
- begin
- // Conversion
- AddFunction(bcConversion,'inttostr','S','I',@BuiltInIntToStr);
- AddFunction(bcConversion,'strtoint','I','S',@BuiltInStrToInt);
- AddFunction(bcConversion,'strtointdef','I','SI',@BuiltInStrToIntDef);
- AddFunction(bcConversion,'floattostr','S','F',@BuiltInFloatToStr);
- AddFunction(bcConversion,'strtofloat','F','S',@BuiltInStrToFloat);
- AddFunction(bcConversion,'strtofloatdef','F','SF',@BuiltInStrToFloatDef);
- AddFunction(bcConversion,'booltostr','S','B',@BuiltInBoolToStr);
- AddFunction(bcConversion,'strtobool','B','S',@BuiltInStrToBool);
- AddFunction(bcConversion,'strtobooldef','B','SB',@BuiltInStrToBoolDef);
- AddFunction(bcConversion,'datetostr','S','D',@BuiltInDateToStr);
- AddFunction(bcConversion,'timetostr','S','D',@BuiltInTimeToStr);
- AddFunction(bcConversion,'strtodate','D','S',@BuiltInStrToDate);
- AddFunction(bcConversion,'strtodatedef','D','SD',@BuiltInStrToDateDef);
- AddFunction(bcConversion,'strtotime','D','S',@BuiltInStrToTime);
- AddFunction(bcConversion,'strtotimedef','D','SD',@BuiltInStrToTimeDef);
- AddFunction(bcConversion,'strtodatetime','D','S',@BuiltInStrToDateTime);
- AddFunction(bcConversion,'strtodatetimedef','D','SD',@BuiltInStrToDateTimeDef);
- AddFunction(bcConversion,'formatfloat','S','SF',@BuiltInFormatFloat);
- AddFunction(bcConversion,'formatdatetime','S','SD',@BuiltinFormatDateTime);
- end;
- if bcAggregate in Categories then
- begin
- AddFunction(bcAggregate,'count','I','',TAggregateCount);
- AddFunction(bcAggregate,'sum','F','F',TAggregateSum);
- AddFunction(bcAggregate,'avg','F','F',TAggregateAvg);
- AddFunction(bcAggregate,'min','F','F',TAggregateMin);
- AddFunction(bcAggregate,'max','F','F',TAggregateMax);
- end;
- end;
- end;
- { TFPBuiltInExprIdentifierDef }
- procedure TFPBuiltInExprIdentifierDef.Assign(Source: TPersistent);
- begin
- inherited Assign(Source);
- If Source is TFPBuiltInExprIdentifierDef then
- FCategory:=(Source as TFPBuiltInExprIdentifierDef).Category;
- end;
- procedure InitFileFormatSettings;
- begin
- FileFormatSettings := FormatSettings;
- FileFormatSettings.DecimalSeparator := '.';
- FileFormatSettings.DateSeparator := '-';
- FileFormatSettings.TimeSeparator := ':';
- FileFormatsettings.ShortDateFormat := 'yyyy-mm-dd';
- FileFormatSettings.LongTimeFormat := 'hh:nn:ss';
- end;
- initialization
- L10:=Ln(10);
- RegisterStdBuiltins(BuiltinIdentifiers);
- InitFileFormatSettings;
- end.
|