GENTRAN.TEX 194 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733
  1. \documentstyle[11pt,reduce]{article}
  2. \title{GENTRAN User's Manual \\ REDUCE Version}
  3. \date{}
  4. \author{Barbara L. Gates \\ RAND \\
  5. Santa Monica CA 90407-2138 USA \\[0.05in]
  6. {\em Updated for {\REDUCE} 3.4 by} \\[0.05in]
  7. Michael C. Dewar \\
  8. The University of Bath \\
  9. Email: miked@nag.co.uk}
  10. \begin{document}
  11. \maketitle
  12. \index{GENTRAN ! package} \index{GENTRAN package !}
  13. \begin{center} February 1991 \end{center}
  14. GENTRAN is an automatic code GENerator and TRANslator which runs under
  15. REDUCE and VAXIMA\index{VAXIMA}. It constructs complete numerical
  16. programs based on sets of algorithmic specifications and symbolic
  17. expressions. Formatted FORTRAN, RATFOR or C code can be generated
  18. through a series of interactive commands or under the control of a
  19. template processing routine. Large expressions can be automatically
  20. segmented into subexpressions of manageable size, and a special
  21. file-handling mechanism maintains stacks of open I/O channels to allow
  22. output to be sent to any number of files simultaneously and to
  23. facilitate recursive invocation of the whole code generation process.
  24. GENTRAN provides the flexibility necessary to handle most code
  25. generation applications. This manual describes usage of the GENTRAN
  26. package for REDUCE.
  27. \subsection*{Acknowledgements}
  28. The GENTRAN package was created at Kent State University to generate
  29. numerical code for computations in finite element analysis. I would
  30. like to thank Prof. Paul Wang for his guidance and many suggestions
  31. used in designing the original package for VAXIMA.
  32. The second version of GENTRAN was implemented at Twente University of
  33. Technology to run under REDUCE. It was designed to be interfaced with
  34. a code optimization facility created by Dr. J. A. van Hulzen. I would
  35. like to thank Dr. van Hulzen for all of his help in the implementation
  36. of GENTRAN in RLISP during a stay at his university in The
  37. Netherlands.
  38. Finally, I would like to thank Dr. Anthony Hearn of the RAND
  39. Corporation for his help in better integrating GENTRAN into the REDUCE
  40. environment.
  41. \section{INTRODUCTION}
  42. Solving a problem in science or engineering is often a two-step
  43. process. First the problem is modeled mathematically and derived
  44. symbolically to provide a set of formulas which describe how to solve
  45. the problem numerically. Next numerical programs are written based on
  46. this set of formulas to efficiently compute specific values for given
  47. sets of input. Computer algebra systems such as REDUCE
  48. provide powerful tools for use in the formula-derivation phase but
  49. only provide primitive program-coding tools. The GENTRAN
  50. package~\cite{Gates:85,Gates:85a,Gates:85b,Gates:86}
  51. has been constructed to automate the tedious,
  52. time consuming and error-prone task of writing numerical programs
  53. based on a set of symbolic expressions.
  54. \subsection{The GENTRAN Code Generator and Translator}
  55. The GENTRAN code GENeration and TRANslation package, originally
  56. implemented in Franz LISP to run under VAXIMA~\cite{Gates:84}, is now also
  57. implemented in RLISP to run under REDUCE. Although GENTRAN
  58. was originally created specifically to generate numerical
  59. code for use with an existing FORTRAN-based finite element analysis
  60. package~\cite{Wang:86,Wang:84}, it was designed
  61. to provide the flexibility required to handle most code generation
  62. applications. GENTRAN contains code generation commands, file-handling
  63. commands, mode switches, and global variables, all of which are
  64. accessible from both the algebraic and symbolic modes of REDUCE to
  65. give the user maximal control over the code generation process. Formatted
  66. \index{FORTRAN} \index{RATFOR} \index{C}
  67. FORTRAN~\cite{FORTRAN}, RATFOR~\cite{Kernighan:79}, C~\cite{Kernighan:78},
  68. or PASCAL code can be generated from algorithmic specifications,
  69. i.e., descriptions of the behaviour of the target numerical program expressed
  70. in the REDUCE programming language, and from symbolically derived expressions
  71. and formulas.
  72. In addition to arithmetic expressions and assignment statements,
  73. GENTRAN can also generate type declarations and control-flow
  74. structures. Code generation can be guided by user-supplied
  75. template file(s) to insert generated code into pre-existing program
  76. skeletons, or it can be accomplished interactively through a series
  77. of translation commands without the use of template files. Special
  78. mode switches enable the user to turn on or off specific features such as
  79. automatic segmentation of large expressions, and global variables
  80. allow the user to modify the code formatting process. Generated
  81. code can be sent to one or more files and, optionally, to
  82. the user's terminal. Stacks of open I/O channels facilitate temporary
  83. output redirection and recursive invocation of the code generation process.
  84. \subsection{Code Optimization}
  85. \index{optimization, code}
  86. A code optimizer~\cite{vanHulzen:89}, which runs under REDUCE, has
  87. been constructed to reduce the arithmetic complexity of a set of
  88. symbolic expressions (see the SCOPE package on
  89. page~\pageref{SCOPE:intro}). It optimizes them by extracting common
  90. subexpressions and assigning them to temporary variables which are
  91. inserted in their places. The optimization technique is based on
  92. mapping the expressions onto a matrix of coefficients and exponents
  93. which are searched for patterns corresponding to the common
  94. subexpressions. Due to this process the size of the expressions is
  95. often considerably reduced.
  96. GENTRAN and the Code Optimizer have been interfaced to make it
  97. possible to generate optimized numerical programs directly
  98. \index{GENTRANOPT switch} from REDUCE. Setting the switch {\tt
  99. GENTRANOPT} {\bf ON} specifies that all sequences of assignment
  100. statements are to be optimized before being converted to numerical
  101. code.
  102. \subsection{Organization of the Manual}
  103. The remainder of this manual is divided into five sections. Sections
  104. \ref{GENTRAN:inter} and \ref{GENTRAN:template} describe code
  105. generation. Section \ref{GENTRAN:inter} explains interactive code
  106. generation, the expression segmentation facility, and how temporary
  107. variables can be generated; then section \ref{GENTRAN:template}
  108. explains how code generation can be guided by a user-supplied template
  109. file. Section \ref{GENTRAN:output} describes methods of output
  110. redirection, and section \ref{GENTRAN:mod} describes user-accessible
  111. global variables and mode switches which alter the code generation
  112. process. Finally section \ref{GENTRAN:examples} presents three
  113. complete examples.
  114. \subsubsection{Typographic Conventions}
  115. The following conventions are used in the syntactic definitions of
  116. commands in this manual:
  117. \begin{itemize}
  118. \item[{-}]
  119. Command parts which must be typed exactly as shown are given in
  120. {\bf BOLD PRINT}.
  121. \item[{-}]
  122. User-supplied arguments are {\it emphasized}.
  123. \item[{-}]
  124. [ ... ] indicate optional command parts.
  125. \end{itemize}
  126. The syntax of each GENTRAN command is shown terminated with a {\bf ;}.
  127. However, either {\bf ;} or {\bf \$} can be used to terminate any
  128. command with the usual REDUCE meaning: {\bf ;} indicates that the
  129. returned value is to be printed, while {\bf \$} indicates that printing
  130. of the returned value is to be suppressed.
  131. Throughout this manual it is stated that file name arguments must be
  132. atoms. The exact type of atom (e.g., identifier or string) is
  133. system and/or site dependent. The instructions for the implementation
  134. being used should therefore be consulted.
  135. \section{Interactive Code Generation}\label{GENTRAN:inter}
  136. GENTRAN generates numerical programs based on algorithmic specifications
  137. in the REDUCE programming language and derived symbolic expressions
  138. \index{FORTRAN} \index{RATFOR} \index{PASCAL} \index{C}
  139. produced by REDUCE evaluations. FORTRAN, RATFOR, PASCAL or C code can
  140. be produced. Type declarations can be generated, and comments and
  141. other literal strings can be inserted into the generated code. In
  142. addition, large arithmetic expressions can be automatically segmented
  143. into a sequence of subexpressions of manageable size.
  144. This section explains how to select the target language, generate
  145. code, control expression segmentation, and how to generate temporary
  146. variable names.
  147. \subsection{Target Language Selection}
  148. \label{gentranlang}
  149. Before generating code, the target numerical language must be
  150. selected. GENTRAN is currently able to generate FORTRAN, RATFOR,
  151. PASCAL and C \ttindex{GENTRANLANG"!*} code. The global variable {\bf
  152. GENTRANLANG!*} determines which type of code is produced. {\bf
  153. GENTRANLANG!*} can be set in algebraic or symbolic mode. It can be
  154. set to any value, but only four atoms have special meaning: {\bf
  155. FORTRAN}, {\bf RATFOR}, {\bf PASCAL} and {\bf C}. Any other value is
  156. assumed to mean {\bf FORTRAN}. {\bf GENTRANLANG!*} is always
  157. initialized to {\bf FORTRAN}.
  158. \subsection{Translation}
  159. \label{translation}
  160. \index{GENTRAN ! command}
  161. The {\bf GENTRAN} (GENerate/TRANslate) command is used to generate
  162. numerical code and also to translate code from algorithmic
  163. specifications in the REDUCE programming language to code in the
  164. target numerical language. Section~\ref{generation} explains code
  165. {\em generation}. This section explains code {\em translation}.
  166. A substantial subset of all expressions and statements in the REDUCE
  167. programming language can be translated directly into numerical code.
  168. The {\bf GENTRAN} command takes a REDUCE expression, statement, or
  169. procedure definition, and translates it into code in the target
  170. language.
  171. \begin{describe}{Syntax:}
  172. {\bf GENTRAN} {\it stmt} [ {\bf OUT} {\it f1,f2,\dots\ ,fn} ]{\it ;}
  173. \end{describe}
  174. \begin{describe}{Arguments:}
  175. {\it stmt} is any REDUCE expression, statement (simple, compound, or
  176. group), or procedure definition that can be translated by GENTRAN into the
  177. target language\footnote{See~\ref{appa} for a complete listing of REDUCE
  178. expressions and statements that can be translated.}
  179. {\it stmt} may contain any number of calls
  180. to the special functions {\bf EVAL}, {\bf DECLARE}, and {\bf LITERAL}
  181. (see sections~\ref{translation}~--~\ref{comments}).
  182. {\it f1,f2,\dots\ ,fn } is an optional argument list containing one or more
  183. {\it f}'s, where each {\it f} is one of:
  184. \par
  185. \begin{tabular}{lll}
  186. {\it an atom} &= &an output file\\
  187. {\bf T} &= &the terminal\\
  188. {\bf NIL} &= &the current output file(s)\\
  189. \ttindex{ALL"!*} {\bf ALL!*} &= &all files currently open for output \\
  190. & & by GENTRAN (see section~\ref{GENTRAN:output})\\
  191. \end{tabular}
  192. \end{describe}
  193. \index{side effects}
  194. \begin{describe}{Side Effects:}
  195. {\bf GENTRAN} translates {\it stmt} into formatted code in the target language.
  196. If the optional part of the command is not given, generated code is simply
  197. written to the current output file. However, if it is
  198. given, then the current output file is temporarily overridden. Generated
  199. code is written to each file represented by
  200. {\it f1,f2,\dots\ ,fn} for this command only. Files which were open prior
  201. to the call to {\bf GENTRAN} will remain open after the call, and files
  202. which did not exist prior to the call will be created, opened, written to,
  203. and closed. The output stack will be exactly the same both before and
  204. after the call.
  205. \end{describe}
  206. \begin{describe}{Returned Value:}
  207. {\bf GENTRAN} returns the name(s) of the file(s) to which code was written.
  208. \end{describe}
  209. \begin{describe}{Diagnostic Messages:}
  210. \begin{verbatim}
  211. *** OUTPUT FILE ALREADY EXISTS
  212. OVERWRITE FILE? (Y/N)
  213. \end{verbatim}
  214. \begin{verbatim}
  215. ***** WRONG TYPE OF ARG
  216. \end{verbatim}
  217. exp
  218. \begin{verbatim}
  219. ***** CANNOT BE TRANSLATED
  220. \end{verbatim}
  221. \end{describe}
  222. \begin{describe}{\example\footnote{When the {\bf PERIOD} flag (default
  223. setting: ON) is turned on, all \ttindex{PERIOD}
  224. integers are automatically printed as real numbers except exponents,
  225. subscripts in subscripted variables, and index values in DO-type loops.}}
  226. \index{GENTRAN package ! example}
  227. \begin{verbatim}
  228. 1: GENTRANLANG!* := 'FORTRAN$
  229. 2: GENTRAN
  230. 2: FOR I:=1:N DO
  231. 2: V(I) := 0$
  232. DO 25001 I=1,N
  233. V(I)=0.0
  234. 25001 CONTINUE
  235. 3: GENTRANLANG!* := 'RATFOR$
  236. 4: GENTRAN
  237. 4: FOR I:=1:N DO
  238. 4: FOR J:=I+1:N DO
  239. 4: <<
  240. 4: X(J,I) := X(I,J);
  241. 4: Y(J,I) := Y(I,J)
  242. 4: >>$
  243. DO I=1,N
  244. DO J=I+1,N
  245. {
  246. X(J,I)=X(I,J)
  247. Y(J,I)=Y(I,J)
  248. }
  249. 5: GENTRANLANG!* := 'C$
  250. 6: GENTRAN
  251. 6: P := FOR I:=1:N PRODUCT I$
  252. {
  253. P=1;
  254. for (I=1;I<=N;++I)
  255. P*=I;
  256. }
  257. 7: GENTRANLANG!* := 'PASCAL$
  258. 8: GENTRAN
  259. 8: S := FOR I := 1:10 SUM V(I)$
  260. BEGIN
  261. S:=0;
  262. FOR I:=1 TO 10 DO
  263. S:=S+V(I)
  264. END;
  265. \end{verbatim}
  266. \end{describe}
  267. \index{numeric code} Translation is a convenient method of producing
  268. numerical code when the exact behaviour of the resultant code is
  269. known. It gives the REDUCE user who is familiar with the syntax of
  270. statements in the REDUCE programming language the ability to write
  271. code in a numerical programming language without knowing the exact
  272. syntactical requirements of the language. However the {\em real}
  273. power of the {\bf GENTRAN} command lies in its ability to generate
  274. code: it can produce numerical code from symbolic expressions derived
  275. in REDUCE in addition to translating statements directly. This aspect
  276. is described in section~\ref{generation}.
  277. \subsection{Precision}
  278. \label{precision}
  279. \index{precision} \index{DOUBLE switch}
  280. By default {\bf GENTRAN} generates constants and type declarations in
  281. single precision form. If the user requires double precision output
  282. then the switch {\bf DOUBLE} must be set {\bf ON}. This does the
  283. following:
  284. \begin{itemize}
  285. \item Declarations of appropriate type are converted to their double
  286. precision counterparts. In FORTRAN and RATFOR this means that objects of type
  287. {\it REAL\/} are converted to objects of type {\it DOUBLE PRECISION\/}
  288. and objects of type {\it COMPLEX\/} are converted to {\it COMPLEX*16\/}
  289. \footnote{This is not part of the ANSI FORTRAN standard. Some compilers
  290. accept {\it DOUBLE COMPLEX\/} as well as, or instead of, {\it COMPLEX*16\/},
  291. and some accept neither.}. \index{DOUBLE PRECISION} \index{COMPLEX}
  292. \index{COMPLEX*16}
  293. In C the counterpart of {\it float\/} is {\it double\/}, and of {\it int\/}
  294. is {\it long\/}. There is no complex data type and trying to translate complex
  295. objects causes an error.
  296. \item Similarly subprograms are given their correct type where appropriate.
  297. \item In FORTRAN and RATFOR {\it REAL\/} and {\it COMPLEX\/} numbers are
  298. printed with the correct double precision format.
  299. \item Intrinsic functions are converted to their double precision counterparts
  300. (e.g. in FORTRAN $SIN \rightarrow DSIN$ etc.).
  301. \end{itemize}
  302. \subsubsection{Intrinsic FORTRAN and RATFOR functions.}
  303. An attempt is made to convert the arguments of intrinsic functions to
  304. the correct type. For example:
  305. \begin{verbatim}
  306. 5: GENTRAN f:=sin(1)$
  307. F=SIN(1.0)
  308. 6: GENTRAN f:=sin(x)$
  309. F=SIN(REAL(X))
  310. 7: GENTRAN DECLARE <<x:real>>$
  311. 8: GENTRAN f:=sin(x)$
  312. F=SIN(X)
  313. \end{verbatim}
  314. Which function is used to coerce the argument may, of course, depend on the
  315. setting of the switch {\bf DOUBLE}.
  316. \subsubsection{Number of printed floating point digits.}
  317. \index{PRECISION command} \index{PRINT"!-PRECISION command}
  318. To ensure the correct number of floating point digits are
  319. generated it may be necessary to use either the {\bf PRECISION} or
  320. {\bf PRINT!-PRECISION} commands. The former alters the number of
  321. digits REDUCE calculates, the latter only the number of digits REDUCE
  322. prints. Each takes an integer argument. It is not possible to set
  323. the printed precision higher than the actual precision. Calling {\bf
  324. PRINT!-PRECISION} with a negative argument causes the printed
  325. precision to revert to the actual precision.
  326. \begin{verbatim}
  327. 1: on rounded$
  328. 2: precision 16$
  329. 3: 1/3;
  330. 0.333 33333 33333 333
  331. 4: print!-precision 6$
  332. 5: 1/3;
  333. 0.333333
  334. 6: print!-precision(-1)$
  335. 7: 1/3;
  336. 0.333 33333 33333 333
  337. \end{verbatim}
  338. \subsection{Code Generation: Evaluation Prior to Translation}
  339. \label{generation}
  340. Section~\ref{translation} showed how REDUCE statements and expressions
  341. can be translated directly into the target language. This section
  342. shows how to indicate that parts of those statements and expressions
  343. are to be handed to REDUCE to be evaluated before being translated.
  344. In other words, this section explains how to generate numerical code
  345. from algorithmic specifications (in the REDUCE programming language)
  346. and symbolic expressions. Each of the following four subsections
  347. describes a special function or operator that can be used to request
  348. partial or full evaluation of expressions prior to translation. Note
  349. that these functions and operators have the described effects {\it
  350. only} when applied to arguments to the {\bf GENTRAN} function and that
  351. evaluation is done in algebraic or symbolic mode, depending on the
  352. value of the REDUCE variable {\bf !*MODE}.\ttindex{"!*MODE}
  353. \subsubsection{The EVAL Function}
  354. \label{eval}
  355. \begin{describe}{Syntax:}
  356. {\bf EVAL} {\it exp}
  357. \end{describe} \ttindex{EVAL}
  358. \begin{describe}{Argument:}
  359. {\it exp} is any REDUCE expression or statement which, after evaluation
  360. by REDUCE, results in an expression that can be translated by
  361. GENTRAN into the target language.
  362. \end{describe}
  363. \begin{describe}{Side Effect:}
  364. When {\bf EVAL} is called on an expression which is to be translated, it
  365. tells {\bf GENTRAN} to give the expression to REDUCE
  366. for evaluation first, and then to translate the result of that evaluation.
  367. \end{describe}
  368. \begin{describe}{\example}\index{GENTRAN package ! example}
  369. The following formula, F, has been derived symbolically:
  370. \begin{verbatim}
  371. 2
  372. 2*X - 5*X + 6
  373. \end{verbatim}
  374. We wish to generate an assignment statement for the quotient
  375. of F and its derivative.
  376. \begin{verbatim}
  377. 1: GENTRAN
  378. 1: Q := EVAL(F)/EVAL(DF(F,X))$
  379. Q=(2.0*X**2-(5.0*X)+6.0)/(4.0*X-5.0)
  380. \end{verbatim}
  381. \end{describe}
  382. \subsubsection{The :=: Operator}
  383. \index{:=:}
  384. \label{rsetq} \index{GENTRAN ! preevaluation} \index{rsetq operator}
  385. In many applications, assignments must be generated in which the
  386. left-hand side is some known variable name, but the
  387. right-hand side is an expression that must be evaluated. For
  388. this reason, a special operator is provided to indicate that the expression
  389. on the right-hand side is to be evaluated prior to translation. This
  390. special operator is {\bf :=:} (i.e., the usual REDUCE assignment operator
  391. with an extra ``:'' on the right).
  392. \begin{describe}{\example} \index{GENTRAN package ! example}
  393. \begin{verbatim}
  394. 1: GENTRAN
  395. 1: DERIV :=: DF(X^4-X^3+2*x^2+1,X)$
  396. DERIV=4.0*X**3-(3.0*X**2)+4.0*X
  397. \end{verbatim}
  398. \end{describe}
  399. Each built-in operator in REDUCE has an alternative alphanumeric identifier
  400. associated with it. Similarly, the GENTRAN {\bf :=:} operator has a
  401. special identifier associated with it: {\bf RSETQ} may be used \ttindex{RSETQ}
  402. interchangeably with {\bf :=:} on input.
  403. \subsubsection{The ::= Operator}
  404. \label{lsetq}
  405. \index{matrices ! in GENTRAN}
  406. When assignments to matrix or array elements must be generated, many
  407. times the indices of the element must be evaluated first. The special operator
  408. \index{::=} \index{lsetq operator}
  409. {\bf ::=} can be used within a call to {\bf GENTRAN}
  410. to indicate that the indices of the matrix or
  411. array element on the left-hand side of the assignment are to
  412. be evaluated prior to translation. (This is the usual REDUCE
  413. assignment operator with an extra ``:'' on the left.)
  414. \begin{describe}{\example}\index{GENTRAN package ! example}
  415. We wish to generate assignments which assign zeros to all elements
  416. on the main diagonal of M, an n x n matrix.
  417. \begin{verbatim}
  418. 10: FOR j := 1 : 8 DO
  419. 10: GENTRAN
  420. 10: M(j,j) ::= 0$
  421. M(1,1)=0.0
  422. M(2,2)=0.0
  423. :
  424. :
  425. M(8,8)=0.0
  426. \end{verbatim}
  427. \end{describe}
  428. {\bf LSETQ} may be used interchangeably with {\bf ::=} on input.\ttindex{LSETQ}
  429. \subsubsection{The ::=: Operator}
  430. \label{lrsetq}
  431. \index{::=:} \index{lrsetq operator}
  432. In applications in which evaluated expressions are to be assigned to
  433. array elements with evaluated subscripts, the {\bf ::=:} operator can be
  434. used. It is a combination of the {\bf ::=} and {\bf :=:} operators described
  435. in sections~\ref{rsetq} and ~\ref{lsetq}.
  436. \index{matrices ! in GENTRAN}
  437. \newpage
  438. \begin{describe}{\example}\index{GENTRAN package ! example}
  439. The following matrix, M, has been derived symbolically:
  440. \begin{verbatim}
  441. ( A 0 -1 1)
  442. ( )
  443. ( 0 B 0 0)
  444. ( )
  445. ( -1 0 C -1)
  446. ( )
  447. ( 1 0 -1 D)
  448. \end{verbatim}
  449. We wish to generate assignment statements for those elements
  450. on the main diagonal of the matrix.
  451. \begin{verbatim}
  452. 10: FOR j := 1 : 4 DO
  453. 10: GENTRAN
  454. 10: M(j,j) ::=: M(j,j)$
  455. M(1,1)=A
  456. M(2,2)=B
  457. M(3,3)=C
  458. M(4,4)=D
  459. \end{verbatim}
  460. \end{describe}
  461. The alternative alphanumeric identifier associated with {\bf ::=:} is
  462. {\bf LRSETQ}.\ttindex{LRSETQ}
  463. \subsection{Explicit Type Declarations}
  464. \label{explicit:type}
  465. Type declarations are automatically generated each time a subprogram
  466. heading is generated. Type declarations are constructed
  467. from information stored in the GENTRAN symbol table. The user
  468. can place entries into the symbol table explicitly through calls
  469. to the special GENTRAN function {\bf DECLARE}. \index{DECLARE function}
  470. \begin{describe}{Syntax:}
  471. {\bf \ \ DECLARE} {\it v1,v2,\dots\ ,vn} {\bf :} {\it type;}
  472. or
  473. \begin{tabular}{ll}
  474. {\bf DECLARE}\\
  475. {\bf $<$$<$}\\
  476. &{\it v11,v12,\dots\ ,v1n} {\bf :} {\it type1;}\\
  477. &{\it v21,v22,\dots\ ,v2n} {\bf :} {\it type2;}\\
  478. & :\\
  479. & :\\
  480. &{\it vn1,vnn,\dots\ ,vnn} {\bf :} {\it typen;}\\
  481. {\bf $>$$>$}{\it ;}
  482. \end{tabular}
  483. \end{describe}
  484. \begin{describe}{Arguments:}
  485. Each {\it v1,v2,\dots\ ,vn} is a list of one or more variables
  486. (optionally subscripted to indicate array dimensions), or
  487. variable ranges (two letters separated by a ``-''). {\it v}'s are
  488. not evaluated unless given as arguments to {\bf EVAL}.
  489. Each {\it type} is a variable type in the target language. Each
  490. must be an atom, optionally preceded by the atom {\bf IMPLICIT}.
  491. \index{IMPLICIT option}
  492. {\it type}'s are not evaluated unless given as arguments to {\bf EVAL}.
  493. \end{describe}
  494. \begin{describe}{Side Effect:}
  495. Entries are placed in the symbol table for each variable or
  496. variable range declared in the call to this function. The function
  497. call itself is removed from the statement group being
  498. translated. Then after translation, type declarations are
  499. generated from these symbol table entries before the resulting
  500. executable statements are printed.
  501. \end{describe}
  502. \begin{describe}{Diagnostic Message:}
  503. \begin{verbatim}
  504. ***** INVALID SYNTAX
  505. \end{verbatim}
  506. \end{describe}
  507. \begin{describe}{\example}\index{GENTRAN package ! example}
  508. \begin{verbatim}
  509. 1: GENTRAN
  510. 1: <<
  511. 1: DECLARE
  512. 1: <<
  513. 1: A-H, O-Z : IMPLICIT REAL;
  514. 1: M(4,4) : INTEGER
  515. 1: >>;
  516. 1: FOR I:=1:4 DO
  517. 1: FOR J:=1:4 DO
  518. 1: IF I=J
  519. 1: THEN M(I,J):=1
  520. 1: ELSE M(I,J):=0;
  521. 1: DECLARE I, J : INTEGER;
  522. 1: >>$
  523. IMPLICIT REAL (A-H,O-Z)
  524. INTEGER M(4,4),I,J
  525. DO 25001 I=1,4
  526. DO 25002 J=1,4
  527. IF (I.EQ.J) THEN
  528. M(I,J)=1.0
  529. ELSE
  530. M(I,J)=0.0
  531. ENDIF
  532. 25002 CONTINUE
  533. 25001 CONTINUE
  534. \end{verbatim}
  535. \end{describe}
  536. The {\bf DECLARE} statement can also be used to declare subprogram types (i.e.
  537. {\bf SUBROUTINE} or {\bf FUNCTION}) for \index{SUBROUTINE} \index{FUNCTION}
  538. FORTRAN and RATFOR code, and function types for all four languages.
  539. \begin{describe}{\example}\index{GENTRAN package ! example}
  540. \begin{verbatim}
  541. 1: GENTRANLANG!* := 'RATFOR$
  542. 2: GENTRAN
  543. 2: PROCEDURE FAC N;
  544. 2: BEGIN
  545. 2: DECLARE
  546. 2: <<
  547. 2: FAC : FUNCTION;
  548. 2: FAC, N : INTEGER
  549. 2: >>;
  550. 2: F := FOR I:=1:N PRODUCT I;
  551. 2: DECLARE F, I : INTEGER;
  552. 2: RETURN F
  553. 2: END$
  554. INTEGER FUNCTION FAC(N)
  555. INTEGER N,F,I
  556. {
  557. F=1
  558. DO I=1,N
  559. F=F*I
  560. }
  561. RETURN(F)
  562. END
  563. 3: GENTRANLANG!* := 'C$
  564. 4: GENTRAN
  565. 4: PROCEDURE FAC N;
  566. 4: BEGIN
  567. 4: DECLARE FAC, N, I, F : INTEGER;
  568. 4: F := FOR I:=1:N PRODUCT I;
  569. 4: RETURN F
  570. 4: END$
  571. int FAC(N)
  572. int N;
  573. {
  574. int I,F;
  575. {
  576. F=1;
  577. for (I=1;I<=N;++I)
  578. F*=I;
  579. }
  580. return(F);
  581. }
  582. \end{verbatim}
  583. \end{describe}
  584. When generating code for subscripted variables (i.e., matrix and
  585. array elements), it is important to keep several things in mind. First
  586. of all, when a REDUCE array is declared with a declaration such as
  587. \index{ARRAY}
  588. \begin{center}
  589. {\bf ARRAY A(}{\it n}{\bf )\$}
  590. \end{center}
  591. where {\it n} is a positive integer, {\bf A} is actually being declared
  592. to be of size {\bf n}+1. Each of the elements {\bf A(0), A(1), \dots\ , A(n)}
  593. can be used. However, a FORTRAN or RATFOR declaration such as
  594. \begin{center}
  595. {\bf DIMENSION A(}{\it n}{\bf )}
  596. \end{center}
  597. declares {\bf A} only to be of size {\bf n}. Only the elements
  598. {\bf A(1), A(2), \dots\ , A(n)} can be used. Furthermore, a C declaration
  599. such as
  600. \begin{center}
  601. {\bf float A[}{\it n}{\bf ];}
  602. \end{center}
  603. declares {\bf A} to be of size {\bf n} with elements referred to as
  604. {\bf A[0], A[1], \dots\ , A[}{\it n-1}{\bf ]}.
  605. To resolve these array size and subscripting conflicts, the user should
  606. remember the following:
  607. \index{subscripts ! in GENTRAN}
  608. \begin{itemize}
  609. \item {\it All REDUCE array subscripts are translated literally.}
  610. Therefore it is the user's responsibility to be sure that array elements with
  611. subscript 0 are not translated into FORTRAN or RATFOR.
  612. \item Since C and PASCAL
  613. arrays allow elements with a subscript of 0, when an array is
  614. declared to be of size {\it n} by the user, {\it the actual generated type
  615. declaration will be of size n+1} so that the user can translate
  616. elements with subscripts from 0, and up to and including {\it n}.
  617. \end{itemize}
  618. If the user is generating C code, it is possible to produce declarations
  619. for arrays with unknown bounds:
  620. \begin{verbatim}
  621. 5: gentran declare <<x(*,*):real;y(*):integer>>$
  622. 6: gendecs nil;
  623. float X[ ][ ];
  624. int Y[ ];
  625. \end{verbatim}
  626. \subsection{Implicit Type Declarations}
  627. \label{implicit:type} \index{GETDECS switch}
  628. Some type declarations can be made automatically if the switch {\bf GETDECS}
  629. is {\bf ON}. In this case:
  630. \begin{enumerate}
  631. \item The indices of loops are automatically declared to be integers.
  632. \index{loop indices ! in GENTRAN}
  633. \item There is a global variable {\bf DEFTYPE!*}, which is the default
  634. type given to objects. Subprograms, their parameters, and local scalar
  635. objects are automatically assigned this type. \ttindex{DEFTYPE"!*}
  636. \index{REAL*8} \index{DOUBLE PRECISION}
  637. Note that types such as REAL*8 or DOUBLE PRECISION should not
  638. be used as, if {\bf DOUBLE} is on, then a default type of REAL
  639. will in fact be DOUBLE PRECISION anyway.
  640. \item If GENTRAN is used to translate a REDUCE procedure, then it assigns
  641. objects declared {\bf SCALAR} the type given by {\bf DEFTYPE!*}. Note that
  642. \index{INTEGER declaration} \index{REAL declaration}
  643. it is legal to use the commands {\bf INTEGER} and {\bf REAL} in the place
  644. of {\bf SCALAR}, which allows the user to specify an actual type. The
  645. procedure may also be given a return type, in which case that is used as
  646. the default. For example:
  647. \begin{verbatim}
  648. 2: on getdecs,gendecs$
  649. 3: GENTRAN
  650. 3: real procedure f(x);
  651. 3: begin integer n;real y;
  652. 3: n := 4;
  653. 3: y := n/(1+x)^2;
  654. 3: return y;
  655. 3: end;
  656. REAL FUNCTION F(X)
  657. INTEGER N
  658. REAL X,Y
  659. N=4
  660. Y=N/(1.0+X)**2
  661. F=Y
  662. RETURN
  663. END
  664. \end{verbatim}
  665. \end{enumerate}
  666. \subsection{More about Type Declarations}
  667. \label{more:type}
  668. A check is made on output to ensure that all types generated are legal ones.
  669. This is necessary since {\bf DEFTYPE!*} can be set to anything.
  670. Note that {\bf DEFTYPE!*} ought normally to be given a simple
  671. type as its \ttindex{DEFTYPE"!*}
  672. value, such as REAL, INTEGER, or COMPLEX,
  673. since this will always be translated into the corresponding type in the
  674. target language on output.
  675. An entry is removed from the symbol table once a declaration has been
  676. generated for it. The {\bf KEEPDECS} switch (by default {\bf OFF})
  677. disables this, allowing a user to check the types of objects
  678. \index{KEEPDECS switch} which GENTRAN has generated (useful if they
  679. are being generated automatically)
  680. \subsection{Comments and Literal Strings}
  681. \label{comments} \index{comments ! in GENTRAN}
  682. Comments and other strings of characters can be inserted directly into
  683. the stream of generated code through a call to the special function
  684. {\bf LITERAL}.
  685. \begin{describe}{Syntax:}
  686. {\bf LITERAL} {\it arg1,arg2,\dots\ ,argn;}
  687. \end{describe}
  688. \begin{describe}{Arguments:}
  689. {\it arg1,arg2,\dots\ ,argn} is an argument list containing one or more
  690. {\it arg}'s, where each {\it arg} either is, or evaluates to, an atom. The
  691. \ttindex{TAB"!*} \ttindex{CR"!*}
  692. atoms {\bf TAB!*} and {\bf CR!*} have special meanings. {\it arg}'s are
  693. not evaluated unless given as arguments to {\bf EVAL}.
  694. \end{describe}
  695. \begin{describe}{Side Effect:}
  696. This statement is replaced by the character sequence resulting from
  697. concatenation of the given atoms. Double quotes are stripped from
  698. all string type {\it arg}'s, and the reserved atoms {\bf TAB!*} and
  699. {\bf CR!*} are replaced by a tab to the current level of indentation, and
  700. an end-of-line character, respectively.
  701. \end{describe}
  702. \begin{describe}{\example}\index{GENTRAN package ! example}
  703. Suppose N has value 10.
  704. \begin{verbatim}
  705. 1: GENTRANLANG!* := 'FORTRAN$
  706. 2: GENTRAN
  707. 2: <<
  708. 2: LITERAL
  709. 2: "C",TAB!*,"--THIS IS A FORTRAN COMMENT--",CR!*,
  710. 2: "C",CR!*;
  711. 2: LITERAL
  712. 2: TAB!*,"DATA N/",EVAL(N),"/",CR!*
  713. 2: >>$
  714. C --THIS IS A FORTRAN COMMENT--
  715. C
  716. DATA N/10/
  717. 3: GENTRANLANG!* := 'RATFOR$
  718. 4: GENTRAN
  719. 4: FOR I:=1:N DO
  720. 4: <<
  721. 4: LITERAL
  722. 4: TAB!*,"# THIS IS A RATFOR COMMENT",CR!*;
  723. 4: LITERAL
  724. 4: TAB!*,"WRITE(6,10) (M(I,J),J=1,N)",CR!*,
  725. 4: 10,TAB!*,"FORMAT(1X,10(I5,3X))",CR!*
  726. 4: >>$
  727. DO I=1,N
  728. {
  729. # THIS IS A RATFOR COMMENT
  730. WRITE(6,10) (M(I,J),J=1,N)
  731. 10 FORMAT(1X,10(I5,3X))
  732. }
  733. 5: GENTRANLANG!* := 'C$
  734. 6: GENTRAN
  735. 6: <<
  736. 6: X:=0;
  737. 6: LITERAL "/* THIS IS A",CR!*,
  738. 6: " C COMMENT */",CR!*
  739. 6: >>$
  740. {
  741. X=0.0;
  742. /* THIS IS A
  743. C COMMENT */
  744. }
  745. 7: GENTRANLANG!* := 'PASCAL$
  746. 8: GENTRAN
  747. 8: <<
  748. 8: X := SIN(Y);
  749. 8: LITERAL "{ THIS IS A PASCAL COMMENT }", CR!*
  750. 8: >>$
  751. BEGIN
  752. X:=SIN(Y)
  753. { THIS IS A PASCAL COMMENT }
  754. END;
  755. \end{verbatim}
  756. \end{describe}
  757. \subsection{Expression Segmentation}
  758. \label{segmentation} \index{segmenting expressions}
  759. Symbolic derivations can easily produce formulas that can be anywhere
  760. from a few lines to several pages in length. Such formulas
  761. can be translated into numerical assignment statements, but unless they
  762. are broken into smaller pieces they may be too long for a compiler
  763. to handle. (The maximum number of continuation lines for one statement
  764. allowed by most FORTRAN compilers is only 19.) Therefore GENTRAN
  765. \index{continuation lines}
  766. contains a segmentation facility which automatically {\it segments},
  767. or breaks down unreasonably large expressions.
  768. The segmentation facility generates a sequence of assignment
  769. statements, each of which assigns a subexpression to an automatically
  770. generated temporary variable. This sequence is generated in such a
  771. way that temporary variables are re-used as soon as possible, thereby
  772. keeping the number of automatically generated variables to a minimum.
  773. The facility can be turned on or off by setting the mode
  774. \index{GENTRANSEG switch} switch {\bf GENTRANSEG} accordingly (i.e.,
  775. by calling the REDUCE function {\bf ON} or {\bf OFF} on it). The user
  776. can control the maximum allowable expression size by setting the
  777. \ttindex{MAXEXPPRINTLEN"!*}
  778. variable {\bf MAXEXPPRINTLEN!*} to the maximum number of characters
  779. allowed in an expression printed in the target language (excluding
  780. spaces automatically printed by the formatter). The {\bf GENTRANSEG}
  781. switch is on initially, and {\bf MAXEXPPRINTLEN!*} is initialized to
  782. 800.
  783. \begin{describe}{\example}\index{GENTRAN package ! example}
  784. \begin{verbatim}
  785. 1: ON EXP$
  786. 2: JUNK1 := (A+B+C+D)^2$
  787. 3: MAXEXPPRINTLEN!* := 24$
  788. 4: GENTRAN VAL :=: JUNK1$
  789. T0=A**2+2.0*A*B
  790. T0=T0+2.0*A*C+2.0*A*D
  791. T0=T0+B**2+2.0*B*C
  792. T0=T0+2.0*B*D+C**2
  793. VAL=T0+2.0*C*D+D**2
  794. 5: JUNK2 := JUNK1/(E+F+G)$
  795. 6: MAXEXPPRINTLEN!* := 23$
  796. 7: GENTRANLANG!* := 'C$
  797. 8: GENTRAN VAL :=: JUNK2$
  798. {
  799. T0=power(A,2)+2.0*A*B;
  800. T0+=2.0*A*C;
  801. T0=T0+2.0*A*D+power(B,2);
  802. T0+=2.0*B*C;
  803. T0=T0+2.0*B*D+power(C,2);
  804. T0=T0+2.0*C*D+power(D,2);
  805. VAL=T0/(exp(1.0)+F+G);
  806. }
  807. \end{verbatim}
  808. \end{describe}
  809. \subsubsection{Implicit Type Declarations}\label{GENTRAN:itd}
  810. When the segmentation routine generates temporary variables, it places
  811. type declarations in the symbol table for those variables if
  812. possible. It uses the following rules to determine their type:
  813. \index{implicit type declarations} \index{temporary variables ! type}
  814. \begin{itemize}
  815. \item[{(1)}]
  816. If the type of the variable to which the large expression is being
  817. assigned is already known (i.e., has been declared by the user),
  818. then the temporary variables will be declared to be of that same type.
  819. \item[{(2)}] \ttindex{TEMPVARTYPE"!*}
  820. If the global variable {\bf TEMPVARTYPE!*} has a non-NIL value, then the
  821. temporary variables are declared to be of that type.
  822. \item[{(3)}]
  823. Otherwise, the variables are not declared.
  824. \end{itemize}
  825. \newpage
  826. \begin{describe}{\example} \index{GENTRAN package ! example}
  827. \begin{verbatim}
  828. 1: MAXEXPPRINTLEN!* := 20$
  829. 2: TEMPVARTYPE!* := 'REAL$
  830. 3: GENTRAN
  831. 3: <<
  832. 3: DECLARE ISUM : INTEGER;
  833. 3: ISUM := II+JJ+2*KK+LL+10*MM+NN;
  834. 3: PROD := V(X,Y)*SIN(X)*COS(Y^2)*(X+Y+Z^2)
  835. 3: >>$
  836. INTEGER ISUM,T0
  837. REAL T1
  838. T0=II+JJ+2.0*KK+LL
  839. ISUM=T0+10.0*MM+NN
  840. T1=V(X,Y)*SIN(X)*COS(Y**2)
  841. PROD=T1*(X+Y+Z**2)
  842. \end{verbatim}
  843. \end{describe}
  844. \subsection{Generation of Temporary Variable Names}
  845. \label{tempvars} \index{temporary variables ! names}
  846. As we have just seen, GENTRAN's segmentation module generates
  847. temporary variables and places type declarations in the symbol table
  848. for them whenever possible. Various other modules also generate
  849. variables and corresponding declarations. All of these modules call
  850. one special GENTRAN function each time they need a temporary
  851. variable name. This function is {\bf TEMPVAR}. There are situations
  852. in which it may be convenient for the user to be able to generate
  853. temporary variable names directly.\footnote{One such example is suppression
  854. of the simplification process to generate numerical code which is more
  855. efficient. See the example in section~\ref{tempvar:example} on
  856. page~\pageref{tempvar:example}.}
  857. Therefore {\bf TEMPVAR} \ttindex{TEMPVAR}
  858. is a user-accessible function which may be called from both
  859. the algebraic and symbolic modes of REDUCE.
  860. \begin{describe}{Syntax:}
  861. {\bf TEMPVAR} {\it type}
  862. \end{describe}
  863. \begin{describe}{Argument:}
  864. {\it type} is an atom which either indicates the variable type in the
  865. target language (INTEGER, REAL, etc.), or is {\bf NIL} if the variable
  866. type is unknown.
  867. \end{describe}
  868. \begin{describe}{Side Effects:}
  869. {\bf TEMPVAR} creates temporary variable names by repeatedly concatenating
  870. the values of the global variables {\bf TEMPVARNAME!*} (which has a
  871. \ttindex{TEMPVARNUM"!*}
  872. default value of {\bf T}) and {\bf TEMPVARNUM!*} (which is initially set
  873. to 0) and incrementing {\bf TEMPVARNUM!*} until a variable name is created
  874. which satisfies one of the following conditions:
  875. \begin{itemize}
  876. \item[{(1)}]
  877. It was not generated previously, and it has not been declared by the user.
  878. \item[{(2)}]
  879. It was previously generated to hold the same type of value that it
  880. must hold this time (e.g. INTEGER, REAL, etc.), and the value assigned
  881. to it previously is no longer needed.
  882. \end{itemize}
  883. If {\it type} is a non-NIL argument, or if {\it type} is {\bf NIL}
  884. and the global variable {\bf TEMPVARTYPE!*} (initially NIL) has been
  885. \ttindex{TEMPVARTYPE"!*}
  886. set to a non-NIL value, then a type entry for the generated variable name
  887. is placed in the symbol table.
  888. \end{describe}
  889. \begin{describe}{Returned Value:}
  890. {\bf TEMPVAR} returns an atom which can be used as a variable.
  891. \end{describe}
  892. Note: It is the user's responsibility to set {\bf TEMPVARNAME!*} and
  893. {\bf TEMPVARNUM!*} to values such that generated variable
  894. names will not clash with variables used elsewhere in the
  895. program unless those variables have been declared.
  896. \subsubsection{Marking Temporary Variables}
  897. In section~\ref{tempvars} we saw that a temporary variable name (of a certain
  898. type) can be regenerated when the value previously assigned to it
  899. is no longer needed. This section describes a function which {\it marks}
  900. a variable to indicate that it currently holds a
  901. significant value, and the next section describes functions which
  902. {\it unmark} variables to indicate that the values they hold are no
  903. \index{temporary variables ! marking}
  904. \index{marking temporary variables}
  905. longer significant.\ttindex{MARKVAR}
  906. \begin{describe}{Syntax:}
  907. {\bf MARKVAR} {\it var}
  908. \end{describe}
  909. \begin{describe}{Argument:}
  910. {\it var} is an atom.
  911. \end{describe}
  912. \begin{describe}{Side Effects:}
  913. {\bf MARKVAR} sets a flag on {\it var}'s property list to indicate that
  914. {\it var} currently holds a significant value.
  915. \end{describe}
  916. \begin{describe}{Returned Value:}
  917. {\bf MARKVAR} returns {\it var}.
  918. \end{describe}
  919. \begin{describe}{\example}\index{GENTRAN package ! example}
  920. The following matrix, M has been derived symbolically:
  921. \begin{verbatim}
  922. (X*(Y+Z) 0 X*Z)
  923. ( )
  924. ( -X X+Y 0)
  925. ( )
  926. ( X*Z 0 Z**2)
  927. \end{verbatim}
  928. We wish to replace each non-zero element by a generated variable name
  929. to prevent these expressions from being resubstituted into further
  930. calculations. (We will also record these substitutions in the
  931. numerical program we are constructing by generating assignment
  932. statements.)\footnote{ Note: {\bf MARKVAR} is a symbolic mode
  933. procedure. Therefore, the name of each variable whose value is to be
  934. passed to it from algebraic mode must appear in a {\bf SHARE}
  935. \index{SHARE command} declaration. This tells REDUCE to share the
  936. variable's value between algebraic and symbolic modes.}
  937. \begin{verbatim}
  938. 9: SHARE var$
  939. 10: FOR j := 1 : 3 DO
  940. 10: FOR k := 1 : 3 DO
  941. 10: IF M(j,k) NEQ 0 THEN
  942. 10: <<
  943. 10: var := TEMPVAR(NIL);
  944. 10: MARKVAR var;
  945. 10: GENTRAN
  946. 10: EVAL(var) :=: M(j,k);
  947. 10: M(j,k) := var
  948. 10: >>$
  949. T0=X*(Y+Z)
  950. T1=X*Z
  951. T2=-X
  952. T3=X+Y
  953. T4=X*Z
  954. T5=Z**2
  955. \end{verbatim}
  956. Now matrix M contains the following entries:
  957. \begin{verbatim}
  958. (T0 0 T1)
  959. ( )
  960. (T2 T3 0)
  961. ( )
  962. (T4 0 T5)
  963. \end{verbatim}
  964. \end{describe}
  965. \subsubsection{Unmarking Temporary Variables}
  966. \index{unmarking temporary variables} \index{temporary variables ! unmarking}
  967. After the value assigned to a temporary variable has been used
  968. in the numerical program and is no longer needed, the variable name can be \
  969. \ttindex{UNMARKVAR}
  970. {\it unmarked} with the {\bf UNMARKVAR} function.
  971. \begin{describe}{Syntax:}
  972. {\bf UNMARKVAR} {\it var;}
  973. \end{describe}
  974. \begin{describe}{Argument:}
  975. {\it var} is an atom (variable name) or an expression containing one or more
  976. variable names.
  977. \end{describe}
  978. \begin{describe}{Side Effect:}
  979. {\bf UNMARKVAR} resets flags on the property lists of all variable names in
  980. {\it var} to indicate that they do not hold significant values any longer.
  981. \end{describe}
  982. \subsection{Enabling and Disabling Generation of Type Declarations}
  983. \label{control:type}
  984. GENTRAN maintains a symbol table of variable type and dimension
  985. information. It adds information to the symbol table by processing
  986. user-supplied calls to the {\bf DECLARE} function (see
  987. Section~\ref{explicit:type}) and as a
  988. side effect of generating temporary variable names
  989. (see Sections~\ref{segmentation} and \ref{tempvars}).
  990. All information is stored in the symbol table until GENTRAN is ready
  991. to print formatted numerical code. Since programming languages such as
  992. FORTRAN require that type declarations appear before executable statements,
  993. GENTRAN automatically extracts all relevant type information and prints it
  994. in the form of type declarations before printing executable
  995. statements. This feature is useful when the entire body of a (sub)program is
  996. generated at one time: in this case, type declarations are printed
  997. before any executable code. However, if the user chooses to generate code
  998. in pieces, the resulting code may have type declarations interleaved
  999. \index{GENDECS switch}
  1000. with executable code. For this reason, the user may turn the {\bf GENDECS}
  1001. mode switch on or off, depending on whether or not s/he chooses to use
  1002. this feature.
  1003. In the following we re-examine the example of Section~\ref{GENTRAN:itd}.
  1004. \begin{describe}{\example}\index{GENTRAN package ! example}
  1005. \begin{verbatim}
  1006. 1: MAXEXPPRINTLEN!* := 20$
  1007. 2: TEMPVARTYPE!* := 'REAL!*8$
  1008. 3: GENTRAN
  1009. 3: <<
  1010. 3: DECLARE ISUM : INTEGER;
  1011. 3: ISUM := II+JJ+2*KK+LL+10*MM+NN
  1012. 3: >>$
  1013. INTEGER ISUM,T0
  1014. T0=II+JJ+2*KK+LL
  1015. ISUM=T0+10*MM+NN
  1016. 4: GENTRAN PROD := V(X,Y)*SIN(X)*COS(Y^2)*(X+Y+Z^2)$
  1017. REAL*8 T2
  1018. T2=V(X,Y)*SIN(REAL(X))*COS(REAL(Y**2))
  1019. PROD=T2*(X+Y+Z**2)
  1020. 5: OFF GENDECS$
  1021. 6: GENTRAN
  1022. 6: <<
  1023. 6: DECLARE ISUM : INTEGER;
  1024. 6: ISUM := II+JJ+2*KK+LL+10*MM+NN
  1025. 6: >>$
  1026. T0=II+JJ+2*KK+LL
  1027. ISUM=T0+10*MM+NN
  1028. 7: GENTRAN PROD := V(X,Y)*SIN(X)*COS(Y^2)*(X+Y+Z^2)$
  1029. T2=V(X,Y)*SIN(REAL(X))*COS(REAL(Y**2))
  1030. PROD=T2*(X+Y+Z**2)
  1031. \end{verbatim}
  1032. \end{describe}
  1033. In Section~\ref{template:type} we will explain how to further control
  1034. the generation of type declarations.
  1035. \subsection{Complex Numbers}
  1036. \label{complex} \index{complex numbers} \index{COMPLEX}
  1037. With the switch {\bf COMPLEX} set {\bf ON}, GENTRAN will generate the
  1038. correct representation for a complex number in the given precision
  1039. provided that:
  1040. \begin{enumerate}
  1041. \item The current language supports a complex data type (if it doesn't then
  1042. an error results);
  1043. \item The complex quantity is evaluated by REDUCE
  1044. to give an object of the correct
  1045. domain; i.e.
  1046. \begin{verbatim}
  1047. GENTRAN x:=: 1+i;
  1048. GENTRAN x:= eval 1+i;
  1049. z := 1+i;
  1050. GENTRAN x:=: z;
  1051. \end{verbatim}
  1052. will all generate the correct result, as will their Symbolic mode equivalents,
  1053. while:
  1054. \begin{verbatim}
  1055. GENTRAN x := 1+i;
  1056. \end{verbatim}
  1057. will not.
  1058. \end{enumerate}
  1059. \subsection{Intrinsic Functions}
  1060. \label{intrinsic} \index{intrinsic functions}
  1061. A warning is issued if a standard REDUCE function is encountered which
  1062. does not have an intrinsic counterpart in the target language (e.g.
  1063. {\it cot\/},
  1064. {\it sec\/} etc.).
  1065. Output is not halted in case this is a user--supplied function, either via
  1066. a REDUCE definition or within a GENTRAN template.
  1067. The types of intrinsic FORTRAN functions are coerced to reals (in the correct
  1068. precision) as the following examples demonstrate:
  1069. \begin{verbatim}
  1070. 19: GENTRAN x:=sin(0)$
  1071. X=SIN(0.0)
  1072. 20: GENTRAN x:=cos(A)$
  1073. X=COS(REAL(A))
  1074. 21: ON DOUBLE$
  1075. 22: GENTRAN x := log(1)$
  1076. X=DLOG(1.0D0)
  1077. 23: GENTRAN x := exp(B)$
  1078. X=DEXP(DBLE(B))
  1079. 24: GENTRAN DECLARE <<b:real>>$
  1080. 25: GENTRAN x := exp(B)$
  1081. X=DEXP(B)
  1082. \end{verbatim}
  1083. \subsection{Miscellaneous}
  1084. \subsubsection{MAKECALLS}
  1085. A statement like:
  1086. \begin{verbatim}
  1087. GENTRAN x^2+1$
  1088. \end{verbatim}
  1089. will yield the result:
  1090. \begin{verbatim}
  1091. X**2+1
  1092. \end{verbatim}
  1093. but, under normal circumstances, a statement like:
  1094. \begin{verbatim}
  1095. GENTRAN sin(x)$
  1096. \end{verbatim}
  1097. will yield the result:
  1098. \begin{verbatim}
  1099. CALL SIN(X)
  1100. \end{verbatim}
  1101. \index{MAKECALLS switch}
  1102. The switch {\bf MAKECALLS} (OFF by default) will make GENTRAN yield
  1103. \begin{verbatim}
  1104. SIN(X)
  1105. \end{verbatim}
  1106. This is useful if you don't know in advance what the form of the expression
  1107. which you are translating is going to be.
  1108. \subsubsection{E}
  1109. \index{e} \index{EXP}
  1110. When GENTRAN encounters $e$ it translates it into EXP(1), and when GENTRAN
  1111. encounters
  1112. $e^x$ it is translated to EXP(X). This is then translated
  1113. into the correct statement in the given language and precision. Note that
  1114. it is still possible to do something like:
  1115. \begin{verbatim}
  1116. GENTRAN e:=:e;
  1117. \end{verbatim}
  1118. and get the correct result.
  1119. \subsection{Booleans}
  1120. \index{booleans} \index{true} \index{false}
  1121. Some languages, like Fortran-77, have a boolean data type. Others, like
  1122. C, do not. When translating Reduce code into a language with a boolean
  1123. data type, GENTRAN will recognise the special identifiers $true$ and
  1124. $false$. For example:
  1125. \begin{verbatim}
  1126. 3: gentran <<declare t:logical ;t:=true>>;
  1127. LOGICAL T
  1128. T=.TRUE.
  1129. \end{verbatim}
  1130. \section{Template Processing}\label{GENTRAN:template}
  1131. \index{GENTRAN ! templates} \index{templates !} \index{code templates}
  1132. In some code generation applications pieces of the target numerical
  1133. program are known in advance. A {\it template} file containing a
  1134. program outline is supplied by the user, and formulas are derived in
  1135. REDUCE, converted to numerical code, and inserted in the corresponding
  1136. places in the program outline to form a complete numerical program. A
  1137. template processor is provided by GENTRAN for use in these
  1138. applications.
  1139. \subsection{The Template Processing Command}
  1140. \label{templates} \index{GENTRANIN command}
  1141. \begin{describe}{Syntax:}
  1142. {\bf GENTRANIN} {\it f1,f2,\dots\ ,fm} [{\bf OUT} {\it f1,f2,\dots\
  1143. ,fn\/}]{\it ;}
  1144. \end{describe}
  1145. \begin{describe}{Arguments:}
  1146. {\it f1,f2,\dots\ ,fm\/} is an argument list containing one or more
  1147. {\it f\/}'s,
  1148. where each {\it f\/} is one of:
  1149. \begin{center}
  1150. \begin{tabular}{lll}
  1151. {\it an atom}& = &a template (input) file\\
  1152. {\bf T}& = &the terminal\\
  1153. \end{tabular}
  1154. \end{center}
  1155. {\it f1,f2,\dots\ ,fn\/} is an optional argument list containing one or more
  1156. {\it f\/}'s, where each {\it f\/} is one of:
  1157. \begin{center}
  1158. \begin{tabular}{lll}
  1159. {\it an atom}& = &an output file\\
  1160. {\bf T}& = &the terminal\\
  1161. {\bf NIL}& = &the current output file(s)\\
  1162. {\bf ALL!*}& = &all files currently open for output \\
  1163. & & by GENTRAN (see section~\ref{GENTRAN:output}) \\
  1164. \end{tabular}
  1165. \end{center}
  1166. \end{describe}
  1167. \begin{describe}{Side Effects:}
  1168. {\bf GENTRANIN} processes each template file {\it f1,f2,\dots\ ,fm}
  1169. sequentially.
  1170. A template file may contain any number of parts, each of which
  1171. is either an active or an inactive part. All active parts start with
  1172. the character sequence {\bf ;BEGIN;} and end with {\bf ;END;}. The end
  1173. of the template file is indicated by an extra {\bf ;END;} character
  1174. sequence. \index{;BEGIN; marker} \index{;END; marker}
  1175. Inactive parts of template files are assumed to contain code in the
  1176. target language (FORTRAN, RATFOR, PASCAL or C, depending on the value
  1177. \ttindex{GENTRANLANG"!*}
  1178. of the global variable {\bf GENTRANLANG!*}). All inactive parts are
  1179. copied to the output. Comments delimited by the appropriate characters,
  1180. \index{comments ! in GENTRAN}
  1181. \begin{center}
  1182. \begin{tabular}{lll}
  1183. &{\bf C} \dots\ $<$cr$>$ & FORTRAN (beginning in column 1)\\
  1184. &{\bf \#} \dots\ $<$cr$>$ & RATFOR \\
  1185. &{\bf /*} \dots\ {\bf */} & C \\
  1186. &{\bf \{} \dots\ {\bf \}} or {\bf *(} \dots\ {\bf )*} & PASCAL\\
  1187. \end{tabular}
  1188. \end{center}
  1189. are also copied in their entirety to the output. Thus the character
  1190. sequences {\bf ;BEGIN;} and {\bf ;END;} have no special meanings
  1191. within comments.
  1192. Active parts may contain any number of REDUCE expressions, statements,
  1193. and commands. They are not copied directly to the output. Instead,
  1194. they are given to REDUCE for evaluation in algebraic mode\footnote{
  1195. Active parts are evaluated in algebraic mode unless the mode is
  1196. explicitly changed to symbolic from within the active part itself.
  1197. This is true no matter which mode the system was in when the template
  1198. processor was called.}. All output generated by each evaluation is
  1199. sent to the output file(s). Returned values are only printed on the
  1200. terminal.\index{GENTRAN ! preevaluation}
  1201. Active parts will most likely contain calls to {\bf GENTRAN} to
  1202. generate code. This means that the result of processing a
  1203. template file will be the original template file with all active
  1204. parts replaced by generated code.
  1205. If {\bf OUT} {\it f1,f2,\dots\ ,fn} is not given, generated code is simply
  1206. written to the current-output file.
  1207. However, if {\bf OUT} {\it f1,f2,\dots\ ,fn}
  1208. is given, then the current-output file
  1209. is temporarily overridden. Generated code is written to each file represented
  1210. by {\it f1,f2,\dots\ ,fn} for this command only. Files which were
  1211. open prior to the call to {\bf GENTRANIN} will remain open after the
  1212. call, and files which did not exist prior to the call will be
  1213. created, opened, written to, and closed. The output-stack will be
  1214. exactly the same both before and after the call.
  1215. \end{describe}
  1216. \begin{describe}{Returned Value:}
  1217. {\bf GENTRANIN} returns the names of all files written to by this
  1218. command.
  1219. \end{describe}
  1220. \begin{describe}{Diagnostic Messages:}
  1221. \begin{verbatim}
  1222. *** OUTPUT FILE ALREADY EXISTS
  1223. OVERWRITE FILE? (Y/N)
  1224. ***** NONEXISTENT INPUT FILE
  1225. ***** TEMPLATE FILE ALREADY OPEN FOR INPUT
  1226. ***** WRONG TYPE OF ARG
  1227. \end{verbatim}
  1228. \end{describe}
  1229. \begin{describe}{\example}\index{GENTRAN package ! example}
  1230. Suppose we wish to generate a FORTRAN subprogram to compute the
  1231. determinant of a 3 x 3 matrix. We can construct a template
  1232. file with an outline of the FORTRAN subprogram and REDUCE and
  1233. GENTRAN commands to fill it in:
  1234. \index{matrices ! in GENTRAN}
  1235. Contents of file {\tt det.tem}:
  1236. \end{describe}
  1237. \begin{framedverbatim}
  1238. REAL FUNCTION DET(M)
  1239. REAL M(3,3)
  1240. ;BEGIN;
  1241. OPERATOR M$
  1242. MATRIX MM(3,3)$
  1243. MM := MAT( (M(1,1),M(1,2),M(1,3)),
  1244. (M(2,1),M(2,2),M(2,3)),
  1245. (M(3,1),M(3,2),M(3,3)) )$
  1246. GENTRAN DET :=: DET(MM)$
  1247. ;END;
  1248. RETURN
  1249. END
  1250. ;END;
  1251. \end{framedverbatim}
  1252. \begin{describe}{}
  1253. Now we can generate a FORTRAN subprogram with the following
  1254. REDUCE session:
  1255. \begin{verbatim}
  1256. 1: GENTRANLANG!* := 'FORTRAN$
  1257. 2: GENTRANIN
  1258. 2: "det.tem"
  1259. 2: OUT "det.f"$
  1260. \end{verbatim}
  1261. Contents of file det.f:
  1262. \end{describe}
  1263. \begin{framedverbatim}
  1264. REAL FUNCTION DET(M)
  1265. REAL M(3,3)
  1266. DET=M(3,3)*M(2,2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)
  1267. . *M(2,3)*M(1,1))+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1
  1268. . ,2)-(M(3,1)*M(2,2)*M(1,3))
  1269. RETURN
  1270. END
  1271. \end{framedverbatim}
  1272. \subsection{Copying Files into Template Files}
  1273. \label{copy:template}
  1274. \index{GENTRANIN command} \index{files ! in GENTRAN}
  1275. Template files can be copied into other template files with recursive
  1276. calls to {\bf GENTRANIN} ; i.e., by calling {\bf GENTRANIN} from the
  1277. active part of a template file.
  1278. For example, suppose we wish to copy the contents of a file containing
  1279. a subprogram into a file containing a main program. We will call
  1280. {\bf GENTRANIN} to do the copying, so the subprogram file must
  1281. have {\bf ;END;} on its last line:
  1282. Contents of file {\tt det.tem}:
  1283. \begin{framedverbatim}
  1284. REAL FUNCTION DET(M)
  1285. REAL M(3,3)
  1286. DET=M(3,3)*M(2,2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)
  1287. . *M(2,3)*M(1,1))+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1
  1288. . ,2)-(M(3,1)*M(2,2)*M(1,3))
  1289. RETURN
  1290. END
  1291. ;END;
  1292. \end{framedverbatim}
  1293. Now the template file for the main program can be constructed
  1294. with an active part which will include file det.tem:
  1295. Contents of file {\tt main.tem}:
  1296. \begin{framedverbatim}
  1297. C
  1298. C MAIN PROGRAM
  1299. C
  1300. REAL M(3,3),DET
  1301. WRITE(6,*) 'ENTER 3 x 3 MATRIX'
  1302. DO 100 I=1,3
  1303. READ(5,*) (M(I,J),J=1,3)
  1304. 100 CONTINUE
  1305. WRITE(6,*) ' DET = ', DET(M)
  1306. STOP
  1307. END
  1308. C
  1309. C DETERMINANT CALCULATION
  1310. C
  1311. ;BEGIN;
  1312. GENTRANIN "det.tem"$
  1313. ;END;
  1314. ;END;
  1315. \end{framedverbatim}
  1316. The following REDUCE session will create the file {\tt main.f}:
  1317. \begin{verbatim}
  1318. 1: GENTRANIN
  1319. 1: "main.tem"
  1320. 1: OUT "main.f"$
  1321. \end{verbatim}
  1322. Contents of file {\tt main.f}:
  1323. \begin{framedverbatim}
  1324. C
  1325. C MAIN PROGRAM
  1326. C
  1327. REAL M(3,3),DET
  1328. WRITE(6,*) 'ENTER 3 x 3 MATRIX'
  1329. DO 100 I=1,3
  1330. READ(5,*) (M(I,J),J=1,3)
  1331. 100 CONTINUE
  1332. WRITE(6,*) ' DET = ', DET(M)
  1333. STOP
  1334. END
  1335. C
  1336. C DETERMINANT CALCULATION
  1337. C
  1338. REAL FUNCTION DET(M)
  1339. REAL M(3,3)
  1340. DET=M(3,3)*M(2,2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)
  1341. . *M(2,3)*M(1,1))+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*
  1342. . M(1,2)-(M(3,1)*M(2,2)*M(1,3))
  1343. RETURN
  1344. END
  1345. \end{framedverbatim}
  1346. \subsection{The Template File Stack}
  1347. \label{template:stack}
  1348. \index{templates ! file stack}
  1349. The REDUCE {\bf IN} command takes one or more file names as
  1350. arguments. REDUCE reads each of the given files and executes all
  1351. statements and commands, any of which may be another {\bf IN}
  1352. command. A stack of input file names is maintained by
  1353. REDUCE to allow recursive invocation of the {\bf IN} command. Similarly,
  1354. a stack of template file names is maintained by GENTRAN to facilitate
  1355. recursive invocation of the template processor. Section~\ref{copy:template}
  1356. showed that the {\bf GENTRANIN} command can be
  1357. \index{GENTRANIN command}
  1358. called recursively to copy files into other files. This section shows
  1359. that template files which are copied into other template files can also
  1360. contain active parts, and thus the whole code generation process can
  1361. be invoked recursively.
  1362. We can generalize the example of section~\ref{copy:template} by
  1363. generating code recursively. We can extend it to generate code which
  1364. will compute entries of the inverse matrix, also. Suppose
  1365. we have created the file init.red, which contains REDUCE commands to
  1366. create an {\it n}x{\it n} matrix MM and initialize its entries
  1367. to M(1,1), M(1,2),~\dots~, M({\it n}, {\it n}), for some user-entered
  1368. value of {\it n}:
  1369. Contents of file {\tt init.red}:
  1370. \begin{framedverbatim}
  1371. OPERATOR M$
  1372. MATRIX MM(n,n)$
  1373. FOR J := 1 : n DO
  1374. FOR K := 1 : n DO
  1375. MM(J,K) := M(J,K)$
  1376. END$
  1377. \end{framedverbatim}
  1378. We have also created template files {\tt det.tem} and {\tt inv.tem} which
  1379. contain outlines of FORTRAN subprograms to compute the
  1380. determinant and inverse of an {\it n}x{\it n} matrix, respectively:
  1381. Contents of file {\tt det.tem}:
  1382. \begin{framedverbatim}
  1383. REAL FUNCTION DET(M)
  1384. ;BEGIN;
  1385. GENTRAN
  1386. <<
  1387. DECLARE M(EVAL(n),EVAL(n)) : REAL;
  1388. DET :=: DET(MM)
  1389. >>$
  1390. ;END;
  1391. RETURN
  1392. END
  1393. ;END;
  1394. \end{framedverbatim}
  1395. Contents of file {\tt inv.tem}:
  1396. \begin{framedverbatim}
  1397. SUBROUTINE INV(M,MINV)
  1398. ;BEGIN;
  1399. GENTRAN
  1400. <<
  1401. DECLARE M(EVAL(n),EVAL(n)),
  1402. MINV(EVAL(n),EVAL(n)) : REAL;
  1403. MINV :=: MM^(-1)
  1404. >>$
  1405. ;END;
  1406. RETURN
  1407. END
  1408. ;END;
  1409. \end{framedverbatim}
  1410. Now we can construct a template file with a generalized version of the main
  1411. program given in section~\ref{copy:template}
  1412. and can place {\bf GENTRANIN} commands
  1413. in this file to generate code recursively from the template files det.tem
  1414. and inv.tem:
  1415. Contents of file {\tt main.tem}:
  1416. \begin{framedverbatim}
  1417. C
  1418. C MAIN PROGRAM
  1419. C
  1420. ;BEGIN;
  1421. GENTRAN
  1422. <<
  1423. DECLARE
  1424. <<
  1425. M(EVAL(n),EVAL(n)),
  1426. DET,
  1427. MINV(EVAL(n),EVAL(n)) : REAL;
  1428. N : INTEGER
  1429. >>;
  1430. LITERAL TAB!*, "DATA N/", EVAL(n), "/", CR!*
  1431. >>$
  1432. ;END;
  1433. WRITE(6,*) 'ENTER ', N, 'x', N, ' MATRIX'
  1434. DO 100 I=1,N
  1435. READ(5,*) (M(I,J),J=1,N)
  1436. 100 CONTINUE
  1437. WRITE(6,*) ' DET = ', DET(M)
  1438. WRITE(6,*) ' INVERSE MATRIX:'
  1439. CALL INV(M,MINV)
  1440. DO 200 I=1,N
  1441. WRITE(6,*) (MINV(I,J),J=1,N)
  1442. 200 CONTINUE
  1443. STOP
  1444. END
  1445. C
  1446. C DETERMINANT CALCULATION
  1447. C
  1448. ;BEGIN;
  1449. GENTRANIN "det.tem"$
  1450. ;END;
  1451. C
  1452. C INVERSE CALCULATION
  1453. C
  1454. ;BEGIN;
  1455. GENTRANIN "inv.tem"$
  1456. ;END;
  1457. ;END;
  1458. \end{framedverbatim}
  1459. The following REDUCE session will create the file {\tt main.f}:
  1460. \begin{verbatim}
  1461. 1: n := 3$
  1462. 2: IN "init.red"$
  1463. 3: GENTRANLANG!* := 'FORTRAN$
  1464. 4: GENTRANIN
  1465. 4: "main.tem"
  1466. 4: OUT "main.f"$
  1467. \end{verbatim}
  1468. Contents of file {\tt main.f}:
  1469. \begin{framedverbatim}
  1470. C
  1471. C MAIN PROGRAM
  1472. C
  1473. REAL M(3,3),DET,MINV(3,3)
  1474. INTEGER N
  1475. DATA N/3/
  1476. WRITE(6,*) 'ENTER ', N, 'x', N, ' MATRIX'
  1477. DO 100 I=1,N
  1478. READ(5,*) (M(I,J),J=1,N)
  1479. 100 CONTINUE
  1480. WRITE(6,*) ' DET = ', DET(M)
  1481. WRITE(6,*) ' INVERSE MATRIX:'
  1482. CALL INV(M,MINV)
  1483. DO 200 I=1,N
  1484. WRITE(6,*) (MINV(I,J),J=1,N)
  1485. 200 CONTINUE
  1486. STOP
  1487. END
  1488. C
  1489. C DETERMINANT CALCULATION
  1490. C
  1491. REAL FUNCTION DET(M)
  1492. REAL M(3,3)
  1493. DET=M(3,3)*M(2,2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)
  1494. . *M(2,3)*M(1,1))+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)
  1495. . *M(1,2)-(M(3,1)*M(2,2)*M(1,3))
  1496. RETURN
  1497. END
  1498. C
  1499. C INVERSE CALCULATION
  1500. C
  1501. SUBROUTINE INV(M,MINV)
  1502. REAL M(3,3),MINV(3,3)
  1503. MINV(1,1)=(M(3,3)*M(2,2)-(M(3,2)*M(2,3)))/(M(3,3)*M(2,2
  1504. . )*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1))
  1505. . +M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(2
  1506. . ,2)*M(1,3)))
  1507. MINV(1,2)=(-(M(3,3)*M(1,2))+M(3,2)*M(1,3))/(M(3,3)*M(2,
  1508. . 2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1)
  1509. . )+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(
  1510. . 2,2)*M(1,3)))
  1511. MINV(1,3)=(M(2,3)*M(1,2)-(M(2,2)*M(1,3)))/(M(3,3)*M(2,2
  1512. . )*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1))
  1513. . +M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(2
  1514. . ,2)*M(1,3)))
  1515. MINV(2,1)=(-(M(3,3)*M(2,1))+M(3,1)*M(2,3))/(M(3,3)*M(2,
  1516. . 2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1)
  1517. . )+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(
  1518. . 2,2)*M(1,3)))
  1519. MINV(2,2)=(M(3,3)*M(1,1)-(M(3,1)*M(1,3)))/(M(3,3)*M(2,2
  1520. . )*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1))
  1521. . +M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(2
  1522. . ,2)*M(1,3)))
  1523. MINV(2,3)=(-(M(2,3)*M(1,1))+M(2,1)*M(1,3))/(M(3,3)*M(2,
  1524. . 2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1)
  1525. . )+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(
  1526. . 2,2)*M(1,3)))
  1527. MINV(3,1)=(M(3,2)*M(2,1)-(M(3,1)*M(2,2)))/(M(3,3)*M(2,2
  1528. . )*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1))
  1529. . +M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(2
  1530. . ,2)*M(1,3)))
  1531. MINV(3,2)=(-(M(3,2)*M(1,1))+M(3,1)*M(1,2))/(M(3,3)*M(2,
  1532. . 2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1)
  1533. . )+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(
  1534. . 2,2)*M(1,3)))
  1535. MINV(3,3)=(M(2,2)*M(1,1)-(M(2,1)*M(1,2)))/(M(3,3)*M(2,2
  1536. . )*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)*M(2,3)*M(1,1))
  1537. . +M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1,2)-(M(3,1)*M(2
  1538. . ,2)*M(1,3)))
  1539. RETURN
  1540. END
  1541. \end{framedverbatim}
  1542. This is an example of a modular approach to code generation; separate
  1543. subprogram templates are given in separate files. Furthermore, the template
  1544. files are general; they can be used for matrices of any predetermined
  1545. size. Therefore, we can easily generate different subprograms to
  1546. handle matrices of different sizes from the same template files
  1547. simply by assigning different values to {\it n}, and reloading the
  1548. file init.red.
  1549. \subsection{Template Processing and Generation of Type Declarations}
  1550. \label{template:type}
  1551. \index{GENDECS switch} \index{type declarations}
  1552. In Section~\ref{control:type} we described the {\bf GENDECS} flag. We
  1553. explained that type declarations are not generated when this flag is
  1554. turned off. Now that the concept of template processing has been
  1555. explained, it is appropriate to continue our discussion of generation
  1556. of type declarations.
  1557. When the {\bf GENDECS} flag is off, type declaration information is not
  1558. simply discarded --- it is still maintained in the symbol table. Only the
  1559. automatic extraction of this information in the form of declarations is
  1560. disabled. When the {\bf GENDECS} flag is turned off, all type
  1561. information associated with a specific subprogram can be retrieved in the
  1562. form of generated declarations by calling the {\bf GENDECS} function with
  1563. the subprogram name as argument. The template processor recognizes
  1564. function and subroutine headings. It always keeps track of the name of
  1565. the subprogram it is processing. Therefore, the declarations associated with
  1566. a particular subprogram {\it subprogname} can be generated with a call to
  1567. {\bf GENDECS} as follows:
  1568. \begin{center}
  1569. {\bf GENDECS} {\it subprogname}\$
  1570. \end{center}
  1571. By using the {\bf GENDECS} flag and function together with the template
  1572. processing facility, it is possible to have type information
  1573. inserted into the symbol table during a first pass over a template file, and
  1574. then to have it extracted during a second pass. Consider the following
  1575. example in which the original template file is transformed into an
  1576. intermediate template during the first pass, and then into the final file
  1577. of FORTRAN code during the second pass:
  1578. Contents of file {\tt junk.tem}:
  1579. \begin{framedverbatim}
  1580. ;BEGIN;
  1581. MAXEXPPRINTLEN!* := 50$
  1582. OFF GENDECS$
  1583. ;END;
  1584. SUBROUTINE CALC(X,Y,Z,A,B,RES)
  1585. ;BEGIN;
  1586. GENTRAN LITERAL ";BEGIN;", CR!*,
  1587. "GENDECS CALC$", CR!*,
  1588. ";END;", CR!*$
  1589. ;END;
  1590. X=3.75
  1591. Y=-10.2
  1592. Z=16.473
  1593. ;BEGIN;
  1594. GENTRAN
  1595. <<
  1596. DECLARE X,Y,Z,A,B,RES : REAL;
  1597. RES :=: (X + Y + Z)^3*(A + B)^2
  1598. >>$
  1599. ;END;
  1600. RETURN
  1601. END
  1602. ;BEGIN;
  1603. GENTRAN LITERAL ";END;", CR!*$
  1604. ;END;
  1605. ;END;
  1606. \end{framedverbatim}
  1607. Invocation of the template processor on this file produces an
  1608. intermediate template file:
  1609. \begin{verbatim}
  1610. 1: GENTRANIN
  1611. 1: "junk.tem"
  1612. 1: OUT "#junk.tem"$
  1613. \end{verbatim}
  1614. Contents of file {\tt \#junk.tem}:
  1615. \begin{framedverbatim}
  1616. SUBROUTINE CALC(X,Y,Z,A,B,RES)
  1617. ;BEGIN;
  1618. GENDECS CALC$
  1619. ;END;
  1620. X=3.75
  1621. Y=-10.2
  1622. Z=16.473
  1623. T0=A**2*X**3+3.0*A**2*X**2*Y
  1624. T0=T0+3.0*A**2*X**2*Z+3.0*A**2*X*Y**2
  1625. T0=T0+6.0*A**2*X*Y*Z+3.0*A**2*X*Z**2
  1626. T0=T0+A**2*Y**3+3.0*A**2*Y**2*Z
  1627. T0=T0+3.0*A**2*Y*Z**2+A**2*Z**3
  1628. T0=T0+2.0*A*B*X**3+6.0*A*B*X**2*Y
  1629. T0=T0+6.0*A*B*X**2*Z+6.0*A*B*X*Y**2
  1630. T0=T0+12.0*A*B*X*Y*Z+6.0*A*B*X*Z**2
  1631. T0=T0+2.0*A*B*Y**3+6.0*A*B*Y**2*Z
  1632. T0=T0+6.0*A*B*Y*Z**2+2.0*A*B*Z**3
  1633. T0=T0+B**2*X**3+3.0*B**2*X**2*Y
  1634. T0=T0+3.0*B**2*X**2*Z+3.0*B**2*X*Y**2
  1635. T0=T0+6.0*B**2*X*Y*Z+3.0*B**2*X*Z**2
  1636. T0=T0+B**2*Y**3+3.0*B**2*Y**2*Z
  1637. RES=T0+3.0*B**2*Y*Z**2+B**2*Z**3
  1638. RETURN
  1639. END
  1640. ;END;
  1641. \end{framedverbatim}
  1642. Another pass of the template processor produced the final file of FORTRAN
  1643. code:
  1644. \begin{verbatim}
  1645. 2: GENTRANIN
  1646. 2: "#junk.tem"
  1647. 2: OUT "junk.f"$
  1648. \end{verbatim}
  1649. Contents of file {\tt junk.f}:
  1650. \begin{framedverbatim}
  1651. SUBROUTINE CALC(X,Y,Z,A,B,RES)
  1652. REAL X,Y,Z,A,B,RES,T0
  1653. X=3.75
  1654. Y=-10.2
  1655. Z=16.473
  1656. T0=A**2*X**3+3.0*A**2*X**2*Y
  1657. T0=T0+3.0*A**2*X**2*Z+3.0*A**2*X*Y**2
  1658. T0=T0+6.0*A**2*X*Y*Z+3.0*A**2*X*Z**2
  1659. T0=T0+A**2*Y**3+3.0*A**2*Y**2*Z
  1660. T0=T0+3.0*A**2*Y*Z**2+A**2*Z**3
  1661. T0=T0+2.0*A*B*X**3+6.0*A*B*X**2*Y
  1662. T0=T0+6.0*A*B*X**2*Z+6.0*A*B*X*Y**2
  1663. T0=T0+12.0*A*B*X*Y*Z+6.0*A*B*X*Z**2
  1664. T0=T0+2.0*A*B*Y**3+6.0*A*B*Y**2*Z
  1665. T0=T0+6.0*A*B*Y*Z**2+2.0*A*B*Z**3
  1666. T0=T0+B**2*X**3+3.0*B**2*X**2*Y
  1667. T0=T0+3.0*B**2*X**2*Z+3.0*B**2*X*Y**2
  1668. T0=T0+6.0*B**2*X*Y*Z+3.0*B**2*X*Z**2
  1669. T0=T0+B**2*Y**3+3.0*B**2*Y**2*Z
  1670. RES=T0+3.0*B**2*Y*Z**2+B**2*Z**3
  1671. RETURN
  1672. END
  1673. \end{framedverbatim}
  1674. \subsection{Referencing Subprogram and Parameter Names}
  1675. \index{"!\$n parameters} \index{"!\$0 subprogram name}
  1676. In some code generation applications in which template processing is used,
  1677. it is useful to be able to reference the names of the parameters
  1678. given in the subprogram header. For this reason, the special
  1679. symbols {\bf !\$1}, {\bf !\$2},~\dots, {\bf !\${\it n}}, where {\it n}
  1680. is the number
  1681. of parameters, can be used in computations and code generation commands in
  1682. active parts of template files. Each of these symbols will be replaced by
  1683. the corresponding parameter name when code is generated. In addition, the
  1684. special symbol {\bf !\$0} will be replaced by the subprogram name. This is
  1685. useful when FORTRAN or RATFOR functions are being generated. Finally, the
  1686. \index{"!\$"!\# in GENTRAN}
  1687. special global variable {\bf !\$!\#} is bound to the number of parameters in
  1688. the subprogram header.
  1689. \section{Output Redirection}\label{GENTRAN:output}
  1690. \index{GENTRAN ! file output}
  1691. Many examples given thus far in this manual have sent all generated code to
  1692. the terminal screen. In actual code generation applications, however,
  1693. code must be sent to a file which will be compiled at a later
  1694. time. This section explains methods of redirecting code to a
  1695. file as it is generated. Any number of output files can be open
  1696. simultaneously, and generated code can be sent to any combination
  1697. of these open files.
  1698. \subsection{File Selection Commands}
  1699. \label{file:selection}
  1700. \index{OUT command} \index{SHUT command}
  1701. REDUCE provides the user with two file handling commands for output
  1702. redirection: {\bf OUT} and {\bf SHUT}. The {\bf OUT} command takes a
  1703. single file name as argument and directs all REDUCE output to that
  1704. file from then on, until another {\bf OUT} changes the output file, or
  1705. {\bf SHUT} closes it. Output can go to only one file at a time,
  1706. although many can be open. If the file has previously been used for
  1707. output during the current job and not {\bf SHUT}, then the new output
  1708. is appended onto the end of the file. Any existing file is erased
  1709. before its first use for output in a job. To output on the terminal
  1710. without closing the output file, the reserved file name {\bf T} (for
  1711. terminal) may be used.
  1712. The REDUCE {\bf SHUT} command takes a list of names of files which
  1713. have been previously opened via an {\bf OUT} command and closes them.
  1714. Most systems require this action by the user before he ends the REDUCE
  1715. job; otherwise the output may be lost. If a file is {\bf SHUT} and a
  1716. further {\bf OUT} command is issued for the same file, the file is
  1717. erased before the new output is written. If it is the current output
  1718. file that is {\bf SHUT}, output will switch to the terminal.
  1719. These commands are suitable for most applications in which REDUCE
  1720. output must be saved. However, they have two deficiencies when
  1721. considered for use in code generation applications. First, they are
  1722. inconvenient. {\bf OUT} tells REDUCE to direct {\it all\/} output to
  1723. a specified file. Thus in addition to output written as side effects
  1724. of functions, returned values are also written to the file (unless the
  1725. user is careful to terminate all statements and commands with a {\bf
  1726. \$}, in which case only output produced by side effects is written).
  1727. If code generation is to be accomplished interactively; i.e., if
  1728. algebraic computations and code generation commands are interleaved,
  1729. then {\bf OUT} {\it filename\/}{\bf \$} must be issued before every
  1730. group of code generation requests, and {\bf OUT T\$} must be issued
  1731. after every group. Secondly, the {\bf OUT} command does not allow
  1732. output to be sent to two or more files without reissuing the {\bf OUT}
  1733. with another file name. In an effort to remove these deficiencies and
  1734. make the code generation commands flexible and easy to use, separate
  1735. file handling commands are provided by GENTRAN which redirect
  1736. generated code {\it only}.
  1737. \index{GENTRANOUT command} \index{GENTRANSHUT command}
  1738. The {\bf GENTRANOUT} and {\bf GENTRANSHUT} commands are identical to
  1739. the REDUCE {\bf OUT} and {\bf SHUT} commands with the following
  1740. exceptions:
  1741. \begin{itemize}
  1742. \item {\bf GENTRANOUT} and {\bf GENTRANSHUT} redirect {\it only\/} code which
  1743. is printed as a side effect of GENTRAN commands.
  1744. \item {\bf GENTRANOUT} allows more than one file name to be given
  1745. to indicate that generated code is to be sent to two or more
  1746. files. (It is particularly convenient to be able to
  1747. have generated code sent to
  1748. the terminal screen and one or more file simultaneously.)
  1749. \item {\bf GENTRANOUT} does not automatically erase existing files; it prints
  1750. a warning message on the terminal and asks the user whether the existing
  1751. file should be erased or the whole command be aborted.
  1752. \end{itemize}
  1753. The next two subsections describe these commands in detail.
  1754. \index{GENTRANOUT command}
  1755. \subsubsection{GENTRANOUT}
  1756. \begin{describe}{Syntax:}
  1757. {\bf GENTRANOUT} {\it f1,f2,\dots\ ,fn;}
  1758. \end{describe}
  1759. \begin{describe}{Arguments:}
  1760. {\it f1,f2,\dots\ ,fn\/} is a list of one or more {\it f\/}'s, where each
  1761. {\it f\/} is one of:
  1762. \begin{center}
  1763. \begin{tabular}{lll}
  1764. {\it an atom} & = & an output file\\
  1765. {\bf T} & = & the terminal\\
  1766. {\bf NIL} & = & the current output file(s)\\
  1767. {\bf ALL!*} & = & all files currently open for output \\
  1768. & & by GENTRAN\\
  1769. \end{tabular}
  1770. \end{center}
  1771. \end{describe}
  1772. \begin{describe}{Side Effects:}
  1773. GENTRAN maintains a list of files currently open for output by
  1774. GENTRAN {\it only}. {\bf GENTRANOUT} inserts each file name represented by
  1775. {\it f1,f2,\dots\ ,fn\/} into that list and opens each one for output. It
  1776. also resets the current output file(s) to be all files in {\it f1,f2,\dots\
  1777. ,fn}.
  1778. \end{describe}
  1779. \begin{describe}{Returned Value:}
  1780. {\bf GENTRANOUT} returns the list of files represented by
  1781. {\it f1,f2,\dots\ ,fn\/};
  1782. i.e., the current output file(s) after the command has been executed.
  1783. \end{describe}
  1784. \begin{describe}{Diagnostic Messages:}
  1785. \begin{verbatim}
  1786. *** OUTPUT FILE ALREADY EXISTS
  1787. OVERWRITE FILE? (Y/N)
  1788. ***** WRONG TYPE OF ARG
  1789. \end{verbatim}
  1790. \end{describe}
  1791. \begin{describe}{\example}
  1792. Output file list:
  1793. {\setlength{\unitlength}{1cm}
  1794. \begin{picture}(5,2)(0,0)
  1795. \put(0,0) {\framebox(1.5,.75){T}}
  1796. \put(.75,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1797. \put(.7,1.5) {\vector(0,-1){.75}}
  1798. \end{picture}}
  1799. \begin{verbatim}
  1800. 1: GENTRANOUT "f1";
  1801. "f1"
  1802. \end{verbatim}
  1803. Output file list:
  1804. {\setlength{\unitlength}{1cm}
  1805. \begin{picture}(5,2)(0,0)
  1806. \put(0,0) {\framebox(1.5,.75){T}}
  1807. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1808. \put(2.25,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1809. \put(2.2,1.5) {\vector(0,-1){.75}}
  1810. \end{picture}}
  1811. \begin{verbatim}
  1812. 2: GENTRANOUT "f2";
  1813. "f2"
  1814. \end{verbatim}
  1815. Output file list:
  1816. {\setlength{\unitlength}{1cm}
  1817. \begin{picture}(5,2)(0,0)
  1818. \put(0,0) {\framebox(1.5,.75){T}}
  1819. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1820. \put(3,0) {\framebox(1.5,.75){"f2"}}
  1821. \put(3.75,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1822. \put(3.7,1.5) {\vector(0,-1){.75}}
  1823. \end{picture}}
  1824. \begin{verbatim}
  1825. 3: GENTRANOUT T,"f3";
  1826. {T,"f3"}
  1827. \end{verbatim}
  1828. Output file list:
  1829. {\setlength{\unitlength}{1cm}
  1830. \begin{picture}(10,2)(0,0)
  1831. \put(0,0) {\framebox(1.5,.75){T}}
  1832. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1833. \put(3,0) {\framebox(1.5,.75){"f2"}}
  1834. \put(4.5,0) {\framebox(1.5,.75){"f3"}}
  1835. \put(5.5,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1836. \put(5.25,1.5) {\vector(0,-1){.75}}
  1837. \put(5.45,1.5) {\line(-1,0){4.70}}
  1838. \put(.75,1.5) {\vector(0,-1){.75}}
  1839. \end{picture}}
  1840. \begin{verbatim}
  1841. 4: GENTRANOUT "f1";
  1842. "f1"
  1843. \end{verbatim}
  1844. Output file list:
  1845. {\setlength{\unitlength}{1cm}
  1846. \begin{picture}(10,2)(0,0)
  1847. \put(0,0) {\framebox(1.5,.75){T}}
  1848. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1849. \put(3,0) {\framebox(1.5,.75){"f2"}}
  1850. \put(4.5,0) {\framebox(1.5,.75){"f3"}}
  1851. \put(2.25,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1852. \put(2.2,1.5) {\vector(0,-1){.75}}
  1853. \end{picture}}
  1854. \begin{verbatim}
  1855. 5: GENTRANOUT NIL,"f4";
  1856. {"f1","f4"}
  1857. \end{verbatim}
  1858. Output file list:
  1859. {\setlength{\unitlength}{1cm}
  1860. \begin{picture}(10,2)(0,0)
  1861. \put(0,0) {\framebox(1.5,.75){T}}
  1862. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1863. \put(3,0) {\framebox(1.5,.75){"f2"}}
  1864. \put(4.5,0) {\framebox(1.5,.75){"f3"}}
  1865. \put(6,0) {\framebox(1.5,.75){"f4"}}
  1866. \put(7.5,1.5) {\makebox(0,0)[bl]{\tt current-output}}
  1867. \put(6.75,1.5) {\vector(0,-1){.75}}
  1868. \put(2.25,1.5) {\vector(0,-1){.75}}
  1869. \put(7.45,1.5) {\line(-1,0){5.2}}
  1870. \end{picture}}
  1871. \ttindex{ALL"!*}
  1872. \begin{verbatim}
  1873. 6: GENTRANOUT ALL!*;
  1874. {"f1","f2","f3","f4"}
  1875. \end{verbatim}
  1876. Output file list:
  1877. {\setlength{\unitlength}{1cm}
  1878. \begin{picture}(10,2)(0,0)
  1879. \put(0,0) {\framebox(1.5,.75){T}}
  1880. \put(1.5,0) {\framebox(1.5,.75){"f1"}}
  1881. \put(3,0) {\framebox(1.5,.75){"f2"}}
  1882. \put(4.5,0) {\framebox(1.5,.75){"f3"}}
  1883. \put(6,0) {\framebox(1.5,.75){"f4"}}
  1884. \put(7.5,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1885. \put(6.75,1.5) {\vector(0,-1){.75}}
  1886. \put(5.25,1.5) {\vector(0,-1){.75}}
  1887. \put(3.75,1.5) {\vector(0,-1){.75}}
  1888. \put(2.25,1.5) {\vector(0,-1){.75}}
  1889. \put(7.45,1.5) {\line(-1,0){5.2}}
  1890. \end{picture}}
  1891. \end{describe}
  1892. \subsubsection{GENTRANSHUT}
  1893. \index{GENTRANSHUT command}
  1894. \begin{describe}{Syntax:}
  1895. {\bf GENTRANSHUT} {\it f1,f2,\dots\ ,fn;\/}
  1896. \end{describe}
  1897. \begin{describe}{Arguments:}
  1898. {\it f1,f2,\dots\ ,fn\/} is a list of one or more {\it f\/}'s, where each
  1899. {\it f\/} is one of:
  1900. \begin{center}
  1901. \begin{tabular}{lll}
  1902. {\it an atom} & = & an output file\\
  1903. {\bf NIL} & = & the current output file(s)\\
  1904. {\bf ALL!*} & = & all files currently open for output \\
  1905. & & by GENTRAN\\
  1906. \end{tabular}
  1907. \end{center}
  1908. \end{describe}
  1909. \begin{describe}{Side Effects:}
  1910. {\bf GENTRANSHUT} creates a list of file names from {\it f1,f2,\dots\ ,fn},
  1911. deletes each from the output file list, and closes the
  1912. corresponding files. If (all of) the current output file(s) are
  1913. closed, then the current output file is reset to the terminal.
  1914. \end{describe}
  1915. \begin{describe}{Returned Value:}
  1916. {\bf GENTRANSHUT} returns the current output file(s) after the command has
  1917. been executed.
  1918. \end{describe}
  1919. \begin{describe}{Diagnostic Messages:}
  1920. \begin{verbatim}
  1921. *** FILE NOT OPEN FOR OUTPUT
  1922. ***** WRONG TYPE OF ARG
  1923. \end{verbatim}
  1924. \end{describe}
  1925. \begin{describe}{\example}\index{GENTRAN package ! example}
  1926. Output file list:
  1927. {\setlength{\unitlength}{1cm}
  1928. \begin{picture}(10,2)(0,0)
  1929. \put(0,0) {\framebox(1,.75){T}}
  1930. \put(1,0) {\framebox(1,.75){"f1"}}
  1931. \put(2,0) {\framebox(1,.75){"f2"}}
  1932. \put(3,0) {\framebox(1,.75){"f3"}}
  1933. \put(4,0) {\framebox(1,.75){"f4"}}
  1934. \put(5,0) {\framebox(1,.75){"f5"}}
  1935. \put(6,0) {\framebox(1,.75){"f6"}}
  1936. \put(7,0) {\framebox(1,.75){"f7"}}
  1937. \put(2,1.5) {\makebox(0,0) [br]{\tt current-output}}
  1938. \put(3.5,1.5) {\vector(0,-1){.75}}
  1939. \put(4.5,1.5) {\vector(0,-1){.75}}
  1940. \put(7.5,1.5) {\vector(0,-1){.75}}
  1941. \put(2.05,1.5) {\line(1,0){5.45}}
  1942. \end{picture}}
  1943. \begin{verbatim}
  1944. 1: GENTRANSHUT "f1","f2","f7";
  1945. {"f3","f4"}
  1946. \end{verbatim}
  1947. Output file list:
  1948. {\setlength{\unitlength}{1cm}
  1949. \begin{picture}(10,2)(0,0)
  1950. \put(0,0) {\framebox(1,.75){T}}
  1951. \put(1,0) {\framebox(1,.75){"f3"}}
  1952. \put(2,0) {\framebox(1,.75){"f4"}}
  1953. \put(3,0) {\framebox(1,.75){"f5"}}
  1954. \put(4,0) {\framebox(1,.75){"f6"}}
  1955. \put(4.5,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1956. \put(1.5,1.5) {\vector(0,-1){.75}}
  1957. \put(2.5,1.5) {\vector(0,-1){.75}}
  1958. \put(4.45,1.5) {\line(-1,0){2.95}}
  1959. \end{picture}}
  1960. \begin{verbatim}
  1961. 2: GENTRANSHUT NIL;
  1962. T
  1963. \end{verbatim}
  1964. Output file list:
  1965. {\setlength{\unitlength}{1cm}
  1966. \begin{picture}(10,2)(0,0)
  1967. \put(0,0) {\framebox(1,.75){T}}
  1968. \put(1,0) {\framebox(1,.75){"f5"}}
  1969. \put(2,0) {\framebox(1,.75){"f6"}}
  1970. \put(.55,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1971. \put(.5,1.5) {\vector(0,-1){.75}}
  1972. \end{picture}}
  1973. \begin{verbatim}
  1974. 3: GENTRANSHUT ALL!*;
  1975. T
  1976. \end{verbatim}
  1977. Output file list:
  1978. {\setlength{\unitlength}{1cm}
  1979. \begin{picture}(10,2)(0,0)
  1980. \put(0,0) {\framebox(1,.75){T}}
  1981. \put(.55,1.5) {\makebox(0,0) [bl]{\tt current-output}}
  1982. \put(.5,1.5) {\vector(0,-1){.75}}
  1983. \end{picture}}
  1984. \end{describe}
  1985. \subsection{The Output File Stack}
  1986. Section~\ref{file:selection}
  1987. \index{files ! in GENTRAN}
  1988. explained the {\bf GENTRANOUT} and {\bf GENTRANSHUT}
  1989. commands which are very similar to the REDUCE {\bf OUT} and {\bf SHUT}
  1990. commands but redirect {\it only code generated as side effects of GENTRAN
  1991. commands\/} to files. This section describes another pair of file
  1992. handling commands provided by GENTRAN.
  1993. In some code generation applications it may be convenient to be
  1994. able to send generated code to one (set of) file(s), then
  1995. temporarily send code to another (set of) file(s), and later
  1996. resume sending generated code to the first (set of) file(s). In
  1997. other words, it is convenient to think of the output files as
  1998. being arranged in a stack which can be pushed whenever new
  1999. files are to be written to temporarily, and popped whenever
  2000. previously written-to files are to be appended onto. {\bf GENTRANPUSH}
  2001. \index{GENTRANPUSH command} \index{GENTRANPOP command}
  2002. and {\bf GENTRANPOP} enable the user to manipulate a stack of open
  2003. output files in these ways.
  2004. {\bf GENTRANPUSH} simply pushes a (set of) file(s) onto
  2005. the stack and opens each one that is not already open for
  2006. output. {\bf GENTRANPOP} deletes the top-most occurrence of
  2007. the given file(s) from the stack and closes each one that is no
  2008. longer in the stack. The stack is initialized to one element: the
  2009. terminal. This element is always on the bottom of the stack, and thus,
  2010. is the default output file. The current output file is always the
  2011. file(s) on top of the stack.
  2012. \subsubsection{GENTRANPUSH}
  2013. \index{GENTRANPUSH command}
  2014. \begin{describe}{Syntax:}
  2015. {\bf GENTRANPUSH} {\it f1,f2,\dots\ ,fn;}
  2016. \end{describe}
  2017. \begin{describe}{Arguments:}
  2018. {\it f1,f2,\dots\ ,fn\/} is a list of one or more {\it f\/}'s, where each
  2019. {\it f\/} is one of:
  2020. \begin{center}
  2021. \begin{tabular}{lll}
  2022. {\it an atom} & = & an output file\\
  2023. {\bf T} & = & the terminal\\
  2024. {\bf NIL} & = & the current output file(s)\\
  2025. {\bf ALL!*} & = & all files currently open for output \\
  2026. & & by GENTRAN\\
  2027. \end{tabular}
  2028. \end{center}
  2029. \end{describe}
  2030. \begin{describe}{Side Effects:}
  2031. {\bf GENTRANPUSH} creates a list of file name(s) represented by
  2032. {\it f1,f2,\dots\ ,fn\/} and pushes that list onto the output stack. Each file
  2033. in the list that is not already open for output is opened at this time. The
  2034. current output file is reset to this new element on the top of the stack.
  2035. \end{describe}
  2036. \begin{describe}{Returned Value:}
  2037. {\bf GENTRANPUSH} returns the list of files represented by
  2038. {\it f1,f2,\dots\ ,fn\/};
  2039. i.e., the current output file(s) after the command has been executed.
  2040. \end{describe}
  2041. \begin{describe}{Diagnostic Messages:}
  2042. \begin{verbatim}
  2043. *** OUTPUT FILE ALREADY EXISTS
  2044. OVERWRITE FILE? (Y/N)
  2045. ***** WRONG TYPE OF ARG
  2046. \end{verbatim}
  2047. \end{describe}
  2048. \begin{describe}{\example}\index{GENTRAN package ! example}
  2049. Output stack:
  2050. {\setlength{\unitlength}{1cm}
  2051. \begin{picture}(10,1)(0,0)
  2052. \put(0,0) {\framebox(3,1){}}
  2053. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2054. \put(4,.5) {\vector(-1,0){1}}
  2055. \put(4.1,.5) {\makebox(0,0)[cl]{\tt current-output}}
  2056. \end{picture}}
  2057. \begin{verbatim}
  2058. 1: GENTRANPUSH "f1";
  2059. "f1"
  2060. \end{verbatim}
  2061. Output stack:
  2062. {\setlength{\unitlength}{1cm}
  2063. \begin{picture}(10,1.5)(0,0)
  2064. \put(0,0) {\framebox(3,1.5){}}
  2065. \put(0.25,1) {\makebox(0,0)[cl]{"f1"}}
  2066. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2067. \put(4,1) {\vector(-1,0){1}}
  2068. \put(4.1,1) {\makebox(0,0)[cl]{\tt current-output}}
  2069. \end{picture}}
  2070. \begin{verbatim}
  2071. 2: GENTRANPUSH "f2","f3";
  2072. {"f2","f3"}
  2073. \end{verbatim}
  2074. Output stack:
  2075. {\setlength{\unitlength}{1cm}
  2076. \begin{picture}(10,2)(0,0)
  2077. \put(0,0) {\framebox(3,2){}}
  2078. \put(0.25,1.5) {\makebox(0,0)[cl]{"f2" "f3"}}
  2079. \put(0.25,1) {\makebox(0,0)[cl]{"f1"}}
  2080. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2081. \put(4,1.5) {\vector(-1,0){1}}
  2082. \put(4.1,1.5) {\makebox(0,0)[cl]{\tt current-output}}
  2083. \end{picture}}
  2084. \begin{verbatim}
  2085. 3: GENTRANPUSH NIL,T;
  2086. {"f2","f3",T}
  2087. \end{verbatim}
  2088. Output stack:
  2089. {\setlength{\unitlength}{1cm}
  2090. \begin{picture}(10,2.5)(0,0)
  2091. \put(0,0) {\framebox(3,2.5){}}
  2092. \put(0.25,2) {\makebox(0,0)[cl]{"f2" "f3" T}}
  2093. \put(0.25,1.5) {\makebox(0,0)[cl]{"f2" "f3"}}
  2094. \put(0.25,1) {\makebox(0,0)[cl]{"f1"}}
  2095. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2096. \put(4,2) {\vector(-1,0){1}}
  2097. \put(4.1,2) {\makebox(0,0)[cl]{\tt current-output}}
  2098. \end{picture}}
  2099. \begin{verbatim}
  2100. 4: GENTRANPUSH "f1";
  2101. "f1"
  2102. \end{verbatim}
  2103. Output stack:
  2104. {\setlength{\unitlength}{1cm}
  2105. \begin{picture}(10,3)(0,0)
  2106. \put(0,0) {\framebox(3,3){}}
  2107. \put(0.25,2.5) {\makebox(0,0)[cl]{"f1"}}
  2108. \put(0.25,2) {\makebox(0,0)[cl]{"f2" "f3" T}}
  2109. \put(0.25,1.5) {\makebox(0,0)[cl]{"f2" "f3"}}
  2110. \put(0.25,1) {\makebox(0,0)[cl]{"f1"}}
  2111. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2112. \put(4,2.5) {\vector(-1,0){1}}
  2113. \put(4.1,2.5) {\makebox(0,0)[cl]{\tt current-output}}
  2114. \end{picture}}
  2115. \begin{verbatim}
  2116. 5: GENTRANPUSH ALL!*;
  2117. {"f1","f2","f3"}
  2118. \end{verbatim}
  2119. Output stack:
  2120. {\setlength{\unitlength}{1cm}
  2121. \begin{picture}(10,3.5)(0,0)
  2122. \put(0,0) {\framebox(3,3.5){}}
  2123. \put(0.25,3) {\makebox(0,0)[cl]{"f1" "f2" "f3"}}
  2124. \put(0.25,2.5) {\makebox(0,0)[cl]{"f1"}}
  2125. \put(0.25,2) {\makebox(0,0)[cl]{"f2" "f3" T}}
  2126. \put(0.25,1.5) {\makebox(0,0)[cl]{"f2" "f3"}}
  2127. \put(0.25,1) {\makebox(0,0)[cl]{"f1"}}
  2128. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2129. \put(4,3) {\vector(-1,0){1}}
  2130. \put(4.1,3) {\makebox(0,0)[cl]{\tt current-output}}
  2131. \end{picture}}
  2132. \end{describe}
  2133. \subsubsection{GENTRANPOP}
  2134. \index{GENTRANPOP command}
  2135. \begin{describe}{Syntax:}
  2136. {\bf GENTRANPOP} {\it f1,f2,\dots\ ,fn;}
  2137. \end{describe}
  2138. \begin{describe}{Arguments:}
  2139. {\it f1,f2,\dots\ ,fn\/} is a list of one or more {\it f\/}'s, where each
  2140. {\it f\/} is one of:
  2141. \begin{center}
  2142. \begin{tabular}{lll}
  2143. {\it an atom} & = & an output file\\
  2144. {\bf T} & = & the terminal\\
  2145. {\bf NIL} & = & the current output file(s)\\
  2146. {\bf ALL!*} & = & all files currently open for output \\
  2147. & & by GENTRAN\\
  2148. \end{tabular}
  2149. \end{center}
  2150. \end{describe}
  2151. \begin{describe}{Side Effects:}
  2152. {\bf GENTRANPOP} deletes the top-most occurrence of the single element
  2153. containing the file name(s) represented by {\it f1,f2,\dots\ ,fn\/}
  2154. from the output stack. Files whose names have been completely removed from
  2155. the output stack are closed. The current output file is reset to the
  2156. (new) element on the top of the output stack.
  2157. \end{describe}
  2158. \begin{describe}{Returned Value:}
  2159. {\bf GENTRANPOP} returns the current output file(s) after this command
  2160. has been executed.
  2161. \end{describe}
  2162. \begin{describe}{Diagnostic Messages:}
  2163. \begin{verbatim}
  2164. *** FILE NOT OPEN FOR OUTPUT
  2165. ***** WRONG TYPE OF ARG
  2166. \end{verbatim}
  2167. \end{describe}
  2168. \begin{describe}{\example}\index{GENTRAN package ! example}
  2169. Output stack:
  2170. {\setlength{\unitlength}{1cm}
  2171. \begin{picture}(10,4)(0,0)
  2172. \put(0,0) {\framebox(3,4){}}
  2173. \put(0.25,3.5) {\makebox(0,0)[cl]{"f4"}}
  2174. \put(0.25,3) {\makebox(0,0)[cl]{"f4" "f2" T}}
  2175. \put(0.25,2.5) {\makebox(0,0)[cl]{"f4"}}
  2176. \put(0.25,2) {\makebox(0,0)[cl]{T}}
  2177. \put(0.25,1.5) {\makebox(0,0)[cl]{"f3"}}
  2178. \put(0.25,1) {\makebox(0,0)[cl]{"f2" "f1"}}
  2179. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2180. \put(4,3.5) {\vector(-1,0){1}}
  2181. \put(4.1,3.5) {\makebox(0,0)[cl]{\tt current-output}}
  2182. \end{picture}}
  2183. \begin{verbatim}
  2184. 1: GENTRANPOP NIL;
  2185. {"f4","f2",T}
  2186. \end{verbatim}
  2187. Output stack:
  2188. {\setlength{\unitlength}{1cm}
  2189. \begin{picture}(10,3.5)(0,0)
  2190. \put(0,0) {\framebox(3,3.5){}}
  2191. \put(0.25,3) {\makebox(0,0)[cl]{"f4" "f2" T}}
  2192. \put(0.25,2.5) {\makebox(0,0)[cl]{"f4"}}
  2193. \put(0.25,2) {\makebox(0,0)[cl]{T}}
  2194. \put(0.25,1.5) {\makebox(0,0)[cl]{"f3"}}
  2195. \put(0.25,1) {\makebox(0,0)[cl]{"f2" "f1"}}
  2196. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2197. \put(4,3) {\vector(-1,0){1}}
  2198. \put(4.1,3) {\makebox(0,0)[cl]{\tt current-output}}
  2199. \end{picture}}
  2200. \begin{verbatim}
  2201. 2: GENTRANPOP NIL;
  2202. "f4"
  2203. \end{verbatim}
  2204. Output stack:
  2205. {\setlength{\unitlength}{1cm}
  2206. \begin{picture}(10,3)(0,0)
  2207. \put(0,0) {\framebox(3,3){}}
  2208. \put(0.25,2.5) {\makebox(0,0)[cl]{"f4"}}
  2209. \put(0.25,2) {\makebox(0,0)[cl]{T}}
  2210. \put(0.25,1.5) {\makebox(0,0)[cl]{"f3"}}
  2211. \put(0.25,1) {\makebox(0,0)[cl]{"f2" "f1"}}
  2212. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2213. \put(4,2.5) {\vector(-1,0){1}}
  2214. \put(4.1,2.5) {\makebox(0,0)[cl]{\tt current-output}}
  2215. \end{picture}}
  2216. \begin{verbatim}
  2217. 3: GENTRANPOP "f2","f1";
  2218. "f4"
  2219. \end{verbatim}
  2220. Output stack:
  2221. {\setlength{\unitlength}{1cm}
  2222. \begin{picture}(10,2.5)(0,0)
  2223. \put(0,0) {\framebox(3,2.5){}}
  2224. \put(0.25,2) {\makebox(0,0)[cl]{"f4"}}
  2225. \put(0.25,1.5) {\makebox(0,0)[cl]{T}}
  2226. \put(0.25,1) {\makebox(0,0)[cl]{"f3"}}
  2227. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2228. \put(4,2) {\vector(-1,0){1}}
  2229. \put(4.1,2) {\makebox(0,0)[cl]{\tt current-output}}
  2230. \end{picture}}
  2231. \begin{verbatim}
  2232. 4: GENTRANPOP ALL!*;
  2233. T
  2234. \end{verbatim}
  2235. Output stack:
  2236. {\setlength{\unitlength}{1cm}
  2237. \begin{picture}(10,1)(0,0)
  2238. \put(0,0) {\framebox(3,1){}}
  2239. \put(0.25,.5) {\makebox(0,0)[cl]{T}}
  2240. \put(4,.5) {\vector(-1,0){1}}
  2241. \put(4.1,.5) {\makebox(0,0)[cl]{\tt current-output}}
  2242. \end{picture}}
  2243. \end{describe}
  2244. \subsection{Temporary Output Redirection}
  2245. Sections~\ref{translation} and ~\ref{templates}
  2246. explain how to use the code generation and
  2247. template processing commands. The syntax for these two commands
  2248. is:
  2249. \index{output redirection (temporary)}
  2250. \index{GENTRAN command} \index{GENTRANIN command}
  2251. \begin{tabular}{lll}
  2252. &\multicolumn{2}{l}{{\bf GENTRAN} {\it stmt\/} [{\bf OUT} {\it f1,f2,\dots\
  2253. ,fn\/}]{\it ;}}\\
  2254. &&and\\
  2255. &\multicolumn{2}{l}{{\bf GENTRANIN} {\it f1,f2,\dots\ ,fm\/} [{\bf OUT}
  2256. {\it f1,f2,\dots\ ,fn\/}]{\it ;}}\\
  2257. \end{tabular}
  2258. The optional parts of these two commands can be used for {\it temporary}
  2259. output redirection; they can be used when the current output
  2260. file is to be temporarily reset, for this command only.
  2261. Thus the following two sequences of commands are equivalent:
  2262. \begin{verbatim}
  2263. 10: GENTRANPUSH "f1",T$
  2264. 11: GENTRAN ... $
  2265. 12: GENTRANPOP NIL$
  2266. \end{verbatim}
  2267. and
  2268. \begin{verbatim}
  2269. 10: GENTRAN
  2270. 10: ...
  2271. 10: OUT "f1",T$
  2272. \end{verbatim}
  2273. \section{Modification of the Code Generation Process}\label{GENTRAN:mod}
  2274. GENTRAN is designed to be flexible enough to be used in a variety of
  2275. code generation applications. For this reason, several mode
  2276. switches and variables are provided to enable the user to tailor the
  2277. code generation process to meet his or her particular needs.
  2278. \subsection{Mode Switches}
  2279. \index{GENTRAN package ! switches}
  2280. The following GENTRAN mode switches can be turned on and off with the
  2281. REDUCE {\bf ON} and {\bf OFF} commands.
  2282. \begin{describe}{DOUBLE}
  2283. \index{DOUBLE switch} \index{precision}
  2284. \begin{itemize}
  2285. \item When turned on, causes (where appropriate):
  2286. \begin{itemize}
  2287. \item floating point numbers to be printed in double precision format;
  2288. \item intrinsic functions to be replaced by their double precision
  2289. counterparts;
  2290. \item generated type declarations to be of double precision form.
  2291. \end{itemize}
  2292. See also section~\ref{precision} on page~\pageref{precision}.
  2293. \item default setting: off
  2294. \end{itemize}
  2295. \end{describe}
  2296. \begin{describe}{GENDECS}
  2297. \index{GENDECS switch}
  2298. \begin{itemize}
  2299. \item when turned on, allows type declarations to be generated automatically;
  2300. otherwise, type information is stored in but not automatically retrieved
  2301. from the symbol table. See also sections~\ref{explicit:type} on
  2302. page~\pageref{explicit:type}, \ref{more:type} on page~\pageref{more:type},
  2303. and \ref{template:type} on page~\pageref{template:type}.
  2304. \item default setting: on
  2305. \end{itemize}
  2306. \end{describe}
  2307. \begin{describe}{GENTRANOPT}
  2308. \index{GENTRANOPT switch}
  2309. \begin{itemize}
  2310. \item when turned on, replaces each block of straightline code by
  2311. an optimized sequence of assignments.
  2312. The Code Optimizer takes a sequence of assignments and replaces common
  2313. subexpressions with temporary variables. It returns the resulting assignment
  2314. statements with common-subexpression-to-temporary-variable assignment
  2315. statements preceding them
  2316. \item default setting: off
  2317. \end{itemize}
  2318. \end{describe}
  2319. \begin{describe}{GENTRANSEG}
  2320. \index{GENTRANSEG switch}
  2321. \begin{itemize}
  2322. \item when turned on, checks the print length of expressions and breaks
  2323. those expressions that are longer than {\bf MAXEXPPRINTLEN!*} down
  2324. \ttindex{MAXEXPPRINTLEN"!*}
  2325. into subexpressions which are assigned to temporary variables.
  2326. See also section~\ref{segmentation} on page~\pageref{segmentation}.
  2327. \item default setting: on
  2328. \end{itemize}
  2329. \end{describe}
  2330. \begin{describe}{GETDECS}
  2331. \index{GETDECS switch}
  2332. \begin{itemize}
  2333. \item when on, causes:
  2334. \begin{itemize}
  2335. \item the indices of loops to be declared integer;
  2336. \item objects without an explicit type declaration to be declared of the type
  2337. given by the variable {\bf DEFTYPE!*}. \ttindex{DEFTYPE"!*}
  2338. \end{itemize}
  2339. See also section~\ref{implicit:type} on page~\pageref{implicit:type}.
  2340. \item default setting: off
  2341. \end{itemize}
  2342. \end{describe}
  2343. \begin{describe}{KEEPDECS}
  2344. \index{KEEPDECS switch}
  2345. \begin{itemize}
  2346. \item when on, prevents declarations being removed from the symbol table when
  2347. type declarations are generated.
  2348. \item default: off
  2349. \end{itemize}
  2350. \end{describe}
  2351. \begin{describe}{MAKECALLS}
  2352. \index{MAKECALLS switch}
  2353. \begin{itemize}
  2354. \item when turned on, causes GENTRAN to translate functional expressions as
  2355. subprogram calls.
  2356. \item default setting: on
  2357. \end{itemize}
  2358. \end{describe}
  2359. \begin{describe}{PERIOD}
  2360. \index{PERIOD switch}
  2361. \begin{itemize}
  2362. \item when turned on, causes all integers to be printed out as floating point
  2363. numbers except:
  2364. \begin{itemize}
  2365. \item exponents;
  2366. \item variable subscripts;
  2367. \item index values in DO-type loops;
  2368. \item those which have been declared to be integers.
  2369. \end{itemize}
  2370. \item default setting: on
  2371. \end{itemize}
  2372. \end{describe}
  2373. \subsection{Variables}
  2374. \index{GENTRAN package ! variables}
  2375. Several global variables are provided in GENTRAN to enable the
  2376. user to
  2377. \begin{itemize}
  2378. \item select the target language
  2379. \item control expression segmentation
  2380. \item change automatically generated variable names and statement numbers
  2381. \item modify the code formatter
  2382. \end{itemize}
  2383. The following four subsections describe these variables\footnote{
  2384. Note that when an atomic value (other than an integer) is assigned to a
  2385. variable, that value must be quoted. For example,
  2386. {\bf GENTRANLANG!* := 'FORTRAN\$}
  2387. assigns the atom {\bf FORTRAN} to the variable {\bf GENTRANLANG!*}.}.
  2388. \subsubsection{Target Language Selection}
  2389. \begin{describe}{GENTRANLANG!*}
  2390. \ttindex{GENTRANLANG"!*}
  2391. \begin{itemize}
  2392. \item target language (FORTRAN, RATFOR, PASCAL or C)
  2393. See also section~\ref{gentranlang} on page~\pageref{gentranlang}.
  2394. \item value type: atom
  2395. \item default value: FORTRAN
  2396. \end{itemize}
  2397. \end{describe}
  2398. \subsubsection{Expression Segmentation Control}
  2399. \begin{describe}{MAXEXPPRINTLEN!*}
  2400. \ttindex{MAXEXPPRINTLEN"!*}
  2401. \begin{itemize}
  2402. \item value used to determine whether or not an expression should be
  2403. segmented; maximum number of characters permitted in an expression
  2404. in the target language (excluding spaces printed for formatting).
  2405. See also section~\ref{segmentation} on page~\pageref{segmentation}.
  2406. \item value type: integer
  2407. \item default value: 800
  2408. \end{itemize}
  2409. \end{describe}
  2410. \subsubsection{Variable Names \& Statement Numbers}
  2411. \begin{describe}{TEMPVARNAME!*}
  2412. \ttindex{TEMPVARNAME"!*}
  2413. \begin{itemize}
  2414. \item name used as prefix in generating temporary variable names.
  2415. See also section~\ref{tempvars} on page~\pageref{tempvars}.
  2416. \item value type: atom
  2417. \item default value: T
  2418. \end{itemize}
  2419. \end{describe}
  2420. \begin{describe}{TEMPVARNUM!*}
  2421. \ttindex{TEMPVARNUM"!*}
  2422. \begin{itemize}
  2423. \item number appended to {\bf TEMPVARNAME!*} to create a temporary variable
  2424. name. If the temporary variable name resulting from appending
  2425. {\bf TEMPVARNUM!*} onto {\bf TEMPVARNAME!*} has already been generated
  2426. and still holds a useful value, then {\bf TEMPVARNUM!*} is incremented
  2427. and temporary variable names are compressed until one is found which
  2428. was not previously generated or does not still hold a significant value.
  2429. See also section~\ref{tempvars} on page~\pageref{tempvars}.
  2430. \item value type: integer
  2431. \item default value: 0
  2432. \end{itemize}
  2433. \end{describe}
  2434. \begin{describe}{TEMPVARTYPE!*}
  2435. \ttindex{TEMPVARTYPE"!*}
  2436. \begin{itemize}
  2437. \item target language variable type (e.g., INTEGER, REAL!*8, FLOAT, etc) used
  2438. as a default for automatically generated variables whose type cannot be
  2439. determined otherwise. If {\bf TEMPVARTYPE!*} is NIL, then generated
  2440. temporary variables whose type cannot be determined are not automatically
  2441. declared. See also section~\ref{tempvars} on page~\pageref{tempvars}.
  2442. \item value type: atom
  2443. \item default value: NIL
  2444. \end{itemize}
  2445. \end{describe}
  2446. \begin{describe}{GENSTMTNUM!*}
  2447. \ttindex{GENSTMTNUM"!*}
  2448. \begin{itemize}
  2449. \item number used when a statement number must be generated
  2450. \item value type: integer
  2451. \item default value: 25000
  2452. \end{itemize}
  2453. \end{describe}
  2454. \begin{describe}{GENSTMTINCR!*}
  2455. \ttindex{GENSTMTINCR"!*}
  2456. \begin{itemize}
  2457. \item number by which {\bf GENSTMTNUM!*} is increased each time a new
  2458. statement number is generated.
  2459. \item value type: integer
  2460. \item default value: 1
  2461. \end{itemize}
  2462. \end{describe}
  2463. \begin{describe}{DEFTYPE!*}
  2464. \ttindex{DEFTYPE"!*}
  2465. \begin{itemize}
  2466. \item default type for objects when the switch {\bf GETDECS} is on. See also
  2467. section~\ref{implicit:type} on page~\pageref{implicit:type}.
  2468. \item value type: atom
  2469. \item default value: real
  2470. \end{itemize}
  2471. \end{describe}
  2472. \subsubsection{Code Formatting}
  2473. \begin{describe}{FORTCURRIND!*}
  2474. \ttindex{FORTCURRIND"!*}
  2475. \begin{itemize}
  2476. \item number of blank spaces printed at the beginning of each line of
  2477. generated FORTRAN code beyond column 6
  2478. \item value type: integer
  2479. \item default value: 0
  2480. \end{itemize}
  2481. \end{describe}
  2482. \begin{describe}{RATCURRIND!*}
  2483. \ttindex{RATCURRIND"!*}
  2484. \begin{itemize}
  2485. \item number of blank spaces printed at the beginning of each line of
  2486. generated RATFOR code.
  2487. \item value type: integer
  2488. \item default value: 0
  2489. \end{itemize}
  2490. \end{describe}
  2491. \begin{describe}{CCURRIND!*}
  2492. \ttindex{CCURRIND"!*}
  2493. \begin{itemize}
  2494. \item number of blank spaces printed at the beginning of each line of
  2495. generated C code.
  2496. \item value type: integer
  2497. \item default value: 0
  2498. \end{itemize}
  2499. \end{describe}
  2500. \begin{describe}{PASCCURRIND!*}
  2501. \ttindex{PASCCURRIND"!*}
  2502. \begin{itemize}
  2503. \item number of blank spaces printed at the beginning of each line of
  2504. generated PASCAL code.
  2505. \item value type: integer
  2506. \item default value: 0
  2507. \end{itemize}
  2508. \end{describe}
  2509. \begin{describe}{TABLEN!*}
  2510. \ttindex{TABLEN"!*}
  2511. \begin{itemize}
  2512. \item number of blank spaces printed for each new level of indentation.
  2513. \item value type: integer
  2514. \item default value: 4
  2515. \end{itemize}
  2516. \end{describe}
  2517. \begin{describe}{FORTLINELEN!*}
  2518. \ttindex{FORTLINELEN"!*}
  2519. \begin{itemize}
  2520. \item maximum number of characters printed on each line of generated FORTRAN
  2521. code.
  2522. \item value type: integer
  2523. \item default value: 72
  2524. \end{itemize}
  2525. \end{describe}
  2526. \begin{describe}{RATLINELEN!*}
  2527. \ttindex{RATLINELEN"!*}
  2528. \begin{itemize}
  2529. \item maximum number of characters printed on each line of generated RATFOR
  2530. code.
  2531. \item value type: integer
  2532. \item default value: 80
  2533. \end{itemize}
  2534. \end{describe}
  2535. \begin{describe}{CLINELEN!*}
  2536. \ttindex{CLINELEN"!*}
  2537. \begin{itemize}
  2538. \item maximum number of characters printed on each line of generated C code.
  2539. \item value type: integer
  2540. \item default value: 80
  2541. \end{itemize}
  2542. \end{describe}
  2543. \begin{describe}{PASCLINELEN!*}
  2544. \ttindex{PASCLINELEN"!*}
  2545. \begin{itemize}
  2546. \item maximum number of characters printed on each line of generated PASCAL
  2547. code.
  2548. \item value type: integer
  2549. \item default value: 70
  2550. \end{itemize}
  2551. \end{describe}
  2552. \begin{describe}{MINFORTLINELEN!*}
  2553. \ttindex{MINFORTLINELEN"!*}
  2554. \begin{itemize}
  2555. \item minimum number of characters printed on each line of generated FORTRAN
  2556. code after indentation.
  2557. \item value type: integer
  2558. \item default value: 40
  2559. \end{itemize}
  2560. \end{describe}
  2561. \begin{describe}{MINRATLINELEN!*}
  2562. \ttindex{MINRATLINELEN"!*}
  2563. \begin{itemize}
  2564. \item minimum number of characters printed on each line of generated RATFOR
  2565. code after indentation.
  2566. \item value type: integer
  2567. \item default value: 40
  2568. \end{itemize}
  2569. \end{describe}
  2570. \begin{describe}{MINCLINELEN!*}
  2571. \ttindex{MINCLINELEN"!*}
  2572. \begin{itemize}
  2573. \item minimum number of characters printed on each line of generated C
  2574. code after indentation.
  2575. \item value type: integer
  2576. \item default value: 40
  2577. \end{itemize}
  2578. \end{describe}
  2579. \begin{describe}{MINPASCLINELEN!*}
  2580. \ttindex{MINPASCLINELEN"!*}
  2581. \begin{itemize}
  2582. \item minimum number of characters printed on each line of generated PASCAL
  2583. code after indentation.
  2584. \item value type: integer
  2585. \item default value: 40
  2586. \end{itemize}
  2587. \end{describe}
  2588. \section{Examples}\label{GENTRAN:examples}
  2589. \index{GENTRAN package ! example}
  2590. Short examples have been given throughout this manual to illustrate
  2591. usage of the GENTRAN commands. This section gives complete code
  2592. generation examples.
  2593. \subsection{Interactive Code Generation} \index{GENTRAN package ! example}
  2594. \index{interactive code generation}
  2595. Suppose we wish to generate a FORTRAN subprogram which can be used for
  2596. \index{Graeffe's Root-Squaring Method}
  2597. computing the roots of a polynomial by Graeffe's Root-Squaring Method\footnote{
  2598. This is for instance convenient for ill-conditioned polynomials. More
  2599. details are given in {\it Introduction to Numerical Analysis\/} by
  2600. C. E. Froberg, Addison-Wesley Publishing Company, 1966.}. This
  2601. method states that the roots $x_i$ of a polynomial
  2602. $$P_n(x) = \sum_{i=0}^{n}{a_i x^{n-i}} $$
  2603. can be found by constructing the polynomial
  2604. $$P^{*}_n\left({x^2}\right) = \left( a_0x^n + a_2x^{n-2} + \dots\right)^2 -
  2605. \left( a_1x^{n-1} + a_3x^{n-3} + \dots\right)^2$$
  2606. with roots $x_i^2$
  2607. When read into REDUCE, the following file of REDUCE statements
  2608. will place the coefficients of $P^{*}_n$
  2609. into the list B for some user-entered value of n greater than zero.
  2610. Contents of file {\tt graeffe.red}:\footnote{
  2611. In accordance with section~\ref{explicit:type},
  2612. the subscripts of A are I+1 instead of I.}
  2613. \begin{framedverbatim}
  2614. OPERATOR A$
  2615. Q := FOR I := 0 STEP 2 UNTIL n SUM (A(I+1)*X^(n-I))$
  2616. R := FOR I := 1 STEP 2 UNTIL n-1 SUM (A(I+1)*X^(n-I))$
  2617. P := Q^2 - R^2$
  2618. LET X^2 = Y$
  2619. B := COEFF(P,Y)$
  2620. END$
  2621. \end{framedverbatim}
  2622. Now a numerical subprogram can be generated with assignment
  2623. statements for the coefficients of $P^{*}_n$ (now stored in list B in
  2624. REDUCE). Since these coefficients are given in terms of the coefficients
  2625. of $P_n$ (i.e., operator A in REDUCE), the subprogram will need two
  2626. parameters: A and B, each of which must be arrays of size n+1.
  2627. The following REDUCE session will create subroutine GRAEFF for a polynomial
  2628. of degree n=10 and write it to file {\tt graeffe.f}:
  2629. {\small
  2630. \begin{verbatim}
  2631. 1: n := 10$
  2632. 2: IN "graeffe.red"$
  2633. 3: GENTRANLANG!* := 'FORTRAN$
  2634. 4: ON DOUBLE$
  2635. 5: GENTRAN
  2636. 5: (
  2637. 5: PROCEDURE GRAEFF(A,B);
  2638. 5: BEGIN
  2639. 5: DECLARE
  2640. 5: <<
  2641. 5: GRAEFF : SUBROUTINE;
  2642. 5: A(11),B(11) : REAL
  2643. 5: >>;
  2644. 5: LITERAL
  2645. 5: "C",CR!*,
  2646. 5: "C",TAB!*,"GRAEFFE ROOT-SQUARING METHOD TO FIND",CR!*,
  2647. 5: "C",TAB!*,"ROOTS OF A POLYNOMIAL",CR!*,
  2648. 5: "C",CR!*;
  2649. 5: B(1) :=: PART (B,1);
  2650. 5: B(2) :=: PART (B,2);
  2651. 5: B(3) :=: PART (B,3);
  2652. 5: B(4) :=: PART (B,4);
  2653. 5: B(5) :=: PART (B,5);
  2654. 5: B(6) :=: PART (B,6);
  2655. 5: B(7) :=: PART (B,7);
  2656. 5: B(8) :=: PART (B,8);
  2657. 5: B(9) :=: PART (B,9);
  2658. 5: B(10) :=: PART (B,10);
  2659. 5: B(11) :=: PART (B,11)
  2660. 5: END
  2661. 5: )
  2662. 5: OUT "graeffe.f"$
  2663. \end{verbatim}
  2664. }
  2665. Contents of file {\tt graeffe.f}:
  2666. \begin{framedverbatim}
  2667. SUBROUTINE GRAEFF(A,B)
  2668. DOUBLE PRECISION A(11),B(11)
  2669. C
  2670. C GRAEFFE ROOT-SQUARING METHOD TO FIND
  2671. C ROOTS OF A POLYNOMIAL
  2672. C
  2673. B(1)=A(11)**2
  2674. B(2)=2.0D0*A(11)*A(9)-A(10)**2
  2675. B(3)=2.0D0*A(11)*A(7)-(2.0D0*A(10)*A(8))+A(9)**2
  2676. B(4)=2.0D0*A(11)*A(5)-(2.0D0*A(10)*A(6))+2.0D0*A(9)*A(7
  2677. . )-A(8)**2
  2678. B(5)=2.0D0*A(11)*A(3)-(2.0D0*A(10)*A(4))+2.0D0*A(9)*A(5
  2679. . )-(2.0D0*A(8)*A(6))+A(7)**2
  2680. B(6)=2.0D0*A(11)*A(1)-(2.0D0*A(10)*A(2))+2.0D0*A(9)*A(3
  2681. . )-(2.0D0*A(8)*A(4))+2.0D0*A(7)*A(5)-A(6)**2
  2682. B(7)=2.0D0*A(9)*A(1)-(2.0D0*A(8)*A(2))+2.0D0*A(7)*A(3)-
  2683. . (2.0D0*A(6)*A(4))+A(5)**2
  2684. B(8)=2.0D0*A(7)*A(1)-(2.0D0*A(6)*A(2))+2.0D0*A(5)*A(3)-
  2685. . A(4)**2
  2686. B(9)=2.0D0*A(5)*A(1)-(2.0D0*A(4)*A(2))+A(3)**2
  2687. B(10)=2.0D0*A(3)*A(1)-A(2)**2
  2688. B(11)=A(1)**2
  2689. RETURN
  2690. END
  2691. \end{framedverbatim}
  2692. \subsection{Code Generation, Segmentation \& Temporary Variables}
  2693. \index{GENTRAN package ! example}
  2694. The following 3 x 3 inertia matrix M was derived in the course of
  2695. some research \footnote{For details see:
  2696. Bos, A. M. and M. J. L. Tiernego. ``Formula Manipulation in the
  2697. Bond Graph Modelling and Simulation of Large Mechanical Systems'',
  2698. {\it Journal of the Franklin Institute} , Pergamon Press Ltd.,
  2699. Vol. 319, No. 1/2, pp. 51-65, January/February 1985.}:
  2700. \begin{eqnarray*}
  2701. M(1,1) & = & 18*\cos (q_3)*\cos (q_2)*m_{30}*p^2 - \sin ^2(q_3) *j_{30}y +
  2702. \sin ^2(q_3) \\
  2703. & & *j_{30}z - 9*\sin ^2(q_3) *m_{30}*p^2 + j_{10}y + j_{30}y +
  2704. m_{10}*p^2 + \\
  2705. & & 18*m_{30}*p^2\\
  2706. M(1,2) & = & 9*\cos (q_3)*\cos (q_2)*m_{30}*p^2 - \sin ^2(q_3) *j_{30}y
  2707. +\sin ^2(q_3) \\
  2708. & & *j_{30}z - 9*\sin ^2(q_3) *m_{30}*p^2 + j_{30}y + 9* m_{30}*p^2\\
  2709. M(2,1) & = & M(1,2)\\
  2710. M(1,3) & = & - 9*\sin (q_3)*\sin (q_2)*m_{30}*p^2\\
  2711. M(3,1) & = & M(1,3)\\
  2712. M(2,2) & = & - \sin ^2(q_3) *j_{30}y + \sin ^2(q_3) *j_{30}z -
  2713. 9*\sin ^2(q_3)*m_{30}*p^2 \\
  2714. & & + j_{30}y + 9*m_{30}*p^2\\
  2715. M(2,3) & = & 0\\
  2716. M(3,2) & = & M(2,3)\\
  2717. M(3,3) & = & 9*m_{30}*p^2 + j_{30}x\\
  2718. \end{eqnarray*}
  2719. We know M is symmetric. We wish to generate numerical code
  2720. to compute values for M and its inverse matrix.
  2721. \subsubsection{Code Generation}
  2722. \label{code:example}
  2723. Generating code for matrix M and its inverse matrix is
  2724. straightforward. We can simply generate an assignment statement
  2725. for each element of M, compute the inverse matrix MIV, and generate
  2726. an assignment statement for each element of MIV. Since we
  2727. know M is symmetric, we know that MIV will also be symmetric. To
  2728. avoid duplicate computations, we will not generate assignments
  2729. for elements below the main diagonals of these matrices. Instead,
  2730. we will copy elements across the main diagonal by generating
  2731. nested loops. The following REDUCE session will write to the file {\tt m1.f}:
  2732. \begin{verbatim}
  2733. 1: IN "m.red"$ % Initialize M
  2734. 2: GENTRANOUT "m1.f"$
  2735. 3: GENTRANLANG!* := 'FORTRAN$
  2736. 4: ON DOUBLE$
  2737. 5: FOR J := 1 : 3 DO
  2738. 5: FOR K := J : 3 DO
  2739. 5: GENTRAN M(J,K) ::=: M(J,K)$
  2740. 6: MIV := M^(-1)$
  2741. 7: FOR J := 1 : 3 DO
  2742. 7: FOR K := J : 3 DO
  2743. 7: GENTRAN MIV(J,K) ::=: MIV(J,K)$
  2744. 8: GENTRAN
  2745. 8: FOR J := 1 : 3 DO
  2746. 8: FOR K := J+1 : 3 DO
  2747. 8: <<
  2748. 8: M(K,J) := M(J,K);
  2749. 8: MIV(K,J) := MIV(J,K)
  2750. 8: >>$
  2751. 9: GENTRANSHUT "m1.f"$
  2752. \end{verbatim}
  2753. The contents of {\tt m1.f} are reproduced in~\ref{appc} on page~\pageref{appc}.
  2754. This code was generated with the segmentation facility turned off. However,
  2755. most FORTRAN compilers cannot handle statements more than 20 lines
  2756. long. The next section shows how to generate segmented assignments.
  2757. \subsubsection{Segmentation}
  2758. \label{seg:example}
  2759. \index{segmented assignments}
  2760. Large arithmetic expressions can be broken into pieces of manageable
  2761. size with the expression segmentation facility. The following REDUCE
  2762. session will write segmented assignment statements to the
  2763. file {\tt m2.f}. Large arithmetic expressions will be broken into
  2764. subexpressions of approximately 300 characters in length.
  2765. \begin{verbatim}
  2766. 1: IN "m.red"$ % Initialize M
  2767. 2: GENTRANOUT "m2.f"$
  2768. 3: ON DOUBLE$
  2769. 4: ON GENTRANSEG$
  2770. 5: MAXEXPPRINTLEN!* := 300$
  2771. 6: FOR J := 1 : 3 DO
  2772. 6: FOR K := J : 3 DO
  2773. 6: GENTRAN M(J,K) ::=: M(J,K)$
  2774. 7: MIV := M^(-1)$
  2775. 8: FOR J := 1 : 3 DO
  2776. 8: FOR K := J : 3 DO
  2777. 8: GENTRAN MIV(J,K) ::=: MIV(J,K)$
  2778. 9: GENTRAN
  2779. 9: FOR J := 1 : 3 DO
  2780. 9: FOR K := J+1 : 3 DO
  2781. 9: <<
  2782. 9: M(K,J) := M(J,K);
  2783. 9: MIV(K,J) := MIV(J,K)
  2784. 9: >>$
  2785. 10: GENTRANSHUT "m2.f"$
  2786. \end{verbatim}
  2787. The contents of file {\tt m2.f} are reproduced in~\ref{appc} on
  2788. page~\pageref{appc}.
  2789. \subsubsection{Generation of Temporary Variables to Suppress Simplification}
  2790. \label{tempvar:example}
  2791. We can dramatically improve the efficiency of the code generated
  2792. in sections~\ref{code:example} on page~\pageref{code:example} and
  2793. \ref{seg:example} on page~\pageref{seg:example}
  2794. by replacing expressions by temporary variables before computing the
  2795. inverse matrix. This effectively suppresses simplification; these
  2796. expressions will not be substituted into later computations. We
  2797. will replace each non-zero element of the REDUCE matrix M by a
  2798. generated variable name, and generate a numerical assignment statement
  2799. to reflect that substitution in the numerical program being generated.
  2800. The following REDUCE session will write to the file {\tt m3.f}:
  2801. \begin{verbatim}
  2802. 1: in "m.red"$ % Initialize M
  2803. 2: GENTRANOUT "m3.f"$
  2804. 3: GENTRANLANG!* := 'FORTRAN$
  2805. 4: ON DOUBLE$
  2806. 5: FOR J := 1 : 3 DO
  2807. 5: FOR K := J : 3 DO
  2808. 5: GENTRAN M(J,K) ::=: M(J,K)$
  2809. 6: SHARE VAR$
  2810. 7: FOR J := 1 : 3 DO
  2811. 7: FOR K := J : 3 DO
  2812. 7: IF M(J,K) NEQ 0 THEN
  2813. 7: <<
  2814. 7: VAR := TEMPVAR(NIL)$
  2815. 7: MARKVAR VAR$
  2816. 7: M(J,K) := VAR$
  2817. 7: M(K,J) := VAR$
  2818. 7: GENTRAN
  2819. 7: EVAL(VAR) := M(EVAL(J),EVAL(K))
  2820. 7: >>$
  2821. 8: COMMENT ** Contents of matrix M: **$
  2822. 9: M;
  2823. [T0 T1 T2]
  2824. [ ]
  2825. [T1 T3 0 ]
  2826. [ ]
  2827. [T2 0 T4]
  2828. 10: MIV := M^(-1)$
  2829. 11: FOR J := 1 : 3 DO
  2830. 11: FOR K := J : 3 DO
  2831. 11: GENTRAN MIV(J,K) ::=: MIV(J,K)$
  2832. 12: GENTRAN
  2833. 12: FOR J := 1 : 3 DO
  2834. 12: FOR K := J+1 : 3 DO
  2835. 12: <<
  2836. 12: M(K,J) := M(J,K);
  2837. 12: MIV(K,J) := MIV(J,K)
  2838. 12: >>$
  2839. 13: GENTRANSHUT "m3.f"$
  2840. \end{verbatim}
  2841. Contents of file {\tt m3.f}:
  2842. \begin{framedverbatim}
  2843. M(1,1)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  2844. . Q3))**2*Y*J30)+DSIN(DBLE(Q3))**2*J30Z+18.0D0*DCOS(DBLE
  2845. . (Q3))*DCOS(DBLE(Q2))*P**2*M30+18.0D0*P**2*M30+P**2*M10
  2846. . +J30Y+J10Y
  2847. M(1,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  2848. . Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*DCOS(DBLE(
  2849. . Q3))*DCOS(DBLE(Q2))*P**2*M30+9.0D0*P**2*M30+J30Y
  2850. M(1,3)=-(9.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**2*M30)
  2851. M(2,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  2852. . Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*P**2*M30+
  2853. . J30Y
  2854. M(2,3)=0.0D0
  2855. M(3,3)=9.0D0*P**2*M30+J30X
  2856. T0=M(1,1)
  2857. T1=M(1,2)
  2858. T2=M(1,3)
  2859. T3=M(2,2)
  2860. T4=M(3,3)
  2861. MIV(1,1)=-(T4*T3)/(T4*T1**2-(T4*T3*T0)+T2**2*T3)
  2862. MIV(1,2)=(T4*T1)/(T4*T1**2-(T4*T3*T0)+T2**2*T3)
  2863. MIV(1,3)=(T2*T3)/(T4*T1**2-(T4*T3*T0)+T2**2*T3)
  2864. MIV(2,2)=(-(T4*T0)+T2**2)/(T4*T1**2-(T4*T3*T0)+T2**2*
  2865. . T3)
  2866. MIV(2,3)=-(T1*T2)/(T4*T1**2-(T4*T3*T0)+T2**2*T3)
  2867. MIV(3,3)=(T1**2-(T3*T0))/(T4*T1**2-(T4*T3*T0)+T2**2*T3)
  2868. DO 25009 J=1,3
  2869. DO 25010 K=J+1,3
  2870. M(K,J)=M(J,K)
  2871. MIV(K,J)=MIV(J,K)
  2872. 25010 CONTINUE
  2873. 25009 CONTINUE
  2874. \end{framedverbatim}
  2875. \subsection{Template Processing} \index{template processing}
  2876. \index{GENTRAN package ! example} \index{Automatic Circuitry Code Generator}
  2877. Circuit simulation plays a vital role in computer hardware
  2878. development. A recent paper\footnote{Loe, K. F., N. Ohsawa, and E.
  2879. Goto. ``Design of an Automatic Circuitry Code Generator (ACCG)'',
  2880. {\it RSYMSAC Proceedings}, Wako-shi, Saitama, Japan. 1984.} describes
  2881. the design of an Automatic Circuitry Code Generator (ACCG), which
  2882. generates circuit simulation programs based on user-supplied circuit
  2883. specifications. The actual code generator consists of a series of
  2884. REDUCE {\bf WRITE} statements, each of which writes one line of
  2885. FORTRAN code.
  2886. This section presents an alternative implementation for the ACCG
  2887. which uses GENTRAN's template processor to generate code. Template
  2888. processing is a much more natural method of code generation than the
  2889. REDUCE {\bf WRITE} statement method.
  2890. First we will put all REDUCE calculations into two files: {\tt rk.red} and
  2891. {\tt ham.red}.
  2892. Contents of file {\tt rk.red}:\footnote{
  2893. Line 11 of procedure RUNGEKUTTA was changed from
  2894. \begin{center}
  2895. {\tt K41 := HH*SUB(TT=TT+HH, P=P+K31, Q=Q+K32, P2);}
  2896. \end{center}
  2897. as given in (Loe84), to
  2898. \begin{center}
  2899. {\tt K42 := HH*SUB(TT=TT+HH, P=P+K31, Q=Q+K32, P2);}
  2900. \end{center}
  2901. }
  2902. \begin{framedverbatim}
  2903. COMMENT -- RUNGE-KUTTA METHOD --$
  2904. PROCEDURE RUNGEKUTTA(P1, P2, P, Q, TT);
  2905. BEGIN
  2906. SCALAR K11,K12,K21,K22,K31,K32,K41,K42;
  2907. K11 := HH*P1;
  2908. K12 := HH*P2;
  2909. K21 := HH*SUB(TT=TT+HH/2, P=P+K11/2, Q=Q+K12/2, P1);
  2910. K22 := HH*SUB(TT=TT+HH/2, P=P+K11/2, Q=Q+K12/2, P2);
  2911. K31 := HH*SUB(TT=TT+HH/2, P=P+K21/2, Q=Q+K22/2, P1);
  2912. K32 := HH*SUB(TT=TT+HH/2, P=P+K21/2, Q=Q+K22/2, P2);
  2913. K41 := HH*SUB(TT=TT+HH, P=P+K31, Q=Q+K32, P1);
  2914. K42 := HH*SUB(TT=TT+HH, P=P+K31, Q=Q+K32, P2);
  2915. PN := P + (K11 + 2*K21 + 2*K31 + K41)/6;
  2916. QN := Q + (K12 + 2*K22 + 2*K32 + K42)/6
  2917. END$
  2918. END$
  2919. \end{framedverbatim}
  2920. Contents of file {\tt ham.red}:
  2921. \begin{framedverbatim}
  2922. COMMENT -- HAMILTONIAN CALCULATION --$
  2923. DIFQ := DF(H,P)$
  2924. DIFP := -DF(H,Q) - SUB(QDOT=P/M, DF(D,QDOT))$
  2925. RUNGEKUTTA(DIFP, DIFQ, P, Q, TT)$
  2926. END$
  2927. \end{framedverbatim}
  2928. Next we will create a template file with an outline of the target
  2929. FORTRAN program and GENTRAN commands.
  2930. Contents of file {\tt runge.tem}:
  2931. \begin{framedverbatim}
  2932. PROGRAM RUNGE
  2933. IMPLICIT DOUBLE PRECISION (K,M)
  2934. C
  2935. C INPUT
  2936. C
  2937. WRITE(6,*) 'INITIAL VALUE OF P'
  2938. READ(5,*) P
  2939. WRITE(6,*) ' P = ', P
  2940. WRITE(6,*) 'INITIAL VALUE OF Q'
  2941. READ(5,*) Q
  2942. WRITE(6,*) ' Q = ', Q
  2943. WRITE(6,*) 'VALUE OF M'
  2944. READ(5,*) M
  2945. WRITE(6,*) ' M = ', M
  2946. WRITE(6,*) 'VALUE OF K0'
  2947. READ(5,*) K0
  2948. WRITE(6,*) ' K0 = ', K0
  2949. WRITE(6,*) 'VALUE OF B'
  2950. READ(5,*) B
  2951. WRITE(6,*) ' B = ', B
  2952. WRITE(6,*) 'STEP SIZE OF T'
  2953. READ(5,*) HH
  2954. WRITE(6,*) ' STEP SIZE OF T = ', HH
  2955. WRITE(6,*) 'FINAL VALUE OF T'
  2956. READ(5,*) TP
  2957. WRITE(6,*) ' FINAL VALUE OF T = ', TP
  2958. C
  2959. C INITIALIZATION
  2960. C
  2961. TT=0.0D0
  2962. ;BEGIN;
  2963. GENTRAN
  2964. LITERAL
  2965. TAB!*, "WRITE(9,*) ' H = ", EVAL(H), "'", CR!*,
  2966. TAB!*, "WRITE(9,*) ' D = ", EVAL(D), "'", CR!*$
  2967. ;END;
  2968. WRITE(9,901) C
  2969. 901 FORMAT(' C= ',D20.10)
  2970. WRITE(9,910) TT, Q, P
  2971. 910 FORMAT(' '3D20.10)
  2972. C
  2973. C LOOP
  2974. C
  2975. ;BEGIN;
  2976. GENTRAN
  2977. REPEAT
  2978. <<
  2979. PN :=: PN;
  2980. Q :=: QN;
  2981. P := PN;
  2982. TT := TT + HH;
  2983. LITERAL
  2984. TAB!*, "WRITE(9,910) TT, QQ, P", CR!*
  2985. >>
  2986. UNTIL TT >= TF$
  2987. ;END;
  2988. STOP
  2989. END
  2990. ;END;
  2991. \end{framedverbatim}
  2992. Now we can generate a circuit simulation program simply by starting
  2993. a REDUCE session and following three steps:
  2994. \begin{enumerate}
  2995. \item Enter circuit specifications.
  2996. \item Perform calculations.
  2997. \item Call the GENTRAN template processor.
  2998. \end{enumerate}
  2999. For example, the following REDUCE session will write a simulation
  3000. program to the file {\tt runge.f}:
  3001. \begin{verbatim}
  3002. 1: COMMENT -- INPUT --$
  3003. 2: K := 1/(2*M)*P^2$ % kinetic energy
  3004. 3: U := K0/2*Q^2$ % potential energy
  3005. 4: D := B/2*QDOT$ % dissipating function
  3006. 5: H := K + U$ % hamiltonian
  3007. 6: COMMENT -- CALCULATIONS --$
  3008. 7: IN "rk.red", "ham.red"$
  3009. 8: COMMENT -- FORTRAN CODE GENERATION --$
  3010. 9: GENTRANLANG!* := 'FORTRAN$
  3011. 10: ON DOUBLE$
  3012. 11: GENTRANIN "runge.tem" OUT "runge.f"$
  3013. \end{verbatim}
  3014. Contents of file {\tt runge.f}:
  3015. \begin{framedverbatim}
  3016. PROGRAM RUNGE
  3017. IMPLICIT DOUBLE PRECISION (K,M)
  3018. C
  3019. C INPUT
  3020. C
  3021. WRITE(6,*) 'INITIAL VALUE OF P'
  3022. READ(5,*) P
  3023. WRITE(6,*) ' P = ', P
  3024. WRITE(6,*) 'INITIAL VALUE OF Q'
  3025. READ(5,*) Q
  3026. WRITE(6,*) ' Q = ', Q
  3027. WRITE(6,*) 'VALUE OF M'
  3028. READ(5,*) M
  3029. WRITE(6,*) ' M = ', M
  3030. WRITE(6,*) 'VALUE OF K0'
  3031. READ(5,*) K0
  3032. WRITE(6,*) ' K0 = ', K0
  3033. WRITE(6,*) 'VALUE OF B'
  3034. READ(5,*) B
  3035. WRITE(6,*) ' B = ', B
  3036. WRITE(6,*) 'STEP SIZE OF T'
  3037. READ(5,*) HH
  3038. WRITE(6,*) ' STEP SIZE OF T = ', HH
  3039. WRITE(6,*) 'FINAL VALUE OF T'
  3040. READ(5,*) TP
  3041. WRITE(6,*) ' FINAL VALUE OF T = ', TP
  3042. C
  3043. C INITIALIZATION
  3044. C
  3045. TT=0.0D0
  3046. WRITE(9,*) ' H = (M*Q**2*K0+P**2)/(2.0D0*M)'
  3047. WRITE(9,*) ' D = (B*QDOT)/2.0D0'
  3048. WRITE(9,901) C
  3049. 901 FORMAT(' C= ',D20.10)
  3050. WRITE(9,910) TT, Q, P
  3051. 910 FORMAT(' '3D20.10)
  3052. C
  3053. C LOOP
  3054. C
  3055. 25001 CONTINUE
  3056. PN=(-(12.0D0*B*M**2*HH)+2.0D0*B*M*K0*HH**3+24.0D0*
  3057. . M**2*P-(24.0D0*M**2*Q*K0*HH)-(12.0D0*M*P*K0*HH**2)
  3058. . +4.0D0*M*Q*K0**2*HH**3+P*K0**2*HH**4)/(24.0D0*M**2
  3059. . )
  3060. Q=(-(12.0D0*B*M*HH**2)+B*K0*HH**4+48.0D0*M**2*Q+
  3061. . 48.0D0*M*P*HH-(24.0D0*M*Q*K0*HH**2)-(8.0D0*P*K0*HH
  3062. . **3)+2.0D0*Q*K0**2*HH**4)/(48.0D0*M**2)
  3063. P=PN
  3064. TT=TT+HH
  3065. WRITE(9,910) TT, QQ, P
  3066. IF (.NOT.TT.GE.TF) GOTO 25001
  3067. STOP
  3068. END
  3069. \end{framedverbatim}
  3070. \section{Symbolic Mode Functions}
  3071. \index{symbolic mode ! in GENTRAN}
  3072. Thus far in this manual, commands have been presented which are meant
  3073. to be used primarily in the algebraic mode of REDUCE. These commands
  3074. are designed to be used interactively. However, many code generation
  3075. applications require code to be generated under program control\footnote{
  3076. \cite{vandenHeuvel:86ms} contains one such example.}. In these
  3077. applications, it is generally more convenient to generate code from
  3078. (computed) prefix forms. Therefore, GENTRAN provides code generation
  3079. and file handling functions designed specifically to be used in the
  3080. symbolic mode of REDUCE. This section presents the symbolic functions
  3081. which are analogous to the code generation, template processing, and
  3082. output file handling commands presented in sections \ref{GENTRAN:inter},
  3083. \ref{GENTRAN:template}, and \ref{GENTRAN:output}.
  3084. \subsection{Code Generation and Translation}
  3085. Sections~\ref{translation} through \ref{comments}
  3086. describe interactive commands and functions which
  3087. generate and translate code, declare variables to be of
  3088. specific types, and insert literal strings of characters into the
  3089. stream of generated code. This section describes analogous symbolic
  3090. mode code generation functions.
  3091. \subsubsection{Translation of Prefix Forms}
  3092. In algebraic mode, the {\bf GENTRAN} command translates algorithmic
  3093. specifications supplied in the form of REDUCE statements into
  3094. numerical code. Similarly, the symbolic function {\bf SYM!-GENTRAN}
  3095. \index{SYM"!-GENTRAN command}
  3096. translates algorithmic specifications supplied in the form of REDUCE
  3097. prefix forms into numerical code.
  3098. \begin{describe}{Syntax:}
  3099. {\bf SYM!-GENTRAN} {\it form\/};
  3100. \end{describe}
  3101. \begin{describe}{Function Type:}
  3102. expr
  3103. \end{describe}
  3104. \begin{describe}{Argument:}
  3105. {\it form\/} is any LISP prefix form that evaluates to a
  3106. REDUCE prefix form that can be translated by GENTRAN into the target
  3107. language\footnote{
  3108. See~\ref{appa} on page~\pageref{appa} for a complete listing of REDUCE
  3109. prefix forms that can be translated.}.
  3110. {\it form\/} may contain any number of occurrences of the special forms
  3111. \ttindex{EVAL} \ttindex{LSETQ} \ttindex{RSETQ} \ttindex{LRSETQ}
  3112. \ttindex{DECLARE} \ttindex{LITERAL}
  3113. {\bf EVAL}, {\bf LSETQ}, {\bf RSETQ}, {\bf LRSETQ}, {\bf DECLARE}, and
  3114. {\bf LITERAL} (see sections~\ref{sym:cg} through \ref{special} on
  3115. pages~\pageref{sym:cg}--\pageref{special}).
  3116. \end{describe}
  3117. \begin{describe}{Side Effects:}
  3118. {\bf SYM!-GENTRAN} translates {\it form\/} into formatted code in the target
  3119. language and writes it to the file(s) currently selected for output.
  3120. \end{describe}
  3121. \begin{describe}{Returned Value:}
  3122. {\bf SYM!-GENTRAN} returns the name(s) of the file(s) to which code
  3123. was written. If code was written to one file, the returned value is an atom;
  3124. otherwise, it is a list.
  3125. \end{describe}
  3126. \begin{describe}{Diagnostic Messages:}
  3127. \begin{verbatim}
  3128. *** OUTPUT FILE ALREADY EXISTS
  3129. OVERWRITE FILE? (Y/N)
  3130. ***** WRONG TYPE OF ARG
  3131. \end{verbatim}
  3132. {\it exp}
  3133. \begin{verbatim}
  3134. ***** CANNOT BE TRANSLATED
  3135. \end{verbatim}
  3136. \end{describe}
  3137. \begin{describe}{\example}\index{GENTRAN package ! example}
  3138. \begin{verbatim}
  3139. 1: SYMBOLIC$
  3140. 2: GENTRANLANG!* := 'FORTRAN$
  3141. 3: SYM!-GENTRAN '(FOR I (1 1 n) DO (SETQ (V I) 0))$
  3142. DO 25001 I=1,N
  3143. V(I)=0.0
  3144. 25001 CONTINUE
  3145. 4: GENTRANLANG!* := 'RATFOR$
  3146. 5: SYM!-GENTRAN '(FOR I (1 1 N) DO
  3147. 5: (FOR J ((PLUS I 1) 1 N) DO
  3148. 5: (PROGN
  3149. 5: (SETQ (X J I) (X I J))
  3150. 5: (SETQ (Y J I) (Y I J)))))$
  3151. DO I=1,N
  3152. DO J=I+1,N
  3153. {
  3154. X(J,I)=X(I,J)
  3155. Y(J,I)=Y(I,J)
  3156. }
  3157. 6: GENTRANLANG!* := 'C$
  3158. 7: SYM!-GENTRAN '(SETQ P (FOR I (1 1 N) PRODUCT I))$
  3159. {
  3160. P=1;
  3161. for (I=1;I<=N;++I)
  3162. P*=I;
  3163. }
  3164. 8: GENTRANLANG!* := 'PASCAL$
  3165. 9: SYM!-GENTRAN '(SETQ C
  3166. 9: (COND ((LESSP A B) A) (T B)))$
  3167. IF A<B THEN
  3168. C:=A;
  3169. ELSE
  3170. C:=B;
  3171. \end{verbatim}
  3172. \end{describe}
  3173. \subsubsection{Code Generation} \index{code generation}
  3174. \label{sym:cg}
  3175. Sections~\ref{eval} through~\ref{lrsetq} on
  3176. pages~\pageref{eval}--\pageref{lrsetq} described the special functions
  3177. and operators {\bf EVAL}, {\bf ::=}, {\bf :=:}, and {\bf ::=:} that
  3178. could be included in arguments to the {\bf GENTRAN} command to
  3179. indicate that parts of those arguments were to be given to REDUCE FOR
  3180. Evaluation prior to translation. This section describes the analogous
  3181. functions that can be supplied in prefix form to the {\bf SYM!-GENTRAN}
  3182. function.
  3183. The following special forms may be interleaved arbitrarily in forms
  3184. supplied as arguments to {\bf SYM!-GENTRAN} to specify partial
  3185. \ttindex{EVAL} \ttindex{LSETQ} \ttindex{RSETQ} \ttindex{LRSETQ}
  3186. evaluation: {\bf EVAL}, {\bf LSETQ}, {\bf RSETQ}, and {\bf LRSETQ}.
  3187. Sections~\ref{sym:eval} through \ref{sym:lrsetq} describe these forms. Then
  3188. section~\ref{lispeval} through \ref{share}
  3189. present examples of the usage of these
  3190. forms for evaluation of expressions in both symbolic and algebraic modes.
  3191. \paragraph{The EVAL Form}
  3192. \label{sym:eval}
  3193. \begin{describe}{Syntax:} \ttindex{EVAL}
  3194. {\bf (EVAL} {\it form\/}{\bf )}
  3195. \end{describe}
  3196. \begin{describe}{Argument:}
  3197. {\it form\/} is any LISP prefix form that evaluates to a REDUCE prefix form
  3198. that can be translated by GENTRAN into the target language.
  3199. \end{describe}
  3200. \paragraph{The LSETQ Form} \ttindex{LSETQ}
  3201. \begin{describe}{Syntax:}
  3202. {\bf (LSETQ} {\it svar exp\/}{\bf )}
  3203. \end{describe}
  3204. \begin{describe}{Arguments:}
  3205. {\it svar\/} is a subscripted variable in LISP prefix form. Its subscripts
  3206. must evaluate to REDUCE prefix forms that can be translated
  3207. into the target language. {\it exp\/} is any REDUCE expression in
  3208. prefix form that can be translated by GENTRAN.
  3209. \end{describe}
  3210. \paragraph{The RSETQ Form} \ttindex{RSETQ}
  3211. \begin{describe}{Syntax:}
  3212. {\bf (RSETQ} {\it var exp\/}{\bf )}
  3213. \end{describe}
  3214. \begin{describe}{Arguments:}
  3215. {\it var\/} is a variable in REDUCE prefix form. {\it exp\/} is a LISP
  3216. prefix form which evaluates to a translatable REDUCE prefix form.
  3217. \end{describe}
  3218. \paragraph{The LRSETQ Form} \ttindex{RSETQ}
  3219. \label{sym:lrsetq}
  3220. \begin{describe}{Syntax:}
  3221. {\bf (LRSETQ} {\it svar exp\/}{\bf )}
  3222. \end{describe}
  3223. \begin{describe}{Arguments:}
  3224. {\it svar\/} is a subscripted variable in LISP prefix form with
  3225. subscripts that evaluate to REDUCE prefix forms
  3226. that can be translated by GENTRAN. {\it exp\/} is a LISP prefix
  3227. form that evaluates to a translatable REDUCE prefix form.
  3228. \end{describe}
  3229. \paragraph{Symbolic Mode Evaluation}
  3230. \label{lispeval}
  3231. The symbolic mode evaluation forms that have just been described are
  3232. analogous to their algebraic mode counterparts, except that
  3233. by default, they evaluate their argument(s) in symbolic mode. The
  3234. following is an example of evaluation of subscripts in symbolic mode:
  3235. \begin{describe}{\example}\index{GENTRAN package ! example}
  3236. \begin{verbatim}
  3237. 1: SYMBOLIC$
  3238. 2: FOR i:=1:2 DO
  3239. 2: FOR j:=1:2 DO
  3240. 2: SYM!-GENTRAN '(LSETQ (M i j) 0)$
  3241. M(1,1)=0.0
  3242. M(1,2)=0.0
  3243. M(2,1)=0.0
  3244. M(2,2)=0.0
  3245. \end{verbatim}
  3246. \end{describe}
  3247. \paragraph{Algebraic Mode Evaluation}
  3248. As we have just seen, the symbolic mode evaluation forms evaluate their
  3249. argument(s) in symbolic mode. This default evaluation mode can be
  3250. overridden by explicitly requesting evaluation in algebraic mode with
  3251. the REDUCE {\bf AEVAL} function.\ttindex{AEVAL}
  3252. \begin{describe}{\example}\index{GENTRAN package ! example}
  3253. \begin{verbatim}
  3254. 1: ALGEBRAIC$
  3255. 2: F := 2*x^2 - 5*X + 6$
  3256. 3: SYMBOLIC$
  3257. 4: SYM!-GENTRAN '(SETQ Q (QUOTIENT
  3258. 4: (EVAL (AEVAL 'F))
  3259. 4: (EVAL (AEVAL '(DF F X)))))$
  3260. Q=(2.0*X**2-5.0*X+6.0)/(4.0*X-5.0)
  3261. 5: ALGEBRAIC$
  3262. 6: M := MAT(( A, 0, -1, 1),
  3263. 6: ( 0, B^2, 0, 1),
  3264. 6: (-1, B, B*C, 0),
  3265. 6: ( 1, 0, -C, -D))$
  3266. 7: SYMBOLIC$
  3267. 8: FOR i:=1:4 DO
  3268. 8: SYM!-GENTRAN '(LRSETQ (M i i)
  3269. (AEVAL (MKQUOTE (LIST 'M i i))))$
  3270. M(1,1)=A
  3271. M(2,2)=B**2
  3272. M(3,3)=B*C
  3273. M(4,4)=-D
  3274. \end{verbatim}
  3275. \end{describe}
  3276. \paragraph{SHAREd Variables}
  3277. \label{share} \index{SHARE command}
  3278. The REDUCE {\bf SHARE} command enables variables to be shared
  3279. between algebraic and symbolic modes. Thus, we can derive an expression in
  3280. algebraic mode, assign it to a shared variable, and then access the value
  3281. of that variable to generate code from symbolic mode.
  3282. \begin{describe}{Example:}
  3283. \begin{verbatim}
  3284. 1: ALGEBRAIC$
  3285. 2: SHARE dfx1$
  3286. 3: dfx1 := DF(X**4 - X**3 + 2*X**2 + 1, X)$
  3287. 4: SYMBOLIC$
  3288. 5: SYM!-GENTRAN '(RSETQ DERIV dfx1)$
  3289. DERIV=4.0*X**3-(3.0*X**2)+4.0*X
  3290. \end{verbatim}
  3291. \end{describe}
  3292. \subsubsection{Special Translatable Forms}
  3293. \label{special}
  3294. Sections~\ref{explicit:type} through \ref{comments} described special
  3295. functions that could be used to declare variable types and insert
  3296. literal strings of characters into generated code. This section
  3297. contains explanations of analogous prefix forms for usage in symbolic
  3298. mode.
  3299. \paragraph{Explicit Type Declarations}
  3300. A similar form of the algebraic mode {\bf DECLARE} function is provided in
  3301. symbolic mode:
  3302. \begin{describe}{Syntax:} \index{DECLARE function}
  3303. \begin{tabular}{ll}
  3304. {\bf (DECLARE} & {\bf (}{\it type1 v1 v2 \dots\ vn1\/}{\bf )}\\
  3305. & {\bf (}{\it type2 v1 v2 \dots\ vn2\/}{\bf )}\\
  3306. & \ \ \ :\\
  3307. & {\bf (}{\it typen v1 v2 \dots\ vnn\/}{\bf )) }\\
  3308. \end{tabular}
  3309. \end{describe}
  3310. \begin{describe}{Arguments:}
  3311. Each {\it v1 v2 \dots\ vn\/} is a sequence of one or more variables
  3312. (optionally subscripted to indicate array dimensions -- in prefix form), or
  3313. variable ranges (two letters concatenated together with "-" in between). {\it
  3314. v\/}s are not evaluated unless given as arguments to {\bf EVAL}.
  3315. Each {\it type\/} is a variable type in the target language. Each
  3316. must be an atom, optionally concatenated to the atom {\bf IMPLICIT!\ }
  3317. (note the trailing space). \index{IMPLICIT"! atom}
  3318. {\it type\/}s are not evaluated unless given as arguments to {\bf EVAL}.
  3319. \end{describe}
  3320. \begin{describe}{Side Effect:}
  3321. Entries are placed in the symbol table for each variable or
  3322. variable range declared in the call to this function. The
  3323. function call itself is removed from the statement group
  3324. being translated. Then after translation, type declarations are
  3325. generated from these symbol table entries before the resulting
  3326. executable statements are printed.
  3327. \end{describe}
  3328. \begin{describe}{\example}\index{GENTRAN package ! example}
  3329. \begin{verbatim}
  3330. 1: SYMBOLIC$
  3331. 2: GENTRANLANG!* := 'FORTRAN$
  3332. 3: SYM!-GENTRAN
  3333. 3: '(PROGN
  3334. 3: (DECLARE (IMPLICIT! REAL!*8 A!-H O!-Z)
  3335. 3: (INTEGER (M 4 4)))
  3336. 3: (FOR I (1 1 4) DO
  3337. 3: (FOR J (1 1 4) DO
  3338. 3: (COND ((EQUAL I J) (SETQ (M I J) 1))
  3339. 3: (T (SETQ (M I J) 0)))))
  3340. 3: (DECLARE (INTEGER I J))
  3341. :
  3342. :
  3343. 3: )$
  3344. IMPLICIT REAL*8 (A-H,O-Z)
  3345. INTEGER M(4,4),I,J
  3346. DO 25001 I=1,4
  3347. DO 25002 J=1,4
  3348. IF (I.EQ.J) THEN
  3349. M(I,J)=1
  3350. ELSE
  3351. M(I,J)=0
  3352. ENDIF
  3353. 25002 CONTINUE
  3354. 25001 CONTINUE
  3355. :
  3356. :
  3357. 4: GENTRANLANG!* := 'RATFOR$
  3358. 5: SYM!-GENTRAN
  3359. 5: '(PROCEDURE FAC NIL EXPR (N)
  3360. 5: (BLOCK ()
  3361. 5: (DECLARE (FUNCTION FAC)
  3362. 5: (INTEGER FAC N))
  3363. 5: (SETQ F (FOR I (1 1 N) PRODUCT I))
  3364. 5: (DECLARE (INTEGER F I))
  3365. 5: (RETURN F)))$
  3366. INTEGER FUNCTION FAC(N)
  3367. INTEGER N,F,I
  3368. {
  3369. F=1
  3370. DO I=1,N
  3371. F=F*I
  3372. }
  3373. RETURN(F)
  3374. END
  3375. 6: GENTRANLANG!* := 'C$
  3376. 7: SYM!-GENTRAN
  3377. 7: '(PROCEDURE FAC NIL EXPR (N)
  3378. 7: (BLOCK ()
  3379. 7: (DECLARE (INTEGER FAC N I F))
  3380. 7: (SETQ F (FOR I (1 1 N) PRODUCT I))
  3381. 7: (RETURN F)))$
  3382. int FAC(N)
  3383. int N;
  3384. {
  3385. int I,F;
  3386. {
  3387. F=1;
  3388. for (I=1;I<=N;++I)
  3389. F*=I;
  3390. }
  3391. return(F);
  3392. }
  3393. 8: GENTRANLANG!* := 'PASCAL$
  3394. 9: SYM!-GENTRAN
  3395. 9: '(PROCEDURE FAC NIL EXPR (N)
  3396. 9: (BLOCK ()
  3397. 9: (DECLARE (INTEGER FAC N I F))
  3398. 9: (SETQ F (FOR I (1 1 N) PRODUCT I))
  3399. 9: (RETURN F)))$
  3400. FUNCTION FAC(N:INTEGER):INTEGER;
  3401. LABEL
  3402. 99999;
  3403. VAR
  3404. I,F: INTEGER;
  3405. BEGIN
  3406. BEGIN
  3407. F:=1;
  3408. FOR I:=1 TO N DO
  3409. F:=F*I
  3410. END;
  3411. BEGIN
  3412. FAC:=F;
  3413. GOTO 99999{RETURN}
  3414. END;
  3415. 99999:
  3416. END;
  3417. \end{verbatim}
  3418. \end{describe}
  3419. \paragraph{Comments and Literal Strings}
  3420. \index{comments ! in GENTRAN} \index{literals ! in GENTRAN}
  3421. \ttindex{LITERAL}
  3422. A form similar to the algebraic mode {\bf LITERAL} function is provided in
  3423. symbolic mode:
  3424. \begin{describe}{Syntax:}
  3425. {\bf (LITERAL} {\it arg1 arg2 \dots\ argn\/}{\bf )}
  3426. \end{describe}
  3427. \begin{describe}{Arguments:}
  3428. {\it arg1 arg2 \dots\ argn\/} is an argument sequence containing one or more
  3429. {\it arg\/}s, where each {\it arg\/} either is, or evaluates to, an atom. The
  3430. atoms {\bf TAB!*} and {\bf CR!*} have special meanings. \ttindex{TAB"!*}
  3431. \ttindex{CR"!*} {\it arg\/}s are
  3432. not evaluated unless given as arguments to {\bf EVAL}.
  3433. \end{describe}
  3434. \begin{describe}{Side Effect:}
  3435. This form is replaced by the character sequence resulting from
  3436. concatenation of the given atoms. Double quotes are stripped from
  3437. all string type {\it arg\/}s, and the reserved atoms {\bf TAB!*}
  3438. and {\bf CR!*} are replaced by a tab to the current level of indentation,
  3439. and an end-of-line character, respectively.
  3440. \end{describe}
  3441. \begin{describe}{\example}\index{GENTRAN package ! example}
  3442. \begin{verbatim}
  3443. 1: SYMBOLIC$
  3444. 2: GENTRANLANG!* := 'FORTRAN$
  3445. 3: N := 100$
  3446. 4: SYM!-GENTRAN
  3447. 4: '(PROGN
  3448. 4: (LITERAL C TAB!* "--THIS IS A FORTRAN COMMENT--"
  3449. 4: CR!* C CR!*)
  3450. 4: (LITERAL TAB!* "DATA N/" (EVAL N) "/" CR!*))$
  3451. C --THIS IS A FORTRAN COMMENT--
  3452. C
  3453. DATA N/100/
  3454. 5: GENTRANLANG!* := 'RATFOR$
  3455. 6: SYM!-GENTRAN
  3456. 6: '(FOR I (1 1 N) DO
  3457. 6: (PROGN
  3458. 6: (LITERAL TAB!* "# THIS IS A RATFOR COMMENT" CR!*)
  3459. 6: (LITERAL TAB!* "WRITE(6,10) (M(I,J),J=1,N)" CR!*
  3460. 6: 10 TAB!* "FORMAT(1X,10(I5,3X))" CR!*)))$
  3461. DO I=1,N
  3462. {
  3463. # THIS IS A RATFOR COMMENT
  3464. WRITE(6,10) (M(I,J),J=1,N)
  3465. 10 FORMAT(1X,10(I5,3X))
  3466. }
  3467. 7: GENTRANLANG!* := 'C$
  3468. 8: SYM!-GENTRAN
  3469. 8: '(PROGN
  3470. 8: (SETQ X 0)
  3471. 8: (LITERAL "/* THIS IS A" CR!* "
  3472. 8: C COMMENT */" CR!*))$
  3473. {
  3474. X=0.0;
  3475. /* THIS IS A
  3476. C COMMENT */
  3477. }
  3478. 9: GENTRANLANG!* := 'PASCAL$
  3479. 10: SYM!-GENTRAN
  3480. 10: '(PROGN
  3481. 10: (SETQ X (SIN Y))
  3482. 10: (LITERAL "{ THIS IS A PASCAL COMMENT }" CR!*))$
  3483. BEGIN
  3484. X:=SIN(Y)
  3485. { THIS IS A PASCAL COMMENT }
  3486. END;
  3487. \end{verbatim}
  3488. \end{describe}
  3489. \subsection{Template Processing}
  3490. \index{template processing}
  3491. The template processor can be invoked from either algebraic or
  3492. symbolic mode. Section~\ref{templates} described the algebraic mode
  3493. command. This section describes the analogous symbolic mode function.
  3494. \begin{describe}{Syntax:}\index{SYM"!-GENTRANIN command}
  3495. {\bf SYM!-GENTRANIN} {\it list-of-fnames\/};
  3496. \end{describe}
  3497. \begin{describe}{Function Type:}
  3498. expr
  3499. \end{describe}
  3500. \begin{describe}{Argument:}
  3501. {\it list-of-fnames\/} evaluates to a LISP list containing one or more
  3502. {\it fname\/}s, where each {\it fname\/} is one of:
  3503. \begin{tabular}{lll}
  3504. {\it an atom} & = & a template (input) file\\
  3505. {\bf T} & = & the terminal\\
  3506. \end{tabular}
  3507. \end{describe}
  3508. \begin{describe}{Side Effects:}
  3509. {\bf SYM!-GENTRANIN} processes each template file in {\it list-of-fnames\/}
  3510. sequentially.
  3511. A template file may contain any number of parts, each of which
  3512. is either an active or an inactive part. All active parts start with
  3513. the character sequence {\bf ;BEGIN;} and end with {\bf ;END;}. The end
  3514. of the template file is indicated by an extra {\bf ;END;} character sequence.
  3515. Inactive parts of template files are assumed to contain code in
  3516. the target language (FORTRAN, RATFOR, PASCAL or C, depending on
  3517. the value of the global varibale {\bf GENTRANLANG!*}). All
  3518. inactive parts are copied to the output. Comments delimited
  3519. by the appropriate characters are also copied in their entirety
  3520. to the output. Thus the character sequences {\bf ;BEGIN;} and {\bf ;END;}
  3521. have no special meanings within comments. \index{;BEGIN; marker}
  3522. \index{;END; marker}
  3523. Active parts may contain any number of REDUCE expressions, statements,
  3524. and commands. They are not copied directly to the output. Instead,
  3525. they are given to REDUCE for evaluation in algebraic mode\footnote{
  3526. Active parts are evaluated in algebraic mode unless the mode is
  3527. explicitly changed to symbolic from within the active part itself.
  3528. This is true regardless of which mode the system was in when the
  3529. template processor was called.}. All output generated by each
  3530. evaluation is sent to the file(s) currently selected for output.
  3531. Returned values are only printed on the terminal.
  3532. Active parts will most likely contain calls to GENTRAN to generate
  3533. code. This means that the result of processing a template file will
  3534. be the original template file with all active parts replaced by
  3535. generated code.
  3536. \end{describe}
  3537. \begin{describe}{Returned Value:}
  3538. {\bf SYM!-GENTRANIN} returns the name(s) of the file(s) to which code was
  3539. written. If code was written to one file, the returned value is an atom;
  3540. otherwise, it is a list.
  3541. \end{describe}
  3542. \begin{describe}{Diagnostic Messages:}
  3543. \begin{verbatim}
  3544. *** OUTPUT FILE ALREADY EXISTS
  3545. OVERWRITE FILE? (Y/N)
  3546. ***** NONEXISTENT INPUT FILE
  3547. ***** TEMPLATE FILE ALREADY OPEN FOR INPUT
  3548. ***** WRONG TYPE OF ARG
  3549. \end{verbatim}
  3550. \end{describe}
  3551. \subsection{Output Redirection}
  3552. \index{output redirection (temporary)}
  3553. Section~\ref{GENTRAN:output} describes four slgebraic mode commands
  3554. which select, open, and close output files. The algebraic mode commands
  3555. \index{GENTRANOUT command} \index{GENTRANSHUT command}
  3556. \index{GENTRANPUSH command} \index{GENTRANPOP command}
  3557. {\bf GENTRANOUT}, {\bf GENTRANSHUT}, {\bf GENTRANPUSH}, and {\bf
  3558. GENTRANPOP} are analogous to the symbolic mode {\bf
  3559. SYM!-GENTRANOUT}, {\bf SYM!-GENTRANSHUT}, {\bf SYM!-GENTRANPUSH}, and
  3560. {\bf SYM!-GENTRANPOP} functions, respectively.
  3561. \subsubsection{SYM!-GENTRANOUT} \index{SYM"!-GENTRANOUT command}
  3562. \begin{describe}{Syntax:}
  3563. {\bf SYM!-GENTRANOUT} {\it list-of-fnames\/};
  3564. \end{describe}
  3565. \begin{describe}{Function Type:}
  3566. expr
  3567. \end{describe}
  3568. \begin{describe}{Argument:}
  3569. {\it list-of-fnames\/} evaluates to a LISP list containing one or more
  3570. {\it fname\/}s, where each {\it fname} is one of:
  3571. \begin{tabular}{lll}
  3572. {\it an atom} & = & an output file\\
  3573. {\bf T} & = & the terminal\\
  3574. {\bf NIL} & = & the current output file(s)\\
  3575. {\bf ALL!*} & = & all files currently open for output \\
  3576. & & by GENTRAN\\
  3577. \end{tabular}
  3578. \end{describe}
  3579. \begin{describe}{Side Effect:}
  3580. GENTRAN maintains a list of files currently open for output by GENTRAN
  3581. {\it only}. {\bf SYM!-GENTRANOUT} inserts each file name represented in
  3582. {\it list-of-fnames\/} into that list and opens each one
  3583. for output. It also resets the currently selected output file(s) to be
  3584. all of the files represented in {\it list-of-fnames}.
  3585. \end{describe}
  3586. \begin{describe}{Returned Value:}
  3587. {\bf SYM!-GENTRANOUT} returns the name(s) of the file(s) represented
  3588. by {\it list-of-fnames\/}; i.e., the current output file(s) after the
  3589. command has been executed. If there is only one file
  3590. selected for output, the returned value is an atom; otherwise, it is
  3591. a list.
  3592. \end{describe}
  3593. \begin{describe}{Diagnostic Messages:}
  3594. \begin{verbatim}
  3595. *** OUTPUT FILE ALREADY EXISTS
  3596. OVERWRITE FILE? (Y/N)
  3597. ***** WRONG TYPE OF ARG
  3598. \end{verbatim}
  3599. \end{describe}
  3600. \subsubsection{SYM!-GENTRANSHUT}\index{SYM"!-GENTRANSHUT command}
  3601. \begin{describe}{Syntax:}
  3602. {\bf SYM!-GENTRANSHUT} {\it list-of-fnames\/} ;
  3603. \end{describe}
  3604. \begin{describe}{Function Type:}
  3605. expr
  3606. \end{describe}
  3607. \begin{describe}{Argument:}
  3608. {\it list-of-fnames\/} evaluates to a LISP list containing one or more
  3609. {\it fnames}, where each {\it fname\/} is one of:
  3610. \begin{tabular}{lll}
  3611. {\it an atom} & = & an output file\\
  3612. {\bf NIL} & = & the current output file(s)\\
  3613. {\bf ALL!*} & = & all files currently open for output \\
  3614. & & by GENTRAN\\
  3615. \end{tabular}
  3616. \end{describe}
  3617. \begin{describe}{Side Effects:}
  3618. {\bf SYM!-GENTRANSHUT} creates a list of file names from {\it list-of-fnames},
  3619. deletes each from the output file list,
  3620. and closes the corresponding files. If (all of) the
  3621. current output file(s) are closed, then the current output
  3622. file is reset to the terminal.
  3623. \end{describe}
  3624. \begin{describe}{Returned Value:}
  3625. {\bf SYM!-GENTRANSHUT} returns the name(s) of the file(s) selected for
  3626. output after the command has been executed. If there is
  3627. only one file selected for output, the returned value is an atom;
  3628. otherwise, it is a list.
  3629. \end{describe}
  3630. \begin{describe}{Diagnostic Messages:}
  3631. \begin{verbatim}
  3632. *** FILE NOT OPEN FOR OUTPUT
  3633. ***** WRONG TYPE OF ARG
  3634. \end{verbatim}
  3635. \end{describe}
  3636. \subsubsection{SYM!-GENTRANPUSH}\index{SYM"!-GENTRANPUSH command}
  3637. \begin{describe}{Syntax:}
  3638. {\bf SYM!-GENTRANPUSH} {\it list-of-fnames\/};
  3639. \end{describe}
  3640. \begin{describe}{Function Type:}
  3641. expr
  3642. \end{describe}
  3643. \begin{describe}{Argument:}
  3644. {\it list-of-fnames\/} evaluates to a LISP list containing one or more
  3645. {\it fname}s, each of which is one of:
  3646. \begin{tabular}{lll}
  3647. {\it an atom} & = & an output file\\
  3648. {\bf T} & = & the terminal\\
  3649. {\bf NIL} & = & the current output file(s)\\
  3650. {\bf ALL!*} & = & all files currently open for output \\
  3651. & & by GENTRAN\\
  3652. \end{tabular}
  3653. \end{describe}
  3654. \begin{describe}{Side Effects:}
  3655. {\bf SYM!-GENTRANPUSH} creates a list of file name(s) from
  3656. {\it lis-of-fnames\/}
  3657. and pushes that list onto the output stack. Each file in the list that
  3658. is not already open for output is opened at this time. The current
  3659. output file is reset to this new element on the top of the stack.
  3660. \end{describe}
  3661. \begin{describe}{Returned Value:}
  3662. {\bf SYM!-GENTRANPUSH} returns the name(s) of the file(s) represented by
  3663. {\it list-of-fnames\/}; i.e., the current output
  3664. file(s) after the command has been executed. If there is
  3665. only one file selected for output, the returned value is an
  3666. atom; otherwise, it is a list.
  3667. \end{describe}
  3668. \begin{describe}{Diagnostic Messages:}
  3669. \begin{verbatim}
  3670. *** OUTPUT FILE ALREADY EXISTS
  3671. OVERWRITE FILE? (Y/N)
  3672. ***** WRONG TYPE OF ARG
  3673. \end{verbatim}
  3674. \end{describe}
  3675. \subsubsection{SYM!-GENTRANPOP} \index{SYM"!-GENTRANPOP command}
  3676. \begin{describe}{Syntax:}
  3677. {\bf SYM!-GENTRANPOP} {\it list-of-fnames\/};
  3678. \end{describe}
  3679. \begin{describe}{Function Type:}
  3680. expr
  3681. \end{describe}
  3682. \begin{describe}{Argument:}
  3683. {\it list-of-fnames\/} evaluates to a LISP list containing one or more
  3684. {\it fname\/}s, where each {\it fname\/} is one of:
  3685. \begin{tabular}{lll}
  3686. {\it an atom} & = & an output file\\
  3687. {\bf T} & = & the terminal\\
  3688. {\bf NIL} & = & the current output file(s)\\
  3689. {\bf ALL!*} & = & all files currently open for output \\
  3690. & & by GENTRAN\\
  3691. \end{tabular}
  3692. \end{describe}
  3693. \begin{describe}{Side Effects:}
  3694. {\bf SYM!-GENTRANPOP} deletes the top-most occurrence of the
  3695. single element containing the file name(s) represented by
  3696. {\it list-of-fnames\/} from the output stack. Files whose names have been
  3697. completely removed from the output stack are closed. The current output file
  3698. is reset to the (new) element on the top of the output stack.
  3699. \end{describe}
  3700. \begin{describe}{Returned Value:}
  3701. {\bf SYM!-GENTRANPOP} returns the name(s) of the file(s)
  3702. selected for output after the command has been executed. If there is
  3703. only one file selected for output, the returned value is an atom; otherwise,
  3704. it is a list.
  3705. \end{describe}
  3706. \begin{describe}{Diagnostic Messages:}
  3707. \begin{verbatim}
  3708. *** FILE NOT OPEN FOR OUTPUT
  3709. ***** WRONG TYPE OF ARG
  3710. \end{verbatim}
  3711. \end{describe}
  3712. \section{Translatable REDUCE Expressions \& Statements}
  3713. \label{appa}
  3714. A substantial subset of all REDUCE expressions and statements
  3715. can be translated by GENTRAN into semantically equivalent code
  3716. in the target numerical language\footnote{
  3717. It should be noted that call-by-value parameter passing is used
  3718. in REDUCE, whereas call-by-address parameter passing is normally
  3719. used in FORTRAN and RATFOR. GENTRAN does {\it not} attempt
  3720. to simulate call-by-value passing in FORTRAN and RATFOR, although
  3721. this could be done by generating temporary variables, assigning
  3722. values to them, and using them in subprogram calls.
  3723. \index{call-by-value} \index{call-by-address}}. This
  3724. section contains examples and a formal definition of translatable REDUCE
  3725. expressions and statements.
  3726. \subsection{Examples of Translatable Statements}
  3727. The following three tables contain listings of REDUCE statement types
  3728. that can be translated by GENTRAN. An example of each statement
  3729. type is shown, and FORTRAN, RATFOR, PASCAL and C code generated for each
  3730. example is also shown.
  3731. \begin{table}
  3732. \begin{tabular}{||l|l|l||}\hline\hline
  3733. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3734. & \multicolumn{1}{c||}{\bf FORTRAN CODE} \\ \hline\hline
  3735. simple &{\bf V:=X\^{}2+X\$} &\verb! V=X**2+X!\\
  3736. & & \\
  3737. matrix &{\bf M:=MAT((U,V),} &\verb! M(1,1)=U!\\
  3738. & {\bf\ \ \ \ \ \ \ \ (W,X))\$ } &\verb! M(1,2)=V!\\
  3739. & &\verb! M(2,1)=W!\\
  3740. & &\verb! M(2,2)=X!\\
  3741. & & \\
  3742. sum &{\bf S:=FOR I:=1:10} &\verb! S=0.0!\\
  3743. &{\bf\ \ \ \ \ \ SUM V(I)\$} &\verb! DO 25001 I=1,10!\\
  3744. & &\verb! S=S+V(I)!\\
  3745. & &\verb!25001 CONTINUE!\\
  3746. & & \\
  3747. product &{\bf P:=FOR I:=2 STEP 2} &\verb! P=1!\\
  3748. &{\bf\ \ \ \ \ \ \ \ UNTIL N} &\verb! DO 25002 I=2,N,2!\\
  3749. &{\bf \ \ \ \ PRODUCT I\$} &\verb! P=P*I!\\
  3750. & &\verb!25002 CONTINUE!\\
  3751. & & \\
  3752. conditional & {\bf X := IF A$<$B THEN} &\verb! IF (A.LT.B) THEN!\\
  3753. & {\bf \ \ \ \ \ \ \ \ A ELSE B\$} &\verb! X=A!\\
  3754. & &\verb! ELSE!\\
  3755. & &\verb! X=B!\\
  3756. & &\verb! ENDIF!\\
  3757. & & \\ \hline\hline
  3758. \end{tabular}
  3759. \caption{REDUCE assignments translatable to FORTRAN}
  3760. \end{table}
  3761. \begin{table}
  3762. \begin{tabular}{||l|l|l||}\hline\hline
  3763. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3764. & \multicolumn{1}{c||}{\bf FORTRAN CODE} \\ \hline\hline
  3765. for &{\bf FOR I:=1:8 DO} &\verb! DO 25003 I=1,8!\\
  3766. &{\bf \ \ \ \ V(I):=0.0\$} &\verb! V(I)=0.0!\\
  3767. & &\verb!25003 CONTINUE!\\
  3768. & & \\
  3769. while &{\bf WHILE F(N)$>$0.0 DO} &\verb!25004 IF(.NOT.F(N).GT.0.0)!\\
  3770. & &\verb! . GOTO 25005!\\
  3771. &{\bf \ \ \ \ N:=N+1\$} &\verb! N=N+1!\\
  3772. & &\verb! GOTO 25004!\\
  3773. & &\verb!25005 CONTINUE!\\
  3774. & & \\
  3775. repeat &{\bf REPEAT X:=X/2.0} &\verb!25006 CONTINUE!\\
  3776. &{\bf \ \ \ \ UNTIL F(X)$<$0.0\$} &\verb! X=X/2.0!\\
  3777. & &\verb! IF(.NOT.F(X).LT.0.0)!\\
  3778. & &\verb! . GOTO 25006!\\
  3779. & & \\\hline\hline
  3780. \end{tabular}
  3781. \caption{REDUCE Loop structures translatable to FORTRAN}
  3782. \end{table}
  3783. \begin{table}
  3784. \begin{tabular}{||l|l|l||}\hline\hline
  3785. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3786. & \multicolumn{1}{c||}{\bf FORTRAN CODE} \\ \hline\hline
  3787. Conditionals:& &\\
  3788. & &\\
  3789. if &{\bf IF X$>$0.0} &\verb! IF (X.GT.0.0) THEN!\\
  3790. & {\bf \ \ \ \ \ \ \ THEN Y:=X\$} &\verb! Y=X!\\
  3791. & &\verb! ENDIF!\\
  3792. & &\\
  3793. if - else &{\bf IF X$>$0.0 THEN Y:=X} &\verb! IF (X.GT.0.0) THEN!\\
  3794. &{\bf\ \ \ \ ELSE Y:=-X\$}&\verb! Y=X!\\
  3795. & &\verb! ELSE!\\
  3796. & &\verb! Y=-X!\\
  3797. & &\verb! ENDIF!\\
  3798. & & \\\hline
  3799. Unconditional& &\\
  3800. Transfer of & &\\
  3801. Control: & &\\
  3802. & &\\
  3803. goto&{\bf GOTO LOOP\$} &\verb! GOTO 25010!\\
  3804. & &\\
  3805. call&{\bf CALCV(V,X,Y,Z)\$} &\verb! CALL CALCV(V,X,Y,Z)!\\
  3806. & &\\
  3807. return &{\bf RETURN X\^{}2\$} &\verb! !{\it
  3808. functionname\/}\verb!=X**2!\\
  3809. & &\verb! RETURN!\\
  3810. & & \\\hline
  3811. Sequences \& & &\\
  3812. Groups: & &\\
  3813. & &\\
  3814. sequence &{\bf $<$$<$ U:=X\^{}2;}&\verb! U=X**2!\\
  3815. & {\bf \ \ \ \ \ \ \ \ V:=Y\^{}2$>$$>$\$} &\verb! V=Y**2!\\
  3816. & &\\
  3817. group &{\bf BEGIN}&\verb! U=X**2!\\
  3818. &{\bf\ \ \ \ U:=X\^{}2;}&\verb! V=Y**2!\\
  3819. &{\bf\ \ \ \ V:=Y\^{}2} &\\
  3820. &{\bf END\$}&\\
  3821. & & \\\hline\hline
  3822. \end{tabular}
  3823. \caption{REDUCE control structures translatable to FORTRAN}
  3824. \end{table}
  3825. \begin{table}
  3826. \begin{tabular}{||l|l|l||}\hline\hline
  3827. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3828. & \multicolumn{1}{c||}{\bf RATFOR CODE} \\ \hline\hline
  3829. Assignments: & &\\
  3830. & & \\
  3831. simple &{\bf V:=X\^{}2+X\$} &\verb!V=X**2+X!\\
  3832. & & \\
  3833. matrix &{\bf M:=MAT((U,V),(W,X))\$} &\verb!M(1,1)=U!\\
  3834. & &\verb!M(1,2)=V!\\
  3835. & &\verb!M(2,1)=W!\\
  3836. & &\verb!M(2,2)=X!\\
  3837. & & \\
  3838. sum &{\bf S:=FOR I:=1:10} &\verb!S=0.0!\\
  3839. &{\bf\ \ \ \ \ \ SUM V(I)\$} &\verb!DO I=1,10!\\
  3840. & &\verb! S=S+V(I)!\\
  3841. & & \\
  3842. product &{\bf P:=FOR I:=2 STEP 2} &\verb!P=1!\\
  3843. &{\bf\ \ \ \ \ \ \ \ UNTIL N} &\verb!DO I=2,N,2!\\
  3844. &{\ \ \ \ PRODUCT I\$} &\verb! P=P*I!\\
  3845. & & \\
  3846. conditional & {\bf X := IF A$<$B THEN} &\verb!IF (A<B)!\\
  3847. & {\bf \ \ \ \ \ \ \ \ A ELSE B\$} &\verb! X=A!\\
  3848. & &\verb!ELSE!\\
  3849. & &\verb! X=B!\\
  3850. & & \\\hline
  3851. Control & & \\
  3852. Structures: & &\\
  3853. & & \\
  3854. Loops: & &\\
  3855. & &\\
  3856. for &{\bf FOR I:=1:8 DO} &\verb!DO I=1,8!\\
  3857. &{\bf \ \ \ \ V(I):=0.0\$} &\verb! V(I)=0.0!\\
  3858. & & \\
  3859. while &{\bf WHILE F(N)$>$0.0 DO} &\verb!WHILE(F(N)>0.0)!\\
  3860. &{\bf \ \ \ \ N:=N+1\$} &\verb! N=N+1!\\
  3861. & & \\
  3862. repeat &{\bf REPEAT X:=X/2.0} &\verb!REPEAT!\\
  3863. &{\bf \ \ \ \ UNTIL F(X)$<$0.0\$} &\verb! X=X/2.0!\\
  3864. & &\verb!UNTIL(F(X)<0.0)!\\
  3865. & & \\\hline\hline
  3866. \end{tabular}
  3867. \caption{REDUCE forms translatable to RATFOR}
  3868. \end{table}
  3869. \begin{table}
  3870. \begin{tabular}{||l|l|l||}\hline\hline
  3871. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3872. & \multicolumn{1}{c||}{\bf RATFOR CODE} \\ \hline\hline
  3873. Conditionals:& &\\
  3874. & &\\
  3875. if &{\bf IF X$>$0.0 THEN Y:=X\$} &\verb!IF(X>0.0)!\\
  3876. & &\verb! Y=X!\\
  3877. & &\\
  3878. if - else &{\bf IF X$>$0.0 THEN Y:=X} &\verb!IF(X>0.0)!\\
  3879. &{\bf\ \ \ \ ELSE Y:=-X\$}&\verb! Y=X!\\
  3880. & &\verb!ELSE!\\
  3881. & &\verb! Y=-X!\\
  3882. & & \\\hline
  3883. Unconditional& &\\
  3884. Transfer of & &\\
  3885. Control: & &\\
  3886. & &\\
  3887. goto&{\bf GOTO LOOP\$} &\verb!GOTO 25010!\\
  3888. & &\\
  3889. call&{\bf CALCV(V,X,Y,Z)\$} &\verb!CALL CALCV(V,X,Y,Z)!\\
  3890. & &\\
  3891. return &{\bf RETURN X\^{}2\$} &\verb!RETURN(X**2)!\\
  3892. & & \\\hline
  3893. Sequences \& & &\\
  3894. Groups: & &\\
  3895. & &\\
  3896. sequence &{\bf $<$$<$ U:=X\^{}2;V:=Y\^{}2$>$$>$\$}&\verb!U=X**2!\\
  3897. & &\verb!V=Y**2!\\
  3898. & &\\
  3899. group &{\bf BEGIN}&\verb!{!\\
  3900. &{\bf\ \ \ \ U:=X\^{}2;}& \verb! U=X**2!\\
  3901. &{\bf\ \ \ \ V:=Y\^{}2} & \verb! V=Y**2!\\
  3902. &{\bf END\$}&\verb!}!\\
  3903. & & \\\hline\hline
  3904. \end{tabular}
  3905. \caption{REDUCE forms translatable to RATFOR}
  3906. \end{table}
  3907. \begin{table}
  3908. \begin{tabular}{||l|l|l||}\hline\hline
  3909. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3910. & \multicolumn{1}{c||}{\bf PASCAL CODE} \\ \hline\hline
  3911. Assignments: & &\\
  3912. & & \\
  3913. simple &{\bf V:=X\^{}2+X\$} &\verb!V=X**2+X;!\\
  3914. & & \\
  3915. matrix &{\bf M:=MAT((U,V),} &\verb!BEGIN!\\
  3916. & {\bf \ \ \ \ \ \ \ \ (W,X))\$} &\verb! M(1,1)=U;!\\
  3917. & &\verb! M(1,2)=V;!\\
  3918. & &\verb! M(2,1)=W;!\\
  3919. & &\verb! M(2,2)=X;!\\
  3920. & &\verb!END;!\\
  3921. & & \\
  3922. sum &{\bf S:=FOR I:=1:10} &\verb!BEGIN!\\
  3923. &{\bf\ \ \ \ \ \ SUM V(I)\$} &\verb! S=0.0!\\
  3924. & &\verb! FOR I:=1 TO 10 DO!\\
  3925. & &\verb! S:=S+V(I)!\\
  3926. & &\verb!END;!\\
  3927. & & \\
  3928. product &{\bf P:=FOR I:=2:N} &\verb!BEGIN!\\
  3929. &{\bf \ \ \ \ PRODUCT I\$} &\verb! P:=1;!\\
  3930. & &\verb! FOR I:=2 TO N DO!\\
  3931. & &\verb! P:=P*I!\\
  3932. & &\verb!END;!\\
  3933. & & \\
  3934. conditional & {\bf X := IF A$<$B THEN} &\verb!IF (A<B) THEN!\\
  3935. & \ \ \ \ \ \ {\bf \ \ \ \ \ \ \ \ A ELSE B\$} &\verb! X:=A;!\\
  3936. & &\verb!ELSE!\\
  3937. & &\verb! X:=B;!\\
  3938. & & \\\hline\hline
  3939. \end{tabular}
  3940. \caption{REDUCE forms translatable to PASCAL}
  3941. \end{table}
  3942. \begin{table}
  3943. \begin{tabular}{||l|l|l||}\hline\hline
  3944. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3945. & \multicolumn{1}{c||}{\bf PASCAL CODE} \\ \hline\hline
  3946. Control & & \\
  3947. Structures: & &\\
  3948. & & \\
  3949. Loops: & &\\
  3950. & &\\
  3951. for &{\bf FOR I:=1:8 DO} &\verb!FOR I:=1 TO 8 DO!\\
  3952. &{\bf \ \ \ \ V(I):=0.0\$} &\verb! V(I):=0.0;!\\
  3953. & & \\
  3954. while &{\bf WHILE F(N)$>$0.0 DO} &\verb!WHILE (F(N)>0.0)!\\
  3955. &{\bf \ \ \ \ N:=N+1\$} &\verb! N:=N+1.0;!\\
  3956. & & \\
  3957. repeat &{\bf REPEAT X:=X/2.0} &\verb!REPEAT!\\
  3958. &{\bf \ \ \ \ UNTIL F(X)$<$0.0\$} &\verb! X:=X/2.0!\\
  3959. & &\verb!UNTIL F(X)<0.0;!\\
  3960. & & \\\hline\hline
  3961. \end{tabular}
  3962. \caption{REDUCE forms translatable to PASCAL}
  3963. \end{table}
  3964. \begin{table}
  3965. \begin{tabular}{||l|l|l||}\hline\hline
  3966. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  3967. & \multicolumn{1}{c||}{\bf PASCAL CODE} \\ \hline\hline
  3968. Conditionals:& &\\
  3969. & &\\
  3970. if &{\bf IF X$>$0.0 THEN Y:=X\$} &\verb!IF X>0.0 THEN!\\
  3971. & &\verb! Y:=X;!\\
  3972. & &\\
  3973. if - else &{\bf IF X$>$0.0 THEN Y:=X} &\verb!IF X>0.0 THEN!\\
  3974. &{\bf\ \ \ \ ELSE Y:=-X\$}&\verb! Y:=X;!\\
  3975. & &\verb!ELSE!\\
  3976. & &\verb! Y:=-X;!\\
  3977. & & \\\hline
  3978. Unconditional& &\\
  3979. Transfer of & &\\
  3980. Control: & &\\
  3981. & &\\
  3982. goto&{\bf GOTO LOOP\$} &\verb!GOTO 25010;!\\
  3983. & &\\
  3984. call&{\bf CALCV(V,X,Y,Z)\$} &\verb!CALCV(V,X,Y,Z);!\\
  3985. & &\\
  3986. return &{\bf RETURN X\^{}2\$} &{\it functionname\/}\verb!=X**2;!\\
  3987. & &\verb!GOTO 99999{RETURN}!\\
  3988. & &\verb!99999;!\\
  3989. & & \\\hline
  3990. Sequences \& & &\\
  3991. Groups: & &\\
  3992. & &\\
  3993. sequence &{\bf $<$$<$ U:=X\^{}2;V:=Y\^{}2$>$$>$\$}&\verb!BEGIN!\\
  3994. &&\verb! U:=X**2;!\\
  3995. &&\verb! V:=Y**2!\\
  3996. &&\verb!END;!\\
  3997. & &\\
  3998. group &{\bf BEGIN}&\verb!BEGIN!\\
  3999. &{\bf\ \ \ \ U:=X\^{}2;}&\verb! U:=X**2;!\\
  4000. &{\bf\ \ \ \ V:=Y\^{}2} &\verb! V:=Y**2!\\
  4001. &{\bf END\$}&\verb!END!\\
  4002. & & \\\hline\hline
  4003. \end{tabular}
  4004. \caption{REDUCE forms translatable to PASCAL}
  4005. \end{table}
  4006. \begin{table}
  4007. \begin{tabular}{||l|l|l||}\hline\hline
  4008. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE}
  4009. & \multicolumn{1}{c||}{\bf C CODE} \\ \hline\hline
  4010. Assignments: & &\\
  4011. & & \\
  4012. simple &{\bf V:=X\^{}2+X\$} &\verb!V=power(X,2)+X;!\\
  4013. & & \\
  4014. matrix &{\bf M:=MAT((U,V),(W,X))\$} &\verb!M[1][1]=U;!\\
  4015. & &\verb!M[1][2]=V;!\\
  4016. & &\verb!M[2][1]=W;!\\
  4017. & &\verb!M[2][2]=X;!\\
  4018. & & \\
  4019. sum &{\bf S:=FOR I:=1:10} &\verb!S=0.0;!\\
  4020. &{\bf\ \ \ \ \ \ SUM V(I)\$} &\verb!for(I=1;I<=10;++I)!\\
  4021. & &\verb! S+=V[I];!\\
  4022. & & \\
  4023. product &{\bf P:=FOR I:=2 STEP 2} &\verb!P=1;!\\
  4024. &{\bf\ \ \ \ \ \ \ \ UNTIL N} &\verb!for(I=2;I<=N;++I)!\\
  4025. &{\ \ \ \ PRODUCT I\$} &\verb! P*=I;!\\
  4026. & & \\
  4027. conditional & {\bf X := IF A$<$B THEN} &\verb!if (A<B)!\\
  4028. & {\bf \ \ \ \ \ \ \ \ A ELSE B\$} &\verb! X=A;!\\
  4029. & &\verb!else!\\
  4030. & &\verb! X=B;!\\
  4031. & & \\\hline
  4032. Control & & \\
  4033. Structures: & &\\
  4034. & & \\
  4035. Loops: & &\\
  4036. & &\\
  4037. for &{\bf FOR I:=1:8 DO} &\verb!for(I=1;I<=8;++I)!\\
  4038. &{\bf \ \ \ \ V(I):=0.0\$} &\verb! V[I]=0.0;!\\
  4039. & & \\
  4040. while &{\bf WHILE F(N)$>$0.0 DO} &\verb!while(F(N)>0.0)!\\
  4041. &{\bf \ \ \ \ N:=N+1\$} &\verb! N+=1;!\\
  4042. & & \\
  4043. repeat &{\bf REPEAT X:=X/2.0} &\verb!do!\\
  4044. &{\bf \ \ \ \ UNTIL F(X)$<$0.0\$} &\verb! X/=2.0;!\\
  4045. & &\verb!while(F(X)>=0.0);!\\
  4046. & & \\\hline\hline
  4047. \end{tabular}
  4048. \caption{REDUCE forms translatable to C}
  4049. \end{table}
  4050. \begin{table}
  4051. \begin{tabular}{||l|l|l||}\hline\hline
  4052. \multicolumn{1}{||c|}{\bf TYPE} & \multicolumn{1}{c|}{\bf EXAMPLE} &
  4053. \multicolumn{1}{c||}{\bf C CODE} \\ \hline\hline
  4054. Conditionals:& &\\
  4055. & &\\
  4056. if &{\bf IF X$>$0.0 THEN Y:=X\$} &\verb!if(X>0.0)!\\
  4057. & &\verb! Y=X;!\\
  4058. & &\\
  4059. if - else &{\bf IF X$>$0.0 THEN Y:=X} &\verb!if(X>0.0)!\\
  4060. &{\bf\ \ \ \ ELSE Y:=-X\$}&\verb! Y=X;!\\
  4061. & &\verb!else!\\
  4062. & &\verb! Y=-X;!\\
  4063. & & \\\hline
  4064. Unconditional& &\\
  4065. Transfer of & &\\
  4066. Control: & &\\
  4067. & &\\
  4068. goto&{\bf GOTO LOOP\$} &\verb!goto LOOP;!\\
  4069. & &\\
  4070. call&{\bf CALCV(V,X,Y,Z)\$} &\verb!CALCV(V,X,Y,Z);!\\
  4071. & &\\
  4072. return &{\bf RETURN X\^{}2\$} &\verb!return(power(X,2) );!\\
  4073. & & \\\hline
  4074. Sequences \& & &\\
  4075. Groups: & &\\
  4076. & &\\
  4077. sequence &{\bf $<$$<$ U:=X\^{}2;V:=Y\^{}2$>$$>$\$}&\verb!U=power(X,2);!\\
  4078. & &\verb!V=power(Y,2);!\\
  4079. & &\\
  4080. group &{\bf BEGIN}&\verb!{!\\
  4081. &{\bf\ \ \ \ U:=X\^{}2;}& \verb! U=power(x,2);!\\
  4082. &{\bf\ \ \ \ V:=Y\^{}2} & \verb! V=power(Y,2);!\\
  4083. &{\bf END\$}&\verb!}!\\
  4084. & & \\\hline\hline
  4085. \end{tabular}
  4086. \caption{REDUCE forms translatable to C}
  4087. \end{table}
  4088. \subsection{Formal Definition}
  4089. The remainder of this section contains a formal definition of all
  4090. REDUCE expressions, statements, and prefix forms that can be translated by
  4091. GENTRAN into FORTRAN, RATFOR, PASCAL and C code.
  4092. \begin{describe}{Preliminary Definitions}
  4093. An {\it id\/} is an identifier. Certain {\it id\/}'s are reserved words
  4094. and may not be used as array names or subprogram names. The
  4095. complete list appears in the {\it Reserved Words\/} section.
  4096. A {\it string\/} consists of any number of characters (excluding double
  4097. quotes) which are enclosed in double quotes.
  4098. \end{describe}
  4099. \begin{describe}{Reserved Words}\index{reserved words}
  4100. The following reserved words may not be used as array names or
  4101. subprogram names\footnote{Note that names of other built-in REDUCE functions
  4102. {\it can\/} be translated, but remember that they will be translated
  4103. {\it literally\/} unless {\bf EVAL}'d first. For example:
  4104. {\bf GENTRAN~DERIV~:=~DF(2*X\^{}2-X-1,~X)\$}
  4105. generates {\tt DERIV=DF(2*X**2-X-1,X)}
  4106. whereas
  4107. {\bf GENTRAN~DERIV~:=:~DF(2*X\^{}2-X-1,~X)\$}
  4108. generates {\tt DERIV=4*X-1} }:
  4109. {\bf AND, BLOCK, COND, DIFFERENCE, EQUAL, EXPT, FOR, GEQ,
  4110. GO, GREATERP, LEQ, LESSP, MAT, MINUS, NEQ, NOT, OR,
  4111. PLUS, PROCEDURE, PROGN, QUOTIENT, RECIP, REPEAT,
  4112. RETURN, SETQ, TIMES, WHILE, WRITE}
  4113. \end{describe}
  4114. \subsubsection{Translatable REDUCE Expressions and Statements}
  4115. \begin{describe}{Expressions}
  4116. \begin{tabular}{lll}
  4117. \multicolumn{3}{l}{Arithmetic Expressions:} \\
  4118. & & \\
  4119. exp & ::= & {\it number} $\mid$ var $\mid$ funcall $\mid$ - exp $\mid$
  4120. / exp $\mid$ exp + exp $\mid$ \\
  4121. & & exp - exp $\mid$ exp * exp $\mid$ exp / exp $\mid$ exp ** exp
  4122. $\mid$ \\
  4123. & & exp \^{} exp $\mid$ ( exp )\\\\
  4124. & & \\
  4125. var & ::= & {\it id} $\mid$ {\it id} ( exp$_1$, exp$_2$, \dots\ , exp$_n$ )
  4126. $n > 0$ \\
  4127. & & \\
  4128. funcall & ::= & {\it id} ( arg$_1$, arg$_2$, \dots\ , arg$_n$ ) $n \geq 0$ \\
  4129. & & \\
  4130. arg & ::= & exp $\mid$ logexp $\mid$ {\it string} \\
  4131. & &\\
  4132. \multicolumn{3}{l}{Logical Expressions:}\\
  4133. & & \\
  4134. logexp & ::= & {\it T} $\mid$ {\it NIL} $\mid$ var $\mid$ funcall $\mid$
  4135. exp $>$ exp $\mid$ exp $>$= exp $\mid$\\
  4136. & & exp = exp $\mid$ exp {\it NEQ} exp $\mid$ exp $<$ exp $\mid$ \\
  4137. & & exp $<$= exp $\mid$ {\it NOT\/} logexp $\mid$ logexp {\it AND\/}
  4138. logexp $\mid$ \\
  4139. & & logexp {\it OR\/} logexp $\mid$ ( logexp )\\
  4140. \end{tabular}
  4141. \end{describe}
  4142. \begin{describe}{Operator Precedence}
  4143. The following is a list of REDUCE arithmetic and logical
  4144. operators in order of decreasing precedence:
  4145. \begin{center}
  4146. ** (or \^{}) / * --- + $<$ $<$= $>$ $>$= NEQ = NOT AND OR
  4147. \end{center}
  4148. When unparenthesised expressions are translated which contain
  4149. operators whose precedence in REDUCE differs from that in the
  4150. target language, parentheses are automatically generated. Thus
  4151. the meaning of the original expression is preserved\footnote{
  4152. For example in REDUCE, {\bf NOT~A~=~B} and {\bf NOT~(A~=~B)}
  4153. are equivalent, whereas in C, {\bf !~A~==~B} and {\bf (!A)~==~B}
  4154. are equivalent. Therefore, {\bf NOT~A~=~B}
  4155. is translated into C code which forces the REDUCE precedence rules:
  4156. {\bf !(A~==~B)}
  4157. }.
  4158. \end{describe}
  4159. \begin{describe}{Statements}
  4160. \begin{tabular}{lll}
  4161. stmt & ::= & assign $\mid$ break $\mid$ cond $\mid$ while $\mid$
  4162. repeat $\mid$ for $\mid$ goto $\mid$ label $\mid$ \\
  4163. & & call $\mid$ return $\mid$ stop $\mid$ stmtgp \\
  4164. \end{tabular}
  4165. Assignment Statements:
  4166. \begin{tabular}{llll}
  4167. assign & ::= & \multicolumn{2}{l}{var := assign' $\mid$ matassign $\mid$
  4168. cond}\\
  4169. & & & \\
  4170. assign' & ::= & \multicolumn{2}{l}{exp $\mid$ logexp}\\
  4171. & & & \\
  4172. matassign & ::= & {\it id} := {\it MAT\/}(&(exp$_{11}$, \dots\ , exp$_{1m}$),\\
  4173. & & &(exp$_{21}$, \dots\ , exp$_{2m}$ ),\\
  4174. & & & \ \ \ \ \ \ :\\
  4175. & & & \ \ \ \ \ \ :\\
  4176. & & &( exp$_{n1}$, \dots\ , exp$_{nm}$ ) ) $n,m > 0$ \\
  4177. \end{tabular}
  4178. Break Statement:
  4179. break ::= {\it BREAK()}
  4180. Conditional Statements:
  4181. \begin{tabular}{lll}
  4182. cond & ::= & {\it IF\/} logexp {\it THEN\/} stmt\\
  4183. & & {\it IF\/} logexp {\it THEN\/} stmt {\it ELSE\/} stmt\\
  4184. \end{tabular}
  4185. Loops:
  4186. \index{FOR loop} \index{WHILE loop} \index{REPEAT loop}
  4187. \begin{tabular}{lll}
  4188. while & ::= & {\it WHILE\/} logexp {\it DO\/} stmt\\
  4189. & &\\
  4190. repeat & ::= & {\it REPEAT\/} stmt {\it UNTIL\/} logexp\\
  4191. & &\\
  4192. for & ::= & {\it FOR\/} var := exp {\it STEP\/} exp {\it UNTIL\/} exp
  4193. {\it DO\/} stmt $\mid$\\
  4194. & &{\it FOR\/} var := exp {\it UNTIL\/} exp {\it DO\/} stmt $\mid$\\
  4195. & &{\it FOR\/} var := exp : exp {\it DO\/} stmt $\mid$\\
  4196. & &var := for' $\mid$ \\
  4197. & &\\
  4198. for' & ::= & var := for' $\mid$\\
  4199. & &{\it FOR\/} var := exp {\it STEP\/} exp {\it UNTIL\/} exp {\it SUM\/} exp
  4200. $\mid$\\
  4201. & &{\it FOR\/} var := exp {\it UNTIL\/} exp {\it SUM\/} exp $\mid$\\
  4202. & &{\it FOR\/} var := exp : exp {\it SUM\/} exp $\mid$\\
  4203. & &{\it FOR\/} var := exp {\it STEP\/} exp {\it UNTIL\/} exp\\
  4204. & & \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\it PRODUCT\/} exp $\mid$ \\
  4205. & &{\it FOR\/} var := exp {\it UNTIL\/} exp {\it PRODUCT\/} exp $\mid$\\
  4206. & &{\it FOR\/} var := exp : exp {\it PRODUCT\/} exp\\
  4207. \end{tabular}
  4208. Goto Statement:
  4209. \begin{tabular}{lll}
  4210. goto & ::= & {\it GOTO\/} label $\mid$ {\it GO TO\/} label\\
  4211. label & ::= & {\it id\/} :\\
  4212. \end{tabular}
  4213. Subprogram Calls \& Returns \footnote{ Note that return statements can
  4214. only be translated from inside of procedure definitions.
  4215. \index{LITERAL command} The LITERAL function must be used to generate
  4216. a return statement from anywhere else.}:
  4217. \begin{tabular}{lll}
  4218. call & ::= & {\it id\/} ( arg$_1$, arg$_2$, \dots\ , arg$_n$ ) $n \geq 0$\\
  4219. & &\\
  4220. return & ::= & {\it RETURN\/} $\mid$ {\it RETURN\/} arg\\
  4221. \end{tabular}
  4222. Stop \& Exit Statements \footnote{
  4223. In certain cases it may be convenient to generate a FORTRAN
  4224. STOP statement or a C EXIT statement. Since there is no
  4225. semantically equivalent REDUCE statement, STOP() can be used
  4226. and will be translated appropriately.}:
  4227. stop ::= {\it STOP\/}()
  4228. Statement Groups \footnote{
  4229. Note that REDUCE BEGIN\dots\ END statement groups are translated
  4230. into RATFOR or C \{\dots\ \} statement groups, whereas
  4231. REDUCE $<$$<$\dots\ $>$$>$ statement groups are translated into RATFOR or
  4232. C statement {\it sequences}. When the target language is FORTRAN, both
  4233. types of REDUCE statement groups are translated into statement
  4234. sequences.}:
  4235. \begin{tabular}{lll}
  4236. stmtgp & ::= & $<$$<$ stmt$_1$ ; stmt$_2$ ; \dots\ ; stmt$_n$ $>$$>$
  4237. $\mid$\\
  4238. & &{\it BEGIN\/} stmt$_1$ ; stmt$_2$ ; \dots\ ; stmt$_n$ {\it END\/} $ n >
  4239. 0$\\
  4240. \end{tabular}
  4241. \end{describe}
  4242. \begin{describe}{Subprogram Definitions}
  4243. \begin{tabular}{lll}
  4244. defn & ::= & {\it PROCEDURE id\/} ({\it id$_1$, id$_2$, \dots\ , id$_n$\/}) ;
  4245. stmt $\mid$\\
  4246. & & {\it PROCEDURE id\/} ({\it id$_1$, id$_2$, \dots\ , id$_n$\/}) ;
  4247. exp\ \ \ \ \ \ $n \geq 0$ \\
  4248. \end{tabular}
  4249. \end{describe}
  4250. \subsubsection{Translatable REDUCE Prefix Forms}
  4251. \begin{describe}{Expressions}
  4252. Arithmetic Expressions:
  4253. \begin{tabular}{lll}
  4254. exp & ::= & {\it number\/} $\mid$ funcall $\mid$ var $\mid$
  4255. ({\it DIFFERENCE\/} exp exp) $\mid$\\
  4256. & &({\it EXPT\/} exp exp) $\mid$ ({\it MINUS\/} exp) $\mid$ ({\it PLUS\/}
  4257. exp exp') $\mid$\\
  4258. & & ({\it QUOTIENT\/} exp exp) $\mid$ ({\it RECIP\/} exp) $\mid$\\
  4259. & & ({\it TIMES\/} exp exp exp') $\mid$ ({\it !*SQ\/} sqform)\\
  4260. \end{tabular}
  4261. where sqform is a standard quotient form equivalent to any acceptable prefix
  4262. form.
  4263. exp' ::= exp$_1$ exp$_2$ \dots\ exp$_n$ $n \geq 0$
  4264. Logical Expressions:
  4265. \begin{tabular}{lll}
  4266. logexp & ::= & {\it NIL\/} $\mid$ {\it T\/} $\mid$ funcall $\mid$ var
  4267. $\mid$\\
  4268. & & ({\it AND\/} logexp logexp logexp') $\mid$ ({\it EQUAL\/} exp exp)
  4269. $\mid$\\
  4270. & & ({\it GEQ\/} exp exp) $\mid$ ({\it GREATERP\/} exp exp) $\mid$ \\
  4271. & & ({\it LEQ\/} exp exp) $\mid$ ({\it LESSP\/} exp exp) $\mid$ \\
  4272. & & ({\it NEQ\/} exp exp) $\mid$ ({\it NOT\/} logexp) $\mid$ \\
  4273. & & ({\it OR\/} logexp logexp logexp')\\
  4274. & &\\
  4275. logexp' & ::= & logexp$_1$ logexp$_2$ \dots\ logexp$_n$ $n \geq 0$\\
  4276. \end{tabular}
  4277. \end{describe}
  4278. \begin{describe}{Statements}
  4279. \begin{tabular}{lll}
  4280. stmt & ::= & assign $\mid$ break $\mid$ call $\mid$ cond $\mid$
  4281. for $\mid$ goto $\mid$\\
  4282. & & label $\mid$ read $\mid$ repeat $\mid$ return $\mid$ stmtgp
  4283. $\mid$\\
  4284. & & stop $\mid$ while $\mid$ write \\
  4285. & &\\
  4286. stmt' & ::= & stmt$_1$ stmt$_2$ \dots\ stmt$_n$ $n \geq 0$\\
  4287. \end{tabular}
  4288. Assignment Statements:
  4289. assign ::= ({\it SETQ\/} var exp) $\mid$ ({\it SETQ\/} var logexp) $\mid$
  4290. ({\it SETQ\/} id ({\it MAT\/} list list'))
  4291. Conditional Statements:
  4292. \begin{tabular}{lll}
  4293. cond & ::= & ({\it COND\/} (logexp stmt) cond1) \\
  4294. & & \\
  4295. cond1 & ::= & (logexp stmt$_1$) \dots\ (logexp stmt$_n$) $n \geq 0$\\
  4296. \end{tabular}
  4297. Loops:
  4298. \begin{tabular}{lll}
  4299. for & ::= & ({\it FOR\/} var (exp exp exp) {\it DO\/} stmt) $\mid$\\
  4300. & & ({\it SETQ\/} var ({\it FOR\/} var (exp exp exp) {\it SUM\/} exp) $\mid$\\
  4301. & & ({\it SETQ\/} var ({\it FOR\/} var (exp exp exp) \\
  4302. & & \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\it PRODUCT\/} exp)\\
  4303. & &\\
  4304. repeat & ::= & ({\it REPEAT\/} stmt logexp)\\
  4305. & &\\
  4306. while & ::= & ({\it WHILE\/} logexp stmt)
  4307. \end{tabular}
  4308. Go To Statements:
  4309. \begin{tabular}{lll}
  4310. break & ::= & ({\it BREAK\/})\\
  4311. & & \\
  4312. goto & ::= & ({\it GO\/} label)\\
  4313. & & \\
  4314. label & ::= & {\it id}\\
  4315. \end{tabular}
  4316. Subprogram Calls \& Returns:
  4317. \begin{tabular}{lll}
  4318. call & ::= & ({\it id\/} arg')\\
  4319. & &\\
  4320. return & ::= & ({\it RETURN\/}) $\mid$ ({\it RETURN\/} arg)\\
  4321. \end{tabular}
  4322. Stop \& Exit Statements:
  4323. stop ::= ({\it STOP\/})
  4324. Statement Groups:
  4325. stmtgp ::= ({\it PROGN\/} stmt stmt') $\mid$ ({\it BLOCK\/} (id') stmt')
  4326. I/O Statements:
  4327. \begin{tabular}{lll}
  4328. read & ::= & ({\it SETQ\/} var ({\it READ\/}))\\
  4329. & &\\
  4330. write & ::= & ({\it WRITE\/} arg arg')\\
  4331. \end{tabular}
  4332. Subprogram Definitions:
  4333. defn ::= ({\it PROCEDURE id NIL EXPR\/} (id') stmt)
  4334. \end{describe}
  4335. \begin{describe}{Miscellaneous}
  4336. \begin{tabular}{lll}
  4337. funcall & ::= & ({\it id\/} arg')\\
  4338. & &\\
  4339. var & ::= & {\it id\/} $\mid$ ({\it id\/} exp exp')\\
  4340. & &\\
  4341. arg & ::= & {\it string\/} $\mid$ exp $\mid$ logexp\\
  4342. & &\\
  4343. arg' & ::= & arg$_1$ arg$_2$ \dots\ arg$_n$ $n \geq 0$ \\
  4344. & &\\
  4345. list & ::= & (exp exp')\\
  4346. & &\\
  4347. list' & ::= & list$_1$ list$_2$ \dots\ list$_n$ $n \geq 0$ \\
  4348. & &\\
  4349. id' & ::= & {\it id$_1$ id$_2$} \dots\ {\it id$_n$} $n \geq 0$ \\
  4350. \end{tabular}
  4351. \end{describe}
  4352. \section{List of Commands, Switches, \& Variables}
  4353. \label{appb}
  4354. \begin{describe}{COMMANDS}
  4355. \index{GENTRAN command}
  4356. {\bf GENTRAN} {\it stmt\/} [{\bf OUT}{\it f1,f2,\dots\ ,fn\/}]{\it ;}
  4357. \index{GENTRANIN command}
  4358. {\bf GENTRANIN} {\it f1,f2,\dots\ ,fm\/} [{\bf OUT}{\it f1,f2,\dots\
  4359. ,fn\/}]{\it ;}
  4360. \index{GENTRANOUT command}
  4361. {\bf GENTRANOUT} {\it f1,f2,\dots\ ,fn;}
  4362. \index{GENTRANSHUT command}
  4363. {\bf GENTRANSHUT} {\it f1,f2,\dots\ ,fn;}
  4364. \index{GENTRANPUSH command}
  4365. {\bf GENTRANPUSH} {\it f1,f2,\dots\ ,fn;}
  4366. \index{GENTRANPOP command}
  4367. {\bf GENTRANPOP} {\it f1,f2,\dots\ ,fn;}
  4368. \end{describe}
  4369. \begin{describe}{SPECIAL FUNCTIONS \& OPERATORS}
  4370. \ttindex{EVAL}
  4371. {\bf EVAL} {\it exp}
  4372. \index{::=}
  4373. {\it var} {\bf ::=} {\it exp;}
  4374. \index{:=:}
  4375. {\it var} {\bf :=:} {\it exp;}
  4376. \index{::=:}
  4377. {\it var} {\bf ::=:} {\it exp;}
  4378. \ttindex{LSETQ}
  4379. {\it var} {\bf LSETQ} {\it exp;}
  4380. \ttindex{RSETQ}
  4381. {\it var} {\bf RSETQ} {\it exp;}
  4382. \ttindex{LRSETQ}
  4383. {\it var} {\bf LRSETQ} {\it exp;}
  4384. \index{DECLARE function}
  4385. {\bf DECLARE} {\it v1,v2,\dots\ ,vn\/}{\bf :} {\it type;}
  4386. \begin{tabular}{ll}
  4387. {\bf DECLARE}\\
  4388. {\bf $<$$<$}\\
  4389. &{\it v11,v12,\dots\ ,v1n} {\bf :} {\it type1\/}{\bf ;}\\
  4390. &{\it v12,v22,\dots\ ,v2n} {\bf :} {\it type2\/}{\bf ;}\\
  4391. & \ \ \ :\\
  4392. & \ \ \ :\\
  4393. &{\it vm1,vm2,\dots\ ,vmn} {\bf :} {\it typen\/}{\bf ;}\\
  4394. {\bf $>$$>$}{\it ;}
  4395. \end{tabular}
  4396. \ttindex{LITERAL}
  4397. {\bf LITERAL} {\it arg1,arg2,\dots\ ,argn;}
  4398. \end{describe}
  4399. \begin{describe}{MODE SWITCHES}
  4400. {\bf PERIOD} \index{PERIOD switch}
  4401. {\bf GENTRANSEG} \index{GENTRANSEG switch}
  4402. {\bf GENDECS} \index{GENDECS switch}
  4403. {\bf DOUBLE} \index{DOUBLE switch}
  4404. {\bf MAKECALLS} \index{MAKECALLS switch}
  4405. {\bf KEEPDECS} \index{KEEPDECS switch}
  4406. {\bf GETDECS} \index{GETDECS switch}
  4407. \end{describe}
  4408. \begin{describe}{VARIABLES}
  4409. {\bf GENTRANLANG!*} \ttindex{GENTRANLANG!*}
  4410. {\bf MAXEXPPRINTLEN!*} \ttindex{MAXEXPPRINTLEN!*}
  4411. {\bf TEMPVARNAME!*} \ttindex{TEMPVARNAME!*}
  4412. {\bf TEMPVARNUM!*} \ttindex{TEMPVARNUM!*}
  4413. {\bf TEMPVARTYPE!*} \ttindex{TEMPVARTYPE!*}
  4414. {\bf GENSTMTNUM!*} \ttindex{GENSTMTNUM!*}
  4415. {\bf GENSTMTINCR!*} \ttindex{GENSTMTINCR!*}
  4416. {\bf TABLEN!*} \ttindex{TABLEN!*}
  4417. {\bf FORTLINELEN!*} \ttindex{FORTLINELEN!*}
  4418. {\bf RATLINELEN!*} \ttindex{RATLINELEN!*}
  4419. {\bf CLINELEN!*} \ttindex{CLINELEN!*}
  4420. {\bf PASCLINELEN!*} \ttindex{PASCLINELEN!*}
  4421. {\bf MINFORTLINELEN!*} \ttindex{MINFORTLINELEN!*}
  4422. {\bf MINRATLINELEN!*} \ttindex{MINRATLINELEN!*}
  4423. {\bf MINCLINELEN!*} \ttindex{MINCLINELEN!*}
  4424. {\bf MINPASCLINELEN!*} \ttindex{MINPASCLINELEN!*}
  4425. {\bf DEFTYPE!*} \ttindex{DEFTYPE!*}
  4426. \end{describe}
  4427. \begin{describe}{TEMPORARY VARIABLE GENERATION, MARKING \& UNMARKING}
  4428. {\bf TEMPVAR} {\it type;} \ttindex{TEMPVAR}
  4429. {\bf MARKVAR} {\it var;} \ttindex{MARKVAR}
  4430. {\bf UNMARKVAR} {\it var;} \ttindex{UNMARKVAR}
  4431. \end{describe}
  4432. \begin{describe}{EXPLICIT GENERATION OF TYPE DECLARATIONS}
  4433. {\bf GENDECS} {\it subprogname;} \ttindex{GENDECS switch}
  4434. \end{describe}
  4435. \begin{describe}{SYMBOLIC MODE FUNCTIONS}
  4436. {\bf SYM!-GENTRAN} {\it form;} \index{SYM"!-GENTRAN command}
  4437. {\bf SYM!-GENTRANIN} {\it list-of-fnames;} \index{SYM"!-GENTRANIN command}
  4438. {\bf SYM!-GENTRANOUT} {\it list-of-fnames;} \index{SYM"!-GENTRANOUT command}
  4439. {\bf SYM!-GENTRANSHUT} {\it list-of-fnames;} \index{SYM"!-GENTRANSHUT command}
  4440. {\bf SYM!-GENTRANPUSH} {\it list-of-fnames;} \index{SYM"!-GENTRANPUSH command}
  4441. {\bf SYM!-GENTRANPOP} {\it list-of-fnames;} \index{SYM"!-GENTRANPOP command}
  4442. \end{describe}
  4443. \begin{describe}{SYMBOLIC MODE SPECIAL FORMS}
  4444. \begin{tabular}{ll}
  4445. \ttindex{DECLARE}
  4446. {\bf (DECLARE} & {\bf (}{\it type1 v11 v12 \dots\ v1n\/}{\bf )}\\
  4447. & {\bf (}{\it type2 v21 v22 \dots\ v2n\/}{\bf )}\\
  4448. & \ \ \ :\\
  4449. & \ \ \ :\\
  4450. & {\bf (}{\it typen vn1 vn2 \dots\ vnn\/}{\bf ))}\\
  4451. \end{tabular}
  4452. {\bf (LITERAL} {\it arg1 arg2 \dots\ argn\/}{\bf )} \ttindex{LITERAL}
  4453. {\bf (EVAL} {\it exp\/}{\bf )} \ttindex{EVAL}
  4454. {\bf (LSETQ} {\it var exp\/}{\bf )} \ttindex{LSETQ}
  4455. {\bf (RSETQ} {\it var exp\/}{\bf )} \ttindex{RSETQ}
  4456. {\bf (LRSETQ} {\it var exp\/}{\bf )} \ttindex{LRSETQ}
  4457. \end{describe}
  4458. \section{The Programs {\tt M1.F} and {\tt M2.F}.}
  4459. \label{appc}
  4460. This section contains the two files generated in chapter 6.
  4461. Contents of file m1.f:
  4462. \begin{framedverbatim}
  4463. M(1,1)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  4464. . Q3))**2*Y*J30)+DSIN(DBLE(Q3))**2*J30Z+18.0D0*DCOS(DBLE
  4465. . (Q3))*DCOS(DBLE(Q2))*P**2*M30+18.0D0*P**2*M30+P**2*M10
  4466. . +J30Y+J10Y
  4467. M(1,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  4468. . Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*DCOS(DBLE(
  4469. . Q3))*DCOS(DBLE(Q2))*P**2*M30+9.0D0*P**2*M30+J30Y
  4470. M(1,3)=-(9.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**2*M30)
  4471. M(2,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  4472. . Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*P**2*M30+
  4473. . J30Y
  4474. M(2,3)=0.0D0
  4475. M(3,3)=9.0D0*P**2*M30+J30X
  4476. MIV(1,1)=(-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2)-(
  4477. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y)+9.0D0*DSIN(DBLE
  4478. . (Q3))**2*P**2*M30*J30Z-(9.0D0*DSIN(DBLE(Q3))**2*P**2*
  4479. . M30*J30X)-(DSIN(DBLE(Q3))**2*J30Y*J30X)+DSIN(DBLE(Q3))
  4480. . **2*J30Z*J30X+81.0D0*P**4*M30**2+9.0D0*P**2*M30*J30Y+
  4481. . 9.0D0*P**2*M30*J30X+J30Y*J30X)/(729.0D0*DSIN(DBLE(Q3))
  4482. . **4*DSIN(DBLE(Q2))**2*P**6*M30**3+81.0D0*DSIN(DBLE(Q3
  4483. . ))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y-(81.0D0*DSIN(
  4484. . DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Z)+
  4485. . 81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*M30**2*J30-(81.0D0*
  4486. . DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)+9.0D0*DSIN(DBLE(Q3
  4487. . ))**4*P**2*Y*M30*J30Y*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**
  4488. . 2*Y*M30*J30Z*J30)+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*
  4489. . J30X*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+
  4490. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN
  4491. . (DBLE(Q3))**4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*
  4492. . J30Y*J30X*J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(
  4493. . DSIN(DBLE(Q3))**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y
  4494. . *J30Z*J30X-(729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**
  4495. . 2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2)
  4496. . )**2*P**4*M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6
  4497. . *M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(
  4498. . 81.0D0*DSIN(DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*
  4499. . DSIN(DBLE(Q3))**2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(
  4500. . Q3))**2*P**4*M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P
  4501. . **4*M30**2*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*
  4502. . J30Y*M10)+9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(
  4503. . 9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN
  4504. . (DBLE(Q3))**2*P**2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3
  4505. . ))**2*P**2*Y*M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**
  4506. . 2*M30*J30Y**2-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*
  4507. . J10Y)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y+9.0D0
  4508. . *DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0*DSIN(DBLE
  4509. . (Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))**2*P**2*
  4510. . J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*M10*J30X-(
  4511. . DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE(Q3))**2*
  4512. . J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*J30X)+DSIN(
  4513. . DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(DBLE(Q3))**2
  4514. . *DCOS(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DCOS(DBLE(Q3))
  4515. . **2*DCOS(DBLE(Q2))**2*P**4*M30**2*J30X)+729.0D0*P**6*
  4516. . M30**3+81.0D0*P**6*M30**2*M10+81.0D0*P**4*M30**2*J30Y+
  4517. . 81.0D0*P**4*M30**2*J10Y+81.0D0*P**4*M30**2*J30X+9.0D0*
  4518. . P**4*M30*J30Y*M10+9.0D0*P**4*M30*M10*J30X+9.0D0*P**2*
  4519. . M30*J30Y*J10Y+9.0D0*P**2*M30*J30Y*J30X+9.0D0*P**2*M30*
  4520. . J10Y*J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  4521. MIV(1,2)=(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2+9.0D0*
  4522. . DSIN(DBLE(Q3))**2*P**2*M30*J30Y-(9.0D0*DSIN(DBLE(Q3))
  4523. . **2*P**2*M30*J30Z)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*
  4524. . J30X+DSIN(DBLE(Q3))**2*J30Y*J30X-(DSIN(DBLE(Q3))**2*
  4525. . J30Z*J30X)-(81.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**4*
  4526. . M30**2)-(9.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**2*M30*
  4527. . J30X)-(81.0D0*P**4*M30**2)-(9.0D0*P**2*M30*J30Y)-(
  4528. . 9.0D0*P**2*M30*J30X)-(J30Y*J30X))/(729.0D0*DSIN(DBLE(
  4529. . Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30**3+81.0D0*DSIN(DBLE
  4530. . (Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y-(81.0D0*
  4531. . DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Z)+
  4532. . 81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*M30**2*J30-(81.0D0*
  4533. . DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)+9.0D0*DSIN(DBLE(Q3
  4534. . ))**4*P**2*Y*M30*J30Y*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**
  4535. . 2*Y*M30*J30Z*J30)+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*
  4536. . J30X*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+
  4537. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN
  4538. . (DBLE(Q3))**4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*
  4539. . J30Y*J30X*J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(
  4540. . DSIN(DBLE(Q3))**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y
  4541. . *J30Z*J30X-(729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**
  4542. . 2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2)
  4543. . )**2*P**4*M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6
  4544. . *M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(
  4545. . 81.0D0*DSIN(DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*
  4546. . DSIN(DBLE(Q3))**2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(
  4547. . Q3))**2*P**4*M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P
  4548. . **4*M30**2*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*
  4549. . J30Y*M10)+9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(
  4550. . 9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN
  4551. . (DBLE(Q3))**2*P**2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3
  4552. . ))**2*P**2*Y*M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**
  4553. . 2*M30*J30Y**2-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*
  4554. . J10Y)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y+9.0D0
  4555. . *DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0*DSIN(DBLE
  4556. . (Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))**2*P**2*
  4557. . J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*M10*J30X-(
  4558. . DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE(Q3))**2*
  4559. . J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*J30X)+DSIN(
  4560. . DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(DBLE(Q3))**2
  4561. . *DCOS(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DCOS(DBLE(Q3))
  4562. . **2*DCOS(DBLE(Q2))**2*P**4*M30**2*J30X)+729.0D0*P**6*
  4563. . M30**3+81.0D0*P**6*M30**2*M10+81.0D0*P**4*M30**2*J30Y+
  4564. . 81.0D0*P**4*M30**2*J10Y+81.0D0*P**4*M30**2*J30X+9.0D0*
  4565. . P**4*M30*J30Y*M10+9.0D0*P**4*M30*M10*J30X+9.0D0*P**2*
  4566. . M30*J30Y*J10Y+9.0D0*P**2*M30*J30Y*J30X+9.0D0*P**2*M30*
  4567. . J10Y*J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  4568. MIV(1,3)=(-(81.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**
  4569. . 4*M30**2)-(9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2
  4570. . *M30*J30Y)+9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2
  4571. . *M30*J30Z+81.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**4*
  4572. . M30**2+9.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**2*M30*
  4573. . J30Y)/(729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**
  4574. . 6*M30**3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P
  4575. . **4*M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2
  4576. . ))**2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*
  4577. . Y*M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*
  4578. . J30Y)+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(
  4579. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)+9.0D0*
  4580. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(9.0D0*DSIN(DBLE
  4581. . (Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(DBLE(Q3))**4*P**
  4582. . 2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y
  4583. . *J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*J30-(DSIN(DBLE(Q3
  4584. . ))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3))**4*J30Y**2*J30X
  4585. . )+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(729.0D0*DSIN(DBLE(
  4586. . Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DSIN(
  4587. . DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y)-(
  4588. . 729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(81.0D0*DSIN(
  4589. . DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN(DBLE(Q3))**
  4590. . 2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))**2*P**4*M30
  4591. . **2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*J10Y)-(
  4592. . 81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*J30X)-(9.0D0*DSIN
  4593. . (DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0*DSIN(DBLE(Q3))
  4594. . **2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(Q3))**2*P**4*
  4595. . M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30Y
  4596. . *J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30X*J30)+
  4597. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2-(9.0D0*DSIN(
  4598. . DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*DSIN(DBLE(Q3))
  4599. . **2*P**2*M30*J30Z*J10Y+9.0D0*DSIN(DBLE(Q3))**2*P**2*
  4600. . M30*J30Z*J30X-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J10Y*
  4601. . J30X)-(DSIN(DBLE(Q3))**2*P**2*J30Y*M10*J30X)+DSIN(DBLE
  4602. . (Q3))**2*P**2*J30Z*M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*
  4603. . J30X*J30)+DSIN(DBLE(Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3
  4604. . ))**2*J30Y*J10Y*J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X
  4605. . -(729.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30
  4606. . **3)-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4607. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4608. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4609. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  4610. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  4611. . M30*J30Y*J30X+9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*
  4612. . J30X+J30Y*J10Y*J30X)
  4613. MIV(2,2)=(-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*
  4614. . P**4*M30**2)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2)-(
  4615. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30)+9.0D0*DSIN(
  4616. . DBLE(Q3))**2*P**2*M30*J30Z-(9.0D0*DSIN(DBLE(Q3))**2*P
  4617. . **2*M30*J30X)-(DSIN(DBLE(Q3))**2*Y*J30X*J30)+DSIN(DBLE
  4618. . (Q3))**2*J30Z*J30X+162.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2
  4619. . ))*P**4*M30**2+18.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P
  4620. . **2*M30*J30X+162.0D0*P**4*M30**2+9.0D0*P**4*M30*M10+
  4621. . 9.0D0*P**2*M30*J30Y+9.0D0*P**2*M30*J10Y+18.0D0*P**2*
  4622. . M30*J30X+P**2*M10*J30X+J30Y*J30X+J10Y*J30X)/(729.0D0*
  4623. . DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30**3+81.0D0
  4624. . *DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y-
  4625. . (81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**
  4626. . 2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*M30**2*J30-(
  4627. . 81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)+9.0D0*DSIN(
  4628. . DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*DSIN(DBLE(Q3))
  4629. . **4*P**2*Y*M30*J30Z*J30)+9.0D0*DSIN(DBLE(Q3))**4*P**2*
  4630. . Y*M30*J30X*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y
  4631. . **2)+9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0
  4632. . *DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))
  4633. . **4*Y*J30Y*J30X*J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30
  4634. . )-(DSIN(DBLE(Q3))**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*
  4635. . J30Y*J30Z*J30X-(729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2
  4636. . ))**2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE
  4637. . (Q2))**2*P**4*M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*
  4638. . P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10
  4639. . )-(81.0D0*DSIN(DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*
  4640. . DSIN(DBLE(Q3))**2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(
  4641. . Q3))**2*P**4*M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P
  4642. . **4*M30**2*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*
  4643. . J30Y*M10)+9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(
  4644. . 9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN
  4645. . (DBLE(Q3))**2*P**2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3
  4646. . ))**2*P**2*Y*M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**
  4647. . 2*M30*J30Y**2-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*
  4648. . J10Y)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y+9.0D0
  4649. . *DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0*DSIN(DBLE
  4650. . (Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))**2*P**2*
  4651. . J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*M10*J30X-(
  4652. . DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE(Q3))**2*
  4653. . J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*J30X)+DSIN(
  4654. . DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(DBLE(Q3))**2
  4655. . *DCOS(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DCOS(DBLE(Q3))
  4656. . **2*DCOS(DBLE(Q2))**2*P**4*M30**2*J30X)+729.0D0*P**6*
  4657. . M30**3+81.0D0*P**6*M30**2*M10+81.0D0*P**4*M30**2*J30Y+
  4658. . 81.0D0*P**4*M30**2*J10Y+81.0D0*P**4*M30**2*J30X+9.0D0*
  4659. . P**4*M30*J30Y*M10+9.0D0*P**4*M30*M10*J30X+9.0D0*P**2*
  4660. . M30*J30Y*J10Y+9.0D0*P**2*M30*J30Y*J30X+9.0D0*P**2*M30*
  4661. . J10Y*J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  4662. MIV(2,3)=(81.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**4*
  4663. . M30**2+9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2*M30
  4664. . *J30Y-(9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2*M30
  4665. . *J30Z)-(81.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*DCOS(DBLE
  4666. . (Q3))*DCOS(DBLE(Q2))*P**4*M30**2)-(81.0D0*DSIN(DBLE(Q3
  4667. . ))*DSIN(DBLE(Q2))*P**4*M30**2)-(9.0D0*DSIN(DBLE(Q3))*
  4668. . DSIN(DBLE(Q2))*P**2*M30*J30Y))/(729.0D0*DSIN(DBLE(Q3))
  4669. . **4*DSIN(DBLE(Q2))**2*P**6*M30**3+81.0D0*DSIN(DBLE(Q3)
  4670. . )**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y-(81.0D0*DSIN(
  4671. . DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Z)+
  4672. . 81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*M30**2*J30-(81.0D0*
  4673. . DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)+9.0D0*DSIN(DBLE(Q3
  4674. . ))**4*P**2*Y*M30*J30Y*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**
  4675. . 2*Y*M30*J30Z*J30)+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*
  4676. . J30X*J30-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+
  4677. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN
  4678. . (DBLE(Q3))**4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*
  4679. . J30Y*J30X*J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(
  4680. . DSIN(DBLE(Q3))**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y
  4681. . *J30Z*J30X-(729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**
  4682. . 2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2)
  4683. . )**2*P**4*M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6
  4684. . *M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(
  4685. . 81.0D0*DSIN(DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*
  4686. . DSIN(DBLE(Q3))**2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(
  4687. . Q3))**2*P**4*M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P
  4688. . **4*M30**2*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*
  4689. . J30Y*M10)+9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(
  4690. . 9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN
  4691. . (DBLE(Q3))**2*P**2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3
  4692. . ))**2*P**2*Y*M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**
  4693. . 2*M30*J30Y**2-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*
  4694. . J10Y)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y+9.0D0
  4695. . *DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0*DSIN(DBLE
  4696. . (Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))**2*P**2*
  4697. . J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*M10*J30X-(
  4698. . DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE(Q3))**2*
  4699. . J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*J30X)+DSIN(
  4700. . DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(DBLE(Q3))**2
  4701. . *DCOS(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DCOS(DBLE(Q3))
  4702. . **2*DCOS(DBLE(Q2))**2*P**4*M30**2*J30X)+729.0D0*P**6*
  4703. . M30**3+81.0D0*P**6*M30**2*M10+81.0D0*P**4*M30**2*J30Y+
  4704. . 81.0D0*P**4*M30**2*J10Y+81.0D0*P**4*M30**2*J30X+9.0D0*
  4705. . P**4*M30*J30Y*M10+9.0D0*P**4*M30*M10*J30X+9.0D0*P**2*
  4706. . M30*J30Y*J10Y+9.0D0*P**2*M30*J30Y*J30X+9.0D0*P**2*M30*
  4707. . J10Y*J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  4708. MIV(3,3)=(9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30-(9.0D0
  4709. . *DSIN(DBLE(Q3))**4*P**2*M30*J30Y)+DSIN(DBLE(Q3))**4*Y*
  4710. . J30Y*J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30)-(DSIN(DBLE(Q3)
  4711. . )**4*J30Y**2)+DSIN(DBLE(Q3))**4*J30Y*J30Z-(81.0D0*DSIN
  4712. . (DBLE(Q3))**2*P**4*M30**2)-(9.0D0*DSIN(DBLE(Q3))**2*P
  4713. . **4*M30*M10)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30)+
  4714. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z-(9.0D0*DSIN(DBLE
  4715. . (Q3))**2*P**2*M30*J10Y)-(DSIN(DBLE(Q3))**2*P**2*J30Y*
  4716. . M10)+DSIN(DBLE(Q3))**2*P**2*J30Z*M10-(DSIN(DBLE(Q3))**
  4717. . 2*Y*J30Y*J30)+DSIN(DBLE(Q3))**2*J30Y**2-(DSIN(DBLE(Q3)
  4718. . )**2*J30Y*J10Y)+DSIN(DBLE(Q3))**2*J30Z*J10Y-(81.0D0*
  4719. . DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*M30**2)+
  4720. . 81.0D0*P**4*M30**2+9.0D0*P**4*M30*M10+9.0D0*P**2*M30*
  4721. . J30Y+9.0D0*P**2*M30*J10Y+P**2*J30Y*M10+J30Y*J10Y)/(
  4722. . 729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30**
  4723. . 3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*M30
  4724. . **2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P
  4725. . **4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*M30**
  4726. . 2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)+
  4727. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4728. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)+9.0D0*DSIN(DBLE
  4729. . (Q3))**4*P**2*Y*M30*J30X*J30-(9.0D0*DSIN(DBLE(Q3))**4*
  4730. . P**2*M30*J30Y**2)+9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*
  4731. . J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y*J30X)
  4732. . +DSIN(DBLE(Q3))**4*Y*J30Y*J30X*J30-(DSIN(DBLE(Q3))**4*
  4733. . Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3))**4*J30Y**2*J30X)+DSIN
  4734. . (DBLE(Q3))**4*J30Y*J30Z*J30X-(729.0D0*DSIN(DBLE(Q3))**
  4735. . 2*DSIN(DBLE(Q2))**2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3)
  4736. . )**2*DSIN(DBLE(Q2))**2*P**4*M30**2*J30Y)-(729.0D0*DSIN
  4737. . (DBLE(Q3))**2*P**6*M30**3)-(81.0D0*DSIN(DBLE(Q3))**2*P
  4738. . **6*M30**2*M10)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*Y*M30**
  4739. . 2*J30)+81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*J30Z-(
  4740. . 81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*J10Y)-(81.0D0*
  4741. . DSIN(DBLE(Q3))**2*P**4*M30**2*J30X)-(9.0D0*DSIN(DBLE(
  4742. . Q3))**2*P**4*M30*J30Y*M10)+9.0D0*DSIN(DBLE(Q3))**2*P**
  4743. . 4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*M10*
  4744. . J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30Y*J30)-(
  4745. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30X*J30)+9.0D0*
  4746. . DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2-(9.0D0*DSIN(DBLE(Q3
  4747. . ))**2*P**2*M30*J30Y*J10Y)+9.0D0*DSIN(DBLE(Q3))**2*P**2
  4748. . *M30*J30Z*J10Y+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*
  4749. . J30X-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(
  4750. . DSIN(DBLE(Q3))**2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**
  4751. . 2*P**2*J30Z*M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*
  4752. . J30)+DSIN(DBLE(Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2
  4753. . *J30Y*J10Y*J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(
  4754. . 729.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**
  4755. . 3)-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4756. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4757. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4758. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0
  4759. . *P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2
  4760. . *M30*J30Y*J30X+9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*
  4761. . J30X+J30Y*J10Y*J30X)
  4762. DO 25005 J=1,3
  4763. DO 25006 K=J+1,3
  4764. M(K,J)=M(J,K)
  4765. MIV(K,J)=MIV(J,K)
  4766. 25006 CONTINUE
  4767. 25005 CONTINUE
  4768. \end{framedverbatim}
  4769. \newpage
  4770. Contents of file m2.f:
  4771. \begin{framedverbatim}
  4772. M(1,1)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  4773. . Q3))**2*Y*J30)+DSIN(DBLE(Q3))**2*J30Z+18.0D0*DCOS(DBLE
  4774. . (Q3))*DCOS(DBLE(Q2))*P**2*M30+18.0D0*P**2*M30+P**2*M10
  4775. . +J30Y+J10Y(1,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(
  4776. . DSIN(DBLE(Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*
  4777. . DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**2*M30+9.0D0*P**2*M30+
  4778. . J30Y(1,3)=-(9.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**2*
  4779. . M30)
  4780. M(2,2)=-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30)-(DSIN(DBLE(
  4781. . Q3))**2*J30Y)+DSIN(DBLE(Q3))**2*J30Z+9.0D0*P**2*M30+
  4782. . J30Y
  4783. M(2,3)=0.0D0
  4784. M(3,3)=9.0D0*P**2*M30+J30X
  4785. T1=-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2)-(9.0D0*DSIN(
  4786. . DBLE(Q3))**2*P**2*M30*J30Y)+9.0D0*DSIN(DBLE(Q3))**2*P
  4787. . **2*M30*J30Z-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30X)-(
  4788. . DSIN(DBLE(Q3))**2*J30Y*J30X)+DSIN(DBLE(Q3))**2*J30Z*
  4789. . J30X+81.0D0*P**4*M30**2+9.0D0*P**2*M30*J30Y+9.0D0*P**2
  4790. . *M30*J30X+J30Y*J30X
  4791. T0=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  4792. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  4793. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  4794. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  4795. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  4796. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4797. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  4798. T0=T0+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  4799. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  4800. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  4801. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  4802. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  4803. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  4804. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  4805. . 3)
  4806. T0=T0-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  4807. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  4808. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  4809. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  4810. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  4811. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  4812. . J30X)
  4813. T0=T0-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  4814. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  4815. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  4816. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  4817. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  4818. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  4819. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  4820. T0=T0+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  4821. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  4822. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  4823. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  4824. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  4825. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  4826. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  4827. T0=T0-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4828. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4829. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4830. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  4831. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  4832. ; M30*J30Y*J30X
  4833. MIV(1,1)=T1/(T0+9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*
  4834. . J30X+J30Y*J10Y*J30X)
  4835. T0=81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2+9.0D0*DSIN(DBLE
  4836. . (Q3))**2*P**2*M30*J30Y-(9.0D0*DSIN(DBLE(Q3))**2*P**2*
  4837. . M30*J30Z)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30X+DSIN(
  4838. . DBLE(Q3))**2*J30Y*J30X-(DSIN(DBLE(Q3))**2*J30Z*J30X)-(
  4839. . 81.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**4*M30**2)-(
  4840. . 9.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**2*M30*J30X)-(
  4841. . 81.0D0*P**4*M30**2)-(9.0D0*P**2*M30*J30Y)
  4842. T1=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  4843. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  4844. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  4845. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  4846. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  4847. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4848. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  4849. T1=T1+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  4850. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  4851. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  4852. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  4853. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  4854. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  4855. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  4856. . 3)
  4857. T1=T1-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  4858. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  4859. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  4860. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  4861. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  4862. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  4863. . J30X)
  4864. T1=T1-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  4865. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  4866. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  4867. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  4868. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  4869. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  4870. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  4871. T1=T1+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  4872. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  4873. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  4874. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  4875. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  4876. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  4877. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  4878. T1=T1-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4879. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4880. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4881. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  4882. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  4883. . M30*J30Y*J30X
  4884. MIV(1,2)=(T0-(9.0D0*P**2*M30*J30X)-(J30Y*J30X))/(T1+
  4885. . 9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*
  4886. . J30X)
  4887. T0=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  4888. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  4889. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  4890. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  4891. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  4892. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4893. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  4894. T0=T0+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  4895. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  4896. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  4897. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  4898. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  4899. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  4900. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  4901. . 3)
  4902. T0=T0-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  4903. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  4904. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  4905. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  4906. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  4907. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  4908. . J30X)
  4909. T0=T0-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  4910. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  4911. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  4912. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  4913. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  4914. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  4915. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  4916. T0=T0+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  4917. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  4918. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  4919. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  4920. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  4921. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  4922. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  4923. T0=T0-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4924. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4925. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4926. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  4927. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  4928. . M30*J30Y*J30X
  4929. MIV(1,3)=(-(81.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**
  4930. . 4*M30**2)-(9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2
  4931. . *M30*J30Y)+9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2
  4932. . *M30*J30Z+81.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**4*
  4933. . M30**2+9.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*P**2*M30*
  4934. . J30Y)/(T0+9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*J30X+
  4935. . J30Y*J10Y*J30X)
  4936. T0=-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  4937. . M30**2)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2)-(9.0D0*
  4938. . DSIN(DBLE(Q3))**2*P**2*Y*M30*J30)+9.0D0*DSIN(DBLE(Q3))
  4939. . **2*P**2*M30*J30Z-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*
  4940. . J30X)-(DSIN(DBLE(Q3))**2*Y*J30X*J30)+DSIN(DBLE(Q3))**2
  4941. . *J30Z*J30X+162.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**4*
  4942. . M30**2+18.0D0*DCOS(DBLE(Q3))*DCOS(DBLE(Q2))*P**2*M30*
  4943. . J30X+162.0D0*P**4*M30**2
  4944. T1=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  4945. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  4946. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  4947. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  4948. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  4949. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4950. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  4951. T1=T1+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  4952. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  4953. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  4954. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  4955. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  4956. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  4957. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  4958. . 3)
  4959. T1=T1-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  4960. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  4961. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  4962. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  4963. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  4964. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  4965. . J30X)
  4966. T1=T1-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  4967. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  4968. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  4969. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  4970. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  4971. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  4972. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  4973. T1=T1+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  4974. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  4975. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  4976. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  4977. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  4978. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  4979. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  4980. T1=T1-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  4981. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  4982. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  4983. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  4984. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  4985. . M30*J30Y*J30X
  4986. MIV(2,2)=(T0+9.0D0*P**4*M30*M10+9.0D0*P**2*M30*J30Y+
  4987. . 9.0D0*P**2*M30*J10Y+18.0D0*P**2*M30*J30X+P**2*M10*J30X
  4988. . +J30Y*J30X+J10Y*J30X)/(T1+9.0D0*P**2*M30*J10Y*J30X+P**
  4989. . 2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  4990. T0=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  4991. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  4992. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  4993. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  4994. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  4995. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  4996. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  4997. T0=T0+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  4998. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  4999. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  5000. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  5001. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  5002. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  5003. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  5004. . 3)
  5005. T0=T0-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  5006. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  5007. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  5008. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  5009. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  5010. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  5011. . J30X)
  5012. T0=T0-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  5013. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  5014. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  5015. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  5016. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  5017. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  5018. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  5019. T0=T0+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  5020. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  5021. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  5022. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  5023. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  5024. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  5025. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  5026. T0=T0-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  5027. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  5028. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  5029. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  5030. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  5031. . M30*J30Y*J30X
  5032. MIV(2,3)=(81.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**4*
  5033. . M30**2+9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2*M30
  5034. . *J30Y-(9.0D0*DSIN(DBLE(Q3))**3*DSIN(DBLE(Q2))*P**2*M30
  5035. . *J30Z)-(81.0D0*DSIN(DBLE(Q3))*DSIN(DBLE(Q2))*DCOS(DBLE
  5036. . (Q3))*DCOS(DBLE(Q2))*P**4*M30**2)-(81.0D0*DSIN(DBLE(Q3
  5037. . ))*DSIN(DBLE(Q2))*P**4*M30**2)-(9.0D0*DSIN(DBLE(Q3))*
  5038. . DSIN(DBLE(Q2))*P**2*M30*J30Y))/(T0+9.0D0*P**2*M30*J10Y
  5039. . *J30X+P**2*J30Y*M10*J30X+J30Y*J10Y*J30X)
  5040. T0=9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30-(9.0D0*DSIN(
  5041. . DBLE(Q3))**4*P**2*M30*J30Y)+DSIN(DBLE(Q3))**4*Y*J30Y*
  5042. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30)-(DSIN(DBLE(Q3))**4*
  5043. . J30Y**2)+DSIN(DBLE(Q3))**4*J30Y*J30Z-(81.0D0*DSIN(DBLE
  5044. . (Q3))**2*P**4*M30**2)-(9.0D0*DSIN(DBLE(Q3))**2*P**4*
  5045. . M30*M10)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*M30*J30)+
  5046. . 9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z
  5047. T0=T0-(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J10Y)-(DSIN(
  5048. . DBLE(Q3))**2*P**2*J30Y*M10)+DSIN(DBLE(Q3))**2*P**2*
  5049. . J30Z*M10-(DSIN(DBLE(Q3))**2*Y*J30Y*J30)+DSIN(DBLE(Q3))
  5050. . **2*J30Y**2-(DSIN(DBLE(Q3))**2*J30Y*J10Y)+DSIN(DBLE(Q3
  5051. . ))**2*J30Z*J10Y-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2
  5052. . ))**2*P**4*M30**2)+81.0D0*P**4*M30**2+9.0D0*P**4*M30*
  5053. . M10+9.0D0*P**2*M30*J30Y
  5054. T1=729.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**6*M30
  5055. . **3+81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**2*P**4*
  5056. . M30**2*J30Y-(81.0D0*DSIN(DBLE(Q3))**4*DSIN(DBLE(Q2))**
  5057. . 2*P**4*M30**2*J30Z)+81.0D0*DSIN(DBLE(Q3))**4*P**4*Y*
  5058. . M30**2*J30-(81.0D0*DSIN(DBLE(Q3))**4*P**4*M30**2*J30Y)
  5059. . +9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Y*J30-(9.0D0*
  5060. . DSIN(DBLE(Q3))**4*P**2*Y*M30*J30Z*J30)
  5061. T1=T1+9.0D0*DSIN(DBLE(Q3))**4*P**2*Y*M30*J30X*J30-(
  5062. . 9.0D0*DSIN(DBLE(Q3))**4*P**2*M30*J30Y**2)+9.0D0*DSIN(
  5063. . DBLE(Q3))**4*P**2*M30*J30Y*J30Z-(9.0D0*DSIN(DBLE(Q3))
  5064. . **4*P**2*M30*J30Y*J30X)+DSIN(DBLE(Q3))**4*Y*J30Y*J30X*
  5065. . J30-(DSIN(DBLE(Q3))**4*Y*J30Z*J30X*J30)-(DSIN(DBLE(Q3)
  5066. . )**4*J30Y**2*J30X)+DSIN(DBLE(Q3))**4*J30Y*J30Z*J30X-(
  5067. . 729.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**6*M30**
  5068. . 3)
  5069. T1=T1-(81.0D0*DSIN(DBLE(Q3))**2*DSIN(DBLE(Q2))**2*P**4*
  5070. . M30**2*J30Y)-(729.0D0*DSIN(DBLE(Q3))**2*P**6*M30**3)-(
  5071. . 81.0D0*DSIN(DBLE(Q3))**2*P**6*M30**2*M10)-(81.0D0*DSIN
  5072. . (DBLE(Q3))**2*P**4*Y*M30**2*J30)+81.0D0*DSIN(DBLE(Q3))
  5073. . **2*P**4*M30**2*J30Z-(81.0D0*DSIN(DBLE(Q3))**2*P**4*
  5074. . M30**2*J10Y)-(81.0D0*DSIN(DBLE(Q3))**2*P**4*M30**2*
  5075. . J30X)
  5076. T1=T1-(9.0D0*DSIN(DBLE(Q3))**2*P**4*M30*J30Y*M10)+9.0D0
  5077. . *DSIN(DBLE(Q3))**2*P**4*M30*J30Z*M10-(9.0D0*DSIN(DBLE(
  5078. . Q3))**2*P**4*M30*M10*J30X)-(9.0D0*DSIN(DBLE(Q3))**2*P
  5079. . **2*Y*M30*J30Y*J30)-(9.0D0*DSIN(DBLE(Q3))**2*P**2*Y*
  5080. . M30*J30X*J30)+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y**2
  5081. . -(9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Y*J10Y)+9.0D0*
  5082. . DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J10Y
  5083. T1=T1+9.0D0*DSIN(DBLE(Q3))**2*P**2*M30*J30Z*J30X-(9.0D0
  5084. . *DSIN(DBLE(Q3))**2*P**2*M30*J10Y*J30X)-(DSIN(DBLE(Q3))
  5085. . **2*P**2*J30Y*M10*J30X)+DSIN(DBLE(Q3))**2*P**2*J30Z*
  5086. . M10*J30X-(DSIN(DBLE(Q3))**2*Y*J30Y*J30X*J30)+DSIN(DBLE
  5087. . (Q3))**2*J30Y**2*J30X-(DSIN(DBLE(Q3))**2*J30Y*J10Y*
  5088. . J30X)+DSIN(DBLE(Q3))**2*J30Z*J10Y*J30X-(729.0D0*DCOS(
  5089. . DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**6*M30**3)
  5090. T1=T1-(81.0D0*DCOS(DBLE(Q3))**2*DCOS(DBLE(Q2))**2*P**4*
  5091. . M30**2*J30X)+729.0D0*P**6*M30**3+81.0D0*P**6*M30**2*
  5092. . M10+81.0D0*P**4*M30**2*J30Y+81.0D0*P**4*M30**2*J10Y+
  5093. . 81.0D0*P**4*M30**2*J30X+9.0D0*P**4*M30*J30Y*M10+9.0D0*
  5094. . P**4*M30*M10*J30X+9.0D0*P**2*M30*J30Y*J10Y+9.0D0*P**2*
  5095. . M30*J30Y*J30X
  5096. MIV(3,3)=(T0+9.0D0*P**2*M30*J10Y+P**2*J30Y*M10+J30Y*
  5097. . J10Y)/(T1+9.0D0*P**2*M30*J10Y*J30X+P**2*J30Y*M10*J30X+
  5098. . J30Y*J10Y*J30X)
  5099. DO 25007 J=1,3
  5100. DO 25008 K=J+1,3
  5101. M(K,J)=M(J,K)
  5102. MIV(K,J)=MIV(J,K)
  5103. 25008 CONTINUE
  5104. 25007 CONTINUE
  5105. \end{framedverbatim}
  5106. \bibliography{gentran}
  5107. \bibliographystyle{plain}
  5108. \end{document}