1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449 |
- REDUCE 3.6, 15-Jul-95, patched to 6 Mar 96 ...
- % Test of Rlisp88 version of Rlisp. Many of these functions are taken
- % from the solved exercises in the book "RLISP '88: An Evolutionary
- % Approach to Program Design and Reuse".
- % Author: Jed B. Marti.
- on rlisp88;
- nil
- % Confidence test tries to do a little of everything. This doesn't really
- % test itself so you need to compare to the log file. Syntax errors on
- % the other hand should be cause for alarm.
- % ARRAYS
- % 1. Single dimension array.
- global '(v1);
- nil
- v1 := mkarray 5;
- [nil nil nil nil nil nil]
- for i:=0:5 do v1[i] := 3**i;
- nil
- v1;
- [1 3 9 27 81 243]
- % 2. 2D array.
- global '(v3x3);
- nil
- v3x3 := mkarray(2, 2);
- [[nil nil nil] [nil nil nil] [nil nil nil]]
- for row := 0:2 do
- for col := 0:2 do
- v3x3[row, col] := if row = col then 1.0 else 0.0;
- nil
- v3x3;
- [[1.0 0.0e+000 0.0e+000] [0.0e+000 1.0 0.0e+000] [0.0e+000 0.0e+000 1.0]]
- % 3. Triangular array.
- global '(tri);
- nil
- tri := mkarray 3;
- [nil nil nil nil]
- for row := 0:3 do tri[row] := mkarray row;
- nil
- for row := 0:3 do
- for col := 0:row do
- tri[row,col] := row * col;
- nil
- tri;
- [[0] [0 1] [0 2 4] [0 3 6 9]]
- % 4. ARRAY test.
- expr procedure rotate theta;
- /* Generates rotation array for angle theta (in radians) */
- array(array(cosd theta, - sind theta, 0.0),
- array(sind theta, cosd theta, 0.0),
- array(0.0, 0.0, 1.0));
- rotate
- rotate 45.0;
- [[0.70710678118655 -0.70710678118655 0.0e+000] [0.70710678118655 0.70710678118655
- 0.0e+000] [0.0e+000 0.0e+000 1.0]]
- % 5. Random elements.
- % Now create a vector with random elements.
- M3 := ARRAY('A, 3 + 4, ARRAY("String", 'ID), '(a b));
- [a 7 ["String" id] (a b)]
- M3[2, 1];
- id
- M4 := ARRAY(ARRAY('a, 'b), ARRAY('c, 'd));
- [[a b] [c d]]
- M4[1];
- [c d]
- % 6. Array addition.
- expr procedure ArrayAdd(a, b);
- if vectorp a then
- for i:=0:uc
- with c, uc
- initially c := mkarray(uc := upbv a)
- do c[i] := ArrayAdd(a[i], b[i])
- returns c
- else a + b;
- arrayadd
- ArrayAdd(array(array(array(1, 2), array(3, 4)),
- array(array(5, 6), array(7, 8))),
- array(array(array(1, 1), array(2, 2)),
- array(array(3, 3), array(4, 4))));
- [[[2 3] [5 6]] [[8 9] [11 12]]]
- % RECORDS
- % 1: Declaration.
- RECORD MAPF /* A MAPF record defines
- the contents of a MAPF file. */
- WITH
- MAPF!:NAME := "" /* Name of MAPF (a string) */,
- MAPF!:NUMBER := 0 /* MAPF number (integer) */,
- MAPF!:ROAD-COUNT := 0 /* Number of roads */,
- MAPF!:NODE-COUNT := 0 /* Number of nodes */,
- MAPF!:LLAT := 0.0 /* Lower left hand corner map latitude */,
- MAPF!:LLONG := 0.0 /* Lower left hand corner map longitude */,
- MAPF!:ULAT := 0.0 /* Upper right hand corner map latitude */,
- MAPF!:ULONG := 0.0 /* Upper right hand corner map longitude */;
- mapf
- % 2: Creation.
- global '(r1 r2 r3);
- nil
- r1 := mapf();
- [mapf "" 0 0 0 0.0e+000 0.0e+000 0.0e+000 0.0e+000]
- r2 := mapf(mapf!:name := "foobar", mapf!:road-count := 34);
- [mapf "foobar" 0 34 0 0.0e+000 0.0e+000 0.0e+000 0.0e+000]
- r3 := list('a . r1, 'b . r2);
- ((a . [mapf "" 0 0 0 0.0e+000 0.0e+000 0.0e+000 0.0e+000]) (b . [mapf "foobar" 0
- 34 0 0.0e+000 0.0e+000 0.0e+000 0.0e+000]))
- % 3: Accessing.
- mapf!:number r1;
- 0
- mapf!:road-count cdr assoc('b, r3);
- 34
- % 4: Assignment.
- mapf!:number r1 := 7622;
- 7622
- mapf!:road-count cdr assoc('b, r3) := 376;
- 376
- mapf!:node-count(mapf!:name r2 := mapf()) := 34;
- 34
- r2;
- [mapf [mapf "" 0 0 34 0.0e+000 0.0e+000 0.0e+000 0.0e+000] 0 376 0 0.0e+000
- 0.0e+000 0.0e+000 0.0e+000]
- % 5. Options.
- RECORD complex /* Stores complex reals */
- WITH
- R := 0.0 /* Real part */,
- I := 0.0 /* Imaginary part */
- HAS CONSTRUCTOR;
- complex
- Make-Complex(I := 34.0, R := 12.0);
- [complex 12.0 34.0]
- RECORD Rational /* Representation of rational numbers */
- WITH
- Num := 0 /* Numerator */,
- Den := 1 /* Denominator */
- HAS CONSTRUCTOR = rat;
- +++ num redefined as a macro
- +++ den redefined as a macro
- rational
- expr procedure gcd(p, q);
- if q > p then gcd(q, p)
- else (if r = 0 then q else gcd(q, r)) where r = remainder(p,q);
- gcd
- expr procedure Rational(a, b);
- /* Build a rational number in lowest terms */
- Rat(Num := a / g, Den := b / g) where g := gcd(a, b);
- +++ rational redefined
- rational
- Rational(34, 12);
- [rational 17 6]
- RECORD Timing /* Timing Record for RLISP test */
- WITH
- Machine := "" /* Machine name */,
- Storage := 0 /* Main storage in bits */,
- TimeMS = 0 /* Test time in milliseconds */
- HAS NO CONSTRUCTOR;
- timing
- % PREDICATE option.
- RECORD History /* Record of an event */
- WITH
- EventTime := 0.0 /* Time of event (units) */,
- EventData := NIL /* List with (type ...) */
- HAS PREDICATE = History!?;
- history
- History!? History(EventData := '(MOVE 34.5 52.5));
- t
- % FOR LOOP
- % 1) Basic test.
- EXPR PROCEDURE LPRINT lst;
- /* LPRINT displays each element of its argument separated by blanks.
- After the last element has been displayed, the print line is
- terminated. */
- FOR EACH element IN lst
- DO << PRIN2 element; PRINC " " >>
- FINALLY TERPRI()
- RETURNS lst;
- lprint
- LPRINT '(Now is the time to use RLISP);
- now is the time to use rlisp
- (now is the time to use rlisp)
- % 2) Basic iteration in both directions.
- FOR i:=5 STEP -2 UNTIL 0 DO PRINT i;
- 5
- 3
- 1
- nil
- FOR i:=1:3 DO PRINT i;
- 1
- 2
- 3
- nil
- % 3) COLLECT option.
- FOR EACH leftpart IN '(A B C)
- EACH rightpart IN '(1 2 "string")
- COLLECT leftpart . rightpart;
- ((a . 1) (b . 2) (c . "string"))
- % 4) IN/ON iterators.
- FOR EACH X IN '(a b c) DO PRINT x;
- a
- b
- c
- nil
- FOR EACH x ON '(a b c) DO PRINT x;
- (a b c)
- (b c)
- (c)
- nil
- % 5) EVERY option.
- FOR EACH x IN '(A B C) EVERY IDP x
- RETURNS "They are all id's";
- "They are all id's"
- FOR EACH x IN '(A B 12) EVERY IDP x
- RETURNS "They are all id's";
- nil
- % 6) INITIALLY/FINALLY option.
- EXPR PROCEDURE ListPrint x;
- /* ListPrint(x) displays each element of x separated by blanks. The
- first element is prefixed with "*** ". The last element is suffixed
- with a period and a new line. */
- FOR EACH element ON x
- INITIALLY PRIN2 "*** "
- DO << PRIN2 CAR element;
- IF CDR element THEN PRIN2 " " >>
- FINALLY << PRIN2 "."; TERPRI() >>;
- listprint
- ListPrint '(The quick brown bert died);
- *** the quick brown bert died.
- nil
- % 7) MAXIMIZE/MINIMIZE options.
- FOR EACH x IN '(A B 12 -34 2.3)
- WHEN NUMBERP x
- MAXIMIZE x;
- 12
- FOR EACH x IN '(A B 12 -34 2.3)
- WHEN NUMBERP x
- MINIMIZE x;
- -34
- % 8) RETURNS option.
- EXPR PROCEDURE ListFiddle(f, x);
- /* ListFiddle displays every element of its second argument and returns
- a list of those for which the first argument returns non-NIL. */
- FOR EACH element IN x
- WITH clist
- DO << PRINT element;
- IF APPLY(f, LIST element) THEN clist := element . clist >>
- RETURNS REVERSIP clist;
- listfiddle
- ListFiddle(FUNCTION ATOM, '(a (BANG 12) "OOPS!"));
- a
- (bang 12)
- "OOPS!"
- (a "OOPS!")
- % 9) SOME option.
- FOR EACH x IN '(a b 12) SOME NUMBERP x
- DO PRINT x;
- a
- b
- t
- % 10) UNTIL/WHILE options.
- EXPR PROCEDURE CollectUpTo l;
- /* CollectUpTo collect all the elements of the list l up to the
- first number. */
- FOR EACH x IN l UNTIL NUMBERP x COLLECT x;
- collectupto
- CollectUpTo '(a b c 1 2 3);
- (a b c)
- % 11) WHEN/UNLESS options.
- FOR EACH x IN '(A 12 "A String" 32)
- WHEN NUMBERP x
- COLLECT x;
- (12 32)
- % ##### Basic Tests #####
- % Tests some very basic things that seem to go wrong frequently.
- % Numbers.
- if +1 neq 1 then error(0, "+1 doesn't parse");
- nil
- if -1 neq - 1 then error(0, "-1 doesn't parse");
- nil
- expr procedure factorial n;
- if n < 2 then 1 else n * factorial(n - 1);
- +++ factorial redefined
- factorial
- if +2432902008176640000 neq factorial 20 then
- error(0, "bignum + doesn't work");
- nil
- if -2432902008176640000 neq - factorial 20 then
- error(0, "bignum - doesn't work");
- nil
- % This actually blew up at one time.
- if -3.14159 neq - 3.14159 then error(0, "negative floats don't work");
- nil
- if +3.14159 neq 3.14159 then error(0, "positive floats don't work");
- nil
- % ##### Safe Functions #####
- % Description: A set of CAR/CDR alternatives that
- % return NIL when CAR/CDR of an atom is tried.
- expr procedure SafeCar x;
- /* Returns CAR of a list or NIL. */
- if atom x then nil else car x;
- safecar
- expr procedure SafeCdr x;
- /* Returns CDR of a list or NIL. */
- if atom x then nil else cdr x;
- safecdr
- expr procedure SafeFirst x; SafeCar x;
- safefirst
- expr procedure SafeSecond x; SafeCar SafeCdr x;
- safesecond
- expr procedure SafeThird x; SafeSecond SafeCdr x;
- safethird
- % ##### Test of Procedures #####
- %------------------------- Exercise #1 -------------------------
- expr procedure delassoc(x, a);
- /* Delete the element from x from the alist a non-destructively. Returns
- the reconstructed list. */
- if null a then nil
- else if atom a then a . delassoc(x, cdr a)
- else if caar a = x then cdr a
- else car a . delassoc(x, cdr a);
- delassoc
- if delassoc('a, '((a b) (c d))) = '((c d))
- then "Test 1 delassoc OK"
- else error(0, "Test 1 delassoc failed");
- "Test 1 delassoc OK"
- if delassoc('b, '((a b) (b c) (c d))) = '((a b) (c d))
- then "Test 2 delassoc OK"
- else error(0, "Test 2 delassoc failed");
- "Test 2 delassoc OK"
- if delassoc('c, '((a b) (b c) (c d))) = '((a b) (b c))
- then "Test 3 delassoc OK"
- else error(0, "Test 3 delassoc failed");
- "Test 3 delassoc OK"
- if delassoc('d, '((a b) (b c) (c d))) = '((a b) (b c) (c d))
- then "Test 4 delassoc OK"
- else error(0, "Test 4 delassoc failed");
- "Test 4 delassoc OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure gcd(u, v);
- if v = 0 then u else gcd(v, remainder(u, v));
- +++ gcd redefined
- gcd
- if gcd(2, 4) = 2 then "Test 1 GCD OK" else error(0, "Test 1 GCD fails");
- "Test 1 GCD OK"
- if gcd(13, 7) = 1
- then "Test 2 GCD OK" else error(0, "Test 2 GCD fails");
- "Test 2 GCD OK"
- if gcd(15, 10) = 5
- then "Test 3 GCD OK" else error(0, "Test 3 GCD fails");
- "Test 3 GCD OK"
- if gcd(-15, 10) = -5
- then "Test 4 GCD OK" else error(0, "Test 4 GCD fails");
- "Test 4 GCD OK"
- if gcd(-15, 0) = -15
- then "Test 5 GCD OK" else error(0, "Test 5 GCD fails");
- "Test 5 GCD OK"
- %-------------------- Exercise #3 --------------------
- expr procedure properintersection(a, b);
- /* Returns the proper intersection of proper sets a and b.
- The set representation is a list of elements with the
- EQUAL relation. */
- if null a then nil
- else if car a member b then car a . properintersection(cdr a, b)
- else properintersection(cdr a, b);
- properintersection
- % Test an EQ intersection.
- properintersection('(a b), '(b c));
- (b)
- if properintersection('(a b), '(b c)) = '(b)
- then "Test 1 properintersection OK"
- else error(0, "Test 1 properintersection fails");
- "Test 1 properintersection OK"
- % Test an EQUAL intersection.
- properintersection('((a) b (c)), '((a) b (c)));
- ((a) b (c))
- if properintersection('((a) b (c)), '((a) b (c))) = '((a) b (c))
- then "Test 2 properintersection OK"
- else error(0, "Test 2 properintersection fails");
- "Test 2 properintersection OK"
- % Test an EQUAL intersection, out of order.
- properintersection('((a) b (c)), '(b (c) (a)));
- ((a) b (c))
- if properintersection('((a) b (c)), '(b (c) (a))) = '((a) b (c))
- then "Test 3 properintersection OK"
- else error(0, "Test 3 properintersection fails");
- "Test 3 properintersection OK"
- % Test an empty intersection.
- properintersection('((a) b (c)), '(a (b) c));
- nil
- if properintersection('((a) b (c)), '(a (b) c)) = nil
- then "Test 4 properintersection OK"
- else error(0, "Test 4 properintersection fails");
- "Test 4 properintersection OK"
- %-------------------- Exercise #4 -------------------------
- expr procedure TreeVisit(a, tree, c);
- /* Preorder visit of tree to find a. Returns path from root. c
- contains path to root of tree so far. */
- if null tree then nil
- else if a = car tree then append(c, {a})
- else TreeVisit(a, cadr tree, append(c, {car tree})) or
- TreeVisit(a, caddr tree, append(c, {car tree}));
- treevisit
- TreeVisit('c, '(a (b (d nil nil) (c nil nil)) (e nil nil)), nil);
- (a b c)
- if TreeVisit('c, '(a (b (d nil nil) (c nil nil)) (e nil nil)), nil)
- = '(a b c)
- then "Test 1 TreeVisit OK"
- else error(0, "Test 1 TreeVisit fails");
- "Test 1 TreeVisit OK"
- TreeVisit('h, '(a (b (d nil nil) (c nil nil))
- (e (f nil nil) (g (h nil nil) nil)) ), nil);
- (a e g h)
- if TreeVisit('h, '(a (b (d nil nil) (c nil nil))
- (e (f nil nil) (g (h nil nil) nil))),nil) = '(a e g h)
- then "Test 2 TreeVisit OK"
- else error(0, "Test 2 TreeVisit fails");
- "Test 2 TreeVisit OK"
- if TreeVisit('i, '(a (b (d nil nil) (c nil nil))
- (e (f nil nil) (g (h nil nil) nil)) ), nil) = nil
- then "Test 3 TreeVisit OK"
- else error(0, "Test 3 TreeVisit fails");
- "Test 3 TreeVisit OK"
- if TreeVisit('a, '(a (b (d nil nil) (c nil nil))
- (e (f nil nil) (g (h nil nil) nil)) ), nil) = '(a)
- then "Test 4 TreeVisit OK"
- else error(0, "Test 4 TreeVisit fails");
- "Test 4 TreeVisit OK"
- if TreeVisit('e, '(a (b (d nil nil) (c nil nil))
- (e (f nil nil) (g (h nil nil) nil)) ), nil) = '(a e)
- then "Test 5 TreeVisit OK"
- else error(0, "Test 5 TreeVisit fails");
- "Test 5 TreeVisit OK"
- %-------------------- Exercise #5 -------------------------
- expr procedure lookfor(str, l);
- /* Search for the list str (using =) in the top level
- of list l. Returns str and remaining part of l if
- found. */
- if null l then nil
- else if lookfor1(str, l) then l
- else lookfor(str, cdr l);
- lookfor
- expr procedure lookfor1(str, l);
- if null str then t
- else if null l then nil
- else if car str = car l then lookfor1(cdr str, cdr l);
- lookfor1
- 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)
- then "Test 1 lookfor OK"
- else error(0, "Test 1 lookfor fails");
- "Test 1 lookfor OK"
- if lookfor('(now is), '(now we have nothing is)) = NIL
- then "Test 2 lookfor OK"
- else error(0, "Test 2 lookfor fails");
- "Test 2 lookfor OK"
- if lookfor('(now is), '(well hello!, now)) = NIL
- then "Test 3 lookfor OK"
- else error(0, "Test 3 lookfor fails");
- "Test 3 lookfor OK"
- %-------------------- Exercise #6 -------------------------
- expr procedure add(a, b, carry, modulus);
- /* Add two numbers stored as lists with digits of
- modulus. Carry passes the carry around. Tries to
- suppress leading 0's but fails with negatives. */
- if null a then
- if null b then if zerop carry then nil
- else {carry}
- else remainder(carry + car b, modulus) .
- add(nil, cdr b, (carry + car b) / modulus, modulus)
- else if null b then add(b, a, carry, modulus)
- else remainder(car a + car b + carry, modulus) .
- add(cdr a, cdr b, (car a + car b + carry) / modulus,
- modulus);
- add
- if add('(9 9), '(9 9), 0, 10) = '(8 9 1)
- then "Test 1 add OK"
- else error(0, "Test 1 add fails");
- "Test 1 add OK"
- if add('(-9 -9), '(9 9), 0, 10) = '(0 0)
- then "Test 2 add OK"
- else error(0, "Test 2 add fails");
- "Test 2 add OK"
- if add('(9 9 9), '(9 9 9 9), 0, 10) = '(8 9 9 0 1)
- then "Test 3 add OK"
- else error(0, "Test 3 add fails");
- "Test 3 add OK"
- if add('(99 99 99), '(99 99 99 99), 0, 100) = '(98 99 99 0 1)
- then "Test 4 add OK"
- else error(0, "Test 4 add fails");
- "Test 4 add OK"
- if add('(13 12), '(15 1), 0, 16) = '(12 14)
- then "Test 5 add OK"
- else error(0, "Test 5 add fails");
- "Test 5 add OK"
- %-------------------- Exercise #7 -------------------------
- expr procedure clength(l, tmp);
- /* Compute the length of the (possibly circular) list l.
- tmp is used to pass values looked at down the list. */
- if null l or l memq tmp then 0
- else 1 + clength(cdr l, l . tmp);
- clength
- if clength('(a b c), nil) = 3
- then "Test 1 clength OK"
- else error(0, "Test 1 clength fails");
- "Test 1 clength OK"
- << xxx := '(a b c); cdr lastpair xxx := xxx; nil >>;
- nil
- if clength(xxx, nil) = 3
- then "Test 2 clength OK"
- else error(0, "Test 1 clength fails");
- "Test 2 clength OK"
- if clength(append('(a b c), xxx), nil) = 6
- then "Test 3 clength OK"
- else error(0, "Test 1 clength fails");
- "Test 3 clength OK"
- %------------------------- Exercise #8 -------------------------
- expr procedure fringe x;
- /* FRINGE(X) -- returns the fringe of X (the atoms at the
- end of the tree structure of X). */
- if atom x then {x}
- else if cdr x then append(fringe car x, fringe cdr x)
- else fringe car x;
- fringe
- if fringe nil = '(NIL)
- then "Test 1 fringe OK"
- else error(0, "Test 1 fringe fails");
- "Test 1 fringe OK"
- if fringe '(a b . c) = '(a b c)
- then "Test 2 fringe OK"
- else error(0, "Test 2 fringe fails");
- "Test 2 fringe OK"
- if fringe '((((a) . b) (c . d)) . e) = '(a b c d e)
- then "Test 3 fringe OK"
- else error(0, "Test 3 fringe fails");
- "Test 3 fringe OK"
- %------------------------- Exercise #9 -------------------------
- expr procedure delall(x, l);
- /* DELALL(X, L) -- Delete all X's from the list L using EQUAL
- test. The list is reconstructed. */
- if null l then nil
- else if x = car l then delall(x, cdr l)
- else car l . delall(x, cdr l);
- delall
- if delall('X, nil) = NIL
- then "Test 1 delall OK"
- else error(0, "Test 1 delall fails");
- "Test 1 delall OK"
- if delall('X, '(X)) = NIL
- then "Test 2 delall OK"
- else error(0, "Test 2 delall fails");
- "Test 2 delall OK"
- if delall('X, '(A)) = '(A)
- then "Test 3 delall OK"
- else error(0, "Test 3 delall fails");
- "Test 3 delall OK"
- if delall('(X B), '(A (B) (X B))) = '(A (B))
- then "Test 4 delall OK"
- else error(0, "Test 4 delall fails");
- "Test 4 delall OK"
- if delall('(X B), '((X B) (X B))) = NIL
- then "Test 5 delall OK"
- else error(0, "Test 5 delall fails");
- "Test 5 delall OK"
- if delall('(X B), '((X B) X B (X B))) = '(X B)
- then "Test 6 delall OK"
- else error(0, "Test 6 delall fails");
- "Test 6 delall OK"
- % ------------------------- Exercise #10 -------------------------
- expr procedure startswith(prefix, word);
- /* STARTSWITH(PREFIX, WORD) -- Returns T if the list of
- characters WORD begins with the list of characters PREFIX. */
- if null prefix then T
- else if word then
- if car prefix eq car word then
- startswith(cdr prefix, cdr word);
- startswith
- if startswith('(P R E), '(P R E S I D E N T)) = T
- then "Test 1 startswith OK!"
- else error(0, "Test 1 startswith fails");
- "Test 1 startswith OK!"
- if startswith('(P R E), '(P O S T F I X)) = NIL
- then "Test 2 startswith OK!"
- else error(0, "Test 2 startswith fails");
- "Test 2 startswith OK!"
- if startswith('(P R E), '(P R E)) = T
- then "Test 3 startswith OK!"
- else error(0, "Test 3 startswith fails");
- "Test 3 startswith OK!"
- if startswith('(P R E), '(P R)) = NIL
- then "Test 4 startswith OK!"
- else error(0, "Test 4 startswith fails");
- "Test 4 startswith OK!"
- if startswith('(P R E), NIL) = NIL
- then "Test 5 startswith OK!"
- else error(0, "Test 5 startswith fails");
- "Test 5 startswith OK!"
- if startswith('(P R E), '(P P R E)) = NIL
- then "Test 6 startswith OK!"
- else error(0, "Test 6 startswith fails");
- "Test 6 startswith OK!"
- % ##### Test of Definitions #####
- %------------------------- Exercise #1 -------------------------
- expr procedure goodlist l;
- /* GOODLIST(L) - returns T if L is a proper list. */
- if null l then T
- else if pairp l then goodlist cdr l;
- goodlist
- if goodlist '(a b c) = T
- then "Test 1 goodlist OK"
- else error(0, "Test 1 goodlist fails");
- "Test 1 goodlist OK"
- if goodlist nil = T
- then "Test 2 goodlist OK"
- else error(0, "Test 2 goodlist fails");
- "Test 2 goodlist OK"
- if goodlist '(a . b) = NIL
- then "Test 3 goodlist OK"
- else error(0, "Test 3 goodlist fails");
- "Test 3 goodlist OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure fmember(a, b, fn);
- /* FMEMBER(A, B, FN) - Returns rest of B is A is a member
- of B using the FN of two arguments as an equality check. */
- if null b then nil
- else if apply(fn, {a, car b}) then b
- else fmember(a, cdr b, fn);
- fmember
- if fmember('a, '(b c a d), function EQ) = '(a d)
- then "Test 1 fmember is OK"
- else error(0, "Test 1 fmember fails");
- "Test 1 fmember is OK"
- if fmember('(a), '((b c) (a) d), function EQ) = NIL
- then "Test 2 fmember is OK"
- else error(0, "Test 2 fmember fails");
- "Test 2 fmember is OK"
- if fmember('(a), '((b c) (a) d), function EQUAL) = '((a) d)
- then "Test 3 fmember is OK"
- else error(0, "Test 3 fmember fails");
- "Test 3 fmember is OK"
- if fmember(34, '(1 2 56 12), function LESSP) = '(56 12)
- then "Test 4 fmember is OK"
- else error(0, "Test 4 fmember fails");
- "Test 4 fmember is OK"
- %------------------------- Exercise #3-4 -------------------------
- expr procedure findem(l, fn);
- /* FINDEM(L, FN) - returns a list of elements in L that satisfy
- the single argument function FN. */
- if null l then nil
- else if apply(fn, {car l}) then car l . findem(cdr l, fn)
- else findem(cdr l, fn);
- findem
- if findem('(a 1 23 b "foo"), function idp) = '(a b)
- then "Test 1 findem OK!"
- else error(0, "Test 1 findem fails");
- "Test 1 findem OK!"
- if findem('(1 3 a (44) 12 9),
- function (lambda x; numberp x and x < 10)) = '(1 3 9)
- then "Test 2 findem OK!"
- else error(0, "Test 2 findem fails");
- "Test 2 findem OK!"
- %------------------------- Exercise #5 -------------------------
- expr procedure insert(a, l, f);
- /* Insert the value a into list l based on the partial ordering function
- f(x,y). Non-destructive insertion. */
- if null l then {a}
- else if apply(f, {car l, a}) then a . l
- else car l . insert(a, cdr l, f);
- insert
- % Basic ascending order sort.
- insert(6, '(1 5 10), function geq);
- (1 5 6 10)
- if insert(6, '(1 5 10), function geq) = '(1 5 6 10)
- then "Test 1 insert (>=) OK"
- else error(0, "Test 1 insert (>=) fails");
- "Test 1 insert (>=) OK"
- % Try inserting element at end of list.
- insert(11, '(1 5 10), function geq);
- (1 5 10 11)
- if insert(11, '(1 5 10), function geq) = '(1 5 10 11)
- then "Test 2 insert (>=) OK"
- else error(0, "Test 2 insert (>=) fails");
- "Test 2 insert (>=) OK"
- % Tru inserting something at the list beginning.
- insert(-1, '(1 5 10), function geq);
- (-1 1 5 10)
- if insert(-1, '(1 5 10), function geq) = '(-1 1 5 10)
- then "Test 3 insert (>=) OK"
- else error(0, "Test 3 insert (>=) fails");
- "Test 3 insert (>=) OK"
- % Insert into an empty list.
- insert('34, nil, function leq);
- (34)
- if insert(34, nil, function leq) = '(34)
- then "Test 4 insert (<=) OK"
- else error(0, "Test 4 insert (<=) fails");
- "Test 4 insert (<=) OK"
- % Use a funny insertion function for (order . any);
- expr procedure cargeq(a, b); car a >= car b;
- cargeq
- insert('(34 . any), '((5 . now) (20 . and) (30 . then) (40 . but)),
- function cargeq);
- ((5 . now) (20 . and) (30 . then) (34 . any) (40 . but))
- if insert('(34 . any), '((5 . now) (20 . and) (30 . then) (40 . but)),
- function cargeq) = '((5 . now) (20 . and) (30 . then) (34 . any)
- (40 . but))
- then "Test 5 insert (>=) OK"
- else error(0, "Test 5 insert (>=) fails");
- "Test 5 insert (>=) OK"
- % ###### FOR Loop Exercises #####
- %------------------------- Exercise #1 -------------------------
- expr procedure floatlist l;
- /* FLOATLIST(L) returns a list of all floating point
- numbers in list L. */
- for each x in l
- when floatp x
- collect x;
- floatlist
- if floatlist '(3 3.4 a nil) = '(3.4)
- then "Test 1 floatlist OK"
- else error(0, "Test 1 floatlist fails");
- "Test 1 floatlist OK"
- if floatlist '(3.4 1.222 1.0e22) = '(3.4 1.222 1.0e22)
- then "Test 2 floatlist OK"
- else error(0, "Test 2 floatlist fails");
- "Test 2 floatlist OK"
- if floatlist '(a b c) = NIL
- then "Test 3 floatlist OK"
- else error(0, "Test 3 floatlist fails");
- "Test 3 floatlist OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure revpairnum l;
- /* REVPAIRNUM(L) returns elements of L in a pair with
- the CAR a number starting at length of L and working
- backwards.*/
- for i:=length l step -1 until 0
- each x in l
- collect i . x;
- revpairnum
- if revpairnum '(a b c) = '((3 . a) (2 . b) (1 . c))
- then "Test 1 revpairnum OK"
- else error(0, "Test 1 revpairnum fails");
- "Test 1 revpairnum OK"
- if revpairnum nil = nil
- then "Test 2 revpairnum OK"
- else error(0, "Test 2 revpairnum fails");
- "Test 2 revpairnum OK"
- if revpairnum '(a) = '((1 . a))
- then "Test 3 revpairnum OK"
- else error(0, "Test 3 revpairnum fails");
- "Test 3 revpairnum OK"
- %------------------------- Exercise #3 -------------------------
- expr procedure lflatten l;
- /* LFLATTEN(L) destructively flattens the list L
- to all levels. */
- if listp l then for each x in l conc lflatten x
- else {l};
- lflatten
- if lflatten '(a (b) c (e (e))) = '(a b c e e)
- then "Test 1 lflatten OK"
- else error(0, "Test 1 lflatten fails");
- "Test 1 lflatten OK"
- if lflatten '(a b c) = '(a b c)
- then "Test 2 lflatten OK"
- else error(0, "Test 2 lflatten fails");
- "Test 2 lflatten OK"
- if lflatten nil = nil
- then "Test 3 lflatten OK"
- else error(0, "Test 3 lflatten fails");
- "Test 3 lflatten OK"
- if lflatten '(a (b (c (d)))) = '(a b c d)
- then "Test 4 lflatten OK"
- else error(0, "Test 4 lflatten fails");
- "Test 4 lflatten OK"
- %------------------------- Exercise #4 -------------------------
- expr procedure realstuff l;
- /* REALSTUFF(L) returns the number of non-nil items in l. */
- for each x in l count x;
- realstuff
- if realstuff '(a b nil c) = 3
- then "Test 1 realstuff OK"
- else error(0, "Test 1 realstuff fails");
- "Test 1 realstuff OK"
- if realstuff '(nil nil nil) = 0
- then "Test 2 realstuff OK"
- else error(0, "Test 2 realstuff fails");
- "Test 2 realstuff OK"
- if realstuff '(a b c d) = 4
- then "Test 3 realstuff OK"
- else error(0, "Test 3 realstuff fails");
- "Test 3 realstuff OK"
- %------------------------- Exercise #5 -------------------------
- expr procedure psentence s;
- /* PSENTENCE(S) prints the list of "words" S with
- separating blanks and a period at the end. */
- for each w on s
- do << prin2 car w;
- if cdr w then prin2 " " else prin2t "." >>;
- psentence
- psentence '(The man in the field is happy);
- the man in the field is happy.
- nil
- %------------------------- Exercise #6 -------------------------
- expr procedure bsort v;
- /* BSORT(V) sorts the vector V into ascending order using
- bubble sort. */
- for i:=0:sub1 upbv v
- returns v
- do for j:=add1 i:upbv v
- when i neq j and v[i] > v[j]
- with tmp
- do << tmp := v[j]; v[j] := v[i]; v[i] := tmp >>;
- bsort
- xxx := [4,3,2,1, 5];
- [4 3 2 1 5]
- if bsort xxx = [1,2,3,4,5]
- then "Test 1 bsort OK"
- else error(0, "Test 1 bsort fails");
- "Test 1 bsort OK"
- xxx := [1];
- [1]
- if bsort xxx = [1]
- then "Test 2 bsort OK"
- else error(0, "Test 2 bsort fails");
- "Test 2 bsort OK"
- %------------------------- Exercise #7 -------------------------
- expr procedure bsortt v;
- /* BSORTT(V) sorts the vector V into ascending order using
- bubble sort. It verifies that all elements are numbers. */
- << for i:=0:upbv v
- when not numberp v[i]
- do error(0, {v[i], "is not a number for BSORTT"});
- for i:=0:sub1 upbv v
- returns v
- do for j:=add1 i:upbv v
- when i neq j and v[i] > v[j]
- with tmp
- do << tmp := v[j]; v[j] := v[i]; v[i] := tmp >> >>;
- bsortt
- xxx := [1,2,'a];
- [1 2 a]
- if atom errorset(quote bsortt xxx, nil, nil)
- then "Test 1 bsortt OK"
- else error(0, "Test 1 bsortt fails");
- "Test 1 bsortt OK"
- xxx := [1, 4, 3, 1];
- [1 4 3 1]
- if car errorset(quote bsortt xxx, nil, nil) = [1,1,3,4]
- then "Test 2 bsortt OK"
- else error(0, "Test 2 bsortt fails");
- "Test 2 bsortt OK"
- % ------------------------- Exercise #8 -------------------------
- expr procedure average l;
- /* AVERAGE(L) compute the average of the numbers
- in list L. Returns 0 if there are none. */
- for each x in l
- with sm, cnt
- initially sm := cnt := 0
- when numberp x
- do << sm := sm + x; cnt := cnt + 1 >>
- returns if cnt > 0 then sm / cnt else 0;
- average
- if average '(a 12 34) = 23 then
- "Test 1 average OK"
- else error(0, "Test 1 average fails");
- "Test 1 average OK"
- if average '(a b c) = 0 then
- "Test 2 average OK"
- else error(0, "Test 2 average fails");
- "Test 2 average OK"
- if average '(a b c 5 6) = 5 then
- "Test 3 average OK"
- else error(0, "Test 3 average fails");
- "Test 3 average OK"
- if average '(a b c 5 6.0) = 5.5 then
- "Test 4 average OK"
- else error(0, "Test 4 average fails");
- "Test 4 average OK"
- %------------------------- Exercise #9 -------------------------
- expr procedure boundingbox L;
- /* BOUNDINGBOX(L) returns a list of
- (min X, max X, min Y, max Y)
- for the list L of dotted-pairs (x . y). */
- { for each x in L minimize car x,
- for each x in L maximize car x,
- for each y in L minimize cdr y,
- for each y in L maximize cdr y};
- boundingbox
- if boundingbox '((0 . 1) (4 . 5)) = '(0 4 1 5)
- then "Test 1 boundingbox OK"
- else error(0, "Test 1 boundingbox fails");
- "Test 1 boundingbox OK"
- if boundingbox nil = '(0 0 0 0)
- then "Test 2 boundingbox OK"
- else error(0, "Test 2 boundingbox fails");
- "Test 2 boundingbox OK"
- if boundingbox '((-5 . 3.4) (3.3 . 2.3) (1.2 . 33)
- (-5 . -8) (22.11 . 3.14) (2 . 3)) = '(-5 22.11 -8 33)
- then "Test 3 boundingbox OK"
- else error(0, "Test 3 boundingbox fails");
- "Test 3 boundingbox OK"
- %------------------------- Exercise #10 -------------------------
- expr procedure maxlists(a, b);
- /* MAXLISTS(A, B) -- Build a list such that for each pair
- of elements in lists A and B the new list has the largest
- element. */
- for each ae in a
- each be in b
- collect max(ae, be);
- maxlists
- if maxlists('(3 1.2), '(44.22 0.9 1.3)) = '(44.22 1.2)
- then "Test 1 maxlists OK"
- else error(0, "Test 1 maxlists fails");
- "Test 1 maxlists OK"
- if maxlists(nil, '(44.22 0.9 1.3)) = nil
- then "Test 2 maxlists OK"
- else error(0, "Test 2 maxlists fails");
- "Test 2 maxlists OK"
- if maxlists('(44.22 0.9 1.3), nil) = nil
- then "Test 3 maxlists OK"
- else error(0, "Test 3 maxlists fails");
- "Test 3 maxlists OK"
- if maxlists('(1.0 1.2 3.4), '(1 1)) = '(1.0 1.2)
- then "Test 4 maxlists OK"
- else error(0, "Test 4 maxlists fails");
- "Test 4 maxlists OK"
- %------------------------- Exercise #11 -------------------------
- expr procedure numberedlist l;
- /* NUMBEREDLIST(L) -- returns an a-list with the CAR being
- elements of L and CDR, the position in the list of the
- element starting with 0. */
- for i:=0:length l
- each e in l
- collect e . i;
- numberedlist
- if numberedlist nil = nil
- then "Test 1 numberedlist is OK"
- else error(0, "Test 1 numberedlist fails");
- "Test 1 numberedlist is OK"
- if numberedlist '(a) = '((a . 0))
- then "Test 2 numberedlist is OK"
- else error(0, "Test 2 numberedlist fails");
- "Test 2 numberedlist is OK"
- if numberedlist '(a b c) = '((a . 0) (b . 1) (c . 2))
- then "Test 2 numberedlist is OK"
- else error(0, "Test 2 numberedlist fails");
- "Test 2 numberedlist is OK"
- %------------------------- Exercise #12 -------------------------
- expr procedure reduce x;
- /* REDUCE(X) -- X is a list of things some of which are
- encapsulated as (!! . y) and returns x. Destructively
- replace these elements with just y. */
- for each v on x
- when eqcar(car v, '!!)
- do car v := cdar v
- returns x;
- reduce
- global '(x11);
- nil
- x11 := '((!! . a) (b c) (d (!! . 34)));
- ((!! . a) (b c) (d (!! . 34)))
- if reduce x11 = '(a (b c) (d (!! . 34)))
- then "Test 1 reduce OK"
- else error(0, "Test 1 reduce fails");
- "Test 1 reduce OK"
- if x11 = '(a (b c) (d (!! . 34)))
- then "Test 2 reduce OK"
- else error(0, "Test 2 reduce fails");
- "Test 2 reduce OK"
- % ##### Further Procedure Tests #####
- %------------------------- Exercise #1 -------------------------
- expr procedure removeflags x;
- /* REMOVEFLAGS(X) -- Scan list x replacing each top level
- occurrence of (!! . x) with x (whatever x is) and return
- the list. Replacement is destructive. */
- while x and eqcar(car x, '!!)
- with v
- initially v := x
- do << print x; car x := cdar x; print x; x := cdr x >>
- returns v;
- removeflags
- xxx := '((!!. a) (!! . b) c (!! . d));
- ((!! . a) (!! . b) c (!! . d))
- if removeflags xxx = '(a b c (!! . d))
- then "Test 1 removeflags OK"
- else error(0, "Test 1 removeflags fails");
- ((!! . a) (!! . b) c (!! . d))
- (a (!! . b) c (!! . d))
- ((!! . b) c (!! . d))
- (b c (!! . d))
- "Test 1 removeflags OK"
- if xxx = '(a b c (!! . d))
- then "Test 2 removeflags OK"
- else error(0, "Test 2 removeflags fails");
- "Test 2 removeflags OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure read2char c;
- /* READ2CHAR(C) -- Read characters to C and return the
- list including C. Terminates at end of file. */
- repeat l := (ch := readch()) . l
- with ch, l
- until ch eq c or ch eq !$EOF!$
- returns reversip l;
- read2char
- if read2char '!* = {!$EOL!$, 'A, 'B, 'C, '!*}
- then "Test 1 read2char OK"
- else error(0, "Test 1 read2char fails");
- ABC*
- "Test 1 read2char OK"
- %------------------------- Exercise #3 -------------------------
- expr procedure skipblanks l;
- /* SKIPBLANKS(L) - Returns L with leading blanks
- removed. */
- while l and eqcar(l, '! )
- do l := cdr l
- returns l;
- skipblanks
- if skipblanks '(! ! ! a b) neq '(a b)
- then error(0, "Skipblanks fails test #1");
- nil
- if skipblanks nil
- then error(0, "Skipblanks fails test #2");
- nil
- if skipblanks '(! ! ! )
- then error(0, "Skipblanks fails test #3");
- nil
- if skipblanks '(! ! a b ! ) neq '(a b ! )
- then error(0, "Skipblanks fails test #4");
- nil
- %------------------------- Exercise #4 -------------------------
- expr procedure ntoken l;
- /* NTOKEN(L) - Scan over blanks in l. Then collect
- and return all characters up to the next blank
- returning a dotted-pair of (token . rest of L) or
- NIL if none is found. */
- while l and eqcar(l, '! ) do l := cdr l
- returns
- if l then
- while l and not eqcar(l, '! )
- with tok
- do << tok := car l . tok;
- l := cdr l >>
- returns (reversip tok . l);
- ntoken
- if ntoken '(! ! a b ! ) neq '((a b) . (! ))
- then error(0, "ntoken fails test #1");
- nil
- if ntoken nil then error(0, "ntoken fails test #2");
- nil
- if ntoken '(! ! ! ) then error(0, "ntoken fails test #3");
- nil
- if ntoken '(! ! a b) neq '((a b) . nil)
- then error(0, "ntoken fails test #4");
- nil
- % ##### Block Statement Exercises #####
- %------------------------- Exercise #1 -------------------------
- expr procedure r2nums;
- /* R2NUMS() -- Read 2 numbers and return as a list. */
- begin scalar n1;
- n1 := read();
- return {n1, read()}
- end;
- r2nums
- if r2nums() = '(2 3)
- then "Test 1 r2nums OK"
- else error(0, "Test 1 r2nums failed");
- 2 3
- "Test 1 r2nums OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure readcoordinate;
- /* READCOORDINATE() -- Read a coordinate and return
- it in radians. If prefixed with @, convert from
- degrees. If a list convert from degrees minutes
- seconds. */
- begin scalar x;
- return
- (if (x := read()) eq '!@ then read() / 57.2957795130823208767981
- else if pairp x then
- (car x + cadr x / 60.0 + caddr x / 3600.0)
- / 57.2957795130823208767981
- else x)
- end;
- readcoordinate
- fluid '(val);
- nil
- val := readcoordinate();
- @ 57.29577
- 0.99999983396539
- if val < 1.000001 AND val > 0.999999
- then "Test 1 readcoordinate OK"
- else error(0, "Test 1 readcoordinate failed");
- "Test 1 readcoordinate OK"
- % This fails with poor arithmetic.
- val := readcoordinate();
- (57 17 44.772)
- 0.99999983396539
- if val < 1.000001 AND val > 0.999999
- then "Test 2 readcoordinate OK"
- else error(0, "Test 2 readcoordinate failed");
- "Test 2 readcoordinate OK"
- unfluid '(val);
- nil
- if readcoordinate() = 1.0
- then "Test 3 readcoordinate OK"
- else error(0, "Test 3 readcoordinate failed");
- 1.0
- "Test 3 readcoordinate OK"
- %------------------------- Exercise #3 -------------------------
- expr procedure delallnils l;
- /* DELALLNILS(L) - destructively remove all NIL's from
- list L. The resulting value is always EQ to L. */
- begin scalar p, prev;
- p := l;
- loop: if null p then return l;
- if null car p then
- if null cdr p then
- if null prev then return nil
- else << cdr prev := nil;
- return l >>
- else << car p := cadr p;
- cdr p := cddr p;
- go to loop >>;
- prev := p;
- p := cdr p;
- go to loop
- end;
- delallnils
- fluid '(xxx yyy);
- nil
- % New - added to aid CSL.
- xxx := '(a b c nil d);
- (a b c nil d)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 1 dellallnils OK"
- else error(0, "Test 1 delallnils Fails!");
- "Test 1 dellallnils OK"
- xxx := '(a nil b nil c nil d);
- (a nil b nil c nil d)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 2 dellallnils OK"
- else error(0, "Test 2 delallnils Fails!");
- "Test 2 dellallnils OK"
- xxx := '(a nil b nil c nil d nil);
- (a nil b nil c nil d nil)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 3 dellallnils OK"
- else error(0, "Test 3 delallnils Fails!");
- "Test 3 dellallnils OK"
- xxx := '(a nil nil nil nil b c d);
- (a nil nil nil nil b c d)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 4 dellallnils OK"
- else error(0, "Test 4 delallnils Fails!");
- "Test 4 dellallnils OK"
- xxx := '(nil a b c d);
- (nil a b c d)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 5 dellallnils OK"
- else error(0, "Test 5 delallnils Fails!");
- "Test 5 dellallnils OK"
- xxx := '(nil nil nil a b c d);
- (nil nil nil a b c d)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 6 dellallnils OK"
- else error(0, "Test 6 delallnils Fails!");
- "Test 6 dellallnils OK"
- xxx := '(a b c d nil nil nil);
- (a b c d nil nil nil)
- yyy := delallnils xxx;
- (a b c d)
- if yyy = '(a b c d) and yyy eq xxx
- then "Test 7 dellallnils OK"
- else error(0, "Test 7 delallnils Fails!");
- "Test 7 dellallnils OK"
- %------------------------- Exercise 4 -------------------------
- expr procedure dprin1 x;
- /* DPRIN1(X) - Print X in dotted-pair notation (to
- all levels). Returns X as its value. */
- if vectorp x then
- << prin2 "[";
- for i:=0:upbv x
- do << dprin1 x[i];
- if i < upbv x then prin2 " " >>;
- prin2 "]";
- x >>
- else if atom x then prin1 x
- else << prin2 "(";
- dprin1 car x;
- prin2 " . ";
- dprin1 cdr x;
- prin2 ")";
- x >>;
- dprin1
- % The test is hard to make because we're doing output.
- % Verify the results by hand and make sure it returns the
- % argument.
- dprin1 nil;
- nil
- nil
- dprin1 '(a . b);
- (a . b)
- (a . b)
- dprin1 '(a 1 "foo");
- (a . (1 . ("foo" . nil)))
- (a 1 "foo")
- dprin1 '(((a)));
- (((a . nil) . nil) . nil)
- (((a)))
- << x := mkvect 2; x[0] := 'a; x[1] := '(b c); x[2] := 34; >>;
- nil
- dprin1 {'(b c), x, 34};
- ((b . (c . nil)) . ([a (b . (c . nil)) 34] . (34 . nil)))
- ((b c) [a (b c) 34] 34)
- % ##### Property List Exercises #####
- %---------------------------- Exercise #1 ------------------------------
- global '(stack!*);
- nil
- expr procedure pexecute l;
- /* PEXECUTE(L) - L is a stack language. Constants are
- placed on the global stack!*, id's mean a function
- call to a function under the STACKFN property of the
- function name. Other values are placed on the stack
- without evaluation. */
- if null l then nil
- else if constantp car l then
- << stack!* := car l . stack!*;
- pexecute cdr l >>
- else if idp car l then
- if get(car l, 'STACKFN) then
- << apply(get(car l, 'STACKFN), nil);
- pexecute cdr l >>
- else error(0, {car l, "undefined function"})
- else << stack!* := car l . stack!*;
- pexecute cdr l >>;
- pexecute
- expr procedure pdiff;
- /* PADD1() - Subtract the 2nd stack elt from the
- first and replace top two entries with result. */
- stack!* := (cadr stack!* - car stack!*) . cddr stack!*;
- pdiff
- put('!-, 'STACKFN, 'pdiff);
- pdiff
- expr procedure pplus2;
- /* PPLUS2() - Pop and add the top two numbers
- on the stack and push the result. */
- stack!* := (car stack!* + cadr stack!*) . cddr stack!*;
- pplus2
- put('!+, 'STACKFN, 'pplus2);
- pplus2
- expr procedure pprint;
- /* PPRINT() - Print the top stack element. */
- print car stack!*;
- pprint
- put('PRINT, 'STACKFN, 'pprint);
- pprint
- pexecute '(3 4 !+);
- nil
- if stack!* neq '(7) then error(0, "PEXECUTE test #1 fails");
- nil
- stack!* := nil;
- nil
- pexecute '(5 3 !- 2 4 !+ !+);
- nil
- if stack!* neq '(8) then error(0, "PEXECUTE test #2 fails");
- nil
- %---------------------------- Exercise #2 ------------------------------
- expr procedure pexecute l;
- /* PEXECUTE(L) - L is a stack language. Constants are
- placed on the global stack!*, id's mean a function
- call to a function under the STACKFN property of the
- function name. Other values are placed on the stack
- without evaluation. */
- if null l then nil
- else if constantp car l then
- << stack!* := car l . stack!*;
- pexecute cdr l >>
- else if idp car l then
- if eqcar(l, 'QUOTE) then
- << stack!* := cadr l . stack!*;
- pexecute cddr l >>
- else if flagp(car l, 'STACKVAR) then
- << stack!* := get(car l, 'STACKVAL) . stack!*;
- pexecute cdr l >>
- else if get(car l, 'STACKFN) then
- << apply(get(car l, 'STACKFN), nil);
- pexecute cdr l >>
- else error(0, {car l, "undefined function"})
- else << stack!* := car l . stack!*;
- pexecute cdr l >>;
- +++ pexecute redefined
- pexecute
- expr procedure pset;
- /* PSET() - Put the second value on the stack under
- the STACKVAL attribute of the first. Flag the id as
- a STACKVAR for later use. Pop the top stack
- element. */
- << put(car stack!*, 'STACKVAL, cadr stack!*);
- flag({car stack!*}, 'STACKVAR);
- stack!* := cdr stack!* >>;
- pset
- put('SET, 'STACKFN, 'pset);
- pset
- stack!* := nil;
- nil
- pexecute '(4.5 quote x set 4 !+ x !+ PRINT);
- 13.0
- nil
- if stack!* neq '(13.0) then error(0, "Test 3 PEXECUTE fails");
- nil
- % ##### Records Exercises #####
- %------------------------- Exercise #1 -------------------------
- record qtree /* QTREE is a quad tree node element. */
- with
- node := NIL /* Node name */,
- q1 := NIL /* Child #1 */,
- q2 := NIL /* Child #2 */,
- q3 := NIL /* Child #3 */,
- q4 := NIL /* Child #4 */;
- qtree
- expr procedure qvisit q;
- /* QVISIT(Q) -- Q is a QTREE data structure or NIL as are
- each of its children. Return a preorder visit of each
- node. */
- if null q then nil
- else append({node q},
- append(qvisit q1 q,
- append(qvisit q2 q,
- append(qvisit q3 q, qvisit q4 q))));
- qvisit
- /* A simple quad tree. */
- global '(qdemo);
- nil
- qdemo := qtree(node := 'A,
- q1 := qtree(node := 'B),
- q2 := qtree(node := 'C),
- q3 := qtree(node := 'D,
- q1 := qtree(node := 'E)),
- q4 := qtree(node := 'F));
- [qtree a [qtree b nil nil nil nil] [qtree c nil nil nil nil] [qtree d [qtree e
- nil nil nil nil] nil nil nil] [qtree f nil nil nil nil]]
- if qvisit qdemo = '(A B C D E F)
- then "Test 1 qvisit OK!"
- else error(0, "Test 1 qvisit Fails!");
- "Test 1 qvisit OK!"
- /* The quadtree in the book. */
- global '(qdemo2);
- nil
- qdemo2 := qtree(node := 'A,
- q1 := qtree(node := 'B),
- q2 := qtree(node := 'C),
- q3 := qtree(node := 'D,
- q1 := qtree(node := 'E,
- q2 := qtree(node := 'F)),
- q2 := qtree(node := 'G),
- q3 := qtree(node := 'H),
- q4 := qtree(node := 'I)));
- [qtree a [qtree b nil nil nil nil] [qtree c nil nil nil nil] [qtree d [qtree e
- nil [qtree f nil nil nil nil] nil nil] [qtree g nil nil nil nil] [qtree h nil nil
- nil nil] [qtree i nil nil nil nil]] nil]
- if qvisit qdemo2 = '(A B C D E F G H I)
- then "Test 2 qvisit OK!"
- else error(0, "Test 2 qvisit Fails!");
- "Test 2 qvisit OK!"
- if qvisit nil = NIL
- then "Test 3 qvisit OK!"
- else error(0, "Test 3 qvisit Fails!");
- "Test 3 qvisit OK!"
- %------------------------- Exercise #2 -------------------------
- expr procedure qsearch(q, val, fn);
- /* QSEARCH(Q, VAL, FN) -- Returns the node path from the
- root of the quadtree Q to VAL using FN as an equality
- function whose first argument is from the tree and
- second VAL. */
- if null q then nil
- else if apply(fn, {val, node q}) then {node q}
- else begin scalar v;
- if v := qsearch(q1 q, val, fn) then return node q . v;
- if v := qsearch(q2 q, val, fn) then return node q . v;
- if v := qsearch(q3 q, val, fn) then return node q . v;
- if v := qsearch(q4 q, val, fn) then return node q . v
- end;
- qsearch
- if qsearch(qdemo, 'E, function EQ) = '(A D E)
- then "Test 1 qsearch OK!"
- else error(0, "Test 1 qsearch fails");
- "Test 1 qsearch OK!"
- if qsearch(qdemo, 'XXX, function EQ) = nil
- then "Test 2 qsearch OK!"
- else error(0, "Test 2 qsearch fails");
- "Test 2 qsearch OK!"
- if qsearch(qdemo2, 'F, function EQ) = '(A D E F)
- then "Test 3 qsearch OK!"
- else error(0, "Test 3 qsearch fails");
- "Test 3 qsearch OK!"
- %------------------------- Exercise #3 -------------------------
- record commchain
- /* A COMMCHAIN is an n-ary tree with superior and
- subordinate links. */
- with
- name := NIL /* Name of this node. */,
- superior := NIL /* Pointer to superior node. */,
- subordinates := NIL /* List of subordinates. */;
- commchain
- expr procedure backchain(l, sup);
- /* BACKCHAIN(L, SUP) -- Fill in the SUPERIOR fields of
- each record in the n-ary tree (links in the SUBORDINATES
- field) to the lowest level. SUP is the current
- superior. */
- if null l then nil
- else << superior l := sup;
- for each sb in subordinates l
- do backchain(sb, l) >>;
- backchain
- /* Demo the back chain. */
- global '(cch);
- nil
- cch :=
- commchain(
- name := 'TOP,
- subordinates :=
- {commchain(name := 'LEV1-A),
- commchain(
- name := 'LEV1-B,
- subordinates :=
- {commchain(name := 'LEV2-A),
- commchain(name := 'LEV2-B)}),
- commchain(name := 'LEV1-C)});
- [commchain top nil ([commchain lev1!-a nil nil] [commchain lev1!-b nil ([
- commchain lev2!-a nil nil] [commchain lev2!-b nil nil])] [commchain lev1!-c nil
- nil])]
- % Wrap this up to avoid printing problems.
- << backchain(cch, 'COMMANDER); NIL >>;
- nil
- if superior cch EQ 'COMMANDER
- then "Test 1 backchain OK!"
- else error(0, "Test 1 backchain Fails!");
- "Test 1 backchain OK!"
- if name superior car subordinates cch EQ 'TOP
- then "Test 2 backchain OK!"
- else error(0, "Test 2 backchain Fails!");
- "Test 2 backchain OK!"
- if name superior car subordinates cadr subordinates cch
- eq 'LEV1-B
- then "Test 3 backchain OK!"
- else error(0, "Test 3 backchain Fails!");
- "Test 3 backchain OK!"
- % ##### Local Variable Exercises #####
- %------------------------- Exercise #1 -------------------------
- expr procedure lookup(v, a);
- /* LOOKUP(V, A) -> Look for V in A and signal an error if not present.*/
- (if rv then cdr rv else error(0, {v, "not in association list"}))
- where rv := assoc(v, a);
- lookup
- if lookup('a, '((a . b) (c . d))) = 'b
- then "Test 1 lookup success"
- else error(0, "Test 1 lookup fails");
- "Test 1 lookup success"
- if errorset(quote lookup('f, '((a . b) (c . d))), nil, nil) = 0
- then "Test 2 lookup success"
- else error(0, "Test 2 lookup fails");
- "Test 2 lookup success"
- %------------------------- Exercise #2 -------------------------
- expr procedure quadratic(a, b, c);
- /* QUADRATIC(A, B, C) -- Returns both solutions of the
- quadratic equation A*X^2 + B*X + C */
- {(-B + U) / V, (-B - U) / V}
- where U := SQRT(B^2 - 4*A*C),
- V := 2.0 * A;
- quadratic
- if quadratic(1.0, 2.0, 1.0) = '(-1.0 -1.0)
- then "Test 1 quadratic OK!"
- else error(0, "Test 1 quadratic Fails!");
- "Test 1 quadratic OK!"
- if quadratic(1.0, 0.0, -1.0) = '(1.0 -1.0)
- then "Test 2 quadratic OK!"
- else error(0, "Test 2 quadratic Fails!");
- "Test 2 quadratic OK!"
- %------------------------- Exercise #3 -------------------------
- expr procedure lineintersection(x1, y1,
- x2, y2,
- x3, y3,
- x4, y4);
- /* LINEINTERSECTION(X1,Y1,X2,Y2,X3,Y3,X4,Y4) -
- Computes the intersection of line X1,Y1 ->
- X2,Y2 with X3,Y3 -> X4,Y4 if any. Returns NIL
- if no such intersection. */
- (if zerop denom or zerop d1 or zerop d2 then nil
- else
- ((if p1 < 0 or p1 > d1 or p2 < 0 or p2 > d2
- then nil
- else (x1 + (x2 - x1) * p1 / d1) .
- (y1 + (y2 - y1) * p1 / d1))
- where p1 := num1 / denom,
- p2 := num2 / denom)
- where
- num1 := d1*(x1*y3 - x1*y4 - x3*y1 + x3*y4
- + x4*y1 - x4*y3),
- num2 := d2*(- x1*y2 + x1*y3 + x2*y1 - x2*y3
- - x3*y1 + x3*y2))
- where d1 :=sqrt((x2 - x1)^2 + (y2 - y1)^2),
- d2 := sqrt((x4 - x3)^2 + (y4 - y3)^2),
- denom := x1*y3 - x1*y4 - x2*y3 + x2*y4
- - x3*y1 + x3*y2 + x4*y1 - x4*y2;
- lineintersection
- if lineintersection(1, 1, 3, 3, 1, 2, 5, 2) = '(2.0 . 2.0)
- then "Test 1 LINEINTERSECTION success!"
- else error(0, "Test 1 LINEINTERSECTION fails intersect test");
- "Test 1 LINEINTERSECTION success!"
- % intersection at start and end points.
- if lineintersection(1, 1, 2, 2, 1, 1, 1, 0) = '(1.0 . 1.0)
- then "Test 2 LINEINTERSECTION success!"
- else error(0, "Test 2LINEINTERSECTION fails intersect at start test");
- "Test 2 LINEINTERSECTION success!"
- if lineintersection(1, 1, 2, 2, 0, 1, 2, 2) = '(2.0 . 2.0)
- then "Test 3 LINEINTERSECTION success!"
- else error(0,
- "Test 3 LINEINTERSECTION fails intersect at endpoint test");
- "Test 3 LINEINTERSECTION success!"
- if lineintersection(1, 1, 2, 2, 2, 2, 3, 4) = '(2.0 . 2.0)
- then "Test 4 LINEINTERSECTION success!"
- else error(0,
- "Test 4 LINEINTERSECTION fails intersect end - begin point test");
- "Test 4 LINEINTERSECTION success!"
- % Now try no intersection test.
- if null lineintersection(1, 1, 2, 3, 2, 4, 4, 5)
- then "Test 5 LINEINTERSECTION success!"
- else error(0,
- "Test 5 LINEINTERSECTION fails quadrant 1 no intersection");
- "Test 5 LINEINTERSECTION success!"
- if null lineintersection(1, 1, 2, 2, 1.75, 1.5, 5, 1.75)
- then "Test 6 LINEINTERSECTION success!"
- else error(0,
- "Test 6 LINEINTERSECTION fails quadrant 2 no intersection");
- "Test 6 LINEINTERSECTION success!"
- %------------------------- Exercise #4 -------------------------
- expr procedure stdev x;
- /* STDEV(X) - compute the standard deviation of the
- numbers in list X. */
- if null x then 0
- else (sqrt((for each v in x sum (v - avg)^2) / n)
- where avg := (for each v in x sum v) / n)
- where n := length x;
- stdev
- if stdev '(3.0 3.0 3.0) neq 0.0 then
- error(0, "Test 1 STDEV fails");
- nil
- % ##### Array Exercises #####
- %------------------------- Exercise #1 -------------------------
- expr procedure vaverage v;
- /* VAVERAGE(V) -- compute the average of all numeric
- elements of the vector v. */
- (if cnt > 0 then
- ((for i:=0:upbv v when numberp v[i] sum v[i]) / float cnt)
- else 0.0)
- where cnt := for i:=0:upbv v count numberp v[i];
- vaverage
- if vaverage array(1,2,3) = 2.0
- then "Test 1 vaverage is OK"
- else error(0, "Test 1 vaverage fails");
- "Test 1 vaverage is OK"
- if vaverage array(3, 'a, 3, 6.0, 'f) = 4.0
- then "Test 2 vaverage is OK"
- else error(0, "Test 2 vaverage fails");
- "Test 2 vaverage is OK"
- if vaverage array('a, 'b) = 0.0
- then "Test 3 vaverage is OK"
- else error(0, "Test 3 vaverage fails");
- "Test 3 vaverage is OK"
- %------------------------- Exercise #2 -------------------------
- expr procedure MAPPEND(a, b);
- /* MAPPEND(A, B) -- Appends array B to array A and
- returns a new array with both. */
- begin scalar c, ua;
- c := mkvect((ua := 1 + upbv a) + upbv b);
- for i:=0:upbv a do c[i] := a[i];
- for i:=0:upbv b do c[i + ua] := b[i];
- return c
- end;
- +++ mappend redefined
- mappend
- global '(a1 a2);
- nil
- a1 := array(1, 2, 3);
- [1 2 3]
- a2 := array(3, 4, 5, 6);
- [3 4 5 6]
- if mappend(a1, a2) = array(1,2,3,3,4,5,6)
- then "Test 1 MAPPEND is OK"
- else error(0, "Test 1 MAPPEND fails");
- "Test 1 MAPPEND is OK"
- if mappend(mkvect 0, mkvect 0) = mkvect 1
- then "Test 2 MAPPEND is OK"
- else error(0, "Test 2 MAPPEND fails");
- "Test 2 MAPPEND is OK"
- %------------------------- Exercise #3 -------------------------
- expr procedure indx(a, v);
- /* INDX(A, V) -- returns index of A in V using EQ test,
- otherwise NIL. */
- for i:=0:upbv v
- until a eq v[i]
- returns if i <= upbv v then i
- if indx('a, array(1, 2, 'a, 34)) = 2
- then "Test 1 indx OK"
- else error(0, "Test 1 indx fails");
- indx
- if null indx('a, array(1, 2, 3, 4))
- then "Test 2 indx OK"
- else error(0, "Test 2 indx fails");
- "Test 2 indx OK"
- %------------------------- Exercise #4 -------------------------
- expr procedure mpy4x4(a, b);
- /* MPY4X4(A, B) -- Create a new 4x4 matrix and return with
- the product of A and B in it. */
- for row:=0:3
- with c, s
- initially c := mkarray(3,3)
- do << for col := 0:3 do
- do c[row,col] :=
- for p := 0:3 sum a[row,p] * b[p,col] >>
- returns c;
- mpy4x4
- expr procedure translate4x4(x, y, z);
- /* TRANSLATE4X4(X, Y, Z) -- Generate and return a
- 4x4 matrix to translate X, Y, Z. */
- array(array(1.0, 0.0, 0.0, 0.0),
- array(0.0, 1.0, 0.0, 0.0),
- array(0.0, 0.0, 1.0, 0.0),
- array(x, y, z, 1.0));
- translate4x4
- expr procedure rotatex4x4 th;
- /* ROTATEX4X4(TH) -- Generate a 4x4 rotation matrix about
- the X axis, TH radians. */
- array(array(1.0, 0.0, 0.0, 0.0),
- array(0.0, cos th, -sin th, 0.0),
- array(0.0, sin th, cos th, 0.0),
- array(0.0, 0.0, 0.0, 1.0));
- rotatex4x4
- expr procedure mappoint(x, y, z, m);
- /* MAPPOINT(X, Y, Z, M) -- Returns the transformed point
- X, Y, Z by the 4x4 matrix M. */
- {x*m[0,0] + y*m[1,0] + z*m[2,0] + m[3,0],
- x*m[0,1] + y*m[1,1] + z*m[2,1] + m[3,1],
- x*m[0,2] + y*m[1,2] + z*m[2,2] + m[3,2]};
- mappoint
- /* tmat is test matrix to rotate about x. In our tests we
- have to construct the resulting numbers on the fly
- because when input, they aren't the same for EQUAL. */
- global '(tmat);
- nil
- tmat := rotatex4x4(45.0 / 57.29577);
- [[1.0 0.0e+000 0.0e+000 0.0e+000] [0.0e+000 0.70710668897748 -0.7071068733956
- 0.0e+000] [0.0e+000 0.7071068733956 0.70710668897748 0.0e+000] [0.0e+000 0.0e+000
- 0.0e+000 1.0]]
- if mappoint(0.0, 0.0, 0.0, tmat) = '(0.0 0.0 0.0)
- then "Test 1 4x4 OK"
- else error(0, "Test 1 4x4 failed");
- "Test 1 4x4 OK"
- if mappoint(1.0, 0.0, 0.0, tmat) = '(1.0 0.0 0.0)
- then "Test 2 4x4 OK"
- else error(0, "Test 2 4x4 failed");
- "Test 2 4x4 OK"
- if mappoint(0.0, 1.0, 0.0, tmat) =
- {0.0, cos(45.0 / 57.29577), - sin(45.0 / 57.29577)}
- then "Test 3 4x4 OK"
- else error(0, "Test 3 4x4 failed");
- "Test 3 4x4 OK"
- if mappoint(1.0, 1.0, 0.0, tmat) =
- {1.0, cos(45.0 / 57.29577), - sin(45.0 / 57.29577)}
- then "Test 4 4x4 OK"
- else error(0, "Test 4 4x4 failed");
- "Test 4 4x4 OK"
- if mappoint(0.0, 0.0, 1.0, tmat) =
- {0.0, sin(45.0 / 57.29577), cos(45.0 / 57.29577)}
- then "Test 5 4x4 OK"
- else error(0, "Test 5 4x4 failed");
- "Test 5 4x4 OK"
- if mappoint(1.0, 0.0, 1.0, tmat) =
- {1.0, sin(45.0 / 57.29577), cos(45.0 / 57.29577)}
- then "Test 6 4x4 OK"
- else error(0, "Test 6 4x4 failed");
- "Test 6 4x4 OK"
- if mappoint(0.0, 1.0, 1.0, tmat) =
- {0.0, cos(45.0 / 57.29577) + sin(45.0 / 57.29577),
- cos(45.0 / 57.29577) - sin(45.0 / 57.29577)}
- then "Test 7 4x4 OK"
- else error(0, "Test 7 4x4 failed");
- "Test 7 4x4 OK"
- if mappoint(1.0, 1.0, 1.0, tmat) =
- {1.0, cos(45.0 / 57.29577) + sin(45.0 / 57.29577),
- cos(45.0 / 57.29577) - sin(45.0 / 57.29577)}
- then "Test 8 4x4 OK"
- else error(0, "Test 8 4x4 failed");
- "Test 8 4x4 OK"
- /* Now try the multiplication routine. */
- tmat := mpy4x4(rotatex4x4(45.0 / 57.29577),
- translate4x4(1.0, 2.0, 3.0));
- [[1.0 0.0e+000 0.0e+000 0.0e+000] [0.0e+000 0.70710668897748 -0.7071068733956
- 0.0e+000] [0.0e+000 0.7071068733956 0.70710668897748 0.0e+000] [1.0 2.0 3.0 1.0]
- ]
- if mappoint(0.0, 0.0, 0.0, tmat) = '(1.0 2.0 3.0)
- then "Test 9 4x4 OK"
- else error(0, "Test 9 4x4 failed");
- "Test 9 4x4 OK"
- if mappoint(0.0, 0.0, 1.0, tmat) =
- {1.0, 2.0 + sin(45.0 / 57.29577),
- 3.0 + cos(45.0 / 57.29577)}
- then "Test 10 4x4 OK"
- else error(0, "Test 10 4x4 failed");
- "Test 10 4x4 OK"
-
- %------------------------- Exercise 4 -------------------------
- expr procedure ltident n;
- /* LTIDENT(N) -- Create and return a lower triangular,
- square, identity matrix with N+1 rows. */
- for i:=0:n
- with a
- initially a := mkvect n
- do << a[i] := mkvect i;
- for j:=0:i - 1 do a[i,j] := 0.0;
- a[i,i] := 1.0 >>
- returns a;
- ltident
- expr procedure ltmpy(a, b);
- /* LTMPY(A, B) -- Compute the product of two square,
- lower triangular matrices of the same size and return.
- Note that the product is also lower triangular. */
- (for i:=0:rows
- with c
- initially c := mkvect rows
- do << c[i] := mkvect i;
- for j:=0:i do
- c[i,j] := for k:=j:i sum a[i,k] * b[k,j] >>
- returns c)
- where rows := upbv a;
- ltmpy
- if ltident 2 = array(array(1.0),
- array(0.0, 1.0),
- array(0.0, 0.0, 1.0))
- then "Test 1 ltident OK"
- else "Test 1 ltident fails";
- "Test 1 ltident OK"
- if ltident 0 = array(array(1.0))
- then "Test 2 ltident OK"
- else "Test 2 ltident fails";
- "Test 2 ltident OK"
- if ltmpy(ltident 2, ltident 2) = ltident 2
- then "Test 3 ltident OK"
- else "Test 3 ltident fails";
- "Test 3 ltident OK"
- if ltmpy(array(array(1.0),
- array(1.0, 2.0),
- array(1.0, 2.0, 3.0)),
- array(array(1.0),
- array(1.0, 2.0),
- array(1.0, 2.0, 3.0))) =
- array(array(1.0),
- array(3.0, 4.0),
- array(6.0, 10.0, 9.0))
- then "Test 4 ltmpy OK"
- else error(0, "Test 4 ltmpy fails");
- "Test 4 ltmpy OK"
- if ltmpy(array(array(1.2),
- array(3.4, 5.0),
- array(1.0,-2.3,-1.3)), ltident 2)
- = array(array(1.2),
- array(3.4, 5.0),
- array(1.0, -2.3, -1.3))
- then "Test 5 ltmpy OK"
- else error(0, "Test 5 ltmpy fails");
- "Test 5 ltmpy OK"
-
- %------------------------- Exercise #5 -------------------------
- expr procedure coerce(a, b, pth, cmat);
- /* COERCE(A,B,PTH,CMAT) -- return a list of functions
- to coerce type A (an index into CMAT) into type B. PTH
- is NIL to start and CMAT the coercion table arranged
- with "from" type as rows, "to" type as columns. */
- if cmat[a,b] then cmat[a,b] . pth
- else
- for j:=0:upbv cmat[a]
- with cp
- until j neq a and cmat[a,j] and
- not (cmat[a,j] memq pth) and
- not(cmat[j,a] memq pth) and
- (cp := coerce(j, b, cmat[a,j] . pth, cmat))
- returns cp;
- coerce
- /* Create the coercion array. Here int=0, string=1,
- float=2, complex=3, and gaussian=4 */
- global '(cpath);
- nil
- cpath :=
- array(array('ident, 'int2str, 'float, nil, nil),
- array('str2int, 'ident, 'str2flt, nil, nil),
- array('fix, 'flt2str, 'ident, 'flt2cplx,nil),
- array(nil, nil, nil, 'ident, 'cfix),
- array(nil, nil, nil, 'cfloat, 'ident));
- [[ident int2str float nil nil] [str2int ident str2flt nil nil] [fix flt2str ident
- flt2cplx nil] [nil nil nil ident cfix] [nil nil nil cfloat ident]]
- % Coerce int to complex.
- if coerce(0, 3, nil, cpath) = '(FLT2CPLX STR2FLT INT2STR)
- then "Test 1 coerce OK"
- else error(0, "Test 1 coerce fails");
- "Test 1 coerce OK"
- % Coerce Complex into int.
- if coerce(3, 0, nil, cpath) = NIL
- then "Test 2 coerce OK"
- else error(0, "Test 2 coerce fails");
- "Test 2 coerce OK"
- % Coerce int into gaussian.
- if coerce(0, 4, nil, cpath) =
- '(CFIX FLT2CPLX STR2FLT INT2STR)
- then "Test 3 coerce OK"
- else error(0, "Test 3 coerce fails");
- "Test 3 coerce OK"
-
-
- %------------------------- Exercise #6 -------------------------
- expr procedure cellvon(a, b, fn);
- /* CELLVON(A, B, FN) -- Compute the next generation of the
- cellular matrix A and place it into B. Use the VonNeumann
- neighborhood and the function FN to compute the next
- generation. The space edges are wrapped into a torus*/
- for r:=0:rows
- with rows, cols
- initially << rows := upbv a; cols := upbv a[1] >>
- do for c:=0:cols
- do b[r,c] := apply(fn,
- {a[r,c],
- a[torus(r + 1, rows), torus(c - 1, cols)],
- a[torus(r + 1, rows), c],
- a[torus(r + 1, rows), torus(c + 1, cols)],
- a[r, torus(c + 1, cols)],
- a[torus(r - 1, rows), torus(c + 1, cols)],
- a[torus(r - 1, rows), c],
- a[torus(r - 1, rows), torus(c - 1, cols)],
- a[r, torus(c - 1, cols)]});
- cellvon
- expr procedure torus(i, v);
- /* TORUS(I, V) -- A positive modulus: if I is less than
- 0, wrap to V, or if it exceeds V, wrap to I. */
- if i < 0 then v
- else if i > v then 0
- else i;
- torus
- expr procedure life(c, n1, n2, n3, n4, n5, n6, n7, n8);
- /* LIFE(C, N1 ... N8) -- Game of life rules. Here C is
- the cell being examined and N1-N8 are the VonNeumann
- neighbor states. */
- (if c = 1 then if cnt = 2 or cnt = 3 then 1 else 0
- else if cnt = 3 then 1 else 0)
- where cnt = n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8;
- life
- /* LIFESTATES contains a vector of states and what
- character to print. */
- global '(LIFESTATES);
- nil
- LIFESTATES := array(" ", "*");
- [" " "*"]
- expr procedure pcell(gen, a, pr);
- /* PCELL(GEN, A) -- Display the state of the GEN generation
- of the cellular matrix A. Display a * for state=1, and
- a blank for state 0. */
- for r:=0:rows
- with rows, cols
- initially << rows := upbv a; cols := upbv a[1];
- terpri(); prin2 "Generation: "; print gen >>
- do << terpri();
- for c:=0:cols do prin2 pr[a[r,c]] >>;
- pcell
- expr procedure rungame(a, n, fn, pr);
- /* RUNGAME(A, N, FN, PR) -- Run through N generations
- starting with the cellular matrix A and using the
- function FNto compute the new generation. Use the array
- PR to display the state. */
- for i:=1:n
- with tmp, b
- initially b := mkarray(upbv a, upbv a[1])
- do << pcell(i, a, pr);
- cellvon(a, b, function life);
- tmp := a; a := b; b := tmp >>;
- *** local variable fn in procedure rungame not used
- rungame
-
- /* SEED is the seed array with 1's for on state, 0 for
- off. */
- global '(seed);
- nil
- seed := array(
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 1, 0, 0, 0),
- array(0, 0, 0, 0, 1, 1, 1, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- array(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 0 0 0 0 0] [0 0 0 0 0 1 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 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]]
- rungame(seed, 10, function life, LIFESTATES);
- Generation: 1
-
-
-
- *
- *
- ***
-
-
-
-
- Generation: 2
-
-
-
-
- * *
- **
- *
-
-
-
- Generation: 3
-
-
-
-
- *
- * *
- **
-
-
-
- Generation: 4
-
-
-
-
- *
- **
- **
-
-
-
- Generation: 5
-
-
-
-
- *
- *
- ***
-
-
-
- Generation: 6
-
-
-
-
-
- * *
- **
- *
-
-
- Generation: 7
-
-
-
-
-
- *
- * *
- **
-
-
- Generation: 8
-
-
-
-
-
- *
- **
- **
-
-
- Generation: 9
-
-
-
-
-
- *
- *
- ***
-
-
- Generation: 10
-
-
-
-
-
-
- * *
- **
- *
-
- nil
- %------------------------- Exercise #7 -------------------------
- expr procedure compact heap;
- /* compact(HEAP) -- HEAP is an array of blocks of
- sequentially allocated items. The first entry in each
- block is INUSE, the second the total number of entries
- + 2 (for the header). The remainder are random values.
- Free blocks are the same but instead have the header
- FREE. Returns a compacted structure with a single FREE
- entry at the end with entries changed to *. Returns the
- number of free entries. */
- begin scalar dest, src, last, u;
- last := dest := src := 0;
- loop: if src > upbv heap then
- if src = dest then return 0
- else << heap[dest] := 'FREE;
- heap[dest+1] := src - dest;
- for i:=dest+2:upbv heap do heap[i] := '!*;
- return heap[dest+1] >>;
- if heap[src] eq 'FREE then
- src := heap[src+1] + src
- else << u := heap[src+1] + src - 1;
- for i:=src:u do << heap[dest] := heap[i];
- dest := dest + 1 >>;
- src := u + 1 >>;
- go to loop
- end;
- compact
- /* A simple array to test. */
- global '(H);
- nil
- H := array('INUSE, 3, 0,
- 'FREE, 4, '!*, '!*,
- 'INUSE, 4, 0, 1,
- 'FREE, 3, '!*,
- 'FREE, 5, '!*, '!*, '!*,
- 'INUSE, 5, 0, 1, 2,
- 'INUSE, 5, 3, 4, 5);
- [inuse 3 0 free 4 !* !* inuse 4 0 1 free 3 !* free 5 !* !* !* inuse 5 0 1 2 inuse
- 5 3 4 5]
- if compact H = 12
- then "Test 1 compact OK!"
- else error(0, "Test 1 compact fails!");
- "Test 1 compact OK!"
- if H = array('INUSE, 3, 0, 'INUSE, 4, 0, 1, 'INUSE,
- 5, 0, 1, 2, 'INUSE, 5, 3, 4, 5,
- 'FREE, 12, '!*, '!*, '!*, '!*, '!*, '!*,
- '!*, '!*, '!*, '!*)
- then "Test 2 compact OK!"
- else error(0, "Test 2 compact fails!");
- "Test 2 compact OK!"
- /* Test a completely full one. */
- H := array('INUSE, 3, 0, 'INUSE, 5, 1, 2, 3);
- [inuse 3 0 inuse 5 1 2 3]
- if compact H = 0
- then "Test 3 compact OK!"
- else error(0, "Test 3 compact fails!");
- "Test 3 compact OK!"
- if H = array('INUSE, 3, 0, 'INUSE, 5, 1, 2, 3)
- then "Test 4 compact OK!"
- else error(0, "Test 4 compact fails!");
- "Test 4 compact OK!"
- /* Test a completely empty one. */
- H := array('FREE, 3, '!*, 'FREE, 5, '!*, '!*, '!*);
- [free 3 !* free 5 !* !* !*]
- if compact H = 8
- then "Test 5 compact OK!"
- else error(0, "Test 5 compact fails!");
- "Test 5 compact OK!"
- if H = array('FREE, 8, '!*, '!*, '!*, '!*, '!*, '!*)
- then "Test 6 compact OK!"
- else error(0, "Test 6 compact fails!");
- "Test 6 compact OK!"
- %------------------------- Exercise #8 -------------------------
- expr procedure HISTOGRAM(v, n);
- /* HISTOGRAM(V,N) -- V is an arbitrarily size vector of
- numbers. Compute its an N element histogram over its
- range and return it. */
- begin scalar minv, maxv, h, range;
- minv := maxv := v[0];
- for i:=1:upbv v
- do << if v[i] < minv then minv := v[i];
- if v[i] > maxv then maxv := v[i] >>;
- range := maxv - minv;
- h := mkvect(n - 1);
- for i:=0:n - 1 do h[i] := 0;
- for i:=0:upbv v
- with hn
- do << hn := fix(n * (v[i] - minv) / range);
- if hn = n then hn := hn - 1;
- h[hn] := h[hn] + 1 >>;
- return h
- end;
- histogram
- global '(v1);
- nil
- << v1 := mkvect 100;
- for i:=0:100 do v1[i] := float i >>;
- nil
- if HISTOGRAM(v1, 1) = array(101)
- then "Test 1 HISTOGRAM OK!"
- else error(0, "Test 1 HISTOGRAM Fails!");
- "Test 1 HISTOGRAM OK!"
- if HISTOGRAM(v1, 2) = array(50, 51)
- then "Test 2 HISTOGRAM OK!"
- else error(0, "Test 2 HISTOGRAM Fails!");
- "Test 2 HISTOGRAM OK!"
- if HISTOGRAM(v1, 7) = array(15, 14, 14, 15, 14, 14, 15)
- then "Test 3 HISTOGRAM OK!"
- else error(0, "Test 3 HISTOGRAM Fails!");
- "Test 3 HISTOGRAM OK!"
- %------------------------- Exercise #9 -------------------------
- expr procedure rarray n;
- /* RARRAY(N) - generate an NxN matrix with uniform
- distribution random numbers in the range 0.0 -> 1.0. */
- for x:=0:n
- with a
- initially a := mkarray(n,n)
- returns a
- do for y:=0:n do a[x,y] := random(1000) / 1000.0;
- rarray
- if upbv rarray 4 = 4
- then "Test 1 rarray OK"
- else error(0, "Test 1 rarray fails");
- "Test 1 rarray OK"
- expr procedure addcircle(a, r, xc, yc, v);
- /* ADDCIRCLE(A, R, XC, YC, V) -- Add V to each cell within
- distance R from center point XC, YC and return a new
- matrix with these values. Values always remain in the
- range 0.0 -> 1.0. */
- begin scalar uax, uay, b;
- b := mkarray(uax := upbv a, uay := upbv a[0]);
- for x:=0:uax do
- for y:=0:uay do
- b[x,y] := if sqrt((x - xc)^2 + (y - yc)^2) <= r
- then min(1.0, v + a[x,y]) else a[x,y];
- return b
- end;
- addcircle
- global '(xxx);
- nil
- xxx := array(array(0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0),
- array(0, 0, 0, 0, 0),
- array(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]]
- % This will fail if sqrt isn't very accurate.
- if addcircle(xxx, 2.0, 2, 2, 0.75) =
- array(array(0, 0, 0.75, 0, 0),
- array(0, 0.75, 0.75, 0.75, 0),
- array(0.75, 0.75, 0.75, 0.75, 0.75),
- array(0, 0.75, 0.75, 0.75, 0),
- array(0, 0, 0.75, 0, 0))
- then "Test 1 addcircle OK!"
- else error(0, "Test 1 addcircle fails!");
- "Test 1 addcircle OK!"
- if addcircle(xxx, 10.0, 2, 2, 0.75) =
- array(array(0.75, 0.75, 0.75, 0.75, 0.75),
- array(0.75, 0.75, 0.75, 0.75, 0.75),
- array(0.75, 0.75, 0.75, 0.75, 0.75),
- array(0.75, 0.75, 0.75, 0.75, 0.75),
- array(0.75, 0.75, 0.75, 0.75, 0.75))
- then "Test 2 addcircle OK!"
- else error(0, "Test 2 addcircle fails!");
- "Test 2 addcircle OK!"
- %------------------------- Exercise #10 -------------------------
- expr procedure areaaverage(a, n);
- /* AREAAVERAGE(A, N) -- Compute the average of the NxN
- neighborhood of each cell in the matrix A and return a
- new matrix with these values. */
- begin scalar uax, uay, sm, cnt, b, n2;
- n2 := n / 2;
- b := mkarray(uax := upbv a, uay := upbv a[1]);
- for x := 0:uax do
- for y := 0:uay do
- << sm := 0.0;
- cnt := 0;
- for xp := max(0, x - n2):min(uax, x + n2) do
- for yp := max(0, y - n2):min(uay, y + n2) do
- << sm := sm + a[xp,yp];
- cnt := cnt + 1 >>;
- b[x,y] := sm / cnt >>;
- return b
- end;
- areaaverage
- global '(ninth);
- nil
- xxx[2,2] := 1.0;
- 1.0
- ninth := 1.0 / 9.0;
- 0.11111111111111
- if areaaverage(xxx, 3) =
- array(array(0.0, 0.0, 0.0, 0.0, 0.0),
- array(0.0, ninth, ninth, ninth, 0.0),
- array(0.0, ninth, ninth, ninth, 0.0),
- array(0.0, ninth, ninth, ninth, 0.0),
- array(0.0, 0.0, 0.0, 0.0, 0.0))
- then "Test 1 areaaverage OK!"
- else error(0, "Test 1 areaaverage Fails!");
- "Test 1 areaaverage OK!"
- %------------------------- Exercise #11 -------------------------
- expr procedure laplace a;
- /* LAPLACE(A) -- Compute the Laplacian on A but assuming
- 0.0 at the borders. Returns a new array the same size
- as A. */
- begin scalar uax, uay, b, sm;
- b := mkarray(uax := upbv a, uay := upbv a[0]);
- for x := 0:uax do
- for y := 0:uay do
- << sm := 0.0;
- for xp := max(0, x - 1):min(uax, x + 1)
- when xp neq x do
- for yp := max(0, y - 1):min(uay, y + 1)
- when yp neq y
- do sm := sm + a[xp,yp];
- b[x,y] := max(0.0, min(5.0 * a[x,y] - sm, 1.0)) >>;
- return b
- end;
- laplace
- xxx := array(array(0,0,0,0,0),
- array(0,1,1,1,0),
- array(0,1,1,1,0),
- array(0,1,1,1,0),
- array(0,0,0,0,0));
- [[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]]
- if laplace xxx = array(array(0.0, 0.0, 0.0, 0.0, 0.0),
- array(0.0, 1.0, 1.0, 1.0, 0.0),
- array(0.0, 1.0, 1.0, 1.0, 0.0),
- array(0.0, 1.0, 1.0, 1.0, 0.0),
- array(0.0, 0.0, 0.0, 0.0, 0.0))
- then "Test 1 laplace OK!"
- else error(0, "Test 1 laplace fails!");
- "Test 1 laplace OK!"
- %------------------------- Exercise #12 -------------------------
- expr procedure threshold(a, vl, vh);
- /* THRESHOLD(A, VL, VH) -- Returns a new matrix of the same
- size as A with each cell set to 1.0 that is
- VL <= A(i,j) <= VH. Others are set to 0.0. */
- for x := 0:uax
- with uax, uay, b
- initially b := mkarray(uax := upbv a,
- uay := upbv a[0])
- returns b
- do for y := 0:uay
- do b[x,y] :=
- if a[x,y] >= vl and a[x,y] <= vh then 1.0
- else 0.0;
- threshold
- xxx := mkarray(4,4);
- [[nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil nil nil] [nil nil nil
- nil nil] [nil nil nil nil nil]]
- for i:=0:4 do for j:=0:4 do xxx[i,j] := i * j;
- nil
- if threshold(xxx, 8, 10) = array(
- array(0.0, 0.0, 0.0, 0.0, 0.0),
- array(0.0, 0.0, 0.0, 0.0, 0.0),
- array(0.0, 0.0, 0.0, 0.0, 1.0),
- array(0.0, 0.0, 0.0, 1.0, 0.0),
- array(0.0, 0.0, 1.0, 0.0, 0.0))
- then "Test 1 threshold OK!"
- else error(0, "Test 1 threshold Fails!");
- "Test 1 threshold OK!"
- expr procedure dump(a, f);
- /* DUMP(A,F) -- Dump an array A into a PicTex format
- file for document processing. */
- begin scalar fh;
- fh := wrs open(f, 'output);
- for x:=0:upbv a do
- for y:=0:upbv a[0] do
- printf("\setshadegrid span <%wpt>%n\vshade %d %d %d %d %d %d /%n",
- max(0.5, 5.5 - a[x,y]*5.0),
- x, y, y+1, x+1, y, y+1);
- close wrs fh;
- end;
- dump
- % ##### Macro Exercises #####
- %------------------------- Exercise -----------------------
- macro procedure appendl x;
- /* APPENDL( ...) - append all the lists together. */
- expand(cdr x, 'append);
- appendl
- if appendl('(a b), '(c d), '(e f)) = '(a b c d e f)
- then "Test 1 appendl OK!"
- else error(0, "Test 1 appendl fails!");
- "Test 1 appendl OK!"
- if appendl '(a b c) = '(a b c)
- then "Test 2 appendl OK!"
- else error(0, "Test 2 appendl fails!");
- "Test 2 appendl OK!"
- if appendl nil = nil
- then "Test 3 appendl OK!"
- else error(0, "Test 3 appendl fails!");
- "Test 3 appendl OK!"
- %------------------------- Exercise ------------------------
- macro procedure nconcl x;
- /* NCONCL(...) - destructive concatenation of all the
- lists. */
- expand(cdr x, 'nconc);
- nconcl
- global '(b1 b2 b3);
- nil
- b1 := '(a b);
- (a b)
- b2 := '(c d);
- (c d)
- b3 := '(e f);
- (e f)
- if nconcl(b1, b2, b3) = '(a b c d e f)
- then "Test 1 nconcl OK!"
- else error(0, "Test 1 nconcl fails!");
- "Test 1 nconcl OK!"
- if b1 = '(a b c d e f)
- then "Test 2 nconcl OK!"
- else error(0, "Test 2 nconcl fails!");
- "Test 2 nconcl OK!"
- if b2 = '(c d e f)
- then "Test 3 nconcl OK!"
- else error(0, "Test 3 nconcl fails!");
- "Test 3 nconcl OK!"
- if b3 = '(e f)
- then "Test 4 nconcl OK!"
- else error(0, "Test 4 nconcl fails!");
- "Test 4 nconcl OK!"
- %------------------------- Exercise ------------------------
- smacro procedure d(x1, y1, x2, y2);
- /* D(X1, Y1, X2, Y2) - Euclidean distance between points
- (X1,Y1) -> (X2,Y2) */
- sqrt((x1 - x2)^2 + (y1 - y2)^2);
- d
- % This fails with poor sqrt.
- if d(0, 0, 3, 4) = 5.0
- then "Test 1 d OK!"
- else error(0, "Test 1 d Fails!");
- "Test 1 d OK!"
- if d(0, 0, 1, 1) = sqrt 2
- then "Test 2 d OK!"
- else error(0, "Test 2 d Fails!");
- "Test 2 d OK!"
- %------------------------- Exercise -------------------------
- macro procedure pop x;
- /* POP(X) - Assuming X is an identifier, pop the stack
- and return the popped value. */
- (`(prog (!$V!$)
- (setq !$V!$ (car #v))
- (setq #v (cdr #v))
- (return !$V!$))) where v := cadr x;
- pop
- xxx := '(A B);
- (a b)
- if pop xxx eq 'A
- then "Test 1 POP ok!"
- else error(0, "Test 1 POP fails!");
- "Test 1 POP ok!"
- if xxx = '(B)
- then "Test 1 POP ok!"
- else error(0, "Test 1 POP fails!");
- "Test 1 POP ok!"
- if pop xxx eq 'B
- then "Test 2 POP ok!"
- else error(0, "Test 2 POP fails!");
- "Test 2 POP ok!"
- if xxx eq NIL
- then "Test 2 POP ok!"
- else error(0, "Test 2 POP fails!");
- "Test 2 POP ok!"
- %------------------------- Exercise -------------------------
- macro procedure push x;
- /* PUSH(ST, V) - push V onto ST (an identifier) and
- return V. */
- `(progn (setq #st (cons #v #st))
- #v)
- where st := cadr x,
- v := caddr x;
- push
- if push(xxx, 'A) = 'A
- then "Test 1 push OK!"
- else error(0, "Test 1 push fails");
- "Test 1 push OK!"
- if xxx = '(A)
- then "Test 1 push OK!"
- else error(0, "Test 1 push fails");
- "Test 1 push OK!"
- if push(xxx, 'B) = 'B
- then "Test 2 push OK!"
- else error(0, "Test 2 push fails");
- "Test 2 push OK!"
- if xxx = '(B A)
- then "Test 2 push OK!"
- else error(0, "Test 2 push fails");
- "Test 2 push OK!"
-
- %------------------------- Exercise -------------------------
- macro procedure format x;
- /* FORMAT("str", ...) - A formatted print utility. It
- looks for %x things in str, printing everything else.
- A property of printf!-format will cause a call on
- the named function with the corresponding argument.
- This should return a print form to use. A property
- printf!-expand calls a function without an argument.
- Common controls are:
- %n new line
- %p prin2 call.
- %w prin1 call.
- */
- begin scalar str, localstr, m;
- str := explode2 cadr x;
- x := cddr x;
- loop: if null str then
- << if localstr then
- m := {'prin2, makestring reversip localstr} . m;
- return 'progn . reverse m >>;
- if eqcar(str, '!%) then
- if cdr str then
- if fn := get(cadr str, 'printf!-format) then
- << if localstr then
- << m := {'prin2, makestring reversip localstr} . m;
- localstr := nil >>;
- m := apply(fn, {car x}) . m;
- x := cdr x;
- str := cddr str;
- go to loop >>
- else if fn := get(cadr str, 'printf!-expand) then
- << if localstr then
- << m := {'prin2, makestring reverse localstr} . m;
- localstr := nil >>;
- m := apply(fn, nil) . m;
- str := cddr str;
- go to loop >>;
- localstr := car str . localstr;
- str := cdr str;
- go to loop
- end;
- format
- expr procedure makestring l;
- /* MAKESTRING(L) - convert the list of character L into
- a string. */
- compress('!" . append(l, '(!")));
- makestring
- expr procedure printf!-terpri;
- /* PRINTF!-TERPRI() - Generates a TERPRI call for %n */
- '(terpri);
- printf!-terpri
- put('!n, 'printf!-expand, 'printf!-terpri);
- printf!-terpri
- put('!N, 'printf!-expand, 'printf!-terpri);
- printf!-terpri
- expr procedure printf!-prin1 x;
- /* PRINTF!-PRIN1(X) - Generates a PRIN1 call for %w */
- {'prin1, x};
- printf!-prin1
- put('!w, 'printf!-format, 'printf!-prin1);
- printf!-prin1
- put('!W, 'printf!-format, 'printf!-prin1);
- printf!-prin1
- expr procedure printf!-prin2 x;
- /* PRINTF!-PRIN2(X) - Generates a PRIN2 call for %p */
- {'prin2, x};
- printf!-prin2
- put('!p, 'printf!-format, 'printf!-prin2);
- printf!-prin2
- put('!P, 'printf!-format, 'printf!-prin2);
- printf!-prin2
- %------------------------- Exercise -------------------------
- macro procedure rmsg x;
- /* RMSG("str", ...) - A formatted string utility. It
- looks for %x things in str, copying everything else.
- A property of rmsg!-format will cause a call on
- the named function with the corresponding argument.
- This should return a explode form to use. A property
- rmsg!-expand calls a function without an argument.
- Common controls are:
- %n new line
- %p explode2 call.
- %w explode call.
- */
- begin scalar str, localstr, m;
- str := explode2 cadr x;
- x := cddr x;
- loop: if null str then
- << if localstr then
- m := mkquote reversip localstr . m;
- return `(makestring (nconcl #@(reversip m))) >>;
- if eqcar(str, '!%) then
- if cdr str then
- if fn := get(cadr str, 'rmsg!-format) then
- << if localstr then
- << m := mkquote reversip localstr . m;
- localstr := nil >>;
- m := apply(fn, {car x}) . m;
- x := cdr x;
- str := cddr str;
- go to loop >>
- else if fn := get(cadr str, 'rmsg!-expand) then
- << if localstr then
- << m := mkquote reversip localstr . m;
- localstr := nil >>;
- m := apply(fn, nil) . m;
- str := cddr str;
- go to loop >>;
- localstr := car str . localstr;
- str := cdr str;
- go to loop
- end;
- rmsg
- expr procedure makestring l;
- /* MAKESTRING(L) - convert the list of character L into
- a string. */
- compress('!" . append(l, '(!")));
- +++ makestring redefined
- makestring
- expr procedure rmsg!-terpri;
- /* RMSG!-TERPRI() - Generates an EOL. */
- mkquote {!$eol!$};
- rmsg!-terpri
- put('!n, 'rmsg!-expand, 'rmsg!-terpri);
- rmsg!-terpri
- put('!N, 'rmsg!-expand, 'rmsg!-terpri);
- rmsg!-terpri
- expr procedure rmsg!-prin1 x;
- /* RMSG!-PRIN1(X) - Generates an EXPLODE call */
- `(fixstr (explode #x));
- rmsg!-prin1
- put('!w, 'rmsg!-format, 'rmsg!-prin1);
- rmsg!-prin1
- put('!W, 'rmsg!-format, 'rmsg!-prin1);
- rmsg!-prin1
- expr procedure rmsg!-prin2 x;
- /* RMSG!-PRIN2(X) - Generates an EXPLODE2 call for x. */
- `(explode2 #x);
- rmsg!-prin2
- put('!p, 'rmsg!-format, 'rmsg!-prin2);
- rmsg!-prin2
- put('!P, 'rmsg!-format, 'rmsg!-prin2);
- rmsg!-prin2
- expr procedure fixstr x;
- /* FIXSTR(X) - Double up "'s in x. */
- if null x then nil
- else if eqcar(x, '!") then '!" . '!" . fixstr cdr x
- else car x . fixstr cdr x;
- fixstr
- if rmsg "abc" = "abc"
- then "Test 1 rmsg OK!"
- else error(0, "Test 1 rmsg fails!");
- "Test 1 rmsg OK!"
- if rmsg("Test %w test", 12) = "Test 12 test"
- then "Test 2 rmsg OK!"
- else error(0, "Test 2 rmsg fails!");
- "Test 2 rmsg OK!"
- if rmsg("Test %w string", "foo") = "Test ""foo"" string"
- then "Test 3 rmsg OK!"
- else error(0, "Test 3 rmsg fails!");
- "Test 3 rmsg OK!"
- if rmsg("Test %w now %p", "foo", "foo") = "Test ""foo"" now foo"
- then "Test 4 rmsg OK!"
- else error(0, "Test 4 rmsg fails!");
- "Test 4 rmsg OK!"
- %------------------------- Exercise -------------------------
- define CFLAG = T;
- nil
- macro procedure ifcflag x;
- /* IFCLFAG(X) - generate the code for X if CFLAG is non-NIL,
- otherwise generate NIL (this can't be used everywhere). */
- if CFLAG then cadr x else nil;
- ifcflag
- ifCFLAG expr procedure pslfoo x; car x;
- pslfoo
- if getd 'pslfoo
- then "Test 1 ifCFLAG OK!"
- else error(0, "Test 1 ifCFLAG fails!");
- "Test 1 ifCFLAG OK!"
- % ##### Interactive Exercises #####
- %------------------------- Exercise #2 -------------------------
- /* Lists functions that have been embedded with count code. */
- global '(EMBEDDED!*);
- nil
- EMBEDDED!* := NIL;
- nil
- expr procedure embed f;
- /* EMBED(F) - wrap function F with counter code. Error if F is
- not interpreted. Put the information under property COUNT and
- add to the global list EMBEDDED!*. */
- begin scalar def, args, nfn;
- if not(def := getd f) then error(0, {f, "is undefined"});
- if codep cdr def then error(0, {f, "is not interpreted"});
- put(f, 'COUNT, 0);
- if f memq EMBEDDED!* then return NIL;
- EMBEDDED!* := f . EMBEDDED!*;
- putd(nfn := intern gensym(), car def, cdr def);
- putd(f, car def,
- {'lambda, caddr def,
- {'progn,
- {'put, mkquote f, mkquote 'COUNT,
- {'add1, {'get, mkquote f, mkquote 'COUNT}}},
- nfn . caddr def}});
- return f
- end;
- *** local variable args in procedure embed not used
- embed
- expr procedure stats;
- /* STATS() - list all the embedded functions and their
- counts. */
- for each f in EMBEDDED!*
- do << prin1 f; prin2 " "; print get(f, 'COUNT) >>;
- stats
- expr procedure pcnt x;
- /* PCNT(X) - returns the number of dotted-pairs in X (vectors
- can hide dotted-pairs). */
- if atom x then 0
- else 1 + pcnt car x + pcnt cdr x;
- pcnt
- if embed 'pcnt eq 'pcnt
- then "Test 1 embed OK!"
- else error(0, "Test 1 embed Fails!");
- +++ pcnt redefined
- "Test 1 embed OK!"
- if get('pcnt, 'count) = 0
- then "Test 2 embed OK!"
- else error(0, "Test 2 embed Fails!");
- "Test 2 embed OK!"
- if pcnt '(a . (b . c)) = 2
- then "Test 3 embed OK!"
- else error(0, "Test 3 embed Fails!");
- "Test 3 embed OK!"
- if get('pcnt, 'COUNT) = 5
- then "Test 4 embed OK!"
- else error(0, "Test 4 embed Fails!");
- "Test 4 embed OK!"
- if EMBEDDED!* = '(PCNT)
- then "Test 5 embed OK!"
- else error(0, "Test 5 embed Fails!");
- "Test 5 embed OK!"
- % Just a visual check.
- stats();
- pcnt 5
- nil
- % ##### Test the inspector module #####
- %
- % We set LINELENGTH to various values to check how good we do on output.
- % Don't let the default screw up the test:
- LINELENGTH 80;
- t
- % Describe some of the basic data types.
- % Dotted-pairs.
- describe '(a . b);
- A dotted-pair or list
- nil
- % Vectors;
- global '(xvar);
- nil
- xvar := mkvect 3;
- [nil nil nil nil]
- describe xvar;
- A vector with 4 elements
- nil
- % Records.
- record insprec /* A record for testing. */
- with
- field1 := 'a;
- insprec
- xvar := insprec();
- [insprec a]
- describe xvar;
- A insprec record with
- 1: a
- nil
- describe 'insprec;
- insprec is a record constructor with the following fields
- ** not implemented. **
- nil
- % A code pointer (usually).
- describe cdr getd 'car;
- car is an EXPR with an unknown number of arguments
- nil
- % Numbers.
- describe 1;
- A fixed number
- nil
- describe 3.14159;
- A floating-point number
- nil
- % Strings
- describe "This is a string";
- A string
- nil
- % identifiers of various sourts.
- describe 'car;
- car is an EXPR with one argument
- nil
- describe 'a!-plain!-jane!-identifier;
- Don't know anything about a!-plain!-jane!-identifier
- nil
-
- describe nil;
- Identifier 'nil' is fluid
- nil
- % This message is sort of funny in odd ways.
- % Now let's get serious. Here's a global with no active comment. The
- % remprop is something you shouldn't know about but allows us to run
- % the test file multiple times and get the same results.
- remprop('TheCow, 'NEWNAM);
- nil
- DEFINE TheCow = "How now brown cow";
- nil
- describe 'TheCow;
- thecow is a constant defined as "How now brown cow"
- nil
- off saveactives;
- nil
- /* I never saw a purple cow, I never hope to see one now. */
- global '(PurpleCow);
- nil
- describe 'PurpleCow;
- Identifier 'purplecow' is global
- nil
- on saveactives;
- nil
- /* But I'd rather see one than be one! */
- global '(Pcow);
- nil
- describe 'Pcow;
- Identifier 'pcow' is global defined line 2236 in file ../xmpl/rlisp88.tst
- but i'd rather see one than be one!
- nil
- % Now we march on to procedures.
- % Here's one with no comment and we don't save it.
- off saveactives;
- nil
- remd 'comtest1;
- nil
- expr procedure comtest1 x;
- print x;
- comtest1
- describe 'comtest1;
- comtest1 is an EXPR with one argument
- nil
- % Here's one with no comment and we do save it.
- on saveactives;
- nil
- remd 'comtest2;
- nil
- expr procedure comtest2(x, y);
- print x;
- *** local variable y in procedure comtest2 not used
- comtest2
- describe 'comtest2;
- comtest2 is an EXPR with 2 arguments
- nil
- % Here's one with a comment but we don't save it.
- off saveactives;
- nil
- remd 'comtest3;
- nil
- expr procedure comtest3(x, y, z);
- /* You should never see this comment. */
- print x;
- *** local variable y in procedure comtest3 not used
- *** local variable z in procedure comtest3 not used
- comtest3
- describe 'comtest3;
- comtest3 is an EXPR with 3 arguments
- nil
- % Here's one with a comment and we should see it.
- on saveactives;
- nil
- remd 'comtest4;
- nil
- expr procedure comtest4(x, y, z, xx);
- /* COMTEST4(X, Y, Z, XX) - A well commented routine. This routine
- does almost nothing, but a good article thereof. */
- print x;
- *** local variable y in procedure comtest4 not used
- *** local variable z in procedure comtest4 not used
- *** local variable xx in procedure comtest4 not used
- comtest4
- describe 'comtest4;
- comtest4 is an EXPR with 4 arguments
- Function ends on line 2265 in file ../xmpl/rlisp88.tst
- comtest4(x, y, z, xx) - a well commented routine. this routine
- does almost nothing, but a good article thereof.
- nil
- % Now try MACROS.
- remd 'comtest5;
- nil
- macro procedure comtest5 x;
- /* COMTEST5(X) - A macro that doesn't really do much of anything. */
- {'car, cadr x};
- comtest5
- describe 'comtest5;
- comtest5 is a MACRO
- Function ends on line 2272 in file ../xmpl/rlisp88.tst
- comtest5(x) - a macro that doesn't really do much of anything.
- nil
- smacro procedure comtest6 x;
- /* COMTEST6(X) - a SMACRO with an active comment. This smacro expands
- to take CAR of its argument. */
- car x;
- comtest6
- describe 'comtest6;
- comtest6 is an SMACRO with one argument
- Function ends on line 2277 in file ../xmpl/rlisp88.tst
- comtest6(x) - a smacro with an active comment. this smacro expands
- to take car of its argument.
- nil
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Module testing.
- /* This is a test module which occurs at the top level just to make
- sure that the module type works. */
- module testmodule;
- nil
- endmodule;
- nil
- describe 'testmodule;
- Can't find source or fasl file for module testmodule
- this is a test module which occurs at the top level just to make
- sure that the module type works.
- nil
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Format testing. Put a big comment out there and look at it with
- % various line lengths.
- /* ********************
- This is a test comment. We'll try do different things with it in
- different contexts. Does it work?
- expr procedure fact n;
- if n < 2 then 1 else n * fact(n - 1);
- Well hoop de doo! Is there anything else funny?
- +------------+----------+
- | Column 1 | Col. 2 |
- +------------+----------+
- | Aardvarks | 345 |
- +------------+----------+
- | Zarfs | 3 |
- +------------+----------+
- /// */
- global '(testvariable);
- nil
- describe 'testvariable;
- Identifier 'testvariable' is global defined line 2292 in file
- ../xmpl/rlisp88.tst
- ********************
- this is a test comment. we'll try do different things with it in
- different contexts. does it work?
- expr procedure fact n;
- if n < 2 then 1 else n * fact(n - 1);
- well hoop de doo! is there anything else funny?
- +------------+----------+
- | column 1 | col. 2 |
- +------------+----------+
- | aardvarks | 345 |
- +------------+----------+
- | zarfs | 3 |
- +------------+----------+
- ///
- nil
- LINELENGTH 60;
- 80
- describe 'testvariable;
- Identifier 'testvariable' is global defined line 2292
- in file ../xmpl/rlisp88.tst
- ********************
- this is a test comment. we'll try do different things with i
- t in
- different contexts. does it work?
- expr procedure fact n;
- if n < 2 then 1 else n * fact(n - 1);
- well hoop de doo! is there anything else funny?
- +------------+----------+
- | column 1 | col. 2 |
- +------------+----------+
- | aardvarks | 345 |
- +------------+----------+
- | zarfs | 3 |
- +------------+----------+
- ///
- nil
- LINELENGTH 50;
- 60
- describe 'testvariable;
- Identifier 'testvariable' is global defined line
- 2292 in file ../xmpl/rlisp88.tst
- ********************
- this is a test comment. we'll try do different thi
- ngs with it in
- different contexts. does it work?
- expr procedure fact n;
- if n < 2 then 1 else n * fact(n - 1);
- well hoop de doo! is there anything else funny?
- +------------+----------+
- | column 1 | col. 2 |
- +------------+----------+
- | aardvarks | 345 |
- +------------+----------+
- | zarfs | 3 |
- +------------+----------+
- ///
- nil
- LINELENGTH 40;
- 50
- describe 'testvariable;
- Identifier 'testvariable' is global
- defined line 2292 in file
- ../xmpl/rlisp88.tst
- ********************
- this is a test comment. we'll try do dif
- ferent things with it in
- different contexts. does it work?
- expr procedure fact n;
- if n < 2 then 1 else n * fact(n - 1)
- ;
- well hoop de doo! is there anything else
- funny?
- +------------+----------+
- | column 1 | col. 2 |
- +------------+----------+
- | aardvarks | 345 |
- +------------+----------+
- | zarfs | 3 |
- +------------+----------+
- ///
- nil
- LINELENGTH 30;
- 40
- describe 'testvariable;
- Identifier 'testvariable' is
- global defined line 2292
- in file ../xmpl/rlisp88.tst
- ********************
- this is a test comment. we'll
- try do different things with i
- t in
- different contexts. does it wo
- rk?
- expr procedure fact n;
- if n < 2 then 1 else n * f
- act(n - 1);
- well hoop de doo! is there any
- thing else funny?
- +------------+----------+
- | column 1 | col. 2 |
- +------------+----------+
- | aardvarks | 345 |
- +------------+----------+
- | zarfs | 3 |
- +------------+----------+
- ///
- nil
- LINELENGTH 20;
- 30
- describe 'testvariable;
- Identifier '
- testvariable' is
- global defined line
- 2292 in file
- ../xmpl/rlisp88.tst
- ********************
- this is a test comme
- nt. we'll try do dif
- ferent things with i
- t in
- different contexts.
- does it work?
- expr procedure fac
- t n;
- if n < 2 then 1
- else n * fact(n - 1)
- ;
- well hoop de doo! is
- there anything else
- funny?
- +------------+-----
- -----+
- | column 1 | col
- . 2 |
- +------------+-----
- -----+
- | aardvarks |
- 345 |
- +------------+-----
- -----+
- | zarfs |
- 3 |
- +------------+-----
- -----+
- ///
- nil
- LINELENGTH 10;
- 20
- describe 'testvariable;
- Identifier '
- testvariable
- ' is
- global
- defined line
- 2292
- in file
- ../xmpl/rlisp88.tst
- **********
- **********
- this is a
- test comme
- nt. we'll
- try do dif
- ferent thi
- ngs with i
- t in
- different
- contexts.
- does it wo
- rk?
- expr pro
- cedure fac
- t n;
- if n <
- 2 then 1
- else n * f
- act(n - 1)
- ;
- well hoop
- de doo! is
- there any
- thing else
- funny?
- +--------
- ----+-----
- -----+
- | column
- 1 | col
- . 2 |
- +--------
- ----+-----
- -----+
- | aardvar
- ks |
- 345 |
- +--------
- ----+-----
- -----+
- | zarfs
- |
- 3 |
- +--------
- ----+-----
- -----+
- ///
- nil
- % ##### Records Package #####
- global '(rec1 rec2);
- nil
- % Simple test.
- record rtest1;
- rtest1
- rec1 := rtest1();
- [rtest1]
- if rec1 neq array 'rtest1 then
- error(0, "Test 1 RECORD fails creation test!");
- nil
- if null rtest1p rec1 then
- error(0, "Test 1 RECORD fails predicate test!");
- nil
- % A record with two fields.
- record rtest2 with field1 := 0, field2 := 1;
- rtest2
- % Test default creation.
- rec2 := rtest2();
- [rtest2 0 1
- ]
- if rec2 neq array('rtest2, 0, 1) then
- error(0, "Test 2 RECORD fails to create a record");
- nil
- if null rtest2p rec2 then
- error(0, "Test 2 RECORD fails predicate test");
- nil
- if rtest2p rec1 then
- error(0, "Test 2 RECORD fails to test record differences");
- nil
- % Build a record with a predicate. Remove any old occurrence.
- remd 'rtest3!?;
- nil
- record rtest3 with field1 := 0, field2 := 1 has predicate = rtest3!?;
- rtest3
- if not getd 'rtest3!? then
- error(0, "Test 3 RECORD fails - no predicate built");
- nil
- if rtest3!? rec2 then
- error(0, "Test 3 RECORD fails - predicate returns T on non RTEST3 record");
- nil
- for each x in {'identifier, 12, 12.3, "a string", cdr getd 'car,
- '(a list), array("an", "array")}
- when rtest3!? x
- do error(0, {"Test 3 RECORD fails - predicate returns T on", x});
- nil
- rec2 := rtest3();
- [rtest3 0 1
- ]
- if not rtest3!? rec2 then
- error(0, "Test 3 RECORD fails - predicate returns NIL on record");
- nil
- % Check that the no-predicate option works.
- remd 'rtest4p;
- nil
- % Just to make sure.
- record rtest4 with a := 34, b := 56 has no predicate;
- rtest4
- if getd 'rtest4p then
- error(0, "Test 4 RECORD fails - NO PREDICATE option generates a predicate");
- nil
- % Verify that the CONSTRUCTOR option works.
- remd 'rtest5;
- nil
- remd 'make-rtest5;
- nil
- record rtest5 with r5a := 0, r5b := 1 has constructor;
- rtest5
- if getd 'rtest5 then
- error(0, "Test 5 RECORD fails - CONSTRUCTOR generates simple constructor");
- nil
- if not getd 'make-rtest5 then
- error(0, "Test 5 RECORD fails - CONSTRUCTOR doesn't generate constructor");
- nil
- if not rtest5p make-rtest5() then
- error(0, "Test 5 RECORD fails - CONSTRUCTOR doesn't generate record");
- nil
- % Verify that the named constructor works.
- remd 'rtest6;
- nil
- remd 'please-make-rtest6;
- nil
- record rtest6 with r6a := 0 has constructor = please!-make!-arecord;
- rtest6
- if getd 'rtest6 then
- error(0, "Test 6 RECORD fails - CONSTRUCTOR generates simple constructor");
- nil
- if getd 'make-rtest6 then
- error(0, "Test 6 RECORD fails - CONSTRUCTOR generates make- constructor");
- nil
- if not getd 'please-make-arecord then
- error(0, "Test 6 RECORD fails - CONSTRUCTOR doesn't generate constructor");
- nil
- if not rtest6p please-make-arecord() then
- error(0, "Test 6 RECORD fails - CONSTRUCTOR doesn't generate record");
- nil
- end;
- (TIME:
- rlisp88
- 1999 2009)
- nil
|