| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437 |
- MODULE STATEMENTS;
- IMPORT
- PARS, PROG, SCAN, ARITH, STRINGS, LISTS, IL, X86, AMD64, MSP430, THUMB, RVMxI,
- ERRORS, UTILS, AVL := AVLTREES, CONSOLE, C := COLLECTIONS, TARGETS;
- CONST
- eCONST = PARS.eCONST; eTYPE = PARS.eTYPE; eVAR = PARS.eVAR;
- eEXPR = PARS.eEXPR; eVREC = PARS.eVREC; ePROC = PARS.ePROC;
- eVPAR = PARS.eVPAR; ePARAM = PARS.ePARAM; eSTPROC = PARS.eSTPROC;
- eSTFUNC = PARS.eSTFUNC; eSYSFUNC = PARS.eSYSFUNC; eSYSPROC = PARS.eSYSPROC;
- eIMP = PARS.eIMP;
- errASSERT = 1; errPTR = 2; errDIV = 3; errPROC = 4;
- errGUARD = 5; errIDX = 6; errCASE = 7; errCOPY = 8;
- errCHR = 9; errWCHR = 10; errBYTE = 11;
- chkIDX* = 0; chkGUARD* = 1; chkPTR* = 2; chkCHR* = 3; chkWCHR* = 4; chkBYTE* = 5;
- chkSTK* = MSP430.chkSTK; (* 6 *)
- chkALL* = {chkIDX, chkGUARD, chkPTR, chkCHR, chkWCHR, chkBYTE, chkSTK};
- TYPE
- isXXX = PROCEDURE (e: PARS.EXPR): BOOLEAN;
- RANGE = RECORD
- a, b: INTEGER
- END;
- CASE_LABEL = POINTER TO rCASE_LABEL;
- rCASE_LABEL = RECORD (AVL.DATA)
- range: RANGE;
- variant, self: INTEGER;
- _type: PROG._TYPE;
- prev: CASE_LABEL
- END;
- CASE_VARIANT = POINTER TO RECORD (LISTS.ITEM)
- label: INTEGER;
- cmd: IL.COMMAND;
- processed: BOOLEAN
- END;
- VAR
- Options: PROG.OPTIONS;
- begcall, endcall: IL.COMMAND;
- CaseLabels, CaseVar: C.COLLECTION;
- CaseVariants: LISTS.LIST;
- CPU: INTEGER;
- tINTEGER, tBYTE, tCHAR, tWCHAR, tSET, tBOOLEAN, tREAL: PROG._TYPE;
- PROCEDURE isExpr (e: PARS.EXPR): BOOLEAN;
- RETURN e.obj IN {eCONST, eVAR, eEXPR, eVPAR, ePARAM, eVREC}
- END isExpr;
- PROCEDURE isVar (e: PARS.EXPR): BOOLEAN;
- RETURN e.obj IN {eVAR, eVPAR, ePARAM, eVREC}
- END isVar;
- PROCEDURE isBoolean (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tBOOLEAN)
- END isBoolean;
- PROCEDURE isInteger (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tINTEGER)
- END isInteger;
- PROCEDURE isByte (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tBYTE)
- END isByte;
- PROCEDURE isInt (e: PARS.EXPR): BOOLEAN;
- RETURN isByte(e) OR isInteger(e)
- END isInt;
- PROCEDURE isReal (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tREAL)
- END isReal;
- PROCEDURE isSet (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tSET)
- END isSet;
- PROCEDURE isString (e: PARS.EXPR): BOOLEAN;
- RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR})
- END isString;
- PROCEDURE isStringW (e: PARS.EXPR): BOOLEAN;
- RETURN (e.obj = eCONST) & (e._type.typ IN {PROG.tSTRING, PROG.tCHAR, PROG.tWCHAR})
- END isStringW;
- PROCEDURE isChar (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tCHAR)
- END isChar;
- PROCEDURE isCharW (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type = tWCHAR)
- END isCharW;
- PROCEDURE isPtr (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type.typ = PROG.tPOINTER)
- END isPtr;
- PROCEDURE isRec (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type.typ = PROG.tRECORD)
- END isRec;
- PROCEDURE isRecPtr (e: PARS.EXPR): BOOLEAN;
- RETURN isRec(e) OR isPtr(e)
- END isRecPtr;
- PROCEDURE isArr (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type.typ = PROG.tARRAY)
- END isArr;
- PROCEDURE isProc (e: PARS.EXPR): BOOLEAN;
- RETURN isExpr(e) & (e._type.typ = PROG.tPROCEDURE) OR (e.obj IN {ePROC, eIMP})
- END isProc;
- PROCEDURE isNil (e: PARS.EXPR): BOOLEAN;
- RETURN e._type.typ = PROG.tNIL
- END isNil;
- PROCEDURE isCharArray (e: PARS.EXPR): BOOLEAN;
- RETURN isArr(e) & (e._type.base = tCHAR)
- END isCharArray;
- PROCEDURE isCharArrayW (e: PARS.EXPR): BOOLEAN;
- RETURN isArr(e) & (e._type.base = tWCHAR)
- END isCharArrayW;
- PROCEDURE isCharArrayX (e: PARS.EXPR): BOOLEAN;
- RETURN isCharArray(e) OR isCharArrayW(e)
- END isCharArrayX;
- PROCEDURE getpos (parser: PARS.PARSER; VAR pos: PARS.POSITION);
- BEGIN
- pos.line := parser.lex.pos.line;
- pos.col := parser.lex.pos.col;
- pos.parser := parser
- END getpos;
- PROCEDURE NextPos (parser: PARS.PARSER; VAR pos: PARS.POSITION);
- BEGIN
- PARS.Next(parser);
- getpos(parser, pos)
- END NextPos;
- PROCEDURE strlen (e: PARS.EXPR): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- ASSERT(isString(e));
- IF e._type = tCHAR THEN
- res := 1
- ELSE
- res := LENGTH(e.value.string(SCAN.STRING).s)
- END
- RETURN res
- END strlen;
- PROCEDURE _length (s: ARRAY OF CHAR): INTEGER;
- VAR
- i, res: INTEGER;
- BEGIN
- i := 0;
- res := 0;
- WHILE (i < LEN(s)) & (s[i] # 0X) DO
- IF (s[i] <= CHR(127)) OR (s[i] >= CHR(192)) THEN
- INC(res)
- END;
- INC(i)
- END
- RETURN res
- END _length;
- PROCEDURE utf8strlen (e: PARS.EXPR): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- ASSERT(isStringW(e));
- IF e._type.typ IN {PROG.tCHAR, PROG.tWCHAR} THEN
- res := 1
- ELSE
- res := _length(e.value.string(SCAN.STRING).s)
- END
- RETURN res
- END utf8strlen;
- PROCEDURE StrToWChar (s: ARRAY OF CHAR): INTEGER;
- VAR
- res: ARRAY 2 OF WCHAR;
- BEGIN
- ASSERT(STRINGS.Utf8To16(s, res) = 1)
- RETURN ORD(res[0])
- END StrToWChar;
- PROCEDURE isStringW1 (e: PARS.EXPR): BOOLEAN;
- RETURN isString(e) & (utf8strlen(e) = 1) & (strlen(e) > 1)
- END isStringW1;
- PROCEDURE assigncomp (e: PARS.EXPR; t: PROG._TYPE): BOOLEAN;
- VAR
- res: BOOLEAN;
- BEGIN
- IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
- IF t = e._type THEN
- res := TRUE
- ELSIF isInt(e) & (t.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
- IF (e.obj = eCONST) & (t = tBYTE) THEN
- res := ARITH.range(e.value, 0, 255)
- ELSE
- res := TRUE
- END
- ELSIF
- (e.obj = eCONST) & isChar(e) & (t = tWCHAR)
- OR isStringW1(e) & (t = tWCHAR)
- OR PROG.isBaseOf(t, e._type)
- OR ~PROG.isOpenArray(t) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(t, e._type)
- OR isNil(e) & (t.typ IN {PROG.tPOINTER, PROG.tPROCEDURE})
- OR PROG.arrcomp(e._type, t)
- OR isString(e) & (t.typ = PROG.tARRAY) & (t.base = tCHAR) & (t.length > strlen(e))
- OR isStringW(e) & (t.typ = PROG.tARRAY) & (t.base = tWCHAR) & (t.length > utf8strlen(e))
- THEN
- res := TRUE
- ELSE
- res := FALSE
- END
- ELSE
- res := FALSE
- END
- RETURN res
- END assigncomp;
- PROCEDURE String (e: PARS.EXPR): INTEGER;
- VAR
- offset: INTEGER;
- string: SCAN.STRING;
- BEGIN
- IF strlen(e) # 1 THEN
- string := e.value.string(SCAN.STRING);
- IF string.offset = -1 THEN
- string.offset := IL.putstr(string.s);
- END;
- offset := string.offset
- ELSE
- offset := IL.putstr1(ARITH.Int(e.value))
- END
- RETURN offset
- END String;
- PROCEDURE StringW (e: PARS.EXPR): INTEGER;
- VAR
- offset: INTEGER;
- string: SCAN.STRING;
- BEGIN
- IF utf8strlen(e) # 1 THEN
- string := e.value.string(SCAN.STRING);
- IF string.offsetW = -1 THEN
- string.offsetW := IL.putstrW(string.s);
- END;
- offset := string.offsetW
- ELSE
- IF e._type.typ IN {PROG.tWCHAR, PROG.tCHAR} THEN
- offset := IL.putstrW1(ARITH.Int(e.value))
- ELSE (* e._type.typ = PROG.tSTRING *)
- string := e.value.string(SCAN.STRING);
- IF string.offsetW = -1 THEN
- string.offsetW := IL.putstrW(string.s);
- END;
- offset := string.offsetW
- END
- END
- RETURN offset
- END StringW;
- PROCEDURE CheckRange (range, line, errno: INTEGER);
- VAR
- label: INTEGER;
- BEGIN
- label := IL.NewLabel();
- IL.AddCmd2(IL.opCHKIDX, label, range);
- IL.OnError(line, errno);
- IL.SetLabel(label)
- END CheckRange;
- PROCEDURE Float (parser: PARS.PARSER; e: PARS.EXPR);
- VAR
- pos: PARS.POSITION;
- BEGIN
- getpos(parser, pos);
- IL.Float(ARITH.Float(e.value), pos.line, pos.col)
- END Float;
- PROCEDURE assign (parser: PARS.PARSER; e: PARS.EXPR; VarType: PROG._TYPE; line: INTEGER): BOOLEAN;
- VAR
- res: BOOLEAN;
- label: INTEGER;
- BEGIN
- IF isExpr(e) OR (e.obj IN {ePROC, eIMP}) THEN
- res := TRUE;
- IF PROG.arrcomp(e._type, VarType) THEN
- IF ~PROG.isOpenArray(VarType) THEN
- IL.Const(VarType.length)
- END;
- IL.AddCmd(IL.opCOPYA, VarType.base.size);
- label := IL.NewLabel();
- IL.Jmp(IL.opJNZ, label);
- IL.OnError(line, errCOPY);
- IL.SetLabel(label)
- ELSIF isInt(e) & (VarType.typ IN {PROG.tBYTE, PROG.tINTEGER}) THEN
- IF VarType = tINTEGER THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSAVE)
- END
- ELSE
- IF e.obj = eCONST THEN
- res := ARITH.range(e.value, 0, 255);
- IF res THEN
- IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
- END
- ELSE
- IL.AddCmd0(IL.opSAVE8)
- END
- END
- ELSIF isSet(e) & (VarType = tSET) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSAVE)
- END
- ELSIF isBoolean(e) & (VarType = tBOOLEAN) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSBOOLC, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSBOOL)
- END
- ELSIF isReal(e) & (VarType = tREAL) THEN
- IF e.obj = eCONST THEN
- Float(parser, e)
- END;
- IL.savef(e.obj = eCONST)
- ELSIF isChar(e) & (VarType = tCHAR) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSAVE8C, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSAVE8)
- END
- ELSIF (e.obj = eCONST) & isChar(e) & (VarType = tWCHAR) THEN
- IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
- ELSIF isStringW1(e) & (VarType = tWCHAR) THEN
- IL.AddCmd(IL.opSAVE16C, StrToWChar(e.value.string(SCAN.STRING).s))
- ELSIF isCharW(e) & (VarType = tWCHAR) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSAVE16C, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSAVE16)
- END
- ELSIF PROG.isBaseOf(VarType, e._type) THEN
- IF VarType.typ = PROG.tPOINTER THEN
- IL.AddCmd0(IL.opSAVE)
- ELSE
- IL.AddCmd(IL.opCOPY, VarType.size)
- END
- ELSIF (e._type.typ = PROG.tCARD32) & (VarType.typ = PROG.tCARD32) THEN
- IL.AddCmd0(IL.opSAVE32)
- ELSIF ~PROG.isOpenArray(VarType) & ~PROG.isOpenArray(e._type) & PROG.isTypeEq(VarType, e._type) THEN
- IF e.obj = ePROC THEN
- IL.AssignProc(e.ident.proc.label)
- ELSIF e.obj = eIMP THEN
- IL.AssignImpProc(e.ident._import)
- ELSE
- IF VarType.typ = PROG.tPROCEDURE THEN
- IL.AddCmd0(IL.opSAVE)
- ELSE
- IL.AddCmd(IL.opCOPY, VarType.size)
- END
- END
- ELSIF isNil(e) & (VarType.typ IN {PROG.tPOINTER, PROG.tPROCEDURE}) THEN
- IL.AddCmd(IL.opSAVEC, 0)
- ELSIF isString(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base = tCHAR) & (VarType.length > strlen(e))) THEN
- IL.saves(String(e), strlen(e) + 1)
- ELSIF isStringW(e) & ((VarType.typ = PROG.tARRAY) & (VarType.base = tWCHAR) & (VarType.length > utf8strlen(e))) THEN
- IL.saves(StringW(e), (utf8strlen(e) + 1) * 2)
- ELSE
- res := FALSE
- END
- ELSE
- res := FALSE
- END
- RETURN res
- END assign;
- PROCEDURE LoadConst (e: PARS.EXPR);
- BEGIN
- IL.Const(ARITH.Int(e.value))
- END LoadConst;
- PROCEDURE paramcomp (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR; p: PROG.PARAM);
- VAR
- stroffs: INTEGER;
- PROCEDURE arrcomp (e: PARS.EXPR; p: PROG.PARAM): BOOLEAN;
- VAR
- t1, t2: PROG._TYPE;
- BEGIN
- t1 := p._type;
- t2 := e._type;
- WHILE (t2.typ = PROG.tARRAY) & PROG.isOpenArray(t1) DO
- t1 := t1.base;
- t2 := t2.base
- END
- RETURN PROG.isTypeEq(t1, t2)
- END arrcomp;
- PROCEDURE ArrLen (t: PROG._TYPE; n: INTEGER): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- REPEAT
- res := t.length;
- t := t.base;
- DEC(n)
- UNTIL (n < 0) OR (t.typ # PROG.tARRAY);
- ASSERT(n < 0)
- RETURN res
- END ArrLen;
- PROCEDURE OpenArray (t, t2: PROG._TYPE);
- VAR
- n, d1, d2: INTEGER;
- BEGIN
- IF t.length # 0 THEN
- IL.Param1;
- n := PROG.Dim(t2) - 1;
- WHILE n >= 0 DO
- IL.Const(ArrLen(t, n));
- IL.Param1;
- DEC(n)
- END
- ELSE
- d1 := PROG.Dim(t);
- d2 := PROG.Dim(t2);
- IF d1 # d2 THEN
- n := d2 - d1;
- WHILE d2 > d1 DO
- IL.Const(ArrLen(t, d2 - 1));
- DEC(d2)
- END;
- d2 := PROG.Dim(t2);
- WHILE n > 0 DO
- IL.AddCmd(IL.opROT, d2);
- DEC(n)
- END
- END;
- IL.AddCmd(IL.opPARAM, PROG.Dim(t2) + 1)
- END
- END OpenArray;
- BEGIN
- IF p.vPar THEN
- PARS.check(isVar(e), pos, 93);
- IF p._type.typ = PROG.tRECORD THEN
- PARS.check(PROG.isBaseOf(p._type, e._type), pos, 66);
- IF e.obj = eVREC THEN
- IF e.ident # NIL THEN
- IL.AddCmd(IL.opVADR, e.ident.offset - 1)
- ELSE
- IL.AddCmd0(IL.opPUSHT)
- END
- ELSE
- IL.Const(e._type.num)
- END;
- IL.AddCmd(IL.opPARAM, 2)
- ELSIF PROG.isOpenArray(p._type) THEN
- PARS.check(arrcomp(e, p), pos, 66);
- OpenArray(e._type, p._type)
- ELSE
- PARS.check(PROG.isTypeEq(e._type, p._type), pos, 66);
- IL.Param1
- END;
- PARS.check(~e.readOnly, pos, 94)
- ELSE
- PARS.check(isExpr(e) OR isProc(e), pos, 66);
- IF PROG.isOpenArray(p._type) THEN
- IF e._type.typ = PROG.tARRAY THEN
- PARS.check(arrcomp(e, p), pos, 66);
- OpenArray(e._type, p._type)
- ELSIF isString(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tCHAR) THEN
- IL.StrAdr(String(e));
- IL.Param1;
- IL.Const(strlen(e) + 1);
- IL.Param1
- ELSIF isStringW(e) & (p._type.typ = PROG.tARRAY) & (p._type.base = tWCHAR) THEN
- IL.StrAdr(StringW(e));
- IL.Param1;
- IL.Const(utf8strlen(e) + 1);
- IL.Param1
- ELSE
- PARS.error(pos, 66)
- END
- ELSE
- PARS.check(~PROG.isOpenArray(e._type), pos, 66);
- PARS.check(assigncomp(e, p._type), pos, 66);
- IF e.obj = eCONST THEN
- IF e._type = tREAL THEN
- Float(parser, e);
- IL.AddCmd0(IL.opPUSHF)
- ELSIF e._type.typ = PROG.tNIL THEN
- IL.Const(0);
- IL.Param1
- ELSIF isStringW1(e) & (p._type = tWCHAR) THEN
- IL.Const(StrToWChar(e.value.string(SCAN.STRING).s));
- IL.Param1
- ELSIF (e._type.typ = PROG.tSTRING) OR
- (e._type.typ IN {PROG.tCHAR, PROG.tWCHAR}) & (p._type.typ = PROG.tARRAY) & (p._type.base.typ IN {PROG.tCHAR, PROG.tWCHAR}) THEN
- IF p._type.base = tCHAR THEN
- stroffs := String(e);
- IL.StrAdr(stroffs);
- IF (CPU = TARGETS.cpuMSP430) & (p._type.size - strlen(e) - 1 > MSP430.IntVectorSize) THEN
- ERRORS.WarningMsg(pos.line, pos.col, 0)
- END
- ELSE (* WCHAR *)
- stroffs := StringW(e);
- IL.StrAdr(stroffs)
- END;
- IL.set_dmin(stroffs + p._type.size);
- IL.Param1
- ELSE
- LoadConst(e);
- IL.Param1
- END
- ELSIF e.obj = ePROC THEN
- PARS.check(e.ident.global, pos, 85);
- IL.PushProc(e.ident.proc.label);
- IL.Param1
- ELSIF e.obj = eIMP THEN
- IL.PushImpProc(e.ident._import);
- IL.Param1
- ELSIF isExpr(e) & (e._type = tREAL) THEN
- IL.AddCmd0(IL.opPUSHF)
- ELSE
- IF (p._type = tBYTE) & (e._type = tINTEGER) & (chkBYTE IN Options.checking) THEN
- CheckRange(256, pos.line, errBYTE)
- END;
- IL.Param1
- END
- END
- END
- END paramcomp;
- PROCEDURE PExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
- BEGIN
- parser.expression(parser, e)
- END PExpression;
- PROCEDURE stProc (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- e1, e2: PARS.EXPR;
- pos: PARS.POSITION;
- proc,
- label,
- size,
- n, i: INTEGER;
- code: ARITH.VALUE;
- wchar,
- comma: BOOLEAN;
- cmd1,
- cmd2: IL.COMMAND;
- PROCEDURE varparam (parser: PARS.PARSER; pos: PARS.POSITION; isfunc: isXXX; readOnly: BOOLEAN; VAR e: PARS.EXPR);
- BEGIN
- parser.designator(parser, e);
- PARS.check(isVar(e), pos, 93);
- PARS.check(isfunc(e), pos, 66);
- IF readOnly THEN
- PARS.check(~e.readOnly, pos, 94)
- END
- END varparam;
- PROCEDURE shift_minmax (proc: INTEGER): CHAR;
- VAR
- res: CHAR;
- BEGIN
- CASE proc OF
- |PROG.stASR: res := "A"
- |PROG.stLSL: res := "L"
- |PROG.stROR: res := "O"
- |PROG.stLSR: res := "R"
- |PROG.stMIN: res := "m"
- |PROG.stMAX: res := "x"
- END
- RETURN res
- END shift_minmax;
- BEGIN
- ASSERT(e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC});
- proc := e.stproc;
- (* IF (proc # PROG.sysNOP) & (proc # PROG.sysEINT) & (proc # PROG.sysDINT) THEN *)
- PARS.checklex(parser, SCAN.lxLROUND);
- PARS.Next(parser);
- (* END; *)
- getpos(parser, pos);
- IF e.obj IN {eSTPROC, eSYSPROC} THEN
- CASE proc OF
- |PROG.stASSERT:
- PExpression(parser, e);
- PARS.check(isBoolean(e), pos, 66);
- IF e.obj = eCONST THEN
- IF ~ARITH.getBool(e.value) THEN
- IL.OnError(pos.line, errASSERT)
- END
- ELSE
- label := IL.NewLabel();
- IL.not;
- IL.AndOrOpt(label);
- IL.OnError(pos.line, errASSERT);
- IL.SetLabel(label)
- END
- |PROG.stINC, PROG.stDEC:
- IL.pushBegEnd(begcall, endcall);
- varparam(parser, pos, isInt, TRUE, e);
- IF e._type = tINTEGER THEN
- IF parser.sym = SCAN.lxCOMMA THEN
- NextPos(parser, pos);
- IL.setlast(begcall);
- PExpression(parser, e2);
- IL.setlast(endcall.prev(IL.COMMAND));
- PARS.check(isInt(e2), pos, 66);
- IF e2.obj = eCONST THEN
- IL.AddCmd(IL.opINCC, ARITH.Int(e2.value) * (ORD(proc = PROG.stINC) * 2 - 1))
- ELSE
- IL.AddCmd0(IL.opINC + ORD(proc = PROG.stDEC))
- END
- ELSE
- IL.AddCmd(IL.opINCC, ORD(proc = PROG.stINC) * 2 - 1)
- END
- ELSE (* e._type = tBYTE *)
- IF parser.sym = SCAN.lxCOMMA THEN
- NextPos(parser, pos);
- IL.setlast(begcall);
- PExpression(parser, e2);
- IL.setlast(endcall.prev(IL.COMMAND));
- PARS.check(isInt(e2), pos, 66);
- IF e2.obj = eCONST THEN
- IL.AddCmd(IL.opINCCB + ORD(proc = PROG.stDEC), ARITH.Int(e2.value))
- ELSE
- IL.AddCmd0(IL.opINCB + ORD(proc = PROG.stDEC))
- END
- ELSE
- IL.AddCmd(IL.opINCCB + ORD(proc = PROG.stDEC), 1)
- END
- END;
- IL.popBegEnd(begcall, endcall)
- |PROG.stINCL, PROG.stEXCL:
- IL.pushBegEnd(begcall, endcall);
- varparam(parser, pos, isSet, TRUE, e);
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- IL.setlast(begcall);
- PExpression(parser, e2);
- IL.setlast(endcall.prev(IL.COMMAND));
- PARS.check(isInt(e2), pos, 66);
- IF e2.obj = eCONST THEN
- PARS.check(ARITH.range(e2.value, 0, UTILS.target.maxSet), pos, 56);
- IL.AddCmd(IL.opINCLC + ORD(proc = PROG.stEXCL), ARITH.Int(e2.value))
- ELSE
- IL.AddCmd0(IL.opINCL + ORD(proc = PROG.stEXCL))
- END;
- IL.popBegEnd(begcall, endcall)
- |PROG.stNEW:
- varparam(parser, pos, isPtr, TRUE, e);
- IF CPU = TARGETS.cpuMSP430 THEN
- PARS.check(e._type.base.size + 16 < Options.ram, pos, 63)
- END;
- IL.New(e._type.base.size, e._type.base.num)
- |PROG.stDISPOSE:
- varparam(parser, pos, isPtr, TRUE, e);
- IL.AddCmd0(IL.opDISP)
- |PROG.stPACK:
- varparam(parser, pos, isReal, TRUE, e);
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- PExpression(parser, e2);
- PARS.check(isInt(e2), pos, 66);
- IF e2.obj = eCONST THEN
- IL.AddCmd(IL.opPACKC, ARITH.Int(e2.value))
- ELSE
- IL.AddCmd0(IL.opPACK)
- END
- |PROG.stUNPK:
- varparam(parser, pos, isReal, TRUE, e);
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- varparam(parser, pos, isInteger, TRUE, e2);
- IL.AddCmd0(IL.opUNPK)
- |PROG.stCOPY:
- IL.pushBegEnd(begcall, endcall);
- PExpression(parser, e);
- IF isString(e) OR isCharArray(e) THEN
- wchar := FALSE
- ELSIF isStringW(e) OR isCharArrayW(e) THEN
- wchar := TRUE
- ELSE
- PARS.error(pos, 66)
- END;
- IF isCharArrayX(e) & ~PROG.isOpenArray(e._type) THEN
- IL.Const(e._type.length)
- END;
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- IL.setlast(begcall);
- IF wchar THEN
- varparam(parser, pos, isCharArrayW, TRUE, e1)
- ELSE
- IF e.obj = eCONST THEN
- varparam(parser, pos, isCharArrayX, TRUE, e1)
- ELSE
- varparam(parser, pos, isCharArray, TRUE, e1)
- END;
- wchar := e1._type.base = tWCHAR
- END;
- IF ~PROG.isOpenArray(e1._type) THEN
- IL.Const(e1._type.length)
- END;
- IL.setlast(endcall.prev(IL.COMMAND));
- IF e.obj = eCONST THEN
- IF wchar THEN
- IL.StrAdr(StringW(e));
- IL.Const(utf8strlen(e) + 1)
- ELSE
- IL.StrAdr(String(e));
- IL.Const(strlen(e) + 1)
- END
- END;
- IL.AddCmd(IL.opCOPYS, e1._type.base.size);
- IL.popBegEnd(begcall, endcall)
- |PROG.sysGET, PROG.sysGET8, PROG.sysGET16, PROG.sysGET32:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- parser.designator(parser, e2);
- PARS.check(isVar(e2), pos, 93);
- IF proc = PROG.sysGET THEN
- PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66)
- ELSE
- PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66)
- END;
- CASE proc OF
- |PROG.sysGET: size := e2._type.size
- |PROG.sysGET8: size := 1
- |PROG.sysGET16: size := 2
- |PROG.sysGET32: size := 4
- END;
- PARS.check(size <= e2._type.size, pos, 66);
- IF e.obj = eCONST THEN
- IL.AddCmd2(IL.opGETC, ARITH.Int(e.value), size)
- ELSE
- IL.AddCmd(IL.opGET, size)
- END
- |PROG.sysPUT, PROG.sysPUT8, PROG.sysPUT16, PROG.sysPUT32:
- IL.pushBegEnd(begcall, endcall);
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- IF e.obj = eCONST THEN
- LoadConst(e)
- END;
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- IL.setlast(begcall);
- PExpression(parser, e2);
- PARS.check(isExpr(e2), pos, 66);
- IF proc = PROG.sysPUT THEN
- PARS.check(e2._type.typ IN PROG.BASICTYPES + {PROG.tPOINTER, PROG.tPROCEDURE}, pos, 66);
- IF e2.obj = eCONST THEN
- IF e2._type = tREAL THEN
- Float(parser, e2);
- IL.setlast(endcall.prev(IL.COMMAND));
- IL.savef(FALSE)
- ELSE
- LoadConst(e2);
- IL.setlast(endcall.prev(IL.COMMAND));
- IL.SysPut(e2._type.size)
- END
- ELSE
- IL.setlast(endcall.prev(IL.COMMAND));
- IF e2._type = tREAL THEN
- IL.savef(FALSE)
- ELSIF e2._type = tBYTE THEN
- IL.SysPut(tINTEGER.size)
- ELSE
- IL.SysPut(e2._type.size)
- END
- END
- ELSIF (proc = PROG.sysPUT8) OR (proc = PROG.sysPUT16) OR (proc = PROG.sysPUT32) THEN
- PARS.check(e2._type.typ IN {PROG.tINTEGER, PROG.tBYTE, PROG.tCHAR, PROG.tSET, PROG.tWCHAR, PROG.tCARD32}, pos, 66);
- IF e2.obj = eCONST THEN
- LoadConst(e2)
- END;
- IL.setlast(endcall.prev(IL.COMMAND));
- CASE proc OF
- |PROG.sysPUT8: size := 1
- |PROG.sysPUT16: size := 2
- |PROG.sysPUT32: size := 4
- END;
- IL.SysPut(size)
- END;
- IL.popBegEnd(begcall, endcall)
- |PROG.sysMOVE:
- FOR i := 1 TO 2 DO
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- IF e.obj = eCONST THEN
- LoadConst(e)
- END;
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos)
- END;
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opCOPY, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opMOVE)
- END
- |PROG.sysCOPY:
- FOR i := 1 TO 2 DO
- parser.designator(parser, e);
- PARS.check(isVar(e), pos, 93);
- n := PROG.Dim(e._type);
- WHILE n > 0 DO
- IL.drop;
- DEC(n)
- END;
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos)
- END;
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opCOPY, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opMOVE)
- END
- |PROG.sysCODE:
- REPEAT
- getpos(parser, pos);
- PARS.ConstExpression(parser, code);
- PARS.check(code.typ = ARITH.tINTEGER, pos, 43);
- IF TARGETS.WordSize > TARGETS.InstrSize THEN
- CASE TARGETS.InstrSize OF
- |1: PARS.check(ARITH.range(code, 0, 255), pos, 42)
- |2: PARS.check(ARITH.range(code, 0, 65535), pos, 110)
- END
- END;
- IL.AddCmd(IL.opCODE, ARITH.getInt(code));
- comma := parser.sym = SCAN.lxCOMMA;
- IF comma THEN
- PARS.Next(parser)
- ELSE
- PARS.checklex(parser, SCAN.lxRROUND)
- END
- UNTIL (parser.sym = SCAN.lxRROUND) & ~comma
- (*
- |PROG.sysNOP, PROG.sysDINT, PROG.sysEINT:
- IF parser.sym = SCAN.lxLROUND THEN
- PARS.Next(parser);
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser)
- END;
- ASSERT(CPU = cpuMSP430);
- CASE proc OF
- |PROG.sysNOP: IL.AddCmd(IL.opCODE, 4303H)
- |PROG.sysDINT: IL.AddCmd(IL.opCODE, 0C232H); IL.AddCmd(IL.opCODE, 4303H)
- |PROG.sysEINT: IL.AddCmd(IL.opCODE, 0D232H)
- END
- *)
- END;
- e.obj := eEXPR;
- e._type := NIL
- ELSIF e.obj IN {eSTFUNC, eSYSFUNC} THEN
- CASE e.stproc OF
- |PROG.stABS:
- PExpression(parser, e);
- PARS.check(isInt(e) OR isReal(e), pos, 66);
- IF e.obj = eCONST THEN
- PARS.check(ARITH.abs(e.value), pos, 39)
- ELSE
- IL.abs(isReal(e))
- END
- |PROG.stASR, PROG.stLSL, PROG.stROR, PROG.stLSR, PROG.stMIN, PROG.stMAX:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- PARS.checklex(parser, SCAN.lxCOMMA);
- NextPos(parser, pos);
- PExpression(parser, e2);
- PARS.check(isInt(e2), pos, 66);
- e._type := tINTEGER;
- IF (e.obj = eCONST) & (e2.obj = eCONST) THEN
- ASSERT(ARITH.opInt(e.value, e2.value, shift_minmax(proc)))
- ELSE
- IF e.obj = eCONST THEN
- IL.shift_minmax1(shift_minmax(proc), ARITH.Int(e.value))
- ELSIF e2.obj = eCONST THEN
- IL.shift_minmax2(shift_minmax(proc), ARITH.Int(e2.value))
- ELSE
- IL.shift_minmax(shift_minmax(proc))
- END;
- e.obj := eEXPR
- END
- |PROG.stCHR:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- e._type := tCHAR;
- IF e.obj = eCONST THEN
- ARITH.setChar(e.value, ARITH.getInt(e.value));
- PARS.check(ARITH.check(e.value), pos, 107)
- ELSE
- IF chkCHR IN Options.checking THEN
- CheckRange(256, pos.line, errCHR)
- ELSE
- IL.AddCmd(IL.opMODR, 256)
- END
- END
- |PROG.stWCHR:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- e._type := tWCHAR;
- IF e.obj = eCONST THEN
- ARITH.setWChar(e.value, ARITH.getInt(e.value));
- PARS.check(ARITH.check(e.value), pos, 101)
- ELSE
- IF chkWCHR IN Options.checking THEN
- CheckRange(65536, pos.line, errWCHR)
- ELSE
- IL.AddCmd(IL.opMODR, 65536)
- END
- END
- |PROG.stFLOOR:
- PExpression(parser, e);
- PARS.check(isReal(e), pos, 66);
- e._type := tINTEGER;
- IF e.obj = eCONST THEN
- PARS.check(ARITH.floor(e.value), pos, 39)
- ELSE
- IL.AddCmd0(IL.opFLOOR)
- END
- |PROG.stFLT:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- e._type := tREAL;
- IF e.obj = eCONST THEN
- ARITH.flt(e.value)
- ELSE
- IL.AddCmd2(IL.opFLT, pos.line, pos.col)
- END
- |PROG.stLEN:
- cmd1 := IL.getlast();
- varparam(parser, pos, isArr, FALSE, e);
- IF e._type.length > 0 THEN
- cmd2 := IL.getlast();
- IL.delete2(cmd1.next, cmd2);
- IL.setlast(cmd1);
- ASSERT(ARITH.setInt(e.value, e._type.length));
- e.obj := eCONST
- ELSE
- IL.len(PROG.Dim(e._type))
- END;
- e._type := tINTEGER
- |PROG.stLENGTH:
- PExpression(parser, e);
- IF isCharArray(e) THEN
- IF e._type.length > 0 THEN
- IL.Const(e._type.length)
- END;
- IL.AddCmd0(IL.opLENGTH)
- ELSIF isCharArrayW(e) THEN
- IF e._type.length > 0 THEN
- IL.Const(e._type.length)
- END;
- IL.AddCmd0(IL.opLENGTHW)
- ELSE
- PARS.error(pos, 66);
- END;
- e._type := tINTEGER
- |PROG.stODD:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- e._type := tBOOLEAN;
- IF e.obj = eCONST THEN
- ARITH.odd(e.value)
- ELSE
- IL.AddCmd(IL.opMODR, 2)
- END
- |PROG.stORD:
- cmd1 := IL.getlast();
- PExpression(parser, e);
- PARS.check(isChar(e) OR isBoolean(e) OR isSet(e) OR isCharW(e) OR isStringW1(e), pos, 66);
- IF e.obj = eCONST THEN
- IF isStringW1(e) THEN
- ASSERT(ARITH.setInt(e.value, StrToWChar(e.value.string(SCAN.STRING).s)))
- ELSE
- ARITH.ord(e.value)
- END
- ELSE
- IF isBoolean(e) THEN
- cmd2 := IL.getlast();
- IL.setlast(cmd1);
- IL.AddCmd(IL.opPRECALL, 0);
- IL.AddCmd0(IL.opRES);
- IL.drop;
- IL.setlast(cmd2);
- IL._ord
- END
- END;
- e._type := tINTEGER
- |PROG.stBITS:
- PExpression(parser, e);
- PARS.check(isInt(e), pos, 66);
- IF e.obj = eCONST THEN
- ARITH.bits(e.value)
- END;
- e._type := tSET
- |PROG.sysADR:
- parser.designator(parser, e);
- IF isVar(e) THEN
- n := PROG.Dim(e._type);
- WHILE n > 0 DO
- IL.drop;
- DEC(n)
- END
- ELSIF e.obj = ePROC THEN
- IL.PushProc(e.ident.proc.label)
- ELSIF e.obj = eIMP THEN
- IL.PushImpProc(e.ident._import)
- ELSE
- PARS.error(pos, 108)
- END;
- e._type := tINTEGER
- |PROG.sysSADR:
- PExpression(parser, e);
- PARS.check(isString(e), pos, 66);
- IL.StrAdr(String(e));
- e._type := tINTEGER;
- e.obj := eEXPR
- |PROG.sysWSADR:
- PExpression(parser, e);
- PARS.check(isStringW(e), pos, 66);
- IL.StrAdr(StringW(e));
- e._type := tINTEGER;
- e.obj := eEXPR
- |PROG.sysTYPEID:
- PExpression(parser, e);
- PARS.check(e.obj = eTYPE, pos, 68);
- IF e._type.typ = PROG.tRECORD THEN
- ASSERT(ARITH.setInt(e.value, e._type.num))
- ELSIF e._type.typ = PROG.tPOINTER THEN
- ASSERT(ARITH.setInt(e.value, e._type.base.num))
- ELSE
- PARS.error(pos, 52)
- END;
- e.obj := eCONST;
- e._type := tINTEGER
- |PROG.sysINF:
- IL.AddCmd2(IL.opINF, pos.line, pos.col);
- e.obj := eEXPR;
- e._type := tREAL
- |PROG.sysSIZE:
- PExpression(parser, e);
- PARS.check(e.obj = eTYPE, pos, 68);
- ASSERT(ARITH.setInt(e.value, e._type.size));
- e.obj := eCONST;
- e._type := tINTEGER
- END
- END;
- (* IF (proc # PROG.sysNOP) & (proc # PROG.sysEINT) & (proc # PROG.sysDINT) THEN *)
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser);
- (* END; *)
- IF e.obj # eCONST THEN
- e.obj := eEXPR
- END
- END stProc;
- PROCEDURE ActualParameters (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- proc: PROG._TYPE;
- param: LISTS.ITEM;
- e1: PARS.EXPR;
- pos: PARS.POSITION;
- BEGIN
- ASSERT(parser.sym = SCAN.lxLROUND);
- IF (e.obj IN {ePROC, eIMP}) OR isExpr(e) THEN
- proc := e._type;
- PARS.check1(proc.typ = PROG.tPROCEDURE, parser, 86);
- PARS.Next(parser);
- param := proc.params.first;
- WHILE param # NIL DO
- getpos(parser, pos);
- IL.setlast(begcall);
- IF param(PROG.PARAM).vPar THEN
- parser.designator(parser, e1)
- ELSE
- PExpression(parser, e1)
- END;
- paramcomp(parser, pos, e1, param(PROG.PARAM));
- param := param.next;
- IF param # NIL THEN
- PARS.checklex(parser, SCAN.lxCOMMA);
- PARS.Next(parser)
- END
- END;
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser);
- e.obj := eEXPR;
- e._type := proc.base
- ELSIF e.obj IN {eSTPROC, eSTFUNC, eSYSPROC, eSYSFUNC} THEN
- stProc(parser, e)
- ELSE
- PARS.check1(FALSE, parser, 86)
- END
- END ActualParameters;
- PROCEDURE qualident (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- ident: PROG.IDENT;
- imp: BOOLEAN;
- pos: PARS.POSITION;
- BEGIN
- PARS.checklex(parser, SCAN.lxIDENT);
- getpos(parser, pos);
- imp := FALSE;
- ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE);
- PARS.check1(ident # NIL, parser, 48);
- IF ident.typ = PROG.idMODULE THEN
- PARS.ExpectSym(parser, SCAN.lxPOINT);
- PARS.ExpectSym(parser, SCAN.lxIDENT);
- ident := PROG.getIdent(ident.unit, parser.lex.ident, FALSE);
- PARS.check1((ident # NIL) & ident.export, parser, 48);
- imp := TRUE
- END;
- PARS.Next(parser);
- e.readOnly := FALSE;
- e.ident := ident;
- CASE ident.typ OF
- |PROG.idCONST:
- e.obj := eCONST;
- e._type := ident._type;
- e.value := ident.value
- |PROG.idTYPE:
- e.obj := eTYPE;
- e._type := ident._type
- |PROG.idVAR:
- e.obj := eVAR;
- e._type := ident._type;
- e.readOnly := imp
- |PROG.idPROC:
- e.obj := ePROC;
- e._type := ident._type
- |PROG.idIMP:
- e.obj := eIMP;
- e._type := ident._type
- |PROG.idVPAR:
- e._type := ident._type;
- IF e._type.typ = PROG.tRECORD THEN
- e.obj := eVREC
- ELSE
- e.obj := eVPAR
- END
- |PROG.idPARAM:
- e.obj := ePARAM;
- e._type := ident._type;
- e.readOnly := (e._type.typ IN {PROG.tRECORD, PROG.tARRAY})
- |PROG.idSTPROC:
- e.obj := eSTPROC;
- e._type := ident._type;
- e.stproc := ident.stproc
- |PROG.idSTFUNC:
- e.obj := eSTFUNC;
- e._type := ident._type;
- e.stproc := ident.stproc
- |PROG.idSYSPROC:
- e.obj := eSYSPROC;
- e._type := ident._type;
- e.stproc := ident.stproc
- |PROG.idSYSFUNC:
- PARS.check(~parser.constexp, pos, 109);
- e.obj := eSYSFUNC;
- e._type := ident._type;
- e.stproc := ident.stproc
- |PROG.idNONE:
- PARS.error(pos, 115)
- END;
- IF isVar(e) THEN
- PARS.check(e.ident.global OR (e.ident.scopeLvl = parser.unit.scopeLvl), pos, 105)
- END
- END qualident;
- PROCEDURE deref (pos: PARS.POSITION; e: PARS.EXPR; load: BOOLEAN; error: INTEGER);
- VAR
- label: INTEGER;
- BEGIN
- IF load THEN
- IL.load(e._type.size)
- END;
- IF chkPTR IN Options.checking THEN
- label := IL.NewLabel();
- IL.Jmp(IL.opJNZ1, label);
- IL.OnError(pos.line, error);
- IL.SetLabel(label)
- END
- END deref;
- PROCEDURE designator (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- field: PROG.FIELD;
- pos: PARS.POSITION;
- t, idx: PARS.EXPR;
- sysVal: BOOLEAN;
- n: INTEGER;
- PROCEDURE LoadAdr (e: PARS.EXPR);
- VAR
- offset: INTEGER;
- PROCEDURE OpenArray (e: PARS.EXPR);
- VAR
- offset, n: INTEGER;
- BEGIN
- offset := e.ident.offset;
- n := PROG.Dim(e._type);
- WHILE n >= 0 DO
- IL.AddCmd(IL.opVADR, offset);
- DEC(offset);
- DEC(n)
- END
- END OpenArray;
- BEGIN
- IF e.obj = eVAR THEN
- offset := PROG.getOffset(e.ident);
- IF e.ident.global THEN
- IL.AddCmd(IL.opGADR, offset)
- ELSE
- IL.AddCmd(IL.opLADR, -offset)
- END
- ELSIF e.obj = ePARAM THEN
- IF (e._type.typ = PROG.tRECORD) OR ((e._type.typ = PROG.tARRAY) & (e._type.length > 0)) THEN
- IL.AddCmd(IL.opVADR, e.ident.offset)
- ELSIF PROG.isOpenArray(e._type) THEN
- OpenArray(e)
- ELSE
- IL.AddCmd(IL.opLADR, e.ident.offset)
- END
- ELSIF e.obj IN {eVPAR, eVREC} THEN
- IF PROG.isOpenArray(e._type) THEN
- OpenArray(e)
- ELSE
- IL.AddCmd(IL.opVADR, e.ident.offset)
- END
- END
- END LoadAdr;
- PROCEDURE OpenIdx (parser: PARS.PARSER; pos: PARS.POSITION; e: PARS.EXPR);
- VAR
- label, offset, n, k: INTEGER;
- _type: PROG._TYPE;
- BEGIN
- IF chkIDX IN Options.checking THEN
- label := IL.NewLabel();
- IL.AddCmd2(IL.opCHKIDX2, label, 0);
- IL.OnError(pos.line, errIDX);
- IL.SetLabel(label)
- ELSE
- IL.AddCmd(IL.opCHKIDX2, -1)
- END;
- _type := PROG.OpenBase(e._type);
- IF _type.size # 1 THEN
- IL.AddCmd(IL.opMULC, _type.size)
- END;
- n := PROG.Dim(e._type) - 1;
- k := n;
- WHILE n > 0 DO
- IL.AddCmd0(IL.opMUL);
- DEC(n)
- END;
- IL.AddCmd0(IL.opADD);
- offset := e.ident.offset - 1;
- n := k;
- WHILE n > 0 DO
- IL.AddCmd(IL.opVADR, offset);
- DEC(offset);
- DEC(n)
- END
- END OpenIdx;
- BEGIN
- qualident(parser, e);
- sysVal := (e.obj = eSYSPROC) & (e.stproc = PROG.sysVAL);
- IF sysVal THEN
- PARS.checklex(parser, SCAN.lxLROUND);
- PARS.Next(parser);
- getpos(parser, pos);
- designator(parser, e);
- PARS.check(isVar(e), pos, 93);
- IF PROG.isOpenArray(e._type) THEN
- n := PROG.Dim(e._type);
- WHILE n > 0 DO
- IL.drop;
- DEC(n)
- END
- END;
- PARS.checklex(parser, SCAN.lxCOMMA);
- PARS.Next(parser);
- getpos(parser, pos);
- qualident(parser, t);
- PARS.check(t.obj = eTYPE, pos, 79);
- e._type := t._type;
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser)
- END;
- IF e.obj IN {ePROC, eIMP} THEN
- PROG.UseProc(parser.unit, e.ident.proc)
- END;
- IF isVar(e) & ~sysVal THEN
- LoadAdr(e)
- END;
- WHILE parser.sym = SCAN.lxPOINT DO
- getpos(parser, pos);
- PARS.check1(isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}), parser, 73);
- IF e._type.typ = PROG.tPOINTER THEN
- deref(pos, e, TRUE, errPTR)
- END;
- PARS.ExpectSym(parser, SCAN.lxIDENT);
- IF e._type.typ = PROG.tPOINTER THEN
- e._type := e._type.base;
- e.readOnly := FALSE
- END;
- field := PROG.getField(e._type, parser.lex.ident, parser.unit);
- PARS.check1(field # NIL, parser, 74);
- e._type := field._type;
- IF e.obj = eVREC THEN
- e.obj := eVPAR
- END;
- IF field.offset # 0 THEN
- IL.AddCmd(IL.opADDC, field.offset)
- END;
- PARS.Next(parser);
- e.ident := NIL
- ELSIF parser.sym = SCAN.lxLSQUARE DO
- REPEAT
- PARS.check1(isArr(e), parser, 75);
- NextPos(parser, pos);
- PExpression(parser, idx);
- PARS.check(isInt(idx), pos, 76);
- IF idx.obj = eCONST THEN
- IF e._type.length > 0 THEN
- PARS.check(ARITH.range(idx.value, 0, e._type.length - 1), pos, 83);
- IF ARITH.Int(idx.value) > 0 THEN
- IL.AddCmd(IL.opADDC, ARITH.Int(idx.value) * e._type.base.size)
- END
- ELSE
- PARS.check(ARITH.range(idx.value, 0, UTILS.target.maxInt), pos, 83);
- LoadConst(idx);
- OpenIdx(parser, pos, e)
- END
- ELSE
- IF e._type.length > 0 THEN
- IF chkIDX IN Options.checking THEN
- CheckRange(e._type.length, pos.line, errIDX)
- END;
- IF e._type.base.size # 1 THEN
- IL.AddCmd(IL.opMULC, e._type.base.size)
- END;
- IL.AddCmd0(IL.opADD)
- ELSE
- OpenIdx(parser, pos, e)
- END
- END;
- e._type := e._type.base
- UNTIL parser.sym # SCAN.lxCOMMA;
- PARS.checklex(parser, SCAN.lxRSQUARE);
- PARS.Next(parser);
- IF ~(isArr(e) & (e._type.length = 0) & (parser.sym = SCAN.lxLSQUARE)) THEN
- e.ident := NIL
- END
- ELSIF parser.sym = SCAN.lxCARET DO
- getpos(parser, pos);
- PARS.check1(isPtr(e), parser, 77);
- deref(pos, e, TRUE, errPTR);
- e._type := e._type.base;
- e.readOnly := FALSE;
- PARS.Next(parser);
- e.ident := NIL;
- e.obj := eVREC
- ELSIF (parser.sym = SCAN.lxLROUND) & isExpr(e) & (e._type.typ IN {PROG.tRECORD, PROG.tPOINTER}) DO
- IF e._type.typ = PROG.tRECORD THEN
- PARS.check1(e.obj = eVREC, parser, 78)
- END;
- NextPos(parser, pos);
- qualident(parser, t);
- PARS.check(t.obj = eTYPE, pos, 79);
- IF e._type.typ = PROG.tRECORD THEN
- PARS.check(t._type.typ = PROG.tRECORD, pos, 80);
- IF chkGUARD IN Options.checking THEN
- IF e.ident = NIL THEN
- IL.TypeGuard(IL.opTYPEGD, t._type.num, pos.line, errGUARD)
- ELSE
- IL.AddCmd(IL.opVADR, e.ident.offset - 1);
- IL.TypeGuard(IL.opTYPEGR, t._type.num, pos.line, errGUARD)
- END
- END;
- ELSE
- PARS.check(t._type.typ = PROG.tPOINTER, pos, 81);
- IF chkGUARD IN Options.checking THEN
- IL.TypeGuard(IL.opTYPEGP, t._type.base.num, pos.line, errGUARD)
- END
- END;
- PARS.check(PROG.isBaseOf(e._type, t._type), pos, 82);
- e._type := t._type;
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser)
- END
- END designator;
- PROCEDURE ProcCall (e: PARS.EXPR; procType: PROG._TYPE; isfloat: BOOLEAN; parser: PARS.PARSER; pos: PARS.POSITION; CallStat: BOOLEAN);
- VAR
- cconv,
- parSize,
- callconv,
- fparSize,
- int, flt,
- stk_par: INTEGER;
- BEGIN
- cconv := procType.call;
- parSize := procType.parSize;
- IF cconv IN {PROG._win64, PROG.win64} THEN
- callconv := IL.call_win64;
- fparSize := LSL(ORD(PROG.getFloatParamsPos(procType, 3, int, flt)), 5) + MIN(parSize, 4)
- ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
- callconv := IL.call_sysv;
- fparSize := LSL(ORD(PROG.getFloatParamsPos(procType, PROG.MAXSYSVPARAM - 1, int, flt)), 5) + parSize;
- stk_par := MAX(0, int - 6) + MAX(0, flt - 8)
- ELSIF cconv IN {PROG.fastcall, PROG._fastcall} THEN
- IF parSize = 0 THEN
- callconv := IL.call_stack
- ELSIF parSize = 1 THEN
- callconv := IL.call_fast1
- ELSIF parSize >= 2 THEN
- callconv := IL.call_fast2
- END;
- fparSize := 0
- ELSE
- callconv := IL.call_stack;
- fparSize := 0
- END;
- IL.setlast(begcall);
- IL.AddCmd(IL.opPRECALL, ORD(isfloat));
- IF cconv IN {PROG._ccall, PROG.ccall} THEN
- IL.AddCmd(IL.opALIGN16, parSize)
- ELSIF cconv IN {PROG._win64, PROG.win64} THEN
- IL.AddCmd(IL.opWIN64ALIGN16, parSize)
- ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
- IL.AddCmd(IL.opSYSVALIGN16, parSize + stk_par)
- END;
- IL.setlast(endcall.prev(IL.COMMAND));
- IF e.obj = eIMP THEN
- IL.CallImp(e.ident._import, callconv, fparSize)
- ELSIF e.obj = ePROC THEN
- IL.Call(e.ident.proc.label, callconv, fparSize)
- ELSIF isExpr(e) THEN
- deref(pos, e, CallStat, errPROC);
- IL.CallP(callconv, fparSize)
- END;
- IF cconv IN {PROG._ccall, PROG.ccall} THEN
- IL.AddCmd(IL.opCLEANUP, parSize);
- IL.AddCmd0(IL.opPOPSP)
- ELSIF cconv IN {PROG._win64, PROG.win64} THEN
- IL.AddCmd(IL.opCLEANUP, MAX(parSize + parSize MOD 2, 4) + 1);
- IL.AddCmd0(IL.opPOPSP)
- ELSIF cconv IN {PROG._systemv, PROG.systemv} THEN
- IL.AddCmd(IL.opCLEANUP, parSize + stk_par);
- IL.AddCmd0(IL.opPOPSP)
- ELSIF cconv IN {PROG._cdecl, PROG.cdecl, PROG.default16, PROG.code, PROG._code} THEN
- IL.AddCmd(IL.opCLEANUP, parSize)
- END;
- IF CallStat THEN
- IL.AddCmd0(IL.opRES);
- IL.drop
- ELSE
- IF isfloat THEN
- IL.AddCmd2(IL.opRESF, pos.line, pos.col)
- ELSE
- IL.AddCmd0(IL.opRES)
- END
- END
- END ProcCall;
- PROCEDURE expression (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- pos, pos0, pos1: PARS.POSITION;
- e1: PARS.EXPR;
- op, cmp, error: INTEGER;
- constant, eq: BOOLEAN;
- PROCEDURE relation (sym: INTEGER): BOOLEAN;
- RETURN (sym = SCAN.lxEQ) OR (sym = SCAN.lxNE) OR
- (sym = SCAN.lxLT) OR (sym = SCAN.lxLE) OR
- (sym = SCAN.lxGT) OR (sym = SCAN.lxGE) OR
- (sym = SCAN.lxIN) OR (sym = SCAN.lxIS)
- END relation;
- PROCEDURE AddOperator (sym: INTEGER): BOOLEAN;
- RETURN (sym = SCAN.lxPLUS) OR (sym = SCAN.lxMINUS) OR
- (sym = SCAN.lxOR)
- END AddOperator;
- PROCEDURE MulOperator (sym: INTEGER): BOOLEAN;
- RETURN (sym = SCAN.lxMUL) OR (sym = SCAN.lxSLASH) OR
- (sym = SCAN.lxDIV) OR (sym = SCAN.lxMOD) OR
- (sym = SCAN.lxAND)
- END MulOperator;
- PROCEDURE element (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- e1, e2: PARS.EXPR;
- pos: PARS.POSITION;
- range: BOOLEAN;
- BEGIN
- range := FALSE;
- getpos(parser, pos);
- expression(parser, e1);
- PARS.check(isInt(e1), pos, 76);
- IF e1.obj = eCONST THEN
- PARS.check(ARITH.range(e1.value, 0, UTILS.target.maxSet), pos, 44)
- END;
- range := parser.sym = SCAN.lxRANGE;
- IF range THEN
- NextPos(parser, pos);
- expression(parser, e2);
- PARS.check(isInt(e2), pos, 76);
- IF e2.obj = eCONST THEN
- PARS.check(ARITH.range(e2.value, 0, UTILS.target.maxSet), pos, 44)
- END
- ELSE
- IF e1.obj = eCONST THEN
- e2 := e1
- END
- END;
- e._type := tSET;
- IF (e1.obj = eCONST) & (e2.obj = eCONST) THEN
- ARITH.constrSet(e.value, e1.value, e2.value);
- e.obj := eCONST
- ELSE
- IF range THEN
- IF e1.obj = eCONST THEN
- IL.AddCmd(IL.opRSETL, ARITH.Int(e1.value))
- ELSIF e2.obj = eCONST THEN
- IL.AddCmd(IL.opRSETR, ARITH.Int(e2.value))
- ELSE
- IL.AddCmd0(IL.opRSET)
- END
- ELSE
- IL.AddCmd0(IL.opRSET1)
- END;
- e.obj := eEXPR
- END
- END element;
- PROCEDURE set (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- e1: PARS.EXPR;
- BEGIN
- ASSERT(parser.sym = SCAN.lxLCURLY);
- e.obj := eCONST;
- e._type := tSET;
- ARITH.emptySet(e.value);
- PARS.Next(parser);
- IF parser.sym # SCAN.lxRCURLY THEN
- element(parser, e1);
- IF e1.obj = eCONST THEN
- ARITH.opSet(e.value, e1.value, "+")
- ELSE
- e.obj := eEXPR
- END;
- WHILE parser.sym = SCAN.lxCOMMA DO
- PARS.Next(parser);
- element(parser, e1);
- IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
- ARITH.opSet(e.value, e1.value, "+")
- ELSE
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opADDSC, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opADDSC, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opADDS)
- END;
- e.obj := eEXPR
- END
- END;
- PARS.checklex(parser, SCAN.lxRCURLY)
- END;
- PARS.Next(parser);
- END set;
- PROCEDURE factor (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- sym: INTEGER;
- pos: PARS.POSITION;
- e1: PARS.EXPR;
- isfloat: BOOLEAN;
- PROCEDURE LoadVar (e: PARS.EXPR; parser: PARS.PARSER; pos: PARS.POSITION);
- BEGIN
- IF ~(e._type.typ IN {PROG.tRECORD, PROG.tARRAY}) THEN
- IF e._type = tREAL THEN
- IL.AddCmd2(IL.opLOADF, pos.line, pos.col)
- ELSE
- IL.load(e._type.size)
- END
- END
- END LoadVar;
- BEGIN
- sym := parser.sym;
- IF (sym = SCAN.lxINTEGER) OR (sym = SCAN.lxHEX) OR (sym = SCAN.lxFLOAT) OR (sym = SCAN.lxCHAR) OR (sym = SCAN.lxSTRING) THEN
- e.obj := eCONST;
- e.value := parser.lex.value;
- e._type := PROG.getType(e.value.typ);
- PARS.Next(parser)
- ELSIF sym = SCAN.lxNIL THEN
- e.obj := eCONST;
- e._type := PROG.program.stTypes.tNIL;
- PARS.Next(parser)
- ELSIF (sym = SCAN.lxTRUE) OR (sym = SCAN.lxFALSE) THEN
- e.obj := eCONST;
- ARITH.setbool(e.value, sym = SCAN.lxTRUE);
- e._type := tBOOLEAN;
- PARS.Next(parser)
- ELSIF sym = SCAN.lxLCURLY THEN
- set(parser, e)
- ELSIF sym = SCAN.lxIDENT THEN
- getpos(parser, pos);
- IL.pushBegEnd(begcall, endcall);
- designator(parser, e);
- IF isVar(e) THEN
- LoadVar(e, parser, pos)
- END;
- IF parser.sym = SCAN.lxLROUND THEN
- e1 := e;
- ActualParameters(parser, e);
- PARS.check(e._type # NIL, pos, 59);
- isfloat := e._type = tREAL;
- IF e1.obj IN {ePROC, eIMP} THEN
- ProcCall(e1, e1.ident._type, isfloat, parser, pos, FALSE)
- ELSIF isExpr(e1) THEN
- ProcCall(e1, e1._type, isfloat, parser, pos, FALSE)
- END
- END;
- IL.popBegEnd(begcall, endcall)
- ELSIF sym = SCAN.lxLROUND THEN
- PARS.Next(parser);
- expression(parser, e);
- PARS.checklex(parser, SCAN.lxRROUND);
- PARS.Next(parser);
- IF isExpr(e) & (e.obj # eCONST) THEN
- e.obj := eEXPR
- END
- ELSIF sym = SCAN.lxNOT THEN
- NextPos(parser, pos);
- factor(parser, e);
- PARS.check(isBoolean(e), pos, 72);
- IF e.obj # eCONST THEN
- IL.not;
- e.obj := eEXPR
- ELSE
- ASSERT(ARITH.neg(e.value))
- END
- ELSE
- PARS.check1(FALSE, parser, 34)
- END
- END factor;
- PROCEDURE term (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- pos: PARS.POSITION;
- e1: PARS.EXPR;
- op, label, label1: INTEGER;
- BEGIN
- factor(parser, e);
- label := -1;
- WHILE MulOperator(parser.sym) DO
- op := parser.sym;
- getpos(parser, pos);
- PARS.Next(parser);
- IF op = SCAN.lxAND THEN
- IF ~parser.constexp THEN
- IF label = -1 THEN
- label := IL.NewLabel()
- END;
- IF (e.obj = eCONST) & isBoolean(e) THEN
- IL.Const(ORD(ARITH.getBool(e.value)))
- END;
- IL.Jmp(IL.opJZ, label)
- END
- END;
- factor(parser, e1);
- CASE op OF
- |SCAN.lxMUL:
- PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
- IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
- CASE e.value.typ OF
- |ARITH.tINTEGER: PARS.check(ARITH.opInt(e.value, e1.value, "*"), pos, 39)
- |ARITH.tREAL: PARS.check(ARITH.opFloat(e.value, e1.value, "*"), pos, 40)
- |ARITH.tSET: ARITH.opSet(e.value, e1.value, "*")
- END
- ELSE
- IF isInt(e) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opMULC, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opMULC, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opMUL)
- END
- ELSIF isReal(e) THEN
- IF e.obj = eCONST THEN
- Float(parser, e)
- ELSIF e1.obj = eCONST THEN
- Float(parser, e1)
- END;
- IL.AddCmd0(IL.opMULF)
- ELSIF isSet(e) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opMULSC, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opMULSC, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opMULS)
- END
- END;
- e.obj := eEXPR
- END
- |SCAN.lxSLASH:
- PARS.check(isReal(e) & isReal(e1) OR isSet(e) & isSet(e1), pos, 37);
- IF (e1.obj = eCONST) & isReal(e1) THEN
- PARS.check(~ARITH.isZero(e1.value), pos, 45)
- END;
- IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
- CASE e.value.typ OF
- |ARITH.tREAL: PARS.check(ARITH.opFloat(e.value, e1.value, "/"), pos, 40)
- |ARITH.tSET: ARITH.opSet(e.value, e1.value, "/")
- END
- ELSE
- IF isReal(e) THEN
- IF e.obj = eCONST THEN
- Float(parser, e);
- IL.AddCmd0(IL.opDIVFI)
- ELSIF e1.obj = eCONST THEN
- Float(parser, e1);
- IL.AddCmd0(IL.opDIVF)
- ELSE
- IL.AddCmd0(IL.opDIVF)
- END
- ELSIF isSet(e) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opDIVSC, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opDIVSC, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opDIVS)
- END
- END;
- e.obj := eEXPR
- END
- |SCAN.lxDIV, SCAN.lxMOD:
- PARS.check(isInt(e) & isInt(e1), pos, 37);
- IF e1.obj = eCONST THEN
- PARS.check(ARITH.Int(e1.value) > 0, pos, 122)
- END;
- IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
- IF op = SCAN.lxDIV THEN
- PARS.check(ARITH.opInt(e.value, e1.value, "D"), pos, 39)
- ELSE
- ASSERT(ARITH.opInt(e.value, e1.value, "M"))
- END
- ELSE
- IF e1.obj # eCONST THEN
- label1 := IL.NewLabel();
- IL.Jmp(IL.opJG, label1)
- END;
- IF e.obj = eCONST THEN
- IL.OnError(pos.line, errDIV);
- IL.SetLabel(label1);
- IL.AddCmd(IL.opDIVL + ORD(op = SCAN.lxMOD), ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opDIVR + ORD(op = SCAN.lxMOD), ARITH.Int(e1.value))
- ELSE
- IL.OnError(pos.line, errDIV);
- IL.SetLabel(label1);
- IL.AddCmd0(IL.opDIV + ORD(op = SCAN.lxMOD))
- END;
- e.obj := eEXPR
- END
- |SCAN.lxAND:
- PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
- IF (e.obj = eCONST) & (e1.obj = eCONST) & parser.constexp THEN
- ARITH.opBoolean(e.value, e1.value, "&")
- ELSE
- e.obj := eEXPR;
- IF e1.obj = eCONST THEN
- IL.Const(ORD(ARITH.getBool(e1.value)))
- END
- END
- END
- END;
- IF label # -1 THEN
- label1 := IL.NewLabel();
- IL.Jmp(IL.opJNZ, label1);
- IL.SetLabel(label);
- IL.Const(0);
- IL.drop;
- label := IL.NewLabel();
- IL.Jmp(IL.opJMP, label);
- IL.SetLabel(label1);
- IL.Const(1);
- IL.SetLabel(label);
- IL.AddCmd0(IL.opAND)
- END
- END term;
- PROCEDURE SimpleExpression (parser: PARS.PARSER; VAR e: PARS.EXPR);
- VAR
- pos: PARS.POSITION;
- op: INTEGER;
- e1: PARS.EXPR;
- s, s1: SCAN.TEXTSTR;
- plus, minus: BOOLEAN;
- label, label1: INTEGER;
- BEGIN
- plus := parser.sym = SCAN.lxPLUS;
- minus := parser.sym = SCAN.lxMINUS;
- IF plus OR minus THEN
- getpos(parser, pos);
- PARS.Next(parser)
- END;
- term(parser, e);
- IF plus OR minus THEN
- PARS.check(isInt(e) OR isReal(e) OR isSet(e), pos, 36);
- IF minus & (e.obj = eCONST) THEN
- PARS.check(ARITH.neg(e.value), pos, 39)
- END;
- IF e.obj # eCONST THEN
- IF minus THEN
- IF isInt(e) THEN
- IL.AddCmd0(IL.opUMINUS)
- ELSIF isReal(e) THEN
- IL.AddCmd0(IL.opUMINF)
- ELSIF isSet(e) THEN
- IL.AddCmd0(IL.opUMINS)
- END
- END;
- e.obj := eEXPR
- END
- END;
- label := -1;
- WHILE AddOperator(parser.sym) DO
- op := parser.sym;
- getpos(parser, pos);
- PARS.Next(parser);
- IF op = SCAN.lxOR THEN
- IF ~parser.constexp THEN
- IF label = -1 THEN
- label := IL.NewLabel()
- END;
- IF (e.obj = eCONST) & isBoolean(e) THEN
- IL.Const(ORD(ARITH.getBool(e.value)))
- END;
- IL.Jmp(IL.opJNZ, label)
- END
- END;
- term(parser, e1);
- CASE op OF
- |SCAN.lxPLUS, SCAN.lxMINUS:
- minus := op = SCAN.lxMINUS;
- IF minus THEN
- op := ORD("-")
- ELSE
- op := ORD("+")
- END;
- PARS.check(isInt(e) & isInt(e1) OR isReal(e) & isReal(e1) OR isSet(e) & isSet(e1) OR isString(e) & isString(e1) & ~minus, pos, 37);
- IF (e.obj = eCONST) & (e1.obj = eCONST) THEN
- CASE e.value.typ OF
- |ARITH.tINTEGER:
- PARS.check(ARITH.opInt(e.value, e1.value, CHR(op)), pos, 39)
- |ARITH.tREAL:
- PARS.check(ARITH.opFloat(e.value, e1.value, CHR(op)), pos, 40)
- |ARITH.tSET:
- ARITH.opSet(e.value, e1.value, CHR(op))
- |ARITH.tCHAR, ARITH.tSTRING:
- IF e.value.typ = ARITH.tCHAR THEN
- ARITH.charToStr(e.value, s)
- ELSE
- s := e.value.string(SCAN.STRING).s
- END;
- IF e1.value.typ = ARITH.tCHAR THEN
- ARITH.charToStr(e1.value, s1)
- ELSE
- s1 := e1.value.string(SCAN.STRING).s
- END;
- PARS.check(ARITH.concat(s, s1), pos, 5);
- e.value.string := SCAN.enterStr(s);
- e.value.typ := ARITH.tSTRING;
- e._type := PROG.program.stTypes.tSTRING
- END
- ELSE
- IF isInt(e) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opADDC - ORD(minus), ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opADDC + ORD(minus), ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opADD + ORD(minus))
- END
- ELSIF isReal(e) THEN
- IF e.obj = eCONST THEN
- Float(parser, e);
- IL.AddCmd0(IL.opADDF - ORD(minus))
- ELSIF e1.obj = eCONST THEN
- Float(parser, e1);
- IL.AddCmd0(IL.opADDF + ORD(minus))
- ELSE
- IL.AddCmd0(IL.opADDF + ORD(minus))
- END
- ELSIF isSet(e) THEN
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opADDSC - ORD(minus), ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opADDSC + ORD(minus), ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opADDS + ORD(minus))
- END
- END;
- e.obj := eEXPR
- END
- |SCAN.lxOR:
- PARS.check(isBoolean(e) & isBoolean(e1), pos, 37);
- IF (e.obj = eCONST) & (e1.obj = eCONST) & parser.constexp THEN
- ARITH.opBoolean(e.value, e1.value, "|")
- ELSE
- e.obj := eEXPR;
- IF e1.obj = eCONST THEN
- IL.Const(ORD(ARITH.getBool(e1.value)))
- END
- END
- END
- END;
- IF label # -1 THEN
- label1 := IL.NewLabel();
- IL.Jmp(IL.opJZ, label1);
- IL.SetLabel(label);
- IL.Const(1);
- IL.drop;
- label := IL.NewLabel();
- IL.Jmp(IL.opJMP, label);
- IL.SetLabel(label1);
- IL.Const(0);
- IL.SetLabel(label);
- IL.AddCmd0(IL.opOR)
- END
- END SimpleExpression;
- PROCEDURE cmpcode (op: INTEGER): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- CASE op OF
- |SCAN.lxEQ: res := ARITH.opEQ
- |SCAN.lxNE: res := ARITH.opNE
- |SCAN.lxLT: res := ARITH.opLT
- |SCAN.lxLE: res := ARITH.opLE
- |SCAN.lxGT: res := ARITH.opGT
- |SCAN.lxGE: res := ARITH.opGE
- |SCAN.lxIN: res := ARITH.opIN
- |SCAN.lxIS: res := ARITH.opIS
- END
- RETURN res
- END cmpcode;
- PROCEDURE invcmpcode (op: INTEGER): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- CASE op OF
- |SCAN.lxEQ: res := ARITH.opEQ
- |SCAN.lxNE: res := ARITH.opNE
- |SCAN.lxLT: res := ARITH.opGT
- |SCAN.lxLE: res := ARITH.opGE
- |SCAN.lxGT: res := ARITH.opLT
- |SCAN.lxGE: res := ARITH.opLE
- |SCAN.lxIN: res := ARITH.opIN
- |SCAN.lxIS: res := ARITH.opIS
- END
- RETURN res
- END invcmpcode;
- PROCEDURE BoolCmp (eq, val: BOOLEAN);
- BEGIN
- IF eq = val THEN
- IL.AddCmd0(IL.opNEC)
- ELSE
- IL.AddCmd0(IL.opEQC)
- END
- END BoolCmp;
- PROCEDURE strcmp (VAR e, e1: PARS.EXPR; op: INTEGER): BOOLEAN;
- VAR
- res: BOOLEAN;
- cmp: INTEGER;
- BEGIN
- res := TRUE;
- cmp := cmpcode(op);
- IF isString(e) & isCharArray(e1) THEN
- IL.StrAdr(String(e));
- IL.Const(strlen(e) + 1);
- IL.AddCmd0(IL.opEQS + invcmpcode(op))
- ELSIF (isString(e) OR isStringW(e)) & isCharArrayW(e1) THEN
- IL.StrAdr(StringW(e));
- IL.Const(utf8strlen(e) + 1);
- IL.AddCmd0(IL.opEQSW + invcmpcode(op))
- ELSIF isCharArray(e) & isString(e1) THEN
- IL.StrAdr(String(e1));
- IL.Const(strlen(e1) + 1);
- IL.AddCmd0(IL.opEQS + cmp)
- ELSIF isCharArrayW(e) & (isString(e1) OR isStringW(e1)) THEN
- IL.StrAdr(StringW(e1));
- IL.Const(utf8strlen(e1) + 1);
- IL.AddCmd0(IL.opEQSW + cmp)
- ELSIF isCharArrayW(e) & isCharArrayW(e1) THEN
- IL.AddCmd0(IL.opEQSW + cmp)
- ELSIF isCharArray(e) & isCharArray(e1) THEN
- IL.AddCmd0(IL.opEQS + cmp)
- ELSIF isString(e) & isString(e1) THEN
- PARS.strcmp(e.value, e1.value, op)
- ELSE
- res := FALSE
- END
- RETURN res
- END strcmp;
- BEGIN
- getpos(parser, pos0);
- SimpleExpression(parser, e);
- IF relation(parser.sym) THEN
- IF (isCharArray(e) OR isCharArrayW(e)) & (e._type.length # 0) THEN
- IL.Const(e._type.length)
- END;
- op := parser.sym;
- getpos(parser, pos);
- PARS.Next(parser);
- getpos(parser, pos1);
- SimpleExpression(parser, e1);
- IF (isCharArray(e1) OR isCharArrayW(e1)) & (e1._type.length # 0) THEN
- IL.Const(e1._type.length)
- END;
- constant := (e.obj = eCONST) & (e1.obj = eCONST);
- error := 0;
- cmp := cmpcode(op);
- CASE op OF
- |SCAN.lxEQ, SCAN.lxNE:
- eq := op = SCAN.lxEQ;
- IF isInt(e) & isInt(e1) OR isSet(e) & isSet(e1) OR isChar(e) & isChar(e1) OR isCharW(e) & isCharW(e1) OR
- isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
- isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
- isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) OR
- isPtr(e) & isPtr(e1) & (PROG.isBaseOf(e._type, e1._type) OR PROG.isBaseOf(e1._type, e._type)) THEN
- IF constant THEN
- ARITH.relation(e.value, e1.value, cmp, error)
- ELSE
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opEQ + cmp)
- END
- END
- ELSIF isStringW1(e) & isCharW(e1) THEN
- IL.AddCmd(IL.opEQC + cmp, StrToWChar(e.value.string(SCAN.STRING).s))
- ELSIF isStringW1(e1) & isCharW(e) THEN
- IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.STRING).s))
- ELSIF isBoolean(e) & isBoolean(e1) THEN
- IF constant THEN
- ARITH.relation(e.value, e1.value, cmp, error)
- ELSE
- IF e.obj = eCONST THEN
- BoolCmp(eq, ARITH.Int(e.value) # 0)
- ELSIF e1.obj = eCONST THEN
- BoolCmp(eq, ARITH.Int(e1.value) # 0)
- ELSE
- IF eq THEN
- IL.AddCmd0(IL.opEQB)
- ELSE
- IL.AddCmd0(IL.opNEB)
- END
- END
- END
- ELSIF isReal(e) & isReal(e1) THEN
- IF constant THEN
- ARITH.relation(e.value, e1.value, cmp, error)
- ELSE
- IF e.obj = eCONST THEN
- Float(parser, e)
- ELSIF e1.obj = eCONST THEN
- Float(parser, e1)
- END;
- IL.AddCmd0(IL.opEQF + cmp)
- END
- ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
- IF ~strcmp(e, e1, op) THEN
- PARS.error(pos, 37)
- END
- ELSIF isPtr(e) & isNil(e1) OR isNil(e) & isPtr(e1) THEN
- IL.AddCmd0(IL.opEQC + cmp)
- ELSIF isProc(e) & isNil(e1) THEN
- IF e.obj IN {ePROC, eIMP} THEN
- PARS.check(e.ident.global, pos0, 85);
- constant := TRUE;
- e.obj := eCONST;
- ARITH.setbool(e.value, ~eq)
- ELSE
- IL.AddCmd0(IL.opEQC + cmp)
- END
- ELSIF isNil(e) & isProc(e1) THEN
- IF e1.obj IN {ePROC, eIMP} THEN
- PARS.check(e1.ident.global, pos1, 85);
- constant := TRUE;
- e.obj := eCONST;
- ARITH.setbool(e.value, ~eq)
- ELSE
- IL.AddCmd0(IL.opEQC + cmp)
- END
- ELSIF isProc(e) & isProc(e1) & PROG.isTypeEq(e._type, e1._type) THEN
- IF e.obj = ePROC THEN
- PARS.check(e.ident.global, pos0, 85)
- END;
- IF e1.obj = ePROC THEN
- PARS.check(e1.ident.global, pos1, 85)
- END;
- IF (e.obj IN {ePROC, eIMP}) & (e1.obj IN {ePROC, eIMP}) THEN
- constant := TRUE;
- e.obj := eCONST;
- IF eq THEN
- ARITH.setbool(e.value, e.ident = e1.ident)
- ELSE
- ARITH.setbool(e.value, e.ident # e1.ident)
- END
- ELSIF e.obj = ePROC THEN
- IL.ProcCmp(e.ident.proc.label, eq)
- ELSIF e1.obj = ePROC THEN
- IL.ProcCmp(e1.ident.proc.label, eq)
- ELSIF e.obj = eIMP THEN
- IL.ProcImpCmp(e.ident._import, eq)
- ELSIF e1.obj = eIMP THEN
- IL.ProcImpCmp(e1.ident._import, eq)
- ELSE
- IL.AddCmd0(IL.opEQ + cmp)
- END
- ELSIF isNil(e) & isNil(e1) THEN
- constant := TRUE;
- e.obj := eCONST;
- ARITH.setbool(e.value, eq)
- ELSE
- PARS.error(pos, 37)
- END
- |SCAN.lxLT, SCAN.lxLE, SCAN.lxGT, SCAN.lxGE:
- IF isInt(e) & isInt(e1) OR isChar(e) & isChar(e1) OR isCharW(e) & isCharW(e1) OR
- isCharW(e) & isChar(e1) & (e1.obj = eCONST) OR isCharW(e1) & isChar(e) & (e.obj = eCONST) OR
- isCharW(e1) & (e1.obj = eCONST) & isChar(e) & (e.obj = eCONST) OR
- isCharW(e) & (e.obj = eCONST) & isChar(e1) & (e1.obj = eCONST) THEN
- IF constant THEN
- ARITH.relation(e.value, e1.value, cmp, error)
- ELSE
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opEQC + invcmpcode(op), ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opEQC + cmp, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opEQ + cmp)
- END
- END
- ELSIF isStringW1(e) & isCharW(e1) THEN
- IL.AddCmd(IL.opEQC + invcmpcode(op), StrToWChar(e.value.string(SCAN.STRING).s))
- ELSIF isStringW1(e1) & isCharW(e) THEN
- IL.AddCmd(IL.opEQC + cmp, StrToWChar(e1.value.string(SCAN.STRING).s))
- ELSIF isReal(e) & isReal(e1) THEN
- IF constant THEN
- ARITH.relation(e.value, e1.value, cmp, error)
- ELSE
- IF e.obj = eCONST THEN
- Float(parser, e);
- IL.AddCmd0(IL.opEQF + invcmpcode(op))
- ELSIF e1.obj = eCONST THEN
- Float(parser, e1);
- IL.AddCmd0(IL.opEQF + cmp)
- ELSE
- IL.AddCmd0(IL.opEQF + cmp)
- END
- END
- ELSIF (isStringW(e) OR isCharArrayX(e)) & (isStringW(e1) OR isCharArrayX(e1)) THEN
- IF ~strcmp(e, e1, op) THEN
- PARS.error(pos, 37)
- END
- ELSE
- PARS.error(pos, 37)
- END
- |SCAN.lxIN:
- PARS.check(isInt(e) & isSet(e1), pos, 37);
- IF e.obj = eCONST THEN
- PARS.check(ARITH.range(e.value, 0, UTILS.target.maxSet), pos0, 56)
- END;
- IF constant THEN
- ARITH.relation(e.value, e1.value, ARITH.opIN, error)
- ELSE
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opINL, ARITH.Int(e.value))
- ELSIF e1.obj = eCONST THEN
- IL.AddCmd(IL.opINR, ARITH.Int(e1.value))
- ELSE
- IL.AddCmd0(IL.opIN)
- END
- END
- |SCAN.lxIS:
- PARS.check(isRecPtr(e), pos, 73);
- PARS.check(e1.obj = eTYPE, pos1, 79);
- IF isRec(e) THEN
- PARS.check(e.obj = eVREC, pos0, 78);
- PARS.check(e1._type.typ = PROG.tRECORD, pos1, 80);
- IF e.ident = NIL THEN
- IL.TypeCheck(e1._type.num)
- ELSE
- IL.AddCmd(IL.opVADR, e.ident.offset - 1);
- IL.TypeCheckRec(e1._type.num)
- END
- ELSE
- PARS.check(e1._type.typ = PROG.tPOINTER, pos1, 81);
- IL.TypeCheck(e1._type.base.num)
- END;
- PARS.check(PROG.isBaseOf(e._type, e1._type), pos1, 82)
- END;
- ASSERT(error = 0);
- e._type := tBOOLEAN;
- IF ~constant THEN
- e.obj := eEXPR
- END
- END
- END expression;
- PROCEDURE ElementaryStatement (parser: PARS.PARSER);
- VAR
- e, e1: PARS.EXPR;
- pos: PARS.POSITION;
- line: INTEGER;
- call: BOOLEAN;
- BEGIN
- getpos(parser, pos);
- IL.pushBegEnd(begcall, endcall);
- designator(parser, e);
- IF parser.sym = SCAN.lxASSIGN THEN
- line := parser.lex.pos.line;
- PARS.check(isVar(e), pos, 93);
- PARS.check(~e.readOnly, pos, 94);
- IL.setlast(begcall);
- NextPos(parser, pos);
- expression(parser, e1);
- IF (e._type.typ = PROG.tBYTE) & (e1.obj # eCONST) & (e1._type.typ = PROG.tINTEGER) & (chkBYTE IN Options.checking) THEN
- CheckRange(256, pos.line, errBYTE)
- END;
- IL.setlast(endcall.prev(IL.COMMAND));
- PARS.check(assign(parser, e1, e._type, line), pos, 91);
- IF e1.obj = ePROC THEN
- PARS.check(e1.ident.global, pos, 85)
- END;
- call := FALSE
- ELSIF parser.sym = SCAN.lxEQ THEN
- PARS.check1(FALSE, parser, 96)
- ELSIF parser.sym = SCAN.lxLROUND THEN
- e1 := e;
- ActualParameters(parser, e1);
- PARS.check((e1._type = NIL) OR ODD(e._type.call), pos, 92);
- call := TRUE
- ELSE
- IF e.obj IN {eSYSPROC, eSTPROC} THEN
- stProc(parser, e);
- call := FALSE
- ELSE
- PARS.check(isProc(e), pos, 86);
- PARS.check((e._type.base = NIL) OR ODD(e._type.call), pos, 92);
- PARS.check1(e._type.params.first = NIL, parser, 64);
- call := TRUE
- END
- END;
- IF call THEN
- IF e.obj IN {ePROC, eIMP} THEN
- ProcCall(e, e.ident._type, FALSE, parser, pos, TRUE)
- ELSIF isExpr(e) THEN
- ProcCall(e, e._type, FALSE, parser, pos, TRUE)
- END
- END;
- IL.popBegEnd(begcall, endcall)
- END ElementaryStatement;
- PROCEDURE IfStatement (parser: PARS.PARSER; _if: BOOLEAN);
- VAR
- e: PARS.EXPR;
- pos: PARS.POSITION;
- label, L: INTEGER;
- BEGIN
- L := IL.NewLabel();
- IF ~_if THEN
- IL.AddCmd(IL.opNOP, IL.begin_loop);
- IL.SetLabel(L)
- END;
- REPEAT
- NextPos(parser, pos);
- label := IL.NewLabel();
- expression(parser, e);
- PARS.check(isBoolean(e), pos, 72);
- IF e.obj = eCONST THEN
- IF ~ARITH.getBool(e.value) THEN
- IL.Jmp(IL.opJMP, label)
- END
- ELSE
- IL.AndOrOpt(label)
- END;
- IF _if THEN
- PARS.checklex(parser, SCAN.lxTHEN)
- ELSE
- PARS.checklex(parser, SCAN.lxDO)
- END;
- PARS.Next(parser);
- parser.StatSeq(parser);
- IF ~_if OR (parser.sym # SCAN.lxEND) THEN
- IL.Jmp(IL.opJMP, L)
- END;
- IL.SetLabel(label)
- UNTIL parser.sym # SCAN.lxELSIF;
- IF _if THEN
- IF parser.sym = SCAN.lxELSE THEN
- PARS.Next(parser);
- parser.StatSeq(parser)
- END;
- IL.SetLabel(L)
- ELSE
- IL.AddCmd(IL.opNOP, IL.end_loop)
- END;
- PARS.checklex(parser, SCAN.lxEND);
- PARS.Next(parser)
- END IfStatement;
- PROCEDURE RepeatStatement (parser: PARS.PARSER);
- VAR
- e: PARS.EXPR;
- pos: PARS.POSITION;
- label: INTEGER;
- L: IL.COMMAND;
- BEGIN
- IL.AddCmd(IL.opNOP, IL.begin_loop);
- label := IL.NewLabel();
- IL.SetLabel(label);
- L := IL.getlast();
- PARS.Next(parser);
- parser.StatSeq(parser);
- PARS.checklex(parser, SCAN.lxUNTIL);
- NextPos(parser, pos);
- expression(parser, e);
- PARS.check(isBoolean(e), pos, 72);
- IF e.obj = eCONST THEN
- IF ~ARITH.getBool(e.value) THEN
- IL.Jmp(IL.opJMP, label)
- END
- ELSE
- IL.AndOrOpt(label);
- L.param1 := label
- END;
- IL.AddCmd(IL.opNOP, IL.end_loop)
- END RepeatStatement;
- PROCEDURE LabelCmp (a, b: AVL.DATA): INTEGER;
- VAR
- La, Ra, Lb, Rb, res: INTEGER;
- BEGIN
- La := a(CASE_LABEL).range.a;
- Ra := a(CASE_LABEL).range.b;
- Lb := b(CASE_LABEL).range.a;
- Rb := b(CASE_LABEL).range.b;
- IF (Ra < Lb) OR (La > Rb) THEN
- res := ORD(La > Lb) - ORD(La < Lb)
- ELSE
- res := 0
- END
- RETURN res
- END LabelCmp;
- PROCEDURE DestroyLabel (VAR label: AVL.DATA);
- BEGIN
- C.push(CaseLabels, label);
- label := NIL
- END DestroyLabel;
- PROCEDURE NewVariant (label: INTEGER; cmd: IL.COMMAND): CASE_VARIANT;
- VAR
- res: CASE_VARIANT;
- citem: C.ITEM;
- BEGIN
- citem := C.pop(CaseVar);
- IF citem = NIL THEN
- NEW(res)
- ELSE
- res := citem(CASE_VARIANT)
- END;
- res.label := label;
- res.cmd := cmd;
- res.processed := FALSE
- RETURN res
- END NewVariant;
- PROCEDURE CaseStatement (parser: PARS.PARSER);
- VAR
- e: PARS.EXPR;
- pos: PARS.POSITION;
- PROCEDURE Label (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR _type: PROG._TYPE): INTEGER;
- VAR
- a: INTEGER;
- label: PARS.EXPR;
- pos: PARS.POSITION;
- value: ARITH.VALUE;
- BEGIN
- getpos(parser, pos);
- _type := NIL;
- IF isChar(caseExpr) THEN
- PARS.ConstExpression(parser, value);
- PARS.check(value.typ = ARITH.tCHAR, pos, 99);
- a := ARITH.getInt(value)
- ELSIF isCharW(caseExpr) THEN
- PARS.ConstExpression(parser, value);
- IF (value.typ = ARITH.tSTRING) & (_length(value.string(SCAN.STRING).s) = 1) & (LENGTH(value.string(SCAN.STRING).s) > 1) THEN
- ASSERT(ARITH.setInt(value, StrToWChar(value.string(SCAN.STRING).s)))
- ELSE
- PARS.check(value.typ IN {ARITH.tWCHAR, ARITH.tCHAR}, pos, 99)
- END;
- a := ARITH.getInt(value)
- ELSIF isInt(caseExpr) THEN
- PARS.ConstExpression(parser, value);
- PARS.check(value.typ = ARITH.tINTEGER, pos, 99);
- a := ARITH.getInt(value)
- ELSIF isRecPtr(caseExpr) THEN
- qualident(parser, label);
- PARS.check(label.obj = eTYPE, pos, 79);
- PARS.check(PROG.isBaseOf(caseExpr._type, label._type), pos, 99);
- IF isRec(caseExpr) THEN
- a := label._type.num
- ELSE
- a := label._type.base.num
- END;
- _type := label._type
- END
- RETURN a
- END Label;
- PROCEDURE CheckType (node: AVL.NODE; _type: PROG._TYPE; parser: PARS.PARSER; pos: PARS.POSITION);
- BEGIN
- IF node # NIL THEN
- PARS.check(~(PROG.isBaseOf(node.data(CASE_LABEL)._type, _type) OR PROG.isBaseOf(_type, node.data(CASE_LABEL)._type)), pos, 100);
- CheckType(node.left, _type, parser, pos);
- CheckType(node.right, _type, parser, pos)
- END
- END CheckType;
- PROCEDURE LabelRange (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; variant: INTEGER): AVL.NODE;
- VAR
- label: CASE_LABEL;
- citem: C.ITEM;
- pos, pos1: PARS.POSITION;
- node: AVL.NODE;
- newnode: BOOLEAN;
- range: RANGE;
- BEGIN
- citem := C.pop(CaseLabels);
- IF citem = NIL THEN
- NEW(label)
- ELSE
- label := citem(CASE_LABEL)
- END;
- label.variant := variant;
- label.self := IL.NewLabel();
- getpos(parser, pos1);
- range.a := Label(parser, caseExpr, label._type);
- IF parser.sym = SCAN.lxRANGE THEN
- PARS.check1(~isRecPtr(caseExpr), parser, 53);
- NextPos(parser, pos);
- range.b := Label(parser, caseExpr, label._type);
- PARS.check(range.a <= range.b, pos, 103)
- ELSE
- range.b := range.a
- END;
- label.range := range;
- IF isRecPtr(caseExpr) THEN
- CheckType(tree, label._type, parser, pos1)
- END;
- tree := AVL.insert(tree, label, LabelCmp, newnode, node);
- PARS.check(newnode, pos1, 100)
- RETURN node
- END LabelRange;
- PROCEDURE CaseLabelList (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; variant: INTEGER): AVL.NODE;
- VAR
- exit: BOOLEAN;
- res: AVL.NODE;
- BEGIN
- exit := FALSE;
- REPEAT
- res := LabelRange(parser, caseExpr, tree, variant);
- IF parser.sym = SCAN.lxCOMMA THEN
- PARS.check1(~isRecPtr(caseExpr), parser, 53);
- PARS.Next(parser)
- ELSE
- exit := TRUE
- END
- UNTIL exit
- RETURN res
- END CaseLabelList;
- PROCEDURE _case (parser: PARS.PARSER; caseExpr: PARS.EXPR; VAR tree: AVL.NODE; _end: INTEGER);
- VAR
- sym: INTEGER;
- t: PROG._TYPE;
- variant: INTEGER;
- node: AVL.NODE;
- last: IL.COMMAND;
- BEGIN
- sym := parser.sym;
- IF sym # SCAN.lxBAR THEN
- variant := IL.NewLabel();
- node := CaseLabelList(parser, caseExpr, tree, variant);
- PARS.checklex(parser, SCAN.lxCOLON);
- PARS.Next(parser);
- IF isRecPtr(caseExpr) THEN
- t := caseExpr._type;
- caseExpr.ident._type := node.data(CASE_LABEL)._type
- END;
- last := IL.getlast();
- IL.SetLabel(variant);
- IF ~isRecPtr(caseExpr) THEN
- LISTS.push(CaseVariants, NewVariant(variant, last))
- END;
- parser.StatSeq(parser);
- IL.Jmp(IL.opJMP, _end);
- IF isRecPtr(caseExpr) THEN
- caseExpr.ident._type := t
- END
- END
- END _case;
- PROCEDURE Table (node: AVL.NODE; _else: INTEGER);
- VAR
- L, R: INTEGER;
- range: RANGE;
- left, right: AVL.NODE;
- last: IL.COMMAND;
- v: CASE_VARIANT;
- BEGIN
- IF node # NIL THEN
- range := node.data(CASE_LABEL).range;
- left := node.left;
- IF left # NIL THEN
- L := left.data(CASE_LABEL).self
- ELSE
- L := _else
- END;
- right := node.right;
- IF right # NIL THEN
- R := right.data(CASE_LABEL).self
- ELSE
- R := _else
- END;
- last := IL.getlast();
- v := CaseVariants.last(CASE_VARIANT);
- WHILE (v # NIL) & (v.label # 0) & (v.label # node.data(CASE_LABEL).variant) DO
- v := v.prev(CASE_VARIANT)
- END;
- ASSERT((v # NIL) & (v.label # 0));
- IL.setlast(v.cmd);
- IL.SetLabel(node.data(CASE_LABEL).self);
- IL._case(range.a, range.b, L, R);
- IF v.processed THEN
- IL.Jmp(IL.opJMP, node.data(CASE_LABEL).variant)
- END;
- v.processed := TRUE;
- IL.setlast(last);
- Table(left, _else);
- Table(right, _else)
- END
- END Table;
- PROCEDURE TableT (node: AVL.NODE);
- BEGIN
- IF node # NIL THEN
- IL.AddCmd2(IL.opCASET, node.data(CASE_LABEL).variant, node.data(CASE_LABEL).range.a);
- TableT(node.left);
- TableT(node.right)
- END
- END TableT;
- PROCEDURE ParseCase (parser: PARS.PARSER; e: PARS.EXPR; pos: PARS.POSITION);
- VAR
- table, _end, _else: INTEGER;
- tree: AVL.NODE;
- item: LISTS.ITEM;
- BEGIN
- LISTS.push(CaseVariants, NewVariant(0, NIL));
- _end := IL.NewLabel();
- _else := IL.NewLabel();
- table := IL.NewLabel();
- IL.AddCmd(IL.opSWITCH, ORD(isRecPtr(e)));
- IL.Jmp(IL.opJMP, table);
- tree := NIL;
- _case(parser, e, tree, _end);
- WHILE parser.sym = SCAN.lxBAR DO
- PARS.Next(parser);
- _case(parser, e, tree, _end)
- END;
- IL.SetLabel(_else);
- IF parser.sym = SCAN.lxELSE THEN
- PARS.Next(parser);
- parser.StatSeq(parser);
- IL.Jmp(IL.opJMP, _end)
- ELSE
- IL.OnError(pos.line, errCASE)
- END;
- PARS.checklex(parser, SCAN.lxEND);
- PARS.Next(parser);
- IF isRecPtr(e) THEN
- IL.SetLabel(table);
- TableT(tree);
- IL.Jmp(IL.opJMP, _else)
- ELSE
- tree.data(CASE_LABEL).self := table;
- Table(tree, _else)
- END;
- AVL.destroy(tree, DestroyLabel);
- IL.SetLabel(_end);
- IL.AddCmd0(IL.opENDSW);
- REPEAT
- item := LISTS.pop(CaseVariants);
- C.push(CaseVar, item)
- UNTIL item(CASE_VARIANT).cmd = NIL
- END ParseCase;
- BEGIN
- NextPos(parser, pos);
- expression(parser, e);
- PARS.check(isInt(e) OR isChar(e) OR isCharW(e) OR isPtr(e) OR isRec(e), pos, 95);
- IF isRecPtr(e) THEN
- PARS.check(isVar(e), pos, 93);
- PARS.check(e.ident # NIL, pos, 106)
- END;
- IF isRec(e) THEN
- PARS.check(e.obj = eVREC, pos, 78)
- END;
- IF e.obj = eCONST THEN
- LoadConst(e)
- ELSIF isRec(e) THEN
- IL.drop;
- IL.AddCmd(IL.opLADR, e.ident.offset - 1);
- IL.load(TARGETS.WordSize)
- ELSIF isPtr(e) THEN
- deref(pos, e, FALSE, errPTR);
- IL.AddCmd(IL.opSUBR, TARGETS.WordSize);
- IL.load(TARGETS.WordSize)
- END;
- PARS.checklex(parser, SCAN.lxOF);
- PARS.Next(parser);
- ParseCase(parser, e, pos)
- END CaseStatement;
- PROCEDURE ForStatement (parser: PARS.PARSER);
- VAR
- e: PARS.EXPR;
- pos, pos2: PARS.POSITION;
- step: ARITH.VALUE;
- st: INTEGER;
- ident: PROG.IDENT;
- offset: INTEGER;
- L1, L2: INTEGER;
- BEGIN
- IL.AddCmd(IL.opNOP, IL.begin_loop);
- L1 := IL.NewLabel();
- L2 := IL.NewLabel();
- PARS.ExpectSym(parser, SCAN.lxIDENT);
- ident := PROG.getIdent(parser.unit, parser.lex.ident, TRUE);
- PARS.check1(ident # NIL, parser, 48);
- PARS.check1(ident.typ = PROG.idVAR, parser, 93);
- PARS.check1(ident._type = tINTEGER, parser, 97);
- PARS.ExpectSym(parser, SCAN.lxASSIGN);
- NextPos(parser, pos);
- expression(parser, e);
- PARS.check(isInt(e), pos, 76);
- offset := PROG.getOffset(ident);
- IF ident.global THEN
- IL.AddCmd(IL.opGADR, offset)
- ELSE
- IL.AddCmd(IL.opLADR, -offset)
- END;
- IF e.obj = eCONST THEN
- IL.AddCmd(IL.opSAVEC, ARITH.Int(e.value))
- ELSE
- IL.AddCmd0(IL.opSAVE)
- END;
- IL.SetLabel(L1);
- IF ident.global THEN
- IL.AddCmd(IL.opGADR, offset)
- ELSE
- IL.AddCmd(IL.opLADR, -offset)
- END;
- IL.load(ident._type.size);
- PARS.checklex(parser, SCAN.lxTO);
- NextPos(parser, pos2);
- expression(parser, e);
- PARS.check(isInt(e), pos2, 76);
- IF parser.sym = SCAN.lxBY THEN
- NextPos(parser, pos);
- PARS.ConstExpression(parser, step);
- PARS.check(step.typ = ARITH.tINTEGER, pos, 76);
- st := ARITH.getInt(step);
- PARS.check(st # 0, pos, 98)
- ELSE
- st := 1
- END;
- IF e.obj = eCONST THEN
- IF st > 0 THEN
- IL.AddCmd(IL.opLEC, ARITH.Int(e.value));
- IF ARITH.Int(e.value) = UTILS.target.maxInt THEN
- ERRORS.WarningMsg(pos2.line, pos2.col, 1)
- END
- ELSE
- IL.AddCmd(IL.opGEC, ARITH.Int(e.value));
- IF ARITH.Int(e.value) = UTILS.target.minInt THEN
- ERRORS.WarningMsg(pos2.line, pos2.col, 1)
- END
- END
- ELSE
- IF st > 0 THEN
- IL.AddCmd0(IL.opLE)
- ELSE
- IL.AddCmd0(IL.opGE)
- END
- END;
- IL.Jmp(IL.opJZ, L2);
- PARS.checklex(parser, SCAN.lxDO);
- PARS.Next(parser);
- parser.StatSeq(parser);
- IF ident.global THEN
- IL.AddCmd(IL.opGADR, offset)
- ELSE
- IL.AddCmd(IL.opLADR, -offset)
- END;
- IL.AddCmd(IL.opINCC, st);
- IL.Jmp(IL.opJMP, L1);
- PARS.checklex(parser, SCAN.lxEND);
- PARS.Next(parser);
- IL.SetLabel(L2);
- IL.AddCmd(IL.opNOP, IL.end_loop)
- END ForStatement;
- PROCEDURE statement (parser: PARS.PARSER);
- VAR
- sym: INTEGER;
- BEGIN
- sym := parser.sym;
- IF sym = SCAN.lxIDENT THEN
- ElementaryStatement(parser)
- ELSIF sym = SCAN.lxIF THEN
- IfStatement(parser, TRUE)
- ELSIF sym = SCAN.lxWHILE THEN
- IfStatement(parser, FALSE)
- ELSIF sym = SCAN.lxREPEAT THEN
- RepeatStatement(parser)
- ELSIF sym = SCAN.lxCASE THEN
- CaseStatement(parser)
- ELSIF sym = SCAN.lxFOR THEN
- ForStatement(parser)
- END
- END statement;
- PROCEDURE StatSeq (parser: PARS.PARSER);
- BEGIN
- statement(parser);
- WHILE parser.sym = SCAN.lxSEMI DO
- PARS.Next(parser);
- statement(parser)
- END
- END StatSeq;
- PROCEDURE chkreturn (parser: PARS.PARSER; e: PARS.EXPR; t: PROG._TYPE; pos: PARS.POSITION): BOOLEAN;
- VAR
- res: BOOLEAN;
- BEGIN
- res := assigncomp(e, t);
- IF res THEN
- IF e.obj = eCONST THEN
- IF e._type = tREAL THEN
- Float(parser, e)
- ELSIF e._type.typ = PROG.tNIL THEN
- IL.Const(0)
- ELSE
- LoadConst(e)
- END
- ELSIF (e._type = tINTEGER) & (t = tBYTE) & (chkBYTE IN Options.checking) THEN
- CheckRange(256, pos.line, errBYTE)
- ELSIF e.obj = ePROC THEN
- PARS.check(e.ident.global, pos, 85);
- IL.PushProc(e.ident.proc.label)
- ELSIF e.obj = eIMP THEN
- IL.PushImpProc(e.ident._import)
- END
- END
- RETURN res
- END chkreturn;
- PROCEDURE setrtl;
- VAR
- rtl: PROG.UNIT;
- PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.IDSTR; idx: INTEGER);
- VAR
- id: PROG.IDENT;
- ident: SCAN.IDENT;
- BEGIN
- SCAN.setIdent(ident, name);
- id := PROG.getIdent(rtl, ident, FALSE);
- IF (id # NIL) & (id._import # NIL) THEN
- IL.set_rtl(idx, -id._import(IL.IMPORT_PROC).label);
- id.proc.used := TRUE
- ELSIF (id # NIL) & (id.proc # NIL) THEN
- IL.set_rtl(idx, id.proc.label);
- id.proc.used := TRUE
- ELSE
- ERRORS.WrongRTL(name)
- END
- END getproc;
- BEGIN
- rtl := PROG.program.rtl;
- ASSERT(rtl # NIL);
- getproc(rtl, "_strcmp", IL._strcmp);
- getproc(rtl, "_length", IL._length);
- getproc(rtl, "_arrcpy", IL._arrcpy);
- getproc(rtl, "_is", IL._is);
- getproc(rtl, "_guard", IL._guard);
- getproc(rtl, "_guardrec", IL._guardrec);
- getproc(rtl, "_new", IL._new);
- getproc(rtl, "_rot", IL._rot);
- getproc(rtl, "_strcpy", IL._strcpy);
- getproc(rtl, "_move", IL._move);
- getproc(rtl, "_set", IL._set);
- getproc(rtl, "_set1", IL._set1);
- getproc(rtl, "_lengthw", IL._lengthw);
- getproc(rtl, "_strcmpw", IL._strcmpw);
- getproc(rtl, "_init", IL._init);
- IF CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN
- getproc(rtl, "_error", IL._error);
- getproc(rtl, "_divmod", IL._divmod);
- getproc(rtl, "_exit", IL._exit);
- getproc(rtl, "_dispose", IL._dispose);
- getproc(rtl, "_isrec", IL._isrec);
- getproc(rtl, "_dllentry", IL._dllentry);
- getproc(rtl, "_sofinit", IL._sofinit)
- ELSIF CPU IN {TARGETS.cpuTHUMB, TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
- getproc(rtl, "_fmul", IL._fmul);
- getproc(rtl, "_fdiv", IL._fdiv);
- getproc(rtl, "_fdivi", IL._fdivi);
- getproc(rtl, "_fadd", IL._fadd);
- getproc(rtl, "_fsub", IL._fsub);
- getproc(rtl, "_fsubi", IL._fsubi);
- getproc(rtl, "_fcmp", IL._fcmp);
- getproc(rtl, "_floor", IL._floor);
- getproc(rtl, "_flt", IL._flt);
- getproc(rtl, "_pack", IL._pack);
- getproc(rtl, "_unpk", IL._unpk);
- IF CPU IN {TARGETS.cpuRVM32I, TARGETS.cpuRVM64I} THEN
- getproc(rtl, "_error", IL._error)
- END
- END
- END setrtl;
- PROCEDURE compile* (path, lib_path, modname, outname: PARS.PATH; target: INTEGER; options: PROG.OPTIONS);
- VAR
- parser: PARS.PARSER;
- ext: PARS.PATH;
- BEGIN
- tINTEGER := PROG.program.stTypes.tINTEGER;
- tBYTE := PROG.program.stTypes.tBYTE;
- tCHAR := PROG.program.stTypes.tCHAR;
- tSET := PROG.program.stTypes.tSET;
- tBOOLEAN := PROG.program.stTypes.tBOOLEAN;
- tWCHAR := PROG.program.stTypes.tWCHAR;
- tREAL := PROG.program.stTypes.tREAL;
- Options := options;
- CPU := TARGETS.CPU;
- ext := UTILS.FILE_EXT;
- CaseLabels := C.create();
- CaseVar := C.create();
- CaseVariants := LISTS.create(NIL);
- LISTS.push(CaseVariants, NewVariant(0, NIL));
- IL.init(CPU);
- IF TARGETS.RTL THEN
- parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
- IF parser.open(parser, UTILS.RTL_NAME, UTILS.FILE_EXT) THEN
- parser.parse(parser);
- PARS.destroy(parser)
- ELSE
- PARS.destroy(parser);
- parser := PARS.create(lib_path, lib_path, StatSeq, expression, designator, chkreturn);
- IF parser.open(parser, UTILS.RTL_NAME, UTILS.FILE_EXT) THEN
- parser.parse(parser);
- PARS.destroy(parser)
- ELSE
- ERRORS.FileNotFound(lib_path, UTILS.RTL_NAME, UTILS.FILE_EXT)
- END
- END
- END;
- parser := PARS.create(path, lib_path, StatSeq, expression, designator, chkreturn);
- parser.main := TRUE;
- IF parser.open(parser, modname, UTILS.FILE_EXT) THEN
- parser.parse(parser)
- ELSE
- ERRORS.FileNotFound(path, modname, UTILS.FILE_EXT)
- END;
- PARS.destroy(parser);
- IF PROG.program.bss > UTILS.MAX_GLOBAL_SIZE THEN
- ERRORS.Error(204)
- END;
- IF TARGETS.RTL THEN
- setrtl
- END;
- PROG.DelUnused(IL.DelImport);
- IL.set_bss(PROG.program.bss);
- CASE CPU OF
- |TARGETS.cpuAMD64: AMD64.CodeGen(outname, target, options)
- |TARGETS.cpuX86: X86.CodeGen(outname, target, options)
- |TARGETS.cpuMSP430: MSP430.CodeGen(outname, target, options)
- |TARGETS.cpuTHUMB: THUMB.CodeGen(outname, target, options)
- |TARGETS.cpuRVM32I,
- TARGETS.cpuRVM64I: RVMxI.CodeGen(outname, target, options)
- END
- END compile;
- END STATEMENTS.
|