rlisp88.rlg 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455
  1. Sun Jan 3 23:46:29 MET 1999
  2. REDUCE 3.7, 15-Jan-99 ...
  3. 1: 1:
  4. 2: 2: 2: 2: 2: 2: 2: 2: 2:
  5. 3: 3: % Test of Rlisp88 version of Rlisp. Many of these functions are taken
  6. % from the solved exercises in the book "RLISP '88: An Evolutionary
  7. % Approach to Program Design and Reuse".
  8. % Author: Jed B. Marti.
  9. on rlisp88;
  10. nil
  11. % Confidence test tries to do a little of everything. This doesn't really
  12. % test itself so you need to compare to the log file. Syntax errors on
  13. % the other hand should be cause for alarm.
  14. % ARRAYS
  15. % 1. Single dimension array.
  16. global '(v1);
  17. nil
  18. v1 := mkarray 5;
  19. [nil nil nil nil nil nil]
  20. for i:=0:5 do v1[i] := 3**i;
  21. nil
  22. v1;
  23. [1 3 9 27 81 243]
  24. % 2. 2D array.
  25. global '(v3x3);
  26. nil
  27. v3x3 := mkarray(2, 2);
  28. [[nil nil nil] [nil nil nil] [nil nil nil]]
  29. for row := 0:2 do
  30. for col := 0:2 do
  31. v3x3[row, col] := if row = col then 1.0 else 0.0;
  32. nil
  33. v3x3;
  34. [[1.0 0.0 0.0] [0.0 1.0 0.0] [0.0 0.0 1.0]]
  35. % 3. Triangular array.
  36. global '(tri);
  37. nil
  38. tri := mkarray 3;
  39. [nil nil nil nil]
  40. for row := 0:3 do tri[row] := mkarray row;
  41. nil
  42. for row := 0:3 do
  43. for col := 0:row do
  44. tri[row,col] := row * col;
  45. nil
  46. tri;
  47. [[0] [0 1] [0 2 4] [0 3 6 9]]
  48. % 4. ARRAY test.
  49. expr procedure rotate theta;
  50. /* Generates rotation array for angle theta (in radians) */
  51. array(array(cosd theta, - sind theta, 0.0),
  52. array(sind theta, cosd theta, 0.0),
  53. array(0.0, 0.0, 1.0));
  54. rotate
  55. rotate 45.0;
  56. [[0.707107 -0.707107 0.0] [0.707107 0.707107 0.0] [0.0 0.0 1.0]]
  57. % 5. Random elements.
  58. % Now create a vector with random elements.
  59. M3 := ARRAY('A, 3 + 4, ARRAY("String", 'ID), '(a b));
  60. [a 7 ["String" id] (a b)]
  61. M3[2, 1];
  62. id
  63. M4 := ARRAY(ARRAY('a, 'b), ARRAY('c, 'd));
  64. [[a b] [c d]]
  65. M4[1];
  66. [c d]
  67. % 6. Array addition.
  68. expr procedure ArrayAdd(a, b);
  69. if vectorp a then
  70. for i:=0:uc
  71. with c, uc
  72. initially c := mkarray(uc := upbv a)
  73. do c[i] := ArrayAdd(a[i], b[i])
  74. returns c
  75. else a + b;
  76. arrayadd
  77. ArrayAdd(array(array(array(1, 2), array(3, 4)),
  78. array(array(5, 6), array(7, 8))),
  79. array(array(array(1, 1), array(2, 2)),
  80. array(array(3, 3), array(4, 4))));
  81. [[[2 3] [5 6]] [[8 9] [11 12]]]
  82. % RECORDS
  83. % 1: Declaration.
  84. RECORD MAPF /* A MAPF record defines
  85. the contents of a MAPF file. */
  86. WITH
  87. MAPF!:NAME := "" /* Name of MAPF (a string) */,
  88. MAPF!:NUMBER := 0 /* MAPF number (integer) */,
  89. MAPF!:ROAD-COUNT := 0 /* Number of roads */,
  90. MAPF!:NODE-COUNT := 0 /* Number of nodes */,
  91. MAPF!:LLAT := 0.0 /* Lower left hand corner map latitude */,
  92. MAPF!:LLONG := 0.0 /* Lower left hand corner map longitude */,
  93. MAPF!:ULAT := 0.0 /* Upper right hand corner map latitude */,
  94. MAPF!:ULONG := 0.0 /* Upper right hand corner map longitude */;
  95. mapf
  96. % 2: Creation.
  97. global '(r1 r2 r3);
  98. nil
  99. r1 := mapf();
  100. [mapf "" 0 0 0 0.0 0.0 0.0 0.0]
  101. r2 := mapf(mapf!:name := "foobar", mapf!:road-count := 34);
  102. [mapf "foobar" 0 34 0 0.0 0.0 0.0 0.0]
  103. r3 := list('a . r1, 'b . r2);
  104. ((a . [mapf "" 0 0 0 0.0 0.0 0.0 0.0]) (b . [mapf "foobar" 0 34 0 0.0 0.0 0.0
  105. 0.0]))
  106. % 3: Accessing.
  107. mapf!:number r1;
  108. 0
  109. mapf!:road-count cdr assoc('b, r3);
  110. 34
  111. % 4: Assignment.
  112. mapf!:number r1 := 7622;
  113. 7622
  114. mapf!:road-count cdr assoc('b, r3) := 376;
  115. 376
  116. mapf!:node-count(mapf!:name r2 := mapf()) := 34;
  117. 34
  118. r2;
  119. [mapf [mapf "" 0 0 34 0.0 0.0 0.0 0.0] 0 376 0 0.0 0.0 0.0 0.0]
  120. % 5. Options.
  121. RECORD complex /* Stores complex reals */
  122. WITH
  123. R := 0.0 /* Real part */,
  124. I := 0.0 /* Imaginary part */
  125. HAS CONSTRUCTOR;
  126. complex
  127. Make-Complex(I := 34.0, R := 12.0);
  128. [complex 12.0 34.0]
  129. RECORD Rational /* Representation of rational numbers */
  130. WITH
  131. Num := 0 /* Numerator */,
  132. Den := 1 /* Denominator */
  133. HAS CONSTRUCTOR = rat;
  134. *** Function `num' has been redefined
  135. *** Function `den' has been redefined
  136. rational
  137. expr procedure gcd(p, q);
  138. if q > p then gcd(q, p)
  139. else (if r = 0 then q else gcd(q, r)) where r = remainder(p,q);
  140. gcd
  141. expr procedure Rational(a, b);
  142. /* Build a rational number in lowest terms */
  143. Rat(Num := a / g, Den := b / g) where g := gcd(a, b);
  144. rational
  145. Rational(34, 12);
  146. [rational 17 6]
  147. RECORD Timing /* Timing Record for RLISP test */
  148. WITH
  149. Machine := "" /* Machine name */,
  150. Storage := 0 /* Main storage in bits */,
  151. TimeMS = 0 /* Test time in milliseconds */
  152. HAS NO CONSTRUCTOR;
  153. timing
  154. % PREDICATE option.
  155. RECORD History /* Record of an event */
  156. WITH
  157. EventTime := 0.0 /* Time of event (units) */,
  158. EventData := NIL /* List with (type ...) */
  159. HAS PREDICATE = History!?;
  160. history
  161. History!? History(EventData := '(MOVE 34.5 52.5));
  162. t
  163. % FOR LOOP
  164. % 1) Basic test.
  165. EXPR PROCEDURE LPRINT lst;
  166. /* LPRINT displays each element of its argument separated by blanks.
  167. After the last element has been displayed, the print line is
  168. terminated. */
  169. FOR EACH element IN lst
  170. DO << PRIN2 element; PRINC " " >>
  171. FINALLY TERPRI()
  172. RETURNS lst;
  173. lprint
  174. LPRINT '(Now is the time to use RLISP);
  175. now is the time to use rlisp
  176. (now is the time to use rlisp)
  177. % 2) Basic iteration in both directions.
  178. FOR i:=5 STEP -2 UNTIL 0 DO PRINT i;
  179. 5
  180. 3
  181. 1
  182. nil
  183. FOR i:=1:3 DO PRINT i;
  184. 1
  185. 2
  186. 3
  187. nil
  188. % 3) COLLECT option.
  189. FOR EACH leftpart IN '(A B C)
  190. EACH rightpart IN '(1 2 "string")
  191. COLLECT leftpart . rightpart;
  192. ((a . 1) (b . 2) (c . "string"))
  193. % 4) IN/ON iterators.
  194. FOR EACH X IN '(a b c) DO PRINT x;
  195. a
  196. b
  197. c
  198. nil
  199. FOR EACH x ON '(a b c) DO PRINT x;
  200. (a b c)
  201. (b c)
  202. (c)
  203. nil
  204. % 5) EVERY option.
  205. FOR EACH x IN '(A B C) EVERY IDP x
  206. RETURNS "They are all id's";
  207. "They are all id's"
  208. FOR EACH x IN '(A B 12) EVERY IDP x
  209. RETURNS "They are all id's";
  210. nil
  211. % 6) INITIALLY/FINALLY option.
  212. EXPR PROCEDURE ListPrint x;
  213. /* ListPrint(x) displays each element of x separated by blanks. The
  214. first element is prefixed with "*** ". The last element is suffixed
  215. with a period and a new line. */
  216. FOR EACH element ON x
  217. INITIALLY PRIN2 "*** "
  218. DO << PRIN2 CAR element;
  219. IF CDR element THEN PRIN2 " " >>
  220. FINALLY << PRIN2 "."; TERPRI() >>;
  221. listprint
  222. ListPrint '(The quick brown bert died);
  223. *** the quick brown bert died.
  224. nil
  225. % 7) MAXIMIZE/MINIMIZE options.
  226. FOR EACH x IN '(A B 12 -34 2.3)
  227. WHEN NUMBERP x
  228. MAXIMIZE x;
  229. 12
  230. FOR EACH x IN '(A B 12 -34 2.3)
  231. WHEN NUMBERP x
  232. MINIMIZE x;
  233. -34
  234. % 8) RETURNS option.
  235. EXPR PROCEDURE ListFiddle(f, x);
  236. /* ListFiddle displays every element of its second argument and returns
  237. a list of those for which the first argument returns non-NIL. */
  238. FOR EACH element IN x
  239. WITH clist
  240. DO << PRINT element;
  241. IF APPLY(f, LIST element) THEN clist := element . clist >>
  242. RETURNS REVERSIP clist;
  243. listfiddle
  244. ListFiddle(FUNCTION ATOM, '(a (BANG 12) "OOPS!"));
  245. a
  246. (bang 12)
  247. "OOPS!"
  248. (a "OOPS!")
  249. % 9) SOME option.
  250. FOR EACH x IN '(a b 12) SOME NUMBERP x
  251. DO PRINT x;
  252. a
  253. b
  254. t
  255. % 10) UNTIL/WHILE options.
  256. EXPR PROCEDURE CollectUpTo l;
  257. /* CollectUpTo collect all the elements of the list l up to the
  258. first number. */
  259. FOR EACH x IN l UNTIL NUMBERP x COLLECT x;
  260. collectupto
  261. CollectUpTo '(a b c 1 2 3);
  262. (a b c)
  263. % 11) WHEN/UNLESS options.
  264. FOR EACH x IN '(A 12 "A String" 32)
  265. WHEN NUMBERP x
  266. COLLECT x;
  267. (12 32)
  268. % ##### Basic Tests #####
  269. % Tests some very basic things that seem to go wrong frequently.
  270. % Numbers.
  271. if +1 neq 1 then error(0, "+1 doesn't parse");
  272. nil
  273. if -1 neq - 1 then error(0, "-1 doesn't parse");
  274. nil
  275. expr procedure factorial n;
  276. if n < 2 then 1 else n * factorial(n - 1);
  277. *** Function `factorial' has been redefined
  278. factorial
  279. if +2432902008176640000 neq factorial 20 then
  280. error(0, "bignum + doesn't work");
  281. nil
  282. if -2432902008176640000 neq - factorial 20 then
  283. error(0, "bignum - doesn't work");
  284. nil
  285. % This actually blew up at one time.
  286. if -3.14159 neq - 3.14159 then error(0, "negative floats don't work");
  287. nil
  288. if +3.14159 neq 3.14159 then error(0, "positive floats don't work");
  289. nil
  290. % ##### Safe Functions #####
  291. % Description: A set of CAR/CDR alternatives that
  292. % return NIL when CAR/CDR of an atom is tried.
  293. expr procedure SafeCar x;
  294. /* Returns CAR of a list or NIL. */
  295. if atom x then nil else car x;
  296. *** Function `safecar' has been redefined
  297. safecar
  298. expr procedure SafeCdr x;
  299. /* Returns CDR of a list or NIL. */
  300. if atom x then nil else cdr x;
  301. *** Function `safecdr' has been redefined
  302. safecdr
  303. expr procedure SafeFirst x; SafeCar x;
  304. safefirst
  305. expr procedure SafeSecond x; SafeCar SafeCdr x;
  306. safesecond
  307. expr procedure SafeThird x; SafeSecond SafeCdr x;
  308. safethird
  309. % ##### Test of Procedures #####
  310. %------------------------- Exercise #1 -------------------------
  311. expr procedure delassoc(x, a);
  312. /* Delete the element from x from the alist a non-destructively. Returns
  313. the reconstructed list. */
  314. if null a then nil
  315. else if atom a then a . delassoc(x, cdr a)
  316. else if caar a = x then cdr a
  317. else car a . delassoc(x, cdr a);
  318. delassoc
  319. if delassoc('a, '((a b) (c d))) = '((c d))
  320. then "Test 1 delassoc OK"
  321. else error(0, "Test 1 delassoc failed");
  322. "Test 1 delassoc OK"
  323. if delassoc('b, '((a b) (b c) (c d))) = '((a b) (c d))
  324. then "Test 2 delassoc OK"
  325. else error(0, "Test 2 delassoc failed");
  326. "Test 2 delassoc OK"
  327. if delassoc('c, '((a b) (b c) (c d))) = '((a b) (b c))
  328. then "Test 3 delassoc OK"
  329. else error(0, "Test 3 delassoc failed");
  330. "Test 3 delassoc OK"
  331. if delassoc('d, '((a b) (b c) (c d))) = '((a b) (b c) (c d))
  332. then "Test 4 delassoc OK"
  333. else error(0, "Test 4 delassoc failed");
  334. "Test 4 delassoc OK"
  335. %------------------------- Exercise #2 -------------------------
  336. expr procedure gcd(u, v);
  337. if v = 0 then u else gcd(v, remainder(u, v));
  338. *** Function `gcd' has been redefined
  339. gcd
  340. if gcd(2, 4) = 2 then "Test 1 GCD OK" else error(0, "Test 1 GCD fails");
  341. "Test 1 GCD OK"
  342. if gcd(13, 7) = 1
  343. then "Test 2 GCD OK" else error(0, "Test 2 GCD fails");
  344. "Test 2 GCD OK"
  345. if gcd(15, 10) = 5
  346. then "Test 3 GCD OK" else error(0, "Test 3 GCD fails");
  347. "Test 3 GCD OK"
  348. if gcd(-15, 10) = -5
  349. then "Test 4 GCD OK" else error(0, "Test 4 GCD fails");
  350. "Test 4 GCD OK"
  351. if gcd(-15, 0) = -15
  352. then "Test 5 GCD OK" else error(0, "Test 5 GCD fails");
  353. "Test 5 GCD OK"
  354. %-------------------- Exercise #3 --------------------
  355. expr procedure properintersection(a, b);
  356. /* Returns the proper intersection of proper sets a and b.
  357. The set representation is a list of elements with the
  358. EQUAL relation. */
  359. if null a then nil
  360. else if car a member b then car a . properintersection(cdr a, b)
  361. else properintersection(cdr a, b);
  362. properintersection
  363. % Test an EQ intersection.
  364. properintersection('(a b), '(b c));
  365. (b)
  366. if properintersection('(a b), '(b c)) = '(b)
  367. then "Test 1 properintersection OK"
  368. else error(0, "Test 1 properintersection fails");
  369. "Test 1 properintersection OK"
  370. % Test an EQUAL intersection.
  371. properintersection('((a) b (c)), '((a) b (c)));
  372. ((a) b (c))
  373. if properintersection('((a) b (c)), '((a) b (c))) = '((a) b (c))
  374. then "Test 2 properintersection OK"
  375. else error(0, "Test 2 properintersection fails");
  376. "Test 2 properintersection OK"
  377. % Test an EQUAL intersection, out of order.
  378. properintersection('((a) b (c)), '(b (c) (a)));
  379. ((a) b (c))
  380. if properintersection('((a) b (c)), '(b (c) (a))) = '((a) b (c))
  381. then "Test 3 properintersection OK"
  382. else error(0, "Test 3 properintersection fails");
  383. "Test 3 properintersection OK"
  384. % Test an empty intersection.
  385. properintersection('((a) b (c)), '(a (b) c));
  386. nil
  387. if properintersection('((a) b (c)), '(a (b) c)) = nil
  388. then "Test 4 properintersection OK"
  389. else error(0, "Test 4 properintersection fails");
  390. "Test 4 properintersection OK"
  391. %-------------------- Exercise #4 -------------------------
  392. expr procedure TreeVisit(a, tree, c);
  393. /* Preorder visit of tree to find a. Returns path from root. c
  394. contains path to root of tree so far. */
  395. if null tree then nil
  396. else if a = car tree then append(c, {a})
  397. else TreeVisit(a, cadr tree, append(c, {car tree})) or
  398. TreeVisit(a, caddr tree, append(c, {car tree}));
  399. treevisit
  400. TreeVisit('c, '(a (b (d nil nil) (c nil nil)) (e nil nil)), nil);
  401. (a b c)
  402. if TreeVisit('c, '(a (b (d nil nil) (c nil nil)) (e nil nil)), nil)
  403. = '(a b c)
  404. then "Test 1 TreeVisit OK"
  405. else error(0, "Test 1 TreeVisit fails");
  406. "Test 1 TreeVisit OK"
  407. TreeVisit('h, '(a (b (d nil nil) (c nil nil))
  408. (e (f nil nil) (g (h nil nil) nil)) ), nil);
  409. (a e g h)
  410. if TreeVisit('h, '(a (b (d nil nil) (c nil nil))
  411. (e (f nil nil) (g (h nil nil) nil))),nil) = '(a e g h)
  412. then "Test 2 TreeVisit OK"
  413. else error(0, "Test 2 TreeVisit fails");
  414. "Test 2 TreeVisit OK"
  415. if TreeVisit('i, '(a (b (d nil nil) (c nil nil))
  416. (e (f nil nil) (g (h nil nil) nil)) ), nil) = nil
  417. then "Test 3 TreeVisit OK"
  418. else error(0, "Test 3 TreeVisit fails");
  419. "Test 3 TreeVisit OK"
  420. if TreeVisit('a, '(a (b (d nil nil) (c nil nil))
  421. (e (f nil nil) (g (h nil nil) nil)) ), nil) = '(a)
  422. then "Test 4 TreeVisit OK"
  423. else error(0, "Test 4 TreeVisit fails");
  424. "Test 4 TreeVisit OK"
  425. if TreeVisit('e, '(a (b (d nil nil) (c nil nil))
  426. (e (f nil nil) (g (h nil nil) nil)) ), nil) = '(a e)
  427. then "Test 5 TreeVisit OK"
  428. else error(0, "Test 5 TreeVisit fails");
  429. "Test 5 TreeVisit OK"
  430. %-------------------- Exercise #5 -------------------------
  431. expr procedure lookfor(str, l);
  432. /* Search for the list str (using =) in the top level
  433. of list l. Returns str and remaining part of l if
  434. found. */
  435. if null l then nil
  436. else if lookfor1(str, l) then l
  437. else lookfor(str, cdr l);
  438. lookfor
  439. expr procedure lookfor1(str, l);
  440. if null str then t
  441. else if null l then nil
  442. else if car str = car l then lookfor1(cdr str, cdr l);
  443. lookfor1
  444. if lookfor('(n o w),'(h e l l o a n d n o w i t i s)) = '(n o w i t i s)
  445. then "Test 1 lookfor OK"
  446. else error(0, "Test 1 lookfor fails");
  447. "Test 1 lookfor OK"
  448. if lookfor('(now is), '(now we have nothing is)) = NIL
  449. then "Test 2 lookfor OK"
  450. else error(0, "Test 2 lookfor fails");
  451. "Test 2 lookfor OK"
  452. if lookfor('(now is), '(well hello!, now)) = NIL
  453. then "Test 3 lookfor OK"
  454. else error(0, "Test 3 lookfor fails");
  455. "Test 3 lookfor OK"
  456. %-------------------- Exercise #6 -------------------------
  457. expr procedure add(a, b, carry, modulus);
  458. /* Add two numbers stored as lists with digits of
  459. modulus. Carry passes the carry around. Tries to
  460. suppress leading 0's but fails with negatives. */
  461. if null a then
  462. if null b then if zerop carry then nil
  463. else {carry}
  464. else remainder(carry + car b, modulus) .
  465. add(nil, cdr b, (carry + car b) / modulus, modulus)
  466. else if null b then add(b, a, carry, modulus)
  467. else remainder(car a + car b + carry, modulus) .
  468. add(cdr a, cdr b, (car a + car b + carry) / modulus,
  469. modulus);
  470. add
  471. if add('(9 9), '(9 9), 0, 10) = '(8 9 1)
  472. then "Test 1 add OK"
  473. else error(0, "Test 1 add fails");
  474. "Test 1 add OK"
  475. if add('(-9 -9), '(9 9), 0, 10) = '(0 0)
  476. then "Test 2 add OK"
  477. else error(0, "Test 2 add fails");
  478. "Test 2 add OK"
  479. if add('(9 9 9), '(9 9 9 9), 0, 10) = '(8 9 9 0 1)
  480. then "Test 3 add OK"
  481. else error(0, "Test 3 add fails");
  482. "Test 3 add OK"
  483. if add('(99 99 99), '(99 99 99 99), 0, 100) = '(98 99 99 0 1)
  484. then "Test 4 add OK"
  485. else error(0, "Test 4 add fails");
  486. "Test 4 add OK"
  487. if add('(13 12), '(15 1), 0, 16) = '(12 14)
  488. then "Test 5 add OK"
  489. else error(0, "Test 5 add fails");
  490. "Test 5 add OK"
  491. %-------------------- Exercise #7 -------------------------
  492. expr procedure clength(l, tmp);
  493. /* Compute the length of the (possibly circular) list l.
  494. tmp is used to pass values looked at down the list. */
  495. if null l or l memq tmp then 0
  496. else 1 + clength(cdr l, l . tmp);
  497. clength
  498. if clength('(a b c), nil) = 3
  499. then "Test 1 clength OK"
  500. else error(0, "Test 1 clength fails");
  501. "Test 1 clength OK"
  502. << xxx := '(a b c); cdr lastpair xxx := xxx; nil >>;
  503. nil
  504. if clength(xxx, nil) = 3
  505. then "Test 2 clength OK"
  506. else error(0, "Test 1 clength fails");
  507. "Test 2 clength OK"
  508. if clength(append('(a b c), xxx), nil) = 6
  509. then "Test 3 clength OK"
  510. else error(0, "Test 1 clength fails");
  511. "Test 3 clength OK"
  512. %------------------------- Exercise #8 -------------------------
  513. expr procedure fringe x;
  514. /* FRINGE(X) -- returns the fringe of X (the atoms at the
  515. end of the tree structure of X). */
  516. if atom x then {x}
  517. else if cdr x then append(fringe car x, fringe cdr x)
  518. else fringe car x;
  519. fringe
  520. if fringe nil = '(NIL)
  521. then "Test 1 fringe OK"
  522. else error(0, "Test 1 fringe fails");
  523. "Test 1 fringe OK"
  524. if fringe '(a b . c) = '(a b c)
  525. then "Test 2 fringe OK"
  526. else error(0, "Test 2 fringe fails");
  527. "Test 2 fringe OK"
  528. if fringe '((((a) . b) (c . d)) . e) = '(a b c d e)
  529. then "Test 3 fringe OK"
  530. else error(0, "Test 3 fringe fails");
  531. "Test 3 fringe OK"
  532. %------------------------- Exercise #9 -------------------------
  533. expr procedure delall(x, l);
  534. /* DELALL(X, L) -- Delete all X's from the list L using EQUAL
  535. test. The list is reconstructed. */
  536. if null l then nil
  537. else if x = car l then delall(x, cdr l)
  538. else car l . delall(x, cdr l);
  539. delall
  540. if delall('X, nil) = NIL
  541. then "Test 1 delall OK"
  542. else error(0, "Test 1 delall fails");
  543. "Test 1 delall OK"
  544. if delall('X, '(X)) = NIL
  545. then "Test 2 delall OK"
  546. else error(0, "Test 2 delall fails");
  547. "Test 2 delall OK"
  548. if delall('X, '(A)) = '(A)
  549. then "Test 3 delall OK"
  550. else error(0, "Test 3 delall fails");
  551. "Test 3 delall OK"
  552. if delall('(X B), '(A (B) (X B))) = '(A (B))
  553. then "Test 4 delall OK"
  554. else error(0, "Test 4 delall fails");
  555. "Test 4 delall OK"
  556. if delall('(X B), '((X B) (X B))) = NIL
  557. then "Test 5 delall OK"
  558. else error(0, "Test 5 delall fails");
  559. "Test 5 delall OK"
  560. if delall('(X B), '((X B) X B (X B))) = '(X B)
  561. then "Test 6 delall OK"
  562. else error(0, "Test 6 delall fails");
  563. "Test 6 delall OK"
  564. % ------------------------- Exercise #10 -------------------------
  565. expr procedure startswith(prefix, word);
  566. /* STARTSWITH(PREFIX, WORD) -- Returns T if the list of
  567. characters WORD begins with the list of characters PREFIX. */
  568. if null prefix then T
  569. else if word then
  570. if car prefix eq car word then
  571. startswith(cdr prefix, cdr word);
  572. startswith
  573. if startswith('(P R E), '(P R E S I D E N T)) = T
  574. then "Test 1 startswith OK!"
  575. else error(0, "Test 1 startswith fails");
  576. "Test 1 startswith OK!"
  577. if startswith('(P R E), '(P O S T F I X)) = NIL
  578. then "Test 2 startswith OK!"
  579. else error(0, "Test 2 startswith fails");
  580. "Test 2 startswith OK!"
  581. if startswith('(P R E), '(P R E)) = T
  582. then "Test 3 startswith OK!"
  583. else error(0, "Test 3 startswith fails");
  584. "Test 3 startswith OK!"
  585. if startswith('(P R E), '(P R)) = NIL
  586. then "Test 4 startswith OK!"
  587. else error(0, "Test 4 startswith fails");
  588. "Test 4 startswith OK!"
  589. if startswith('(P R E), NIL) = NIL
  590. then "Test 5 startswith OK!"
  591. else error(0, "Test 5 startswith fails");
  592. "Test 5 startswith OK!"
  593. if startswith('(P R E), '(P P R E)) = NIL
  594. then "Test 6 startswith OK!"
  595. else error(0, "Test 6 startswith fails");
  596. "Test 6 startswith OK!"
  597. % ##### Test of Definitions #####
  598. %------------------------- Exercise #1 -------------------------
  599. expr procedure goodlist l;
  600. /* GOODLIST(L) - returns T if L is a proper list. */
  601. if null l then T
  602. else if pairp l then goodlist cdr l;
  603. goodlist
  604. if goodlist '(a b c) = T
  605. then "Test 1 goodlist OK"
  606. else error(0, "Test 1 goodlist fails");
  607. "Test 1 goodlist OK"
  608. if goodlist nil = T
  609. then "Test 2 goodlist OK"
  610. else error(0, "Test 2 goodlist fails");
  611. "Test 2 goodlist OK"
  612. if goodlist '(a . b) = NIL
  613. then "Test 3 goodlist OK"
  614. else error(0, "Test 3 goodlist fails");
  615. "Test 3 goodlist OK"
  616. %------------------------- Exercise #2 -------------------------
  617. expr procedure fmember(a, b, fn);
  618. /* FMEMBER(A, B, FN) - Returns rest of B is A is a member
  619. of B using the FN of two arguments as an equality check. */
  620. if null b then nil
  621. else if apply(fn, {a, car b}) then b
  622. else fmember(a, cdr b, fn);
  623. fmember
  624. if fmember('a, '(b c a d), function EQ) = '(a d)
  625. then "Test 1 fmember is OK"
  626. else error(0, "Test 1 fmember fails");
  627. "Test 1 fmember is OK"
  628. if fmember('(a), '((b c) (a) d), function EQ) = NIL
  629. then "Test 2 fmember is OK"
  630. else error(0, "Test 2 fmember fails");
  631. "Test 2 fmember is OK"
  632. if fmember('(a), '((b c) (a) d), function EQUAL) = '((a) d)
  633. then "Test 3 fmember is OK"
  634. else error(0, "Test 3 fmember fails");
  635. "Test 3 fmember is OK"
  636. if fmember(34, '(1 2 56 12), function LESSP) = '(56 12)
  637. then "Test 4 fmember is OK"
  638. else error(0, "Test 4 fmember fails");
  639. "Test 4 fmember is OK"
  640. %------------------------- Exercise #3-4 -------------------------
  641. expr procedure findem(l, fn);
  642. /* FINDEM(L, FN) - returns a list of elements in L that satisfy
  643. the single argument function FN. */
  644. if null l then nil
  645. else if apply(fn, {car l}) then car l . findem(cdr l, fn)
  646. else findem(cdr l, fn);
  647. findem
  648. if findem('(a 1 23 b "foo"), function idp) = '(a b)
  649. then "Test 1 findem OK!"
  650. else error(0, "Test 1 findem fails");
  651. "Test 1 findem OK!"
  652. if findem('(1 3 a (44) 12 9),
  653. function (lambda x; numberp x and x < 10)) = '(1 3 9)
  654. then "Test 2 findem OK!"
  655. else error(0, "Test 2 findem fails");
  656. "Test 2 findem OK!"
  657. %------------------------- Exercise #5 -------------------------
  658. expr procedure insert(a, l, f);
  659. /* Insert the value a into list l based on the partial ordering function
  660. f(x,y). Non-destructive insertion. */
  661. if null l then {a}
  662. else if apply(f, {car l, a}) then a . l
  663. else car l . insert(a, cdr l, f);
  664. insert
  665. % Basic ascending order sort.
  666. insert(6, '(1 5 10), function geq);
  667. (1 5 6 10)
  668. if insert(6, '(1 5 10), function geq) = '(1 5 6 10)
  669. then "Test 1 insert (>=) OK"
  670. else error(0, "Test 1 insert (>=) fails");
  671. "Test 1 insert (>=) OK"
  672. % Try inserting element at end of list.
  673. insert(11, '(1 5 10), function geq);
  674. (1 5 10 11)
  675. if insert(11, '(1 5 10), function geq) = '(1 5 10 11)
  676. then "Test 2 insert (>=) OK"
  677. else error(0, "Test 2 insert (>=) fails");
  678. "Test 2 insert (>=) OK"
  679. % Tru inserting something at the list beginning.
  680. insert(-1, '(1 5 10), function geq);
  681. (-1 1 5 10)
  682. if insert(-1, '(1 5 10), function geq) = '(-1 1 5 10)
  683. then "Test 3 insert (>=) OK"
  684. else error(0, "Test 3 insert (>=) fails");
  685. "Test 3 insert (>=) OK"
  686. % Insert into an empty list.
  687. insert('34, nil, function leq);
  688. (34)
  689. if insert(34, nil, function leq) = '(34)
  690. then "Test 4 insert (<=) OK"
  691. else error(0, "Test 4 insert (<=) fails");
  692. "Test 4 insert (<=) OK"
  693. % Use a funny insertion function for (order . any);
  694. expr procedure cargeq(a, b); car a >= car b;
  695. cargeq
  696. insert('(34 . any), '((5 . now) (20 . and) (30 . then) (40 . but)),
  697. function cargeq);
  698. ((5 . now) (20 . and) (30 . then) (34 . any) (40 . but))
  699. if insert('(34 . any), '((5 . now) (20 . and) (30 . then) (40 . but)),
  700. function cargeq) = '((5 . now) (20 . and) (30 . then) (34 . any)
  701. (40 . but))
  702. then "Test 5 insert (>=) OK"
  703. else error(0, "Test 5 insert (>=) fails");
  704. "Test 5 insert (>=) OK"
  705. % ###### FOR Loop Exercises #####
  706. %------------------------- Exercise #1 -------------------------
  707. expr procedure floatlist l;
  708. /* FLOATLIST(L) returns a list of all floating point
  709. numbers in list L. */
  710. for each x in l
  711. when floatp x
  712. collect x;
  713. floatlist
  714. if floatlist '(3 3.4 a nil) = '(3.4)
  715. then "Test 1 floatlist OK"
  716. else error(0, "Test 1 floatlist fails");
  717. "Test 1 floatlist OK"
  718. if floatlist '(3.4 1.222 1.0e22) = '(3.4 1.222 1.0e22)
  719. then "Test 2 floatlist OK"
  720. else error(0, "Test 2 floatlist fails");
  721. "Test 2 floatlist OK"
  722. if floatlist '(a b c) = NIL
  723. then "Test 3 floatlist OK"
  724. else error(0, "Test 3 floatlist fails");
  725. "Test 3 floatlist OK"
  726. %------------------------- Exercise #2 -------------------------
  727. expr procedure revpairnum l;
  728. /* REVPAIRNUM(L) returns elements of L in a pair with
  729. the CAR a number starting at length of L and working
  730. backwards.*/
  731. for i:=length l step -1 until 0
  732. each x in l
  733. collect i . x;
  734. revpairnum
  735. if revpairnum '(a b c) = '((3 . a) (2 . b) (1 . c))
  736. then "Test 1 revpairnum OK"
  737. else error(0, "Test 1 revpairnum fails");
  738. "Test 1 revpairnum OK"
  739. if revpairnum nil = nil
  740. then "Test 2 revpairnum OK"
  741. else error(0, "Test 2 revpairnum fails");
  742. "Test 2 revpairnum OK"
  743. if revpairnum '(a) = '((1 . a))
  744. then "Test 3 revpairnum OK"
  745. else error(0, "Test 3 revpairnum fails");
  746. "Test 3 revpairnum OK"
  747. %------------------------- Exercise #3 -------------------------
  748. expr procedure lflatten l;
  749. /* LFLATTEN(L) destructively flattens the list L
  750. to all levels. */
  751. if listp l then for each x in l conc lflatten x
  752. else {l};
  753. lflatten
  754. if lflatten '(a (b) c (e (e))) = '(a b c e e)
  755. then "Test 1 lflatten OK"
  756. else error(0, "Test 1 lflatten fails");
  757. "Test 1 lflatten OK"
  758. if lflatten '(a b c) = '(a b c)
  759. then "Test 2 lflatten OK"
  760. else error(0, "Test 2 lflatten fails");
  761. "Test 2 lflatten OK"
  762. if lflatten nil = nil
  763. then "Test 3 lflatten OK"
  764. else error(0, "Test 3 lflatten fails");
  765. "Test 3 lflatten OK"
  766. if lflatten '(a (b (c (d)))) = '(a b c d)
  767. then "Test 4 lflatten OK"
  768. else error(0, "Test 4 lflatten fails");
  769. "Test 4 lflatten OK"
  770. %------------------------- Exercise #4 -------------------------
  771. expr procedure realstuff l;
  772. /* REALSTUFF(L) returns the number of non-nil items in l. */
  773. for each x in l count x;
  774. realstuff
  775. if realstuff '(a b nil c) = 3
  776. then "Test 1 realstuff OK"
  777. else error(0, "Test 1 realstuff fails");
  778. "Test 1 realstuff OK"
  779. if realstuff '(nil nil nil) = 0
  780. then "Test 2 realstuff OK"
  781. else error(0, "Test 2 realstuff fails");
  782. "Test 2 realstuff OK"
  783. if realstuff '(a b c d) = 4
  784. then "Test 3 realstuff OK"
  785. else error(0, "Test 3 realstuff fails");
  786. "Test 3 realstuff OK"
  787. %------------------------- Exercise #5 -------------------------
  788. expr procedure psentence s;
  789. /* PSENTENCE(S) prints the list of "words" S with
  790. separating blanks and a period at the end. */
  791. for each w on s
  792. do << prin2 car w;
  793. if cdr w then prin2 " " else prin2t "." >>;
  794. psentence
  795. psentence '(The man in the field is happy);
  796. the man in the field is happy.
  797. nil
  798. %------------------------- Exercise #6 -------------------------
  799. expr procedure bsort v;
  800. /* BSORT(V) sorts the vector V into ascending order using
  801. bubble sort. */
  802. for i:=0:sub1 upbv v
  803. returns v
  804. do for j:=add1 i:upbv v
  805. when i neq j and v[i] > v[j]
  806. with tmp
  807. do << tmp := v[j]; v[j] := v[i]; v[i] := tmp >>;
  808. bsort
  809. xxx := [4,3,2,1, 5];
  810. [4 3 2 1 5]
  811. if bsort xxx = [1,2,3,4,5]
  812. then "Test 1 bsort OK"
  813. else error(0, "Test 1 bsort fails");
  814. "Test 1 bsort OK"
  815. xxx := [1];
  816. [1]
  817. if bsort xxx = [1]
  818. then "Test 2 bsort OK"
  819. else error(0, "Test 2 bsort fails");
  820. "Test 2 bsort OK"
  821. %------------------------- Exercise #7 -------------------------
  822. expr procedure bsortt v;
  823. /* BSORTT(V) sorts the vector V into ascending order using
  824. bubble sort. It verifies that all elements are numbers. */
  825. << for i:=0:upbv v
  826. when not numberp v[i]
  827. do error(0, {v[i], "is not a number for BSORTT"});
  828. for i:=0:sub1 upbv v
  829. returns v
  830. do for j:=add1 i:upbv v
  831. when i neq j and v[i] > v[j]
  832. with tmp
  833. do << tmp := v[j]; v[j] := v[i]; v[i] := tmp >> >>;
  834. bsortt
  835. xxx := [1,2,'a];
  836. [1 2 a]
  837. if atom errorset(quote bsortt xxx, nil, nil)
  838. then "Test 1 bsortt OK"
  839. else error(0, "Test 1 bsortt fails");
  840. "Test 1 bsortt OK"
  841. xxx := [1, 4, 3, 1];
  842. [1 4 3 1]
  843. if car errorset(quote bsortt xxx, nil, nil) = [1,1,3,4]
  844. then "Test 2 bsortt OK"
  845. else error(0, "Test 2 bsortt fails");
  846. "Test 2 bsortt OK"
  847. % ------------------------- Exercise #8 -------------------------
  848. expr procedure average l;
  849. /* AVERAGE(L) compute the average of the numbers
  850. in list L. Returns 0 if there are none. */
  851. for each x in l
  852. with sm, cnt
  853. initially sm := cnt := 0
  854. when numberp x
  855. do << sm := sm + x; cnt := cnt + 1 >>
  856. returns if cnt > 0 then sm / cnt else 0;
  857. average
  858. if average '(a 12 34) = 23 then
  859. "Test 1 average OK"
  860. else error(0, "Test 1 average fails");
  861. "Test 1 average OK"
  862. if average '(a b c) = 0 then
  863. "Test 2 average OK"
  864. else error(0, "Test 2 average fails");
  865. "Test 2 average OK"
  866. if average '(a b c 5 6) = 5 then
  867. "Test 3 average OK"
  868. else error(0, "Test 3 average fails");
  869. "Test 3 average OK"
  870. if average '(a b c 5 6.0) = 5.5 then
  871. "Test 4 average OK"
  872. else error(0, "Test 4 average fails");
  873. "Test 4 average OK"
  874. %------------------------- Exercise #9 -------------------------
  875. expr procedure boundingbox L;
  876. /* BOUNDINGBOX(L) returns a list of
  877. (min X, max X, min Y, max Y)
  878. for the list L of dotted-pairs (x . y). */
  879. { for each x in L minimize car x,
  880. for each x in L maximize car x,
  881. for each y in L minimize cdr y,
  882. for each y in L maximize cdr y};
  883. boundingbox
  884. if boundingbox '((0 . 1) (4 . 5)) = '(0 4 1 5)
  885. then "Test 1 boundingbox OK"
  886. else error(0, "Test 1 boundingbox fails");
  887. "Test 1 boundingbox OK"
  888. if boundingbox nil = '(0 0 0 0)
  889. then "Test 2 boundingbox OK"
  890. else error(0, "Test 2 boundingbox fails");
  891. "Test 2 boundingbox OK"
  892. if boundingbox '((-5 . 3.4) (3.3 . 2.3) (1.2 . 33)
  893. (-5 . -8) (22.11 . 3.14) (2 . 3)) = '(-5 22.11 -8 33)
  894. then "Test 3 boundingbox OK"
  895. else error(0, "Test 3 boundingbox fails");
  896. "Test 3 boundingbox OK"
  897. %------------------------- Exercise #10 -------------------------
  898. expr procedure maxlists(a, b);
  899. /* MAXLISTS(A, B) -- Build a list such that for each pair
  900. of elements in lists A and B the new list has the largest
  901. element. */
  902. for each ae in a
  903. each be in b
  904. collect max(ae, be);
  905. maxlists
  906. if maxlists('(3 1.2), '(44.22 0.9 1.3)) = '(44.22 1.2)
  907. then "Test 1 maxlists OK"
  908. else error(0, "Test 1 maxlists fails");
  909. "Test 1 maxlists OK"
  910. if maxlists(nil, '(44.22 0.9 1.3)) = nil
  911. then "Test 2 maxlists OK"
  912. else error(0, "Test 2 maxlists fails");
  913. "Test 2 maxlists OK"
  914. if maxlists('(44.22 0.9 1.3), nil) = nil
  915. then "Test 3 maxlists OK"
  916. else error(0, "Test 3 maxlists fails");
  917. "Test 3 maxlists OK"
  918. if maxlists('(1.0 1.2 3.4), '(1 1)) = '(1.0 1.2)
  919. then "Test 4 maxlists OK"
  920. else error(0, "Test 4 maxlists fails");
  921. "Test 4 maxlists OK"
  922. %------------------------- Exercise #11 -------------------------
  923. expr procedure numberedlist l;
  924. /* NUMBEREDLIST(L) -- returns an a-list with the CAR being
  925. elements of L and CDR, the position in the list of the
  926. element starting with 0. */
  927. for i:=0:length l
  928. each e in l
  929. collect e . i;
  930. numberedlist
  931. if numberedlist nil = nil
  932. then "Test 1 numberedlist is OK"
  933. else error(0, "Test 1 numberedlist fails");
  934. "Test 1 numberedlist is OK"
  935. if numberedlist '(a) = '((a . 0))
  936. then "Test 2 numberedlist is OK"
  937. else error(0, "Test 2 numberedlist fails");
  938. "Test 2 numberedlist is OK"
  939. if numberedlist '(a b c) = '((a . 0) (b . 1) (c . 2))
  940. then "Test 2 numberedlist is OK"
  941. else error(0, "Test 2 numberedlist fails");
  942. "Test 2 numberedlist is OK"
  943. %------------------------- Exercise #12 -------------------------
  944. expr procedure reduce x;
  945. /* REDUCE(X) -- X is a list of things some of which are
  946. encapsulated as (!! . y) and returns x. Destructively
  947. replace these elements with just y. */
  948. for each v on x
  949. when eqcar(car v, '!!)
  950. do car v := cdar v
  951. returns x;
  952. reduce
  953. global '(x11);
  954. nil
  955. x11 := '((!! . a) (b c) (d (!! . 34)));
  956. ((!! . a) (b c) (d (!! . 34)))
  957. if reduce x11 = '(a (b c) (d (!! . 34)))
  958. then "Test 1 reduce OK"
  959. else error(0, "Test 1 reduce fails");
  960. "Test 1 reduce OK"
  961. if x11 = '(a (b c) (d (!! . 34)))
  962. then "Test 2 reduce OK"
  963. else error(0, "Test 2 reduce fails");
  964. "Test 2 reduce OK"
  965. % ##### Further Procedure Tests #####
  966. %------------------------- Exercise #1 -------------------------
  967. expr procedure removeflags x;
  968. /* REMOVEFLAGS(X) -- Scan list x replacing each top level
  969. occurrence of (!! . x) with x (whatever x is) and return
  970. the list. Replacement is destructive. */
  971. while x and eqcar(car x, '!!)
  972. with v
  973. initially v := x
  974. do << print x; car x := cdar x; print x; x := cdr x >>
  975. returns v;
  976. removeflags
  977. xxx := '((!!. a) (!! . b) c (!! . d));
  978. ((!! . a) (!! . b) c (!! . d))
  979. if removeflags xxx = '(a b c (!! . d))
  980. then "Test 1 removeflags OK"
  981. else error(0, "Test 1 removeflags fails");
  982. ((!! . a) (!! . b) c (!! . d))
  983. (a (!! . b) c (!! . d))
  984. ((!! . b) c (!! . d))
  985. (b c (!! . d))
  986. "Test 1 removeflags OK"
  987. if xxx = '(a b c (!! . d))
  988. then "Test 2 removeflags OK"
  989. else error(0, "Test 2 removeflags fails");
  990. "Test 2 removeflags OK"
  991. %------------------------- Exercise #2 -------------------------
  992. expr procedure read2char c;
  993. /* READ2CHAR(C) -- Read characters to C and return the
  994. list including C. Terminates at end of file. */
  995. repeat l := (ch := readch()) . l
  996. with ch, l
  997. until ch eq c or ch eq !$EOF!$
  998. returns reversip l;
  999. read2char
  1000. if read2char '!* = {!$EOL!$, 'a, 'b, 'c, '!*}
  1001. then "Test 1 read2char OK"
  1002. else error(0, "Test 1 read2char fails");
  1003. abc*
  1004. "Test 1 read2char OK"
  1005. %------------------------- Exercise #3 -------------------------
  1006. expr procedure skipblanks l;
  1007. /* SKIPBLANKS(L) - Returns L with leading blanks
  1008. removed. */
  1009. while l and eqcar(l, '! )
  1010. do l := cdr l
  1011. returns l;
  1012. skipblanks
  1013. if skipblanks '(! ! ! a b) neq '(a b)
  1014. then error(0, "Skipblanks fails test #1");
  1015. nil
  1016. if skipblanks nil
  1017. then error(0, "Skipblanks fails test #2");
  1018. nil
  1019. if skipblanks '(! ! ! )
  1020. then error(0, "Skipblanks fails test #3");
  1021. nil
  1022. if skipblanks '(! ! a b ! ) neq '(a b ! )
  1023. then error(0, "Skipblanks fails test #4");
  1024. nil
  1025. %------------------------- Exercise #4 -------------------------
  1026. expr procedure ntoken l;
  1027. /* NTOKEN(L) - Scan over blanks in l. Then collect
  1028. and return all characters up to the next blank
  1029. returning a dotted-pair of (token . rest of L) or
  1030. NIL if none is found. */
  1031. while l and eqcar(l, '! ) do l := cdr l
  1032. returns
  1033. if l then
  1034. while l and not eqcar(l, '! )
  1035. with tok
  1036. do << tok := car l . tok;
  1037. l := cdr l >>
  1038. returns (reversip tok . l);
  1039. ntoken
  1040. if ntoken '(! ! a b ! ) neq '((a b) . (! ))
  1041. then error(0, "ntoken fails test #1");
  1042. nil
  1043. if ntoken nil then error(0, "ntoken fails test #2");
  1044. nil
  1045. if ntoken '(! ! ! ) then error(0, "ntoken fails test #3");
  1046. nil
  1047. if ntoken '(! ! a b) neq '((a b) . nil)
  1048. then error(0, "ntoken fails test #4");
  1049. nil
  1050. % ##### Block Statement Exercises #####
  1051. %------------------------- Exercise #1 -------------------------
  1052. expr procedure r2nums;
  1053. /* R2NUMS() -- Read 2 numbers and return as a list. */
  1054. begin scalar n1;
  1055. n1 := read();
  1056. return {n1, read()}
  1057. end;
  1058. r2nums
  1059. if r2nums() = '(2 3)
  1060. then "Test 1 r2nums OK"
  1061. else error(0, "Test 1 r2nums failed");
  1062. 2 3
  1063. "Test 1 r2nums OK"
  1064. %------------------------- Exercise #2 -------------------------
  1065. expr procedure readcoordinate;
  1066. /* READCOORDINATE() -- Read a coordinate and return
  1067. it in radians. If prefixed with @, convert from
  1068. degrees. If a list convert from degrees minutes
  1069. seconds. */
  1070. begin scalar x;
  1071. return
  1072. (if (x := read()) eq '!@ then read() / 57.2957795130823208767981
  1073. else if pairp x then
  1074. (car x + cadr x / 60.0 + caddr x / 3600.0)
  1075. / 57.2957795130823208767981
  1076. else x)
  1077. end;
  1078. readcoordinate
  1079. fluid '(val);
  1080. nil
  1081. val := readcoordinate();
  1082. @ 57.29577
  1083. 1.0
  1084. if val < 1.000001 AND val > 0.999999
  1085. then "Test 1 readcoordinate OK"
  1086. else error(0, "Test 1 readcoordinate failed");
  1087. "Test 1 readcoordinate OK"
  1088. % This fails with poor arithmetic.
  1089. val := readcoordinate();
  1090. (57 17 44.772)
  1091. 1.0
  1092. if val < 1.000001 AND val > 0.999999
  1093. then "Test 2 readcoordinate OK"
  1094. else error(0, "Test 2 readcoordinate failed");
  1095. "Test 2 readcoordinate OK"
  1096. unfluid '(val);
  1097. nil
  1098. if readcoordinate() = 1.0
  1099. then "Test 3 readcoordinate OK"
  1100. else error(0, "Test 3 readcoordinate failed");
  1101. 1.0
  1102. "Test 3 readcoordinate OK"
  1103. %------------------------- Exercise #3 -------------------------
  1104. expr procedure delallnils l;
  1105. /* DELALLNILS(L) - destructively remove all NIL's from
  1106. list L. The resulting value is always EQ to L. */
  1107. begin scalar p, prev;
  1108. p := l;
  1109. loop: if null p then return l;
  1110. if null car p then
  1111. if null cdr p then
  1112. if null prev then return nil
  1113. else << cdr prev := nil;
  1114. return l >>
  1115. else << car p := cadr p;
  1116. cdr p := cddr p;
  1117. go to loop >>;
  1118. prev := p;
  1119. p := cdr p;
  1120. go to loop
  1121. end;
  1122. delallnils
  1123. fluid '(xxx yyy);
  1124. nil
  1125. % New - added to aid CSL.
  1126. xxx := '(a b c nil d);
  1127. (a b c nil d)
  1128. yyy := delallnils xxx;
  1129. (a b c d)
  1130. if yyy = '(a b c d) and yyy eq xxx
  1131. then "Test 1 dellallnils OK"
  1132. else error(0, "Test 1 delallnils Fails!");
  1133. "Test 1 dellallnils OK"
  1134. xxx := '(a nil b nil c nil d);
  1135. (a nil b nil c nil d)
  1136. yyy := delallnils xxx;
  1137. (a b c d)
  1138. if yyy = '(a b c d) and yyy eq xxx
  1139. then "Test 2 dellallnils OK"
  1140. else error(0, "Test 2 delallnils Fails!");
  1141. "Test 2 dellallnils OK"
  1142. xxx := '(a nil b nil c nil d nil);
  1143. (a nil b nil c nil d nil)
  1144. yyy := delallnils xxx;
  1145. (a b c d)
  1146. if yyy = '(a b c d) and yyy eq xxx
  1147. then "Test 3 dellallnils OK"
  1148. else error(0, "Test 3 delallnils Fails!");
  1149. "Test 3 dellallnils OK"
  1150. xxx := '(a nil nil nil nil b c d);
  1151. (a nil nil nil nil b c d)
  1152. yyy := delallnils xxx;
  1153. (a b c d)
  1154. if yyy = '(a b c d) and yyy eq xxx
  1155. then "Test 4 dellallnils OK"
  1156. else error(0, "Test 4 delallnils Fails!");
  1157. "Test 4 dellallnils OK"
  1158. xxx := '(nil a b c d);
  1159. (nil a b c d)
  1160. yyy := delallnils xxx;
  1161. (a b c d)
  1162. if yyy = '(a b c d) and yyy eq xxx
  1163. then "Test 5 dellallnils OK"
  1164. else error(0, "Test 5 delallnils Fails!");
  1165. "Test 5 dellallnils OK"
  1166. xxx := '(nil nil nil a b c d);
  1167. (nil nil nil a b c d)
  1168. yyy := delallnils xxx;
  1169. (a b c d)
  1170. if yyy = '(a b c d) and yyy eq xxx
  1171. then "Test 6 dellallnils OK"
  1172. else error(0, "Test 6 delallnils Fails!");
  1173. "Test 6 dellallnils OK"
  1174. xxx := '(a b c d nil nil nil);
  1175. (a b c d nil nil nil)
  1176. yyy := delallnils xxx;
  1177. (a b c d)
  1178. if yyy = '(a b c d) and yyy eq xxx
  1179. then "Test 7 dellallnils OK"
  1180. else error(0, "Test 7 delallnils Fails!");
  1181. "Test 7 dellallnils OK"
  1182. %------------------------- Exercise 4 -------------------------
  1183. expr procedure dprin1 x;
  1184. /* DPRIN1(X) - Print X in dotted-pair notation (to
  1185. all levels). Returns X as its value. */
  1186. if vectorp x then
  1187. << prin2 "[";
  1188. for i:=0:upbv x
  1189. do << dprin1 x[i];
  1190. if i < upbv x then prin2 " " >>;
  1191. prin2 "]";
  1192. x >>
  1193. else if atom x then prin1 x
  1194. else << prin2 "(";
  1195. dprin1 car x;
  1196. prin2 " . ";
  1197. dprin1 cdr x;
  1198. prin2 ")";
  1199. x >>;
  1200. dprin1
  1201. % The test is hard to make because we're doing output.
  1202. % Verify the results by hand and make sure it returns the
  1203. % argument.
  1204. dprin1 nil;
  1205. nil
  1206. nil
  1207. dprin1 '(a . b);
  1208. (a . b)
  1209. (a . b)
  1210. dprin1 '(a 1 "foo");
  1211. (a . (1 . ("foo" . nil)))
  1212. (a 1 "foo")
  1213. dprin1 '(((a)));
  1214. (((a . nil) . nil) . nil)
  1215. (((a)))
  1216. << x := mkvect 2; x[0] := 'a; x[1] := '(b c); x[2] := 34; >>;
  1217. nil
  1218. dprin1 {'(b c), x, 34};
  1219. ((b . (c . nil)) . ([a (b . (c . nil)) 34] . (34 . nil)))
  1220. ((b c) [a (b c) 34] 34)
  1221. % ##### Property List Exercises #####
  1222. %---------------------------- Exercise #1 ------------------------------
  1223. global '(stack!*);
  1224. nil
  1225. expr procedure pexecute l;
  1226. /* PEXECUTE(L) - L is a stack language. Constants are
  1227. placed on the global stack!*, id's mean a function
  1228. call to a function under the STACKFN property of the
  1229. function name. Other values are placed on the stack
  1230. without evaluation. */
  1231. if null l then nil
  1232. else if constantp car l then
  1233. << stack!* := car l . stack!*;
  1234. pexecute cdr l >>
  1235. else if idp car l then
  1236. if get(car l, 'STACKFN) then
  1237. << apply(get(car l, 'STACKFN), nil);
  1238. pexecute cdr l >>
  1239. else error(0, {car l, "undefined function"})
  1240. else << stack!* := car l . stack!*;
  1241. pexecute cdr l >>;
  1242. pexecute
  1243. expr procedure pdiff;
  1244. /* PADD1() - Subtract the 2nd stack elt from the
  1245. first and replace top two entries with result. */
  1246. stack!* := (cadr stack!* - car stack!*) . cddr stack!*;
  1247. pdiff
  1248. put('!-, 'STACKFN, 'pdiff);
  1249. pdiff
  1250. expr procedure pplus2;
  1251. /* PPLUS2() - Pop and add the top two numbers
  1252. on the stack and push the result. */
  1253. stack!* := (car stack!* + cadr stack!*) . cddr stack!*;
  1254. pplus2
  1255. put('!+, 'STACKFN, 'pplus2);
  1256. pplus2
  1257. expr procedure pprint;
  1258. /* PPRINT() - Print the top stack element. */
  1259. print car stack!*;
  1260. pprint
  1261. put('PRINT, 'STACKFN, 'pprint);
  1262. pprint
  1263. pexecute '(3 4 !+);
  1264. nil
  1265. if stack!* neq '(7) then error(0, "PEXECUTE test #1 fails");
  1266. nil
  1267. stack!* := nil;
  1268. nil
  1269. pexecute '(5 3 !- 2 4 !+ !+);
  1270. nil
  1271. if stack!* neq '(8) then error(0, "PEXECUTE test #2 fails");
  1272. nil
  1273. %---------------------------- Exercise #2 ------------------------------
  1274. expr procedure pexecute l;
  1275. /* PEXECUTE(L) - L is a stack language. Constants are
  1276. placed on the global stack!*, id's mean a function
  1277. call to a function under the STACKFN property of the
  1278. function name. Other values are placed on the stack
  1279. without evaluation. */
  1280. if null l then nil
  1281. else if constantp car l then
  1282. << stack!* := car l . stack!*;
  1283. pexecute cdr l >>
  1284. else if idp car l then
  1285. if eqcar(l, 'QUOTE) then
  1286. << stack!* := cadr l . stack!*;
  1287. pexecute cddr l >>
  1288. else if flagp(car l, 'STACKVAR) then
  1289. << stack!* := get(car l, 'STACKVAL) . stack!*;
  1290. pexecute cdr l >>
  1291. else if get(car l, 'STACKFN) then
  1292. << apply(get(car l, 'STACKFN), nil);
  1293. pexecute cdr l >>
  1294. else error(0, {car l, "undefined function"})
  1295. else << stack!* := car l . stack!*;
  1296. pexecute cdr l >>;
  1297. *** Function `pexecute' has been redefined
  1298. pexecute
  1299. expr procedure pset;
  1300. /* PSET() - Put the second value on the stack under
  1301. the STACKVAL attribute of the first. Flag the id as
  1302. a STACKVAR for later use. Pop the top stack
  1303. element. */
  1304. << put(car stack!*, 'STACKVAL, cadr stack!*);
  1305. flag({car stack!*}, 'STACKVAR);
  1306. stack!* := cdr stack!* >>;
  1307. pset
  1308. put('SET, 'STACKFN, 'pset);
  1309. pset
  1310. stack!* := nil;
  1311. nil
  1312. pexecute '(4.5 quote x set 4 !+ x !+ PRINT);
  1313. 13.0
  1314. nil
  1315. if stack!* neq '(13.0) then error(0, "Test 3 PEXECUTE fails");
  1316. nil
  1317. % ##### Records Exercises #####
  1318. %------------------------- Exercise #1 -------------------------
  1319. record qtree /* QTREE is a quad tree node element. */
  1320. with
  1321. node := NIL /* Node name */,
  1322. q1 := NIL /* Child #1 */,
  1323. q2 := NIL /* Child #2 */,
  1324. q3 := NIL /* Child #3 */,
  1325. q4 := NIL /* Child #4 */;
  1326. qtree
  1327. expr procedure qvisit q;
  1328. /* QVISIT(Q) -- Q is a QTREE data structure or NIL as are
  1329. each of its children. Return a preorder visit of each
  1330. node. */
  1331. if null q then nil
  1332. else append({node q},
  1333. append(qvisit q1 q,
  1334. append(qvisit q2 q,
  1335. append(qvisit q3 q, qvisit q4 q))));
  1336. qvisit
  1337. /* A simple quad tree. */
  1338. global '(qdemo);
  1339. nil
  1340. qdemo := qtree(node := 'A,
  1341. q1 := qtree(node := 'B),
  1342. q2 := qtree(node := 'C),
  1343. q3 := qtree(node := 'D,
  1344. q1 := qtree(node := 'E)),
  1345. q4 := qtree(node := 'F));
  1346. [qtree a [qtree b nil nil nil nil] [qtree c nil nil nil nil] [qtree d [qtree e
  1347. nil nil nil nil] nil nil nil] [qtree f nil nil nil nil]]
  1348. if qvisit qdemo = '(A B C D E F)
  1349. then "Test 1 qvisit OK!"
  1350. else error(0, "Test 1 qvisit Fails!");
  1351. "Test 1 qvisit OK!"
  1352. /* The quadtree in the book. */
  1353. global '(qdemo2);
  1354. nil
  1355. qdemo2 := qtree(node := 'A,
  1356. q1 := qtree(node := 'B),
  1357. q2 := qtree(node := 'C),
  1358. q3 := qtree(node := 'D,
  1359. q1 := qtree(node := 'E,
  1360. q2 := qtree(node := 'F)),
  1361. q2 := qtree(node := 'G),
  1362. q3 := qtree(node := 'H),
  1363. q4 := qtree(node := 'I)));
  1364. [qtree a [qtree b nil nil nil nil] [qtree c nil nil nil nil] [qtree d [qtree e
  1365. nil [qtree f nil nil nil nil] nil nil] [qtree g nil nil nil nil] [qtree h nil
  1366. nil nil nil] [qtree i nil nil nil nil]] nil]
  1367. if qvisit qdemo2 = '(A B C D E F G H I)
  1368. then "Test 2 qvisit OK!"
  1369. else error(0, "Test 2 qvisit Fails!");
  1370. "Test 2 qvisit OK!"
  1371. if qvisit nil = NIL
  1372. then "Test 3 qvisit OK!"
  1373. else error(0, "Test 3 qvisit Fails!");
  1374. "Test 3 qvisit OK!"
  1375. %------------------------- Exercise #2 -------------------------
  1376. expr procedure qsearch(q, val, fn);
  1377. /* QSEARCH(Q, VAL, FN) -- Returns the node path from the
  1378. root of the quadtree Q to VAL using FN as an equality
  1379. function whose first argument is from the tree and
  1380. second VAL. */
  1381. if null q then nil
  1382. else if apply(fn, {val, node q}) then {node q}
  1383. else begin scalar v;
  1384. if v := qsearch(q1 q, val, fn) then return node q . v;
  1385. if v := qsearch(q2 q, val, fn) then return node q . v;
  1386. if v := qsearch(q3 q, val, fn) then return node q . v;
  1387. if v := qsearch(q4 q, val, fn) then return node q . v
  1388. end;
  1389. qsearch
  1390. if qsearch(qdemo, 'E, function EQ) = '(A D E)
  1391. then "Test 1 qsearch OK!"
  1392. else error(0, "Test 1 qsearch fails");
  1393. "Test 1 qsearch OK!"
  1394. if qsearch(qdemo, 'XXX, function EQ) = nil
  1395. then "Test 2 qsearch OK!"
  1396. else error(0, "Test 2 qsearch fails");
  1397. "Test 2 qsearch OK!"
  1398. if qsearch(qdemo2, 'F, function EQ) = '(A D E F)
  1399. then "Test 3 qsearch OK!"
  1400. else error(0, "Test 3 qsearch fails");
  1401. "Test 3 qsearch OK!"
  1402. %------------------------- Exercise #3 -------------------------
  1403. record commchain
  1404. /* A COMMCHAIN is an n-ary tree with superior and
  1405. subordinate links. */
  1406. with
  1407. name := NIL /* Name of this node. */,
  1408. superior := NIL /* Pointer to superior node. */,
  1409. subordinates := NIL /* List of subordinates. */;
  1410. commchain
  1411. expr procedure backchain(l, sup);
  1412. /* BACKCHAIN(L, SUP) -- Fill in the SUPERIOR fields of
  1413. each record in the n-ary tree (links in the SUBORDINATES
  1414. field) to the lowest level. SUP is the current
  1415. superior. */
  1416. if null l then nil
  1417. else << superior l := sup;
  1418. for each sb in subordinates l
  1419. do backchain(sb, l) >>;
  1420. backchain
  1421. /* Demo the back chain. */
  1422. global '(cch);
  1423. nil
  1424. cch :=
  1425. commchain(
  1426. name := 'TOP,
  1427. subordinates :=
  1428. {commchain(name := 'LEV1-A),
  1429. commchain(
  1430. name := 'LEV1-B,
  1431. subordinates :=
  1432. {commchain(name := 'LEV2-A),
  1433. commchain(name := 'LEV2-B)}),
  1434. commchain(name := 'LEV1-C)});
  1435. [commchain top nil ([commchain lev1!-a nil nil] [commchain lev1!-b nil ([
  1436. commchain lev2!-a nil nil] [commchain lev2!-b nil nil])] [commchain lev1!-c nil
  1437. nil])]
  1438. % Wrap this up to avoid printing problems.
  1439. << backchain(cch, 'COMMANDER); NIL >>;
  1440. nil
  1441. if superior cch EQ 'COMMANDER
  1442. then "Test 1 backchain OK!"
  1443. else error(0, "Test 1 backchain Fails!");
  1444. "Test 1 backchain OK!"
  1445. if name superior car subordinates cch EQ 'TOP
  1446. then "Test 2 backchain OK!"
  1447. else error(0, "Test 2 backchain Fails!");
  1448. "Test 2 backchain OK!"
  1449. if name superior car subordinates cadr subordinates cch
  1450. eq 'LEV1-B
  1451. then "Test 3 backchain OK!"
  1452. else error(0, "Test 3 backchain Fails!");
  1453. "Test 3 backchain OK!"
  1454. % ##### Local Variable Exercises #####
  1455. %------------------------- Exercise #1 -------------------------
  1456. expr procedure lookup(v, a);
  1457. /* LOOKUP(V, A) -> Look for V in A and signal an error if not present.*/
  1458. (if rv then cdr rv else error(0, {v, "not in association list"}))
  1459. where rv := assoc(v, a);
  1460. lookup
  1461. if lookup('a, '((a . b) (c . d))) = 'b
  1462. then "Test 1 lookup success"
  1463. else error(0, "Test 1 lookup fails");
  1464. "Test 1 lookup success"
  1465. if errorset(quote lookup('f, '((a . b) (c . d))), nil, nil) = 0
  1466. then "Test 2 lookup success"
  1467. else error(0, "Test 2 lookup fails");
  1468. "Test 2 lookup success"
  1469. %------------------------- Exercise #2 -------------------------
  1470. expr procedure quadratic(a, b, c);
  1471. /* QUADRATIC(A, B, C) -- Returns both solutions of the
  1472. quadratic equation A*X^2 + B*X + C */
  1473. {(-B + U) / V, (-B - U) / V}
  1474. where U := SQRT(B^2 - 4*A*C),
  1475. V := 2.0 * A;
  1476. quadratic
  1477. if quadratic(1.0, 2.0, 1.0) = '(-1.0 -1.0)
  1478. then "Test 1 quadratic OK!"
  1479. else error(0, "Test 1 quadratic Fails!");
  1480. "Test 1 quadratic OK!"
  1481. if quadratic(1.0, 0.0, -1.0) = '(1.0 -1.0)
  1482. then "Test 2 quadratic OK!"
  1483. else error(0, "Test 2 quadratic Fails!");
  1484. "Test 2 quadratic OK!"
  1485. %------------------------- Exercise #3 -------------------------
  1486. expr procedure lineintersection(x1, y1,
  1487. x2, y2,
  1488. x3, y3,
  1489. x4, y4);
  1490. /* LINEINTERSECTION(X1,Y1,X2,Y2,X3,Y3,X4,Y4) -
  1491. Computes the intersection of line X1,Y1 ->
  1492. X2,Y2 with X3,Y3 -> X4,Y4 if any. Returns NIL
  1493. if no such intersection. */
  1494. (if zerop denom or zerop d1 or zerop d2 then nil
  1495. else
  1496. ((if p1 < 0 or p1 > d1 or p2 < 0 or p2 > d2
  1497. then nil
  1498. else (x1 + (x2 - x1) * p1 / d1) .
  1499. (y1 + (y2 - y1) * p1 / d1))
  1500. where p1 := num1 / denom,
  1501. p2 := num2 / denom)
  1502. where
  1503. num1 := d1*(x1*y3 - x1*y4 - x3*y1 + x3*y4
  1504. + x4*y1 - x4*y3),
  1505. num2 := d2*(- x1*y2 + x1*y3 + x2*y1 - x2*y3
  1506. - x3*y1 + x3*y2))
  1507. where d1 :=sqrt((x2 - x1)^2 + (y2 - y1)^2),
  1508. d2 := sqrt((x4 - x3)^2 + (y4 - y3)^2),
  1509. denom := x1*y3 - x1*y4 - x2*y3 + x2*y4
  1510. - x3*y1 + x3*y2 + x4*y1 - x4*y2;
  1511. lineintersection
  1512. if lineintersection(1, 1, 3, 3, 1, 2, 5, 2) = '(2.0 . 2.0)
  1513. then "Test 1 LINEINTERSECTION success!"
  1514. else error(0, "Test 1 LINEINTERSECTION fails intersect test");
  1515. "Test 1 LINEINTERSECTION success!"
  1516. % intersection at start and end points.
  1517. if lineintersection(1, 1, 2, 2, 1, 1, 1, 0) = '(1.0 . 1.0)
  1518. then "Test 2 LINEINTERSECTION success!"
  1519. else error(0, "Test 2LINEINTERSECTION fails intersect at start test");
  1520. "Test 2 LINEINTERSECTION success!"
  1521. if lineintersection(1, 1, 2, 2, 0, 1, 2, 2) = '(2.0 . 2.0)
  1522. then "Test 3 LINEINTERSECTION success!"
  1523. else error(0,
  1524. "Test 3 LINEINTERSECTION fails intersect at endpoint test");
  1525. "Test 3 LINEINTERSECTION success!"
  1526. if lineintersection(1, 1, 2, 2, 2, 2, 3, 4) = '(2.0 . 2.0)
  1527. then "Test 4 LINEINTERSECTION success!"
  1528. else error(0,
  1529. "Test 4 LINEINTERSECTION fails intersect end - begin point test");
  1530. "Test 4 LINEINTERSECTION success!"
  1531. % Now try no intersection test.
  1532. if null lineintersection(1, 1, 2, 3, 2, 4, 4, 5)
  1533. then "Test 5 LINEINTERSECTION success!"
  1534. else error(0,
  1535. "Test 5 LINEINTERSECTION fails quadrant 1 no intersection");
  1536. "Test 5 LINEINTERSECTION success!"
  1537. if null lineintersection(1, 1, 2, 2, 1.75, 1.5, 5, 1.75)
  1538. then "Test 6 LINEINTERSECTION success!"
  1539. else error(0,
  1540. "Test 6 LINEINTERSECTION fails quadrant 2 no intersection");
  1541. "Test 6 LINEINTERSECTION success!"
  1542. %------------------------- Exercise #4 -------------------------
  1543. expr procedure stdev x;
  1544. /* STDEV(X) - compute the standard deviation of the
  1545. numbers in list X. */
  1546. if null x then 0
  1547. else (sqrt((for each v in x sum (v - avg)^2) / n)
  1548. where avg := (for each v in x sum v) / n)
  1549. where n := length x;
  1550. stdev
  1551. if stdev '(3.0 3.0 3.0) neq 0.0 then
  1552. error(0, "Test 1 STDEV fails");
  1553. nil
  1554. % ##### Array Exercises #####
  1555. %------------------------- Exercise #1 -------------------------
  1556. expr procedure vaverage v;
  1557. /* VAVERAGE(V) -- compute the average of all numeric
  1558. elements of the vector v. */
  1559. (if cnt > 0 then
  1560. ((for i:=0:upbv v when numberp v[i] sum v[i]) / float cnt)
  1561. else 0.0)
  1562. where cnt := for i:=0:upbv v count numberp v[i];
  1563. vaverage
  1564. if vaverage array(1,2,3) = 2.0
  1565. then "Test 1 vaverage is OK"
  1566. else error(0, "Test 1 vaverage fails");
  1567. "Test 1 vaverage is OK"
  1568. if vaverage array(3, 'a, 3, 6.0, 'f) = 4.0
  1569. then "Test 2 vaverage is OK"
  1570. else error(0, "Test 2 vaverage fails");
  1571. "Test 2 vaverage is OK"
  1572. if vaverage array('a, 'b) = 0.0
  1573. then "Test 3 vaverage is OK"
  1574. else error(0, "Test 3 vaverage fails");
  1575. "Test 3 vaverage is OK"
  1576. %------------------------- Exercise #2 -------------------------
  1577. expr procedure MAPPEND(a, b);
  1578. /* MAPPEND(A, B) -- Appends array B to array A and
  1579. returns a new array with both. */
  1580. begin scalar c, ua;
  1581. c := mkvect((ua := 1 + upbv a) + upbv b);
  1582. for i:=0:upbv a do c[i] := a[i];
  1583. for i:=0:upbv b do c[i + ua] := b[i];
  1584. return c
  1585. end;
  1586. *** Function `mappend' has been redefined
  1587. mappend
  1588. global '(a1 a2);
  1589. nil
  1590. a1 := array(1, 2, 3);
  1591. [1 2 3]
  1592. a2 := array(3, 4, 5, 6);
  1593. [3 4 5 6]
  1594. if mappend(a1, a2) = array(1,2,3,3,4,5,6)
  1595. then "Test 1 MAPPEND is OK"
  1596. else error(0, "Test 1 MAPPEND fails");
  1597. "Test 1 MAPPEND is OK"
  1598. if mappend(mkvect 0, mkvect 0) = mkvect 1
  1599. then "Test 2 MAPPEND is OK"
  1600. else error(0, "Test 2 MAPPEND fails");
  1601. "Test 2 MAPPEND is OK"
  1602. %------------------------- Exercise #3 -------------------------
  1603. expr procedure indx(a, v);
  1604. /* INDX(A, V) -- returns index of A in V using EQ test,
  1605. otherwise NIL. */
  1606. for i:=0:upbv v
  1607. until a eq v[i]
  1608. returns if i <= upbv v then i
  1609. if indx('a, array(1, 2, 'a, 34)) = 2
  1610. then "Test 1 indx OK"
  1611. else error(0, "Test 1 indx fails");
  1612. !~indx
  1613. if null indx('a, array(1, 2, 3, 4))
  1614. then "Test 2 indx OK"
  1615. else error(0, "Test 2 indx fails");
  1616. "Test 2 indx OK"
  1617. %------------------------- Exercise #4 -------------------------
  1618. expr procedure mpy4x4(a, b);
  1619. /* MPY4X4(A, B) -- Create a new 4x4 matrix and return with
  1620. the product of A and B in it. */
  1621. for row:=0:3
  1622. with c, s
  1623. initially c := mkarray(3,3)
  1624. do << for col := 0:3 do
  1625. do c[row,col] :=
  1626. for p := 0:3 sum a[row,p] * b[p,col] >>
  1627. returns c;
  1628. mpy4x4
  1629. expr procedure translate4x4(x, y, z);
  1630. /* TRANSLATE4X4(X, Y, Z) -- Generate and return a
  1631. 4x4 matrix to translate X, Y, Z. */
  1632. array(array(1.0, 0.0, 0.0, 0.0),
  1633. array(0.0, 1.0, 0.0, 0.0),
  1634. array(0.0, 0.0, 1.0, 0.0),
  1635. array(x, y, z, 1.0));
  1636. translate4x4
  1637. expr procedure rotatex4x4 th;
  1638. /* ROTATEX4X4(TH) -- Generate a 4x4 rotation matrix about
  1639. the X axis, TH radians. */
  1640. array(array(1.0, 0.0, 0.0, 0.0),
  1641. array(0.0, cos th, -sin th, 0.0),
  1642. array(0.0, sin th, cos th, 0.0),
  1643. array(0.0, 0.0, 0.0, 1.0));
  1644. rotatex4x4
  1645. expr procedure mappoint(x, y, z, m);
  1646. /* MAPPOINT(X, Y, Z, M) -- Returns the transformed point
  1647. X, Y, Z by the 4x4 matrix M. */
  1648. {x*m[0,0] + y*m[1,0] + z*m[2,0] + m[3,0],
  1649. x*m[0,1] + y*m[1,1] + z*m[2,1] + m[3,1],
  1650. x*m[0,2] + y*m[1,2] + z*m[2,2] + m[3,2]};
  1651. mappoint
  1652. /* tmat is test matrix to rotate about x. In our tests we
  1653. have to construct the resulting numbers on the fly
  1654. because when input, they aren't the same for EQUAL. */
  1655. global '(tmat);
  1656. nil
  1657. tmat := rotatex4x4(45.0 / 57.29577);
  1658. [[1.0 0.0 0.0 0.0] [0.0 0.707107 -0.707107 0.0] [0.0 0.707107 0.707107 0.0] [0.0
  1659. 0.0 0.0 1.0]]
  1660. if mappoint(0.0, 0.0, 0.0, tmat) = '(0.0 0.0 0.0)
  1661. then "Test 1 4x4 OK"
  1662. else error(0, "Test 1 4x4 failed");
  1663. "Test 1 4x4 OK"
  1664. if mappoint(1.0, 0.0, 0.0, tmat) = '(1.0 0.0 0.0)
  1665. then "Test 2 4x4 OK"
  1666. else error(0, "Test 2 4x4 failed");
  1667. "Test 2 4x4 OK"
  1668. if mappoint(0.0, 1.0, 0.0, tmat) =
  1669. {0.0, cos(45.0 / 57.29577), - sin(45.0 / 57.29577)}
  1670. then "Test 3 4x4 OK"
  1671. else error(0, "Test 3 4x4 failed");
  1672. "Test 3 4x4 OK"
  1673. if mappoint(1.0, 1.0, 0.0, tmat) =
  1674. {1.0, cos(45.0 / 57.29577), - sin(45.0 / 57.29577)}
  1675. then "Test 4 4x4 OK"
  1676. else error(0, "Test 4 4x4 failed");
  1677. "Test 4 4x4 OK"
  1678. if mappoint(0.0, 0.0, 1.0, tmat) =
  1679. {0.0, sin(45.0 / 57.29577), cos(45.0 / 57.29577)}
  1680. then "Test 5 4x4 OK"
  1681. else error(0, "Test 5 4x4 failed");
  1682. "Test 5 4x4 OK"
  1683. if mappoint(1.0, 0.0, 1.0, tmat) =
  1684. {1.0, sin(45.0 / 57.29577), cos(45.0 / 57.29577)}
  1685. then "Test 6 4x4 OK"
  1686. else error(0, "Test 6 4x4 failed");
  1687. "Test 6 4x4 OK"
  1688. if mappoint(0.0, 1.0, 1.0, tmat) =
  1689. {0.0, cos(45.0 / 57.29577) + sin(45.0 / 57.29577),
  1690. cos(45.0 / 57.29577) - sin(45.0 / 57.29577)}
  1691. then "Test 7 4x4 OK"
  1692. else error(0, "Test 7 4x4 failed");
  1693. "Test 7 4x4 OK"
  1694. if mappoint(1.0, 1.0, 1.0, tmat) =
  1695. {1.0, cos(45.0 / 57.29577) + sin(45.0 / 57.29577),
  1696. cos(45.0 / 57.29577) - sin(45.0 / 57.29577)}
  1697. then "Test 8 4x4 OK"
  1698. else error(0, "Test 8 4x4 failed");
  1699. "Test 8 4x4 OK"
  1700. /* Now try the multiplication routine. */
  1701. tmat := mpy4x4(rotatex4x4(45.0 / 57.29577),
  1702. translate4x4(1.0, 2.0, 3.0));
  1703. [[1.0 0.0 0.0 0.0] [0.0 0.707107 -0.707107 0.0] [0.0 0.707107 0.707107 0.0] [1.0
  1704. 2.0 3.0 1.0]]
  1705. if mappoint(0.0, 0.0, 0.0, tmat) = '(1.0 2.0 3.0)
  1706. then "Test 9 4x4 OK"
  1707. else error(0, "Test 9 4x4 failed");
  1708. "Test 9 4x4 OK"
  1709. if mappoint(0.0, 0.0, 1.0, tmat) =
  1710. {1.0, 2.0 + sin(45.0 / 57.29577),
  1711. 3.0 + cos(45.0 / 57.29577)}
  1712. then "Test 10 4x4 OK"
  1713. else error(0, "Test 10 4x4 failed");
  1714. "Test 10 4x4 OK"
  1715. %------------------------- Exercise 4 -------------------------
  1716. expr procedure ltident n;
  1717. /* LTIDENT(N) -- Create and return a lower triangular,
  1718. square, identity matrix with N+1 rows. */
  1719. for i:=0:n
  1720. with a
  1721. initially a := mkvect n
  1722. do << a[i] := mkvect i;
  1723. for j:=0:i - 1 do a[i,j] := 0.0;
  1724. a[i,i] := 1.0 >>
  1725. returns a;
  1726. ltident
  1727. expr procedure ltmpy(a, b);
  1728. /* LTMPY(A, B) -- Compute the product of two square,
  1729. lower triangular matrices of the same size and return.
  1730. Note that the product is also lower triangular. */
  1731. (for i:=0:rows
  1732. with c
  1733. initially c := mkvect rows
  1734. do << c[i] := mkvect i;
  1735. for j:=0:i do
  1736. c[i,j] := for k:=j:i sum a[i,k] * b[k,j] >>
  1737. returns c)
  1738. where rows := upbv a;
  1739. ltmpy
  1740. if ltident 2 = array(array(1.0),
  1741. array(0.0, 1.0),
  1742. array(0.0, 0.0, 1.0))
  1743. then "Test 1 ltident OK"
  1744. else "Test 1 ltident fails";
  1745. "Test 1 ltident OK"
  1746. if ltident 0 = array(array(1.0))
  1747. then "Test 2 ltident OK"
  1748. else "Test 2 ltident fails";
  1749. "Test 2 ltident OK"
  1750. if ltmpy(ltident 2, ltident 2) = ltident 2
  1751. then "Test 3 ltident OK"
  1752. else "Test 3 ltident fails";
  1753. "Test 3 ltident OK"
  1754. if ltmpy(array(array(1.0),
  1755. array(1.0, 2.0),
  1756. array(1.0, 2.0, 3.0)),
  1757. array(array(1.0),
  1758. array(1.0, 2.0),
  1759. array(1.0, 2.0, 3.0))) =
  1760. array(array(1.0),
  1761. array(3.0, 4.0),
  1762. array(6.0, 10.0, 9.0))
  1763. then "Test 4 ltmpy OK"
  1764. else error(0, "Test 4 ltmpy fails");
  1765. "Test 4 ltmpy OK"
  1766. if ltmpy(array(array(1.2),
  1767. array(3.4, 5.0),
  1768. array(1.0,-2.3,-1.3)), ltident 2)
  1769. = array(array(1.2),
  1770. array(3.4, 5.0),
  1771. array(1.0, -2.3, -1.3))
  1772. then "Test 5 ltmpy OK"
  1773. else error(0, "Test 5 ltmpy fails");
  1774. "Test 5 ltmpy OK"
  1775. %------------------------- Exercise #5 -------------------------
  1776. expr procedure coerce(a, b, pth, cmat);
  1777. /* COERCE(A,B,PTH,CMAT) -- return a list of functions
  1778. to coerce type A (an index into CMAT) into type B. PTH
  1779. is NIL to start and CMAT the coercion table arranged
  1780. with "from" type as rows, "to" type as columns. */
  1781. if cmat[a,b] then cmat[a,b] . pth
  1782. else
  1783. for j:=0:upbv cmat[a]
  1784. with cp
  1785. until j neq a and cmat[a,j] and
  1786. not (cmat[a,j] memq pth) and
  1787. not(cmat[j,a] memq pth) and
  1788. (cp := coerce(j, b, cmat[a,j] . pth, cmat))
  1789. returns cp;
  1790. coerce
  1791. /* Create the coercion array. Here int=0, string=1,
  1792. float=2, complex=3, and gaussian=4 */
  1793. global '(cpath);
  1794. nil
  1795. cpath :=
  1796. array(array('ident, 'int2str, 'float, nil, nil),
  1797. array('str2int, 'ident, 'str2flt, nil, nil),
  1798. array('fix, 'flt2str, 'ident, 'flt2cplx,nil),
  1799. array(nil, nil, nil, 'ident, 'cfix),
  1800. array(nil, nil, nil, 'cfloat, 'ident));
  1801. [[ident int2str float nil nil] [str2int ident str2flt nil nil] [fix flt2str
  1802. ident flt2cplx nil] [nil nil nil ident cfix] [nil nil nil cfloat ident]]
  1803. % Coerce int to complex.
  1804. if coerce(0, 3, nil, cpath) = '(FLT2CPLX STR2FLT INT2STR)
  1805. then "Test 1 coerce OK"
  1806. else error(0, "Test 1 coerce fails");
  1807. "Test 1 coerce OK"
  1808. % Coerce Complex into int.
  1809. if coerce(3, 0, nil, cpath) = NIL
  1810. then "Test 2 coerce OK"
  1811. else error(0, "Test 2 coerce fails");
  1812. "Test 2 coerce OK"
  1813. % Coerce int into gaussian.
  1814. if coerce(0, 4, nil, cpath) =
  1815. '(CFIX FLT2CPLX STR2FLT INT2STR)
  1816. then "Test 3 coerce OK"
  1817. else error(0, "Test 3 coerce fails");
  1818. "Test 3 coerce OK"
  1819. %------------------------- Exercise #6 -------------------------
  1820. expr procedure cellvon(a, b, fn);
  1821. /* CELLVON(A, B, FN) -- Compute the next generation of the
  1822. cellular matrix A and place it into B. Use the VonNeumann
  1823. neighborhood and the function FN to compute the next
  1824. generation. The space edges are wrapped into a torus*/
  1825. for r:=0:rows
  1826. with rows, cols
  1827. initially << rows := upbv a; cols := upbv a[1] >>
  1828. do for c:=0:cols
  1829. do b[r,c] := apply(fn,
  1830. {a[r,c],
  1831. a[torus(r + 1, rows), torus(c - 1, cols)],
  1832. a[torus(r + 1, rows), c],
  1833. a[torus(r + 1, rows), torus(c + 1, cols)],
  1834. a[r, torus(c + 1, cols)],
  1835. a[torus(r - 1, rows), torus(c + 1, cols)],
  1836. a[torus(r - 1, rows), c],
  1837. a[torus(r - 1, rows), torus(c - 1, cols)],
  1838. a[r, torus(c - 1, cols)]});
  1839. cellvon
  1840. expr procedure torus(i, v);
  1841. /* TORUS(I, V) -- A positive modulus: if I is less than
  1842. 0, wrap to V, or if it exceeds V, wrap to I. */
  1843. if i < 0 then v
  1844. else if i > v then 0
  1845. else i;
  1846. torus
  1847. expr procedure life(c, n1, n2, n3, n4, n5, n6, n7, n8);
  1848. /* LIFE(C, N1 ... N8) -- Game of life rules. Here C is
  1849. the cell being examined and N1-N8 are the VonNeumann
  1850. neighbor states. */
  1851. (if c = 1 then if cnt = 2 or cnt = 3 then 1 else 0
  1852. else if cnt = 3 then 1 else 0)
  1853. where cnt = n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8;
  1854. life
  1855. /* LIFESTATES contains a vector of states and what
  1856. character to print. */
  1857. global '(LIFESTATES);
  1858. nil
  1859. LIFESTATES := array(" ", "*");
  1860. [" " "*"]
  1861. expr procedure pcell(gen, a, pr);
  1862. /* PCELL(GEN, A) -- Display the state of the GEN generation
  1863. of the cellular matrix A. Display a * for state=1, and
  1864. a blank for state 0. */
  1865. for r:=0:rows
  1866. with rows, cols
  1867. initially << rows := upbv a; cols := upbv a[1];
  1868. terpri(); prin2 "Generation: "; print gen >>
  1869. do << terpri();
  1870. for c:=0:cols do prin2 pr[a[r,c]] >>;
  1871. pcell
  1872. expr procedure rungame(a, n, fn, pr);
  1873. /* RUNGAME(A, N, FN, PR) -- Run through N generations
  1874. starting with the cellular matrix A and using the
  1875. function FNto compute the new generation. Use the array
  1876. PR to display the state. */
  1877. for i:=1:n
  1878. with tmp, b
  1879. initially b := mkarray(upbv a, upbv a[1])
  1880. do << pcell(i, a, pr);
  1881. cellvon(a, b, function life);
  1882. tmp := a; a := b; b := tmp >>;
  1883. *** local variable fn in procedure rungame not used
  1884. rungame
  1885. /* SEED is the seed array with 1's for on state, 0 for
  1886. off. */
  1887. global '(seed);
  1888. nil
  1889. seed := array(
  1890. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1891. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1892. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1893. array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
  1894. array(0, 0, 0, 0, 0, 0, 1, 0, 0, 0),
  1895. array(0, 0, 0, 0, 1, 1, 1, 0, 0, 0),
  1896. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1897. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1898. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  1899. array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  1900. [[0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1
  1901. 0 0 0 0] [0 0 0 0 0 0 1 0 0 0] [0 0 0 0 1 1 1 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0
  1902. 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0]]
  1903. rungame(seed, 10, function life, LIFESTATES);
  1904. Generation: 1
  1905. *
  1906. *
  1907. ***
  1908. Generation: 2
  1909. * *
  1910. **
  1911. *
  1912. Generation: 3
  1913. *
  1914. * *
  1915. **
  1916. Generation: 4
  1917. *
  1918. **
  1919. **
  1920. Generation: 5
  1921. *
  1922. *
  1923. ***
  1924. Generation: 6
  1925. * *
  1926. **
  1927. *
  1928. Generation: 7
  1929. *
  1930. * *
  1931. **
  1932. Generation: 8
  1933. *
  1934. **
  1935. **
  1936. Generation: 9
  1937. *
  1938. *
  1939. ***
  1940. Generation: 10
  1941. * *
  1942. **
  1943. *
  1944. nil
  1945. %------------------------- Exercise #7 -------------------------
  1946. expr procedure compact heep;
  1947. /* compact(HEEP) -- HEEP is an array of blocks of
  1948. sequentially allocated items. The first entry in each
  1949. block is INUSE, the second the total number of entries
  1950. + 2 (for the header). The remainder are random values.
  1951. Free blocks are the same but instead have the header
  1952. FREE. Returns a compacted structure with a single FREE
  1953. entry at the end with entries changed to *. Returns the
  1954. number of free entries. */
  1955. begin scalar dest, src, last, u;
  1956. last := dest := src := 0;
  1957. loop: if src > upbv heep then
  1958. if src = dest then return 0
  1959. else << heep[dest] := 'FREE;
  1960. heep[dest+1] := src - dest;
  1961. for i:=dest+2:upbv heep do heep[i] := '!*;
  1962. return heep[dest+1] >>;
  1963. if heep[src] eq 'FREE then
  1964. src := heep[src+1] + src
  1965. else << u := heep[src+1] + src - 1;
  1966. for i:=src:u do << heep[dest] := heep[i];
  1967. dest := dest + 1 >>;
  1968. src := u + 1 >>;
  1969. go to loop
  1970. end;
  1971. compact
  1972. /* A simple array to test. */
  1973. global '(H);
  1974. nil
  1975. H := array('INUSE, 3, 0,
  1976. 'FREE, 4, '!*, '!*,
  1977. 'INUSE, 4, 0, 1,
  1978. 'FREE, 3, '!*,
  1979. 'FREE, 5, '!*, '!*, '!*,
  1980. 'INUSE, 5, 0, 1, 2,
  1981. 'INUSE, 5, 3, 4, 5);
  1982. [inuse 3 0 free 4 !* !* inuse 4 0 1 free 3 !* free 5 !* !* !* inuse 5 0 1 2
  1983. inuse 5 3 4 5]
  1984. if compact H = 12
  1985. then "Test 1 compact OK!"
  1986. else error(0, "Test 1 compact fails!");
  1987. "Test 1 compact OK!"
  1988. if H = array('INUSE, 3, 0, 'INUSE, 4, 0, 1, 'INUSE,
  1989. 5, 0, 1, 2, 'INUSE, 5, 3, 4, 5,
  1990. 'FREE, 12, '!*, '!*, '!*, '!*, '!*, '!*,
  1991. '!*, '!*, '!*, '!*)
  1992. then "Test 2 compact OK!"
  1993. else error(0, "Test 2 compact fails!");
  1994. "Test 2 compact OK!"
  1995. /* Test a completely full one. */
  1996. H := array('INUSE, 3, 0, 'INUSE, 5, 1, 2, 3);
  1997. [inuse 3 0 inuse 5 1 2 3]
  1998. if compact H = 0
  1999. then "Test 3 compact OK!"
  2000. else error(0, "Test 3 compact fails!");
  2001. "Test 3 compact OK!"
  2002. if H = array('INUSE, 3, 0, 'INUSE, 5, 1, 2, 3)
  2003. then "Test 4 compact OK!"
  2004. else error(0, "Test 4 compact fails!");
  2005. "Test 4 compact OK!"
  2006. /* Test a completely empty one. */
  2007. H := array('FREE, 3, '!*, 'FREE, 5, '!*, '!*, '!*);
  2008. [free 3 !* free 5 !* !* !*]
  2009. if compact H = 8
  2010. then "Test 5 compact OK!"
  2011. else error(0, "Test 5 compact fails!");
  2012. "Test 5 compact OK!"
  2013. if H = array('FREE, 8, '!*, '!*, '!*, '!*, '!*, '!*)
  2014. then "Test 6 compact OK!"
  2015. else error(0, "Test 6 compact fails!");
  2016. "Test 6 compact OK!"
  2017. %------------------------- Exercise #8 -------------------------
  2018. expr procedure HISTOGRAM(v, n);
  2019. /* HISTOGRAM(V,N) -- V is an arbitrarily size vector of
  2020. numbers. Compute its an N element histogram over its
  2021. range and return it. */
  2022. begin scalar minv, maxv, h, range;
  2023. minv := maxv := v[0];
  2024. for i:=1:upbv v
  2025. do << if v[i] < minv then minv := v[i];
  2026. if v[i] > maxv then maxv := v[i] >>;
  2027. range := maxv - minv;
  2028. h := mkvect(n - 1);
  2029. for i:=0:n - 1 do h[i] := 0;
  2030. for i:=0:upbv v
  2031. with hn
  2032. do << hn := fix(n * (v[i] - minv) / range);
  2033. if hn = n then hn := hn - 1;
  2034. h[hn] := h[hn] + 1 >>;
  2035. return h
  2036. end;
  2037. histogram
  2038. global '(v1);
  2039. nil
  2040. << v1 := mkvect 100;
  2041. for i:=0:100 do v1[i] := float i >>;
  2042. nil
  2043. if HISTOGRAM(v1, 1) = array(101)
  2044. then "Test 1 HISTOGRAM OK!"
  2045. else error(0, "Test 1 HISTOGRAM Fails!");
  2046. "Test 1 HISTOGRAM OK!"
  2047. if HISTOGRAM(v1, 2) = array(50, 51)
  2048. then "Test 2 HISTOGRAM OK!"
  2049. else error(0, "Test 2 HISTOGRAM Fails!");
  2050. "Test 2 HISTOGRAM OK!"
  2051. if HISTOGRAM(v1, 7) = array(15, 14, 14, 15, 14, 14, 15)
  2052. then "Test 3 HISTOGRAM OK!"
  2053. else error(0, "Test 3 HISTOGRAM Fails!");
  2054. "Test 3 HISTOGRAM OK!"
  2055. %------------------------- Exercise #9 -------------------------
  2056. expr procedure rarray n;
  2057. /* RARRAY(N) - generate an NxN matrix with uniform
  2058. distribution random numbers in the range 0.0 -> 1.0. */
  2059. for x:=0:n
  2060. with a
  2061. initially a := mkarray(n,n)
  2062. returns a
  2063. do for y:=0:n do a[x,y] := random(1000) / 1000.0;
  2064. rarray
  2065. if upbv rarray 4 = 4
  2066. then "Test 1 rarray OK"
  2067. else error(0, "Test 1 rarray fails");
  2068. "Test 1 rarray OK"
  2069. expr procedure addcircle(a, r, xc, yc, v);
  2070. /* ADDCIRCLE(A, R, XC, YC, V) -- Add V to each cell within
  2071. distance R from center point XC, YC and return a new
  2072. matrix with these values. Values always remain in the
  2073. range 0.0 -> 1.0. */
  2074. begin scalar uax, uay, b;
  2075. b := mkarray(uax := upbv a, uay := upbv a[0]);
  2076. for x:=0:uax do
  2077. for y:=0:uay do
  2078. b[x,y] := if sqrt((x - xc)^2 + (y - yc)^2) <= r
  2079. then min(1.0, v + a[x,y]) else a[x,y];
  2080. return b
  2081. end;
  2082. addcircle
  2083. global '(xxx);
  2084. *** fluid `xxx' cannot become global
  2085. nil
  2086. xxx := array(array(0, 0, 0, 0, 0),
  2087. array(0, 0, 0, 0, 0),
  2088. array(0, 0, 0, 0, 0),
  2089. array(0, 0, 0, 0, 0),
  2090. array(0, 0, 0, 0, 0));
  2091. [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
  2092. % This will fail if sqrt isn't very accurate.
  2093. if addcircle(xxx, 2.0, 2, 2, 0.75) =
  2094. array(array(0, 0, 0.75, 0, 0),
  2095. array(0, 0.75, 0.75, 0.75, 0),
  2096. array(0.75, 0.75, 0.75, 0.75, 0.75),
  2097. array(0, 0.75, 0.75, 0.75, 0),
  2098. array(0, 0, 0.75, 0, 0))
  2099. then "Test 1 addcircle OK!"
  2100. else error(0, "Test 1 addcircle fails!");
  2101. "Test 1 addcircle OK!"
  2102. if addcircle(xxx, 10.0, 2, 2, 0.75) =
  2103. array(array(0.75, 0.75, 0.75, 0.75, 0.75),
  2104. array(0.75, 0.75, 0.75, 0.75, 0.75),
  2105. array(0.75, 0.75, 0.75, 0.75, 0.75),
  2106. array(0.75, 0.75, 0.75, 0.75, 0.75),
  2107. array(0.75, 0.75, 0.75, 0.75, 0.75))
  2108. then "Test 2 addcircle OK!"
  2109. else error(0, "Test 2 addcircle fails!");
  2110. "Test 2 addcircle OK!"
  2111. %------------------------- Exercise #10 -------------------------
  2112. expr procedure areaaverage(a, n);
  2113. /* AREAAVERAGE(A, N) -- Compute the average of the NxN
  2114. neighborhood of each cell in the matrix A and return a
  2115. new matrix with these values. */
  2116. begin scalar uax, uay, sm, cnt, b, n2;
  2117. n2 := n / 2;
  2118. b := mkarray(uax := upbv a, uay := upbv a[1]);
  2119. for x := 0:uax do
  2120. for y := 0:uay do
  2121. << sm := 0.0;
  2122. cnt := 0;
  2123. for xp := max(0, x - n2):min(uax, x + n2) do
  2124. for yp := max(0, y - n2):min(uay, y + n2) do
  2125. << sm := sm + a[xp,yp];
  2126. cnt := cnt + 1 >>;
  2127. b[x,y] := sm / cnt >>;
  2128. return b
  2129. end;
  2130. areaaverage
  2131. global '(ninth);
  2132. nil
  2133. xxx[2,2] := 1.0;
  2134. 1.0
  2135. ninth := 1.0 / 9.0;
  2136. 0.111111
  2137. if areaaverage(xxx, 3) =
  2138. array(array(0.0, 0.0, 0.0, 0.0, 0.0),
  2139. array(0.0, ninth, ninth, ninth, 0.0),
  2140. array(0.0, ninth, ninth, ninth, 0.0),
  2141. array(0.0, ninth, ninth, ninth, 0.0),
  2142. array(0.0, 0.0, 0.0, 0.0, 0.0))
  2143. then "Test 1 areaaverage OK!"
  2144. else error(0, "Test 1 areaaverage Fails!");
  2145. "Test 1 areaaverage OK!"
  2146. %------------------------- Exercise #11 -------------------------
  2147. expr procedure laplace a;
  2148. /* LAPLACE(A) -- Compute the Laplacian on A but assuming
  2149. 0.0 at the borders. Returns a new array the same size
  2150. as A. */
  2151. begin scalar uax, uay, b, sm;
  2152. b := mkarray(uax := upbv a, uay := upbv a[0]);
  2153. for x := 0:uax do
  2154. for y := 0:uay do
  2155. << sm := 0.0;
  2156. for xp := max(0, x - 1):min(uax, x + 1)
  2157. when xp neq x do
  2158. for yp := max(0, y - 1):min(uay, y + 1)
  2159. when yp neq y
  2160. do sm := sm + a[xp,yp];
  2161. b[x,y] := max(0.0, min(5.0 * a[x,y] - sm, 1.0)) >>;
  2162. return b
  2163. end;
  2164. laplace
  2165. xxx := array(array(0,0,0,0,0),
  2166. array(0,1,1,1,0),
  2167. array(0,1,1,1,0),
  2168. array(0,1,1,1,0),
  2169. array(0,0,0,0,0));
  2170. [[0 0 0 0 0] [0 1 1 1 0] [0 1 1 1 0] [0 1 1 1 0] [0 0 0 0 0]]
  2171. if laplace xxx = array(array(0.0, 0.0, 0.0, 0.0, 0.0),
  2172. array(0.0, 1.0, 1.0, 1.0, 0.0),
  2173. array(0.0, 1.0, 1.0, 1.0, 0.0),
  2174. array(0.0, 1.0, 1.0, 1.0, 0.0),
  2175. array(0.0, 0.0, 0.0, 0.0, 0.0))
  2176. then "Test 1 laplace OK!"
  2177. else error(0, "Test 1 laplace fails!");
  2178. "Test 1 laplace OK!"
  2179. %------------------------- Exercise #12 -------------------------
  2180. expr procedure threshold(a, vl, vh);
  2181. /* THRESHOLD(A, VL, VH) -- Returns a new matrix of the same
  2182. size as A with each cell set to 1.0 that is
  2183. VL <= A(i,j) <= VH. Others are set to 0.0. */
  2184. for x := 0:uax
  2185. with uax, uay, b
  2186. initially b := mkarray(uax := upbv a,
  2187. uay := upbv a[0])
  2188. returns b
  2189. do for y := 0:uay
  2190. do b[x,y] :=
  2191. if a[x,y] >= vl and a[x,y] <= vh then 1.0
  2192. else 0.0;
  2193. threshold
  2194. xxx := mkarray(4,4);
  2195. [[nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil
  2196. nil nil] [nil nil nil nil nil]]
  2197. for i:=0:4 do for j:=0:4 do xxx[i,j] := i * j;
  2198. nil
  2199. if threshold(xxx, 8, 10) = array(
  2200. array(0.0, 0.0, 0.0, 0.0, 0.0),
  2201. array(0.0, 0.0, 0.0, 0.0, 0.0),
  2202. array(0.0, 0.0, 0.0, 0.0, 1.0),
  2203. array(0.0, 0.0, 0.0, 1.0, 0.0),
  2204. array(0.0, 0.0, 1.0, 0.0, 0.0))
  2205. then "Test 1 threshold OK!"
  2206. else error(0, "Test 1 threshold Fails!");
  2207. "Test 1 threshold OK!"
  2208. expr procedure dump(a, f);
  2209. /* DUMP(A,F) -- Dump an array A into a PicTex format
  2210. file for document processing. */
  2211. begin scalar fh;
  2212. fh := wrs open(f, 'output);
  2213. for x:=0:upbv a do
  2214. for y:=0:upbv a[0] do
  2215. printf("\setshadegrid span <%wpt>%n\vshade %d %d %d %d %d %d /%n",
  2216. max(0.5, 5.5 - a[x,y]*5.0),
  2217. x, y, y+1, x+1, y, y+1);
  2218. close wrs fh;
  2219. end;
  2220. dump
  2221. % ##### Macro Exercises #####
  2222. %------------------------- Exercise -----------------------
  2223. macro procedure appendl x;
  2224. /* APPENDL( ...) - append all the lists together. */
  2225. expand(cdr x, 'append);
  2226. appendl
  2227. if appendl('(a b), '(c d), '(e f)) = '(a b c d e f)
  2228. then "Test 1 appendl OK!"
  2229. else error(0, "Test 1 appendl fails!");
  2230. "Test 1 appendl OK!"
  2231. if appendl '(a b c) = '(a b c)
  2232. then "Test 2 appendl OK!"
  2233. else error(0, "Test 2 appendl fails!");
  2234. "Test 2 appendl OK!"
  2235. if appendl nil = nil
  2236. then "Test 3 appendl OK!"
  2237. else error(0, "Test 3 appendl fails!");
  2238. "Test 3 appendl OK!"
  2239. %------------------------- Exercise ------------------------
  2240. macro procedure nconcl x;
  2241. /* NCONCL(...) - destructive concatenation of all the
  2242. lists. */
  2243. expand(cdr x, 'nconc);
  2244. nconcl
  2245. global '(b1 b2 b3);
  2246. nil
  2247. b1 := '(a b);
  2248. (a b)
  2249. b2 := '(c d);
  2250. (c d)
  2251. b3 := '(e f);
  2252. (e f)
  2253. if nconcl(b1, b2, b3) = '(a b c d e f)
  2254. then "Test 1 nconcl OK!"
  2255. else error(0, "Test 1 nconcl fails!");
  2256. "Test 1 nconcl OK!"
  2257. if b1 = '(a b c d e f)
  2258. then "Test 2 nconcl OK!"
  2259. else error(0, "Test 2 nconcl fails!");
  2260. "Test 2 nconcl OK!"
  2261. if b2 = '(c d e f)
  2262. then "Test 3 nconcl OK!"
  2263. else error(0, "Test 3 nconcl fails!");
  2264. "Test 3 nconcl OK!"
  2265. if b3 = '(e f)
  2266. then "Test 4 nconcl OK!"
  2267. else error(0, "Test 4 nconcl fails!");
  2268. "Test 4 nconcl OK!"
  2269. %------------------------- Exercise ------------------------
  2270. smacro procedure d(x1, y1, x2, y2);
  2271. /* D(X1, Y1, X2, Y2) - Euclidean distance between points
  2272. (X1,Y1) -> (X2,Y2) */
  2273. sqrt((x1 - x2)^2 + (y1 - y2)^2);
  2274. d
  2275. % This fails with poor sqrt.
  2276. if d(0, 0, 3, 4) = 5.0
  2277. then "Test 1 d OK!"
  2278. else error(0, "Test 1 d Fails!");
  2279. "Test 1 d OK!"
  2280. if d(0, 0, 1, 1) = sqrt 2
  2281. then "Test 2 d OK!"
  2282. else error(0, "Test 2 d Fails!");
  2283. "Test 2 d OK!"
  2284. %------------------------- Exercise -------------------------
  2285. macro procedure pop x;
  2286. /* POP(X) - Assuming X is an identifier, pop the stack
  2287. and return the popped value. */
  2288. (`(prog (!$V!$)
  2289. (setq !$V!$ (car #v))
  2290. (setq #v (cdr #v))
  2291. (return !$V!$))) where v := cadr x;
  2292. pop
  2293. xxx := '(A B);
  2294. (a b)
  2295. if pop xxx eq 'A
  2296. then "Test 1 POP ok!"
  2297. else error(0, "Test 1 POP fails!");
  2298. "Test 1 POP ok!"
  2299. if xxx = '(B)
  2300. then "Test 1 POP ok!"
  2301. else error(0, "Test 1 POP fails!");
  2302. "Test 1 POP ok!"
  2303. if pop xxx eq 'B
  2304. then "Test 2 POP ok!"
  2305. else error(0, "Test 2 POP fails!");
  2306. "Test 2 POP ok!"
  2307. if xxx eq NIL
  2308. then "Test 2 POP ok!"
  2309. else error(0, "Test 2 POP fails!");
  2310. "Test 2 POP ok!"
  2311. %------------------------- Exercise -------------------------
  2312. macro procedure push x;
  2313. /* PUSH(ST, V) - push V onto ST (an identifier) and
  2314. return V. */
  2315. `(progn (setq #st (cons #v #st))
  2316. #v)
  2317. where st := cadr x,
  2318. v := caddr x;
  2319. push
  2320. if push(xxx, 'A) = 'A
  2321. then "Test 1 push OK!"
  2322. else error(0, "Test 1 push fails");
  2323. "Test 1 push OK!"
  2324. if xxx = '(A)
  2325. then "Test 1 push OK!"
  2326. else error(0, "Test 1 push fails");
  2327. "Test 1 push OK!"
  2328. if push(xxx, 'B) = 'B
  2329. then "Test 2 push OK!"
  2330. else error(0, "Test 2 push fails");
  2331. "Test 2 push OK!"
  2332. if xxx = '(B A)
  2333. then "Test 2 push OK!"
  2334. else error(0, "Test 2 push fails");
  2335. "Test 2 push OK!"
  2336. %------------------------- Exercise -------------------------
  2337. macro procedure format x;
  2338. /* FORMAT("str", ...) - A formatted print utility. It
  2339. looks for %x things in str, printing everything else.
  2340. A property of printf!-format will cause a call on
  2341. the named function with the corresponding argument.
  2342. This should return a print form to use. A property
  2343. printf!-expand calls a function without an argument.
  2344. Common controls are:
  2345. %n new line
  2346. %p prin2 call.
  2347. %w prin1 call.
  2348. */
  2349. begin scalar str, localstr, m;
  2350. str := explode2 cadr x;
  2351. x := cddr x;
  2352. loop: if null str then
  2353. << if localstr then
  2354. m := {'prin2, makestring reversip localstr} . m;
  2355. return 'progn . reverse m >>;
  2356. if eqcar(str, '!%) then
  2357. if cdr str then
  2358. if fn := get(cadr str, 'printf!-format) then
  2359. << if localstr then
  2360. << m := {'prin2, makestring reversip localstr} . m;
  2361. localstr := nil >>;
  2362. m := apply(fn, {car x}) . m;
  2363. x := cdr x;
  2364. str := cddr str;
  2365. go to loop >>
  2366. else if fn := get(cadr str, 'printf!-expand) then
  2367. << if localstr then
  2368. << m := {'prin2, makestring reverse localstr} . m;
  2369. localstr := nil >>;
  2370. m := apply(fn, nil) . m;
  2371. str := cddr str;
  2372. go to loop >>;
  2373. localstr := car str . localstr;
  2374. str := cdr str;
  2375. go to loop
  2376. end;
  2377. format
  2378. expr procedure makestring l;
  2379. /* MAKESTRING(L) - convert the list of character L into
  2380. a string. */
  2381. compress('!" . append(l, '(!")));
  2382. makestring
  2383. expr procedure printf!-terpri;
  2384. /* PRINTF!-TERPRI() - Generates a TERPRI call for %n */
  2385. '(terpri);
  2386. printf!-terpri
  2387. put('!n, 'printf!-expand, 'printf!-terpri);
  2388. printf!-terpri
  2389. put('!N, 'printf!-expand, 'printf!-terpri);
  2390. printf!-terpri
  2391. expr procedure printf!-prin1 x;
  2392. /* PRINTF!-PRIN1(X) - Generates a PRIN1 call for %w */
  2393. {'prin1, x};
  2394. printf!-prin1
  2395. put('!w, 'printf!-format, 'printf!-prin1);
  2396. printf!-prin1
  2397. put('!W, 'printf!-format, 'printf!-prin1);
  2398. printf!-prin1
  2399. expr procedure printf!-prin2 x;
  2400. /* PRINTF!-PRIN2(X) - Generates a PRIN2 call for %p */
  2401. {'prin2, x};
  2402. printf!-prin2
  2403. put('!p, 'printf!-format, 'printf!-prin2);
  2404. printf!-prin2
  2405. put('!P, 'printf!-format, 'printf!-prin2);
  2406. printf!-prin2
  2407. %------------------------- Exercise -------------------------
  2408. macro procedure rmsg x;
  2409. /* RMSG("str", ...) - A formatted string utility. It
  2410. looks for %x things in str, copying everything else.
  2411. A property of rmsg!-format will cause a call on
  2412. the named function with the corresponding argument.
  2413. This should return a explode form to use. A property
  2414. rmsg!-expand calls a function without an argument.
  2415. Common controls are:
  2416. %n new line
  2417. %p explode2 call.
  2418. %w explode call.
  2419. */
  2420. begin scalar str, localstr, m;
  2421. str := explode2 cadr x;
  2422. x := cddr x;
  2423. loop: if null str then
  2424. << if localstr then
  2425. m := mkquote reversip localstr . m;
  2426. return `(makestring (nconcl #@(reversip m))) >>;
  2427. if eqcar(str, '!%) then
  2428. if cdr str then
  2429. if fn := get(cadr str, 'rmsg!-format) then
  2430. << if localstr then
  2431. << m := mkquote reversip localstr . m;
  2432. localstr := nil >>;
  2433. m := apply(fn, {car x}) . m;
  2434. x := cdr x;
  2435. str := cddr str;
  2436. go to loop >>
  2437. else if fn := get(cadr str, 'rmsg!-expand) then
  2438. << if localstr then
  2439. << m := mkquote reversip localstr . m;
  2440. localstr := nil >>;
  2441. m := apply(fn, nil) . m;
  2442. str := cddr str;
  2443. go to loop >>;
  2444. localstr := car str . localstr;
  2445. str := cdr str;
  2446. go to loop
  2447. end;
  2448. rmsg
  2449. expr procedure makestring l;
  2450. /* MAKESTRING(L) - convert the list of character L into
  2451. a string. */
  2452. compress('!" . append(l, '(!")));
  2453. *** Function `makestring' has been redefined
  2454. makestring
  2455. expr procedure rmsg!-terpri;
  2456. /* RMSG!-TERPRI() - Generates an EOL. */
  2457. mkquote {!$eol!$};
  2458. rmsg!-terpri
  2459. put('!n, 'rmsg!-expand, 'rmsg!-terpri);
  2460. rmsg!-terpri
  2461. put('!N, 'rmsg!-expand, 'rmsg!-terpri);
  2462. rmsg!-terpri
  2463. expr procedure rmsg!-prin1 x;
  2464. /* RMSG!-PRIN1(X) - Generates an EXPLODE call */
  2465. `(fixstr (explode #x));
  2466. rmsg!-prin1
  2467. put('!w, 'rmsg!-format, 'rmsg!-prin1);
  2468. rmsg!-prin1
  2469. put('!W, 'rmsg!-format, 'rmsg!-prin1);
  2470. rmsg!-prin1
  2471. expr procedure rmsg!-prin2 x;
  2472. /* RMSG!-PRIN2(X) - Generates an EXPLODE2 call for x. */
  2473. `(explode2 #x);
  2474. rmsg!-prin2
  2475. put('!p, 'rmsg!-format, 'rmsg!-prin2);
  2476. rmsg!-prin2
  2477. put('!P, 'rmsg!-format, 'rmsg!-prin2);
  2478. rmsg!-prin2
  2479. expr procedure fixstr x;
  2480. /* FIXSTR(X) - Double up "'s in x. */
  2481. if null x then nil
  2482. else if eqcar(x, '!") then '!" . '!" . fixstr cdr x
  2483. else car x . fixstr cdr x;
  2484. fixstr
  2485. if rmsg "abc" = "abc"
  2486. then "Test 1 rmsg OK!"
  2487. else error(0, "Test 1 rmsg fails!");
  2488. "Test 1 rmsg OK!"
  2489. if rmsg("Test %w test", 12) = "Test 12 test"
  2490. then "Test 2 rmsg OK!"
  2491. else error(0, "Test 2 rmsg fails!");
  2492. "Test 2 rmsg OK!"
  2493. if rmsg("Test %w string", "foo") = "Test ""foo"" string"
  2494. then "Test 3 rmsg OK!"
  2495. else error(0, "Test 3 rmsg fails!");
  2496. "Test 3 rmsg OK!"
  2497. if rmsg("Test %w now %p", "foo", "foo") = "Test ""foo"" now foo"
  2498. then "Test 4 rmsg OK!"
  2499. else error(0, "Test 4 rmsg fails!");
  2500. "Test 4 rmsg OK!"
  2501. %------------------------- Exercise -------------------------
  2502. define CFLAG = T;
  2503. nil
  2504. macro procedure ifcflag x;
  2505. /* IFCLFAG(X) - generate the code for X if CFLAG is non-NIL,
  2506. otherwise generate NIL (this can't be used everywhere). */
  2507. if CFLAG then cadr x else nil;
  2508. ifcflag
  2509. ifCFLAG expr procedure pslfoo x; car x;
  2510. pslfoo
  2511. if getd 'pslfoo
  2512. then "Test 1 ifCFLAG OK!"
  2513. else error(0, "Test 1 ifCFLAG fails!");
  2514. "Test 1 ifCFLAG OK!"
  2515. % ##### Interactive Exercises #####
  2516. %------------------------- Exercise #2 -------------------------
  2517. /* Lists functions that have been embedded with count code. */
  2518. global '(EMBEDDED!*);
  2519. nil
  2520. EMBEDDED!* := NIL;
  2521. nil
  2522. expr procedure embed f;
  2523. /* EMBED(F) - wrap function F with counter code. Error if F is
  2524. not interpreted. Put the information under property COUNT and
  2525. add to the global list EMBEDDED!*. */
  2526. begin scalar def, args, nfn;
  2527. if not(def := getd f) then error(0, {f, "is undefined"});
  2528. if codep cdr def then error(0, {f, "is not interpreted"});
  2529. put(f, 'COUNT, 0);
  2530. if f memq EMBEDDED!* then return NIL;
  2531. EMBEDDED!* := f . EMBEDDED!*;
  2532. putd(nfn := intern gensym(), car def, cdr def);
  2533. putd(f, car def,
  2534. {'lambda, caddr def,
  2535. {'progn,
  2536. {'put, mkquote f, mkquote 'COUNT,
  2537. {'add1, {'get, mkquote f, mkquote 'COUNT}}},
  2538. nfn . caddr def}});
  2539. return f
  2540. end;
  2541. *** local variable args in procedure embed not used
  2542. embed
  2543. expr procedure stats;
  2544. /* STATS() - list all the embedded functions and their
  2545. counts. */
  2546. for each f in EMBEDDED!*
  2547. do << prin1 f; prin2 " "; print get(f, 'COUNT) >>;
  2548. stats
  2549. expr procedure pcnt x;
  2550. /* PCNT(X) - returns the number of dotted-pairs in X (vectors
  2551. can hide dotted-pairs). */
  2552. if atom x then 0
  2553. else 1 + pcnt car x + pcnt cdr x;
  2554. pcnt
  2555. if embed 'pcnt eq 'pcnt
  2556. then "Test 1 embed OK!"
  2557. else error(0, "Test 1 embed Fails!");
  2558. *** Function `pcnt' has been redefined
  2559. "Test 1 embed OK!"
  2560. if get('pcnt, 'count) = 0
  2561. then "Test 2 embed OK!"
  2562. else error(0, "Test 2 embed Fails!");
  2563. "Test 2 embed OK!"
  2564. if pcnt '(a . (b . c)) = 2
  2565. then "Test 3 embed OK!"
  2566. else error(0, "Test 3 embed Fails!");
  2567. "Test 3 embed OK!"
  2568. if get('pcnt, 'COUNT) = 5
  2569. then "Test 4 embed OK!"
  2570. else error(0, "Test 4 embed Fails!");
  2571. "Test 4 embed OK!"
  2572. if EMBEDDED!* = '(PCNT)
  2573. then "Test 5 embed OK!"
  2574. else error(0, "Test 5 embed Fails!");
  2575. "Test 5 embed OK!"
  2576. % Just a visual check.
  2577. stats();
  2578. pcnt 5
  2579. nil
  2580. % ##### Test the inspector module #####
  2581. %
  2582. % We set LINELENGTH to various values to check how good we do on output.
  2583. % Don't let the default screw up the test:
  2584. LINELENGTH 80;
  2585. 80
  2586. % Describe some of the basic data types.
  2587. % Dotted-pairs.
  2588. describe '(a . b);
  2589. A dotted-pair or list
  2590. nil
  2591. % Vectors;
  2592. global '(xvar);
  2593. nil
  2594. xvar := mkvect 3;
  2595. [nil nil nil nil]
  2596. describe xvar;
  2597. A vector with 4 elements
  2598. nil
  2599. % Records.
  2600. record insprec /* A record for testing. */
  2601. with
  2602. field1 := 'a;
  2603. insprec
  2604. xvar := insprec();
  2605. [insprec a]
  2606. describe xvar;
  2607. A insprec record with
  2608. 1: a
  2609. nil
  2610. describe 'insprec;
  2611. insprec is a record constructor with the following fields
  2612. ** not implemented. **
  2613. nil
  2614. % A code pointer (usually).
  2615. describe cdr getd 'car;
  2616. A code-pointer
  2617. nil
  2618. % Numbers.
  2619. describe 1;
  2620. A fixed number
  2621. nil
  2622. describe 3.14159;
  2623. A floating-point number
  2624. nil
  2625. % Strings
  2626. describe "This is a string";
  2627. A string
  2628. nil
  2629. % identifiers of various sourts.
  2630. describe 'car;
  2631. car is an EXPR with one argument
  2632. nil
  2633. describe 'a!-plain!-jane!-identifier;
  2634. Don't know anything about a!-plain!-jane!-identifier
  2635. nil
  2636. describe nil;
  2637. Don't know anything about nil
  2638. nil
  2639. % This message is sort of funny in odd ways.
  2640. % Now let's get serious. Here's a global with no active comment. The
  2641. % remprop is something you shouldn't know about but allows us to run
  2642. % the test file multiple times and get the same results.
  2643. remprop('TheCow, 'NEWNAM);
  2644. nil
  2645. DEFINE TheCow = "How now brown cow";
  2646. nil
  2647. describe 'TheCow;
  2648. thecow is a constant defined as "How now brown cow"
  2649. nil
  2650. off saveactives;
  2651. nil
  2652. /* I never saw a purple cow, I never hope to see one now. */
  2653. global '(PurpleCow);
  2654. nil
  2655. describe 'PurpleCow;
  2656. Identifier 'purplecow' is global
  2657. nil
  2658. on saveactives;
  2659. nil
  2660. /* But I'd rather see one than be one! */
  2661. global '(Pcow);
  2662. nil
  2663. describe 'Pcow;
  2664. Identifier 'pcow' is global defined line 2236 in file
  2665. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2666. But I'd rather see one than be one!
  2667. nil
  2668. % Now we march on to procedures.
  2669. % Here's one with no comment and we don't save it.
  2670. off saveactives;
  2671. nil
  2672. remd 'comtest1;
  2673. nil
  2674. expr procedure comtest1 x;
  2675. print x;
  2676. comtest1
  2677. describe 'comtest1;
  2678. comtest1 is an EXPR with one argument
  2679. nil
  2680. % Here's one with no comment and we do save it.
  2681. on saveactives;
  2682. nil
  2683. remd 'comtest2;
  2684. nil
  2685. expr procedure comtest2(x, y);
  2686. print x;
  2687. *** local variable y in procedure comtest2 not used
  2688. comtest2
  2689. describe 'comtest2;
  2690. comtest2 is an EXPR with 2 arguments
  2691. nil
  2692. % Here's one with a comment but we don't save it.
  2693. off saveactives;
  2694. nil
  2695. remd 'comtest3;
  2696. nil
  2697. expr procedure comtest3(x, y, z);
  2698. /* You should never see this comment. */
  2699. print x;
  2700. *** local variable y in procedure comtest3 not used
  2701. *** local variable z in procedure comtest3 not used
  2702. comtest3
  2703. describe 'comtest3;
  2704. comtest3 is an EXPR with 3 arguments
  2705. nil
  2706. % Here's one with a comment and we should see it.
  2707. on saveactives;
  2708. nil
  2709. remd 'comtest4;
  2710. nil
  2711. expr procedure comtest4(x, y, z, xx);
  2712. /* COMTEST4(X, Y, Z, XX) - A well commented routine. This routine
  2713. does almost nothing, but a good article thereof. */
  2714. print x;
  2715. *** local variable y in procedure comtest4 not used
  2716. *** local variable z in procedure comtest4 not used
  2717. *** local variable xx in procedure comtest4 not used
  2718. comtest4
  2719. describe 'comtest4;
  2720. comtest4 is an EXPR with 4 arguments
  2721. Function ends on line 2265 in file /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2722. COMTEST4(X, Y, Z, XX) - A well commented routine. This routine
  2723. does almost nothing, but a good article thereof.
  2724. nil
  2725. % Now try MACROS.
  2726. remd 'comtest5;
  2727. nil
  2728. macro procedure comtest5 x;
  2729. /* COMTEST5(X) - A macro that doesn't really do much of anything. */
  2730. {'car, cadr x};
  2731. comtest5
  2732. describe 'comtest5;
  2733. comtest5 is a MACRO
  2734. Function ends on line 2272 in file /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2735. COMTEST5(X) - A macro that doesn't really do much of anything.
  2736. nil
  2737. smacro procedure comtest6 x;
  2738. /* COMTEST6(X) - a SMACRO with an active comment. This smacro expands
  2739. to take CAR of its argument. */
  2740. car x;
  2741. comtest6
  2742. describe 'comtest6;
  2743. comtest6 is an SMACRO with one argument
  2744. Function ends on line 2277 in file /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2745. COMTEST6(X) - a SMACRO with an active comment. This smacro expands
  2746. to take CAR of its argument.
  2747. nil
  2748. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2749. % Module testing.
  2750. /* This is a test module which occurs at the top level just to make
  2751. sure that the module type works. */
  2752. module testmodule;
  2753. nil
  2754. endmodule;
  2755. nil
  2756. describe 'testmodule;
  2757. Can't find source or fasl file for module testmodule
  2758. This is a test module which occurs at the top level just to make
  2759. sure that the module type works.
  2760. nil
  2761. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2762. % Format testing. Put a big comment out there and look at it with
  2763. % various line lengths.
  2764. /* ********************
  2765. This is a test comment. We'll try do different things with it in
  2766. different contexts. Does it work?
  2767. expr procedure fact n;
  2768. if n < 2 then 1 else n * fact(n - 1);
  2769. Well hoop de doo! Is there anything else funny?
  2770. +------------+----------+
  2771. | Column 1 | Col. 2 |
  2772. +------------+----------+
  2773. | Aardvarks | 345 |
  2774. +------------+----------+
  2775. | Zarfs | 3 |
  2776. +------------+----------+
  2777. /// */
  2778. global '(testvariable);
  2779. nil
  2780. describe 'testvariable;
  2781. Identifier 'testvariable' is global defined line 2292 in file
  2782. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2783. ********************
  2784. This is a test comment. We'll try do different things with it in
  2785. different contexts. Does it work?
  2786. expr procedure fact n;
  2787. if n < 2 then 1 else n * fact(n - 1);
  2788. Well hoop de doo! Is there anything else funny?
  2789. +------------+----------+
  2790. | Column 1 | Col. 2 |
  2791. +------------+----------+
  2792. | Aardvarks | 345 |
  2793. +------------+----------+
  2794. | Zarfs | 3 |
  2795. +------------+----------+
  2796. ///
  2797. nil
  2798. LINELENGTH 60;
  2799. 80
  2800. describe 'testvariable;
  2801. Identifier 'testvariable' is global defined line 2292
  2802. in file /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2803. ********************
  2804. This is a test comment. We'll try do different things with i
  2805. t in
  2806. different contexts. Does it work?
  2807. expr procedure fact n;
  2808. if n < 2 then 1 else n * fact(n - 1);
  2809. Well hoop de doo! Is there anything else funny?
  2810. +------------+----------+
  2811. | Column 1 | Col. 2 |
  2812. +------------+----------+
  2813. | Aardvarks | 345 |
  2814. +------------+----------+
  2815. | Zarfs | 3 |
  2816. +------------+----------+
  2817. ///
  2818. nil
  2819. LINELENGTH 50;
  2820. 60
  2821. describe 'testvariable;
  2822. Identifier 'testvariable' is global defined line
  2823. 2292 in file
  2824. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2825. ********************
  2826. This is a test comment. We'll try do different thi
  2827. ngs with it in
  2828. different contexts. Does it work?
  2829. expr procedure fact n;
  2830. if n < 2 then 1 else n * fact(n - 1);
  2831. Well hoop de doo! Is there anything else funny?
  2832. +------------+----------+
  2833. | Column 1 | Col. 2 |
  2834. +------------+----------+
  2835. | Aardvarks | 345 |
  2836. +------------+----------+
  2837. | Zarfs | 3 |
  2838. +------------+----------+
  2839. ///
  2840. nil
  2841. LINELENGTH 40;
  2842. 50
  2843. describe 'testvariable;
  2844. Identifier 'testvariable' is global
  2845. defined line 2292 in file
  2846. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2847. ********************
  2848. This is a test comment. We'll try do dif
  2849. ferent things with it in
  2850. different contexts. Does it work?
  2851. expr procedure fact n;
  2852. if n < 2 then 1 else n * fact(n - 1)
  2853. ;
  2854. Well hoop de doo! Is there anything else
  2855. funny?
  2856. +------------+----------+
  2857. | Column 1 | Col. 2 |
  2858. +------------+----------+
  2859. | Aardvarks | 345 |
  2860. +------------+----------+
  2861. | Zarfs | 3 |
  2862. +------------+----------+
  2863. ///
  2864. nil
  2865. LINELENGTH 30;
  2866. 40
  2867. describe 'testvariable;
  2868. Identifier 'testvariable' is
  2869. global defined line 2292
  2870. in file
  2871. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2872. ********************
  2873. This is a test comment. We'll
  2874. try do different things with i
  2875. t in
  2876. different contexts. Does it wo
  2877. rk?
  2878. expr procedure fact n;
  2879. if n < 2 then 1 else n * f
  2880. act(n - 1);
  2881. Well hoop de doo! Is there any
  2882. thing else funny?
  2883. +------------+----------+
  2884. | Column 1 | Col. 2 |
  2885. +------------+----------+
  2886. | Aardvarks | 345 |
  2887. +------------+----------+
  2888. | Zarfs | 3 |
  2889. +------------+----------+
  2890. ///
  2891. nil
  2892. LINELENGTH 20;
  2893. 30
  2894. describe 'testvariable;
  2895. Identifier '
  2896. testvariable' is
  2897. global defined line
  2898. 2292 in file
  2899. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2900. ********************
  2901. This is a test comme
  2902. nt. We'll try do dif
  2903. ferent things with i
  2904. t in
  2905. different contexts.
  2906. Does it work?
  2907. expr procedure fac
  2908. t n;
  2909. if n < 2 then 1
  2910. else n * fact(n - 1)
  2911. ;
  2912. Well hoop de doo! Is
  2913. there anything else
  2914. funny?
  2915. +------------+-----
  2916. -----+
  2917. | Column 1 | Col
  2918. . 2 |
  2919. +------------+-----
  2920. -----+
  2921. | Aardvarks |
  2922. 345 |
  2923. +------------+-----
  2924. -----+
  2925. | Zarfs |
  2926. 3 |
  2927. +------------+-----
  2928. -----+
  2929. ///
  2930. nil
  2931. LINELENGTH 10;
  2932. 20
  2933. describe 'testvariable;
  2934. Identifier '
  2935. testvariable
  2936. ' is
  2937. global
  2938. defined line
  2939. 2292
  2940. in file
  2941. /home/hearn/r37/packages/rlisp88/rlisp88.tst
  2942. **********
  2943. **********
  2944. This is a
  2945. test comme
  2946. nt. We'll
  2947. try do dif
  2948. ferent thi
  2949. ngs with i
  2950. t in
  2951. different
  2952. contexts.
  2953. Does it wo
  2954. rk?
  2955. expr pro
  2956. cedure fac
  2957. t n;
  2958. if n <
  2959. 2 then 1
  2960. else n * f
  2961. act(n - 1)
  2962. ;
  2963. Well hoop
  2964. de doo! Is
  2965. there any
  2966. thing else
  2967. funny?
  2968. +--------
  2969. ----+-----
  2970. -----+
  2971. | Column
  2972. 1 | Col
  2973. . 2 |
  2974. +--------
  2975. ----+-----
  2976. -----+
  2977. | Aardvar
  2978. ks |
  2979. 345 |
  2980. +--------
  2981. ----+-----
  2982. -----+
  2983. | Zarfs
  2984. |
  2985. 3 |
  2986. +--------
  2987. ----+-----
  2988. -----+
  2989. ///
  2990. nil
  2991. % ##### Records Package #####
  2992. global '(rec1 rec2);
  2993. nil
  2994. % Simple test.
  2995. record rtest1;
  2996. rtest1
  2997. rec1 := rtest1();
  2998. [rtest1]
  2999. if rec1 neq array 'rtest1 then
  3000. error(0, "Test 1 RECORD fails creation test!");
  3001. nil
  3002. if null rtest1p rec1 then
  3003. error(0, "Test 1 RECORD fails predicate test!");
  3004. nil
  3005. % A record with two fields.
  3006. record rtest2 with field1 := 0, field2 := 1;
  3007. *** Function `
  3008. field1' has been redefined
  3009. rtest2
  3010. % Test default creation.
  3011. rec2 := rtest2();
  3012. [rtest2 0
  3013. 1]
  3014. if rec2 neq array('rtest2, 0, 1) then
  3015. error(0, "Test 2 RECORD fails to create a record");
  3016. nil
  3017. if null rtest2p rec2 then
  3018. error(0, "Test 2 RECORD fails predicate test");
  3019. nil
  3020. if rtest2p rec1 then
  3021. error(0, "Test 2 RECORD fails to test record differences");
  3022. nil
  3023. % Build a record with a predicate. Remove any old occurrence.
  3024. remd 'rtest3!?;
  3025. nil
  3026. record rtest3 with field1 := 0, field2 := 1 has predicate = rtest3!?;
  3027. *** Function `
  3028. field1' has been redefined
  3029. *** Function `
  3030. field2' has been redefined
  3031. rtest3
  3032. if not getd 'rtest3!? then
  3033. error(0, "Test 3 RECORD fails - no predicate built");
  3034. nil
  3035. if rtest3!? rec2 then
  3036. error(0, "Test 3 RECORD fails - predicate returns T on non RTEST3 record");
  3037. nil
  3038. for each x in {'identifier, 12, 12.3, "a string", cdr getd 'car,
  3039. '(a list), array("an", "array")}
  3040. when rtest3!? x
  3041. do error(0, {"Test 3 RECORD fails - predicate returns T on", x});
  3042. nil
  3043. rec2 := rtest3();
  3044. [rtest3 0
  3045. 1]
  3046. if not rtest3!? rec2 then
  3047. error(0, "Test 3 RECORD fails - predicate returns NIL on record");
  3048. nil
  3049. % Check that the no-predicate option works.
  3050. remd 'rtest4p;
  3051. nil
  3052. % Just to make sure.
  3053. record rtest4 with a := 34, b := 56 has no predicate;
  3054. rtest4
  3055. if getd 'rtest4p then
  3056. error(0, "Test 4 RECORD fails - NO PREDICATE option generates a predicate");
  3057. nil
  3058. % Verify that the CONSTRUCTOR option works.
  3059. remd 'rtest5;
  3060. nil
  3061. remd 'make-rtest5;
  3062. nil
  3063. record rtest5 with r5a := 0, r5b := 1 has constructor;
  3064. rtest5
  3065. if getd 'rtest5 then
  3066. error(0, "Test 5 RECORD fails - CONSTRUCTOR generates simple constructor");
  3067. nil
  3068. if not getd 'make-rtest5 then
  3069. error(0, "Test 5 RECORD fails - CONSTRUCTOR doesn't generate constructor");
  3070. nil
  3071. if not rtest5p make-rtest5() then
  3072. error(0, "Test 5 RECORD fails - CONSTRUCTOR doesn't generate record");
  3073. nil
  3074. % Verify that the named constructor works.
  3075. remd 'rtest6;
  3076. nil
  3077. remd 'please-make-rtest6;
  3078. nil
  3079. record rtest6 with r6a := 0 has constructor = please!-make!-arecord;
  3080. rtest6
  3081. if getd 'rtest6 then
  3082. error(0, "Test 6 RECORD fails - CONSTRUCTOR generates simple constructor");
  3083. nil
  3084. if getd 'make-rtest6 then
  3085. error(0, "Test 6 RECORD fails - CONSTRUCTOR generates make- constructor");
  3086. nil
  3087. if not getd 'please-make-arecord then
  3088. error(0, "Test 6 RECORD fails - CONSTRUCTOR doesn't generate constructor");
  3089. nil
  3090. if not rtest6p please-make-arecord() then
  3091. error(0, "Test 6 RECORD fails - CONSTRUCTOR doesn't generate record");
  3092. nil
  3093. end;
  3094. nil
  3095. 4: 4: 4: 4: 4: 4: 4: 4: 4:
  3096. Time for test:
  3097. 800 ms
  3098. 5: 5:
  3099. Quitting
  3100. Sun Jan 3 23:46:31 MET 1999