rlisp88.log 95 KB

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