gentran.red 159 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966
  1. module gentran; % Header module for gentran package.
  2. % Author: Barbara L. Gates.
  3. % Modifications by: Michael C. Dewar.
  4. create!-package('(gentran utils intrfc templt pre gparser redlsp segmnt
  5. lspfor lsprat lspc lsppasc goutput),
  6. '(contrib gentran));
  7. symbolic smacro procedure smallfloatp u;
  8. % Returns true if <structure> is a small rounded.
  9. atom u;
  10. endmodule;
  11. module util; %% GENTRAN Utility Functions %%
  12. %% Author: Barbara L. Gates %%
  13. %% December 1986 %%
  14. % Entry Points: ALL FUNCTIONS
  15. symbolic$
  16. % User-Accessible Primitive Function %
  17. operator genstmtnum$
  18. % User-Accessible Global Variables %
  19. global '(genstmtincr!* genstmtnum!* tablen!*)$
  20. share genstmtincr!*, genstmtnum!*, tablen!*$
  21. genstmtincr!* := 1$
  22. genstmtnum!* := 25000$
  23. tablen!* := 4$
  24. % GENTRAN Global Variables %
  25. global '(!*lisparithexpops!* !*lispdefops!* !*lisplogexpops!*
  26. !*lispstmtgpops!* !*lispstmtops!* !*symboltable!*)$
  27. !*lisparithexpops!* := '(expt minus plus quotient times)$
  28. %LISP arithmetic expression operators
  29. !*lispdefops!* := '(defun)$ %LISP function definition operator
  30. !*lisplogexpops!* := '(and equal geq greaterp leq lessp neq not or)$
  31. %LISP logical & relational exp operators
  32. !*lispstmtgpops!* := '(prog progn)$ %LISP statement group operators
  33. !*lispstmtops!* := '(break cond end for go read repeat
  34. return setq stop while write)$
  35. %LISP statement operators
  36. !*symboltable!* := '(!*main!*)$ %symbol table
  37. global '(!*for!*)$
  38. %% %%
  39. %% Statement Number Generation Function %%
  40. %% %%
  41. procedure genstmtnum;
  42. genstmtnum!* := genstmtnum!* + genstmtincr!*$
  43. %% %%
  44. %% Symbol Table Insertion, Retrieval & Deletion Functions %%
  45. %% %%
  46. procedure symtabput(name, type, value);
  47. % %
  48. % CALL INSERTS %
  49. % SymTabPut(subprogname, NIL, NIL ) subprogram name %
  50. % SymTabPut(subprogname, '!*Type!*, subprogtype ) subprogram type %
  51. % SymTabPut(subprogname, '!*Params!*, paramlist ) parameter list %
  52. % SymTabPut(subprogname, vname, '(type d1 d2 ...)) type & dimensions %
  53. % for variable, %
  54. % variable range, %
  55. % if subprogname=NIL parameter, or %
  56. % then subprogname <-- Car symboltable function name %
  57. % %
  58. <<
  59. name := name or car !*symboltable!*;
  60. !*symboltable!* := name . delete(name, !*symboltable!*);
  61. if type memq '(!*type!* !*params!*) then
  62. put(name, type, value)
  63. else if type then
  64. begin
  65. scalar v, vtype, vdims, dec, decs;
  66. v := type;
  67. vtype := car value;
  68. vdims := cdr value;
  69. decs := get(name, '!*decs!*);
  70. dec := assoc(v, decs);
  71. decs := delete(dec, decs);
  72. vtype := vtype or (if length dec > 1 then cadr dec);
  73. vdims := vdims or (if length dec > 2 then cddr dec);
  74. dec := v . vtype . vdims;
  75. put(name, '!*decs!*, append(decs, list dec))
  76. end
  77. >>$
  78. procedure symtabget(name, type);
  79. % %
  80. % CALL RETRIEVES %
  81. % SymTabGet(NIL, NIL ) all subprogram names %
  82. % SymTabGet(subprogname, '!*Type!* ) subprogram type %
  83. % SymTabGet(subprogname, '!*Params!*) parameter list %
  84. % SymTabGet(subprogname, vname ) type & dimensions for variable, %
  85. % variable range, parameter, or %
  86. % function name %
  87. % SymTabGet(subprogname, '!*Decs!* ) all types & dimensions %
  88. % %
  89. % if subprogname=NIL & 2nd arg is non-NIL %
  90. % then subprogname <-- Car symboltable %
  91. % %
  92. <<
  93. if type then name := name or car !*symboltable!*;
  94. if null name then
  95. !*symboltable!*
  96. else if type memq '(!*type!* !*params!* !*decs!*) then
  97. get(name, type)
  98. else
  99. assoc(type, get(name, '!*decs!*))
  100. >>$
  101. symbolic procedure declared!-as!-float u;
  102. begin scalar decs;
  103. return (decs := symtabget(nil,u)) and
  104. memq(cadr decs,
  105. '(real real!*8 real!*16
  106. double! precision double float) )$
  107. end$
  108. procedure symtabrem(name, type);
  109. % %
  110. % CALL DELETES %
  111. % SymTabRem(subprogname, NIL ) subprogram name %
  112. % SymTabRem(subprogname, '!*Type!* ) subprogram type %
  113. % SymTabRem(subprogname, '!*Params!*) parameter list %
  114. % SymTabRem(subprogname, vname ) type & dimensions for variable, %
  115. % variable range, parameter, or %
  116. % function name %
  117. % SymTabRem(subprogname, '!*Decs!* ) all types & dimensions %
  118. % %
  119. % if subprogname=NIL %
  120. % then subprogname <-- Car symboltable %
  121. % %
  122. <<
  123. name := name or car !*symboltable!*;
  124. if null type then
  125. !*symboltable!* := delete(name, !*symboltable!*) or '(!*main!*)
  126. else if type memq '(!*type!* !*params!* !*decs!*) then
  127. remprop(name, type)
  128. else
  129. begin
  130. scalar v, dec, decs;
  131. v := type;
  132. decs := get(name, '!*decs!*);
  133. dec := assoc(v, decs);
  134. decs := delete(dec, decs);
  135. put(name, '!*decs!*, decs)
  136. end
  137. >>$
  138. procedure getvartype var;
  139. begin
  140. scalar type;
  141. if pairp var then
  142. var := car var;
  143. type := symtabget(nil, var);
  144. if type and length type >= 2 then
  145. type := cadr type
  146. else
  147. type := nil;
  148. return type
  149. end$
  150. procedure arrayeltp exp;
  151. length symtabget(nil, car exp) > 2$
  152. %% %%
  153. %% Functions for Making LISP Forms %%
  154. %% %%
  155. procedure mkassign(var, exp);
  156. list('setq, var, exp)$
  157. procedure mkcond pairs;
  158. 'cond . pairs$
  159. procedure mkdef(name, params, body);
  160. append(list('defun, name, params), body)$
  161. procedure mkreturn exp;
  162. list('return, exp)$
  163. procedure mkstmtgp(vars, stmts);
  164. if numberp vars then
  165. 'progn . stmts
  166. else
  167. 'prog . vars . stmts$
  168. %% LISP Form Predicates %%
  169. procedure lispassignp stmt;
  170. eqcar(stmt,'setq)$
  171. procedure lispbreakp form;
  172. eqcar(form, 'break)$
  173. procedure lispcallp form;
  174. pairp form$
  175. procedure lispcondp stmt;
  176. eqcar(stmt, 'cond)$
  177. procedure lispdefp form;
  178. pairp form and car form memq !*lispdefops!*$
  179. procedure lispexpp form;
  180. atom form or
  181. car form memq !*lisparithexpops!* or
  182. car form memq !*lisplogexpops!* or
  183. not (car form memq !*lispstmtops!*) and
  184. not (car form memq !*lispstmtgpops!*) and
  185. not (car form memq !*lispdefops!*)$
  186. procedure lispendp form;
  187. eqcar( form, 'end)$
  188. procedure lispforp form;
  189. eqcar( form, !*for!*)$
  190. procedure lispgop form;
  191. eqcar( form, 'go)$
  192. procedure lisplabelp form;
  193. atom form$
  194. procedure lispprintp form;
  195. eqcar( form, 'write)$
  196. procedure lispreadp form;
  197. eqcar( form, 'read)$
  198. procedure lisprepeatp form;
  199. eqcar(form, 'repeat)$
  200. procedure lispreturnp stmt;
  201. eqcar( stmt, 'return)$
  202. procedure lispstmtp form;
  203. atom form or
  204. car form memq !*lispstmtops!* or
  205. ( atom car form and
  206. not (car form memq !*lisparithexpops!* or
  207. car form memq !*lisplogexpops!* or
  208. car form memq !*lispstmtgpops!* or
  209. car form memq !*lispdefops!*) )$
  210. procedure lispstmtgpp form;
  211. pairp form and car form memq !*lispstmtgpops!*$
  212. procedure lispstopp form;
  213. eqcar(form, 'stop)$
  214. procedure lispwhilep form;
  215. eqcar(form, 'while)$
  216. %% %%
  217. %% Type Predicates & Type List Forming Functions %%
  218. %% %%
  219. procedure formtypelists varlists;
  220. % ( (var TYPE d1 d2...) ( (TYPE (var d1 d2...) ...) %
  221. % : ==> : %
  222. % (var TYPE d1 d2...) ) (TYPE (var d1 d2...) ...) ) %
  223. begin
  224. scalar type, typelists, tl;
  225. for each vl in varlists do
  226. <<
  227. type := cadr vl;
  228. if onep length(vl := delete(type, vl)) then
  229. vl := car vl;
  230. if (tl := assoc(type, typelists)) then
  231. typelists := delete(tl, typelists)
  232. else
  233. tl := list type;
  234. typelists := append(typelists, list append(tl, list vl))
  235. >>;
  236. return typelists
  237. end$
  238. procedure functionformp(stmt, name);
  239. % Does stmt contain an assignment which assigns a value to name? %
  240. % Does it contain a RETURN exp; stmt? %
  241. % (i.e., (SETQ name exp) -or- (RETURN exp) %
  242. if null stmt or atom stmt then
  243. nil
  244. else if car stmt eq 'setq and cadr stmt eq name then
  245. t
  246. else if car stmt eq 'return and cdr stmt then
  247. t
  248. else
  249. lispeval('or . for each st in stmt collect functionformp(st, name))$
  250. procedure implicitp type;
  251. begin
  252. scalar xtype, ximp, r;
  253. xtype := explode2 type;
  254. ximp := explode2 'implicit;
  255. r := t;
  256. repeat
  257. r := r and (car xtype eq car ximp)
  258. until null(xtype := cdr xtype) or null(ximp := cdr ximp);
  259. return r
  260. end$
  261. %% %%
  262. %% Misc. Functions %%
  263. %% %%
  264. procedure insertcommas lst;
  265. begin
  266. scalar result;
  267. if null lst then
  268. return nil;
  269. result := list car lst;
  270. while lst := cdr lst do
  271. result := car lst . '!, . result;
  272. return reverse result
  273. end$
  274. procedure insertparens exp;
  275. '!( . append(exp, list '!))$
  276. procedure optype op;
  277. get(op, '!*optype!*)$
  278. put('minus, '!*optype!*, 'unary )$
  279. put('not, '!*optype!*, 'unary )$
  280. put('quotient, '!*optype!*, 'binary)$
  281. put('expt, '!*optype!*, 'binary)$
  282. put('equal, '!*optype!*, 'binary)$
  283. put('neq, '!*optype!*, 'binary)$
  284. put('greaterp, '!*optype!*, 'binary)$
  285. put('geq, '!*optype!*, 'binary)$
  286. put('lessp, '!*optype!*, 'binary)$
  287. put('leq, '!*optype!*, 'binary)$
  288. put('plus, '!*optype!*, 'nary )$
  289. put('times, '!*optype!*, 'nary )$
  290. put('and, '!*optype!*, 'nary )$
  291. put('or, '!*optype!*, 'nary )$
  292. procedure seqtogp lst;
  293. if null lst or atom lst or lispstmtp lst or lispstmtgpp lst then
  294. lst
  295. else if onep length lst and pairp car lst then
  296. seqtogp car lst
  297. else
  298. mkstmtgp(nil, for each st in lst collect seqtogp st)$
  299. procedure stringtoatom a;
  300. intern compress
  301. foreach c in append('!" . explode2 a, list '!")
  302. conc list('!!, c)$
  303. procedure stripquotes a;
  304. if atom a then
  305. intern compress
  306. for each c in explode2 a conc list('!!, c)
  307. else if car a eq 'quote then
  308. stripquotes cadr a
  309. else
  310. a$
  311. symbolic procedure flushspaces c;
  312. << while seprp c do
  313. <<
  314. if c eq !$eol!$
  315. then pterpri()
  316. else pprin2 c;
  317. c := readch()
  318. >>;
  319. c
  320. >>;
  321. symbolic procedure flushspacescommas c;
  322. << while seprp c or c eq '!, do
  323. <<
  324. if c eq !$eol!$
  325. then pterpri()
  326. else pprin2 c;
  327. c := readch()
  328. >>;
  329. c
  330. >>;
  331. endmodule;
  332. module intrfc; %% GENTRAN Parsing Routines & Control Functions %%
  333. %% Author: Barbara L. Gates %%
  334. %% December 1986 %%
  335. % Entry Points:
  336. % DeclareStat, GENDECS, GenInStat (GentranIn), GenOutStat
  337. % (GentranOutPush), GenPopStat (GentranPop), GenPushStat, GenShutStat
  338. % (GentranShut), GenStat (Gentran), (GENTRANPAIRS),
  339. % LiteralStat, SYM!-GENTRAN, SYM!-GENTRANIN, SYM!-GENTRANOUT,
  340. % SYM!-GENTRANSHUT,
  341. % SYM!-GENTRANPUSH, SYM!-GENTRANPOP
  342. fluid '(!*getdecs);
  343. % GENTRAN Commands %
  344. put('gentran, 'stat, 'genstat )$
  345. put('gentranin, 'stat, 'geninstat )$
  346. put('gentranout, 'stat, 'genoutstat )$
  347. put('gentranshut, 'stat, 'genshutstat)$
  348. put('gentranpush, 'stat, 'genpushstat)$
  349. put('gentranpop, 'stat, 'genpopstat )$
  350. % Form Analysis Function %
  351. put('gentran, 'formfn, 'formgentran)$
  352. put('gentranin, 'formfn, 'formgentran)$
  353. put('gentranoutpush, 'formfn, 'formgentran)$
  354. put('gentranshut, 'formfn, 'formgentran)$
  355. put('gentranpop, 'formfn, 'formgentran)$
  356. % GENTRAN Functions %
  357. put('declare, 'stat, 'declarestat)$
  358. put('literal, 'stat, 'literalstat)$
  359. % GENTRAN Operators %
  360. newtok '((!: !: !=) lsetq )$ infix ::= $
  361. newtok '((!: != !:) rsetq )$ infix :=: $
  362. newtok '((!: !: != !:) lrsetq)$ infix ::=:$
  363. % User-Accessible Primitive Function %
  364. operator gendecs$
  365. % GENTRAN Mode Switches %
  366. fluid '(!*gendecs)$
  367. !*gendecs := t$
  368. put('gendecs, 'simpfg, '((nil) (t (gendecs nil))))$
  369. switch gendecs$
  370. %See procedure gendecs:
  371. fluid '(!*keepdecs)$
  372. !*keepdecs := nil$
  373. switch keepdecs$
  374. % GENTRAN Flags %
  375. fluid '(!*gentranopt !*gentranseg !*period);
  376. !*gentranseg := t$
  377. switch gentranseg$
  378. % User-Accessible Global Variable %
  379. global '(gentranlang!*)$
  380. share gentranlang!*$
  381. gentranlang!* := 'fortran$
  382. % GENTRAN Global Variable %
  383. global '(!*term!* !*stdin!* !*stdout!* !*instk!* !*currin!* !*outstk!*
  384. !*currout!* !*outchanl!*)$
  385. !*term!* := (t . nil)$ %terminal filepair
  386. !*stdin!* := !*term!*$ %standard input filepair
  387. !*stdout!* := !*term!*$ %standard output filepair
  388. !*instk!* := list !*stdin!*$ %template file stack
  389. !*currin!* := car !*instk!*$ %current input filepair
  390. !*outstk!* := list !*stdout!*$ %output file stack
  391. !*currout!* := car !*outstk!*$ %current output filepair
  392. !*outchanl!* := list cdr !*currout!*$ %current output channel list
  393. global '(!*do!* !*for!*)$
  394. off quotenewnam$
  395. !*do!* := 'do$
  396. !*for!* := 'for$
  397. on quotenewnam$
  398. % REDUCE Variables %
  399. global '(cursym!* !*vars!*)$
  400. fluid '(!*mode)$
  401. %% %%
  402. %% PARSING ROUTINES %%
  403. %% %%
  404. %% GENTRAN Command Parsers %%
  405. procedure genstat;
  406. % %
  407. % GENTRAN %
  408. % stmt %
  409. % [OUT f1,f2,...,fn]; %
  410. % %
  411. begin
  412. scalar stmt;
  413. flag('(out), 'delim);
  414. stmt := xread t;
  415. remflag('(out), 'delim);
  416. if cursym!* eq 'out then
  417. return list('gentran, stmt, readfargs())
  418. else if endofstmtp() then
  419. return list('gentran, stmt, nil)
  420. else
  421. gentranerr('e, nil, "INVALID SYNTAX", nil)
  422. end$
  423. procedure geninstat;
  424. % %
  425. % GENTRANIN %
  426. % f1,f2,...,fm %
  427. % [OUT f1,f2,...,fn]; %
  428. % %
  429. begin
  430. scalar f1, f2;
  431. flag('(out), 'delim);
  432. f1 := xread nil;
  433. if atom f1 then f1 := list f1 else f1 := cdr f1;
  434. remflag('(out), 'delim);
  435. if cursym!* eq 'out then
  436. f2 := readfargs();
  437. return list('gentranin, f1, f2)
  438. end$
  439. procedure genoutstat;
  440. % %
  441. % GENTRANOUT f1,f2,...,fn; %
  442. % %
  443. list('gentranoutpush, readfargs())$
  444. procedure genshutstat;
  445. % %
  446. % GENTRANSHUT f1,f2,...,fn; %
  447. % %
  448. list('gentranshut, readfargs())$
  449. procedure genpushstat;
  450. % %
  451. % GENTRANPUSH f1,f2,...,fn; %
  452. % %
  453. list('gentranoutpush, readfargs())$
  454. procedure genpopstat;
  455. % %
  456. % GENTRANPOP f1,f2,...,fn; %
  457. % %
  458. list('gentranpop, readfargs())$
  459. %% GENTRAN Function Parsers %%
  460. newtok '((!: !:) range);
  461. % Used for declarations with lower and upper bounds;
  462. procedure declarestat;
  463. % %
  464. % DECLARE v1,v2,...,vn : type; %
  465. % %
  466. % DECLARE %
  467. % << %
  468. % v1,v2,...,vn1 : type1; %
  469. % v1,v2,...,vn2 : type2; %
  470. % . %
  471. % . %
  472. % v1,v2,...,vnn : typen %
  473. % >>; %
  474. % %
  475. begin
  476. scalar res, varlst, type;
  477. scan();
  478. put('range,'infix,4);
  479. put('range,'op,'((4 4)));
  480. if cursym!* eq '!*lsqbkt!* then
  481. <<
  482. scan();
  483. while cursym!* neq '!*rsqbkt!* do
  484. <<
  485. varlst := list xread1 'for;
  486. while cursym!* neq '!*colon!* do
  487. varlst := append(varlst, list xread 'for);
  488. type := declarestat1();
  489. res := append(res, list(type . varlst));
  490. if cursym!* eq '!*semicol!* then scan()
  491. >>;
  492. scan()
  493. >>
  494. else
  495. <<
  496. varlst := list xread1 'for;
  497. while cursym!* neq '!*colon!* do
  498. varlst := append(varlst, list xread 'for);
  499. type := declarestat1();
  500. res := list (type . varlst);
  501. >>;
  502. if not endofstmtp() then
  503. gentranerr('e, nil, "INVALID SYNTAX", nil);
  504. remprop('range,'infix);
  505. remprop('range,'op);
  506. return ('declare . res)
  507. end$
  508. procedure declarestat1;
  509. begin
  510. scalar res;
  511. scan();
  512. if endofstmtp() then
  513. return nil;
  514. if cursym!* eq 'implicit then
  515. <<
  516. scan();
  517. res := intern compress append(explode 'implicit! , explode cursym!*)
  518. >>
  519. else
  520. res := cursym!*;
  521. scan();
  522. if cursym!* eq 'times then
  523. <<
  524. scan();
  525. if numberp cursym!* then
  526. <<
  527. res := intern compress append(append(explode res, explode '!*),
  528. explode cursym!*);
  529. scan()
  530. >>
  531. else
  532. gentranerr('e, nil, "INVALID SYNTAX", nil)
  533. >>;
  534. return res
  535. end$
  536. procedure literalstat;
  537. % %
  538. % LITERAL arg1,arg2,...,argn; %
  539. % %
  540. begin
  541. scalar res;
  542. repeat
  543. res := append(res, list xread t)
  544. until endofstmtp();
  545. if atom res then
  546. return list('literal, res)
  547. else if car res eq '!*comma!* then
  548. return rplaca(res, 'literal)
  549. else
  550. return('literal . res)
  551. end$
  552. %% %%
  553. %% Symbolic Mode Functions %%
  554. %% %%
  555. procedure sym!-gentran form;
  556. lispeval formgentran(list('gentran, form, nil), !*vars!*, !*mode)$
  557. procedure sym!-gentranin flist;
  558. lispeval formgentran(list('gentranin,
  559. if atom flist then list flist else flist,
  560. nil),
  561. !*vars!*, !*mode)$
  562. procedure sym!-gentranout flist;
  563. lispeval formgentran(list('gentranoutpush,
  564. if atom flist then list flist else flist),
  565. !*vars!*, !*mode)$
  566. procedure sym!-gentranshut flist;
  567. lispeval formgentran(list('gentranshut,
  568. if atom flist then list flist else flist),
  569. !*vars!*, !*mode)$
  570. procedure sym!-gentranpush flist;
  571. lispeval formgentran(list('gentranoutpush,
  572. if atom flist then list flist else flist),
  573. !*vars!*, !*mode)$
  574. procedure sym!-gentranpop flist;
  575. lispeval formgentran(list('gentranpop,
  576. if atom flist then list flist else flist),
  577. !*vars!*, !*mode)$
  578. %% %%
  579. %% Form Analysis Functions %%
  580. %% %%
  581. procedure formgentran(u, vars, mode);
  582. (car u) . foreach arg in cdr u collect formgentran1(arg, vars, mode)$
  583. symbolic procedure formgentran1(u, vars, mode);
  584. if pairp u and car u eq '!:dn!: then
  585. mkquote <<precmsg length explode abs car(u := cdr u); '!:rd!: . u>>
  586. else if pairp u and car u eq '!:rd!: then mkquote u
  587. else if pairp u and not listp u then
  588. if !*getdecs
  589. then formgentran1(list ('declare,list(cdr u,car u)),vars,mode)
  590. % Amended mcd 13/11/87 to allow local definitions.
  591. else gentranerr('e,u,
  592. "Scalar definitions cannot be translated",nil)
  593. else if atom u then
  594. mkquote u
  595. else if car u eq 'eval then
  596. if mode eq 'algebraic then
  597. list('aeval, form1(cadr u, vars, mode))
  598. else
  599. form1(cadr u, vars, mode)
  600. else if car u memq '(lsetq rsetq lrsetq) then
  601. % (LSETQ (var s1 s2 ... sn) exp) %
  602. % -> (SETQ (var (EVAL s1) (EVAL s2) ... (EVAL sn)) exp) %
  603. % (RSETQ var exp) %
  604. % -> (SETQ var (EVAL exp)) %
  605. % (LRSETQ (var s1 s2 ... sn) exp) %
  606. % -> (SETQ (var (EVAL s1) (EVAL s2) ... (EVAL sn)) (EVAL exp)) %
  607. begin
  608. scalar op, lhs, rhs;
  609. op := car u;
  610. lhs := cadr u;
  611. rhs := caddr u;
  612. if op memq '(lsetq lrsetq) and listp lhs then
  613. lhs := car lhs . foreach s in cdr lhs collect list('eval, s);
  614. if op memq '(rsetq lrsetq) then
  615. rhs := list('eval, rhs);
  616. return formgentran1(list('setq, lhs, rhs), vars, mode)
  617. end
  618. else
  619. 'list . foreach elt in u
  620. collect formgentran1(elt, vars, mode)$
  621. %% %%
  622. %% Control Functions %%
  623. %% %%
  624. %% Command Control Functions %%
  625. symbolic procedure gentran(forms, flist);
  626. begin
  627. if flist then
  628. lispeval list('gentranoutpush, list('quote, flist));
  629. forms := preproc list forms;
  630. gentranparse forms;
  631. forms := lispcode forms;
  632. if !*gentranopt then forms := opt forms;
  633. if !*gentranseg then forms := seg forms;
  634. apply1(get(gentranlang!*,'formatter) or get('fortran,'formatter),
  635. apply1(get(gentranlang!*,'codegen) or get('fortran,'codegen),
  636. forms));
  637. %if gentranlang!* eq 'ratfor then
  638. % formatrat ratcode forms
  639. %else if gentranlang!* eq 'c then
  640. % formatc ccode forms
  641. %else
  642. % formatfort fortcode forms;
  643. if flist then
  644. <<
  645. flist := car !*currout!* or ('list . cdr !*currout!*);
  646. lispeval '(gentranpop '(nil));
  647. return flist
  648. >>
  649. else
  650. return car !*currout!* or ('list . cdr !*currout!*)
  651. end$
  652. procedure gentranin(inlist, outlist);
  653. begin
  654. scalar ich;
  655. foreach f in inlist do
  656. if pairp f then
  657. gentranerr('e, f, "Wrong Type of Arg", nil)
  658. else if not !*filep!* f and f neq car !*stdin!* then
  659. gentranerr('e, f, "Nonexistent Input File", nil);
  660. if outlist then
  661. lispeval list('gentranoutpush, mkquote outlist);
  662. ich := rds nil;
  663. foreach f in inlist do
  664. <<
  665. if f = car !*stdin!* then
  666. pushinputstack !*stdin!*
  667. else if retrieveinputfilepair f then
  668. gentranerr('e, f, "Template File Already Open for Input", nil)
  669. else
  670. pushinputstack makeinputfilepair f;
  671. rds cdr !*currin!*;
  672. lispapply(get(gentranlang!*,'proctem) or get('fortran,'proctem),
  673. nil);
  674. % if gentranlang!* eq 'ratfor then
  675. % procrattem()
  676. % else if gentranlang!* eq 'c then
  677. % procctem()
  678. % else
  679. % procforttem();
  680. rds ich;
  681. popinputstack()
  682. >>;
  683. if outlist then
  684. <<
  685. outlist := car !*currout!* or ('list . cdr !*currout!*);
  686. lispeval '(gentranpop '(nil));
  687. return outlist
  688. >>
  689. else
  690. return car !*currout!* or ('list . cdr !*currout!*)
  691. end$
  692. procedure gentranoutpush flist;
  693. <<
  694. if onep length (flist := fargstonames(flist, t)) then
  695. flist := car flist;
  696. pushoutputstack (retrieveoutputfilepair flist
  697. or makeoutputfilepair flist);
  698. car !*currout!* or ('list . cdr !*currout!*)
  699. >>$
  700. procedure gentranshut flist;
  701. % close, delete, [output to T] %
  702. begin
  703. scalar trm;
  704. flist := fargstonames(flist, nil);
  705. trm := if onep length flist then (car flist = car !*currout!*)
  706. else if car !*currout!*
  707. then (if car !*currout!* member flist then t)
  708. else lispeval('and . foreach f in cdr !*currout!*
  709. collect (if f member flist then t));
  710. deletefromoutputstack flist;
  711. if trm and !*currout!* neq !*stdout!* then
  712. pushoutputstack !*stdout!*;
  713. return car !*currout!* or ('list . cdr !*currout!*)
  714. end$
  715. procedure gentranpop flist;
  716. <<
  717. if 'all!* member flist then
  718. while !*outstk!* neq list !*stdout!* do
  719. lispeval '(gentranpop '(nil))
  720. else
  721. <<
  722. flist := fargstonames(flist,nil);
  723. if onep length flist then
  724. flist := car flist;
  725. popoutputstack flist
  726. >>;
  727. car !*currout!* or ('list . cdr !*currout!*)
  728. >>$
  729. %% Mode Switch Control Function %%
  730. procedure gendecs name;
  731. % Hacked 15/11/88 to make it actually tidy up symbol table properly.
  732. % KEEPDECS also added. mcd.
  733. %%%%%%%%%%%%%%%%%%%%%%%%
  734. % %
  735. % ON/OFF GENDECS; %
  736. % %
  737. % GENDECS subprogname; %
  738. % %
  739. %%%%%%%%%%%%%%%%%%%%%%%%
  740. <<
  741. if name equal 0 then name := nil;
  742. apply1(get(gentranlang!*,'formatter) or get('fortran,'formatter),
  743. apply1(get(gentranlang!*,'gendecs) or get('fortran,'gendecs),
  744. symtabget(name, '!*decs!*)));
  745. % if gentranlang!* eq 'ratfor then
  746. % formatrat ratdecs symtabget(name, '!*decs!*)
  747. % else if gentranlang!* eq 'c then
  748. % formatc cdecs symtabget(name, '!*decs!*)
  749. % else
  750. % formatfort fortdecs symtabget(name, '!*decs!*);
  751. % Sometimes it would be handy to know just what we've generated.
  752. % If the switch KEEPDECS is on (usually off) this is done.
  753. if null !*keepdecs then
  754. <<
  755. symtabrem(name, '!*decs!*);
  756. symtabrem(name, '!*type!*);
  757. >>;
  758. symtabrem(name, nil);
  759. >>$
  760. %% Misc. Control Functions %%
  761. procedure gentranpairs prs;
  762. % %
  763. % GENTRANPAIRS dottedpairlist; %
  764. % %
  765. begin
  766. scalar formatfn,assignfn;
  767. formatfn:=get(gentranlang!*,'formatter) or get('fortran,'formatter);
  768. assignfn:=get(gentranlang!*,'assigner) or get('fortran,'assigner);
  769. return
  770. for each pr in prs do
  771. apply1(formatfn,apply2(assignfn,lispcodeexp(car pr, !*period),
  772. lispcodeexp(cdr pr, !*period)))
  773. end;
  774. %procedure gentranpairs prs;
  775. %% %
  776. %% GENTRANPAIRS dottedpairlist; %
  777. %% %
  778. %if gentranlang!* eq 'ratfor then
  779. % for each pr in prs do
  780. % formatrat mkfratassign(lispcodeexp(car pr, !*period),
  781. % lispcodeexp(cdr pr, !*period))
  782. %else if gentranlang!* eq 'c then
  783. % for each pr in prs do
  784. % formatc mkfcassign(lispcodeexp(car pr, !*period),
  785. % lispcodeexp(cdr pr, !*period))
  786. %else
  787. % for each pr in prs do
  788. % formatfort mkffortassign(lispcodeexp(car pr, !*period),
  789. % lispcodeexp(cdr pr, !*period))$
  790. %% %%
  791. %% Input & Output File Stack Manipulation Functions %%
  792. %% %%
  793. %% Input Stack Manipulation Functions %%
  794. procedure makeinputfilepair fname;
  795. (fname . open(mkfil fname, 'input))$
  796. procedure retrieveinputfilepair fname;
  797. retrievefilepair(fname, !*instk!*)$
  798. procedure pushinputstack pr;
  799. <<
  800. !*instk!* := pr . !*instk!*;
  801. !*currin!* := car !*instk!*;
  802. !*instk!*
  803. >>$
  804. procedure popinputstack;
  805. begin scalar x;
  806. x := !*currin!*;
  807. if cdr !*currin!* then close cdr !*currin!*;
  808. !*instk!* := cdr !*instk!* or list !*stdin!*;
  809. !*currin!* := car !*instk!*;
  810. return x
  811. end$
  812. %% Output File Stack Manipulation Functions %%
  813. procedure makeoutputfilepair f;
  814. if atom f then
  815. (f . open(mkfil f, 'output))
  816. else
  817. aconc((nil . f) .
  818. foreach fn in f
  819. conc if not retrieveoutputfilepair fn
  820. then list makeoutputfilepair fn,
  821. (nil . nil))$
  822. procedure retrieveoutputfilepair f;
  823. if atom f
  824. then retrievefilepair(f, !*outstk!*)
  825. else retrievepfilepair(f, !*outstk!*)$
  826. procedure pushoutputstack pr;
  827. <<
  828. !*outstk!* := if atom cdr pr
  829. then (pr . !*outstk!*)
  830. else append(pr, !*outstk!*);
  831. !*currout!* := car !*outstk!*;
  832. !*outchanl!* := if car !*currout!*
  833. then list cdr !*currout!*
  834. else foreach f in cdr !*currout!*
  835. collect cdr retrieveoutputfilepair f;
  836. !*outstk!*
  837. >>$
  838. procedure popoutputstack f;
  839. % [close], remove top-most exact occurrence, reset vars %
  840. begin
  841. scalar pr, s;
  842. if atom f then
  843. <<
  844. pr := retrieveoutputfilepair f;
  845. while !*outstk!* and car !*outstk!* neq pr do
  846. if caar !*outstk!* then
  847. <<s := aconc(s, car !*outstk!*); !*outstk!* := cdr !*outstk!*>>
  848. else
  849. <<
  850. while car !*outstk!* neq (nil . nil) do
  851. << s := aconc(s, car !*outstk!*);
  852. !*outstk!* := cdr !*outstk!* >>;
  853. s := aconc(s, car !*outstk!*);
  854. !*outstk!* := cdr !*outstk!*
  855. >>;
  856. if !*outstk!* then s := append(s, cdr !*outstk!*);
  857. !*outstk!* := s;
  858. if not retrieveoutputfilepair f then close cdr pr
  859. >>
  860. else
  861. <<
  862. pr := foreach fn in f collect retrieveoutputfilepair fn;
  863. while !*outstk!* and not filelistequivp(cdar !*outstk!*, f) do
  864. if caar !*outstk!* then
  865. << s := aconc(s, car !*outstk!*);
  866. !*outstk!* := cdr !*outstk!* >>
  867. else
  868. <<
  869. while car !*outstk!* neq (nil . nil) do
  870. << s := aconc(s, car !*outstk!*);
  871. !*outstk!* := cdr !*outstk!* >>;
  872. s := aconc(s, car !*outstk!*);
  873. !*outstk!* := cdr !*outstk!*
  874. >>;
  875. if !*outstk!* then
  876. <<
  877. while car !*outstk!* neq (nil . nil) do
  878. !*outstk!* := cdr !*outstk!*;
  879. s := append(s, cdr !*outstk!*)
  880. >>;
  881. !*outstk!* := s;
  882. foreach fn in f do pr := delete(retrieveoutputfilepair fn, pr);
  883. foreach p in pr do close cdr p
  884. >>;
  885. !*outstk!* := !*outstk!* or list !*stdout!*;
  886. !*currout!* := car !*outstk!*;
  887. !*outchanl!* := if car !*currout!*
  888. then list cdr !*currout!*
  889. else foreach fn in cdr !*currout!*
  890. collect cdr retrieveoutputfilepair fn;
  891. return f
  892. end$
  893. procedure deletefromoutputstack f;
  894. begin
  895. scalar s, pr;
  896. if atom f then
  897. <<
  898. pr := retrieveoutputfilepair f;
  899. while retrieveoutputfilepair f do
  900. !*outstk!* := delete(pr, !*outstk!*);
  901. close cdr pr;
  902. foreach pr in !*outstk!* do
  903. if listp cdr pr and pairp cdr pr and f member cdr pr then
  904. rplacd(pr, delete(f, cdr pr)) % Fixed 26-2-88 mcd
  905. >>
  906. else
  907. <<
  908. foreach fn in f do
  909. deletefromoutputstack fn;
  910. foreach fn in f do
  911. foreach pr in !*outstk!* do
  912. if pairp cdr pr and fn member cdr pr then
  913. rplacd(pr, delete(fn, cdr pr))
  914. >>;
  915. while !*outstk!* do
  916. if caar !*outstk!* and caar !*outstk!* neq 't then
  917. <<
  918. s := aconc(s, car !*outstk!*);
  919. !*outstk!* := cdr !*outstk!*
  920. >>
  921. else if cdar !*outstk!* and cdar !*outstk!* neq '(t) then
  922. <<
  923. while car !*outstk!* neq (nil . nil) do
  924. <<
  925. s := aconc(s, car !*outstk!*);
  926. !*outstk!* := cdr !*outstk!*
  927. >>;
  928. s := aconc(s, car !*outstk!*);
  929. !*outstk!* := cdr !*outstk!*
  930. >>
  931. else
  932. if cdr !*outstk!* then !*outstk!* := cddr !*outstk!*
  933. else !*outstk!*:=nil;
  934. !*outstk!* := s or list !*stdout!*;
  935. !*currout!* := car !*outstk!*;
  936. !*outchanl!* := if car !*currout!*
  937. then list cdr !*currout!*
  938. else foreach fn in cdr !*currout!*
  939. collect cdr retrieveoutputfilepair fn;
  940. return f
  941. end$
  942. procedure retrievefilepair(fname, stk);
  943. if null stk then
  944. nil
  945. else if caar stk and mkfil fname = mkfil caar stk then
  946. car stk
  947. else
  948. retrievefilepair(fname, cdr stk)$
  949. procedure retrievepfilepair(f, stk);
  950. if null stk then
  951. nil
  952. else if null caar stk and filelistequivp(f, cdar stk) then
  953. list(car stk, (nil . nil))
  954. else
  955. retrievepfilepair(f, cdr stk)$
  956. procedure filelistequivp(f1, f2);
  957. if pairp f1 and pairp f2 then
  958. <<
  959. f1 := foreach f in f1 collect mkfil f;
  960. f2 := foreach f in f2 collect mkfil f;
  961. while (car f1 member f2) do
  962. <<
  963. f2 := delete(car f1, f2);
  964. f1 := cdr f1
  965. >>;
  966. null f1 and null f2
  967. >>$
  968. %%
  969. procedure !*filep!* f;
  970. not errorp errorset(list('close,
  971. list('open,list('mkfil,mkquote f),''input)),
  972. nil,nil)$
  973. %% %%
  974. %% Scanning & Arg-Conversion Functions %%
  975. %% %%
  976. procedure endofstmtp;
  977. if cursym!* member '(!*semicol!* !*rsqbkt!* end) then t$
  978. procedure fargstonames(fargs, openp);
  979. begin
  980. scalar names;
  981. fargs :=
  982. for each a in fargs conc
  983. if a memq '(nil 0) then
  984. if car !*currout!* then
  985. list car !*currout!*
  986. else
  987. cdr !*currout!*
  988. else if a eq 't then
  989. list car !*stdout!*
  990. else if a eq 'all!* then
  991. for each fp in !*outstk!* conc
  992. (if car fp and not(fp equal !*stdout!*) then list car fp)
  993. else if atom a then
  994. if openp then
  995. <<
  996. if null getd 'bpsmove and
  997. % That essentially disables the test on IBM SLISP
  998. % where it causes chaos with the PDS management.
  999. !*filep!* a and null assoc(a, !*outstk!*) then
  1000. gentranerr('w, a, "OUTPUT FILE ALREADY EXISTS",
  1001. "CONTINUE?");
  1002. list a
  1003. >>
  1004. else
  1005. if retrieveoutputfilepair a then
  1006. list a
  1007. else
  1008. gentranerr('w, a, "File not Open for Output", nil)
  1009. else
  1010. gentranerr('e, a, "WRONG TYPE OF ARG", nil);
  1011. repeat
  1012. if not (car fargs member names) then
  1013. names := append(names, list car fargs)
  1014. until null (fargs := cdr fargs);
  1015. return names
  1016. end$
  1017. procedure readfargs;
  1018. begin
  1019. scalar f;
  1020. while not endofstmtp() do
  1021. f := append(f, list xread t);
  1022. return f or list nil
  1023. end$
  1024. endmodule;
  1025. module templt; %% GENTRAN Template Processing Routines %%
  1026. %% Author: Barbara L. Gates %%
  1027. %% December 1986 %%
  1028. % Entry Points: ProcCTem, ProcFortTem, ProcRatTem
  1029. % Moved to separate language modules - JHD December 1987
  1030. symbolic$
  1031. % User-Accessible Global Variables %
  1032. global '(gentranlang!* !$!#)$
  1033. fluid '(!*gendecs)$
  1034. share gentranlang!*, !$!#$
  1035. gentranlang!* := 'fortran$
  1036. !$!# := 0$
  1037. switch gendecs$
  1038. global '(!*space!* !*stdout!* !$eof!$ !$eol!$)$
  1039. % GENTRAN Global Variables %
  1040. !*space!* := '! $
  1041. fluid '(!*mode)$
  1042. %% %%
  1043. %% Text Processing Routines %%
  1044. %% %%
  1045. %% %%
  1046. %% Template File Active Part Handler %%
  1047. %% %%
  1048. procedure procactive;
  1049. % active parts: ;BEGIN; ... ;END; %
  1050. % eof markers: ;END; %
  1051. begin
  1052. scalar c, buf, mode, och;
  1053. c := readch();
  1054. if c eq 'e then
  1055. if (c := readch()) eq 'n then
  1056. if (c := readch()) eq 'd then
  1057. if (c := readch()) eq '!; then
  1058. return !$eof!$
  1059. else buf := '!;end
  1060. else buf := '!;en
  1061. else buf := '!;e
  1062. else if c eq 'b then
  1063. if (c := readch()) eq 'e then
  1064. if (c := readch()) eq 'g then
  1065. if (c := readch()) eq 'i then
  1066. if (c := readch()) eq 'n then
  1067. if (c := readch()) eq '!; then
  1068. <<
  1069. mode := !*mode;
  1070. !*mode := 'algebraic;
  1071. och := wrs cdr !*stdout!*;
  1072. begin1();
  1073. wrs och;
  1074. !*mode := mode;
  1075. linelength 150;
  1076. return if (c := readch()) eq !$eol!$
  1077. then readch()
  1078. else c
  1079. >>
  1080. else buf := '!;begin
  1081. else buf := '!;begi
  1082. else buf := '!;beg
  1083. else buf := '!;be
  1084. else buf := '!;b
  1085. else buf := '!;;
  1086. pprin2 buf;
  1087. return c
  1088. end$
  1089. endmodule;
  1090. module pre; %% GENTRAN Preprocessing Module %%
  1091. %% Author: Barbara L. Gates %%
  1092. %% December 1986 %%
  1093. % Entry Point: Preproc
  1094. symbolic$
  1095. procedure preproc exp;
  1096. begin
  1097. scalar r;
  1098. r := preproc1 exp;
  1099. if r then
  1100. return car r
  1101. else
  1102. return r
  1103. end$
  1104. % This switch causes gentran to attempt to automatically generate type
  1105. % declarations, without use of the 'declare' statement. mcd 12/11/87.
  1106. fluid '(!*getdecs)$
  1107. !*getdecs := nil$
  1108. switch getdecs$
  1109. % This global variable is the default type given when 'getdecs' is on:
  1110. global '(deftype!*)$
  1111. share deftype!*$
  1112. deftype!* := 'real$
  1113. symbolic procedure preproc1 exp; % Ammended mcd 12/11/87,13/11/87
  1114. if atom exp then
  1115. list exp
  1116. else if car exp = '!:rd!: then
  1117. if smallfloatp cdr exp then list cdr exp else list exp
  1118. else if car exp = '!:dn!: then
  1119. preproc1 ('!:rd!: . cdr exp)
  1120. else if car exp eq '!*sq and listp cdr exp and pairp cadr exp and
  1121. pairp caadr exp and
  1122. caaadr exp memq '(!:cr!: !:crn!: !:gi!:) then
  1123. list caadr exp
  1124. else if car exp eq '!*sq then
  1125. % (!*SQ dpexp) --> (PREPSQ dpexp) %
  1126. preproc1 prepsq cadr exp
  1127. else if car exp eq 'procedure then
  1128. <<
  1129. % Store subprogram name & parameters in symbol table %
  1130. symtabput(cadr exp, '!*params!*, car cddddr exp);
  1131. % Store subprogram type and parameters types in symbol table
  1132. % if !*getdecs switch is on. Use default type unless
  1133. % procedure is declared as either:
  1134. % INTEGER PROCEDURE ... or REAL PROCEDURE ...
  1135. if !*getdecs then
  1136. if caddr exp memq '(real integer) then
  1137. <<
  1138. symtabput(cadr exp,cadr exp,list caddr exp);
  1139. for each v in car cddddr exp do
  1140. symtabput(cadr exp,v,list caddr exp);
  1141. list nconc(list ('procedure,cadr exp,'nil),
  1142. for each e in cdddr exp conc preproc1 e)
  1143. >>
  1144. else
  1145. <<
  1146. for each v in car cddddr exp do
  1147. symtabput(cadr exp,v,list deftype!*);
  1148. list for each e in exp
  1149. conc preproc1 e
  1150. >>
  1151. else
  1152. list for each e in exp
  1153. conc preproc1 e
  1154. >>
  1155. else if car exp eq 'declare then
  1156. <<
  1157. % Store type declarations in symbol table %
  1158. exp := car preproc1 cdr exp;
  1159. exp := preprocdec exp;
  1160. for each dec in exp do
  1161. for each var in cdr dec do
  1162. if car dec memq '(subroutine function) then
  1163. symtabput(var, '!*type!*, car dec)
  1164. else
  1165. symtabput(nil,
  1166. if atom var then var else car var,
  1167. if atom var then list car dec
  1168. else (car dec . cdr var));
  1169. nil
  1170. >>
  1171. else if car exp eq 'setq and listp caddr exp and
  1172. memq(caaddr exp,'(cond progn) ) then
  1173. migrate!-setqs exp
  1174. else
  1175. <<
  1176. % The next statement stores the index of a for loop in the symbol
  1177. % table, assigning them the type integer,
  1178. % if the switch 'getdecs' is on.
  1179. if !*getdecs and (car exp equal '!~for) then
  1180. symtabput(nil,cadr exp, '(integer));
  1181. list for each e in exp
  1182. conc preproc1 e
  1183. >>$
  1184. symbolic procedure preprocdec arg;
  1185. % (TIMES type int) --> type!*int %
  1186. % (IMPLICIT type) --> IMPLICIT! type %
  1187. % (DIFFERENCE v1 v2) --> v1!-v2 %
  1188. if atom arg then
  1189. arg
  1190. else if car arg eq 'times then
  1191. if equal(length arg,3) and fixp(caddr arg) then
  1192. intern
  1193. compress
  1194. append( append( explode cadr arg, explode '!* ),
  1195. explode caddr arg )
  1196. else
  1197. begin scalar result;
  1198. for i:=1:length(arg) do
  1199. result := append(result,
  1200. if equal(nth(arg,i),'times)
  1201. then '(!*)
  1202. else explode nth(arg,i));
  1203. return intern compress result;
  1204. end
  1205. else if car arg eq 'implicit then
  1206. intern
  1207. compress
  1208. append( explode 'implicit! , explode preprocdec cadr arg )
  1209. else if car arg eq 'difference then
  1210. intern
  1211. compress
  1212. append( append( explode cadr arg, explode '!- ),
  1213. explode caddr arg )
  1214. else
  1215. for each a in arg collect
  1216. preprocdec a$
  1217. symbolic procedure migrate!-setqs exp;
  1218. % Move setq's within a progn or cond so that we can translate things
  1219. % like gentran x := if ... then ...
  1220. list migrate!-setqs1(cadr exp,caddr exp)$
  1221. symbolic procedure migrate!-setqs1(var,exp);
  1222. if atom exp then
  1223. list('setq,var,exp)
  1224. else if eqcar(exp,'cond) then
  1225. ('cond . for each u in cdr exp collect
  1226. list (car u,migrate!-setqs1(var,cadr u)) )
  1227. else if eqcar(exp,'progn) then
  1228. reverse rplaca(exp := reverse exp,migrate!-setqs1(var,car exp))
  1229. else
  1230. list('setq,var,exp)$
  1231. endmodule;
  1232. module gparser; %% GENTRAN Parser Module %%
  1233. %% Author: Barbara L. Gates %%
  1234. %% December 1986 %%
  1235. % Entry Point: GentranParse
  1236. symbolic$
  1237. % GENTRAN Global Variable %
  1238. global '(!*reservedops!*)$
  1239. !*reservedops!* := '(and block cond difference equal expt for geq go
  1240. greaterp leq lessp mat minus neq not or plus
  1241. procedure progn quotient read recip repeat return
  1242. setq times while write)$ %reserved operators
  1243. procedure gentranparse forms;
  1244. for each f in forms do
  1245. if not(gpstmtp f or gpexpp f or gpdefnp f) then
  1246. gentranerr('e, f, "CANNOT BE TRANSLATED", nil)$
  1247. procedure gpexpp exp;
  1248. % exp ::= id | number | (PLUS exp exp') | (MINUS exp) | %
  1249. % (DIFFERENCE exp exp) | (TIMES exp exp exp') | %
  1250. % (RECIP exp) |(QUOTIENT exp exp) | (EXPT exp exp) | (id arg') %
  1251. if atom exp then
  1252. idp exp or numberp exp
  1253. else if car exp memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  1254. t
  1255. else
  1256. if car exp eq 'plus then
  1257. length exp >= 2 and gpexpp cadr exp and gpexp1p cddr exp
  1258. else if car exp memq '(minus recip) then
  1259. length exp=2 and gpexpp cadr exp
  1260. else if car exp memq '(difference quotient expt) then
  1261. length exp=3 and gpexpp cadr exp and gpexpp caddr exp
  1262. else if car exp eq 'times then
  1263. length exp >= 3 and gpexpp cadr exp and gpexpp caddr exp and
  1264. gpexp1p cdddr exp
  1265. else if car exp eq '!:rd!: then t
  1266. else if car exp memq '(!:cr!: !:crn!: !:gi!:) then t
  1267. else if unresidp car exp then
  1268. gparg1p cdr exp$
  1269. procedure gpexp1p exp;
  1270. % exp' ::= exp exp' | eps %
  1271. null exp or (gpexpp car exp and gpexp1p cdr exp)$
  1272. procedure gplogexpp exp;
  1273. % logexp ::= id | (EQUAL exp exp) | (NEQ exp exp) | %
  1274. % (GREATERP exp exp) |(GEQ exp exp) | (LESSP exp exp) | %
  1275. % (LEQ exp exp) | (NOT logexp) | (AND logexp logexp logexp')%
  1276. % | (OR logexp logexp logexp') | (id arg') %
  1277. if atom exp then
  1278. idp exp
  1279. else
  1280. if car exp memq '(equal neq greaterp geq lessp leq) then
  1281. length exp=3 and gpexpp cadr exp and gpexpp caddr exp
  1282. else if car exp eq 'not then
  1283. length exp=2 and gplogexpp cadr exp
  1284. else if car exp memq '(and or) then
  1285. length exp >= 3 and gplogexpp cadr exp and gplogexpp caddr exp
  1286. and gplogexp1p cdddr exp
  1287. else if unresidp car exp then
  1288. gparg1p cdr exp$
  1289. procedure gplogexp1p exp;
  1290. % logexp' ::= logexp logexp' | eps %
  1291. null exp or (gplogexpp car exp and gplogexp1p cdr exp)$
  1292. procedure gpargp exp;
  1293. % arg ::= string | exp | logexp %
  1294. stringp exp or gpexpp exp or gplogexpp exp$
  1295. procedure gparg1p exp;
  1296. % arg' ::= arg arg' | eps %
  1297. null exp or (gpargp car exp and gparg1p cdr exp)$
  1298. procedure gpvarp exp;
  1299. % var ::= id | (id exp exp') %
  1300. if atom exp then
  1301. idp exp
  1302. else
  1303. if unresidp car exp then
  1304. length exp >= 2 and gpexpp cadr exp and gpexp1p cddr exp$
  1305. procedure gplistp exp;
  1306. % list ::= (exp exp') %
  1307. if pairp exp then
  1308. length exp >= 1 and gpexpp car exp and gpexp1p cdr exp$
  1309. procedure gplist1p exp;
  1310. % list' ::= list list' | eps %
  1311. null exp or (gplistp car exp and gplist1p cdr exp)$
  1312. procedure gpid1p exp;
  1313. % id' ::= id id' | eps %
  1314. null exp or (idp car exp and gpid1p cdr exp)$
  1315. procedure gpstmtp exp;
  1316. % stmt ::= id | (SETQ setq') | (COND cond') | (WHILE logexp stmt) | %
  1317. % (REPEAT stmt logexp) | (FOR var (exp exp exp) DO stmt) | %
  1318. % (GO id) | (RETURN arg) | (WRITE arg arg') | %
  1319. % (PROGN stmt stmt') | (BLOCK (id') stmt') | (id arg') %
  1320. if atom exp then
  1321. idp exp
  1322. else if car exp memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  1323. nil
  1324. else
  1325. if car exp eq 'setq then
  1326. gpsetq1p cdr exp
  1327. else if car exp eq 'cond then
  1328. gpcond1p cdr exp
  1329. else if car exp eq 'while then
  1330. length exp=3 and gplogexpp cadr exp and gpstmtp caddr exp
  1331. else if car exp eq 'repeat then
  1332. length exp=3 and gpstmtp cadr exp and gplogexpp caddr exp
  1333. else if car exp eq 'for then
  1334. length exp=5 and gpvarp cadr exp and pairp caddr exp and
  1335. (length caddr exp=3 and gpexpp car caddr exp and
  1336. gpexpp cadr caddr exp and gpexpp caddr caddr exp) and
  1337. cadddr exp eq 'do and gpstmtp car cddddr exp
  1338. else if car exp eq 'go then
  1339. length exp=2 and idp cadr exp
  1340. else if car exp eq 'return then
  1341. length exp=2 and gpargp cadr exp
  1342. else if car exp eq 'write then
  1343. length exp >= 2 and gpargp cadr exp and gparg1p cddr exp
  1344. else if car exp eq 'progn then
  1345. length exp >= 2 and gpstmtp cadr exp and gpstmt1p cddr exp
  1346. else if car exp eq 'block then
  1347. length exp >= 2 and gpid1p cadr exp and gpstmt1p cddr exp
  1348. else if unresidp car exp then
  1349. gparg1p cdr exp$
  1350. procedure gpsetq1p exp;
  1351. % setq' ::= id setq'' | (id exp exp') setq''' %
  1352. if exp and length exp=2 then
  1353. if atom car exp then
  1354. idp car exp and gpsetq2p cdr exp
  1355. else
  1356. (length car exp >= 2 and idp car car exp
  1357. and unresidp car car exp and gpexpp cadr car exp
  1358. and gpexp1p cddr car exp) and gpsetq3p cdr exp$
  1359. procedure gpsetq2p exp;
  1360. % setq'' ::= (MAT list list') | setq''' %
  1361. if exp then
  1362. if eqcar(car exp, 'mat) then
  1363. onep length exp and (gplistp cadar exp and gplist1p cddar exp)
  1364. else
  1365. gpsetq3p exp$
  1366. procedure gpsetq3p exp;
  1367. % setq''' ::= (FOR var (exp exp exp) forop exp) | (READ) | exp | logexp
  1368. if exp and onep length exp then
  1369. gpexpp car exp or
  1370. gplogexpp car exp or
  1371. (if caar exp eq 'for then
  1372. length car exp=5 and gpvarp cadar exp and
  1373. (pairp caddar exp and length caddar exp=3 and
  1374. gpexpp car caddar exp and gpexpp cadr caddar exp and
  1375. gpexpp caddr caddar exp) and gpforopp car cdddar exp and
  1376. gpexpp cadr cdddar exp
  1377. else if caar exp eq 'read then
  1378. onep length car exp)$
  1379. procedure gpforopp exp;
  1380. % forop ::= SUM | PRODUCT %
  1381. exp memq '(sum product)$
  1382. procedure gpcond1p exp;
  1383. % cond' ::= (logexp stmt) cond' | eps %
  1384. null exp or
  1385. (pairp car exp and length car exp=2 and gplogexpp caar exp and
  1386. gpstmtp cadar exp and gpcond1p cdr exp)$
  1387. procedure gpstmt1p exp;
  1388. % stmt' ::= stmt stmt' | eps %
  1389. null exp or (gpstmtp car exp and gpstmt1p cdr exp)$
  1390. procedure gpdefnp exp;
  1391. % defn ::= (PROCEDURE id NIL EXPR (id') stmt) %
  1392. eqcar(exp, 'procedure) and length exp=6 and
  1393. idp cadr exp and null caddr exp and atom cadddr exp and
  1394. gpid1p car cddddr exp and gpstmtp cadr cddddr exp
  1395. and not idp cadr cddddr exp$
  1396. %% %%
  1397. %% Predicates %%
  1398. %% %%
  1399. procedure unresidp id;
  1400. not (id memq !*reservedops!*)$
  1401. endmodule;
  1402. module redlsp; %% GENTRAN LISP Code Generation Module %%
  1403. %% Author: Barbara L. Gates %%
  1404. %% December 1986 %%
  1405. % Entry Point: LispCode
  1406. symbolic$
  1407. % GENTRAN Global Variables %
  1408. global '(!*lisparithexpops!* !*lisplogexpops!* !*redarithexpops!*
  1409. !*redlogexpops!* !*redreswds!* !*redstmtgpops!* !*redstmtops!*)$
  1410. !*redarithexpops!*:= '(difference expt minus plus quotient recip times)$
  1411. !*redlogexpops!* := '(and equal geq greaterp leq lessp neq not or)$
  1412. !*redreswds!* := '(and block cond de difference end equal expt !~for for
  1413. geq getel go greaterp leq lessp list minus neq not or
  1414. plus plus2 prog progn procedure quotient read recip
  1415. repeat return setel setk setq stop times times2
  1416. while write)$ %REDUCE reserved words
  1417. !*redstmtgpops!* := '(block progn)$
  1418. !*redstmtops!* := '(cond end !~for for go repeat return setq stop
  1419. while write)$
  1420. % REDUCE Non-local Variable %
  1421. fluid '(!*period);
  1422. global '(deftype!*)$
  1423. global '(!*do!* !*for!*)$
  1424. % Irena variable referenced here.
  1425. global '(irena!-constants)$
  1426. irena!-constants := nil$
  1427. procedure lispcode forms;
  1428. for each f in forms collect
  1429. if redexpp f then
  1430. lispcodeexp(f, !*period)
  1431. else if redstmtp f or redstmtgpp f then
  1432. lispcodestmt f
  1433. else if reddefp f then
  1434. lispcodedef f
  1435. else if pairp f then
  1436. for each e in f collect lispcode e$
  1437. symbolic procedure lispcodeexp(form, fp);
  1438. % (RECIP exp) ==> (QUOTIENT 1.0 exp) %
  1439. % (DIFFERENCE exp1 exp2) ==> (PLUS exp1 (MINUS exp2)) %
  1440. % integer ==> floating point iff PERIOD flag is ON & %
  1441. % not exponent & %
  1442. % not subscript & %
  1443. % not loop index %
  1444. % The above is a little simplistic. We have problems
  1445. % With expressions like x**(1/2)
  1446. % Now believed fixed. JHD 14.5.88
  1447. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1448. %
  1449. % mcd 16-11-88. Added code to spot certain variables which irena
  1450. % needs to generate values for.
  1451. %
  1452. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1453. begin
  1454. return if numberp form then
  1455. if fp then
  1456. float form
  1457. else
  1458. form
  1459. % Substitute (EXP 1) for e - mcd 29/4/88 %
  1460. else if form eq 'e then
  1461. lispcodeexp(list('exp,1.0),fp)
  1462. else if atom form or car form memq '( !:rd!: !:cr!: !:crn!: !:gi!: )then
  1463. <<
  1464. % Irena specific bit:
  1465. if memq(form,irena!-constants) then
  1466. set(get(form,'!*found!-flag),t);
  1467. form
  1468. >>
  1469. else if car form eq 'expt then
  1470. % Changes (EXPT E X) to (EXP X). mcd 29/4/88 %
  1471. if cadr form eq 'e then
  1472. lispcodeexp(list('exp,caddr form),fp)
  1473. else
  1474. list('expt, lispcodeexp(cadr form, fp),
  1475. lispcodeexp(caddr form, nil))
  1476. else if car form eq 'quotient then % re-instate periods if necessary
  1477. %e.g. in expressions like **(1/2)
  1478. list('quotient, lispcodeexp(cadr form, t),
  1479. lispcodeexp(caddr form, t))
  1480. else if car form eq 'recip then
  1481. if !*period then % test this not FP, for same reason as above
  1482. list('quotient, 1.0, lispcodeexp(cadr form, fp))
  1483. else
  1484. list('quotient, 1, lispcodeexp(cadr form, fp))
  1485. else if car form eq 'difference then
  1486. list('plus, lispcodeexp(cadr form, fp),
  1487. list('minus, lispcodeexp(caddr form, fp)))
  1488. else if not car form memq !*lisparithexpops!* and
  1489. not car form memq !*lisplogexpops!* then
  1490. for each elt in form collect lispcodeexp(elt, nil)
  1491. else
  1492. for each elt in form collect lispcodeexp(elt, fp)$
  1493. end$
  1494. procedure lispcodestmt form;
  1495. if atom form then
  1496. form
  1497. else if redassignp form then
  1498. lispcodeassign form
  1499. else if redreadp form then
  1500. lispcoderead form
  1501. else if redprintp form then
  1502. lispcodeprint form
  1503. else if redwhilep form then
  1504. lispcodewhile form
  1505. else if redrepeatp form then
  1506. lispcoderepeat form
  1507. else if redforp form then
  1508. lispcodefor form
  1509. else if redcondp form then
  1510. lispcodecond form
  1511. else if redreturnp form then
  1512. lispcodereturn form
  1513. else if redstmtgpp form then
  1514. lispcodestmtgp form
  1515. else if reddefp form then
  1516. lispcodedef form
  1517. else if car form eq 'literal then
  1518. for each elt in form collect lispcodeexp(elt, nil)
  1519. else
  1520. for each elt in form collect lispcodeexp(elt, !*period)$
  1521. symbolic procedure lispcodeassign form;
  1522. % Modified mcd 27/11/87 to prevent coercing things already declared as
  1523. % integers to reals when the PERIOD flag is on.
  1524. %
  1525. % (SETQ var (MAT lst lst')) --> (PROGN (SETQ (var 1 1) exp11) %
  1526. % (SETQ (var 1 2) exp12) %
  1527. % . %
  1528. % . %
  1529. % (SETQ (var m n) expmn)) %
  1530. if eqcar( caddr form, 'mat) then
  1531. begin
  1532. scalar name, r, c, relts, result,ftype;
  1533. name := cadr form;
  1534. form := caddr form;
  1535. r := c := 1;
  1536. ftype := symtabget(nil,name);
  1537. if null ftype then ftype := !*period else
  1538. << ftype := cadr ftype;
  1539. ftype := if ftype equal 'integer or
  1540. (ftype equal 'scalar and deftype!* equal 'integer) then nil
  1541. else !*period;
  1542. >>;
  1543. while form := cdr form do
  1544. <<
  1545. relts := car form;
  1546. repeat
  1547. <<
  1548. result := mkassign(list(name, r, c),
  1549. lispcodeexp(car relts, ftype))
  1550. . result;
  1551. c := add1 c
  1552. >>
  1553. until null(relts := cdr relts);
  1554. r := add1 r;
  1555. c := 1
  1556. >>;
  1557. return mkstmtgp(nil, reverse result)
  1558. end
  1559. else begin
  1560. scalar ftype,name;
  1561. name := cadr form;
  1562. if pairp name then name := car name;
  1563. ftype := symtabget(nil,name);
  1564. if null ftype then ftype := !*period else
  1565. << ftype := cadr ftype;
  1566. ftype := if ftype equal 'integer or
  1567. (ftype equal 'scalar and deftype!* equal 'integer) then nil
  1568. else !*period;
  1569. >>;
  1570. if cadr form eq 'e then % To prevent an 'e on the lhs
  1571. % being changed to exp(1) by lispcodeexp
  1572. % mcd 29/4/88
  1573. return mkassign('e,lispcodeexp(caddr form, ftype))
  1574. else
  1575. return mkassign(lispcodeexp(cadr form, ftype),
  1576. lispcodeexp(caddr form, ftype))
  1577. end$
  1578. procedure lispcoderead form;
  1579. % (SETQ var (READ)) --> (READ var) %
  1580. list('read, lispcodeexp(cadr form, nil))$
  1581. procedure lispcodeprint form;
  1582. 'write . for each elt in cdr form collect lispcodeexp(elt, !*period)$
  1583. procedure lispcodewhile form;
  1584. 'while . lispcodeexp(cadr form, !*period) .
  1585. foreach st in cddr form collect lispcodestmt st$
  1586. procedure lispcoderepeat form;
  1587. begin
  1588. scalar body, logexp;
  1589. body := reverse cdr form;
  1590. logexp := car body;
  1591. body := reverse cdr body;
  1592. return 'repeat . append(foreach st in body collect lispcodestmt st,
  1593. list lispcodeexp(logexp, !*period))
  1594. end$
  1595. procedure lispcodefor form;
  1596. % (SETQ var1 (FOR var (exp1 exp2 exp3) SUM exp))
  1597. % --> (PROGN (SETQ var1 0/0.0)
  1598. % (FOR var (exp1 exp2 exp3) DO (SETQ var1 (PLUS var1 exp))))
  1599. % (SETQ var1 (FOR var (exp1 exp2 exp3) PRODUCT exp))
  1600. % --> (PROGN (SETQ var1 1/1.0)
  1601. % (FOR var (exp1 exp2 exp3) DO (SETQ var1 (TIMES var1 exp))))
  1602. if car form eq 'for then
  1603. begin
  1604. scalar explst, stmtlst;
  1605. explst := list(cadr form, caddr form);
  1606. stmtlst := cddddr form;
  1607. return append(!*for!* .
  1608. foreach exp in explst collect lispcodeexp(exp, nil),
  1609. !*do!* .
  1610. foreach st in stmtlst collect lispcodestmt st)
  1611. end
  1612. else
  1613. begin
  1614. scalar var1, var, explst, op, exp;
  1615. var1 := cadr form;
  1616. form := caddr form;
  1617. var := cadr form;
  1618. explst := caddr form;
  1619. if cadddr form eq 'sum then
  1620. op := 'plus
  1621. else
  1622. op := 'times;
  1623. exp := car cddddr form;
  1624. form := list('prog, nil,
  1625. list('setq, var1, if op eq 'plus then 0 else 1),
  1626. list(!*for!*, var, explst, !*do!*,
  1627. list('setq, var1, list(op, var1, exp))));
  1628. return lispcodestmt form
  1629. end$
  1630. procedure lispcodecond form;
  1631. begin
  1632. scalar result, pr;
  1633. while form := cdr form do
  1634. <<
  1635. pr := car form;
  1636. pr := lispcodeexp(car pr, !*period)
  1637. . for each stmt in cdr pr collect lispcodestmt stmt;
  1638. result := pr . result
  1639. >>;
  1640. return mkcond reverse result
  1641. end$
  1642. procedure lispcodereturn form;
  1643. % (RETURN NIL) --> (RETURN) %
  1644. if form member '((return) (return nil)) then
  1645. list 'return
  1646. else
  1647. mkreturn lispcodeexp(cadr form, !*period)$
  1648. procedure lispcodestmtgp form;
  1649. % (BLOCK () stmt1 stmt2 .. stmtm) %
  1650. % --> (PROG () stmt1 stmt2 .. stmtm) %
  1651. if car form memq '(prog block) then
  1652. mkstmtgp(cadr form,
  1653. for each stmt in cddr form collect lispcodestmt stmt)
  1654. else
  1655. mkstmtgp(0, for each stmt in cdr form collect lispcodestmt stmt)$
  1656. procedure lispcodedef form;
  1657. % (PROCEDURE id NIL EXPR (p1 p2 .. pn) stmt') %
  1658. % --> (DEFUN id (p1 p2 .. pn) stmt') %
  1659. if car form eq 'procedure then
  1660. mkdef(cadr form, car cddddr form, for each stmt in cdr cddddr form
  1661. collect lispcodestmt stmt)
  1662. else
  1663. mkdef(cadr form, caddr form, for each stmt in cdddr form
  1664. collect lispcodestmt stmt)$
  1665. %% REDUCE Form Predicates %%
  1666. procedure redassignp form;
  1667. eqcar(form, 'setq) and redassign1p caddr form$
  1668. procedure redassign1p form;
  1669. if atom form then
  1670. t
  1671. else if car form eq 'setq then
  1672. redassign1p caddr form
  1673. else if car form memq '(read for) then
  1674. nil
  1675. else
  1676. t$
  1677. procedure redcondp form;
  1678. eqcar(form, 'cond)$
  1679. procedure reddefp form;
  1680. eqcar(form, 'procedure)$
  1681. procedure redexpp form;
  1682. atom form or
  1683. car form memq !*redarithexpops!* or
  1684. car form memq !*redlogexpops!* or
  1685. not(car form memq !*redreswds!*)$
  1686. procedure redforp form;
  1687. if pairp form then
  1688. if car form eq 'for then
  1689. t
  1690. else if car form eq 'setq then
  1691. redfor1p caddr form$
  1692. procedure redfor1p form;
  1693. if atom form then
  1694. nil
  1695. else if car form eq 'setq then
  1696. redfor1p caddr form
  1697. else if car form eq 'for then
  1698. t$
  1699. procedure redprintp form;
  1700. eqcar(form, 'write)$
  1701. procedure redreadp form;
  1702. eqcar(form, 'setq) and redread1p caddr form$
  1703. procedure redread1p form;
  1704. if atom form then
  1705. nil
  1706. else if car form eq 'setq then
  1707. redread1p caddr form
  1708. else if car form eq 'read then
  1709. t$
  1710. procedure redrepeatp form;
  1711. eqcar(form, 'repeat)$
  1712. procedure redreturnp form;
  1713. eqcar(form, 'return)$
  1714. procedure redstmtp form;
  1715. atom form or
  1716. car form memq !*redstmtops!* or
  1717. atom car form and not(car form memq !*redreswds!*)$
  1718. procedure redstmtgpp form;
  1719. pairp form and car form memq !*redstmtgpops!*$
  1720. procedure redwhilep form;
  1721. eqcar(form, 'while)$
  1722. endmodule;
  1723. module segmnt; %% Segmentation Module %%
  1724. %% Author: Barbara L. Gates %%
  1725. %% December 1986 %%
  1726. % Entry points: Seg, MARKEDVARP, MARKVAR, TEMPVAR, UNMARKVAR
  1727. symbolic$
  1728. % User-Accessible Global Variables %
  1729. global '(gentranlang!* maxexpprintlen!* tempvarname!* tempvarnum!*
  1730. tempvartype!*)$
  1731. share gentranlang!*, maxexpprintlen!*, tempvarname!*, tempvarnum!*,
  1732. tempvartype!*$
  1733. maxexpprintlen!* := 800$
  1734. tempvarname!* := 't$
  1735. tempvarnum!* := 0$
  1736. tempvartype!* := nil$
  1737. % User-Accessible Primitive Functions %
  1738. operator markedvarp, markvar, tempvar, unmarkvar$
  1739. global '(!*do!* !*for!*)$
  1740. %% %%
  1741. %% Segmentation Routines %%
  1742. %% %%
  1743. procedure seg forms;
  1744. % exp --+--> exp %
  1745. % +--> (assign assign ... assign exp ) %
  1746. % (1) (2) (n-1) (n) %
  1747. % stmt --+--> stmt %
  1748. % +--> stmtgp %
  1749. % stmtgp --> stmtgp %
  1750. % def --> def %
  1751. for each f in forms collect
  1752. if lispexpp f then
  1753. if toolongexpp f then
  1754. segexp(f, 'unknown)
  1755. else
  1756. f
  1757. else if lispstmtp f then
  1758. segstmt f
  1759. else if lispstmtgpp f then
  1760. if toolongstmtgpp f then
  1761. seggroup f
  1762. else
  1763. f
  1764. else if lispdefp f then
  1765. if toolongdefp f then
  1766. segdef f
  1767. else
  1768. f
  1769. else
  1770. f$
  1771. procedure segexp(exp, type);
  1772. % exp --> (assign assign ... assign exp ) %
  1773. % (1) (2) (n-1) (n) %
  1774. reverse segexp1(exp, type)$
  1775. procedure segexp1(exp, type);
  1776. % exp --> (exp assign assign ... assign ) %
  1777. % (n) (n-1) (n-2) (1) %
  1778. begin
  1779. scalar res;
  1780. res := segexp2(exp, type);
  1781. unmarkvar res;
  1782. if car res = cadadr res then
  1783. <<
  1784. res := cdr res;
  1785. rplaca(res, caddar res)
  1786. >>;
  1787. return res
  1788. end$
  1789. procedure segexp2(exp, type);
  1790. % exp --> (exp assign assign ... assign ) %
  1791. % (n) (n-1) (n-2) (1) %
  1792. begin
  1793. scalar expn, assigns, newassigns, unops, op, termlist, var, tmp;
  1794. expn := exp;
  1795. while length expn=2 do
  1796. << unops := car expn . unops; expn := cadr expn >>;
  1797. op := car expn;
  1798. for each term in cdr expn do
  1799. <<
  1800. if toolongexpp term then
  1801. <<
  1802. tmp := segexp2(term, type);
  1803. term := car tmp;
  1804. newassigns := cdr tmp
  1805. >>
  1806. else
  1807. newassigns := '();
  1808. if toolongexpp (op . term . termlist) and
  1809. termlist and
  1810. (length termlist > 1 or pairp car termlist) then
  1811. <<
  1812. unmarkvar termlist;
  1813. var := var or tempvar type;
  1814. markvar var;
  1815. assigns := mkassign(var, if onep length termlist
  1816. then car termlist
  1817. else op . termlist) . assigns;
  1818. termlist := list(var, term)
  1819. >>
  1820. else
  1821. termlist := append(termlist, list term);
  1822. assigns := append(newassigns, assigns)
  1823. >>;
  1824. expn := if onep length termlist
  1825. then car termlist
  1826. else op . termlist;
  1827. while unops do
  1828. << expn := list(car unops, expn); unops := cdr unops >>;
  1829. if expn = exp then
  1830. <<
  1831. unmarkvar expn;
  1832. var := var or tempvar type;
  1833. markvar var;
  1834. assigns := list mkassign(var, expn);
  1835. expn := var
  1836. >>;
  1837. return expn . assigns
  1838. end$
  1839. procedure segstmt stmt;
  1840. % assign --+--> assign %
  1841. % +--> stmtgp %
  1842. % cond --+--> cond %
  1843. % +--> stmtgp %
  1844. % while --+--> while %
  1845. % +--> stmtgp %
  1846. % repeat --> repeat %
  1847. % for --+--> for %
  1848. % +--> stmtgp %
  1849. % return --+--> return %
  1850. % +--> stmtgp %
  1851. if lispassignp stmt then
  1852. if toolongassignp stmt then
  1853. segassign stmt
  1854. else
  1855. stmt
  1856. else if lispcondp stmt then
  1857. if toolongcondp stmt then
  1858. segcond stmt
  1859. else
  1860. stmt
  1861. else if lispwhilep stmt then
  1862. if toolongwhilep stmt then
  1863. segwhile stmt
  1864. else
  1865. stmt
  1866. else if lisprepeatp stmt then
  1867. if toolongrepeatp stmt then
  1868. segrepeat stmt
  1869. else
  1870. stmt
  1871. else if lispforp stmt then
  1872. if toolongforp stmt then
  1873. segfor stmt
  1874. else
  1875. stmt
  1876. else if lispreturnp stmt then
  1877. if toolongreturnp stmt then
  1878. segreturn stmt
  1879. else
  1880. stmt
  1881. else
  1882. stmt$
  1883. procedure segassign stmt;
  1884. % assign --> stmtgp %
  1885. begin
  1886. scalar var, exp, type;
  1887. var := cadr stmt;
  1888. type := getvartype var;
  1889. exp := caddr stmt;
  1890. stmt := segexp1(exp, type);
  1891. rplaca(stmt, mkassign(var, car stmt));
  1892. return mkstmtgp(nil, reverse stmt)
  1893. end$
  1894. procedure segcond condd;
  1895. % cond --+--> cond %
  1896. % +--> stmtgp %
  1897. begin
  1898. scalar tassigns, res, markedvars, type;
  1899. %if gentranlang!* eq 'c
  1900. % then type := 'int
  1901. % else type := 'logical;
  1902. type:=get(gentranlang!*,'boolean!-type) or get('fortran,'boolean!-type);
  1903. while condd := cdr condd do
  1904. begin
  1905. scalar exp, stmt;
  1906. if toolongexpp(exp := caar condd) then
  1907. <<
  1908. exp := segexp1(exp, type);
  1909. tassigns := append(cdr exp, tassigns);
  1910. exp := car exp;
  1911. markvar exp;
  1912. markedvars := exp . markedvars
  1913. >>;
  1914. stmt := for each st in cdar condd conc seg list st;
  1915. res := (exp . stmt) . res
  1916. end;
  1917. unmarkvar markedvars;
  1918. return
  1919. if tassigns then
  1920. mkstmtgp(nil, reverse(mkcond reverse res . tassigns))
  1921. else
  1922. mkcond reverse res
  1923. end$
  1924. procedure segwhile stmt;
  1925. % while --+--> while %
  1926. % +--> stmtgp %
  1927. begin
  1928. scalar logexp, stmtlst, tassigns, type, res;
  1929. logexp := cadr stmt;
  1930. stmtlst := cddr stmt;
  1931. if toolongexpp logexp then
  1932. <<
  1933. type:=get(gentranlang!*,'boolean!-type)
  1934. or get('fortran,'boolean!-type);
  1935. % if gentranlang!* eq 'c
  1936. % then type := 'int
  1937. % else type := 'logical;
  1938. tassigns := segexp1(logexp, type);
  1939. logexp := car tassigns;
  1940. tassigns := cdr tassigns
  1941. >>;
  1942. stmtlst := foreach st in stmtlst
  1943. conc seg list st;
  1944. res := 'while . logexp . stmtlst;
  1945. if tassigns then
  1946. <<
  1947. res := append(res, reverse tassigns);
  1948. res := 'progn . append(reverse tassigns, list res)
  1949. >>;
  1950. return res
  1951. end$
  1952. procedure segrepeat stmt;
  1953. % repeat --> repeat %
  1954. begin
  1955. scalar stmtlst, logexp, type;
  1956. stmt := reverse cdr stmt;
  1957. logexp := car stmt;
  1958. stmtlst := reverse cdr stmt;
  1959. stmtlst := foreach st in stmtlst conc seg list st;
  1960. if toolongexpp logexp then
  1961. <<
  1962. type:=get(gentranlang!*,'boolean!-type)
  1963. or get('fortran,'boolean!-type);
  1964. % if gentranlang!* eq 'c
  1965. % then type := 'int
  1966. % else type := 'logical;
  1967. logexp := segexp1(logexp, type);
  1968. stmtlst := append(stmtlst, reverse cdr logexp);
  1969. logexp := car logexp
  1970. >>;
  1971. return 'repeat . append(stmtlst, list logexp)
  1972. end$
  1973. procedure segfor stmt;
  1974. % for --+--> for %
  1975. % +--> stmtgp %
  1976. begin
  1977. scalar var, loexp, stepexp, hiexp, stmtlst, tassigns1, tassigns2, type,
  1978. markedvars, res;
  1979. var := cadr stmt;
  1980. type := getvartype var;
  1981. stmt := cddr stmt;
  1982. loexp := caar stmt;
  1983. stepexp := cadar stmt;
  1984. hiexp := caddar stmt;
  1985. stmtlst := cddr stmt;
  1986. if toolongexpp loexp then
  1987. <<
  1988. loexp := segexp1(loexp, type);
  1989. tassigns1 := reverse cdr loexp;
  1990. loexp := car loexp;
  1991. markvar loexp;
  1992. markedvars := loexp . markedvars
  1993. >>;
  1994. if toolongexpp stepexp then
  1995. <<
  1996. stepexp := segexp1(stepexp, type);
  1997. tassigns2 := reverse cdr stepexp;
  1998. stepexp := car stepexp;
  1999. markvar stepexp;
  2000. markedvars := stepexp . markedvars
  2001. >>;
  2002. if toolongexpp hiexp then
  2003. <<
  2004. hiexp := segexp1(hiexp, type);
  2005. tassigns1 := append(tassigns1, reverse cdr hiexp);
  2006. tassigns2 := append(tassigns2, reverse cdr hiexp);
  2007. hiexp := car hiexp
  2008. >>;
  2009. unmarkvar markedvars;
  2010. stmtlst := foreach st in stmtlst conc seg list st;
  2011. stmtlst := append(stmtlst, tassigns2);
  2012. res := !*for!* . var . list(loexp, stepexp, hiexp) . !*do!* . stmtlst;
  2013. if tassigns1 then
  2014. return mkstmtgp(nil, append(tassigns1, list res))
  2015. else
  2016. return res
  2017. end$
  2018. procedure segreturn ret;
  2019. % return --> stmtgp %
  2020. <<
  2021. ret := segexp1(cadr ret, 'unknown);
  2022. rplaca(ret, mkreturn car ret);
  2023. mkstmtgp(nil, reverse ret)
  2024. >>$
  2025. procedure seggroup stmtgp;
  2026. % stmtgp --> stmtgp %
  2027. begin
  2028. scalar locvars, res;
  2029. if car stmtgp eq 'prog then
  2030. <<
  2031. locvars := cadr stmtgp;
  2032. stmtgp := cdr stmtgp
  2033. >>
  2034. else
  2035. locvars := 0;
  2036. while stmtgp := cdr stmtgp do
  2037. res := append(seg list car stmtgp, res);
  2038. return mkstmtgp(locvars, reverse res)
  2039. end$
  2040. procedure segdef deff;
  2041. % def --> def %
  2042. mkdef(cadr deff, caddr deff,
  2043. for each stmt in cdddr deff conc seg list stmt)$
  2044. %% %%
  2045. %% Long Statement & Expression Predicates %%
  2046. %% %%
  2047. procedure toolongexpp exp;
  2048. numprintlen exp > maxexpprintlen!*$
  2049. procedure toolongstmtp stmt;
  2050. if atom stmt then nil else
  2051. if lispstmtp stmt then
  2052. if lispcondp stmt then
  2053. toolongcondp stmt
  2054. else if lispassignp stmt then
  2055. toolongassignp stmt
  2056. else if lispreturnp stmt then
  2057. toolongreturnp stmt
  2058. else if lispwhilep stmt then
  2059. toolongwhilep stmt
  2060. else if lisprepeatp stmt then
  2061. toolongrepeatp stmt
  2062. else if lispforp stmt then
  2063. toolongforp stmt
  2064. else lispeval('or . for each exp in stmt collect toolongexpp exp)
  2065. else
  2066. toolongstmtgpp stmt$
  2067. procedure toolongassignp assign;
  2068. toolongexpp caddr assign$
  2069. procedure toolongcondp condd;
  2070. begin
  2071. scalar toolong;
  2072. while condd := cdr condd do
  2073. if toolongexpp caar condd or toolongstmtp cadar condd then
  2074. toolong := t;
  2075. return toolong
  2076. end$
  2077. procedure toolongwhilep stmt;
  2078. toolongexpp cadr stmt or
  2079. lispeval('or . foreach st in cddr stmt collect toolongstmtp st)$
  2080. procedure toolongrepeatp stmt;
  2081. <<
  2082. stmt := reverse cdr stmt;
  2083. toolongexpp car stmt or
  2084. lispeval('or . foreach st in cdr stmt collect toolongstmtp st)
  2085. >>$
  2086. procedure toolongforp stmt;
  2087. lispeval('or . foreach exp in caddr stmt collect
  2088. toolongexpp exp ) or
  2089. lispeval('or . foreach st in cddddr stmt collect
  2090. toolongstmtp st )$
  2091. procedure toolongreturnp ret;
  2092. toolongexpp cadr ret$
  2093. procedure toolongstmtgpp stmtgp;
  2094. lispeval('or . for each stmt in cdr stmtgp collect
  2095. toolongstmtp stmt )$
  2096. procedure toolongdefp deff;
  2097. if lispstmtgpp cadddr deff then
  2098. toolongstmtgpp cadddr deff
  2099. else
  2100. lispeval('or .
  2101. for each stmt in cdddr deff collect toolongstmtp stmt)$
  2102. %% %%
  2103. %% Print Length Function %%
  2104. %% %%
  2105. procedure numprintlen exp;
  2106. if atom exp then
  2107. length explode exp
  2108. else if onep length exp then
  2109. numprintlen car exp
  2110. else if car exp = '!:rd!: then
  2111. 2+length explode cadr exp + length explode cddr exp
  2112. else if car exp memq '( !:cr!: !:crn!: !:gi!: ) then
  2113. 3+length explode cadr exp + length explode cddr exp
  2114. else
  2115. length exp + lispeval('plus . for each elt in cdr exp collect
  2116. numprintlen elt )$
  2117. %% %%
  2118. %% Temporary Variable Generation, Marking & Unmarking Functions %%
  2119. %% %%
  2120. procedure tempvar type;
  2121. % %
  2122. % IF type Member '(NIL 0) THEN type <- TEMPVARTYPE!* %
  2123. % %
  2124. % IF type Neq 'NIL And type Neq 'UNKNOWN THEN %
  2125. % var <- 1st unmarked tvar of VType type or of VType NIL %
  2126. % which isn't in the symbol table %
  2127. % put type on var's VType property list %
  2128. % put declaration in symbol table %
  2129. % ELSE IF type = NIL THEN %
  2130. % var <- 1st unmarked tvar of type NIL which isn't in the %
  2131. % symbol table %
  2132. % ELSE type = 'UNKNOWN %
  2133. % var <- 1st unmarked tvar of type NIL which isn't in the %
  2134. % symbol table %
  2135. % put 'UNKNOWN on var's VType property list %
  2136. % print warning - "undeclared" %
  2137. % %
  2138. % RETURN var %
  2139. % %
  2140. begin
  2141. scalar tvar, xname, num;
  2142. if type memq '(nil 0) then type := tempvartype!*;
  2143. xname := explode tempvarname!*;
  2144. num := tempvarnum!*;
  2145. if type memq '(nil unknown) then
  2146. repeat
  2147. <<
  2148. tvar := intern compress append(xname, explode num);
  2149. num := add1 num
  2150. >>
  2151. until not markedvarp tvar and not get(tvar, '!*vtype!*) and
  2152. not getvartype tvar
  2153. else
  2154. repeat
  2155. <<
  2156. tvar := intern compress append(xname, explode num);
  2157. num := add1 num
  2158. >>
  2159. until not markedvarp tvar and
  2160. (get(tvar, '!*vtype!*) eq type or
  2161. not get(tvar, '!*vtype!*) and not getvartype tvar);
  2162. put(tvar, '!*vtype!*, type);
  2163. if type eq 'unknown then
  2164. gentranerr('w, tvar, "UNDECLARED VARIABLE", nil)
  2165. else if type then
  2166. symtabput(nil, tvar, list type);
  2167. return tvar
  2168. end$
  2169. procedure markvar var;
  2170. if numberp var then
  2171. var
  2172. else if atom var then
  2173. << flag(list var, '!*marked!*); var >>
  2174. else
  2175. << for each v in var do markvar v; var >>$
  2176. procedure markedvarp var;
  2177. flagp(var, '!*marked!*)$
  2178. procedure unmarkvar var;
  2179. if atom var then
  2180. if numberp var then
  2181. var
  2182. else
  2183. remflag(list var, '!*marked!*)
  2184. else
  2185. foreach elt in var do
  2186. unmarkvar elt$
  2187. endmodule;
  2188. module lspfor; %% GENTRAN LISP-to-FORTRAN Translation Module %%
  2189. %% Author: Barbara L. Gates %%
  2190. %% December 1986 %%
  2191. % Updates:
  2192. % M. Warns 7 Oct 89 Patch in FORTEXP1 for negative constant exponents
  2193. % and integer arguments of functions like SQRT added.
  2194. % M.C. Dewar and J.H. Davenport 8 Jan 88 Double precision etc. added.
  2195. % Entry Point: FortCode
  2196. symbolic$
  2197. fluid '(!*gendecs)$
  2198. switch gendecs$
  2199. fluid '(!*getdecs)$
  2200. fluid '(!*makecalls)$
  2201. switch makecalls$
  2202. !*makecalls := t$
  2203. % User-Accessible Global Variables %
  2204. global '(gentranlang!* fortlinelen!* minfortlinelen!*
  2205. fortcurrind!* !*fortcurrind!* tablen!*)$
  2206. share fortcurrind!*, fortlinelen!*, minfortlinelen!*, tablen!*$
  2207. fortcurrind!* := 0$
  2208. !*fortcurrind!* := 6$ %current level of indentation for FORTRAN code
  2209. fortlinelen!* := 72$
  2210. minfortlinelen!* := 40$
  2211. % Double Precision Switch (defaults to OFF) - mcd 13/1/88 %
  2212. fluid '(!*double);
  2213. % !*double := t;
  2214. switch double;
  2215. % GENTRAN Global Variables %
  2216. global '(!*notfortranfuns!* !*endofloopstack!* !*subprogname!*)$
  2217. !*notfortranfuns!*:= '(acosh asinh atanh cot dilog erf expint sec)$
  2218. %mcd 10/11/87
  2219. !*endofloopstack!* := nil$
  2220. !*subprogname!* := nil$ %name of subprogram being generated
  2221. global '(!*do!* deftype!*)$
  2222. % The following ought to be all the legal Fortran types mcd 19/11/87.
  2223. global '(!*legalforttypes!*);
  2224. !*legalforttypes!* := '(real integer complex real!*8 complex!*16 logical
  2225. implicit! integer implicit! real
  2226. implicit! complex implicit! real!*8
  2227. implicit! complex!*16 implicit! logical)$
  2228. global '(!*stdout!*)$
  2229. global '(!*posn!* !$!#);
  2230. %% %%
  2231. %% LISP-to-FORTRAN Translation Functions %%
  2232. %% %%
  2233. put('fortran,'formatter,'formatfort);
  2234. put('fortran,'codegen,'fortcode);
  2235. put('fortran,'proctem,'procforttem);
  2236. put('fortran,'gendecs,'fortdecs);
  2237. put('fortran,'assigner,'mkffortassign);
  2238. put('fortran,'boolean!-type,'logical);
  2239. %% Control Function %%
  2240. symbolic procedure fortcode forms;
  2241. for each f in forms conc
  2242. if atom f then
  2243. fortexp f
  2244. else if car f memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  2245. fortexp f
  2246. else if lispstmtp f or lispstmtgpp f then
  2247. if !*gendecs then
  2248. begin
  2249. scalar r;
  2250. r := append(fortdecs symtabget('!*main!*, '!*decs!*),
  2251. fortstmt f);
  2252. symtabrem('!*main!*, '!*decs!*);
  2253. return r
  2254. end
  2255. else
  2256. fortstmt f
  2257. else if lispdefp f then
  2258. fortsubprog f
  2259. else
  2260. fortexp f$
  2261. %% Subprogram Translation %%
  2262. symbolic procedure fortsubprog deff;
  2263. begin
  2264. scalar type, stype, name, params, body, lastst, r;
  2265. name := !*subprogname!* := cadr deff;
  2266. if onep length (body := cdddr deff) and lispstmtgpp car body then
  2267. << body := cdar body; if null car body then body := cdr body >>;
  2268. if lispreturnp (lastst := car reverse body) then
  2269. body := append(body, list '(end))
  2270. else if not lispendp lastst then
  2271. body := append(body, list('(return), '(end)));
  2272. type := symtabget(name, name);
  2273. if type then type := cadr type;
  2274. stype := symtabget(name, '!*type!*) or
  2275. ( if type or functionformp(body, name)
  2276. then 'function
  2277. else 'subroutine );
  2278. symtabrem(name, '!*type!*);
  2279. params := symtabget(name, '!*params!*) or caddr deff;
  2280. symtabrem(name, '!*params!*);
  2281. if !*getdecs and null type and stype eq 'function
  2282. then type := deftype!*;
  2283. if type then
  2284. << symtabrem(name, name);
  2285. % Generate the correct double precision type name - mcd 28/1/88 %
  2286. if !*double then
  2287. if type memq '(real real*8) then
  2288. type := 'double! precision
  2289. else if type eq 'complex then
  2290. type := 'complex!*16;
  2291. >>;
  2292. r := mkffortsubprogdec(type, stype, name, params);
  2293. if !*gendecs then
  2294. r := append(r, fortdecs symtabget(name, '!*decs!*));
  2295. r := append(r, for each s in body
  2296. conc fortstmt s);
  2297. if !*gendecs then
  2298. << symtabrem(name, nil); symtabrem(name, '!*decs!*) >>;
  2299. return r
  2300. end$
  2301. %% Generation of Declarations %%
  2302. symbolic procedure fortdecs decs;
  2303. for each tl in formtypelists decs
  2304. conc mkffortdec(car tl, cdr tl)$
  2305. %% Expression Translation %%
  2306. procedure fortexp exp;
  2307. fortexp1(exp, 0)$
  2308. symbolic procedure fortexp1(exp, wtin);
  2309. if atom exp then
  2310. list fortranname exp
  2311. else
  2312. if listp exp and onep length exp then
  2313. fortranname exp
  2314. else if optype car exp then
  2315. begin
  2316. scalar wt, op, res;
  2317. wt := fortranprecedence car exp;
  2318. op := fortranop car exp;
  2319. exp := cdr exp;
  2320. if onep length exp then
  2321. res := op . fortexp1(car exp, wt)
  2322. else
  2323. <<
  2324. res := fortexp1(car exp, wt);
  2325. if op eq '!+ then
  2326. while exp := cdr exp do
  2327. <<
  2328. if atom car exp or caar exp neq 'minus then
  2329. res := append(res, list op);
  2330. res := append(res, fortexp1(car exp, wt))
  2331. >>
  2332. else if op eq '!*!* then
  2333. while exp := cdr exp do
  2334. begin
  2335. if numberp car exp and lessp(car exp, 0) then
  2336. res := append(append(res, list op),
  2337. insertparens fortexp1(car exp, wt))
  2338. else
  2339. res := append(append(res, list op),
  2340. fortexp1(car exp, wt))
  2341. end
  2342. else
  2343. while exp := cdr exp do
  2344. res := append(append(res, list op),
  2345. fortexp1(car exp, wt))
  2346. >>;
  2347. if wtin >= wt then res := insertparens res;
  2348. return res
  2349. end
  2350. else if car exp eq 'literal then
  2351. fortliteral exp
  2352. else if car exp eq 'range
  2353. then append(fortexp cadr exp,'!: . fortexp caddr exp)
  2354. else if car exp eq '!:rd!: then
  2355. if smallfloatp cdr exp then
  2356. list cdr exp
  2357. else
  2358. begin scalar mt; % Print bigfloats more naturally. MCD 26/2/90
  2359. mt := cddr exp;
  2360. exp := explode cadr exp;
  2361. mt := mt + (length exp) - 1;
  2362. exp := list('literal,
  2363. compress ( (car exp) . '!. . (cdr exp) ));
  2364. if null (mt = 0) then
  2365. exp := append(exp,
  2366. list(if !*double then '!D else '!E,mt))
  2367. else if !*double then
  2368. exp := append(exp,'(!D 0));
  2369. return fortliteral exp;
  2370. end
  2371. else if car exp eq '!:crn!: then
  2372. fortexp1(!*crn2cr exp,wtin)
  2373. else if car exp eq '!:gi!: then
  2374. fortexp1(!*gi2cr exp,wtin)
  2375. else if car exp eq '!:cr!: then
  2376. ('!().append(fortexp1(cons('!:rd!:,cadr exp),wtin),
  2377. ('!,).append(fortexp1(cons('!:rd!:,cddr exp),wtin),list '!)))
  2378. % We must make this list up at run time, since there's
  2379. % a CONC loop that relies on being able to RPLAC into it.
  2380. % Yuck. JHD/MCD 19.6.89
  2381. else
  2382. begin scalar op, res, intrinsic;
  2383. intrinsic := get(car exp, '!*fortranname!*);
  2384. op := fortranname car exp;
  2385. exp := cdr exp;
  2386. % Make the arguments of intrinsic functions real if we aren't
  2387. % sure. Note that we can't simply evaluate the argument and
  2388. % test that, unless it is a constant. MCD 7/11/89.
  2389. if intrinsic and fixp car exp then
  2390. exp := list float car exp
  2391. else if intrinsic and null memq(op,'(real dble))
  2392. and null isfloat car exp then
  2393. exp := list list('real,car exp);
  2394. res := fortexp1(car exp, 0);
  2395. while exp := cdr exp do
  2396. res := append(append(res, list '!,),
  2397. fortexp1(car exp, 0));
  2398. return op . insertparens res
  2399. end;
  2400. symbolic procedure isfloat u;
  2401. % Returns T if u is a float or a list whose car is an intrinsic
  2402. % function name. MCD 7/11/89.
  2403. floatp(u) or (idp u and declared!-as!-float(u) ) or
  2404. pairp(u) and (car u eq '!:rd!: or
  2405. get(car u,'!*fortranname!*) or
  2406. declared!-as!-float(car u) );
  2407. procedure fortranop op;
  2408. get(op, '!*fortranop!*) or op$
  2409. put('or, '!*fortranop!*, '!.or!. )$
  2410. put('and, '!*fortranop!*, '!.and!.)$
  2411. put('not, '!*fortranop!*, '!.not!.)$
  2412. put('equal, '!*fortranop!*, '!.eq!. )$
  2413. put('neq, '!*fortranop!*, '!.ne!. )$
  2414. put('greaterp, '!*fortranop!*, '!.gt!. )$
  2415. put('geq, '!*fortranop!*, '!.ge!. )$
  2416. put('lessp, '!*fortranop!*, '!.lt!. )$
  2417. put('leq, '!*fortranop!*, '!.le!. )$
  2418. put('plus, '!*fortranop!*, '!+ )$
  2419. put('times, '!*fortranop!*, '!* )$
  2420. put('quotient, '!*fortranop!*, '/ )$
  2421. put('minus, '!*fortranop!*, '!- )$
  2422. put('expt, '!*fortranop!*, '!*!* )$
  2423. % This procedure (and FORTRANNAME, RATFORNAME properties, and
  2424. % the DOUBLE flag) are shared between FORTRAN and RATFOR
  2425. procedure fortranname a; % Amended mcd 10/11/87
  2426. if stringp a then
  2427. stringtoatom a % convert a to atom containing "'s
  2428. else
  2429. << if a memq !*notfortranfuns!* then
  2430. << wrs cdr !*stdout!*;
  2431. prin2 "** WARNING: ";
  2432. prin1 a;
  2433. prin2t " is not an intrinsic Fortran function";
  2434. >>$
  2435. if !*double then
  2436. get(a, '!*doublename!*) or a
  2437. else
  2438. get(a, '!*fortranname!*) or a
  2439. >>$
  2440. put(t, '!*fortranname!*, '!.true!. )$
  2441. put(nil, '!*fortranname!*, '!.false!.)$
  2442. %% mcd 10/11/87
  2443. %% Reduce functions' equivalent Fortran 77 real function names
  2444. put('abs,'!*fortranname!*, 'abs)$
  2445. put('sqrt,'!*fortranname!*, 'sqrt)$
  2446. put('exp,'!*fortranname!*, 'exp)$
  2447. put('log,'!*fortranname!*, 'alog)$
  2448. put('sin,'!*fortranname!*, 'sin)$
  2449. put('cos,'!*fortranname!*, 'cos)$
  2450. put('tan,'!*fortranname!*, 'tan)$
  2451. put('acos,'!*fortranname!*, 'acos)$
  2452. put('asin,'!*fortranname!*, 'asin)$
  2453. put('atan,'!*fortranname!*, 'atan)$
  2454. put('sinh,'!*fortranname!*, 'sinh)$
  2455. put('cosh,'!*fortranname!*, 'cosh)$
  2456. put('tanh,'!*fortranname!*, 'tanh)$
  2457. put('real,'!*fortranname!*, 'real)$
  2458. %% Reduce function's equivalent Fortran 77 double-precision names
  2459. put('abs,'!*doublename!*, 'dabs)$
  2460. put('sqrt,'!*doublename!*, 'dsqrt)$
  2461. put('exp,'!*doublename!*, 'dexp)$
  2462. put('log,'!*doublename!*, 'dlog)$
  2463. put('sin,'!*doublename!*, 'dsin)$
  2464. put('cos,'!*doublename!*, 'dcos)$
  2465. put('tan,'!*doublename!*, 'dtan)$
  2466. put('acos,'!*doublename!*, 'dacos)$
  2467. put('asin,'!*doublename!*, 'dasin)$
  2468. put('atan,'!*doublename!*, 'datan)$
  2469. put('sinh,'!*doublename!*, 'dsinh)$
  2470. put('cosh,'!*doublename!*, 'dcosh)$
  2471. put('tanh,'!*doublename!*, 'dtanh)$
  2472. put(t, '!*doublename!*, '!.true!. )$
  2473. put(nil, '!*doublename!*, '!.false!.)$
  2474. put('real,'!*doublename!*, 'dble)$
  2475. %% end of mcd
  2476. procedure fortranprecedence op;
  2477. get(op, '!*fortranprecedence!*) or 9$
  2478. put('or, '!*fortranprecedence!*, 1)$
  2479. put('and, '!*fortranprecedence!*, 2)$
  2480. put('not, '!*fortranprecedence!*, 3)$
  2481. put('equal, '!*fortranprecedence!*, 4)$
  2482. put('neq, '!*fortranprecedence!*, 4)$
  2483. put('greaterp, '!*fortranprecedence!*, 4)$
  2484. put('geq, '!*fortranprecedence!*, 4)$
  2485. put('lessp, '!*fortranprecedence!*, 4)$
  2486. put('leq, '!*fortranprecedence!*, 4)$
  2487. put('plus, '!*fortranprecedence!*, 5)$
  2488. put('times, '!*fortranprecedence!*, 6)$
  2489. put('quotient, '!*fortranprecedence!*, 6)$
  2490. put('minus, '!*fortranprecedence!*, 7)$
  2491. put('expt, '!*fortranprecedence!*, 8)$
  2492. %% Statement Translation %%
  2493. procedure fortstmt stmt;
  2494. if null stmt then
  2495. nil
  2496. else if lisplabelp stmt then
  2497. fortstmtnum stmt
  2498. else if car stmt eq 'literal then
  2499. fortliteral stmt
  2500. else if lispreadp stmt then
  2501. fortread stmt
  2502. else if lispassignp stmt then
  2503. fortassign stmt
  2504. else if lispprintp stmt then
  2505. fortwrite stmt
  2506. else if lispcondp stmt then
  2507. fortif stmt
  2508. else if lispbreakp stmt then
  2509. fortbreak stmt
  2510. else if lispgop stmt then
  2511. fortgoto stmt
  2512. else if lispreturnp stmt then
  2513. fortreturn stmt
  2514. else if lispstopp stmt then
  2515. fortstop stmt
  2516. else if lispendp stmt then
  2517. fortend stmt
  2518. else if lispwhilep stmt then
  2519. fortwhile stmt
  2520. else if lisprepeatp stmt then
  2521. fortrepeat stmt
  2522. else if lispforp stmt then
  2523. fortfor stmt
  2524. else if lispstmtgpp stmt then
  2525. fortstmtgp stmt
  2526. else if lispdefp stmt then
  2527. fortsubprog stmt
  2528. else if lispcallp stmt then
  2529. fortcall stmt$
  2530. procedure fortassign stmt;
  2531. mkffortassign(cadr stmt, caddr stmt)$
  2532. procedure fortbreak stmt;
  2533. if null !*endofloopstack!* then
  2534. gentranerr('e, nil, "BREAK NOT INSIDE LOOP - CANNOT BE TRANSLATED",
  2535. nil)
  2536. else if atom car !*endofloopstack!* then
  2537. begin
  2538. scalar n1;
  2539. n1 := genstmtnum();
  2540. rplaca(!*endofloopstack!*, list(car !*endofloopstack!*, n1));
  2541. return mkffortgo n1
  2542. end
  2543. else
  2544. mkffortgo cadar !*endofloopstack!*$
  2545. procedure fortcall stmt;
  2546. mkffortcall(car stmt, cdr stmt)$
  2547. procedure fortfor stmt;
  2548. begin
  2549. scalar n1, result, var, loexp, stepexp, hiexp, stmtlst;
  2550. var := cadr stmt;
  2551. stmt := cddr stmt;
  2552. loexp := caar stmt;
  2553. stepexp := cadar stmt;
  2554. hiexp := caddar stmt;
  2555. stmtlst := cddr stmt;
  2556. n1 := genstmtnum();
  2557. !*endofloopstack!* := n1 . !*endofloopstack!*;
  2558. result := mkffortdo(n1, var, loexp, hiexp, stepexp);
  2559. indentfortlevel(+1);
  2560. result := append(result, for each st in stmtlst conc fortstmt st);
  2561. indentfortlevel(-1);
  2562. result := append(result, mkffortcontinue n1);
  2563. if pairp car !*endofloopstack!* then
  2564. result := append(result, mkffortcontinue cadar !*endofloopstack!*);
  2565. !*endofloopstack!* := cdr !*endofloopstack!*;
  2566. return result
  2567. end$
  2568. procedure fortend stmt;
  2569. mkffortend()$
  2570. procedure fortgoto stmt;
  2571. begin
  2572. scalar stmtnum;
  2573. if not ( stmtnum := get(cadr stmt, '!*stmtnum!*) ) then
  2574. stmtnum := put(cadr stmt, '!*stmtnum!*, genstmtnum());
  2575. return mkffortgo stmtnum
  2576. end$
  2577. symbolic procedure fortif stmt;
  2578. begin scalar r, st;
  2579. r := mkffortif caadr stmt;
  2580. indentfortlevel(+1);
  2581. st := seqtogp cdadr stmt;
  2582. if eqcar(st, 'cond) and length st=2 then
  2583. st := mkstmtgp(0, list st);
  2584. r := append(r, fortstmt st);
  2585. indentfortlevel(-1);
  2586. stmt := cdr stmt;
  2587. while (stmt := cdr stmt) and caar stmt neq t do
  2588. <<
  2589. r := append(r, mkffortelseif caar stmt);
  2590. indentfortlevel(+1);
  2591. st := seqtogp cdar stmt;
  2592. if eqcar(st, 'cond) and length st=2 then
  2593. st := mkstmtgp(0, list st);
  2594. r := append(r, fortstmt st);
  2595. indentfortlevel(-1)
  2596. >>;
  2597. if stmt then
  2598. <<
  2599. r := append(r, mkffortelse());
  2600. indentfortlevel(+1);
  2601. st := seqtogp cdar stmt;
  2602. if eqcar(st, 'cond) and length st=2 then
  2603. st := mkstmtgp(0, list st);
  2604. r := append(r, fortstmt st);
  2605. indentfortlevel(-1)
  2606. >>;
  2607. return append(r,mkffortendif());
  2608. end$
  2609. symbolic procedure mkffortif exp;
  2610. append(append(list(mkforttab(), 'if, '! , '!(), fortexp exp),
  2611. list('!),'! , 'then , mkfortterpri()))$
  2612. symbolic procedure mkffortelseif exp;
  2613. append(append(list(mkforttab(), 'else, '! , 'if, '! , '!(),
  2614. fortexp exp),
  2615. list('!), 'then, mkcterpri()))$
  2616. symbolic procedure mkffortelse();
  2617. list(mkforttab(), 'else, mkfortterpri())$
  2618. symbolic procedure mkffortendif();
  2619. list(mkforttab(), 'endif, mkfortterpri())$
  2620. procedure fortliteral stmt;
  2621. mkffortliteral cdr stmt$
  2622. procedure fortread stmt;
  2623. mkffortread cadr stmt$
  2624. procedure fortrepeat stmt;
  2625. begin
  2626. scalar n, result, stmtlst, logexp;
  2627. stmtlst := reverse cdr stmt;
  2628. logexp := car stmtlst;
  2629. stmtlst := reverse cdr stmtlst;
  2630. n := genstmtnum();
  2631. !*endofloopstack!* := 'dummy . !*endofloopstack!*;
  2632. result := mkffortcontinue n;
  2633. indentfortlevel(+1);
  2634. result := append(result, for each st in stmtlst conc fortstmt st);
  2635. indentfortlevel(-1);
  2636. result := append(result, mkffortifgo(list('not, logexp), n));
  2637. if pairp car !*endofloopstack!* then
  2638. result := append(result, mkffortcontinue cadar !*endofloopstack!*);
  2639. !*endofloopstack!* := cdr !*endofloopstack!*;
  2640. return result
  2641. end$
  2642. procedure fortreturn stmt;
  2643. if onep length stmt then
  2644. mkffortreturn()
  2645. else if !*subprogname!* then
  2646. append(mkffortassign(!*subprogname!*, cadr stmt), mkffortreturn())
  2647. else
  2648. gentranerr('e, nil,
  2649. "RETURN NOT INSIDE FUNCTION - CANNOT BE TRANSLATED",
  2650. nil)$
  2651. procedure fortstmtgp stmtgp;
  2652. <<
  2653. if car stmtgp eq 'progn then
  2654. stmtgp := cdr stmtgp
  2655. else
  2656. stmtgp := cddr stmtgp;
  2657. for each stmt in stmtgp conc fortstmt stmt
  2658. >>$
  2659. procedure fortstmtnum label;
  2660. begin
  2661. scalar stmtnum;
  2662. if not ( stmtnum := get(label, '!*stmtnum!*) ) then
  2663. stmtnum := put(label, '!*stmtnum!*, genstmtnum());
  2664. return mkffortcontinue stmtnum
  2665. end$
  2666. procedure fortstop stmt;
  2667. mkffortstop()$
  2668. procedure fortwhile stmt;
  2669. begin
  2670. scalar n1, n2, result, logexp, stmtlst;
  2671. logexp := cadr stmt;
  2672. stmtlst := cddr stmt;
  2673. n1 := genstmtnum();
  2674. n2 := genstmtnum();
  2675. !*endofloopstack!* := n2 . !*endofloopstack!*;
  2676. result := append(list(n1, '! ), mkffortifgo(list('not, logexp), n2));
  2677. indentfortlevel(+1);
  2678. result := append(result, for each st in stmtlst conc fortstmt st);
  2679. result := append(result, mkffortgo n1);
  2680. indentfortlevel(-1);
  2681. result := append(result, mkffortcontinue n2);
  2682. if pairp car !*endofloopstack!* then
  2683. result := append(result, mkffortcontinue cadar !*endofloopstack!*);
  2684. !*endofloopstack!* := cdr !*endofloopstack!*;
  2685. return result
  2686. end$
  2687. procedure fortwrite stmt;
  2688. mkffortwrite cdr stmt$
  2689. %% %%
  2690. %% FORTRAN Code Formatting Functions %%
  2691. %% %%
  2692. %% Statement Formatting %%
  2693. procedure mkffortassign(lhs, rhs);
  2694. append(append(mkforttab() . fortexp lhs, '!= . fortexp rhs),
  2695. list mkfortterpri())$
  2696. symbolic procedure mkffortcall(fname, params);
  2697. % Installed the switch makecalls 18/11/88 mcd.
  2698. <<
  2699. if params then
  2700. params := append(append(list '!(,
  2701. for each p in insertcommas params
  2702. conc fortexp p),
  2703. list '!));
  2704. % If we want to generate bits of statements, then what might
  2705. % appear a subroutine call may in fact be a function reference.
  2706. if !*makecalls then
  2707. append(append(list(mkforttab(), 'call, '! ), fortexp fname),
  2708. append(params, list mkfortterpri()))
  2709. else
  2710. append(fortexp fname,params)
  2711. >>$
  2712. procedure mkffortcontinue stmtnum;
  2713. list(stmtnum, '! , mkforttab(), 'continue, mkfortterpri())$
  2714. symbolic procedure mkffortdec(type, varlist); %Ammended mcd 13/11/87
  2715. <<
  2716. if type equal 'scalar then type := deftype!*;
  2717. if type and null (type memq !*legalforttypes!*) then
  2718. gentranerr('e,type,"Illegal Fortran type. ",nil);
  2719. type := type or 'dimension;
  2720. % Generate the correct double precision type name - mcd 14/1/88 %
  2721. if !*double then
  2722. if type memq '(real real*8) then
  2723. type := 'double! precision
  2724. else if type memq '(implicit! real implicit! real*8) then
  2725. type := 'implicit! double! precision
  2726. else if type eq 'complex then
  2727. type := 'complex!*16
  2728. else if type eq 'implicit! complex then
  2729. type := 'implicit! complex!*16;
  2730. varlist := for each v in insertcommas varlist
  2731. conc fortexp v;
  2732. if implicitp type then
  2733. append(list(mkforttab(), type, '! , '!(),
  2734. append(varlist, list('!), mkfortterpri())))
  2735. else
  2736. append(list(mkforttab(), type, '! ),
  2737. append(varlist,list mkfortterpri()))
  2738. >>$
  2739. procedure mkffortdo(stmtnum, var, lo, hi, incr);
  2740. <<
  2741. if onep incr then
  2742. incr := nil
  2743. else if incr then
  2744. incr := '!, . fortexp incr;
  2745. append(append(append(list(mkforttab(), !*do!*, '! , stmtnum, '! ),
  2746. fortexp var),
  2747. append('!= . fortexp lo, '!, . fortexp hi)),
  2748. append(incr, list mkfortterpri()))
  2749. >>$
  2750. procedure mkffortend;
  2751. list(mkforttab(), 'end, mkfortterpri())$
  2752. procedure mkffortgo stmtnum;
  2753. list(mkforttab(), 'goto, '! , stmtnum, mkfortterpri())$
  2754. procedure mkffortifgo(exp, stmtnum);
  2755. append(append(list(mkforttab(), 'if, '! , '!(), fortexp exp),
  2756. list('!), '! , 'goto, '! , stmtnum, mkfortterpri()))$
  2757. procedure mkffortliteral args;
  2758. for each a in args conc
  2759. if a eq 'tab!* then
  2760. list mkforttab()
  2761. else if a eq 'cr!* then
  2762. list mkfortterpri()
  2763. else if pairp a then
  2764. fortexp a
  2765. else
  2766. list stripquotes a$
  2767. procedure mkffortread var;
  2768. append(list(mkforttab(), 'read, '!(!*!,!*!), '! ),
  2769. append(fortexp var, list mkfortterpri()))$
  2770. procedure mkffortreturn;
  2771. list(mkforttab(), 'return, mkfortterpri())$
  2772. procedure mkffortstop;
  2773. list(mkforttab(), 'stop, mkfortterpri())$
  2774. procedure mkffortsubprogdec(type, stype, name, params);
  2775. <<
  2776. if params then
  2777. params := append('!( . for each p in insertcommas params
  2778. conc fortexp p,
  2779. list '!));
  2780. if type then
  2781. type := list(mkforttab(), type, '! , stype, '! )
  2782. else
  2783. type := list(mkforttab(), stype, '! );
  2784. append(append(type, fortexp name),
  2785. append(params, list mkfortterpri()))
  2786. >>$
  2787. procedure mkffortwrite arglist;
  2788. append(append(list(mkforttab(), 'write, '!(!*!,!*!), '! ),
  2789. for each arg in insertcommas arglist conc fortexp arg),
  2790. list mkfortterpri())$
  2791. %% Indentation Control %%
  2792. procedure mkforttab;
  2793. list('forttab, fortcurrind!* + 6)$
  2794. procedure indentfortlevel n;
  2795. fortcurrind!* := fortcurrind!* + n * tablen!*$
  2796. procedure mkfortterpri;
  2797. list 'fortterpri$
  2798. %% FORTRAN Code Formatting & Printing Functions %%
  2799. fluid '(maxint);
  2800. maxint := 2**31-1;
  2801. symbolic procedure formatfort lst;
  2802. begin scalar linelen,str, toobig;
  2803. linelen := linelength 300;
  2804. !*posn!* := 0;
  2805. for each elt in lst do
  2806. if pairp elt then lispeval elt
  2807. else
  2808. << toobig := nil;
  2809. if fixp elt and (elt>maxint or elt<-maxint) then
  2810. toobig := 't;
  2811. str:=explode2 elt;
  2812. if toobig then
  2813. str := append(str,if !*double then '(d !0) else '(e !0))
  2814. else if floatp elt then
  2815. if !*double then
  2816. if memq('!e,str)
  2817. then str:=subst('d,'!e,str)
  2818. else if memq('e,str) % some LISPs use E not e
  2819. then str:=subst('d,'e,str)
  2820. else str:=append(str,'(d !0))
  2821. else if memq('!e,str) then
  2822. str:=subst('e,'!e,str);
  2823. % get the casing conventions correct
  2824. if !*posn!* + length str > fortlinelen!* then
  2825. fortcontline();
  2826. for each u in str do pprin2 u
  2827. >>;
  2828. linelength linelen
  2829. end$
  2830. procedure fortcontline;
  2831. <<
  2832. fortterpri();
  2833. pprin2 " .";
  2834. forttab !*fortcurrind!*;
  2835. pprin2 " "
  2836. >>$
  2837. procedure fortterpri;
  2838. pterpri()$
  2839. procedure forttab n;
  2840. <<
  2841. !*fortcurrind!* := max(min0(n, fortlinelen!* - minfortlinelen!*),6);
  2842. if (n := !*fortcurrind!* - !*posn!*) > 0 then pprin2 nspaces n
  2843. >>$
  2844. %% FORTRAN Template routines%%
  2845. procedure procforttem;
  2846. begin
  2847. scalar c, linelen;
  2848. linelen := linelength 150;
  2849. c := procfortcomm();
  2850. while c neq !$eof!$ do
  2851. if c memq '(!F !f !S !s) then
  2852. <<
  2853. pprin2 c;
  2854. c := procsubprogheading c
  2855. >>
  2856. else if c eq !$eol!$ then
  2857. <<
  2858. pterpri();
  2859. c := procfortcomm()
  2860. >>
  2861. else if c eq '!; then
  2862. c := procactive()
  2863. else
  2864. <<
  2865. pprin2 c;
  2866. c := readch()
  2867. >>;
  2868. linelength linelen
  2869. end$
  2870. procedure procfortcomm;
  2871. % <col 1>C ... <cr> %
  2872. % <col 1>c ... <cr> %
  2873. begin
  2874. scalar c;
  2875. while (c := readch()) memq '(!C !c) do
  2876. <<
  2877. pprin2 c;
  2878. repeat
  2879. if (c := readch()) neq !$eol!$ then
  2880. pprin2 c
  2881. until c eq !$eol!$;
  2882. pterpri()
  2883. >>;
  2884. return c
  2885. end$
  2886. %% This function is shared between FORTRAN and RATFOR %%
  2887. procedure procsubprogheading c;
  2888. % Altered to allow an active statement to be included in a subprogram
  2889. % heading. This is more flexible than forbidding it as in the previous
  2890. % version, although it does mean that where such a statement occurs the
  2891. % value of !$!# may be incorrect. MCD 21/11/90
  2892. begin
  2893. scalar lst, name, i, propname;
  2894. lst := if c memq '(!F !f)
  2895. then '((!U !u) (!N !n) (!C !c) (!T !t) (!I !i) (!O !o)
  2896. (!N !n))
  2897. else '((!U !u) (!B !b) (!R !r) (!O !o) (!U !u)
  2898. (!T !t) (!I !i) (!N !n) (!E !e));
  2899. while lst and (c := readch()) memq car lst do
  2900. << pprin2 c; lst := cdr lst >>;
  2901. if lst then return c;
  2902. c:=flushspaces readch();
  2903. while not(seprp c or c eq '!() do
  2904. << name := aconc(name, c); pprin2 c; c := readch() >>;
  2905. name := intern compress name;
  2906. if not !*gendecs then
  2907. symtabput(name, nil, nil);
  2908. propname := if gentranlang!* eq 'fortran
  2909. then '!*fortranname!*
  2910. else '!*ratforname!*;
  2911. put('!$0, propname, name);
  2912. c:=flushspaces c;
  2913. if c neq '!( then return c;
  2914. i := 1;
  2915. pprin2 c;
  2916. c := readch();
  2917. while c neq '!) and c neq '!; do
  2918. <<
  2919. while c neq '!; and (seprp c or c eq '!,) do
  2920. <<
  2921. if c eq !$eol!$
  2922. then pterpri()
  2923. else pprin2 c;
  2924. c := readch()
  2925. >>;
  2926. if c neq '!; then
  2927. <<
  2928. name := list c;
  2929. pprin2 c;
  2930. while not (seprp (c := readch())
  2931. or c memq list('!,,'!;, '!))) do
  2932. << name := aconc(name, c); pprin2 c >>;
  2933. put(intern compress append(explode2 '!$, explode2 i),
  2934. propname,
  2935. intern compress name);
  2936. i := add1 i;
  2937. c:=flushspaces c;
  2938. >>;
  2939. >>;
  2940. !$!# := sub1 i;
  2941. while get(name := intern compress append(explode2 '!$, explode2 i),
  2942. propname) do
  2943. remprop(name, propname);
  2944. return c
  2945. end$
  2946. endmodule;
  2947. module lsprat; %% GENTRAN LISP-to-RATFOR Translation Module %%
  2948. %% Author: Barbara L. Gates %%
  2949. %% December 1986 %%
  2950. % Updates:
  2951. % M.C. Dewar and J.H. Davenport 8 Jan 88 Double precision check added.
  2952. % Entry Point: RatCode
  2953. symbolic$
  2954. fluid '(!*double !*gendecs !*getdecs);
  2955. switch gendecs$
  2956. fluid '(!*makecalls)$
  2957. switch makecalls$
  2958. !*makecalls := t$
  2959. % User-Accessible Global Variables %
  2960. global '(minratlinelen!* ratlinelen!* !*ratcurrind!*
  2961. ratcurrind!* tablen!*)$
  2962. share ratcurrind!*, minratlinelen!*, ratlinelen!*, tablen!*$
  2963. ratcurrind!* := 0$
  2964. minratlinelen!* := 40$
  2965. ratlinelen!* := 80$
  2966. !*ratcurrind!* := 0$ %current level of indentation for RATFOR code
  2967. global '(deftype!* !*do!* !*notfortranfuns!* !*legalforttypes!*)$
  2968. global '(!*stdout!*)$
  2969. global '(!*posn!* !$!#)$
  2970. %% %%
  2971. %% LISP-to-RATFOR Translation Functions %%
  2972. %% %%
  2973. put('ratfor,'formatter,'formatrat);
  2974. put('ratfor,'codegen,'ratcode);
  2975. put('ratfor,'proctem,'procrattem);
  2976. put('ratfor,'gendecs,'ratdecs);
  2977. put('ratfor,'assigner,'mkfratassign);
  2978. put('ratfor,'boolean!-type,'logical);
  2979. %% Control Function %%
  2980. procedure ratcode forms;
  2981. for each f in forms conc
  2982. if atom f then
  2983. ratexp f
  2984. else if car f memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  2985. ratexp f
  2986. else if lispstmtp f or lispstmtgpp f then
  2987. if !*gendecs then
  2988. begin
  2989. scalar r;
  2990. r := append(ratdecs symtabget('!*main!*, '!*decs!*),
  2991. ratstmt f);
  2992. symtabrem('!*main!*, '!*decs!*);
  2993. return r
  2994. end
  2995. else
  2996. ratstmt f
  2997. else if lispdefp f then
  2998. ratsubprog f
  2999. else
  3000. ratexp f$
  3001. %% Subprogram Translation %%
  3002. symbolic procedure ratsubprog deff;
  3003. begin
  3004. scalar type, stype, name, params, body, lastst, r;
  3005. name := cadr deff;
  3006. if onep length(body := cdddr deff) and lispstmtgpp car body then
  3007. << body := cdar body; if null car body then body := cdr body >>;
  3008. if lispreturnp (lastst := car reverse body) then
  3009. body := append(body, list '(end))
  3010. else if not lispendp lastst then
  3011. body := append(body, list('(return), '(end)));
  3012. type := cadr symtabget(name, name);
  3013. stype := symtabget(name, '!*type!*) or
  3014. ( if type or functionformp(body, name)
  3015. then 'function
  3016. else 'subroutine );
  3017. symtabrem(name, '!*type!*);
  3018. params := symtabget(name, '!*params!*) or caddr deff;
  3019. symtabrem(name, '!*params!*);
  3020. if !*getdecs and null type and stype eq 'function
  3021. then type := deftype!*;
  3022. if type then
  3023. << symtabrem(name, name);
  3024. % Generate the correct double precision type name - mcd 28/1/88 %
  3025. if !*double then
  3026. if type memq '(real real*8) then
  3027. type := 'double! precision
  3028. else if type eq 'complex then
  3029. type := 'complex!*16;
  3030. >>;
  3031. r := mkfratsubprogdec(type, stype, name, params);
  3032. if !*gendecs then
  3033. r := append(r, ratdecs symtabget(name, '!*decs!*));
  3034. r := append(r, for each s in body
  3035. conc ratstmt s);
  3036. if !*gendecs then
  3037. << symtabrem(name, nil); symtabrem(name, '!*decs!*) >>;
  3038. return r
  3039. end$
  3040. %% Generation of Declarations %%
  3041. procedure ratdecs decs;
  3042. for each tl in formtypelists decs
  3043. conc mkfratdec(car tl, cdr tl)$
  3044. %% Expression Translation %%
  3045. procedure ratexp exp;
  3046. ratexp1(exp, 0)$
  3047. procedure ratexp1(exp, wtin);
  3048. if atom exp then
  3049. list fortranname exp
  3050. else
  3051. if onep length exp then
  3052. fortranname exp
  3053. else if optype car exp then
  3054. begin
  3055. scalar wt, op, res;
  3056. wt := ratforprecedence car exp;
  3057. op := ratforop car exp;
  3058. exp := cdr exp;
  3059. if onep length exp then
  3060. res := op . ratexp1(car exp, wt)
  3061. else
  3062. <<
  3063. res := ratexp1(car exp, wt);
  3064. if op eq '!+ then
  3065. while exp := cdr exp do
  3066. <<
  3067. if atom car exp or caar exp neq 'minus then
  3068. res := append(res, list op);
  3069. res := append(res, ratexp1(car exp, wt))
  3070. >>
  3071. else
  3072. while exp := cdr exp do
  3073. res := append(append(res, list op),
  3074. ratexp1(car exp, wt))
  3075. >>;
  3076. if wtin >= wt then res := insertparens res;
  3077. return res
  3078. end
  3079. else if car exp eq 'literal then
  3080. ratliteral exp
  3081. else if car exp eq 'range
  3082. then append(fortexp cadr exp,'!: . fortexp caddr exp)
  3083. else if car exp eq '!:rd!: then
  3084. ratliteral list('literal,
  3085. cadr exp,
  3086. if !*double then '!.d else '!.e,
  3087. cddr exp)
  3088. else if car exp memq '(!:cr!: !:crn!: !:gi!:) then
  3089. begin scalar re,im;
  3090. re := explode if smallfloatp cadr exp then cadr exp
  3091. else caadr exp;
  3092. re := if memq ('!e, re) then
  3093. subst('d,'!e,re)
  3094. else if memq ('!E, re) then
  3095. subst('d,'!E,re)
  3096. else if !*double then
  3097. append(re,'(d 0))
  3098. else
  3099. append(re,'(e 0));
  3100. im := explode if smallfloatp cddr exp then cddr exp
  3101. else caddr exp;
  3102. im := if memq ('!e, im) then
  3103. subst('d,'!e,im)
  3104. else if memq ('!E, im) then
  3105. subst('d,'!E,im)
  3106. else if !*double then
  3107. append(im,'(d 0))
  3108. else
  3109. append(im,'(e 0));
  3110. return ('!().append(re,('!,).append(im,'(!))));
  3111. end
  3112. else
  3113. begin
  3114. scalar op, res;
  3115. op := fortranname car exp;
  3116. exp := cdr exp;
  3117. res := ratexp1(car exp, 0);
  3118. while exp := cdr exp do
  3119. res := append(append(res, list '!,), ratexp1(car exp, 0));
  3120. return op . insertparens res
  3121. end$
  3122. procedure ratforop op;
  3123. get(op, '!*ratforop!*) or op$
  3124. put('or, '!*ratforop!*, '| )$
  3125. put('and, '!*ratforop!*, '& )$
  3126. put('not, '!*ratforop!*, '!! )$
  3127. put('equal, '!*ratforop!*, '!=!=)$
  3128. put('neq, '!*ratforop!*, '!!!=)$
  3129. put('greaterp, '!*ratforop!*, '> )$
  3130. put('geq, '!*ratforop!*, '!>!=)$
  3131. put('lessp, '!*ratforop!*, '< )$
  3132. put('leq, '!*ratforop!*, '!<!=)$
  3133. put('plus, '!*ratforop!*, '!+ )$
  3134. put('times, '!*ratforop!*, '* )$
  3135. put('quotient, '!*ratforop!*, '/ )$
  3136. put('minus, '!*ratforop!*, '!- )$
  3137. put('expt, '!*ratforop!*, '!*!*)$
  3138. procedure ratforprecedence op;
  3139. get(op, '!*ratforprecedence!*) or 9$
  3140. put('or, '!*ratforprecedence!*, 1)$
  3141. put('and, '!*ratforprecedence!*, 2)$
  3142. put('not, '!*ratforprecedence!*, 3)$
  3143. put('equal, '!*ratforprecedence!*, 4)$
  3144. put('neq, '!*ratforprecedence!*, 4)$
  3145. put('greaterp, '!*ratforprecedence!*, 4)$
  3146. put('geq, '!*ratforprecedence!*, 4)$
  3147. put('lessp, '!*ratforprecedence!*, 4)$
  3148. put('leq, '!*ratforprecedence!*, 4)$
  3149. put('plus, '!*ratforprecedence!*, 5)$
  3150. put('times, '!*ratforprecedence!*, 6)$
  3151. put('quotient, '!*ratforprecedence!*, 6)$
  3152. put('minus, '!*ratforprecedence!*, 7)$
  3153. put('expt, '!*ratforprecedence!*, 8)$
  3154. %% Statement Translation %%
  3155. procedure ratstmt stmt;
  3156. if null stmt then
  3157. nil
  3158. else if lisplabelp stmt then
  3159. ratstmtnum stmt
  3160. else if car stmt eq 'literal then
  3161. ratliteral stmt
  3162. else if lispreadp stmt then
  3163. ratread stmt
  3164. else if lispassignp stmt then
  3165. ratassign stmt
  3166. else if lispprintp stmt then
  3167. ratwrite stmt
  3168. else if lispcondp stmt then
  3169. ratif stmt
  3170. else if lispbreakp stmt then
  3171. ratbreak stmt
  3172. else if lispgop stmt then
  3173. ratgoto stmt
  3174. else if lispreturnp stmt then
  3175. ratreturn stmt
  3176. else if lispstopp stmt then
  3177. ratstop stmt
  3178. else if lispendp stmt then
  3179. ratend stmt
  3180. else if lisprepeatp stmt then
  3181. ratrepeat stmt
  3182. else if lispwhilep stmt then
  3183. ratwhile stmt
  3184. else if lispforp stmt then
  3185. ratforfor stmt
  3186. else if lispstmtgpp stmt then
  3187. ratstmtgp stmt
  3188. else if lispdefp stmt then
  3189. ratsubprog stmt
  3190. else if lispcallp stmt then
  3191. ratcall stmt$
  3192. procedure ratassign stmt;
  3193. mkfratassign(cadr stmt, caddr stmt)$
  3194. procedure ratbreak stmt;
  3195. mkfratbreak()$
  3196. procedure ratcall stmt;
  3197. mkfratcall(car stmt, cdr stmt)$
  3198. procedure ratforfor stmt;
  3199. begin
  3200. scalar r, var, loexp, stepexp, hiexp, stmtlst;
  3201. var := cadr stmt;
  3202. stmt := cddr stmt;
  3203. loexp := caar stmt;
  3204. stepexp := cadar stmt;
  3205. hiexp := caddar stmt;
  3206. stmtlst := cddr stmt;
  3207. r := mkfratdo(var, loexp, hiexp, stepexp);
  3208. indentratlevel(+1);
  3209. r := append(r, foreach st in stmtlst conc ratstmt st);
  3210. indentratlevel(-1);
  3211. return r
  3212. end$
  3213. procedure ratend stmt;
  3214. mkfratend()$
  3215. procedure ratgoto stmt;
  3216. begin
  3217. scalar stmtnum;
  3218. stmtnum := get(cadr stmt, '!*stmtnum!*) or
  3219. put(cadr stmt, '!*stmtnum!*, genstmtnum());
  3220. return mkfratgo stmtnum
  3221. end$
  3222. procedure ratif stmt;
  3223. begin
  3224. scalar r, st;
  3225. r := mkfratif caadr stmt;
  3226. indentratlevel(+1);
  3227. st := seqtogp cdadr stmt;
  3228. if eqcar(st, 'cond) and length st=2 then
  3229. st := mkstmtgp(0, list st);
  3230. r := append(r, ratstmt st);
  3231. indentratlevel(-1);
  3232. stmt := cdr stmt;
  3233. while (stmt := cdr stmt) and caar stmt neq t do
  3234. <<
  3235. r := append(r, mkfratelseif caar stmt);
  3236. indentratlevel(+1);
  3237. st := seqtogp cdar stmt;
  3238. if eqcar(st, 'cond) and length st=2 then
  3239. st := mkstmtgp(0, list st);
  3240. r := append(r, ratstmt st);
  3241. indentratlevel(-1)
  3242. >>;
  3243. if stmt then
  3244. <<
  3245. r := append(r, mkfratelse());
  3246. indentratlevel(+1);
  3247. st := seqtogp cdar stmt;
  3248. if eqcar(st, 'cond) and length st=2 then
  3249. st := mkstmtgp(0, list st);
  3250. r := append(r, ratstmt st);
  3251. indentratlevel(-1)
  3252. >>;
  3253. return r
  3254. end$
  3255. procedure ratliteral stmt;
  3256. mkfratliteral cdr stmt$
  3257. procedure ratread stmt;
  3258. mkfratread cadr stmt$
  3259. procedure ratrepeat stmt;
  3260. begin
  3261. scalar r, stmtlst, logexp;
  3262. stmt := reverse cdr stmt;
  3263. logexp := car stmt;
  3264. stmtlst := reverse cdr stmt;
  3265. r := mkfratrepeat();
  3266. indentratlevel(+1);
  3267. r := append(r, foreach st in stmtlst conc ratstmt st);
  3268. indentratlevel(-1);
  3269. return append(r, mkfratuntil logexp)
  3270. end$
  3271. procedure ratreturn stmt;
  3272. if cdr stmt then
  3273. mkfratreturn cadr stmt
  3274. else
  3275. mkfratreturn nil$
  3276. procedure ratstmtgp stmtgp;
  3277. begin
  3278. scalar r;
  3279. if car stmtgp eq 'progn then
  3280. stmtgp := cdr stmtgp
  3281. else
  3282. stmtgp := cddr stmtgp;
  3283. r := mkfratbegingp();
  3284. indentratlevel(+1);
  3285. r := append(r, for each stmt in stmtgp conc ratstmt stmt);
  3286. indentratlevel(-1);
  3287. return append(r, mkfratendgp())
  3288. end$
  3289. procedure ratstmtnum label;
  3290. begin
  3291. scalar stmtnum;
  3292. stmtnum := get(label, '!*stmtnum!*) or
  3293. put(label, '!*stmtnum!*, genstmtnum());
  3294. return mkfratcontinue stmtnum
  3295. end$
  3296. procedure ratstop stmt;
  3297. mkfratstop()$
  3298. procedure ratwhile stmt;
  3299. begin
  3300. scalar r, logexp, stmtlst;
  3301. logexp := cadr stmt;
  3302. stmtlst := cddr stmt;
  3303. r := mkfratwhile logexp;
  3304. indentratlevel(+1);
  3305. r := append(r, foreach st in stmtlst conc ratstmt st);
  3306. indentratlevel(-1);
  3307. return r
  3308. end$
  3309. procedure ratwrite stmt;
  3310. mkfratwrite cdr stmt$
  3311. %% %%
  3312. %% RATFOR Code Formatting Functions %%
  3313. %% %%
  3314. %% Statement Formatting %%
  3315. procedure mkfratassign(lhs, rhs);
  3316. append(append(mkrattab() . ratexp lhs, '!= . ratexp rhs),
  3317. list mkratterpri())$
  3318. procedure mkfratbegingp;
  3319. list(mkrattab(), '!{, mkratterpri())$
  3320. procedure mkfratbreak;
  3321. list(mkrattab(), 'break, mkratterpri())$
  3322. procedure mkfratcall(fname, params);
  3323. % Installed the switch makecalls 18/11/88 mcd.
  3324. <<
  3325. if params then
  3326. params := append(append(list '!(,
  3327. for each p in insertcommas params
  3328. conc ratexp p),
  3329. list '!));
  3330. % If we want to generate bits of statements, then what might
  3331. % appear a subroutine call may in fact be a function reference.
  3332. if !*makecalls then
  3333. append(append(list(mkrattab(), 'call, '! ), ratexp fname),
  3334. append(params, list mkratterpri()))
  3335. else
  3336. append(ratexp fname,params)
  3337. >>$
  3338. procedure mkfratcontinue stmtnum;
  3339. list(stmtnum, '! , mkrattab(), 'continue, mkratterpri())$
  3340. symbolic procedure mkfratdec(type, varlist); %Ammended mcd 3/12/87
  3341. <<
  3342. if type equal 'scalar then type := deftype!*;
  3343. if type and null (type memq !*legalforttypes!*) then
  3344. gentranerr('e,type,"Illegal Ratfor type. ",nil);
  3345. type := type or 'dimension;
  3346. % Generate the correct double precision type name - mcd 14/1/88 %
  3347. if !*double then
  3348. if type memq '(real real*8) then
  3349. type := 'double! precision
  3350. else if type memq '(implicit! real implicit! real*8) then
  3351. type := 'implicit! double! precision
  3352. else if type eq 'complex then
  3353. type := 'complex!*16
  3354. else if type eq 'implicit! complex then
  3355. type := 'implicit! complex!*16;
  3356. varlist := for each v in insertcommas varlist
  3357. conc ratexp v;
  3358. if implicitp type then
  3359. append(list(mkrattab(), type, '! , '!(),
  3360. append(varlist, list('!), mkratterpri())))
  3361. else
  3362. append(list(mkrattab(), type, '! ),
  3363. append(varlist, list mkratterpri()))
  3364. >>$
  3365. procedure mkfratdo(var, lo, hi, incr);
  3366. <<
  3367. if onep incr then
  3368. incr := nil
  3369. else if incr then
  3370. incr := '!, . ratexp incr;
  3371. append(append(append(list(mkrattab(), !*do!*, '! ), ratexp var),
  3372. append('!= . ratexp lo, '!, . ratexp hi)),
  3373. append(incr, list mkratterpri()))
  3374. >>$
  3375. procedure mkfratelse;
  3376. list(mkrattab(), 'else, mkratterpri())$
  3377. procedure mkfratelseif exp;
  3378. append(append(list(mkrattab(), 'else, '! , 'if, '! , '!(), ratexp exp),
  3379. list('!), mkratterpri()))$
  3380. procedure mkfratend;
  3381. list(mkrattab(), 'end, mkratterpri())$
  3382. procedure mkfratendgp;
  3383. list(mkrattab(), '!}, mkratterpri())$
  3384. procedure mkfratgo stmtnum;
  3385. list(mkrattab(), 'goto, '! , stmtnum, mkratterpri())$
  3386. procedure mkfratif exp;
  3387. append(append(list(mkrattab(), 'if, '! , '!(), ratexp exp),
  3388. list('!), mkratterpri()))$
  3389. procedure mkfratliteral args;
  3390. for each a in args conc
  3391. if a eq 'tab!* then
  3392. list mkrattab()
  3393. else if a eq 'cr!* then
  3394. list mkratterpri()
  3395. else if pairp a then
  3396. ratexp a
  3397. else
  3398. list stripquotes a$
  3399. procedure mkfratread var;
  3400. append(list(mkrattab(), 'read, '!(!*!,!*!), '! ),
  3401. append(ratexp var, list mkratterpri()))$
  3402. procedure mkfratrepeat;
  3403. list(mkrattab(), 'repeat, mkratterpri())$
  3404. procedure mkfratreturn exp;
  3405. if exp then
  3406. append(append(list(mkrattab(), 'return, '!(), ratexp exp),
  3407. list('!), mkratterpri()))
  3408. else
  3409. list(mkrattab(), 'return, mkratterpri())$
  3410. procedure mkfratstop;
  3411. list(mkrattab(), 'stop, mkratterpri())$
  3412. procedure mkfratsubprogdec(type, stype, name, params);
  3413. <<
  3414. if params then
  3415. params := append('!( . for each p in insertcommas params
  3416. conc ratexp p,
  3417. list '!));
  3418. if type then
  3419. type := list(mkrattab(), type, '! , stype, '! )
  3420. else
  3421. type := list(mkrattab(), stype, '! );
  3422. append(append(type, ratexp name),
  3423. append(params,list mkratterpri()))
  3424. >>$
  3425. procedure mkfratuntil logexp;
  3426. append(list(mkrattab(), 'until, '! , '!(),
  3427. append(ratexp logexp, list('!), mkratterpri())))$
  3428. procedure mkfratwhile exp;
  3429. append(append(list(mkrattab(), 'while, '! , '!(), ratexp exp),
  3430. list('!), mkratterpri()))$
  3431. procedure mkfratwrite arglist;
  3432. append(append(list(mkrattab(), 'write, '!(!*!,!*!), '! ),
  3433. for each arg in insertcommas arglist conc ratexp arg),
  3434. list mkratterpri())$
  3435. %% Indentation Control %%
  3436. procedure mkrattab;
  3437. list('rattab, ratcurrind!*)$
  3438. procedure indentratlevel n;
  3439. ratcurrind!* := ratcurrind!* + n * tablen!*$
  3440. procedure mkratterpri;
  3441. list 'ratterpri$
  3442. %% RATFOR Code Formatting & Printing Functions %%
  3443. procedure formatrat lst;
  3444. begin
  3445. scalar linelen,str;
  3446. linelen := linelength 300;
  3447. !*posn!* := 0;
  3448. for each elt in lst do
  3449. if pairp elt then lispeval elt
  3450. else
  3451. << str:=explode2 elt;
  3452. if floatp elt then
  3453. if !*double then
  3454. if memq('!e,str)
  3455. then str:=subst('d,'!e,str)
  3456. else if memq('e,str) % Some LISPs use E not e
  3457. then str:=subst('d,'e,str)
  3458. else str:=append(str,'(d !0))
  3459. else str:=subst('e,'!e,str);
  3460. % get the casing conventions correct
  3461. if !*posn!* + length str > ratlinelen!* then
  3462. ratcontline();
  3463. for each u in str do pprin2 u
  3464. >>;
  3465. linelength linelen
  3466. end$
  3467. procedure ratcontline;
  3468. <<
  3469. ratterpri();
  3470. rattab !*ratcurrind!*;
  3471. pprin2 " "
  3472. >>$
  3473. procedure ratterpri;
  3474. pterpri()$
  3475. procedure rattab n;
  3476. <<
  3477. !*ratcurrind!* := min0(n, ratlinelen!* - minratlinelen!*);
  3478. if (n := !*ratcurrind!* - !*posn!*) > 0 then pprin2 nspaces n
  3479. >>$
  3480. %% RATFOR template processing %%
  3481. procedure procrattem;
  3482. begin
  3483. scalar c, linelen;
  3484. linelen := linelength 150;
  3485. c := readch();
  3486. while c neq !$eof!$ do
  3487. if c memq '(!F !f !S !s) then
  3488. <<
  3489. pprin2 c;
  3490. c := procsubprogheading c
  3491. >>
  3492. else if c eq '!# then
  3493. c := procratcomm()
  3494. else if c eq '!; then
  3495. c := procactive()
  3496. else if c eq !$eol!$ then
  3497. <<
  3498. pterpri();
  3499. c := readch()
  3500. >>
  3501. else
  3502. <<
  3503. pprin2 c;
  3504. c := readch()
  3505. >>;
  3506. linelength linelen
  3507. end$
  3508. procedure procratcomm;
  3509. % # ... <cr> %
  3510. begin
  3511. scalar c;
  3512. pprin2 '!#;
  3513. while (c := readch()) neq !$eol!$ do
  3514. pprin2 c;
  3515. pterpri();
  3516. return readch()
  3517. end$
  3518. endmodule;
  3519. module lspc; %% GENTRAN LISP-to-C Translation Module %%
  3520. %% Author: Barbara L. Gates %%
  3521. %% December 1986 %%
  3522. % Entry Point: CCode
  3523. symbolic$
  3524. fluid '(!*double !*gendecs)$
  3525. switch gendecs$
  3526. % User-Accessible Global Variables %
  3527. global '(clinelen!* minclinelen!* !*ccurrind!* ccurrind!* tablen!*)$
  3528. share clinelen!*, minclinelen!*, ccurrind!*, tablen!*$
  3529. ccurrind!* := 0$
  3530. clinelen!* := 80$
  3531. minclinelen!* := 40$
  3532. !*ccurrind!* := 0$ %current level of indentation for C code
  3533. global '(deftype!* !*c!-functions!*)$
  3534. global '(!*posn!* !$!#);
  3535. !*c!-functions!* := '(sin cos tan asin acos atan atan2 sinh cosh tanh
  3536. asinh acosh atanh power sincos sinpi cospi
  3537. sincospi tanpi asinpi acospi atanpi exp expm1 exp2
  3538. exp10 log log1p log2 log10 pow compound annuity
  3539. abs fabs fmod sqrt cbrt)$
  3540. %% %%
  3541. %% LISP-to-C Translation Functions %%
  3542. %% %%
  3543. put('c,'formatter,'formatc);
  3544. put('c,'codegen,'ccode);
  3545. put('c,'proctem,'procctem);
  3546. put('c,'gendecs,'cdecs);
  3547. put('c,'assigner,'mkfcassign);
  3548. put('c,'boolean!-type,'int);
  3549. %% Control Function %%
  3550. symbolic procedure ccode forms;
  3551. for each f in forms conc
  3552. if atom f then
  3553. cexp f
  3554. else if car f memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  3555. cexp f
  3556. else if lispstmtp f or lispstmtgpp f then
  3557. if !*gendecs then
  3558. begin
  3559. scalar r;
  3560. r := append(cdecs symtabget('!*main!*, '!*decs!*),
  3561. cstmt f);
  3562. symtabrem('!*main!*, '!*decs!*);
  3563. return r
  3564. end
  3565. else
  3566. cstmt f
  3567. else if lispdefp f then
  3568. cproc f
  3569. else
  3570. cexp f$
  3571. %% Procedure Translation %%
  3572. symbolic procedure cproc deff; % Type details amended mcd 3/3/88
  3573. begin
  3574. scalar type, name, params, paramtypes, vartypes, body, r;
  3575. name := cadr deff;
  3576. if onep length (body := cdddr deff) and lispstmtgpp car body then
  3577. << body := cdar body; if null car body then body := cdr body >>;
  3578. if (type := symtabget(name, name)) then
  3579. << type := cadr type;
  3580. % Convert reduce types to c types
  3581. if type equal 'real then
  3582. type := '!f!l!o!a!t
  3583. else if type equal 'integer then
  3584. type := '!i!n!t;
  3585. if !*double then
  3586. if type equal '!f!l!o!a!t then
  3587. type := '!d!o!u!b!l!e
  3588. else if type equal '!i!n!t then
  3589. type := '!l!o!n!g;
  3590. symtabrem(name, name)
  3591. >>;
  3592. params := symtabget(name, '!*params!*) or caddr deff;
  3593. symtabrem(name, '!*params!*);
  3594. for each dec in symtabget(name, '!*decs!*) do
  3595. if car dec memq params
  3596. then paramtypes := append(paramtypes, list dec)
  3597. else vartypes := append(vartypes, list dec);
  3598. r := append( append( mkfcprocdec(type, name, params),
  3599. cdecs paramtypes ),
  3600. mkfcbegingp() );
  3601. indentclevel(+1);
  3602. if !*gendecs then
  3603. r := append(r, cdecs vartypes);
  3604. r := append(r, for each s in body
  3605. conc cstmt s);
  3606. indentclevel(-1);
  3607. r := append(r, mkfcendgp());
  3608. if !*gendecs then
  3609. << symtabrem(name, nil); symtabrem(name, '!*decs!*) >>;
  3610. return r
  3611. end$
  3612. %% Generation of Declarations %%
  3613. symbolic procedure cdecs decs;
  3614. for each tl in formtypelists decs
  3615. conc mkfcdec(car tl, cdr tl)$
  3616. %% Expression Translation %%
  3617. symbolic procedure cexp exp;
  3618. cexp1(exp, 0)$
  3619. symbolic procedure cexp1(exp, wtin);
  3620. if atom exp then
  3621. list cname exp
  3622. else
  3623. if onep length exp then
  3624. append(cname exp, insertparens(()))
  3625. else if car exp eq 'expt then
  3626. '!p!o!w!e!r . insertparens append(cexp1(cadr exp, 0),
  3627. '!, . cexp1(caddr exp, 0))
  3628. else if optype car exp then
  3629. begin
  3630. scalar wt, op, res;
  3631. wt := cprecedence car exp;
  3632. op := cop car exp;
  3633. exp := cdr exp;
  3634. if onep length exp then
  3635. res := op . cexp1(car exp, wt)
  3636. else
  3637. <<
  3638. res := cexp1(car exp, wt);
  3639. if op eq '!+ then
  3640. while exp := cdr exp do
  3641. <<
  3642. if atom car exp or caar exp neq 'minus then
  3643. res := append(res, list op);
  3644. res := append(res, cexp1(car exp, wt))
  3645. >>
  3646. else
  3647. while exp := cdr exp do
  3648. res := append(append(res, list op),
  3649. cexp1(car exp, wt))
  3650. >>;
  3651. if wtin >= wt then res := insertparens res;
  3652. return res
  3653. end
  3654. else if car exp eq 'literal then
  3655. cliteral exp
  3656. else if car exp eq 'range then
  3657. if cadr exp = 0 then cexp caddr exp
  3658. else gentranerr('e,exp,
  3659. "C does not support non-zero lower bounds",nil)
  3660. else if car exp eq '!:rd!: then
  3661. fortliteral list('literal,
  3662. cadr exp,
  3663. '!.e,
  3664. cddr exp)
  3665. else if car exp memq '(!:cr!: !:crn!: !:gi!:) then
  3666. gentranerr('e,exp,"C doesn't support complex data type",nil)
  3667. else if arrayeltp exp then
  3668. cname car exp . foreach s in cdr exp conc
  3669. insertbrackets cexp1(s, 0)
  3670. else if cfunctcallp exp then
  3671. begin
  3672. scalar op, res;
  3673. op := cname car exp;
  3674. exp := cdr exp;
  3675. res := '!( . cexp1(car exp, 0);
  3676. while exp := cdr exp do
  3677. res := append(res, '!, . cexp1(car exp, 0));
  3678. return op . append(res, list('!)) )
  3679. end
  3680. else
  3681. begin
  3682. scalar op, res;
  3683. op := cname car exp;
  3684. exp := cdr exp;
  3685. res := append( '![ . cexp1(car exp, 0),'( !]) );
  3686. % Changed to generate proper C arrays - mcd 25/9/89
  3687. while exp := cdr exp do
  3688. res := append(res, append('![ . cexp1(car exp, 0)
  3689. ,'( !]) ) );
  3690. return op . res
  3691. end$
  3692. symbolic procedure cfunctcallp exp;
  3693. memq(car exp,!*c!-functions!*) or symtabget(car exp,'!*type!*)$
  3694. symbolic procedure cop op;
  3695. get(op, '!*cop!*) or op$
  3696. put('or, '!*cop!*, '!|!|)$
  3697. put('and, '!*cop!*, '!&!&)$
  3698. put('not, '!*cop!*, '!! )$
  3699. put('equal, '!*cop!*, '!=!=)$
  3700. put('neq, '!*cop!*, '!!!=)$
  3701. put('greaterp, '!*cop!*, '> )$
  3702. put('geq, '!*cop!*, '!>!=)$
  3703. put('lessp, '!*cop!*, '< )$
  3704. put('leq, '!*cop!*, '!<!=)$
  3705. put('plus, '!*cop!*, '!+ )$
  3706. put('times, '!*cop!*, '* )$
  3707. put('quotient, '!*cop!*, '/ )$
  3708. put('minus, '!*cop!*, '!- )$
  3709. symbolic procedure cname a;
  3710. if stringp a then
  3711. stringtoatom a % convert a to atom containing "'s
  3712. else if memq(a,!*c!-functions!*) then
  3713. string!-downcase a
  3714. else
  3715. get(a, '!*cname!*) or a$
  3716. put(t, '!*cname!*, 1)$
  3717. put(nil, '!*cname!*, 0)$
  3718. symbolic procedure cprecedence op;
  3719. get(op, '!*cprecedence!*) or 8$
  3720. put('or, '!*cprecedence!*, 1)$
  3721. put('and, '!*cprecedence!*, 2)$
  3722. put('equal, '!*cprecedence!*, 3)$
  3723. put('neq, '!*cprecedence!*, 3)$
  3724. put('greaterp, '!*cprecedence!*, 4)$
  3725. put('geq, '!*cprecedence!*, 4)$
  3726. put('lessp, '!*cprecedence!*, 4)$
  3727. put('leq, '!*cprecedence!*, 4)$
  3728. put('plus, '!*cprecedence!*, 5)$
  3729. put('times, '!*cprecedence!*, 6)$
  3730. put('quotient, '!*cprecedence!*, 6)$
  3731. put('not, '!*cprecedence!*, 7)$
  3732. put('minus, '!*cprecedence!*, 7)$
  3733. %% Statement Translation %%
  3734. symbolic procedure cstmt stmt;
  3735. if null stmt then
  3736. nil
  3737. else if lisplabelp stmt then
  3738. clabel stmt
  3739. else if car stmt eq 'literal then
  3740. cliteral stmt
  3741. else if lispassignp stmt then
  3742. cassign stmt
  3743. else if lispcondp stmt then
  3744. cif stmt
  3745. else if lispbreakp stmt then
  3746. cbreak stmt
  3747. else if lispgop stmt then
  3748. cgoto stmt
  3749. else if lispreturnp stmt then
  3750. creturn stmt
  3751. else if lispstopp stmt then
  3752. cexit stmt
  3753. else if lisprepeatp stmt then
  3754. crepeat stmt
  3755. else if lispwhilep stmt then
  3756. cwhile stmt
  3757. else if lispforp stmt then
  3758. cfor stmt
  3759. else if lispstmtgpp stmt then
  3760. cstmtgp stmt
  3761. else if lispdefp stmt then
  3762. cproc stmt
  3763. else
  3764. cexpstmt stmt$
  3765. symbolic procedure cassign stmt;
  3766. mkfcassign(cadr stmt, caddr stmt)$
  3767. symbolic procedure cbreak stmt;
  3768. mkfcbreak()$
  3769. symbolic procedure cexit stmt;
  3770. mkfcexit()$
  3771. symbolic procedure cexpstmt exp;
  3772. append(mkctab() . cexp exp, list('!;, mkcterpri()))$
  3773. symbolic procedure cfor stmt;
  3774. begin
  3775. scalar r, var, loexp, stepexp, hiexp, stmtlst;
  3776. var := cadr stmt;
  3777. stmt := cddr stmt;
  3778. loexp := caar stmt;
  3779. stepexp := cadar stmt;
  3780. hiexp := caddar stmt;
  3781. stmtlst := cddr stmt;
  3782. r := mkfcfor(var, loexp,
  3783. list(if (numberp stepexp and stepexp < 0) or
  3784. eqcar(stepexp,'minus) then 'geq else 'leq,
  3785. var, hiexp),
  3786. var,
  3787. list('plus, var, stepexp));
  3788. indentclevel(+1);
  3789. r := append(r, foreach st in stmtlst conc cstmt st);
  3790. indentclevel(-1);
  3791. return r
  3792. end$
  3793. symbolic procedure cgoto stmt;
  3794. mkfcgo cadr stmt$
  3795. symbolic procedure cif stmt;
  3796. begin
  3797. scalar r, st;
  3798. r := mkfcif caadr stmt;
  3799. indentclevel(+1);
  3800. st := seqtogp cdadr stmt;
  3801. if eqcar(st, 'cond) and length st=2 then
  3802. st := mkstmtgp(0, list st);
  3803. r := append(r, cstmt st);
  3804. indentclevel(-1);
  3805. stmt := cdr stmt;
  3806. while (stmt := cdr stmt) and caar stmt neq t do
  3807. <<
  3808. r := append(r, mkfcelseif caar stmt);
  3809. indentclevel(+1);
  3810. st := seqtogp cdar stmt;
  3811. if eqcar(st, 'cond) and length st=2 then
  3812. st := mkstmtgp(0, list st);
  3813. r := append(r, cstmt st);
  3814. indentclevel(-1)
  3815. >>;
  3816. if stmt then
  3817. <<
  3818. r := append(r, mkfcelse());
  3819. indentclevel(+1);
  3820. st := seqtogp cdar stmt;
  3821. if eqcar(st, 'cond) and length st=2 then
  3822. st := mkstmtgp(0, list st);
  3823. r := append(r, cstmt st);
  3824. indentclevel(-1)
  3825. >>;
  3826. return r
  3827. end$
  3828. symbolic procedure clabel label;
  3829. mkfclabel label$
  3830. symbolic procedure cliteral stmt;
  3831. mkfcliteral cdr stmt$
  3832. symbolic procedure crepeat stmt;
  3833. begin
  3834. scalar r, stmtlst, logexp;
  3835. stmt := reverse cdr stmt;
  3836. logexp := car stmt;
  3837. stmtlst := reverse cdr stmt;
  3838. r := mkfcdo();
  3839. indentclevel(+1);
  3840. r := append(r, foreach st in stmtlst conc cstmt st);
  3841. indentclevel(-1);
  3842. return append(r, mkfcdowhile list('not, logexp))
  3843. end$
  3844. symbolic procedure creturn stmt;
  3845. if cdr stmt then
  3846. mkfcreturn cadr stmt
  3847. else
  3848. mkfcreturn nil$
  3849. symbolic procedure cstmtgp stmtgp;
  3850. begin
  3851. scalar r;
  3852. if car stmtgp eq 'progn then
  3853. stmtgp := cdr stmtgp
  3854. else
  3855. stmtgp :=cddr stmtgp;
  3856. r := mkfcbegingp();
  3857. indentclevel(+1);
  3858. r := append(r, for each stmt in stmtgp conc cstmt stmt);
  3859. indentclevel(-1);
  3860. return append(r, mkfcendgp())
  3861. end$
  3862. symbolic procedure cwhile stmt;
  3863. begin
  3864. scalar r, logexp, stmtlst;
  3865. logexp := cadr stmt;
  3866. stmtlst := cddr stmt;
  3867. r := mkfcwhile logexp;
  3868. indentclevel(+1);
  3869. r := append(r, foreach st in stmtlst conc cstmt st);
  3870. indentclevel(-1);
  3871. return r
  3872. end$
  3873. %% %%
  3874. %% C Code Formatting Functions %%
  3875. %% %%
  3876. %% Statement Formatting %%
  3877. symbolic procedure mkfcassign(lhs, rhs);
  3878. begin
  3879. scalar st;
  3880. if length rhs = 3 and lhs member rhs then
  3881. begin
  3882. scalar op, exp1, exp2;
  3883. op := car rhs;
  3884. exp1 := cadr rhs;
  3885. exp2 := caddr rhs;
  3886. if op = 'plus then
  3887. if onep exp1 or onep exp2 then
  3888. st := ('!+!+ . cexp lhs)
  3889. else if exp1 member '(-1 (minus 1))
  3890. or exp2 member '(-1 (minus 1)) then
  3891. st := ('!-!- . cexp lhs)
  3892. else if eqcar(exp1, 'minus) then
  3893. st := append(cexp lhs, '!-!= . cexp cadr exp1)
  3894. else if eqcar(exp2, 'minus) then
  3895. st := append(cexp lhs, '!-!= . cexp cadr exp2)
  3896. else if exp1 = lhs then
  3897. st := append(cexp lhs, '!+!= . cexp exp2)
  3898. else
  3899. st := append(cexp lhs, '!+!= . cexp exp1)
  3900. else if op = 'difference and onep exp2 then
  3901. st := ('!-!- . cexp lhs)
  3902. else if op = 'difference and exp1 = lhs then
  3903. st := append(cexp lhs, '!-!= . cexp exp2)
  3904. else if op = 'times and exp1 = lhs then
  3905. st := append(cexp lhs, '!*!= . cexp exp2)
  3906. else if op = 'times then
  3907. st := append(cexp lhs, '!*!= . cexp exp1)
  3908. else if op = 'quotient and exp1 = lhs then
  3909. st := append(cexp lhs, '!/!= . cexp exp2)
  3910. else
  3911. st := append(cexp lhs, '!= . cexp rhs)
  3912. end
  3913. else
  3914. st := append(cexp lhs, '!= . cexp rhs);
  3915. return append(mkctab() . st, list('!;, mkcterpri()))
  3916. end$
  3917. symbolic procedure mkfcbegingp;
  3918. list(mkctab(), '!{, mkcterpri())$
  3919. symbolic procedure mkfcbreak;
  3920. list(mkctab(), '!b!r!e!a!k, '!;, mkcterpri())$
  3921. symbolic procedure mkfcdec(type, varlist); %Amended mcd 13/11/87,3/3/88
  3922. <<
  3923. if type equal 'scalar then
  3924. type := deftype!*;
  3925. % Convert Reduce types to C types.
  3926. if type equal 'real then
  3927. type := '!f!l!o!a!t
  3928. else if type equal 'integer then
  3929. type := '!i!n!t;
  3930. % Deal with precision.
  3931. if !*double then
  3932. if type equal '!f!l!o!a!t then
  3933. type := '!d!o!u!b!l!e
  3934. else if type equal '!i!n!t then
  3935. type := '!l!o!n!g;
  3936. varlist := for each v in varlist collect
  3937. if atom v then
  3938. v
  3939. else
  3940. car v . for each dim in cdr v collect
  3941. if numberp dim then add1 dim
  3942. else if eqcar (dim, 'range) and cadr dim = 0
  3943. then add1 caddr dim
  3944. else gentranerr('e,dim,"Not C dimension",nil);
  3945. append(mkctab() . type . '! . for each v in insertcommas varlist
  3946. conc cexp v,
  3947. list('!;, mkcterpri()))
  3948. >>$
  3949. symbolic procedure mkfcdo;
  3950. list(mkctab(), '!d!o, mkcterpri())$
  3951. symbolic procedure mkfcdowhile exp;
  3952. append(append(list(mkctab(), '!w!h!i!l!e, '! , '!(), cexp exp),
  3953. list('!), '!;, mkcterpri()))$
  3954. symbolic procedure mkfcelse;
  3955. list(mkctab(), '!e!l!s!e, mkcterpri())$
  3956. symbolic procedure mkfcelseif exp;
  3957. append(append(list(mkctab(), '!e!l!s!e, '! , '!i!f, '! , '!(),cexp exp),
  3958. list('!), mkcterpri()))$
  3959. symbolic procedure mkfcendgp;
  3960. list(mkctab(), '!}, mkcterpri())$
  3961. symbolic procedure mkfcexit;
  3962. list(mkctab(), '!e!x!i!t, '!(, 0, '!), '!;, mkcterpri())$
  3963. symbolic procedure mkfcfor(var1, lo, cond, var2, nextexp);
  3964. <<
  3965. if var1 then
  3966. var1 := append(cexp var1, '!= . cexp lo);
  3967. if cond then
  3968. cond := cexp cond;
  3969. if var2 then
  3970. <<
  3971. var2 := cdr mkfcassign(var2, nextexp);
  3972. var2 := reverse cddr reverse var2
  3973. >>;
  3974. append(append(append(list(mkctab(), '!f!o!r, '! , '!(), var1),
  3975. '!; . cond),
  3976. append('!; . var2, list('!), mkcterpri())))
  3977. >>$
  3978. symbolic procedure mkfcgo label;
  3979. list(mkctab(), '!g!o!t!o, '! , label, '!;, mkcterpri())$
  3980. symbolic procedure mkfcif exp;
  3981. append(append(list(mkctab(), '!i!f, '! , '!(), cexp exp),
  3982. list('!), mkcterpri()))$
  3983. symbolic procedure mkfclabel label;
  3984. list(label, '!:, mkcterpri())$
  3985. symbolic procedure mkfcliteral args;
  3986. for each a in args conc
  3987. if a eq 'tab!* then
  3988. list mkctab()
  3989. else if a eq 'cr!* then
  3990. list mkcterpri()
  3991. else if pairp a then
  3992. cexp a
  3993. else
  3994. list stripquotes a$
  3995. symbolic procedure mkfcprocdec(type, name, params);
  3996. <<
  3997. params := append('!( . for each p in insertcommas params
  3998. conc cexp p,
  3999. list '!));
  4000. if type then
  4001. append(mkctab() . type . '! . cexp name,
  4002. append(params,list mkcterpri()))
  4003. else
  4004. append(mkctab() . cexp name, append(params, list mkcterpri()))
  4005. >>$
  4006. symbolic procedure mkfcreturn exp;
  4007. if exp then
  4008. append(append(list(mkctab(), '!r!e!t!u!r!n, '!(), cexp exp),
  4009. list('!), '!;, mkcterpri()))
  4010. else
  4011. list(mkctab(), '!r!e!t!u!r!n, '!;, mkcterpri())$
  4012. symbolic procedure mkfcwhile exp;
  4013. append(append(list(mkctab(), '!w!h!i!l!e, '! , '!(), cexp exp),
  4014. list('!), mkcterpri()))$
  4015. %% Indentation Control %%
  4016. symbolic procedure mkctab;
  4017. list('ctab, ccurrind!*)$
  4018. symbolic procedure indentclevel n;
  4019. ccurrind!* := ccurrind!* + n * tablen!*$
  4020. symbolic procedure mkcterpri;
  4021. list 'cterpri$
  4022. %% %%
  4023. %% Misc. Functions %%
  4024. %% %%
  4025. symbolic procedure insertbrackets exp;
  4026. '![ . append(exp, list '!])$
  4027. %% C Code Formatting & Printing Functions %%
  4028. symbolic procedure formatc lst;
  4029. begin
  4030. scalar linelen;
  4031. linelen := linelength 300;
  4032. !*posn!* := 0;
  4033. for each elt in lst do
  4034. if pairp elt then lispeval elt
  4035. else
  4036. <<
  4037. if !*posn!* + length explode2 elt > clinelen!* then
  4038. ccontline();
  4039. pprin2 elt
  4040. >>;
  4041. linelength linelen
  4042. end$
  4043. symbolic procedure ccontline;
  4044. <<
  4045. cterpri();
  4046. ctab !*ccurrind!*;
  4047. pprin2 " "
  4048. >>$
  4049. symbolic procedure cterpri;
  4050. pterpri()$
  4051. symbolic procedure ctab n;
  4052. <<
  4053. !*ccurrind!* := min0(n, clinelen!* - minclinelen!*);
  4054. if (n := !*ccurrind!* - !*posn!*) > 0 then pprin2 nspaces n
  4055. >>$
  4056. %% C template processing %%
  4057. symbolic procedure procctem;
  4058. begin
  4059. scalar c, linelen;
  4060. linelen := linelength 150;
  4061. c := readch();
  4062. if c eq '!# then c := procc!#line c;
  4063. while c neq !$eof!$ do
  4064. if c eq !$eol!$ then
  4065. c := procc!#line c
  4066. else if c eq '!/ then
  4067. c := procccomm()
  4068. else if c eq '!; then
  4069. c := procactive()
  4070. else
  4071. c := proccheader(c);
  4072. linelength linelen
  4073. end$
  4074. symbolic procedure procc!#line c;
  4075. % # ... <cr> %
  4076. begin
  4077. if c eq !$eol!$ then
  4078. << pterpri(); c := readch() >>;
  4079. if c eq '!# then
  4080. repeat
  4081. << pprin2 c; c := readch() >>
  4082. until c eq !$eol!$;
  4083. return c
  4084. end$
  4085. symbolic procedure procccomm;
  4086. % /* ... */ %
  4087. begin
  4088. scalar c;
  4089. pprin2 '!/;
  4090. c := readch();
  4091. if c eq '!* then
  4092. <<
  4093. pprin2 c;
  4094. c := readch();
  4095. repeat
  4096. <<
  4097. while c neq '!* do
  4098. <<
  4099. if c eq !$eol!$
  4100. then pterpri()
  4101. else pprin2 c;
  4102. c := readch()
  4103. >>;
  4104. pprin2 c;
  4105. c := readch()
  4106. >>
  4107. until c eq '!/;
  4108. pprin2 c;
  4109. c := readch()
  4110. >>;
  4111. return c
  4112. end$
  4113. symbolic procedure proccheader c;
  4114. begin
  4115. scalar name, i;
  4116. while seprp c and c neq !$eol!$ do
  4117. << pprin2 c; c := readch() >>;
  4118. while not(seprp c or c memq list('!/, '!;, '!()) do
  4119. << name := aconc(name, c); pprin2 c; c := readch() >>;
  4120. if c memq list(!$eol!$, '!/, '!;) then return c;
  4121. while seprp c and c neq !$eol!$ do
  4122. << pprin2 c; c := readch() >>;
  4123. if c neq '!( then return c;
  4124. name := intern compress name;
  4125. if not !*gendecs then
  4126. symtabput(name, nil, nil);
  4127. put('!$0, '!*cname!*, name);
  4128. pprin2 c;
  4129. i := 1;
  4130. c := readch();
  4131. while c neq '!) do
  4132. <<
  4133. while seprp c or c eq '!, do
  4134. <<
  4135. if c eq !$eol!$
  4136. then pterpri()
  4137. else pprin2 c;
  4138. c := readch()
  4139. >>;
  4140. name := list c;
  4141. pprin2 c;
  4142. while not(seprp (c := readch()) or c memq list('!,, '!))) do
  4143. << name := aconc(name, c); pprin2 c >>;
  4144. put(intern compress append(explode2 '!$, explode2 i),
  4145. '!*cname!*,
  4146. intern compress name);
  4147. i := add1 i;
  4148. c:=flushspaces c
  4149. >>;
  4150. !$!# := sub1 i;
  4151. while get(name := intern compress append(explode2 '!$, explode2 i),
  4152. '!*cname!*) do
  4153. remprop(name, '!*cname!*);
  4154. return proccfunction c
  4155. end$
  4156. symbolic procedure proccfunction c;
  4157. begin
  4158. scalar !{!}count;
  4159. while c neq '!{ do
  4160. if c eq '!/ then
  4161. c := procccomm()
  4162. else if c eq '!; then
  4163. c := procactive()
  4164. else if c eq !$eol!$ then
  4165. << pterpri(); c := readch() >>
  4166. else
  4167. << pprin2 c; c := readch() >>;
  4168. pprin2 c;
  4169. !{!}count := 1;
  4170. c := readch();
  4171. while !{!}count > 0 do
  4172. if c eq '!{ then
  4173. << !{!}count := add1 !{!}count; pprin2 c; c := readch() >>
  4174. else if c eq '!} then
  4175. << !{!}count := sub1 !{!}count; pprin2 c; c := readch() >>
  4176. else if c eq '!/ then
  4177. c := procccomm()
  4178. else if c eq '!; then
  4179. c := procactive()
  4180. else if c eq !$eol!$ then
  4181. << pterpri(); c := readch() >>
  4182. else
  4183. << pprin2 c; c := readch() >>;
  4184. return c
  4185. end$
  4186. endmodule;
  4187. module lsppasc; %% GENTRAN LISP-to-PASCAL Translation Module %%
  4188. %% Author: John Fitch and James Davenport after Barbara L. Gates %%
  4189. %% November 1987 %%
  4190. % Entry Point: PASCCode
  4191. symbolic$
  4192. fluid '(!*gendecs)$
  4193. switch gendecs$
  4194. % User-Accessible Global Variables %
  4195. global '(pasclinelen!* minpasclinelen!* !*pasccurrind!* pasccurrind!*
  4196. tablen!* pascfuncname!*)$
  4197. share pasclinelen!*, minpasclinelen!*,
  4198. pasccurrind!*, tablen!*, pascfuncname!*$
  4199. pasccurrind!* := 0$
  4200. minpasclinelen!* := 40$
  4201. pasclinelen!* := 70$
  4202. !*pasccurrind!* := 0$ %current level of indentation for PASCAL code
  4203. global '(!*do!* !*for!*)$
  4204. global '(!*posn!* !$!#)$
  4205. %% %%
  4206. %% LISP-to-PASCAL Translation Functions %%
  4207. %% %%
  4208. put('pascal,'formatter,'formatpasc);
  4209. put('pascal,'codegen,'pasccode);
  4210. put('pascal,'proctem,'procpasctem);
  4211. put('pascal,'gendecs,'pascdecs);
  4212. put('pascal,'assigner,'mkfpascassign);
  4213. put('pascal,'boolean!-type,'boolean);
  4214. symbolic procedure pasc!-symtabput(name,type,value);
  4215. % Like symtabput, but indirects through TYPE declarations.
  4216. % has to be recursive
  4217. begin
  4218. scalar basetype, origtype, wastypedecl;
  4219. basetype:=car value;
  4220. if basetype = 'type then <<
  4221. wastypedecl:=t;
  4222. value:=cdr value;
  4223. basetype:=car value >>;
  4224. origtype:=symtabget(name,basetype) or symtabget('!*main!*,basetype);
  4225. if pairp origtype then origtype:=cdr origtype; % strip off name;
  4226. if pairp origtype and car origtype = 'type
  4227. then value:= (cadr origtype). append(cdr value,cddr origtype);
  4228. if wastypedecl
  4229. then symtabput(name,type,'type . value)
  4230. else symtabput(name,type,value);
  4231. end;
  4232. %% Control Function %%
  4233. procedure pasccode forms;
  4234. for each f in forms conc
  4235. if atom f then
  4236. pascexp f
  4237. else if car f memq '(!:rd!: !:cr!: !:crn!: !:gi!:) then
  4238. pascexp f
  4239. else if lispstmtp f or lispstmtgpp f then
  4240. if !*gendecs then
  4241. begin
  4242. scalar r;
  4243. r := append(pascdecs symtabget('!*main!*, '!*decs!*),
  4244. pascstmt f);
  4245. symtabrem('!*main!*, '!*decs!*);
  4246. return r
  4247. end
  4248. else
  4249. pascstmt f
  4250. else if lispdefp f then
  4251. pascproc f
  4252. else
  4253. pascexp f$
  4254. %% Procedure Translation %%
  4255. procedure pascproc deff;
  4256. begin
  4257. scalar type, name, params, paramtypes, vartypes, body, r;
  4258. name := cadr deff;
  4259. if onep length (body := cdddr deff) and lispstmtgpp car body then
  4260. << body := cdar body;
  4261. if null car body then body := cdr body >>;
  4262. if (type := symtabget(name, name)) then
  4263. << type := cadr type; symtabrem(name, name) >>;
  4264. params := symtabget(name, '!*params!*) or caddr deff;
  4265. symtabrem(name, '!*params!*);
  4266. for each dec in symtabget(name, '!*decs!*) do
  4267. if car dec memq params
  4268. then paramtypes := append(paramtypes, list dec)
  4269. else if cadr dec neq 'type then
  4270. vartypes := append(vartypes, list dec);
  4271. r := mkfpascprocdec(type, name, params, paramtypes);
  4272. if !*gendecs then
  4273. << r:= append(r,list(mkpasctab(),'label,mkpascterpri()));
  4274. indentpasclevel(+1);
  4275. r:= append(r,list(mkpasctab(),'99999, '!;, mkpascterpri()));
  4276. indentpasclevel(-1);
  4277. r := append(r, pascdecs vartypes) >>;
  4278. r:= append(r, mkfpascbegingp() );
  4279. indentpasclevel(+1);
  4280. r := append(r, for each s in body
  4281. conc pascstmt s);
  4282. indentpasclevel(-1);
  4283. r:=append(r,list(mkpasctab(), 99999, '!:, mkpascterpri()));
  4284. r := append(r, mkfpascendgp());
  4285. if !*gendecs then
  4286. << symtabrem(name, nil); symtabrem(name, '!*decs!*) >>;
  4287. return r
  4288. end$
  4289. %% Generation of Declarations %%
  4290. procedure pascdecs decs;
  4291. begin scalar r;
  4292. decs:=for each r in decs conc
  4293. if cadr r eq 'type then nil else list r;
  4294. if decs then <<
  4295. indentpasclevel(+1);
  4296. decs:=for each tl in formtypelists decs
  4297. conc mkfpascdec(car tl, cdr tl);
  4298. indentpasclevel(-1);
  4299. r:=append(list(mkpasctab(),'var, mkpascterpri()), decs) >>;
  4300. return r
  4301. end$
  4302. %% Expression Translation %%
  4303. procedure pascexp exp;
  4304. pascexp1(exp, 0)$
  4305. procedure pascexp1(exp, wtin);
  4306. if atom exp then
  4307. list pascname exp
  4308. else
  4309. if onep length exp then
  4310. pascname exp
  4311. else if optype car exp then
  4312. begin
  4313. scalar wt, op, res;
  4314. wt := pascprecedence car exp;
  4315. op := pascop car exp;
  4316. exp := cdr exp;
  4317. if onep length exp then
  4318. res := op . pascexp1(car exp, wt)
  4319. else
  4320. <<
  4321. res := pascexp1(car exp, wt);
  4322. if op eq '!+ then
  4323. while exp := cdr exp do
  4324. <<
  4325. if atom car exp or caar exp neq 'minus then
  4326. res := append(res, list op);
  4327. res := append(res, pascexp1(car exp, wt))
  4328. >>
  4329. else
  4330. while exp := cdr exp do
  4331. res := append(append(res, list op),
  4332. pascexp1(car exp, wt))
  4333. >>;
  4334. if wtin >= wt then res := insertparens res;
  4335. return res
  4336. end
  4337. else if car exp eq 'literal then
  4338. pascliteral exp
  4339. else if car exp eq 'range then
  4340. append(pascexp cadr exp, '!.!. . pascexp caddr exp)
  4341. else if car exp eq '!:rd!: then
  4342. pascliteral list('literal,
  4343. cadr exp,
  4344. '!.0e,
  4345. cddr exp)
  4346. else if car exp memq '(!:cr!: !:crn!: !:gi!:) then
  4347. gentranerr('e,exp,"Pascal doesn't support complex data",nil)
  4348. else if arrayeltp exp then
  4349. if cddr exp and ((caddr exp) equal '!.!.) then
  4350. pascname car exp . pascinsertbrackets cdr exp
  4351. else pascname car exp .
  4352. pascinsertbrackets cdr foreach s in cdr exp conc
  4353. '!, . pascexp1(s, 0)
  4354. else
  4355. begin
  4356. scalar op, res;
  4357. op := pascname car exp;
  4358. exp := cdr exp;
  4359. res := pascexp1(car exp, 0);
  4360. while exp := cdr exp do
  4361. res := append(append(res, list '!,), pascexp1(car exp, 0));
  4362. return op . insertparens res
  4363. end$
  4364. procedure pascop op;
  4365. get(op, '!*pascop!*) or op$
  4366. put('or, '!*pascop!*, 'or )$
  4367. put('and, '!*pascop!*, 'and )$
  4368. put('not, '!*pascop!*, 'not )$
  4369. put('equal, '!*pascop!*, '!= )$
  4370. put('neq, '!*pascop!*, '!<!>)$
  4371. put('greaterp, '!*pascop!*, '!> )$
  4372. put('geq, '!*pascop!*, '!>!=)$
  4373. put('lessp, '!*pascop!*, '!< )$
  4374. put('leq, '!*pascop!*, '!<!=)$
  4375. put('plus, '!*pascop!*, '!+ )$
  4376. put('times, '!*pascop!*, '!* )$
  4377. put('quotient, '!*pascop!*, '!/ )$
  4378. put('minus, '!*pascop!*, '!- )$
  4379. put('expt, '!*pascop!*, '!*!*)$
  4380. procedure pascname a;
  4381. if stringp a then
  4382. stringtopascatom a % convert a to atom containing ''s
  4383. else
  4384. get(a, '!*pascname!*) or a$
  4385. procedure stringtopascatom a;
  4386. intern compress
  4387. foreach c in append('!' . explode2 a, list '!')
  4388. conc list('!!, c)$
  4389. put(t, '!*pascname!*, 'true)$
  4390. put(nil, '!*pascname!*, 'false)$
  4391. procedure pascprecedence op;
  4392. get(op, '!*pascprecedence!*) or 9$
  4393. put('or, '!*pascprecedence!*, 1)$
  4394. put('and, '!*pascprecedence!*, 2)$
  4395. put('equal, '!*pascprecedence!*, 3)$
  4396. put('neq, '!*pascprecedence!*, 3)$
  4397. put('greaterp, '!*pascprecedence!*, 4)$
  4398. put('geq, '!*pascprecedence!*, 4)$
  4399. put('lessp, '!*pascprecedence!*, 4)$
  4400. put('leq, '!*pascprecedence!*, 4)$
  4401. put('plus, '!*pascprecedence!*, 5)$
  4402. put('times, '!*pascprecedence!*, 6)$
  4403. put('quotient, '!*pascprecedence!*, 6)$
  4404. put('expt, '!*pascprecedence!*, 7)$
  4405. put('not, '!*pascprecedence!*, 8)$
  4406. put('minus, '!*pascprecedence!*, 8)$
  4407. %% Statement Translation %%
  4408. procedure pascstmt stmt;
  4409. if null stmt then
  4410. nil
  4411. else if lisplabelp stmt then
  4412. pasclabel stmt % Are there labels?
  4413. else if car stmt eq 'literal then
  4414. pascliteral stmt
  4415. else if lispassignp stmt then
  4416. pascassign stmt
  4417. else if lispcondp stmt then
  4418. pascif stmt
  4419. else if lispgop stmt then % Is there a go?
  4420. pascgoto stmt
  4421. else if lispreturnp stmt then
  4422. pascreturn stmt
  4423. else if lispstopp stmt then
  4424. pascstop stmt
  4425. else if lisprepeatp stmt then
  4426. pascrepeat stmt
  4427. else if lispwhilep stmt then
  4428. pascwhile stmt
  4429. else if lispforp stmt then
  4430. pascfor stmt
  4431. else if lispstmtgpp stmt then
  4432. pascstmtgp stmt
  4433. else if lispdefp stmt then
  4434. pascproc stmt
  4435. else
  4436. pascexpstmt stmt$
  4437. procedure pascassign stmt;
  4438. mkfpascassign(cadr stmt, caddr stmt)$
  4439. procedure pascstop stmt;
  4440. mkfpascstop()$
  4441. procedure pascexpstmt exp;
  4442. append(mkpasctab() . pascexp exp, list('!;, mkpascterpri()))$
  4443. procedure pascfor stmt;
  4444. begin
  4445. scalar r, variable, loexp, stepexp, hiexp, stmtlst;
  4446. variable := cadr stmt;
  4447. stmt := cddr stmt;
  4448. loexp := caar stmt;
  4449. stepexp := cadar stmt;
  4450. hiexp := caddar stmt;
  4451. stmtlst := cddr stmt;
  4452. r := mkfpascfor(variable, loexp, hiexp, stepexp);
  4453. indentpasclevel(+1);
  4454. %% ?? Should not the stmtlst have only one member??
  4455. r := append(r, foreach st in stmtlst conc pascstmt st);
  4456. indentpasclevel(-1);
  4457. return r
  4458. end$
  4459. procedure pascgoto stmt;
  4460. begin
  4461. scalar stmtnum;
  4462. if not ( stmtnum := get(cadr stmt, '!*stmtnum!*) ) then
  4463. stmtnum := put(cadr stmt, '!*stmtnum!*, genstmtnum());
  4464. return mkfpascgo stmtnum
  4465. end$
  4466. procedure pascif stmt;
  4467. begin
  4468. scalar r, st;
  4469. r := mkfpascif caadr stmt;
  4470. indentpasclevel(+1);
  4471. st := seqtogp cdadr stmt;
  4472. if eqcar(st, 'cond) and length st=2 then
  4473. st := mkstmtgp(0, list st);
  4474. r := append(r, pascstmt st);
  4475. indentpasclevel(-1);
  4476. stmt := cddr stmt;
  4477. if stmt then
  4478. <<
  4479. r := append(r, mkfpascelse());
  4480. indentpasclevel(+1);
  4481. st := seqtogp cdar stmt;
  4482. if eqcar(st, 'cond) and length st=2 then
  4483. st := mkstmtgp(0, list st);
  4484. r := append(r, pascstmt st);
  4485. indentpasclevel(-1)
  4486. >>;
  4487. return r
  4488. end$
  4489. procedure pasclabel label;
  4490. mkfpasclabel label$
  4491. procedure pascliteral stmt;
  4492. mkfpascliteral cdr stmt$
  4493. procedure pascrepeat stmt;
  4494. begin
  4495. scalar r, stmtlst, logexp;
  4496. stmt := reverse cdr stmt;
  4497. logexp := car stmt;
  4498. stmtlst := reverse cdr stmt;
  4499. r := mkfpascrepeat();
  4500. indentpasclevel(+1);
  4501. r := append(r, foreach st in stmtlst conc pascstmt st);
  4502. r:=removefinalsemicolon(r); % Remove final semicolon
  4503. indentpasclevel(-1);
  4504. return append(r, mkfpascuntil logexp)
  4505. end$
  4506. procedure pascreturn stmt;
  4507. if cdr stmt then
  4508. begin scalar r;
  4509. r := mkfpascbegingp();
  4510. indentpasclevel(+1);
  4511. r := append(r, mkfpascassign(pascfuncname!*, cadr stmt));
  4512. r := append(r, mkfpascreturn());
  4513. r := removefinalsemicolon(r); % Remove final semicolon
  4514. indentpasclevel(-1);
  4515. return append(r, mkfpascendgp())
  4516. end
  4517. else
  4518. mkfpascreturn()$
  4519. procedure pascstmtgp stmtgp;
  4520. begin
  4521. scalar r;
  4522. if car stmtgp eq 'progn then
  4523. stmtgp := cdr stmtgp
  4524. else
  4525. stmtgp :=cddr stmtgp;
  4526. r := mkfpascbegingp();
  4527. indentpasclevel(+1);
  4528. r := append(r, for each stmt in stmtgp conc pascstmt stmt);
  4529. r:=removefinalsemicolon(r); % Remove final semicolon
  4530. indentpasclevel(-1);
  4531. return append(r, mkfpascendgp())
  4532. end$
  4533. procedure pascwhile stmt;
  4534. begin
  4535. scalar r, logexp, stmtlst;
  4536. logexp := cadr stmt;
  4537. stmtlst := cddr stmt;
  4538. r := mkfpascwhile logexp;
  4539. indentpasclevel(+1);
  4540. r := append(r, foreach st in stmtlst conc pascstmt st);
  4541. indentpasclevel(-1);
  4542. return r
  4543. end$
  4544. procedure removefinalsemicolon r;
  4545. begin scalar rr;
  4546. r:=reversip r;
  4547. if car r eq '!; then return reversip cdr r;
  4548. if not ('!; memq r) then return reversip r;
  4549. rr:=r;
  4550. while not (cadr rr eq '!;) do << rr := cdr rr >>;
  4551. rplacd(rr, cddr rr);
  4552. return reversip r
  4553. end$
  4554. %% %%
  4555. %% Pascal Code Formatting Functions %%
  4556. %% %%
  4557. %% Statement Formatting %%
  4558. procedure mkfpascassign(lhs, rhs);
  4559. begin
  4560. scalar st;
  4561. st := append(pascexp lhs, '!:!= . pascexp rhs);
  4562. return append(mkpasctab() . st, list('!;, mkpascterpri()))
  4563. end$
  4564. procedure mkfpascbegingp;
  4565. list(mkpasctab(), 'begin, mkpascterpri())$
  4566. symbolic procedure mkfpascdec (type, varlist);
  4567. begin scalar simplet, arrayt;
  4568. varlist := for each v in varlist do
  4569. if atom v then simplet := v . simplet
  4570. else
  4571. arrayt :=
  4572. (car v . cdr for each dim in cdr v conc
  4573. if eqcar(dim,'range)
  4574. then list ('!, , cadr dim, '!.!., caddr dim )
  4575. else list ('!, , 0, '!.!., dim ))
  4576. . arrayt;
  4577. return append(if simplet
  4578. then append(mkpasctab() .
  4579. for each v in insertcommas simplet conc pascexp v,
  4580. (list('!:! , type, '!;, mkpascterpri()))),
  4581. for each v in arrayt conc
  4582. append(mkpasctab() . car pascexp car v. '!:! .
  4583. 'array . insertbrackets cdr v,
  4584. list('! of! , type, '!;, mkpascterpri())))
  4585. end;
  4586. procedure mkfpascdo;
  4587. list(mkpasctab(), !*do!*, mkpascterpri())$
  4588. procedure mkfpascuntil exp;
  4589. append(append(list(mkpasctab(), 'until, '! ),
  4590. pascexp exp),
  4591. list('!;, mkpascterpri() ));
  4592. procedure mkfpascelse;
  4593. list(mkpasctab(), 'else, mkpascterpri())$
  4594. procedure mkfpascendgp;
  4595. list(mkpasctab(), 'end, '!;, mkpascterpri())$
  4596. procedure mkfpascstop;
  4597. list(mkpasctab(), 'svr, '!(, '!0, '!), '!;, mkpascterpri())$
  4598. procedure mkfpascfor(var1, lo, hi, stepexp);
  4599. <<
  4600. stepexp := if stepexp = 1 then list('! , 'to, '! ) else
  4601. if (stepexp = -1) or (stepexp = '(minus 1)) then
  4602. list('! , 'downto, '! ) else list('error);
  4603. hi:=append(pascexp hi,list('! , !*do!*, mkpascterpri()));
  4604. hi:=append(pascexp lo, nconc(stepexp, hi));
  4605. append(list(mkpasctab(), !*for!*, '! , var1, '!:!=), hi)
  4606. >>$
  4607. procedure mkfpascgo label;
  4608. list(mkpasctab(), 'goto, '! , label, '!;, mkpascterpri())$
  4609. procedure mkfpascif exp;
  4610. append(append(list(mkpasctab(), 'if, '! ), pascexp exp),
  4611. list('! , 'then, mkpascterpri()))$
  4612. procedure mkfpasclabel label;
  4613. list(label, '!:, mkpascterpri())$
  4614. procedure mkfpascliteral args;
  4615. for each a in args conc
  4616. if a eq 'tab!* then
  4617. list mkpasctab()
  4618. else if a eq 'cr!* then
  4619. list mkpascterpri()
  4620. else if pairp a then
  4621. pascexp a
  4622. else
  4623. list stripquotes a$
  4624. procedure mkfpascprocdec(type, name, params, paramtypes);
  4625. << pascfuncname!* := name;
  4626. params := append('!( . for each p in insertcommas params
  4627. conc pascdum(p, paramtypes),
  4628. list '!));
  4629. if type then
  4630. append(mkpasctab() . 'function . '! . pascexp name,
  4631. append(params,list( '!:, type, '!;, mkpascterpri())))
  4632. else
  4633. append(mkpasctab() . 'procedure . '! . pascexp name,
  4634. append(params, list('!;, mkpascterpri())))
  4635. >>$
  4636. symbolic procedure pascdum (p,types);
  4637. begin scalar type;
  4638. type := pascgettype(p,types);
  4639. type := if atom type then list type
  4640. else if null cdr type then type
  4641. else append('array .
  4642. insertbrackets
  4643. cdr for each dim in cdr type conc
  4644. if eqcar(dim,'range)
  4645. then list('!,,cadr dim,'!.!.,caddr dim)
  4646. else list ('!, , 0, '!.!., dim),
  4647. list ('! of! , car type));
  4648. return p . '!: . type
  4649. end;
  4650. symbolic procedure pascgettype(p,types);
  4651. if null types then 'default
  4652. else if p memq car types then cdr car types
  4653. else pascgettype(p,cdr types);
  4654. procedure mkfpascrepeat;
  4655. list(mkpasctab(), 'repeat, mkpascterpri())$
  4656. procedure mkfpascreturn;
  4657. list(mkpasctab(), 'goto, '! , 99999, '!;,
  4658. '!{return!}, mkpascterpri())$
  4659. procedure mkfpascwhile exp;
  4660. append(append(list(mkpasctab(), 'while, '! , '!(), pascexp exp),
  4661. list('!), mkpascterpri()))$
  4662. %% Indentation Control %%
  4663. procedure mkpasctab;
  4664. list('pasctab, pasccurrind!*)$
  4665. procedure indentpasclevel n;
  4666. pasccurrind!* := pasccurrind!* + n * tablen!*$
  4667. procedure mkpascterpri;
  4668. list 'pascterpri$
  4669. %% %%
  4670. %% Misc. Functions %%
  4671. %% %%
  4672. procedure pascinsertbrackets exp;
  4673. '![ . append(exp, list '!] )$
  4674. %% PASCAL Code Formatting & Printing Functions %%
  4675. procedure formatpasc lst;
  4676. begin
  4677. scalar linelen;
  4678. linelen := linelength 300;
  4679. !*posn!* := 0;
  4680. for each elt in lst do
  4681. if pairp elt then lispeval elt
  4682. else
  4683. <<
  4684. if !*posn!* + length explode2 elt > pasclinelen!* then
  4685. pasccontline();
  4686. pprin2 elt
  4687. >>;
  4688. linelength linelen
  4689. end$
  4690. procedure pasccontline;
  4691. <<
  4692. pascterpri();
  4693. pasctab !*pasccurrind!*;
  4694. pprin2 " "
  4695. >>$
  4696. procedure pascterpri;
  4697. pterpri()$
  4698. procedure pasctab n;
  4699. <<
  4700. !*pasccurrind!* := min0(n, pasclinelen!* - minpasclinelen!*);
  4701. if (n := !*pasccurrind!* - !*posn!*) > 0 then pprin2 nspaces n
  4702. >>$
  4703. %% PASCAL %%
  4704. %% John Fitch %%
  4705. global '(pascfuncname!*)$
  4706. share pascfuncname!*$
  4707. %procedure procpasctem;
  4708. %begin
  4709. %scalar c, linelen;
  4710. %linelen := linelength 150;
  4711. %c := readch();
  4712. %while c neq !$eof!$ do
  4713. % if c eq !$eol!$ then
  4714. % << pterpri(); c := readch() >>
  4715. % else if c memq '(!F !f !P !p !O !o) then
  4716. % <<
  4717. % pprin2 c;
  4718. % c := procfuncoperheading c
  4719. % >>
  4720. % else if c eq '!{ then
  4721. % c := procpasccomm()
  4722. % else if c eq '!; then
  4723. % c := procactive()
  4724. % else
  4725. % c := procpascheader(c);
  4726. %linelength linelen
  4727. %end$
  4728. symbolic procedure procpasctem;
  4729. begin
  4730. scalar c;
  4731. c:=flushspaces readch();
  4732. while not (c eq !$eof!$ or c eq '!.)
  4733. do c:=flushspaces procpasctem1(c);
  4734. end;
  4735. symbolic procedure procpasctem1 c;
  4736. begin
  4737. scalar l,w, linelen;
  4738. linelen := linelength 150;
  4739. pprin2 c;
  4740. while c neq !$eof!$ and w neq 'end do <<
  4741. if c eq !$eol!$ then
  4742. << pterpri(); c := readch() >>
  4743. else if c eq '!{ then << c := procpasccomm(); w:= nil >>
  4744. else if c eq '!; then
  4745. << c := procactive(); pprin2 c; w:=nil >>;
  4746. if null w then <<
  4747. if liter c then l:= list c;
  4748. c := readch();
  4749. while liter c or digit c or c eq '!_ do
  4750. << pprin2 c; l:=c . l; c := readch() >>;
  4751. w:=intern compress reverse l;
  4752. l:=nil >>;
  4753. if w eq 'var then c:=procpascvar c
  4754. else if w eq 'const then c:=procpascconst c
  4755. else if w eq 'type then c:=procpasctype c
  4756. else if w memq '(function procedure operator)
  4757. then c:=procfuncoperheading(w,c)
  4758. else if w eq 'begin then c:= nil . procpasctem1 c
  4759. else if w neq 'end then <<
  4760. while c neq '!; do <<
  4761. if c eq '!{ then c := procpasccomm()
  4762. else << pprin2 c; c := readch() >> >>;
  4763. pprin2 c;
  4764. c:=nil . readch() >>;
  4765. % recursive, since PASCAL is
  4766. if w eq 'end then <<
  4767. c:=flushspaces c;
  4768. if not ( c memq '(!; !.)) then
  4769. gentranerr('e,nil,"END not followed by ; or .",nil);
  4770. pprin2 c; c:=readch() >>
  4771. else <<
  4772. w:=car c;
  4773. c:=flushspaces cdr c; >>
  4774. >>;
  4775. linelength linelen;
  4776. return c;
  4777. end$
  4778. symbolic procedure procpasctype c;
  4779. % TYPE ...; ...; ... %
  4780. begin
  4781. scalar w,l;
  4782. next:
  4783. while not liter c do <<
  4784. if c eq !$eol!$ then pterpri() else pprin2 c;
  4785. c:=readch() >>;
  4786. l:=nil;
  4787. while liter c or digit c or c eq '!_ do
  4788. << pprin2 c; l:=c . l; c := readch() >>;
  4789. w:=intern compress reverse l;
  4790. if w memq '(function procedure operator const var)
  4791. then return w . c;
  4792. c:=flushspaces c;
  4793. if c neq '!= then
  4794. gentranerr('e,nil,"Malformed TYPE declaration", nil);
  4795. l:=readpascaltype c;
  4796. c:=car l;
  4797. pasc!-symtabput(pascfuncname!*,w,'type . cdr l);
  4798. goto next;
  4799. end;
  4800. symbolic procedure procpascvar c;
  4801. % VAR ...; ...; ... %
  4802. begin
  4803. scalar name,l,namelist;
  4804. next:
  4805. while not liter c do <<
  4806. if c eq !$eol!$ then pterpri() else pprin2 c;
  4807. c:=readch() >>;
  4808. l:=nil;
  4809. while liter c or digit c or c eq '!_ do
  4810. << pprin2 c; l:=c . l; c := readch() >>;
  4811. name:=intern compress reverse l;
  4812. if name memq '(function procedure operator const var begin)
  4813. then return name . c;
  4814. c:=flushspaces c;
  4815. namelist:=list name;
  4816. while (c = '!, ) do <<
  4817. pprin2 c;
  4818. c:=flushspaces readch();
  4819. l:=nil;
  4820. while liter c or digit c or c eq '!_ do
  4821. << pprin2 c; l:=c . l; c := readch() >>;
  4822. name:=intern compress reverse l;
  4823. namelist:= name . namelist;
  4824. c:=flushspaces c >>;
  4825. if c neq '!: then gentranerr('e,nil,"Malformed VAR declaration", nil);
  4826. l:=readpascaltype c;
  4827. c:=car l;
  4828. for each name in namelist do
  4829. pasc!-symtabput(pascfuncname!*,name, cdr l);
  4830. goto next;
  4831. end;
  4832. symbolic procedure procpasccomm;
  4833. % { ... } %
  4834. begin
  4835. scalar c;
  4836. pprin2 '!{;
  4837. c := readch();
  4838. while c neq '!} do
  4839. <<
  4840. if c eq !$eol!$
  4841. then pterpri()
  4842. else pprin2 c;
  4843. c := readch()
  4844. >>;
  4845. pprin2 c;
  4846. c := readch();
  4847. return c
  4848. end$
  4849. symbolic procedure procfuncoperheading(keyword,c);
  4850. % returns the word after the procedure, and the character delimiting it
  4851. begin
  4852. scalar lst, name, i, ty, args, myargs;
  4853. c:=flushspaces c;
  4854. while not(seprp c or c eq '!( or c eq '!: ) do
  4855. << name := aconc(name, c); pprin2 c; c := readch() >>;
  4856. name := intern compress name;
  4857. put('!$0, '!*pascalname!*, name);
  4858. symtabput(name,'!*type!*,keyword);
  4859. pascfuncname!*:=name;
  4860. c:=flushspaces c;
  4861. if c eq '!( then <<
  4862. i := 1;
  4863. pprin2 c;
  4864. c := readch();
  4865. while c neq '!) do
  4866. << c:=flushspacescommas c;
  4867. name := list c;
  4868. pprin2 c;
  4869. while not (seprp (c := readch()) or
  4870. c memq list('!,, '!), '!:)) do
  4871. << name := aconc(name, c); pprin2 c >>;
  4872. put(intern compress append(explode2 '!$, explode2 i),
  4873. '!*pascalname!*,
  4874. name:=intern compress name);
  4875. myargs := name . myargs;
  4876. i := add1 i;
  4877. if c eq '!: then <<
  4878. ty:=readpascaltype(c);
  4879. c:=car ty; ty:=cdr ty;
  4880. foreach n in myargs do
  4881. pasc!-symtabput(pascfuncname!*,n,ty);
  4882. args:=append(myargs,args);
  4883. myargs:=nil;
  4884. if (c eq '!;) then << pprin2 c; c:=readch() >>
  4885. >>;
  4886. c:=flushspaces c
  4887. >>;
  4888. !$!# := sub1 i;
  4889. >>
  4890. else !$!# :=0;
  4891. if c neq '!: then
  4892. << pprin2 c;
  4893. while not (((c := readch()) eq '!:) or (c eq !$eol!$)) do
  4894. pprin2 c >>;
  4895. if c eq '!: then
  4896. <<
  4897. ty := readpascaltype c;
  4898. pasc!-symtabput(name,name,cdr ty);
  4899. c:=car ty
  4900. >>;
  4901. if numberp i then
  4902. while get(name := intern compress append(explode2 '!$, explode2 i),
  4903. '!*pascalname!*) do
  4904. << remprop(name, '!*pascalname!*); i:=sub1 i >>;
  4905. lst:=nil;
  4906. c:=flushspaces c;
  4907. while liter c or digit c or c eq '!_ do
  4908. << pprin2 c; lst:=c . lst; c := readch() >>;
  4909. if lst then
  4910. lst:=intern compress reverse lst;
  4911. return lst . c
  4912. end$
  4913. symbolic procedure readpascaltype(c);
  4914. begin
  4915. scalar ty;
  4916. pprin2 c;
  4917. c := flushspaces readch();
  4918. ty := list c;
  4919. pprin2 c;
  4920. while not (seprp (c := readch()) or c memq list('!;, '!), '![ )) do
  4921. << ty := aconc(ty, c); pprin2 c >>;
  4922. ty := intern compress ty;
  4923. if ty eq 'array then return readpascalarraydeclaration(c)
  4924. else return c . list ty;
  4925. end;
  4926. symbolic procedure readpascalarraydeclaration (c);
  4927. begin
  4928. scalar lo,hi,ty;
  4929. ty:= nil;
  4930. c:=flushspaces c;
  4931. if not (c eq '![) then
  4932. gentranerr(c,nil,"invalid pascal array declaration",nil);
  4933. pprin2 c;
  4934. l: c:=flushspaces readch();
  4935. lo:= list c;
  4936. pprin2 c;
  4937. while not (seprp (c := readch()) or c eq '!.) do
  4938. << lo:=aconc(lo,c); pprin2 c >>;
  4939. lo := compress lo;
  4940. c:=flushspaces c;
  4941. if not numberp lo then lo:=intern lo;
  4942. pprin2 c;
  4943. c:=readch();
  4944. if not (c eq '!.) then
  4945. gentranerr (c,nil,".. not found in array declaration",nil);
  4946. pprin2 c;
  4947. c:=flushspaces readch();
  4948. hi:= list c;
  4949. pprin2 c;
  4950. while not (seprp (c := readch()) or c memq list('!,, '!])) do
  4951. << hi:=aconc(hi,c); pprin2 c >>;
  4952. hi := compress hi;
  4953. if not numberp hi then hi:=intern hi;
  4954. ty:= hi . ty;
  4955. pprin2 c;
  4956. c:=flushspaces c;
  4957. if c eq '!] then
  4958. << ty:= reverse ty;
  4959. c:=flushspaces readch();
  4960. if not c memq '( !o !O) then gentranerr(c,nil,"not 'of'",nil);
  4961. pprin2 c;
  4962. c:=readch();
  4963. if not c memq '( !f !F) then gentranerr(c,nil,"not 'of'",nil);
  4964. pprin2 c;
  4965. c:=readpascaltype(readch());
  4966. return car c . append(cdr c,ty) >>;
  4967. goto l;
  4968. end;
  4969. procedure procpascheader c;
  4970. begin
  4971. scalar name, i;
  4972. while seprp c and c neq !$eol!$ do
  4973. << pprin2 c; c := readch() >>;
  4974. while not(seprp c or c memq list('!{, '!;, '!()) do
  4975. << name := aconc(name, c); pprin2 c; c := readch() >>;
  4976. if c memq list(!$eol!$, '!{, '!;) then return c;
  4977. while seprp c and c neq !$eol!$ do
  4978. << pprin2 c; c := readch() >>;
  4979. if c neq '!( then return c;
  4980. name := intern compress name;
  4981. if not !*gendecs then
  4982. pasc!-symtabput(name, nil, nil);
  4983. put('!$0, '!*cname!*, name);
  4984. pprin2 c;
  4985. i := 1;
  4986. c := readch();
  4987. while c neq '!) do
  4988. << c:=flushspacescommas c;
  4989. name := list c;
  4990. pprin2 c;
  4991. while not(seprp (c := readch()) or c memq list('!,, '!))) do
  4992. << name := aconc(name, c); pprin2 c >>;
  4993. put(intern compress append(explode2 '!$, explode2 i),
  4994. '!*cname!*,
  4995. intern compress name);
  4996. i := add1 i;
  4997. c:=flushspaces c;
  4998. >>;
  4999. !$!# := sub1 i;
  5000. while get(name := intern compress append(explode2 '!$, explode2 i),
  5001. '!*cname!*) do
  5002. remprop(name, '!*cname!*);
  5003. return procpascfunction c
  5004. end$
  5005. procedure procpascfunction c;
  5006. begin
  5007. scalar block!-count;
  5008. while c neq '!{ do
  5009. if c eq '!; then
  5010. c := procactive()
  5011. else if c eq !$eol!$ then
  5012. << pterpri(); c := readch() >>
  5013. else
  5014. << pprin2 c; c := readch() >>;
  5015. pprin2 c;
  5016. block!-count := 1;
  5017. c := readch();
  5018. while block!-count > 0 do
  5019. if c eq 'begin then
  5020. << block!-count := add1 block!-count;
  5021. pprin2 c; c := readch() >>
  5022. else if c eq 'end then
  5023. << block!-count := sub1 block!-count; pprin2 c; c := readch() >>
  5024. else if c eq '!{ then
  5025. c := procpasccomm()
  5026. else if c eq '!; then
  5027. c := procactive()
  5028. else if c eq !$eol!$ then
  5029. << pterpri(); c := readch() >>
  5030. else
  5031. << pprin2 c; c := readch() >>;
  5032. return c
  5033. end$
  5034. % misc routines - JHD 15.12.87
  5035. endmodule;
  5036. module goutput; % GENTRAN Code Formatting & Printing and Error Handler
  5037. %% Author: Barbara L. Gates %%
  5038. %% December 1986 %%
  5039. % Entry Points: FormatC, FormatFort, FormatRat, GentranErr, FormatPasc
  5040. % All format routines moved to individual language modules
  5041. % JHD December 1987
  5042. symbolic$
  5043. % GENTRAN Global Variables %
  5044. global '(!*errchan!* !*outchanl!*
  5045. !*posn!* !*stdin!* !*stdout!* !$eol!$)$
  5046. !*errchan!* := nil$ %error channel number
  5047. !*posn!* := 0$ %current position on output line
  5048. %% %%
  5049. %% General Printing Functions %%
  5050. %% %%
  5051. % Pprin2 and pterpri changed by F.Kako.
  5052. % Original did not work in SLISP/370, since output must be buffered.
  5053. global '(!*pprinbuf!*);
  5054. procedure pprin2 arg;
  5055. begin
  5056. !*pprinbuf!* := arg . !*pprinbuf!*;
  5057. !*posn!* := !*posn!* + length explode2 arg;
  5058. end$
  5059. procedure pterpri;
  5060. begin
  5061. scalar ch,pbuf;
  5062. ch := wrs nil;
  5063. pbuf := reversip !*pprinbuf!*;
  5064. for each c in !*outchanl!* do
  5065. <<wrs c;
  5066. for each a in pbuf do prin2 a;
  5067. terpri()>>;
  5068. !*posn!* := 0;
  5069. !*pprinbuf!* := nil;
  5070. wrs ch
  5071. end$
  5072. %% %%
  5073. %% Error Handler %%
  5074. %% %%
  5075. %% Error & Warning Message Printing Routine %%
  5076. procedure gentranerr(msgtype, exp, msg1, msg2);
  5077. begin scalar holdich, holdoch, resp;
  5078. holdich := rds !*errchan!*;
  5079. holdoch := wrs !*errchan!*;
  5080. terpri();
  5081. if exp then prettyprint exp;
  5082. if msgtype eq 'e then
  5083. <<
  5084. rds cdr !*stdin!*;
  5085. wrs cdr !*stdout!*;
  5086. rederr msg1
  5087. >>;
  5088. prin2 "*** ";
  5089. prin2t msg1;
  5090. if msg2 then resp := yesp msg2;
  5091. wrs holdoch;
  5092. rds holdich;
  5093. if not resp then error1()
  5094. end$
  5095. %% %%
  5096. %% Misc. Functions %%
  5097. %% %%
  5098. procedure min0(n1, n2);
  5099. max(min(n1, n2), 0)$
  5100. procedure nspaces n;
  5101. % Note n is assumed > 0 here.
  5102. begin scalar s;
  5103. for i := 1:n do s := ('!! . '! . s);
  5104. return intern compress s
  5105. end$
  5106. endmodule;
  5107. end;