12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930 |
- This is scheme48.info, produced by makeinfo version 6.7 from
- scheme48.texi.
- This manual is for Scheme48 version 1.3.
- Copyright (C) 2004, 2005, 2006 Taylor Campbell. All rights reserved.
- This manual includes material derived from works bearing the
- following notice:
- Copyright (C) 1993-2005 Richard Kelsey, Jonathan Rees, and Mike
- Sperber. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
- * The name of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
- INFO-DIR-SECTION The Algorithmic Language Scheme
- START-INFO-DIR-ENTRY
- * Scheme48: (scheme48). Nearly complete reference manual for version 1.3
- END-INFO-DIR-ENTRY
- File: scheme48.info, Node: Common-Lisp-style formatting, Next: Library utilities, Prev: TCP & UDP sockets, Up: Libraries
- 6.7 Common-Lisp-style formatting
- ================================
- Scheme48 provides a simple Common-Lisp-style 'format' facility in the
- 'formats' structure. It does not provide nearly as much functionality
- as Common Lisp, however: the considerable complexity of Common Lisp's
- 'format' was deliberately avoided because it was deemed inconsistent
- with Scheme48's design goals. Scheme48's 'format' is suitable for most
- simple purposes, anyhow.
- -- procedure: format port control-string argument ... --> unspecified
- or string
- Prints CONTROL-STRING to PORT. If, anywhere in CONTROL-STRING, the
- character '~' (tilde) occurs, the following character determines
- what to print in the place of the tilde and following character.
- Some formatting directives consume arguments from ARGUMENT ....
- Formatting directive characters are case-insensitive. If PORT is
- '#t', the output is printed to to the value of
- '(current-output-port)'; if PORT is false, the output is collected
- in a string and returned.
- The complete list of formatting directives:
- '~~'
- Prints a single '~' (tilde), and does not consume an argument.
- '~A'
- Consumes and prints the first remaining argument with
- 'display'. ('A'ny)
- '~D'
- Consumes and prints the first remaining argument as a decimal
- number using 'number->string'. ('D'ecimal)
- '~S'
- Consumes and prints the first remaining argument with 'write'.
- ('S'-expression)
- '~%'
- Prints a newline with 'newline'.
- '~&'
- Prints a newline with 'newline', unless it can be determined
- that a newline was immediately previously printed to PORT
- (*note I/O extensions::).
- '~?'
- Recursively formats. The first remaining argument is consumed
- and must be another control string; the argument directly
- thereafter is also consumed, and it must be a list of
- arguments corresponding with that control string. The control
- string is formatted with those arguments using 'format'.
- 'Format' examples:
- (format #t "Hello, ~A!~%" "world")
- -| Hello, world!
- -|
- (format #t "Hello~?~S~%" "~A world" '(#\,) '!)
- -| Hello, world!
- -|
- (format #f "~A~A ~A." "cH" "uMBLE" "spuZz")
- => "cHuMBLE spuZz."
- (let ((x 10) (y .1))
- (format #t "x: ~D~%~&y: ~D~%~&" x y))
- -| x: 10
- -| y: .1
- File: scheme48.info, Node: Library utilities, Prev: Common-Lisp-style formatting, Up: Libraries
- 6.8 Library utilities
- =====================
- Scheme48 provides various miscellaneous library utilities for common
- general-purpose tasks.
- 6.8.1 Destructuring
- -------------------
- The 'destructuring' structure exports a form for destructuring
- S-expressions.
- -- syntax: destructure ((pattern value) ...) body
- For each '(PATTERN VALUE)' pair, binds every name in PATTERN to the
- corresponding location in the S-expression VALUE. For example,
- (destructure (((x . y) (cons 5 3))
- ((#(a b) c) '(#((1 2) 3) (4 5))))
- BODY)
- binds X to '5', Y to '3', A to '(1 2)', B to '3', and C to '(4 5)',
- in BODY.
- 6.8.2 Pretty-printing
- ---------------------
- The 'pp' structure exports a simple pretty-printer.
- -- procedure: p object [port] --> unspecified
- -- procedure: pretty-print object port position --> unspecified
- 'P' is a convenient alias for 'pretty-print'; it passes 0 for
- POSITION and the value of '(current-output-port)' if PORT is not
- passed. 'Pretty-print' pretty-prints OBJECT to PORT, using a left
- margin of POSITION. For example:
- (p '(define (fact n)
- (let loop ((p 1) (c 1))
- (if (> c n) p (loop (* p c) (+ c 1))))))
- -| (define (fact n)
- -| (let loop ((p 1) (c 1))
- -| (if (> c n)
- -| p
- -| (loop (* p c) (+ c 1)))))
- The pretty-printer is somewhat extensible as well:
- -- procedure: define-indentation name count --> unspecified
- Sets the number of subforms to be indented past NAME in
- pretty-printed output to be COUNT. For example:
- (define-indentation 'frobozz 3)
- (p '(frobozz (foo bar baz quux zot) (zot quux baz bar foo)
- (mumble frotz gargle eek) (froomble zargle hrumph)))
- -| (frobozz (foo bar baz quux zot)
- -| (zot quux baz bar foo)
- -| (mumble frotz gargle eek)
- -| (froomble zargle hrumph))
- 6.8.3 Strongly connected graph components
- -----------------------------------------
- The 'strong' structure exports a routine for finding a list of the
- strongly connected components in a graph.
- -- procedure: strongly-connected-components vertices to slot set-slot!
- --> sorted-strong-vertices
- Returns the components of a graph containing vertices from the list
- VERTICES that are strongly connected, in a reversed topologically
- sorted list. TO should be a procedure of one argument, a vertex,
- that returns a list of all vertices that have an edge to its
- argument. SLOT & SET-SLOT! should be procedures of one & two
- arguments, respectively, that access & modify arbitrary slots used
- by the algorithm. The slot for every vertex should initially be
- '#f' before calling 'strongly-connected-components', and the slots
- are reverted to '#f' before 'strongly-connected-components'
- returns.
- 6.8.4 Nondeterminism
- --------------------
- The 'nondeterminism' structure provides a simple nondeterministic
- ambivalence operator, like McCarthy's 'AMB', and a couple utilities atop
- it, built with Scheme's 'call-with-current-continuation'.
- -- procedure: with-nondeterminism thunk --> values
- Initializes the nondeterminism system and calls THUNK; this returns
- the values THUNK returns after then tearing down what was set up.
- -- syntax: either option ... --> value
- -- syntax: one-value exp --> value
- -- syntax: all-values exp --> list
- 'Either' evaluates to the value of any one of the options. It is
- equivalent to McCarthy's 'AMB'. It may return any number of times.
- 'One-value' returns the only value that EXP could produce; it will
- return only once, although it may actually return any number of
- values (if EXP contains a call to 'values'). 'All-values' returns
- a list of all of the single values, not multiple values, that EXP
- could nondeterministically evaluate to.
- -- procedure: fail --> does not return
- Signals a nondeterministic failure. This is invalid outside of a
- 'with-nondeterminism'-protected dynamic extent.
- 6.8.5 Miscellaneous utilities
- -----------------------------
- The 'big-util' structure exports a variety of miscellaneous utilities.
- -- procedure: concatenate-symbol elt ... --> symbol
- Returns a symbol containing the contents of the sequence ELT ....
- Each ELT may be another symbol, a string, or a number. Numbers are
- converted to strings in base ten.
- -- procedure: error format-string argument ... --> values (may not
- return)
- -- procedure: breakpoint format-string argument ... --> values (may not
- return)
- 'Error' signals an error whose message is formatted by 'format'
- (*note Common-Lisp-style formatting::) with the given formatting
- template string and arguments. 'Breakpoint' signals a breakpoint
- with a message similarly constructed and causes the command
- processor to push a new command level (*note Command levels::).
- -- procedure: atom? x --> boolean
- Returns true if X is not a pair or false if it is.
- -- procedure: neq? x y --> boolean
- -- procedure: n= x y --> boolean
- Negations of the 'eq?' and '=' predicates.
- -- procedure: identity value --> value
- -- procedure: no-op value --> value
- These simply return their arguments. The difference between them
- is that 'no-op' is guaranteed not to be integrated by the compiler,
- whereas 'identity' may be.
- -- procedure: null-list? object --> boolean
- Returns '#t' if OBJECT is the null list, returns '#f' if OBJECT is
- a pair, or signals an error if OBJECT is neither the null list nor
- a pair.
- -- procedure: reverse! list --> reversed-list
- Returns a list containing the reverse elements of LIST. Note that
- the original LIST is _not_ reversed; it becomes garbage.
- 'Reverse!' simply re-uses its structure.
- -- procedure: memq? object list --> boolean
- Returns '#t' if OBJECT is a member of LIST, as determined by 'eq?';
- or '#f' if not.
- -- procedure: first predicate list --> elt or '#f'
- -- procedure: any predicate list --> elt or '#f'
- 'First' returns the first element of LIST that satisfies PREDICATE,
- or '#f' if no element does. 'Any' returns an element of LIST that
- satisfies PREDICATE. Note that 'any' may choose any element of the
- list, whereas 'first' explicitly returns the _first_ element that
- satisfies PREDICATE.
- -- procedure: any? predicate list --> boolean
- -- procedure: every? predicate list --> boolean
- 'Any?' returns '#t' if any element of LIST satisfies PREDICATE, or
- '#f' if none do. 'Every?' returns '#t' if every element of LIST
- satisfies PREDICATE, or '#f' if there exists an element that does
- not.
- -- procedure: filter predicate list --> filtered-list
- -- procedure: filter! predicate list --> filtered-list
- These return a list of all elements in LIST that satisfy PREDICATE.
- 'Filter' is not allowed to modify LIST's structure; 'filter!' may,
- however.
- -- procedure: filter-map proc list --> list
- This is a combination of 'filter' and 'map'. For each element E in
- LIST: if '(PROC E)' returns a true value, that true value is
- collected in the output list. 'Filter-map' does not modify LIST's
- structure.
- -- procedure: remove-duplicates list --> uniquified-list
- Returns a unique list of all elements in LIST; that is, if there
- were any duplicates of any element E in LIST, only a single E will
- occur in the returned list. 'Remove-duplicates' does not modify
- LIST's structure.
- -- procedure: partition-list predicate list --> [satisfied unsatisfied]
- -- procedure: partition-list! predicate list --> [satisfied
- unsatisfied]
- These return two values: a list of all elements in LIST that do
- satisfy PREDICATE and a list of all elements that do not.
- 'Partition-list' is not allowed to modify LIST's structure;
- 'partition-list!' is.
- -- procedure: delq object list --> list
- -- procedure: delq! object list --> list
- These return a list containing all elements of LIST except for
- OBJECT. 'Delq' is not allowed to modify LIST's structure; 'delq!'
- is.
- -- procedure: delete predicate list --> list
- Returns a list of all elements in LIST that do not satisfy
- PREDICATE. Note that, despite the lack of exclamation mark in the
- name, this _may_ modify LIST's structure.
- -- procedure: string->immutable-string string --> immutable-string
- Returns an immutable string with STRING's contents. If STRING is
- already immutable, it is returned; otherwise, an immutable copy is
- returned.
- 6.8.6 Multiple value binding
- ----------------------------
- The 'receiving' structure exports the 'receive' macro, a convenient
- syntax atop R5RS's 'call-with-values'.
- -- syntax: receive formals producer body
- Binds the variables in the lambda parameter list FORMALS to the
- return values of PRODUCER in BODY.
- (receive FORMALS
- PRODUCER
- BODY)
- ==
- (call-with-values
- (lambda () PRODUCER)
- (lambda FORMALS BODY))
- For sequences of multiple value bindings, the 'mvlet' structure
- exports two convenient macros.
- -- syntax: mvlet*
- -- syntax: mvlet
- 'Mvlet*' is a multiple-value version of 'let' or a linearly nested
- version of 'receive':
- (mvlet* ((FORMALS_{0} PRODUCER_{0})
- (FORMALS_{1} PRODUCER_{1})
- ...)
- BODY)
- ==
- (call-with-values
- (lambda () PRODUCER_{0})
- (lambda FORMALS_{0}
- (call-with-values
- (lambda () PRODUCER_{1})
- (lambda FORMALS_{1}
- ...BODY...))))
- 'Mvlet' is similar, but each PRODUCER is evaluated in an
- environment where none of the variables in any of the FORMALS is
- bound, and the order in which each producer expression is evaluated
- is unspecified.
- 6.8.7 Object dumper
- -------------------
- Scheme48 has a rudimentary object dumper and retriever in the structure
- 'dump/restore'. It is not a 'real' object dumper in the sense that it
- will not handle cycles in object graphs correctly; it simply performs a
- recursive descent and will diverge if it reaches a cycle or stop after a
- recursive depth parameter.
- The types of objects that the dumper supports are: several
- miscellaneous constants ('()', '#t', '#f', & the unspecific token),
- pairs, vectors, symbols, numbers, strings, characters, and byte vectors.
- -- procedure: dump object char-writer depth --> unspecified
- Dumps OBJECT by repeatedly calling CHAR-WRITER, which must be a
- procedure that accepts exactly one character argument, on the
- characters of the serialized representation. If the dumper
- descends into the object graph whose root is OBJECT for more than
- DEPTH recursions, an ellipsis token is dumped in the place of the
- vertex at DEPTH.
- -- procedure: restore char-reader --> object
- Restores the object whose serialized components are retrieved by
- repeatedly calling CHAR-READER, which must be a procedure that
- accepts zero arguments and returns a character.
- 6.8.8 Simple time access
- ------------------------
- The 'time' structure exports a simple facility for accessing time
- offsets in two different flavours.
- -- procedure: real-time --> milliseconds
- Returns the real time in milliseconds that has passed since some
- unspecified moment in time.(1) Though not suitable for
- measurements relative to entities outside the Scheme48 image, the
- real time is useful for measuring time differences within the
- Scheme image with reasonable precision; for example, thread sleep
- timing is implemented with this real time primitive.
- -- procedure: run-time --> ticks
- Returns the run time as an integer representing processor clock
- ticks since the start of the Scheme48 process. This is much less
- precise than the real time, but it is useful for measuring time
- actually spent in the Scheme48 process, as opposed to time in
- general.
- ---------- Footnotes ----------
- (1) In the current implementation on Unix, this moment happens to be
- the first call to 'real-time'; on Win32, this is the start of the Scheme
- process.
- File: scheme48.info, Node: C interface, Next: POSIX interface, Prev: Libraries, Up: Top
- 7 C interface
- *************
- (This chapter was derived from work copyrighted (C) 1993-2005 by Richard
- Kelsey, Jonathan Rees, and Mike Sperber.)
- This chapter describes an interface for calling C functions from Scheme,
- calling Scheme procedures from C, and working with the Scheme heap in C.
- Scheme48 manages stub functions in C that negotiate between the calling
- conventions of Scheme & C and the memory allocation policies of both
- worlds. No stub generator is available yet, but writing stubs is a
- straightforward task.
- * Menu:
- * Shared bindings between Scheme and C::
- * Calling C functions from Scheme::
- * Dynamic loading of C modules::
- * Accessing Scheme data from C::
- * Calling Scheme procedures from C::
- * Interacting with the Scheme heap in C::
- * Using Scheme records in C::
- * Raising exceptions from C::
- * Unsafe C macros::
- 7.1 Overview of the C interface
- ===============================
- The following facilities are available for interfacing between Scheme48
- & C:
- * Scheme code can call C functions.
- * The external interface provides full introspection for all Scheme
- objects. External code may inspect, modify, and allocate Scheme
- objects arbitrarily.
- * External code may raise exceptions back to Scheme48 to signal
- errors.
- * External code may call back into Scheme. Scheme48 correctly
- unrolls the process stack on non-local exits.
- * External modules may register bindings of names to values with a
- central registry accessible from Scheme. Conversely, Scheme code
- can register shared bindings for access by C code.
- 7.1.1 Scheme structures
- -----------------------
- On the Scheme side of the C interface, there are three pertinent
- structures: 'shared-bindings' (*note Shared bindings between Scheme and
- C::), which provides the Scheme side of the facility for sharing data
- between Scheme and C; 'external-calls' (*note Calling C functions from
- Scheme::), which exports several ways to call C functions from Scheme,
- along with some useful facilities, such as object finalizers, which are
- also available from elsewhere; and 'load-dynamic-externals' (*note
- Dynamic loading of C modules::), which provides a dynamic external
- object loading facility. Also, the old dynamic loading facility is
- still available from the 'dynamic-externals' structure, but its use is
- deprecated, and it will most likely vanish in a later release.
- 7.1.2 C naming conventions
- --------------------------
- Scheme48's C bindings all have strict naming conventions. Variables &
- procedures have 's48_' prefixed to them; macros, 'S48_'. Whenever a C
- name is derived from a Scheme identifier, hyphens are replaced with
- underscores. Also, procedures or variables are converted to lowercase,
- while macros are converted to uppercase. The '?' suffix, generally
- appended to predicates, is converted to '_p' (or '_P' in macro names).
- Trailing '!' is dropped. For example, the C macro that corresponds with
- Scheme's 'pair?' predicate is named 'S48_PAIR_P', and the C macro to
- assign the car of a pair is named 'S48_SET_CAR'. Procedures and macros
- that do not verify the types of their arguments have 'unsafe' in their
- names.
- All of the C functions and macros described have prototypes or
- definitions in the file 'c/scheme48.h' of Scheme48's standard
- distribution. The C type for Scheme values is defined there to be
- 's48_value'.
- 7.1.3 Garbage collection
- ------------------------
- Scheme48 uses a copying garbage collector. The collector must be able
- to locate all references to objects allocated in the Scheme48 heap in
- order to ensure that storage is not reclaimed prematurely and to update
- references to objects moved by the collector. The garbage collector may
- run whenever an object is allocated in the heap. C variables whose
- values are Scheme48 objects and which are live across heap allocation
- calls need to be registered with the garbage collector. For more
- information, *note Interacting with the Scheme heap in C::.
- File: scheme48.info, Node: Shared bindings between Scheme and C, Next: Calling C functions from Scheme, Up: C interface
- 7.2 Shared bindings between Scheme and C
- ========================================
- Shared bindings are the means by which named values are shared between
- Scheme & C code. There are two separate tables of shared bindings, one
- for values defined in Scheme and accessed from C and the other for the
- opposite direction. Shared bindings actually bind names to cells, to
- allow a name to be resolved before it has been assigned. This is
- necessary because C initialization code may run before or after the
- corresponding Scheme code, depending on whether the Scheme code is in
- the resumed image or run in the current session. The Scheme bindings
- described here are available from the 'shared-bindings' structure.
- 7.2.1 Scheme shared binding interface
- -------------------------------------
- -- Scheme procedure: shared-binding? object --> boolean
- -- Scheme procedure: shared-binding-is-import? shared-binding -->
- boolean
- 'Shared-binding?' is the disjoint type predicate for all shared
- bindings, imported or exported; 'shared-binding-is-import?' returns
- true if SHARED-BINDING was imported into Scheme from C, and false
- if it has the converse direction.
- -- Scheme procedure: shared-binding-ref shared-binding --> value
- -- Scheme procedure: shared-binding-set! shared-binding value -->
- unspecified
- 'Shared-binding-ref' returns the value of SHARED-BINDING;
- 'shared-binding-set!' sets the value of SHARED-BINDING to be VALUE.
- -- Scheme procedure: lookup-imported-binding name --> shared-binding
- -- Scheme procedure: define-imported-binding name value --> unspecified
- -- Scheme procedure: undefine-imported-binding name --> unspecified
- 'Lookup-imported-binding' returns the binding imported from C to
- Scheme with the given name; a binding is created if none exists.
- 'Define-imported-binding' creates a new such binding, anomalously
- from within Scheme; such bindings are usually created instead from
- within C using the C 's48_define_exported_binding' function.
- 'Undefine-imported-binding' removes the shared binding whose name
- is NAME from the table of imported bindings.
- -- Scheme procedure: lookup-exported-binding name --> shared-binding
- -- Scheme procedure: define-exported-binding name value --> unspecified
- -- Scheme procedure: undefine-exported-binding name --> unspecified
- Equivalents of the above three procedures, but for bindings
- exported from Scheme to C. 'Define-imported-binding', unlike
- 'define-exported-binding', is customary to use in Scheme, as its
- intended use is to make a Scheme value available to C code from
- within Scheme.
- -- Scheme procedure: find-undefined-imported-bindings --> vector
- Returns a vector of all bindings imported into Scheme from C with
- undefined values, i.e. those created implicitly by lookups that
- have not yet been assigned rather than those created explicitly by
- the shared binding definers ('define-exported-binding', &c.).
- 7.2.2 C shared binding interface
- --------------------------------
- -- C macro: s48_value S48_SHARED_BINDING_P (s48_value OBJ)
- -- C macro: s48_value S48_SHARED_BINDING_NAME (s48_value
- SHARED_BINDING)
- -- C macro: s48_value S48_SHARED_BINDING_IS_IMPORTP (s48_value
- SHARED-BINDING)
- -- C macro: s48_value S48_SHARED_BINDING_REF (s48_value SHARED_BINDING)
- -- C macro: void S48_SHARED_BINDING_SET (s48_value SHARED_BINDING,
- s48_value VALUE)
- These macros are C counterparts to Scheme's 'shared-binding?',
- 'shared-binding-name', 'shared-binding-is-import?',
- 'shared-binding-ref', and 'shared-binding-set!', respectively.
- -- C macro: statement S48_SHARED_BINDING_CHECK (s48_value BINDING)
- Signals an exception if and only if BINDING's value is Scheme48's
- 'unspecific' value.
- *Huh?:* Undefined shared bindings are not initialized with the
- 'unspecific' value, but rather with an entirely different special
- token referred to internally as 'undefined,' used in circumstances
- such as this -- yet 'S48_SHARED_BINDING_CHECK', as defined in
- 'scheme48.h', definitely checks whether BINDING's value is the
- 'unspecific' value.
- -- C function: s48_value s48_get_imported_binding (char *NAME)
- Returns the shared binding defined in Scheme for NAME, creating it
- if necessary.
- -- C function: void s48_define_exported_binding (char *NAME, s48_value
- VALUE)
- Defines a shared binding named NAME with the value VALUE that can
- be accessed from Scheme.
- -- C macro: void S48_EXPORT_FUNCTION (FN)
- This is a convenience for the common case of exporting a C function
- to Scheme. This expands into
- s48_define_exported_binding("FN",
- s48_enter_pointer(FN))
- which boxes the function into a Scheme48 byte vector and then
- exports it as a shared binding. Note that 's48_enter_pointer'
- allocates space in the Scheme heap and may trigger a garbage
- collection; *note Interacting with the Scheme heap in C::.
- File: scheme48.info, Node: Calling C functions from Scheme, Next: Dynamic loading of C modules, Prev: Shared bindings between Scheme and C, Up: C interface
- 7.3 Calling C functions from Scheme
- ===================================
- The 'external-calls' structure exports several ways to call C functions
- from Scheme, along with several other related utilities, many of which
- are also available from other structures. There are two different ways
- to call C functions from Scheme, depending on how the C function was
- obtained:
- -- Scheme procedure: call-imported-binding binding argument ... -->
- value
- -- Scheme procedure: call-external-value byte-vector name argument ...
- --> value
- Each of these applies its first argument, a C function, to the rest
- of the arguments. For 'call-imported-binding', the function
- argument must be an imported binding. For 'call-external-value',
- the function argument must be a byte vector that contains a pointer
- to a C function, and NAME should be a string that names the
- function. The NAME argument is used only for printing error
- messages.
- For both of these, the C function is passed the argument values,
- and the value returned is that returned by the C function. No
- automatic representation conversion occurs for either arguments or
- return values. Up to twelve arguments may be passed. There is no
- method supplied for returning multiple values to Scheme from C or
- vice versa (mainly because C does not have multiple return values).
- Keyboard interrupts that occur during a call to a C function are
- ignored until the function returns to Scheme.(1)
- -- Scheme syntax: import-definition name [c-string]
- -- Scheme syntax: import-lambda-definition name formals [c-string]
- These macros simplify importing bindings from C into Scheme and
- wrapping such bindings in Scheme procedures. 'Import-definition'
- defines NAME to be the shared binding named by C-STRING, whose
- value, if it is not supplied, is by default a string of NAME,
- downcased and with all hyphens translated to underscores.
- (define NAME (lookup-imported-binding C-STRING))
- For example,
- (import-definition my-foo)
- ==> (define my-foo (lookup-imported-binding "my_foo"))
- 'Import-lambda-definition' imports the named C binding, using
- either the provided C binding name or by translating the Scheme
- name as with 'import-definition', and defines NAME to be a
- procedure with the given formal parameter list that calls the
- imported C binding with its arguments:
- (define BINDING (lookup-imported-binding C-STRING))
- (define (NAME FORMAL ...)
- (call-imported-binding BINDING FORMAL ...))
- Examples:
- (import-lambda-definition integer->process-id (int)
- "posix_getpid")
- ==>
- (define BINDING_{0}
- (lookup-imported-binding "posix_getpid"))
- (define (integer->process-id int)
- (call-imported-binding BINDING_{0} int))
- (import-lambda-definition s48-system (string))
- ==>
- (define BINDING_{1}
- (lookup-imported-binding "s48_system"))
- (define (s48-system string)
- (call-imported-binding BINDING_{1} string))
- where BINDING_{0} and BINDING_{1} are fresh, unused variable names.
- *Warning:* 'Import-lambda-definition', as presently implemented,
- requires a fixed parameter list; it does not allow 'rest list'
- arguments.
- -- Scheme procedure: lookup-imported-binding name --> shared-binding
- -- Scheme procedure: define-exported-binding shared-binding -->
- unspecified
- -- Scheme procedure: shared-binding-ref shared-binding --> value
- These are identical to the procedures accessible with the same
- names from the 'shared-bindings' structure (*note Shared bindings
- between Scheme and C::).
- -- Scheme procedure: add-finalizer! object procedure --> unspecified
- Registers PROCEDURE as the finalizer for OBJECT. When OBJECT is
- later about to be reclaimed by the garbage collector, PROCEDURE is
- applied to one argument, OBJECT. All finalizers are applied in a
- child of the root scheduler thread that is spawned after every
- garbage collection. If an error occurs in any finalizer, it will
- be printed to the standard error output port, and all other
- finalizers will be aborted before they are given a chance to run.
- Because of this, and the fact that finalizers are collected and run
- after every garbage collection, they should perform as little
- computation as possible. PROCEDURE may also create new references
- to OBJECT elsewhere in the heap, in which case the object will not
- be reclaimed, but its associated finalizer will be forgotten.
- *Warning:* Finalizers are expensive. Use sparingly.
- -- Scheme procedure: define-record-resumer record-type resumer -->
- unspecified
- Identical to the procedure accessible with the same name from the
- 'record-types' structure (*note Records::). Record resumers are
- often useful in working with foreign C data, which is in many cases
- specific to the program image within the operating system, and
- which cannot straightforwardly be relocated to a different address
- space.
- ---------- Footnotes ----------
- (1) This is clearly a problem; we are working on a solution.
- File: scheme48.info, Node: Dynamic loading of C modules, Next: Accessing Scheme data from C, Prev: Calling C functions from Scheme, Up: C interface
- 7.4 Dynamic loading of C modules
- ================================
- External code can be loaded into a running Scheme48 on most Unices and
- on Windows. Such external code must be stored in shared objects; see
- below on details of the C side. The relevant Scheme procedures are
- available in the 'load-dynamic-externals' structure:
- -- procedure: load-dynamic-externals filename add-file-type?
- reload-on-repeat? reload-on-resume? --> dynamic-externals
- -- procedure: import-dynamic-externals filename --> dynamic-externals
- -- procedure: unload-dynamic-externals dynamic-externals -->
- unspecified
- 'Load-dynamic-external' loads a shared object from FILENAME, with
- an appropriate file type appended if ADD-FILE-TYPE? is true ('.so'
- on Unix and '.dll' on Windows), and returns a "dynamic externals"
- object representing the loaded shared object. If the shared object
- was already loaded, then if RELOAD-ON-REPEAT? is true, it is
- reloaded; otherwise, the 'load-dynamic-externals' call has no
- effect. If the dynamic externals descriptor is stored in a dumped
- heap image, when that heap image is resumed, if 'reload-on-resume?'
- is true, the shared object corresponding with that dynamic external
- descriptor is reloaded. 'Unload-dynamic-externals' unloads the
- given dynamic externals object.
- 'Import-dynamic-externals' is a convenient wrapper for the common
- case of 'load-dynamic-externals'; it is equivalent to
- '(load-dynamic-externals #t #f #t)', i.e. it will append a file
- type, it will not reload the shared object if it was already
- loaded, and the shared object will be loaded if part of a resumed
- heap image.
- -- procedure: reload-dynamic-externals filename --> unspecified
- Reloads the shared object named by FILENAME. This is intended as
- an interactive utility, which is why it accepts the filename of the
- shared object and not a dynamic externals descriptor.
- Shared objects intended to be loaded into Scheme48 must define two
- functions:
- -- C function: void s48_on_load (void)
- -- C function: void s48_on_reload (void)
- 's48_on_load' is called when the shared object is initially loaded
- by Scheme48. It typically consists of a number of invocations of
- 'S48_EXPORT_FUNCTION' to make C functions available to Scheme48
- code. 's48_on_reload' is called when the shared object is reloaded
- after it has been initially loaded once; it typically just calls
- 's48_on_load', but it may perform other reinitializations.
- On Linux, the following commands compile the C source file 'foo.c'
- into a shared object 'foo.so' that can be loaded dynamically by
- Scheme48:
- % gcc -c -o foo.o foo.c
- % ld -shared -o foo.so foo.o
- 7.4.1 Old dynamic loading interface
- -----------------------------------
- The old 'dynamic-externals' structures, which exported 'dynamic-load',
- 'get-external', 'lookup-external', 'lookup-all-externals', 'external?',
- 'external-name', 'external-value', and 'call-external', is still
- supported, but it will not work on Windows, its use is deprecated, and
- it is likely to vanish in a future release. The old documentation is
- preserved to aid updating of old code:
- On architectures that support it, external code can be loaded into a
- running Scheme48 process, and C object file bindings can be accessed at
- runtime & their values called. These Scheme procedures are exported by
- the structure 'dynamic-externals'.
- In some Unices, retrieving a value from the current process may
- require a non-trivial amount of computation. We recommend that a
- dynamically loaded file contain a single initialization function that
- creates shared bindings for the values exported by the file.
- -- Scheme procedure: dynamic-load string --> unspecified
- Loads the filename named by STRING into the current process. An
- exception is raised if the file cannot be found or if dynamic
- loading is not supported by the host operating system. The file
- must have been compiled & linked appropriately. For Linux, for
- example, the following commands compile 'foo.c' into a file
- 'foo.so' that can be loaded dynamically:
- % gcc -c -o foo.o foo.c
- % ld -shared -o foo.so foo.o
- -- Scheme procedure: get-external string --> external
- -- Scheme procedure: external? object --> boolean
- -- Scheme procedure: external-name external --> string
- -- Scheme procedure: external-value external --> byte-vector
- These procedures access external values bound in the current
- process. 'Get-external' returns a "external" object that contains
- the value of the C binding with the name STRING. It signals a
- warning if there is no such binding in the current process.
- 'External?' is the disjoint type predicate for externals, and
- 'external-name' & 'external-value' return the name & value of an
- external. The value is represented as a byte vector (*note Bitwise
- manipulation::) of length four on 32-bit architectures. The value
- is that of the C binding from when 'get-external' (or
- 'lookup-external', as described below) was called.
- -- Scheme procedure: lookup-external external --> boolean
- -- Scheme procedure: lookup-all-externals --> boolean
- 'Lookup-external' updates the value of EXTERNAL by looking up its
- binding in the current process. It returns '#t' if the external is
- bound and '#f' if not. 'Lookup-all-externals' calls
- 'lookup-external' on all externals in the current Scheme48 image.
- It returns '#t' if all were bound and '#f' if there was at least
- one unbound external.
- -- Scheme procedure: call-external external argument ... --> value
- Calls the C function pointed to by EXTERNAL with the given
- arguments, and returns the value that the C function returned.
- This is like 'call-imported-binding' and 'call-external-value'
- except that the function argument is represented as an external,
- not as an imported binding or byte vector containing a pointer.
- For more details, *note Calling C functions from Scheme::.
- File: scheme48.info, Node: Accessing Scheme data from C, Next: Calling Scheme procedures from C, Prev: Dynamic loading of C modules, Up: C interface
- 7.5 Accessing Scheme data from C
- ================================
- The C header file 'scheme48.h' provides access to Scheme48 data
- structures. The type 's48_value' is used for Scheme values. When the
- type of a value is known, such as the integer returned by the Scheme
- procedure 'vector-length' or the boolean returned by 'pair', the
- corresponding C function returns a C value of the appropriate type, not
- an 's48_value'. Predicates return '1' for true and '0' for false.
- -- C macro: s48_value S48_FALSE
- -- C macro: s48_value S48_TRUE
- -- C macro: s48_value S48_NULL
- -- C macro: s48_value S48_UNSPECIFIC
- -- C macro: s48_value S48_EOF
- -- C macro: long S48_MAX_FIXNUM_VALUE
- -- C macro: long S48_MIN_FIXNUM_VALUE
- These C macros denote various Scheme constants. 'S48_FALSE' is the
- boolean false value, written in Scheme as '#f'. 'S48_TRUE' is the
- boolean true value, or '#t'. 'S48_NULL' is the empty list '()'.
- 'S48_UNSPECIFIC' is a miscellaneous value returned by procedures
- that have no meaningful return value (accessed in Scheme48 by the
- nullary procedure 'unspecific' in the 'util' structure). 'S48_EOF'
- is the end-of-file object (which the Scheme procedure 'eof-object?'
- answers true for). 'S48_MAX_FIXNUM_VALUE' is the maximum integer
- as a 'long' that can be represented in a Scheme48 fixnum.
- 'S48_MIN_FIXNUM_VALUE' is similar, but the minimum integer.
- -- C macro: int S48_EXTRACT_BOOLEAN (s48_value BOOLEAN)
- -- C function: unsigned char s48_extract_char (s48_value CHAR)
- -- C function: char * s48_extract_string (s48_value STRING)
- -- C function: char * s48_extract_byte_vector (s48_value BYTEV)
- -- C function: long s48_extract_integer (s48_value INTEGER)
- -- C function: double s48_extract_double (s48_value DOUBLE)
- -- C macro: s48_value S48_ENTER_BOOLEAN (int BOOLEAN)
- -- C function: s48_value s48_enter_char (unsigned char CHAR)
- -- C function: s48_value s48_enter_string (char *STRING)
- -- C function: s48_value s48_enter_byte_vector (char *BYTEV, long
- LENGTH)
- -- C function: s48_value s48_enter_integer (long INTEGER)
- -- C function: s48_value s48_enter_double (double DOUBLE)
- These functions & macros convert values between their respective
- Scheme & C representations.
- 'S48_EXTRACT_BOOLEAN' returns '0' if BOOLEAN is '#f' and '1'
- otherwise. 'S48_ENTER_BOOLEAN' returns the Scheme value '#f' if
- its argument is zero and '#t' otherwise.
- 's48_extract_char' & 's48_enter_char' convert between Scheme
- characters and C 'char's.
- 's48_extract_string' & 's48_extract_byte_vector' return pointers to
- the actual storage used by STRING or BYTEV. These pointers are
- valid only until the next garbage collection, however; *note
- Interacting with the Scheme heap in C::. 's48_enter_string' &
- 's48_enter_byte_vector' allocate space on the Scheme48 heap for the
- given strings or byte vectors. 's48_enter_string' copies the data
- starting from the pointer it is given up to the first ASCII 'NUL'
- character, whereas 's48_enter_byte_vector' is given the number of
- bytes to copy into the Scheme heap.
- 's48_extract_integer' returns a C 'long' that represents the Scheme
- integer as input. If the Scheme integer is too large to be
- represented in a long, an exception is signalled. (The Scheme
- integer may be a fixnum or a bignum.) 's48_enter_integer' converts
- back to Scheme integers, and it will never signal an exception.
- 's48_extract_double' & 's48_enter_double' convert between Scheme &
- C double-precision floating point representations.
- Of these, 's48_enter_string', 's48_enter_byte_vector',
- 's48_enter_integer', & 's48_enter_double' may cause the garbage
- collector to be invoked: the former two copy the string or byte
- vector onto the Scheme heap first, 's48_enter_integer' may need to
- allocate a bignum (since C 'long's are wider than Scheme48
- fixnums), and floats are heap-allocated in Scheme48.
- -- C macro: int S48_TRUE_P (s48_value OBJECT)
- -- C macro: int S48_FALSE_P (s48_value OBJECT)
- 'S48_TRUE_P' returns true if OBJECT is the true constant 'S48_TRUE'
- and false if otherwise. 'S48_FALSE_P' returns true if its argument
- is the false constant 'S48_FALSE' and false if otherwise.
- -- C macro: int S48_FIXNUM_P (s48_value OBJECT)
- -- C function: long s48_extract_fixnum (s48_value FIXNUM)
- -- C function: s48_value s48_enter_fixnum (long INTEGER)
- 'S48_FIXNUM_P' is the C predicate for Scheme48 fixnums, delimited
- in range by 'S48_MIN_FIXNUM_VALUE' & 'S48_MAX_FIXNUM_VALUE'.
- 's48_extract_fixnum' returns the C 'long' representation of the
- Scheme fixnum, and 's48_enter_fixnum' returns the Scheme fixnum
- representation of the C 'long'. These are identical to
- 's48_extract_integer' & 's48_enter_integer', except that
- 's48_extract_fixnum' will never raise a range exception, but
- 's48_enter_fixnum' may, and 's48_enter_fixnum' will never return a
- bignum; this is due to the fact that C 'long's have a wider range
- than Scheme48 fixnums.
- -- C macro: int S48_EQ_P (s48_value A, s48_value B)
- -- C macro: int S48_CHAR_P (s48_value OBJECT)
- -- C macro: int S48_PAIR_P (s48_value OBJECT)
- -- C macro: int S48_VECTOR_P (s48_value OBJECT)
- -- C macro: int S48_STRING_P (s48_value OBJECT)
- -- C macro: int S48_SYMBOL_P (s48_value OBJECT)
- -- C macro: int S48_BYTE_VECTOR_P (s48_value OBJECT)
- -- C macro: s48_value S48_CAR (s48_value PAIR)
- -- C macro: s48_value S48_CDR (s48_value PAIR)
- -- C macro: void S48_SET_CAR (s48_value PAIR, s48_value OBJECT)
- -- C macro: void S48_SET_CDR (s48_value PAIR, s48_value OBJECT)
- -- C function (may GC): s48_value s48_cons (s48_value CAR, s48_value
- CDR)
- -- C function: s48_value s48_length (s48_value LIST)
- -- C macro: long S48_VECTOR_LENGTH (s48_value VECTOR)
- -- C macro: s48_value S48_VECTOR_REF (s48_value VECTOR, long INDEX)
- -- C macro: void S48_VECTOR_SET (s48_value VECTOR, long INDEX,
- s48_value OBJECT)
- -- C function (may GC): s48_value s48_make_vector (long LENGTH,
- s48_value FILL)
- -- C macro: long S48_STRING_LENGTH (s48_value STRING)
- -- C macro: char S48_STRING_REF (s48_value STRING, long INDEX)
- -- C macro: void S48_STRING_SET (s48_value STRING, long INDEX, char
- CHAR)
- -- C function (may GC): s48_value s48_make_string (long LENGTH, char
- FILL)
- -- C macro: s48_value S48_SYMBOL_TO_STRING (s48_value SYMBOL)
- -- C macro: long S48_BYTE_VECTOR_LENGTH (s48_value BYTEV)
- -- C macro: char S48_BYTE_VECTOR_REF (s48_value BYTEV, long INDEX)
- -- C macro: void S48_BYTE_VECTOR_SET (s48_value BYTEV, long INDEX, char
- BYTE)
- -- C function (may GC): s48_value s48_make_byte_vector (long LENGTH)
- C versions of miscellaneous Scheme procedures. The names were
- derived from their Scheme counterparts by replacing hyphens with
- underscores, '?' suffixes with '_P', and dropping '!' suffixes.
- File: scheme48.info, Node: Calling Scheme procedures from C, Next: Interacting with the Scheme heap in C, Prev: Accessing Scheme data from C, Up: C interface
- 7.6 Calling Scheme procedures from C
- ====================================
- -- C function: s48_value s48_call_scheme (s48_value PROC, long NARGS,
- ...)
- Calls the Scheme procedure PROC on NARGS arguments, which are
- passed as additional arguments to 's48_call_scheme'. There may be
- at most twelve arguments. The value returned by the Scheme
- procedure is returned to the C procedure. Calling any Scheme
- procedure may potentially cause a garbage collection.
- There are some complications that arise when mixing calls from C to
- Scheme with continuations & threads. C supports only downward
- continuations (via 'longjmp()'). Scheme continuations that capture a
- portion of the C stack have to follow the same restriction. For
- example, suppose Scheme procedure 's0' captures continuation 'a' and
- then calls C function 'c0', which in turn calls Scheme procedure 's1'.
- 'S1' can safely call the continuation 'a', because that is a downward
- use. When 'a' is called, Scheme48 will remove the portion of the C
- stack used by the call to 'c0'. On the other hand, if 's1' captures a
- continuation, that continuation cannot be used from 's0', because, by
- the time control returns to 's0', the C stack used by 's0' will no
- longer be valid. An attempt to invoke an upward continuation that is
- closed over a portion of the C stack will raise an exception.
- In Scheme48, threads are implemented using continuations, so the
- downward restriction applies to them as well. An attempt to return from
- Scheme to C at a time when the appropriate C frame is not on the top of
- the C stack will cause the current thread to block until the frame is
- available. For example, suppose thread 't0' calls a C function that
- calls back to Scheme, at which point control switches to thread 't1',
- which also calls C & then back to Scheme. At this point, both 't0' &
- 't1' have active calls to C on the C stack, with 't1''s C frame above
- 't0''s. If 't0' attempts to return from Scheme to C, it will block,
- because the frame is not yet accessible. Once 't1' has returned to C
- and from there back to Scheme, 't0' will be able to resume. The return
- to Scheme is required because context switches can occur only while
- Scheme code is running. 'T0' will also be able to resume if 't1' uses a
- continuation to throw past its call out to C.
- File: scheme48.info, Node: Interacting with the Scheme heap in C, Next: Using Scheme records in C, Prev: Calling Scheme procedures from C, Up: C interface
- 7.7 Interacting with the Scheme heap in C
- =========================================
- Scheme48 uses a precise copying garbage collector. Any code that
- allocates objects within the Scheme48 heap may trigger a garbage
- collection. Variables bound to values in the Scheme48 heap need to be
- registered with the garbage collector so that the value will be safely
- held and so that the variables will be updated if the garbage collector
- moves the object. The garbage collector has no facility for updating
- pointers to the interiors of objects, so such pointers, for example the
- ones returned by 'S48_EXTRACT_STRING', will likely become invalid when a
- garbage collection occurs.
- -- C macro: S48_DECLARE_GC_PROTECT (N)
- -- C macro: void S48_GC_PROTECT_N (s48_value VAR_{1}, ..., s48_value
- VAR_{N})
- -- C macro: void S48_GC_UNPROTECT ()
- 'S48_DECLARE_GC_PROTECT', where 1 <= N <= 9, allocates storage for
- registering N variables. At most one use of
- 'S48_DECLARE_GC_PROTECT' may occur in a block. After declaring a
- GC protection, 'S48_GC_PROTECT_N' registers the N variables with
- the garbage collector. It must be within the scope that the
- 'S48_DECLARE_GC_PROTECT' occurred in and before any code that can
- cause a garbage collection. 'S48_GC_UNPROTECT' removes the current
- block's protected variables from the garbage collector's list. It
- must be called at the end of the block after any code that may
- cause a garbage collection. Omitting any of the three may cause
- serious and hard-to-debug problems, because the garbage collector
- may relocate an object and invalidate unprotected 's48_value'
- pointers. If not 'S48_DECLARE_GC_PROTECT' is matched with a
- 'S48_GC_UNPROTECT' or vice versa, a 'gc-protection-mismatch'
- exception is raised when a C procedure returns to Scheme.
- -- C macro: void * S48_GC_PROTECT_GLOBAL (GLOBAL)
- -- C macro: void S48_GC_UNPROTECT_GLOBAL (void *HANDLE)
- 'S48_GC_PROTECT_GLOBAL' permanently registers the l-value GLOBAL
- with the system as a garbage collection root. It returns a pointer
- which may then be supplied to 'S48_GC_UNPROTECT_GLOBAL' to
- unregister the l-value as a root.
- 7.7.1 Keeping C data structures in the Scheme heap
- --------------------------------------------------
- C data structures can be stored within the Scheme heap by embedding them
- inside byte vectors (*note Bitwise manipulation::). The following
- macros can be used to create and access embedded C objects.
- -- C macro: s48_value S48_MAKE_VALUE (TYPE)
- -- C macro: TYPE S48_EXTRACT_VALUE (s48_value BYTEV, TYPE)
- -- C macro: TYPE * S48_EXTRACT_VALUE_POINTER (s48_value BYTEV, TYPE)
- -- C macro: void S48_SET_VALUE (s48_value BYTEV, TYPE, TYPE VALUE)
- 'S48_MAKE_VALUE' allocates a byte vector large enough to hold a C
- value whose type is TYPE. 'S48_EXTRACT_VALUE' returns the contents
- of the byte vector BYTEV cast to TYPE, and
- 'S48_EXTRACT_VALUE_POINTER' returns a pointer to the contents of
- the byte vector, which is valid only until the next garbage
- collection. 'S48_SET_VALUE' stores a value into the byte vector.
- 7.7.2 C code and heap images
- ----------------------------
- Scheme48 uses dumped heap images to restore a previous system state.
- The Scheme48 heap is written into a file in a machine-independent and
- operating-system-independent format. The procedures described above,
- however, may be used to create objects in the Scheme heap that contain
- information specific to the current machine, operating system, or
- process. A heap image containing such objects may not work correctly
- when resumed.
- To address this problem, a record type may be given a "resumer"
- procedure. On startup, the resumer procedure for a record type is
- applied to each record of that type in the image being restarted. This
- procedure can update the record in a manner appropriate to the machine,
- operating system, or process used to resume the image. Note, though,
- that there is no reliable order in which record resumer procedures are
- applied. To specify the resumer for a record type, use the
- 'define-record-resumer' procedure from the 'record-types' structure
- (*note Records::).
- File: scheme48.info, Node: Using Scheme records in C, Next: Raising exceptions from C, Prev: Interacting with the Scheme heap in C, Up: C interface
- 7.8 Using Scheme records in C
- =============================
- External C code can create records and access record slots positionally
- using these functions & macros. Note, however, that named access to
- record fields is not supported, only indexed access, so C code must be
- synchronized carefully with the corresponding Scheme that defines record
- types.
- -- C function (may GC): s48_value s48_make_record (s48_value
- RECORD-TYPE)
- -- C macro: int S48_RECORD_P (s48_value OBJECT)
- -- C macro: s48_value S48_RECORD_TYPE (s48_value RECORD)
- -- C macro: s48_value S48_RECORD_REF (s48_value RECORD, long INDEX)
- -- C macro: void S48_RECORD_SET (s48_value RECORD, long INDEX,
- s48_value VALUE)
- -- C function: void s48_check_record_type (s48_value RECORD, s48_value
- TYPE-BINDING)
- 's48_make_record' allocates a record on Scheme's heap with the
- given record type; its arguments must be a shared binding whose
- value is a record type descriptor (*note Records::).
- 'S48_RECORD_P' is the type predicate for records.
- 'S48_RECORD_TYPE' returns the record type descriptor of RECORD.
- 'S48_RECORD_REF' & 'S48_RECORD_SET' operate on records similarly to
- how 'S48_VECTOR_REF' & 'S48_VECTOR_SET' work on vectors.
- 's48_check_record_type' checks whether RECORD is a record whose
- type is the value of the shared binding TYPE_BINDING. If this is
- not the case, it signals an exception. (It also signals an
- exception if TYPE_BINDING's value is not a record.) Otherwise, it
- returns normally.
- For example, with this record type definition:
- (define-record-type thing :thing
- (make-thing a b)
- thing?
- (a thing-a)
- (b thing-b))
- the identifier ':thing' is bound to the record type and can be exported
- to C thus:
- (define-exported-binding "thing-record-type" :thing)
- and 'thing' records can be made in C:
- static s48_value thing_record_type = S48_FALSE;
- void initialize_things(void)
- {
- S48_GC_PROTECT_GLOBAL(thing_record_type);
- thing_record_type = s48_get_imported_binding("thing-record-type");
- }
- s48_value make_thing(s48_value a, s48_value b)
- {
- s48_value thing;
- S48_DECLARE_GC_PROTECT(2);
- S48_GC_PROTECT_2(a, b);
- thing = s48_make_record(thing_record_type);
- S48_RECORD_SET(thing, 0, a);
- S48_RECORD_SET(thing, 1, b);
- S48_GC_UNPROTECT();
- return thing;
- }
- Note that the variables 'a' & 'b' must be protected against the
- possibility of a garbage collection occurring during the call to
- 's48_make_record'.
- File: scheme48.info, Node: Raising exceptions from C, Next: Unsafe C macros, Prev: Using Scheme records in C, Up: C interface
- 7.9 Raising exceptions from C
- =============================
- The following macros raise certain errors, immediately returning to
- Scheme48. Raising an exception performs all necessary clean-up actions
- to properly return to Scheme48, including adjusting the stack of
- protected variables.
- -- C function: s48_raise_scheme_exception (int TYPE, int NARGS, ...)
- The base procedure for raising exceptions. TYPE is the type of
- exception; it should be one of the 'S48_EXCEPTION_...' constants
- defined in 'scheme48.h'. NARGS is the number of additional values
- to be included in the exception; these follow the NARGS argument
- and should all have the type 's48_value'. NARGS may not be greater
- than ten. 's48_raise_scheme_exception' never returns.
- -- C function: s48_raise_argument_type_error (s48_value ARG)
- -- C function: s48_raise_argument_number_error (s48_value NARGS,
- s48_value MIN, s48_value MAX)
- -- C function: s48_raise_range_error (s48_value VALUE, s48_value MIN,
- s48_value MAX)
- -- C function: s48_raise_closed_channel_error ()
- -- C function: s48_raise_os_error (int ERRNO)
- -- C function: s48_raise_out_of_memory_error ()
- Conveniences for raising certain kinds of exceptions. Argument
- type errors are due to procedures receiving arguments of the
- incorrect type. Argument number errors are due to the number of
- arguments being passed to a procedure, NARGS, not being between MIN
- or MAX, inclusive. Range errors are similar, but they are intended
- for larger ranges, not argument numbers. Closed channel errors
- occur when a channel (*note Channels::) was operated upon with the
- expectation that it would not be closed. OS errors originate from
- the OS, and they are denoted with Unix 'errno' values.
- -- C macro: void S48_CHECK_BOOLEAN (s48_value OBJECT)
- -- C macro: void S48_CHECK_SYMBOL (s48_value OBJECT)
- -- C macro: void S48_CHECK_PAIR (s48_value OBJECT)
- -- C macro: void S48_CHECK_STRING (s48_value OBJECT)
- -- C macro: void S48_CHECK_INTEGER (s48_value OBJECT)
- -- C macro: void S48_CHECK_CHANNEL (s48_value OBJECT)
- -- C macro: void S48_CHECK_BYTE_VECTOR (s48_value OBJECT)
- -- C macro: void S48_CHECK_RECORD (s48_value OBJECT)
- -- C macro: void S48_CHECK_SHARED_BINDING (s48_value OBJECT)
- Conveniences for checking argument types. These signal argument
- type errors with 's48_raise_argument_type_error' if their argument
- is not of the type being tested.
- File: scheme48.info, Node: Unsafe C macros, Prev: Raising exceptions from C, Up: C interface
- 7.10 Unsafe C macros
- ====================
- All of the C functions & macros described previously verify that their
- arguments have the appropriate types and lie in the appropriate ranges.
- The following macros are identical to their safe counterparts, except
- that the unsafe variants, by contrast, do _not_ verify coherency of
- their arguments. They are provided for the purpose of writing more
- efficient code; their general use is not recommended.
- -- C macro: char S48_UNSAFE_EXTRACT_CHAR (s48_value CHAR)
- -- C macro: char * S48_UNSAFE_EXTRACT_STRING (s48_value STRING)
- -- C macro: long S48_UNSAFE_EXTRACT_INTEGER (s48_value INTEGER)
- -- C macro: double S48_UNSAFE_EXTRACT_DOUBLE (s48_value DOUBLE)
- -- C macro: long S48_UNSAFE_EXTRACT_FIXNUM (s48_value FIXNUM)
- -- C macro: s48_value S48_UNSAFE_ENTER_FIXNUM (long INTEGER)
- -- C macro: s48_value S48_UNSAFE_CAR (s48_value PAIR)
- -- C macro: s48_value S48_UNSAFE_CDR (s48_value PAIR)
- -- C macro: void S48_UNSAFE_SET_CAR (s48_value PAIR, s48_value VALUE)
- -- C macro: void S48_UNSAFE_SET_CDR (s48_value PAIR, s48_value VALUE)
- -- C macro: long S48_UNSAFE_VECTOR_LENGTH (s48_value VECTOR)
- -- C macro: s48_value S48_UNSAFE_VECTOR_REF (s48_value VECTOR, long
- INDEX)
- -- C macro: void S48_UNSAFE_VECTOR_SET (s48_value VECTOR, long INDEX,
- s48_value VALUE)
- -- C macro: long S48_UNSAFE_STRING_LENGTH (s48_value STRING)
- -- C macro: char S48_UNSAFE_STRING_REF (s48_value STRING, long INDEX)
- -- C macro: void S48_UNSAFE_STRING_SET (s48_value STRING, long INDEX,
- char CHAR)
- -- C macro: void S48_UNSAFE_SYMBOL_TO_STRING (s48_value SYMBOL)
- -- C macro: long S48_UNSAFE_BYTE_VECTOR_LENGTH (s48_value BYTEV)
- -- C macro: char S48_UNSAFE_BYTE_VECTOR_REF (s48_value BYTEV, long
- INDEX)
- -- C macro: void S48_UNSAFE_BYTE_VECTOR_SET (s48_value BYTEV, long
- INDEX, char BYTE)
- -- C macro: s48_value S48_UNSAFE_SHARED_BINDING_REF (s48_value
- SHARED_BINDING)
- -- C macro: int S48_UNSAFE_SHARED_BINDING_IS_IMPORTP (s48_value
- SHARED_BINDING)
- -- C macro: s48_value S48_UNSAFE_SHARED_BINDING_NAME (s48_value
- SHARED_BINDING)
- -- C macro: void S48_UNSAFE_SHARED_BINDING_SET (s48_value
- SHARED_BINDING, s48_value VALUE)
- -- C macro: TYPE S48_UNSAFE_EXTRACT_VALUE (s48_value BYTEV, TYPE)
- -- C macro: TYPE * S48_UNSAFE_EXTRACT_VALUE_POINTER (s48_value BYTEV,
- TYPE)
- -- C macro: void S48_UNSAFE_SET_VALUE (s48_value BYTEV, TYPE, TYPE
- VALUE)
- File: scheme48.info, Node: POSIX interface, Next: Pre-Scheme, Prev: C interface, Up: Top
- 8 POSIX interface
- *****************
- (This chapter was derived from work copyrighted (C) 1993-2005 by Richard
- Kelsey, Jonathan Rees, and Mike Sperber.)
- This chapter describes Scheme48's interface to POSIX C calls. Scheme
- versions of most of the C functions in POSIX are provided. Both the
- interface and implementation are new and likely to change significantly
- in future releases. The implementation may also contain many bugs.
- The POSIX bindings are available in several structures:
- 'posix-processes'
- 'fork', 'exec', and other process manipulation procedures
- 'posix-process-data'
- procedures for accessing information about processes
- 'posix-files'
- POSIX file system access procedures
- 'posix-i/o'
- pipes and various POSIX I/O controls
- 'posix-time'
- POSIX time operations
- 'posix-users'
- user and group manipulation procedures
- 'posix-regexps'
- POSIX regular expression construction and matching
- 'posix'
- all of the above
- Scheme48's POSIX interface differs from scsh [Shivers 94; Shivers 96;
- Shivers et al. 04] in several ways. The interface here lacks scsh's
- high-level constructs and utilities such as the process notation, 'awk'
- facility, and parsing utilities. Scheme48 uses disjoint types for some
- values that scsh leaves as symbols or simple integers; these include
- file types, file modes, and user & group ids. Many of the names and
- other interface details are different as well.
- * Menu:
- * POSIX processes::
- * POSIX signals::
- * POSIX process environment::
- * POSIX users and groups::
- * POSIX host OS and machine identification::
- * POSIX file system access::
- * POSIX time::
- * POSIX I/O utilities::
- * POSIX regular expressions::
- * POSIX C to Scheme correspondence::
- File: scheme48.info, Node: POSIX processes, Next: POSIX signals, Up: POSIX interface
- 8.1 Processes
- =============
- The procedures described in this section control the creation of
- subprocesses and the execution of programs. They exported by both the
- 'posix-processes' and 'posix' structures.
- -- procedure: fork --> process id or '#f'
- -- procedure: fork-and-forget thunk --> unspecified
- 'Fork' creates a new child process. In the parent process, it
- returns the child's process id; in the child process, it returns
- '#f'. 'Fork-and-forget' calls THUNK in a new process; no process
- id is returned. 'Fork-and-forget' uses an intermediate process to
- avoid creating a zombie.
- -- procedure: process-id? object --> boolean
- -- procedure: process-id=? pid--_{a} pid--_{b} --> boolean
- -- procedure: process-id->integer pid --> integer
- -- procedure: integer->process-id integer --> pid
- 'Process-id?' is the disjoint type predicate for process ids.
- 'Process-id=?' tests whether two process ids are the same.
- 'Process-id->integer' & 'integer->process-id' convert between
- Scheme48's opaque process id type and POSIX process id integers.
- -- procedure: process-id-exit-status pid --> integer or '#f'
- -- procedure: process-id-terminating-signal pid --> signal or '#f'
- -- procedure: wait-for-child-process pid --> unspecified
- If the process identified by PID exited normally or is running,
- 'process-id-exit-status' and 'process-id-terminating-signal' will
- both return '#f'. If, however, it terminated abnormally,
- 'process-id-exit-status' returns its exit status, and if it exited
- due to a signal then 'process-id-terminating-signal' returns the
- signal due to which it exited. 'Wait-for-child-process' blocks the
- current process until the process identified by PID has terminated.
- Scheme48 may reap child processes before the user requests their
- exit status, but it does not always do so.
- -- procedure: exit status --> does not return
- Terminates the current process with the integer STATUS as its exit
- status.
- -- procedure: exec program argument ... --> does not return
- -- procedure: exec-with-environment program env argument ... --> does
- not return
- -- procedure: exec-file filename argument ... --> does not return
- -- procedure: exec-file-with-environment filename env argument ... -->
- does not return
- These all replace the current program with a new one. They differ
- in how the program is found and what process environment the
- program should receive. 'Exec' & 'exec-with-environment' look up
- the program in the search path (the 'PATH' environment variable),
- while 'exec-file' & 'exec-file-with-environment' execute a
- particular file. The environment is either inherited from the
- current process, in the cases of 'exec' & 'exec-file', or
- explicitly specified, in the cases of 'exec-with-environment' &
- 'exec-file-with-environment'. PROGRAM, FILENAME, & all ARGUMENTs
- should be strings. ENV should be a list of strings of the form
- '"NAME=VALUE"'. When the new program is invoked, its arguments
- consist of the program name prepended to the remaining specified
- arguments.
- -- procedure: exec-with-alias name lookup? maybe-env arguments --> does
- not return
- General omnibus procedure that subsumes the other 'exec' variants.
- NAME is looked up in the search path if LOOKUP? is true or used as
- an ordinary filename if it is false. MAYBE-ENV is either '#f', in
- which case the new program's environment should be inherited from
- the current process, or a list of strings of the above form for
- environments, which specifies the new program's environment.
- ARGUMENTS is a list of _all_ of the program's arguments;
- 'exec-with-alias' does _not_ prepend NAME to that list (hence
- '-with-alias').
- File: scheme48.info, Node: POSIX signals, Next: POSIX process environment, Prev: POSIX processes, Up: POSIX interface
- 8.2 Signals
- ===========
- There are two varieties of signals available, named & anonymous. A
- "named" signal is one for which there is provided a symbolic name, such
- as 'kill' or 'pipe'. Anonymous signals are those that the operating
- system provided but for which POSIX does not define a symbolic name,
- only a number, and which may not have meaning on other operating
- systems. Named signals preserve their meaning through heap image dumps;
- anonymous signals may not be dumped in heap images. (If they are, a
- warning is signalled, and they are replaced with a special token that
- denotes a non-portable signal.) Not all named signals are available
- from all operating systems, and there may be multiple names for a single
- operating system signal number.
- -- syntax: signal name --> signal
- -- procedure: name->signal symbol --> signal or '#f'
- -- procedure: integer->signal integer --> signal
- -- procedure: signal? object --> boolean
- -- procedure: signal-name signal --> symbol or '#f'
- -- procedure: signal-os-number signal --> integer
- -- procedure: signal=? signal--_{a} signal--_{b} --> boolean
- 'Signal' evaluates to the signal object with the known symbolic
- name NAME. It is an error if NAME is not recognized as any
- signal's name. 'Name->signal' returns the signal corresponding
- with the given NAME or '#f' if no such signal is known.
- 'Integer->signal' returns a signal, named or anonymous, with the
- given OS number. 'Signal?' is the disjoint type predicate for
- signal objects. 'Signal-name' returns the symbolic name of SIGNAL
- if it is a named signal or '#f' if it is an anonymous signal.
- 'Signal-OS-number' returns the operating system's integer value of
- SIGNAL. 'Signal=?' tests whether two signals are the same, i.e.
- whether their OS numbers are equal equal.
- These are all of the symbols that POSIX defines.
- 'abrt'
- abnormal termination (as by 'abort(3)')
- 'alrm'
- timeout signal (as by 'alarm(2)')
- 'fpe'
- floating point exception
- 'hup'
- hangup on controlling terminal or death of controlling process
- 'ill'
- illegal instruction
- 'int'
- interrupt -- interaction attention
- 'kill'
- termination signal, cannot be caught or ignored
- 'pipe'
- write was attempted on a pipe with no readers
- 'quit'
- interaction termination
- 'segv'
- segmentation violation -- invalid memory reference
- 'term'
- termination signal
- 'usr1'
- 'usr2'
- for use by applications
- 'chld'
- child process stopped or terminated
- 'cont'
- continue if stopped
- 'stop'
- stop immediately, cannot be caught or ignored
- 'tstp'
- interactive stop
- 'ttin'
- read from control terminal attempted by a background process
- 'ttou'
- write to control terminal attempted by a background process
- 'bus'
- bus error -- access to undefined portion of memory
- There are also several other signals whose names are allowed to be
- passed to 'signal' that are not defined by POSIX, but that are
- recognized by many operating systems.
- 'trap'
- trace or breakpoint trap
- 'iot'
- synonym for 'abrt'
- 'emt'
- 'sys'
- bad argument to routine (SVID)
- 'stkflt'
- stack fault on coprocessor
- 'urg'
- urgent condition on socket (4.2 BSD)
- 'io'
- I/O now possible (4.2 BSD)
- 'poll'
- synonym for 'io' (System V)
- 'cld'
- synonym for 'chld'
- 'xcpu'
- CPU time limit exceeded (4.2 BSD)
- 'xfsz'
- file size limit exceeded (4.2 BSD)
- 'vtalrm'
- virtual alarm clock (4.2 BSD)
- 'prof'
- profile alarm clock
- 'pwr'
- power failure (System V)
- 'info'
- synonym for 'pwr'
- 'lock'
- file lock lost
- 'winch'
- Window resize signal (4.3 BSD, Sun)
- 'unused'
- 8.2.1 Sending & receiving signals
- ---------------------------------
- -- procedure: signal-process pid signal --> unspecified
- Sends a signal represented by SIGNAL to the process identified by
- PID.
- Signals received by the Scheme process can be obtained via one or
- more "signal queues". Each signal queue has a list of monitored signals
- and a queue of received signals that have yet to be consumed from the
- queue. When the Scheme process receives a signal, that signal is added
- to the signal queues that are currently monitoring the signal received.
- -- procedure: make-signal-queue signal-list --> signal-queue
- -- procedure: signal-queue? object --> boolean
- -- procedure: signal-queue-monitored-signals signal-queue -->
- signal-list
- -- procedure: dequeue-signal! signal-queue --> signal (may block)
- -- procedure: maybe-dequeue-signal! signal-queue --> signal or '#f'
- 'Make-signal-queue' returns a new signal queue that will monitor
- all of the signals in the given list. 'Signal-queue?' is the
- disjoint type predicate for signal queues.
- 'Signal-queue-monitored-signals' returns a freshly-allocated list
- of the signals currently monitored by SIGNAL-QUEUE.
- 'Dequeue-signal!' & 'maybe-dequeue-signal!' both access the next
- signal ready to be read from SIGNAL-QUEUE. If the signal queue is
- empty, 'dequeue-signal!' will block until a signal is received,
- while 'maybe-dequeue-signal!' will immediately return '#f'.
- *Note:* There is a bug in the current system that causes an erroneous
- deadlock to occur if threads are blocked waiting for signals and no
- other threads are available to run. A workaround is to create a thread
- that sleeps for a long time, which prevents any deadlock errors
- (including real ones):
- > ,open threads
- > (spawn (lambda ()
- ;; Sleep for a year.
- (sleep (* 1000 60 60 24 365))))
- -- procedure: add-signal-queue-signal! signal-queue signal -->
- unspecified
- -- procedure: remove-signal-queue-signal! signal-queue signal -->
- unspecified
- These add & remove signals from signal queues' list of signals to
- monitor. Note that 'remove-signal-queue-signal!' also removes any
- pending signals from the queue, so 'dequeue-signal!' &
- 'maybe-dequeue-signal!' will only ever return signals that are on
- the queue's list of monitored signals when they are called.
- File: scheme48.info, Node: POSIX process environment, Next: POSIX users and groups, Prev: POSIX signals, Up: POSIX interface
- 8.3 Process environment
- =======================
- These procedures are exported by the structures 'posix' &
- 'posix-process-data'.
- -- procedure: get-process-id --> process-id
- -- procedure: get-parent-process-id --> process-id
- These return the process id (*note POSIX processes::) of the
- current process or the current process's parent, respectively.
- -- procedure: get-user-id --> user-id
- -- procedure: get-effective-user-id --> user-id
- -- procedure: set-user-id! user-id --> unspecified
- -- procedure: get-group-id --> group-id
- -- procedure: get-effective-group-id --> group-id
- -- procedure: set-group-id! group-id --> unspecified
- These access the original and effective user & group ids (*note
- POSIX users and groups::) of the current process. The effective
- ids may be set, but not the original ones.
- -- procedure: get-groups --> group-id list
- -- procedure: get-login-name --> string
- 'Get-groups' returns a list of the supplementary groups of the
- current process. 'Get-login-name' returns a user name for the
- current process.
- -- procedure: lookup-environment-variable string --> string or '#f'
- -- procedure: environment-alist --> alist
- 'Lookup-environment-variable' looks up its argument in the
- environment list of the current process and returns the
- corresponding string, or '#f' if there is none.
- 'Environment-alist' returns the entire environment as a list of
- '(NAME-STRING . VALUE-STRING)' pairs.
- File: scheme48.info, Node: POSIX users and groups, Next: POSIX host OS and machine identification, Prev: POSIX process environment, Up: POSIX interface
- 8.4 Users and groups
- ====================
- "User ids" & "group ids" are boxed integers that represent Unix users &
- groups. Also, every user & group has a corresponding "user info" or
- "group info" record, which contains miscellaneous information about the
- user or group. The procedures in this section are exported by the
- structures 'posix-users' & 'posix'.
- -- procedure: user-id? object --> boolean
- -- procedure: user-id=? uid--_{a} uid--_{b} --> boolean
- -- procedure: user-id->integer uid --> integer
- -- procedure: integer->user-id integer --> uid
- -- procedure: group-id? object --> boolean
- -- procedure: group-id=? gid--_{a} gid--_{b} --> boolean
- -- procedure: group-id->integer gid --> integer
- -- procedure: integer->group-id integer --> gid
- 'User-id?' & 'group-id?' are the disjoint type predicates for user
- & group ids. 'User-id=?' & 'group-id=?' test whether two user or
- group ids, respectively, are the same, i.e. whether their numbers
- are equal. 'User-id->integer', 'group-id->integer',
- 'integer->user-id', & 'integer->group-id' convert between user or
- group ids and integers.
- -- procedure: user-id->user-info uid --> user-info
- -- procedure: name->user-info string --> user-info
- -- procedure: group-id->group-info gid --> group-info
- -- procedure: name->group-info string --> group-info
- These provide access for the user or group info records that
- correspond with the given user or group ids or names.
- -- procedure: user-info? object --> boolean
- -- procedure: user-info-name user-info --> string
- -- procedure: user-info-id user-info --> user-id
- -- procedure: user-info-group user-info --> group-id
- -- procedure: user-info-home-directory user-info --> string
- -- procedure: user-info-shell user-info --> string
- -- procedure: group-info? object --> boolean
- -- procedure: group-info-name group-info --> string
- -- procedure: group-info-id group-info --> group-id
- -- procedure: group-info-members group-info --> user-id-list
- 'User-info?' & 'group-info?' are the disjoint type predicates for
- user info & group info records. The others are accessors for the
- various data available in those records.
- File: scheme48.info, Node: POSIX host OS and machine identification, Next: POSIX file system access, Prev: POSIX users and groups, Up: POSIX interface
- 8.5 Host OS and machine identification
- ======================================
- -- procedure: host-name --> string
- -- procedure: os-node-name --> string
- -- procedure: os-release-name --> string
- -- procedure: os-version-name --> string
- -- procedure: machine-name --> string
- These procedures return strings that are intended to identify
- various aspects of the current operating system and physical
- machine. POSIX does not specify the format of the strings. These
- procedures are provided by both the structure
- 'posix-platform-names' and the structure 'posix'.
- File: scheme48.info, Node: POSIX file system access, Next: POSIX time, Prev: POSIX host OS and machine identification, Up: POSIX interface
- 8.6 File system access
- ======================
- These procedures operate on the file system via the facilities defined
- by POSIX and offer more than standard & portable R5RS operations. All
- of these names are exported by the structures 'posix-files' and 'posix'.
- -- procedure: open-directory-stream filename --> dir-stream
- -- procedure: directory-stream? object --> boolean
- -- procedure: read-directory-stream dir-stream --> filename or '#f'
- -- procedure: close-directory-stream dir-stream --> unspecified
- Directory streams are the low-level interface provided by POSIX to
- enumerate the contents of a directory. 'Open-directory-stream'
- opens a new directory stream that will enumerate all of the files
- within the directory named by FILENAME. 'Directory-stream?' is the
- disjoint type predicate for directory streams.
- 'Read-directory-stream' consumes the next filename from DIR-STREAM
- and returns it, or returns '#f' if the stream has finished. Note
- that 'read-directory-stream' will return only simple filenames, not
- full pathnames. 'Close-directory-stream' closes DIR-STREAM,
- removing any storage it required in the operating system. Closing
- an already closed directory stream has no effect.
- -- procedure: list-directory filename --> string list
- Returns the list of filenames in the directory named by FILENAME.
- This is equivalent to opening a directory stream, repeatedly
- reading from it & accumulating the list of filenames, and closing
- the stream.
- -- procedure: working-directory --> string
- -- procedure: set-working-directory! string --> unspecified
- These access the working directory's filename of the current
- process.
- -- procedure: open-file pathname file-options [file-mode] --> port
- Opens a port to the file named by the string PATHNAME.
- FILE-OPTIONS specifies various aspects of the port. The optional
- FILE-MODE argument is used only if the file to be opened does not
- already exist; it specifies the permissions to be assigned to the
- file if it is created. The returned port is an input port if the
- given options include 'read-only'; otherwise 'open-file' returns an
- output port. Because Scheme48 does not support combined
- input/output ports, 'dup-switching-mode' can be used to open an
- input port for output ports opened with the 'read-write' option.
- File options are stored in a boxed mask representation. File option
- sets are created with 'file-options' and tested with 'file-options-on?'.
- -- syntax: file-options name ... --> file-options
- -- procedure: file-options-on? options--_{a} options--_{b} --> boolean
- 'File-options' evaluates to a file option set, suitable for passing
- to 'open-file', that includes all of the given named options.
- 'File-options-on?' returns true if OPTIONS-_{A} includes all of the
- options in OPTIONS-_{B}, or false if otherwise.
- The following file option names are supported as arguments to the
- 'file-options' syntax:
- 'create'
- create file if it does not already exist; a FILE-MODE argument
- is required to be passed to 'open-file' if the 'create' option
- is specified
- 'exclusive'
- an error will be signalled if this option & 'create' are both
- set and the file already exists
- 'no-controlling-tty'
- if the pathname being opened is a terminal device, the
- terminal will not become the controlling terminal of the
- process
- 'truncate'
- file is truncated
- 'append'
- written data to the newly opened file will be appended to the
- existing contents
- 'nonblocking'
- read & write operations will not block
- 'read-only'
- file may not be written to, only read from
- 'read-write'
- file may be both read from & written to
- 'write-only'
- file may not be read from, only written to
- The last three are all mutually exclusive.
- Examples:
- (open-file "some-file.txt"
- (file-options create write-only)
- (file-mode read owner-write))
- returns an output port that writes to a newly-created file that can be
- read from by anyone but written to only by the owner. Once the file
- 'some-file.txt' exists,
- (open-file "some-file.txt"
- (file-options append write-only))
- will open an output port that appends to the file.
- 'I/o-flags' & 'set-i/o-flags!' (*note POSIX I/O utilities::) can be
- used to access the 'append', 'nonblocking', and read/write file options
- of ports, as well as modify the 'append' & 'nonblocking' options.
- To keep port operations from blocking in the Scheme48 process, output
- ports are set to be nonblocking at the time of creation. (Input ports
- are managed using 'select(2)'.) 'Set-i/o-flags!' can be used to make an
- output port blocking, for example directly before forking, but care
- should be exercised, because the Scheme48 run-time system may be
- confused if an I/O operation blocks.
- -- procedure: set-file-creation-mask! file-mode --> file-mode
- Sets the file creation mask to be FILE-MODE. Bits set in FILE-MODE
- are cleared in the modes of any files or directories subsequently
- created by the current process.
- -- procedure: link existing-pathname new-pathname --> unspecified
- -- procedure: make-directory pathname file-mode --> unspecified
- -- procedure: make-fifo pathname file-mode --> unspecified
- 'Link' creates a hard link for the file at EXISTING-PATHNAME at
- NEW-PATHNAME. 'Make-directory' creates a new directory at the
- locations specified by PATHNAME with the the file mode FILE-MODE.
- 'Make-fifo' does similarly, but it creates a FIFO (first-in
- first-out) file instead of a directory.
- -- procedure: unlink pathname --> unspecified
- -- procedure: remove-directory pathname --> unspecified
- -- procedure: rename old-pathname new-pathname --> unspecified
- 'Unlink' removes a link at the location PATHNAME.
- 'Remove-directory' removes a directory at the location specified by
- PATHNAME. The directory must be empty; an exception is signalled
- if it is not. 'Rename' moves the file at the location OLD-PATHNAME
- to the new location NEW-PATHNAME.
- -- procedure: accessible? pathname access-mode more-modes ... -->
- boolean
- -- syntax: access-mode name --> access mode
- 'Accessible?' returns true if PATHNAME is accessible by all of the
- given access modes. (There must be at least one access mode
- argument.) 'Access-mode' evaluates to an access mode, suitable for
- passing to 'accessible?', from the given name. The allowed names
- are 'read', 'write', 'execute', & 'exists'.
- Information about files can be queried using the "file info"
- abstraction. Every file has a corresponding file info record, which
- contains various data about the file including its name, its type, its
- device & inode numbers, the number of links to it, its size in bytes,
- its owner, its group, its file mode, and its access times.
- -- procedure: get-file-info pathname --> file-info
- -- procedure: get-file/link-info pathname --> file-info
- -- procedure: get-port-info fd-port --> file-info
- 'Get-file-info' & 'get-file/link-info' return a file info record
- for the files named by PATHNAME. 'Get-file-info' follows symbolic
- links, however, while 'get-file/link' info does not.
- 'Get-port-info' returns a file info record for the file that
- FD-PORT is a port atop a file descriptor for. If FD-PORT does not
- read from or write to a file descriptor, an error is signalled.
- -- procedure: file-info? object --> boolean
- -- procedure: file-info-name file-info --> string
- -- procedure: file-info-device file-info --> integer
- -- procedure: file-info-inode file-info --> integer
- -- procedure: file-info-link-count file-info --> integer
- -- procedure: file-info-size file-info --> integer
- -- procedure: file-info-owner file-info --> user-id
- -- procedure: file-info-group file-info --> group-id
- -- procedure: file-info-mode file-info --> file-mode
- -- procedure: file-info-last-access file-info --> time
- -- procedure: file-info-last-modification file-info --> time
- -- procedure: file-info-last-change file-info --> time
- Accessors for various file info record fields. The name is the
- string passed to 'get-file-info' or 'get-file/link-info', if the
- file info record was created with either of those two, or the name
- of the file that the file descriptor of the port queried was
- created on, if the file info record was obtained with
- 'get-port-info'.
- -- procedure: file-info-type file-info --> file-type
- -- syntax: file-type name --> file-type
- -- procedure: file-type? object --> boolean
- -- procedure: file-type-name file-type --> symbol
- 'File-info-type' returns the type of the file as a "file type"
- object. File types may be compared using 'eq?'. 'File-type'
- evaluates to a file type of the given name. The disjoint type
- predicate for file types is 'file-type?'. 'File-type-name' returns
- the symbolic name that represents FILE-TYPE.
- The valid file type names are:
- 'regular'
- 'directory'
- 'character-device'
- 'block-device'
- 'fifo'
- 'symbolic-link' (not required by POSIX)
- 'socket' (not required by POSIX)
- 'other'
- "File modes" are boxed integers that represent POSIX file protection
- masks.
- -- syntax: file-mode permission-name ... --> file-mode
- -- procedure: file-mode? object --> boolean
- 'File-mode' evaluates to a file mode object that contains all of
- the specified permissions. 'File-mode?' is the disjoint type
- predicate for file mode descriptor objects. These are all of the
- names, with their corresponding octal bit masks and meanings,
- allowed to be passed to 'file-mode':
- Permission name Octal mask Description
- 'set-uid' '#o4000' set user id when executing
- 'set-gid' '#o2000' set group id when executing
- 'owner-read' '#o0400' read by owner
- 'owner-write' '#o0200' write by owner
- 'owner-exec' '#o0100' execute (or search) by owner
- 'group-read' '#o0040' read by group
- 'group-write' '#o0020' write by group
- 'group-exec' '#o0010' execute (or search) by group
- 'other-read' '#o0004' read by others
- 'other-write' '#o0002' write by others
- 'other-exec' '#o0001' execute (or search) by others
- Also, several compound masks are supported for convenience:
- Permission set name Octal mask Description
- 'owner' '#o0700' read, write, & execute by owner
- 'group' '#o0070' read, write, & execute by group
- 'other' '#o0007' read, write, & execute by others
- 'read' '#o0444' read by anyone
- 'write' '#o0111' write by anyone
- 'exec' '#o0777' read, write, & execute by anyone
- -- procedure: file-mode+ file-mode ... --> file-mode
- -- procedure: file-mode- file-mode--_{a} file-mode--_{b} --> file-mode
- -- procedure: file-mode=? file-mode--_{a} file-mode--_{b} --> boolean
- -- procedure: file-mode<=? file-mode--_{a} file-mode--_{b} --> boolean
- -- procedure: file-mode>=? file-mode--_{a} file-mode--_{b} --> boolean
- 'File-mode+' returns a file mode that contains all of the
- permissions specified in any of its arguments. 'File-mode-'
- returns a file mode that contains all of FILE-MODE-_{A}'s
- permissions not in FILE-MODE-_{B}. 'File-mode=?' tests whether two
- file modes are the same. 'File-mode<=?' returns true if each
- successive file mode argument has the same or more permissions as
- the previous one. 'File-mode>=?' returns true if each successive
- file mode argument has the same or fewer permissions as the
- previous one.
- -- procedure: file-mode->integer file-mode --> integer
- -- procedure: integer->file-mode integer --> file-mode
- These convert between file mode objects and Unix file mode masks as
- integers. The integer representations may or may not be the masks
- used by the underlying operating system.
- File: scheme48.info, Node: POSIX time, Next: POSIX I/O utilities, Prev: POSIX file system access, Up: POSIX interface
- 8.7 Time
- ========
- A "time" record contains an integer that represents a time as the number
- of seconds since the Unix epoch (00:00:00 GMT, January 1, 1970). These
- procedures for operating on time records are in the structures
- 'posix-time' & 'posix'.
- -- procedure: make-time seconds --> time
- -- procedure: current-time --> time
- -- procedure: time? object --> boolean
- -- procedure: time-seconds time --> integer
- 'Make-time' & 'current-time' construct time records; 'make-time'
- uses the number of seconds that is its argument, and 'current-time'
- uses the current number of seconds since the epoch. 'Time?' is the
- disjoint type predicate for time objects. 'Time-seconds' returns
- the number of seconds recorded by TIME.
- -- procedure: time=? time--_{a} time--_{b} --> boolean
- -- procedure: time<? time--_{a} time--_{b} --> boolean
- -- procedure: time<=? time--_{a} time--_{b} --> boolean
- -- procedure: time>? time--_{a} time--_{b} --> boolean
- -- procedure: time>=? time--_{a} time--_{b} --> boolean
- Various time comparators. 'Time=?' returns true if its two
- arguments represent the same number of seconds since the epoch.
- 'Time<?', 'time<=?', 'time>?', & 'time>=' return true if their
- arguments are monotonically increasing, monotonically
- non-decreasing, monotonically decreasing, or monotonically
- non-increasing, respectively.
- -- procedure: time->string time --> string
- Returns a string representation of TIME in the format of '"DDD MMM
- HH:MM:SS YYYY"'. For example,
- (time->string (make-time 1234567890))
- => "Fri Feb 13 18:31:30 2009"
- *Note:* The string has a newline suffix.
- File: scheme48.info, Node: POSIX I/O utilities, Next: POSIX regular expressions, Prev: POSIX time, Up: POSIX interface
- 8.8 I/O utilities
- =================
- These procedures for manipulating pipes and ports built on file
- descriptors are provided by the structures 'posix-i/o' & 'posix'.
- -- procedure: open-pipe --> [input-port output-port]
- Creates a pipe and returns the two ends of the pipe as an input
- port & an output port.
- A "file descriptor port" (or "fd-port") is a port or a channel (*note
- Channels::) that reads from or writes to an OS file descriptor. File
- descriptor ports are returned by the standard Scheme procedures
- 'open-input-file' & 'open-output-file' as well as the procedures
- 'open-file' & 'open-pipe' from this POSIX interface.
- -- procedure: fd-port? port --> boolean
- -- procedure: port->fd port --> integer or '#f'
- 'Fd-port?' returns true if PORT is a port that reads from or writes
- to a file descriptor, or false if not. 'Port->fd' returns the file
- descriptor that PORT reads from or writes to, if it is a file
- descriptor port, or '#f' if it is not. It is an error to pass a
- value that is not a port to either of these procedures.
- *Note:* Channels may _not_ be passed to these procedures. To
- access a channel's file descriptor, use 'channel-os-index'; *note
- Channels:: for more details.
- -- procedure: remap-file-descriptors! fd-spec ... --> unspecified
- Reassigns file descriptors to ports. Each FD-SPEC specifies what
- port is to be mapped to what file descriptor: the first port gets
- file descriptor '0'; the second, '1'; and so on. An FD-SPEC is
- either a port that reads from or writes to a file descriptor or
- '#f'; in the latter case, the corresponding file descriptor is not
- used. Any open ports not listed are marked _close-on-exec_. The
- same port may be moved to multiple new file descriptors.
- For example,
- (remap-file-descriptors! (current-output-port)
- #f
- (current-input-port))
- moves the current output port to file descriptor '0' (i.e. 'stdin')
- and the current input port to file descriptor '2' (i.e. 'stderr').
- File descriptor '1' ('stdout') is not mapped to anything, and all
- other open ports (including anything that had the file descriptor
- '1') are marked _close-on-exec_.
- -- procedure: dup fd-port --> fd-port
- -- procedure: dup-switching-mode fd-port --> fd-port
- -- procedure: dup2 fd-port fdes --> fd-port
- These change FD-PORT's file descriptor and return new ports that
- have the ports' old file descriptors. 'Dup' uses the lowest unused
- file descriptor; 'dup2' uses the one provided.
- 'Dup-switching-mode' is the same as 'dup' except that the returned
- port is an input port if the argument was an output port and vice
- versa. If any existing port uses the file descriptor passed to
- 'dup2', that port is closed.
- -- procedure: close-all-port port-or-channel ... --> unspecified
- Closes all ports or channels not listed as arguments.
- -- procedure: close-on-exec? channel --> boolean
- -- procedure: set-close-on-exec?! channel boolean --> unspecified
- These access the boolean flag that specifies whether CHANNEL will
- be closed when a new program is 'exec''d.
- -- procedure: i/o-flags fd-port --> file-options
- -- procedure: set-i/o-flags! fd-port file-options --> unspecified
- These access various file options (*note POSIX file system
- access::) for FD-PORT. The options that may be read are 'append',
- 'nonblocking', 'read-only', 'read-write', and 'write-only'; only
- the 'append' and 'nonblocking' options can be written.
- -- procedure: port-is-a-terminal? port --> boolean
- -- procedure: port-terminal-name port --> string or '#f'
- 'Port-is-a-terminal?' returns true of PORT is a port that has an
- underlying file descriptor associated with a terminal. For such
- ports, 'port-terminal-name' returns the name of the terminal; for
- all others, it returns '#f'.
- *Note:* These procedures accept only ports, not channels.
- File: scheme48.info, Node: POSIX regular expressions, Next: POSIX C to Scheme correspondence, Prev: POSIX I/O utilities, Up: POSIX interface
- 8.9 Regular expressions
- =======================
- The procedures in this section provide access to POSIX regular
- expression matching. The regular expression syntax and semantics are
- far too complex to be described here.
- *Note:* Because the C interface uses ASCII 'NUL' bytes to mark the
- ends of strings, patterns & strings that contain 'NUL' characters will
- not work correctly.
- 8.9.1 Direct POSIX regular expression interface
- -----------------------------------------------
- The first interface to regular expressions is a thin layer over the
- interface that POSIX provides. It is exported by the structures
- 'posix-regexps' & 'posix'.
- -- procedure: make-regexp string option ... --> regexp
- -- procedure: regexp? object --> boolean
- 'Make-regexp' creates a regular expression with the given string
- pattern. The arguments after STRING specify various options for
- the regular expression; see 'regexp-option' below. The regular
- expression is not compiled until it is matched against a string, so
- any errors in the pattern string will not be reported until that
- point. 'Regexp?' is the disjoint type predicate for regular
- expression objects.
- -- syntax: regexp-option name --> regexp-option
- Evaluates to a regular expression option, suitable to be passed to
- 'make-regexp', with the given name. The possible option names are:
- 'extended'
- use the extended patterns
- 'ignore-case'
- ignore case differences when matching
- 'submatches'
- report submatches
- 'newline'
- treat newlines specially
- -- procedure: regexp-match regexp string start submatches? starts-line?
- ends-line? --> boolean or list of matches
- 'Regexp-match' matches REGEXP against the characters in STRING,
- starting at position START. If the string does not match the
- regular expression, 'regexp-match' returns '#f'. If the string
- does match, then a list of match records is returned if SUBMATCHES?
- is true or '#t' if SUBMATCHES? is false. The first match record
- gives the location of the substring that matched REGEXP. If the
- pattern in REGEXP contained submatches, then the submatches are
- returned in order, with match records in the positions where
- submatches succeeded and '#f' in the positions where submatches
- failed.
- STARTS-LINE? should be true if STRING starts at the beginning of a
- line, and ENDS-LINE? should be true if it ends one.
- -- procedure: match? object --> boolean
- -- procedure: match-start match --> integer
- -- procedure: match-end match --> integer
- -- procedure: match-submatches match --> alist
- 'Match?' is the disjoint type predicate for match records. Match
- records contain three values: the beginning & end of the substring
- that matched the pattern and an association list of submatch keys
- and corresponding match records for any named submatches that also
- matched. 'Match-start' returns the index of the first character in
- the matching substring, and 'match-end' gives the index of the
- first character after the matching substring. 'Match-submatches'
- returns the alist of submatches.
- 8.9.2 High-level regular expression construction
- ------------------------------------------------
- This section describes a functional interface for building regular
- expressions and matching them against strings, higher-level than the
- direct POSIX interface. The matching is done using the POSIX regular
- expression package. Regular expressions constructed by procedures
- listed here are compatible with those in the previous section; that is,
- they satisfy the predicate 'regexp?' from the 'posix-regexps' structure.
- These names are exported by the structure 'regexps'.
- 8.9.2.1 Character sets
- ......................
- Character sets may be defined using a list of characters and strings,
- using a range or ranges of characters, or by using set operations on
- existing character sets.
- -- procedure: set char-or-string ... --> char-set-regexp
- -- procedure: range low-char high-char --> char-set-regexp
- -- procedure: ranges low-char high-char ... --> char-set-regexp
- -- procedure: ascii-range low-char high-char --> char-set-regexp
- -- procedure: ascii-ranges low-char high-char ... --> char-set-regexp
- 'Set' returns a character set that contains all of the character
- arguments and all of the characters in all of the string arguments.
- 'Range' returns a character set that contains all characters
- between LOW-CHAR and HIGH-CHAR, inclusive. 'Ranges' returns a set
- that contains all of the characters in the given set of ranges.
- 'Range' & 'ranges' use the ordering imposed by 'char->integer'.
- 'Ascii-range' & 'ascii-ranges' are like 'range' & 'ranges', but
- they use the ASCII ordering. 'Ranges' & 'ascii-ranges' must be
- given an even number of arguments. It is an error for a HIGH-CHAR
- to be less than the preceding LOW-CHAR in the appropriate ordering.
- -- procedure: negate char-set --> char-set-regexp
- -- procedure: union char-set--_{a} char-set--_{b} --> char-set-regexp
- -- procedure: intersection char-set--_{a} char-set--_{b} -->
- char-set-regexp
- -- procedure: subtract char-set--_{a} char-set--_{b} -->
- char-set-regexp
- Set operations on character sets. 'Negate' returns a character set
- of all characters that are not in CHAR-SET. 'Union' returns a
- character set that contains all of the characters in CHAR-SET-_{A}
- and all of the characters in CHAR-SET-_{B}. 'Intersection' returns
- a character set of all of the characters that are in both
- CHAR-SET-_{A} and CHAR-SET-_{B}. 'Subtract' returns a character
- set of all the characters in CHAR-SET-_{A} that are not also in
- CHAR-SET-_{B}.
- -- character set: lower-case = '(set "abcdefghijklmnopqrstuvwxyz")'
- -- character set: lower-case = '(set "abcdefghijklmnopqrstuvwxyz")'
- -- character set: upper-case = '(set "ABCDEFGHIJKLMNOPQRSTUVWXYZ")'
- -- character set: alphabetic = '(union lower-case upper-case)'
- -- character set: numeric = '(set "0123456789")'
- -- character set: alphanumeric = '(union alphabetic numeric)'
- -- character set: punctuation = '(set
- "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")'
- -- character set: graphic = '(union alphanumeric punctuation)'
- -- character set: printing = '(union graphic (set #\space))'
- -- character set: control = '(negate printing)'
- -- character set: blank = '(set #\space (ascii->char 9)) ; ASCII 9 =
- TAB'
- -- character set: whitespace = '(union (set #\space) (ascii-range 9
- 13))'
- -- character set: hexdigit = '(set "0123456789ABCDEF")'
- Predefined character sets.
- 8.9.2.2 Anchoring
- .................
- -- procedure: string-start --> regexp
- -- procedure: string-end --> regexp
- 'String-start' returns a regular expression that matches the
- beginning of the string being matched against; 'string-end' returns
- one that matches the end.
- 8.9.2.3 Composite expressions
- .............................
- -- procedure: sequence regexp ... --> regexp
- -- procedure: one-of regexp ... --> regexp
- 'Sequence' returns a regular expression that matches concatenation
- of all of its arguments; 'one-of' returns a regular expression that
- matches any one of its arguments.
- -- procedure: text string --> regexp
- Returns a regular expression that matches exactly the characters in
- STRING, in order.
- -- procedure: repeat regexp --> regexp
- -- procedure: repeat count regexp --> regexp
- -- procedure: repeat min max regexp --> regexp
- 'Repeat' returns a regular expression that matches zero or more
- occurrences of its REGEXP argument. With only one argument, the
- result will match REGEXP any number of times. With two arguments,
- i.e. one COUNT argument, the returned regular expression will match
- REGEXP exactly that number of times. The final case will match
- from MIN to MAX repetitions, inclusive. MAX may be '#f', in which
- case there is no maximum number of matches. COUNT & MIN must be
- exact, non-negative integers; MAX should be either '#f' or an
- exact, non-negative integer.
- 8.9.2.4 Case sensitivity
- ........................
- Regular expressions are normally case-sensitive, but case sensitivity
- can be manipulated simply.
- -- procedure: ignore-case regexp --> regexp
- -- procedure: use-case regexp --> regexp
- The regular expression returned by 'ignore-case' is identical to
- its argument except that the case will be ignored when matching.
- The value returned by 'use-case' is protected from future
- applications of 'ignore-case'. The expressions returned by
- 'use-case' and 'ignore-case' are unaffected by any enclosing uses
- of these procedures.
- By way of example, the following matches '"ab"', but not '"aB"',
- '"Ab"', or '"AB"':
- (text "ab")
- while
- (ignore-case (text "ab"))
- matches all of those, and
- (ignore-case (sequence (text "a")
- (use-case (text "b"))))
- matches '"ab"' or '"Ab"', but not '"aB"' or '"AB"'.
- 8.9.2.5 Submatches and matching
- ...............................
- A subexpression within a larger expression can be marked as a submatch.
- When an expression is matched against a string, the success or failure
- of each submatch within that expression is reported, as well as the
- location of the substring matched by each successful submatch.
- -- procedure: submatch key regexp --> regexp
- -- procedure: no-submatches regexp --> regexp
- 'Submatch' returns a regular expression that is equivalent to
- REGEXP in every way except that the regular expression returned by
- 'submatch' will produce a submatch record in the output for the
- part of the string matched by REGEXP. 'No-submatches' returns a
- regular expression that is equivalent to REGEXP in every respect
- except that all submatches generated by REGEXP will be ignored &
- removed from the output.
- -- procedure: any-match? regexp string --> boolean
- -- procedure: exact-match? regexp string --> boolean
- -- procedure: match regexp string --> match or '#f'
- 'Any-match?' returns '#t' if STRING matches REGEXP or contains a
- substring that does, or '#f' if otherwise. 'Exact-match?' returns
- '#t' if STRING matches REGEXP exactly, or '#f' if it does not.
- 'Match' returns '#f' if STRING does not match REGEXP, or a match
- record if it does, as described in the previous section. Matching
- occurs according to POSIX. The match returned is the one with the
- lowest starting index in STRING. If there is more than one such
- match, the longest is returned. Within that match, the longest
- possible submatches are returned.
- All three matching procedures cache a compiled version of REGEXP.
- Subsequent calls with the same input regular expression will be
- more efficient.
- Here are some examples of the high-level regular expression
- interface:
- (define pattern (text "abc"))
- (any-match? pattern "abc") => #t
- (any-match? pattern "abx") => #f
- (any-match? pattern "xxabcxx") => #t
- (exact-match? pattern "abc") => #t
- (exact-match? pattern "abx") => #f
- (exact-match? pattern "xxabcxx") => #f
- (let ((m (match (sequence (text "ab")
- (submatch 'foo (text "cd"))
- (text "ef")))
- "xxabcdefxx"))
- (list m (match-submatches m)))
- => (#{Match 3 9} ((foo . #{Match 5 7})))
- (match-submatches
- (match (sequence (set "a")
- (one-of (submatch 'foo (text "bc"))
- (submatch 'bar (text "BC"))))
- "xxxaBCd"))
- => ((bar . #{Match 4 6}))
- File: scheme48.info, Node: POSIX C to Scheme correspondence, Prev: POSIX regular expressions, Up: POSIX interface
- 8.10 C to Scheme correspondence
- ===============================
- 'access'
- 'accessible?'
- 'chdir'
- 'set-working-directory!'
- 'close'
- 'close-input-port, close-output-port, close-channel, close-socket'
- 'closedir'
- 'close-directory-stream'
- 'creat'
- 'open-file'
- 'ctime'
- 'time->string'
- 'dup'
- 'dup, dup-switching-mode'
- 'dup2'
- 'dup2'
- 'exec[l|v][e|p|eps]'
- 'exec, exec-with-environment, exec-file,
- exec-file-with-environment, exec-with-alias'
- '_exit'
- 'exit'
- 'fcntl'
- 'i/o-flags, set-i/o-flags!, close-on-exec?, set-close-on-exec?!'
- 'fork'
- 'fork, fork-and-forget'
- 'fstat'
- 'get-port-info'
- 'getcwd'
- 'working-directory'
- 'getegid'
- 'get-effective-group-id'
- 'getenv'
- 'lookup-environment-variable, environment-alist'
- 'geteuid'
- 'get-effective-user-id'
- 'getgid'
- 'get-group-id'
- 'getgroups'
- 'get-login-name'
- 'getpid'
- 'get-process-id'
- 'getppid'
- 'get-parent-process-id'
- 'getuid'
- 'get-user-id'
- 'isatty'
- 'port-is-a-terminal?'
- 'link'
- 'link'
- 'lstat'
- 'get-file/link-info'
- 'mkdir'
- 'make-directory'
- 'mkfifo'
- 'make-fifo'
- 'open'
- 'open-file'
- 'opendir'
- 'open-directory-stream'
- 'pipe'
- 'open-pipe'
- 'read'
- 'read-char, read-block'
- 'readdir'
- 'read-directory-stream'
- 'rename'
- 'rename'
- 'rmdir'
- 'remove-directory'
- 'setgid'
- 'set-group-id!'
- 'setuid'
- 'set-user-id!'
- 'stat'
- 'get-file-info'
- 'time'
- 'current-time'
- 'ttyname'
- 'port-terminal-name'
- 'umask'
- 'set-file-creation-mask!'
- 'uname'
- 'os-name, os-node-name, os-release-name, os-version-name,
- machine-name'
- 'unlink'
- 'unlink'
- 'waitpid'
- 'wait-for-child-process'
- 'write'
- 'write-char, write-block'
- File: scheme48.info, Node: Pre-Scheme, Next: References, Prev: POSIX interface, Up: Top
- 9 Pre-Scheme: A low-level dialect of Scheme
- *******************************************
- Pre-Scheme [Kelsey 97] is a low-level dialect of Scheme, designed for
- systems programming with higher-level abstractions. For example, the
- Scheme48 virtual machine is written in Pre-Scheme. Pre-Scheme is a
- particularly interesting alternative to C for many systems programming
- tasks, because not only does it operate at about the same level as C,
- but it also may be run in a regular high-level Scheme development with
- no changes to the source, without resorting to low-level stack munging
- with tools such as gdb. Pre-Scheme also supports two _extremely_
- important high-level abstractions of Scheme: macros and higher-order,
- anonymous functions. Richard Kelsey's Pre-Scheme compiler, based on his
- PhD research on transformational compilation [Kelsey 89], compiles
- Pre-Scheme to efficient C, applying numerous intermediate source
- transformations in the process.
- This chapter describes details of the differences between Scheme and
- Pre-Scheme, listings of the default environment and other packages
- available to Pre-Scheme, the operation of Richard Kelsey's Pre-Scheme
- compiler, and how to run Pre-Scheme code as if it were Scheme in a
- regular Scheme environment.
- * Menu:
- * Differences between Pre-Scheme & Scheme::
- * Pre-Scheme type specifiers::
- * Standard Pre-Scheme environment::
- * More Pre-Scheme packages::
- * Invoking the Pre-Scheme compiler::
- * Example Pre-Scheme compiler usage::
- * Running Pre-Scheme as Scheme::
- File: scheme48.info, Node: Differences between Pre-Scheme & Scheme, Next: Pre-Scheme type specifiers, Up: Pre-Scheme
- 9.1 Differences between Pre-Scheme & Scheme
- ===========================================
- Pre-Scheme is often considered either a dialect of Scheme or a subset of
- Scheme. However, there are several very important fundamental
- differences between the semantics of Pre-Scheme & Scheme to detail.
- *There is no garbage collector in Pre-Scheme.*
- All memory management is manual, as in C, although there are two
- levels to memory management, for higher- and lower-level purposes:
- pointers & addresses. Pointers represent higher-level data that
- are statically checked for type coherency, such as vectors of a
- certain element type, or strings. Addresses represent direct,
- low-level memory indices.
- *Pre-Scheme has no closures.*
- 'Lambda' expressions that would require full closures at run-time
- -- e.g., those whose values are stored in the heap -- are not
- permitted in Pre-Scheme. However, the Pre-Scheme compiler can
- hoist many 'lambda' expressions to the top level, removing the need
- of closures for them. (Closures would be much less useful in the
- absence of garbage collection, in any case.) If the Pre-Scheme
- compiler is unable to move a 'lambda' to a place where it requires
- no closure, it signals an error to the user.
- *Tail call optimization is not universal.*
- The Pre-Scheme compiler optimizes tail calls where it is possible
- -- typically, just in local loops and top-level procedures that are
- not exported from the package, but there are other heuristics --,
- but it is not universal. Programmers may force tail call
- optimization with Pre-Scheme's 'goto' special form (*note Tail call
- optimization in Pre-Scheme::), but, in situations where the
- compiler would not have optimized the tail call, this can make the
- generated code have to jump through many hoops to be a tail call --
- often necessitating code bloat, because the code of the tail-called
- procedure is integrated into the caller's driver loop --; and,
- where the compiler would have otherwise optimized the tail call,
- 'goto' has no effect anyway.
- *Types are strictly verified with Hindley-Milner type inference.*
- The types of Pre-Scheme programs are statically verified based on
- Hindley-Milner type inference, with some modifications specific to
- Pre-Scheme. Type information is _not_ retained at run-time; any
- tagging must be performed explicitly.
- *Pre-Scheme does not support first-class continuations.*
- There is no 'call-with-current-continuation' or other continuation
- manipulation interface. It has been suggested that downward-only
- continuations, based on C's 'setjmp' & 'longjmp', might be
- implemented in the future, but this is not yet the case.(1)
- *The full numeric tower of R5RS is not supported by Pre-Scheme.*
- Pre-Scheme's only numeric types are fixnums and flonums, with
- precision determined by the architecture on which the Pre-Scheme
- code runs. Fixnums are translated to C as the 'long' type; flonums
- are translated as the 'float' type.
- *Top-level Pre-Scheme code is evaluated at compile-time.*
- Closures actually _are_ available, as long as they may be
- eliminated before run-time. Code evaluated at compile-time also
- does not require satisfaction of strict static typing. Moreover,
- certain procedures, such as 'vector-length', are available only at
- compile-time.
- ---------- Footnotes ----------
- (1) It may be possible to use Pre-Scheme's C FFI to manually use
- 'setjmp' & 'longjmp', but the author of this manual cannot attest to
- this working.
- File: scheme48.info, Node: Pre-Scheme type specifiers, Next: Standard Pre-Scheme environment, Prev: Differences between Pre-Scheme & Scheme, Up: Pre-Scheme
- 9.2 Type specifiers
- ===================
- Although Pre-Scheme's static type system is based mostly on
- Hindley-Milner type inference, with as little explicit type information
- as possible, there are still places where it is necessary to specify
- types explicitly; for example, *note Pre-Scheme access to C functions
- and macros::. There are several different kinds of types with different
- syntax:
- 'TYPE-NAME'
- Symbols denote either record type or base types. Record types are
- defined with the 'define-record-type' special form described later;
- the following base types are defined:
- 'integer'
- Fixed-size integers (fixnums). This type is translated into C
- as 'long'. The actual size depends on the size of C's 'long',
- which on most architectures is 32 bits.
- 'float'
- Floating-point data. This type translates to C as 'double'.
- 'null'
- Type which has no value. The 'null' type translates to the C
- 'void' type.
- 'unit'
- Type which has one value. Actually, this, too, translates to
- C's 'void', so that it has one value is not strictly true.
- 'boolean'
- Booleans translate to the C 'char' type. '#t' is emitted as
- 'TRUE', and '#f', as 'FALSE'; these are usually the same as
- '1' & '0', respectively.
- 'input-port'
- 'output-port'
- I/O ports. On Unix, since Pre-Scheme uses 'stdio', these are
- translated to 'FILE *'s, 'stdio' file streams.
- 'char'
- Characters. The size of characters is dependent on the
- underlying C compiler's implementation of the 'char' type.
- 'address'
- Simple addresses for use in Pre-Scheme's low-level memory
- manipulation primitives (*note Low-level Pre-Scheme memory
- manipulation::); see that section for more details.
- '(=> (ARGUMENT-TYPE ...) RETURN-TYPE ...)'
- The types of procedures, known as 'arrow' types.
- '(^ TYPE)'
- The type of pointers that point to TYPE. Note that these are
- distinct from the address type. Pointer types are statically
- verified to be coherent data, with no defined operations except for
- accessing offsets in memory from the pointer -- i.e. operations
- such as 'vector-ref' --; addresses simply index bytes, on which
- only direct dereferencing, but also arbitrary address arithmetic,
- is available. Pointers and addresses are _not_ interchangeable,
- and and there is no way to convert between them, as that would
- break the type safety of Pre-Scheme pointers.
- '(tuple TYPE ...)'
- Multiple value types, internally used for argument & return types.
- File: scheme48.info, Node: Standard Pre-Scheme environment, Next: More Pre-Scheme packages, Prev: Pre-Scheme type specifiers, Up: Pre-Scheme
- 9.3 Standard environment
- ========================
- Pre-Scheme programs usually open the 'prescheme' structure. There are
- several other structures built-in to Pre-Scheme as well, described in
- the next section. This section describes the 'prescheme' structure.
- * Menu:
- * Scheme bindings in Pre-Scheme:: Bindings from R5RS
- * Tail call optimization in Pre-Scheme::
- * Pre-Scheme bitwise manipulation::
- * Compound Pre-Scheme data manipulation::
- * Pre-Scheme error handling::
- * Input & output in Pre-Scheme::
- * Pre-Scheme access to C functions and macros::
- File: scheme48.info, Node: Scheme bindings in Pre-Scheme, Next: Tail call optimization in Pre-Scheme, Up: Standard Pre-Scheme environment
- 9.3.1 Scheme bindings
- ---------------------
- Bindings for all the names specified here from R5RS Scheme are available
- in Pre-Scheme. The remainder of the sections after this one detail
- Pre-Scheme specifics that are not a part of Scheme.
- -- syntax: define name value
- -- syntax: define (name . argument-list) value
- -- syntax: if condition consequent [alternate]
- -- syntax: let ((name expression) ...) body
- -- syntax: let* ((name expression) ...) body
- -- syntax: and conjunct ...
- -- syntax: or disjunct ...
- -- syntax: cond cond-clause ...
- -- syntax: do ((name init-exp [step-exp]) ...) (test-exp [return-exp])
- body
- These special forms & macros are all unchanged from their R5RS
- specifications.
- -- syntax: define-syntax name transformer-expression [aux-names]
- -- syntax: let-syntax ((name transformer-expression) ...) body
- -- syntax: letrec-syntax ((name transformer-expression) ...) body
- Pre-Scheme's macro facility is exactly the same as Scheme48's.
- TRANSFORMER-EXPRESSION may be either a 'syntax-rules' or an
- explicit renaming transformer, just as in Scheme48; in the latter
- case, it is evaluated either in a standard Scheme environment or
- however the 'for-syntax' clause specified of the package in whose
- code the transformer appeared. For details on the extra AUX-NAMES
- operand to 'define-syntax', *note Explicit renaming macros::.
- -- procedure: not boolean --> boolean
- -- procedure: eq? value--_{a} value--_{b} --> boolean
- -- procedure: char=? char--_{a} char--_{b} --> boolean
- -- procedure: char<? char--_{a} char--_{b} --> boolean
- -- procedure: values value ... --> values
- -- procedure: call-with-values producer consumer --> values
- -- procedure: current-input-port --> input-port
- -- procedure: current-output-port --> output-port
- These procedures are all unchanged from their R5RS specifications.
- -- procedure: + addend ... --> integer
- -- procedure: - integer --> integer
- -- procedure: - minuend subtrahend --> integer
- -- procedure: * multiplicand ... --> integer
- -- procedure: = integer--_{a} integer--_{b} --> boolean
- -- procedure: < integer--_{a} integer--_{b} --> boolean
- -- procedure: > integer--_{a} integer--_{b} --> boolean
- -- procedure: <= integer--_{a} integer--_{b} --> boolean
- -- procedure: >= integer--_{a} integer--_{b} --> boolean
- -- procedure: min integer_{1} integer_{2} ... --> integer
- -- procedure: max integer_{1} integer_{2} ... --> integer
- -- procedure: abs integer --> integer
- -- procedure: quotient divisor dividend --> integer
- -- procedure: remainder divisor dividend --> integer
- -- procedure: expt base exponent --> integer
- These numerical operations are all unchanged from their R5RS
- counterparts, except that they are applicable only to fixnums, not
- to flonums, and they always return fixnums.
- File: scheme48.info, Node: Tail call optimization in Pre-Scheme, Next: Pre-Scheme bitwise manipulation, Prev: Scheme bindings in Pre-Scheme, Up: Standard Pre-Scheme environment
- 9.3.2 Tail call optimization
- ----------------------------
- -- syntax: goto procedure argument ...
- The Pre-Scheme compiler can be forced to optimize tail calls, even
- those it would not have otherwise optimized, by use of the 'goto'
- special form, rather than simple procedure calls. In every respect
- other than tail call optimization, this is equivalent to calling
- PROCEDURE with the given arguments. Note, however, that uses of
- 'goto' may cause code to blow up if the Pre-Scheme compiler had
- reason not to optimize the tail call were it not for the 'goto': it
- may need to merge the tail-called procedure into the caller's code.
- File: scheme48.info, Node: Pre-Scheme bitwise manipulation, Next: Compound Pre-Scheme data manipulation, Prev: Tail call optimization in Pre-Scheme, Up: Standard Pre-Scheme environment
- 9.3.3 Bitwise manipulation
- --------------------------
- Pre-Scheme provides basic bitwise manipulation operators.
- -- procedure: bitwise-and integer--_{a} integer--_{b} --> integer
- -- procedure: bitwise-ior integer--_{a} integer--_{b} --> integer
- -- procedure: bitwise-xor integer--_{a} integer--_{b} --> integer
- -- procedure: bitwise-not integer --> integer
- Bitwise boolean logical operations.
- -- procedure: shift-left integer count --> integer
- -- procedure: arithmetic-shift-right integer count --> integer
- -- procedure: logical-shift-right integer count --> integer
- Three ways to shift bit strings: 'shift-left' shifts INTEGER left
- by COUNT, 'arithmetic-shift-right' shifts INTEGER right by COUNT
- arithmetically, and 'logical-shift-right' shifts INTEGER right by
- COUNT logically.
- File: scheme48.info, Node: Compound Pre-Scheme data manipulation, Next: Pre-Scheme error handling, Prev: Pre-Scheme bitwise manipulation, Up: Standard Pre-Scheme environment
- 9.3.4 Compound data manipulation
- --------------------------------
- Pre-Scheme has somewhat lower-level vector & string facilities than
- Scheme, with more orientation towards static typing. It also provides a
- statically typed record facility, which translates to C structs, though
- not described here, as it is not in the 'prescheme' structure; *note
- Pre-Scheme record types::.
- -- procedure: make-vector length init --> vector
- -- procedure: vector-length vector --> integer
- -- procedure: vector-ref vector index --> value
- -- procedure: vector-set! vector index value --> unit
- Vectors in Pre-Scheme are almost the same as vectors in regular
- Scheme, but with a few differences. 'Make-vector' initializes what
- it returns with null pointers (see below); it uses the _required_
- (unlike Scheme) INIT argument only to determine the type of the
- vector: vectors are statically typed; they can contain only values
- that have the same static type as INIT. 'Vector-length' is
- available only at the top level, where calls to it can be evaluated
- at compile-time; vectors do not at run-time store their lengths.
- Vectors must also be explicitly deallocated.
- *Warning:* As in C, there is _no_ vector bounds checking at
- run-time.
- -- procedure: make-string length --> string
- -- procedure: string-length string --> integer
- -- procedure: string-ref string index --> char
- -- procedure: string-set! string index char --> unit
- Strings in Pre-Scheme are the nearly same as strings in R5RS
- Scheme. The only three differences here are that 'make-string'
- accepts exactly one argument, strings must be explicitly
- deallocated, and strings are 'nul'-terminated: 'string-length'
- operates by scanning for the first ASCII 'nul' character in a
- string.
- *Warning:* As in C, there is _no_ string bounds checking at
- run-time.
- -- procedure: deallocate pointer --> unit
- Deallocates the memory pointed to by 'pointer'. This is necessary
- at the end of a string, vector, or record's life, as Pre-Scheme
- data are not automatically garbage-collected.
- -- procedure: null-pointer --> null-pointer
- -- procedure: null-pointer? pointer --> boolean
- 'Null-pointer' returns the distinguished null pointer object. It
- corresponds with '0' in a pointer context or 'NULL' in C.
- 'Null-pointer?' returns true if POINTER is a null pointer, or false
- if not.
- File: scheme48.info, Node: Pre-Scheme error handling, Next: Input & output in Pre-Scheme, Prev: Compound Pre-Scheme data manipulation, Up: Standard Pre-Scheme environment
- 9.3.5 Error handling
- --------------------
- Pre-Scheme's method of error handling is similar to the most common one
- in C: error codes. There is an enumeration 'errors' of some error codes
- commonly and portably encountered in Pre-Scheme.
- -- enumeration: errors
- (define-enumeration errors
- (no-errors
- parse-error
- file-not-found
- out-of-memory
- invalid-port))
- Each enumerand has the following meaning:
- '(enum errors no-errors)'
- Absence of error: success.
- '(enum errors parse-error)'
- Any kind of parsing error. The Scheme48 VM uses this when
- someone attempts to resume a malformed suspended heap image.
- '(enum errors file-not-found)'
- Used when an operation that operates on a file given a string
- filename found that the file for that filename was absent.
- '(enum errors out-of-memory)'
- When there is no more memory to allocate.
- '(enum errors invalid-port)'
- Unused.
- -- procedure: error-string error-status --> string
- Returns a string describing the meaning of the 'errors' enumerand
- ERROR-STATUS.
- -- procedure: error message irritant ...
- Signals a fatal error with the given message & related irritants
- and halts the program. On Unix, the program's exit code is -1.
- File: scheme48.info, Node: Input & output in Pre-Scheme, Next: Pre-Scheme access to C functions and macros, Prev: Pre-Scheme error handling, Up: Standard Pre-Scheme environment
- 9.3.6 Input & output
- --------------------
- Pre-Scheme's I/O facilities are somewhat different from Scheme's, given
- the low level and the static type strictness. There is no exception
- mechanism in Pre-Scheme; everything is maintained by returning a status
- token, as in C. Pre-Scheme's built-in I/O facilities are buffered. (1)
- (*note Low-level Pre-Scheme memory manipulation::, for two other I/O
- primitives, 'read-block' & 'write-block', for reading & writing blocks
- of direct memory.)
- -- procedure: open-input-file filename --> [port status]
- -- procedure: open-output-file filename --> [port status]
- -- procedure: close-input-port input-port --> status
- -- procedure: close-output-port output-port --> status
- 'Open-input-file' & 'open-output-file' open ports for the given
- filenames. They each return two values: the newly open port and an
- 'errors' enumerand status. Users of these procedures should always
- check the error status before proceeding to operate with the port.
- 'Close-input-port' & 'close-output-port' close their port arguments
- and return the 'errors' enumerand status of the closing.
- -- procedure: read-char input-port --> [char eof? status]
- -- procedure: peek-char input-port --> [char eof? status]
- -- procedure: read-integer input-port --> [integer eof? status]
- 'Read-char' reads & consumes a single character from its INPUT-PORT
- argument. 'Peek-char' reads, but does not consume, a single
- character from INPUT-PORT. 'Read-integer' parses an integer
- literal, including sign. All of these also return two other
- values: whether or not the file is at the end and any 'errors'
- enumerand status. If any error occurred, the first two values
- returned should be ignored. If STATUS is '(enum errors
- no-errors)', users of these three procedures should then check
- EOF?; it is true if INPUT-PORT was at the end of the file with
- nothing more left to read and false otherwise. Finally, if both
- STATUS is '(enum errors no-errors)' and EOF? is false, the first
- value returned may be safely used.
- -- procedure: write-char char output-port --> status
- -- procedure: newline output-port --> status
- -- procedure: write-string string output-port --> status
- -- procedure: write-integer integer output-port --> status
- These all write particular elements to their OUTPUT-PORT arguments.
- 'Write-char' writes individual characters. 'Newline' writes
- newlines (line-feed, or ASCII codepoint 10, on Unix).
- 'Write-string' writes the contents of STRING. 'Write-integer'
- writes an ASCII representation of INTEGER to port, suitable to be
- read by 'read-integer'. These all return an 'errors' enumerand
- status. If it is 'no-errors', the write succeeded.
- -- procedure: force-output output-port --> status
- Forces all buffered output in OUTPUT-PORT. STATUS tells whether or
- not the operation was successful.
- ---------- Footnotes ----------
- (1) Scheme48's VM does not use Pre-Scheme's built-in I/O facilities
- to implement channels (*note Channels::) -- it builds its own
- lower-level facilities that are still OS-independent, but, because
- they're written individually for different OSs, they integrate better as
- low-level I/O channels with the OS. On Unix, the Scheme48 VM uses file
- descriptors; Pre-Scheme's built-in I/O uses 'stdio'. Scheme48's VM uses
- Pre-Scheme's built-in I/O only to read heap images.
- File: scheme48.info, Node: Pre-Scheme access to C functions and macros, Prev: Input & output in Pre-Scheme, Up: Standard Pre-Scheme environment
- 9.3.7 Access to C functions and macros
- --------------------------------------
- -- syntax: external c-name ps-type --> procedure
- Special form for accessing C functions & macros. Calls in
- Pre-Scheme to the resulting procedure are compiled to calls in C to
- the function or macro named by C-NAME, which should be a string.
- PS-TYPE is the Pre-Scheme type (*note Pre-Scheme type specifiers::)
- that the procedure should have, which is necessary for type
- inference.
- File: scheme48.info, Node: More Pre-Scheme packages, Next: Invoking the Pre-Scheme compiler, Prev: Standard Pre-Scheme environment, Up: Pre-Scheme
- 9.4 More Pre-Scheme packages
- ============================
- Along with the 'prescheme' structure, there are several other structures
- built-in to Pre-Scheme.
- * Menu:
- * Pre-Scheme floating point operation::
- * Pre-Scheme record types::
- * Multiple return values in Pre-Scheme::
- * Low-level Pre-Scheme memory manipulation::
- File: scheme48.info, Node: Pre-Scheme floating point operation, Next: Pre-Scheme record types, Up: More Pre-Scheme packages
- 9.4.1 Floating point operation
- ------------------------------
- Since Pre-Scheme's strict static type system would not permit
- overloading of the arithmetic operators for integers & floats, it
- provides a different set of operators for floats. These names are all
- exported by the 'ps-flonums' structure.
- -- procedure: fl+ augend addend ... --> float
- -- procedure: fl- float --> float
- -- procedure: fl- minuend subtrahend --> float
- -- procedure: fl* multiplier multiplicand ... --> float
- -- procedure: fl/ divisor dividend --> float
- -- procedure: fl= float--_{a} float--_{b} --> boolean
- -- procedure: fl< float--_{a} float--_{b} --> boolean
- -- procedure: fl> float--_{a} float--_{b} --> boolean
- -- procedure: fl<= float--_{a} float--_{b} --> boolean
- -- procedure: fl>= float--_{a} float--_{b} --> boolean
- All of these operations 'flOP' correspond as floating point
- variations of their OP integer equivalents.
- File: scheme48.info, Node: Pre-Scheme record types, Next: Multiple return values in Pre-Scheme, Prev: Pre-Scheme floating point operation, Up: More Pre-Scheme packages
- 9.4.2 Record types
- ------------------
- The 'ps-record-types' structure defines the following special form for
- introducing record types. Pre-Scheme record types are translated to C
- as structs.
- -- syntax: define-record-type
- (define-record-type TYPE TYPE-DESCRIPTOR
- (CONSTRUCTOR ARGUMENT-FIELD-TAG ...)
- (FIELD-TAG_{1} FIELD-TYPE-SPEC_{1}
- FIELD-ACCESSOR_{1} [FIELD-MODIFIER_{1}])
- (FIELD-TAG_{2} FIELD-TYPE-SPEC_{2}
- FIELD-ACCESSOR_{2} [FIELD-MODIFIER_{2}])
- ...
- (FIELD-TAG_{N} FIELD-TYPE-SPEC_{N}
- FIELD-ACCESSOR_{N} [FIELD-MODIFIER_{N}])
- Defines a record type. TYPE is mangled to the C struct type name
- (TYPE-DESCRIPTOR-NAME is unused unless running Pre-Scheme as
- Scheme). CONSTRUCTOR is defined to construct a record of the new
- type and initialize the fields ARGUMENT-TYPE-FIELD ... with its
- arguments, respectively. If it cannot allocate a sufficient
- quantity of memory, CONSTRUCTOR returns a null pointer. The
- initial values of fields that are not passed to the constructor are
- undefined. For each field FIELD-_{I} specified,
- * FIELD-_{I} is specified to have the type FIELD-TYPE-SPEC-_{I};
- * FIELD-ACCESSOR-_{I} is defined to be a procedure of one
- argument, a record of type TYPE-NAME, that returns the value
- of the field FIELD-_{I} of that record -- its type is defined
- to be '(=> (TYPE-NAME) FIELD-TYPE-SPEC--_{I})'; and
- * if present, FIELD-MODIFIER-_{I} is defined to be a procedure
- of two arguments, a record of type TYPE-NAME and a value of
- type FIELD-TYPE-SPEC, that assigns the value of the field
- FIELD-_{I} in its first argument to be the value of its second
- argument; its type is '(=> (TYPE-NAME FIELD-TYPE-SPEC) unit)'.
- Records must be deallocated explicitly when their lifetime has
- expired with 'deallocate'.
- File: scheme48.info, Node: Multiple return values in Pre-Scheme, Next: Low-level Pre-Scheme memory manipulation, Prev: Pre-Scheme record types, Up: More Pre-Scheme packages
- 9.4.3 Multiple return values
- ----------------------------
- Pre-Scheme support multiple return values, like in Scheme. The only
- difference is that one cannot operate on multiple return values as
- lists, since Pre-Scheme does not have lists. Multiple return values are
- implemented in C as returning in C the first value and passing pointers
- to the remaining values, which the function returning multiple values
- assigns. The 'prescheme' structure exports the two multiple return
- value primitives, 'call-with-values' and 'values', but the 'ps-receive'
- structure exports this macro for more conveniently binding multiple
- return values.
- -- syntax: receive formals producer body
- Binds the 'lambda' parameter list FORMALS to the multiple values
- that PRODUCER returns, and evaluates BODY with the new variables
- bound.
- (receive FORMALS
- PRODUCER
- BODY)
- ==
- (call-with-values
- (lambda () PRODUCER)
- (lambda FORMALS
- BODY))
- File: scheme48.info, Node: Low-level Pre-Scheme memory manipulation, Prev: Multiple return values in Pre-Scheme, Up: More Pre-Scheme packages
- 9.4.4 Low-level memory manipulation
- -----------------------------------
- Pre-Scheme is a low-level language. It provides very low-level, direct
- memory manipulation. 'Addresses' index a flat store of sequences of
- bytes. While Pre-Scheme 'pointers' are statically checked for data
- coherency, allow no arbitrary arithmetic, and in general are high-level
- abstract data to some extent, addresses are much lower-level, have no
- statically checked coherency -- the values an address represents are
- selected by what operation used to read or write from it --, permit
- arbitrary address arithmetic, and are a much more concrete interface
- into direct memory. The 'ps-memory' structure exports these direct
- memory manipulation primitives.
- -- procedure: allocate-memory size --> address
- -- procedure: deallocate-memory address --> unit
- 'Allocate-memory' reserves a sequence of SIZE bytes in the store
- and returns an address to the first byte in the sequence.
- 'Deallocate-memory' releases the memory at ADDRESS, which should
- have been the initial address of a contiguous byte sequence, as
- 'allocate-memory' would return, not an offset address from such an
- initial address.
- -- procedure: unsigned-byte-ref address --> unsigned-byte
- -- procedure: unsigned-byte-set! address unsigned-byte --> unit
- -- procedure: word-ref address --> word
- -- procedure: word-set! address word --> unit
- -- procedure: flonum-ref address --> float
- -- procedure: flonum-set! address float --> unit
- Procedures for reading from & storing to memory.
- 'Unsigned-byte-ref' & 'unsigned-byte-set!' access & store the first
- unsigned byte at ADDRESS. 'Word-ref' & 'word-set!' access & store
- the first word -- Pre-Scheme integer -- beginning at ADDRESS.
- 'Flonum-ref' & 'flonum-set!' access & store 64-bit floats beginning
- at ADDRESS..
- *Bug:* 'Flonum-ref' & 'flonum-set!' are unimplemented in the
- Pre-Scheme-as-Scheme layer (*note Running Pre-Scheme as Scheme::).
- -- procedure: address? value --> boolean
- Disjoint type predicate for addresses.
- *Note:* 'Address?' is available _only_ at the top level, where code
- is evaluated at compile-time. Do not use this in any place where
- it may be called at run-time.
- -- constant: null-address --> address
- The null address. This is somewhat similar to the null pointer,
- except that it is an address.
- *Note:* One acquires the null _pointer_ by calling the _procedure_
- 'null-pointer', whereas the constant value of the _binding_ named
- 'null-address' is the null _address_.
- -- procedure: null-address? address --> boolean
- 'Null-address?' returns true if ADDRESS is the null address and
- false if not.
- -- procedure: address+ address increment --> address
- -- procedure: address- address decrement --> address
- -- procedure: address-difference address--_{a} address--_{b} -->
- integer
- Address arithmetic operators. 'Address+' adds INCREMENT to
- ADDRESS; 'address-' subtracts DECREMENT from ADDRESS; and
- 'address-difference' returns the integer difference between
- ADDRESS-_{A} and ADDRESS-_{B}. For any ADDRESS-_{P} &
- ADDRESS-_{Q}, '(address+ ADDRESS--_{P} (address-difference
- ADDRESS--_{P} ADDRESS--_{Q}))' is equal to ADDRESS-_{Q}.
- -- procedure: address= address--_{a} address--_{b} --> boolean
- -- procedure: address< address--_{a} address--_{b} --> boolean
- -- procedure: address> address--_{a} address--_{b} --> boolean
- -- procedure: address<= address--_{a} address--_{b} --> boolean
- -- procedure: address>= address--_{a} address--_{b} --> boolean
- Address comparators.
- -- procedure: integer->address integer --> address
- -- procedure: address->integer address --> integer
- Integers and addresses, although not the same type, may be
- converted to and from each other; 'integer->address' &
- 'address->integer' perform this conversion. Note that Pre-Scheme
- _pointers_ may not be converted to addresses or integers, and the
- converse is also true.
- -- procedure: copy-memory! source-address target-address count --> unit
- Copies COUNT bytes starting at SOURCE-ADDRESS to TARGET-ADDRESS.
- This is similar to C's 'memcpy'.
- -- procedure: memory-equal? address--_{a} address--_{b} count -->
- boolean
- Compares the two sequences of COUNT bytes starting at addresses
- ADDRESS-_{A} & ADDRESS-_{B}. It returns true if every byte is
- equal and false if not.
- -- procedure: char-pointer->string address size --> string
- -- procedure: char-pointer->nul-terminated-string address --> string
- 'Char-pointer->string' returns a string with SIZE bytes from the
- contiguous sequence of bytes starting at ADDRESS.
- 'Char-pointer->nul-terminated-string' does similarly, but it
- returns a string whose contents include every byte starting at
- ADDRESS until, but not including, the first 0 byte, i.e. ASCII nul
- character, following ADDRESS.
- -- procedure: read-block port address count --> [count-read eof?
- status]
- -- procedure: write-block port address count --> status
- 'Read-block' attempts to read COUNT bytes from PORT into memory
- starting at ADDRESS. 'Write-block' attempts to write COUNT bytes
- to PORT from the contiguous sequence in memory starting at ADDRESS.
- 'Read-block' returns three values: the number of bytes read,
- whether or not the read went to the end of the file, and the error
- status (*note Pre-Scheme error handling::). 'Write-block' returns
- the error status.
- File: scheme48.info, Node: Invoking the Pre-Scheme compiler, Next: Example Pre-Scheme compiler usage, Prev: More Pre-Scheme packages, Up: Pre-Scheme
- 9.5 Invoking the Pre-Scheme compiler
- ====================================
- Richard Kelsey's Pre-Scheme compiler is a whole-program compiler based
- on techniques from his research in transformational compilation [Kelsey
- 89]. It compiles the restricted dialect of Scheme to efficient C, and
- provides facilities for programmer direction in several optimizations.
- 9.5.1 Loading the compiler
- --------------------------
- There is a script, a Scheme48 command program (*note Command
- programs::), that comes with Scheme48 to load the Pre-Scheme compiler,
- which is in the file 'ps-compiler/load-ps-compiler.scm'. It must be
- loaded from the 'ps-compiler/' directory, from Scheme48's main
- distribution, into the 'exec' package, after having loaded
- '../scheme/prescheme/interface.scm' &
- '../scheme/prescheme/package-defs.scm' into the 'config' package. The
- Pre-Scheme compiler takes some time to load, so it may be easier to load
- it once and dump a heap image of the suspended command processor after
- having loaded everything; *note Image-building commands::.
- To load the Pre-Scheme compiler and dump an image to the file
- 'ps-compiler.image' that contains 'prescheme-compiler' in the user
- package, send this sequence of commands to the command processor while
- in the 'ps-compiler/' directory of Scheme48's distribution:
- ,config ,load ../scheme/prescheme/interface.scm
- ,config ,load ../scheme/prescheme/package-defs.scm
- ,exec ,load load-ps-compiler.scm
- ,in prescheme-compiler prescheme-compiler
- ,user (define prescheme-compiler ##)
- ,dump ps-compiler.image "(Pre-Scheme)"
- 9.5.2 Calling the compiler
- --------------------------
- After having loaded the Pre-Scheme compiler, the 'prescheme-compiler'
- structure is the front end to the compiler that exports the
- 'prescheme-compiler' procedure.
- -- procedure: prescheme-compiler structure-spec config-filenames
- init-name c-filename command ...
- Invokes the Pre-Scheme compiler. CONFIG-FILENAMES contain module
- descriptions (*note Module system::) for the components of the
- program. STRUCTURE-SPEC may be a symbol or a list of symbols,
- naming the important structure or structures. All structures that
- it relies/they rely on are traced in the packages' 'open' clauses.
- Modules that are not traced in the dependency graph with root
- vertices of the given structure[s] are omitted from the output.
- C-FILENAME is a string naming the file to which the C code
- generated by the Pre-Scheme compiler should be emitted. INIT-NAME
- is the name for an initialization routine, generated automatically
- by the Pre-Scheme compiler to initialize some top-level variables.
- The COMMAND arguments are used to control certain aspects of the
- compilation. The following commands are defined:
- '(copy (STRUCTURE COPYABLE-PROCEDURE) ...)'
- Specifies that each the body of each COPYABLE-PROCEDURE from
- the respective STRUCTURE (from one of CONFIG-FILENAMES) may be
- integrated & duplicated.
- '(no-copy (STRUCTURE UNCOPYABLE-PROCEDURE) ...)'
- Specifies that the given procedures may not be integrated.
- '(shadow ((PROC-STRUCTURE PROCEDURE) (VAR-STRUCTURE VARIABLE-TO-SHADOW) ...) ...)'
- Specifies that, in PROCEDURE from PROC-STRUCTURE, the global
- variables VARIABLE-TO-SHADOW from their respective
- VAR-STRUCTUREs should be shadowed with local variables, which
- are more likely to be kept in registers for faster operation
- on them.
- '(integrate (CLIENT-PROCEDURE INTEGRABLE-PROCEDURE) ...)'
- Forces INTEGRABLE-PROCEDURE to be integrated in
- CLIENT-PROCEDURE.
- *Note:* The 'integrate' command operates on the global
- program, not on one particular module; each CLIENT-PROCEDURE
- and INTEGRABLE-PROCEDURE is chosen from all variables defined
- in the entirety of the program, across all modules. It is
- advised that there be only one of each.
- '(header HEADER-LINE ...)'
- Each HEADER-LINE is added to the top of the generated C file,
- after a cpp inclusion of '<stdio.h>' and '"prescheme.h"'.
- The command arguments to 'prescheme-compiler' are optional; they
- are used only to optimize the compiled program at the programmer's
- request.
- File: scheme48.info, Node: Example Pre-Scheme compiler usage, Next: Running Pre-Scheme as Scheme, Prev: Invoking the Pre-Scheme compiler, Up: Pre-Scheme
- 9.6 Example Pre-Scheme compiler usage
- =====================================
- The 'ps-compiler/compile-vm.scm', 'ps-compiler/compile-gc.scm', and
- 'ps-compiler/compile-vm-no-gc.scm' files give examples of running the
- Pre-Scheme compiler. They are Scheme48 command programs (*note Command
- programs::), to be loaded into the 'exec' package after having already
- loaded the Pre-Scheme compiler. 'compile-vm.scm' &
- 'compile-vm-no-gc.scm' generate a new 'scheme48vm.c' in the 'scheme/vm/'
- directory -- 'compile-vm.scm' includes the garbage collector, while
- 'compile-vm-no-gc.scm' does not (1) --, and 'compile-gc.scm' generates a
- new 'scheme48heap.c', 'scheme48read-image.c', & 'scheme48write-image.c'
- in the 'scheme/vm/' directory.
- Here is a somewhat simpler example. It assumes a pre-built image
- with the Pre-Scheme compiler loaded is in the 'ps-compiler.image' file
- in the current directory (*note Invoking the Pre-Scheme compiler::,
- where there is a description of how to dump an image with the Pre-Scheme
- compiler loaded).
- % ls
- hello.scm packages.scm ps-compiler.image
- % cat hello.scm
- (define (main argc argv)
- (if (= argc 2)
- (let ((out (current-output-port)))
- (write-string "Hello, world, " out)
- (write-string (vector-ref argv 1) out)
- (write-char #\! out)
- (newline out)
- 0)
- (let ((out (current-error-port)))
- (write-string "Usage: " out)
- (write-string (vector-ref argv 0) out)
- (write-string " <user>" out)
- (newline out)
- (write-string " Greets the world & <user>." out)
- (newline out)
- -1)))
- % cat packages.scm
- (define-structure hello (export main)
- (open prescheme)
- (files hello))
- % scheme48 -i ps-compiler.image
- heap size 3000000 is too small, using 4770088
- Welcome to Scheme 48 1.3 (Pre-Scheme)
- Copyright (c) 1993-2005 by Richard Kelsey and Jonathan Rees.
- Please report bugs to scheme-48-bugs@s48.org.
- Get more information at http://www.s48.org/.
- Type ,? (comma question-mark) for help.
- > (prescheme-compiler 'hello '("packages.scm") 'hello-init "hello.c")
- packages.scm
- hello.scmChecking types
- main : ((integer **char) -> integer)
- In-lining single-use procedures
- Call Graph:
- <procedure name>
- <called non-tail-recursively>
- <called tail-recursively>
- main (exported)
- Merging forms
- Translating
- main
- #{Unspecific}
- > ,exit
- % cat hello.c
- #include <stdio.h>
- #include "prescheme.h"
- long main(long, char**);
- long main(long argc_0X, char **argv_1X)
- {
- FILE * out_3X;
- FILE * out_2X;
- { if ((1 == argc_0X)) {
- out_2X = stdout;
- ps_write_string("Hello, world, ", out_2X);
- ps_write_string((*(argv_1X + 1)), out_2X);
- { long ignoreXX;
- PS_WRITE_CHAR(33, out_2X, ignoreXX) }
- { long ignoreXX;
- PS_WRITE_CHAR(10, out_2X, ignoreXX) }
- return 0;}
- else {
- out_3X = stderr;
- ps_write_string("Usage: ", out_3X);
- ps_write_string((*(argv_1X + 0)), out_3X);
- ps_write_string(" <user>", out_3X);
- { long ignoreXX;
- PS_WRITE_CHAR(10, out_3X, ignoreXX) }
- ps_write_string(" Greets the world & <user>.", out_3X);
- { long ignoreXX;
- PS_WRITE_CHAR(10, out_3X, ignoreXX) }
- return -1;}}
- }
- %
- ---------- Footnotes ----------
- (1) The actual distribution of Scheme48 separates the garbage
- collector and the main virtual machine.
- File: scheme48.info, Node: Running Pre-Scheme as Scheme, Prev: Example Pre-Scheme compiler usage, Up: Pre-Scheme
- 9.7 Running Pre-Scheme as Scheme
- ================================
- To facilitate the operation of Pre-Scheme systems within a high-level
- Scheme development environment, Scheme48 simply defines the 'prescheme',
- 'ps-memory', 'ps-record-types', 'ps-flonums', and 'ps-receive'
- structures in terms of Scheme; Pre-Scheme structures can be loaded as
- regular Scheme structures because of this. Those structures and the
- interfaces they implement are defined in the files
- 'scheme/prescheme/interface.scm' and 'scheme/prescheme/package-defs.scm'
- from the main Scheme48 distribution; simply load these files into the
- config package (*note Module commands::) before loading any Pre-Scheme
- configuration files.
- The Pre-Scheme emulation layer in Scheme has some shortcomings:
- * No more than sixteen megabytes can be allocated at once.
- * More than thirty-two or sixty-four or so allocations result in
- addresses overflowing bignums, which deallocations does not affect.
- * Flonum memory access is unimplemented. (Flonum arithmetic works,
- though.)
- * The layer is very slow.
- File: scheme48.info, Node: References, Next: Concept index, Prev: Pre-Scheme, Up: Top
- References
- **********
- [Cejtin et al. 95]
- Henry Cejtin, Suresh Jagannathan, and Richard Kelsey. Higher-Order
- Distributed Objects. In 'ACM Transactions on Programming Languages
- and Systems', vol. 17, pp. 704-739, ACM Press, September 1995.
- [Clinger 91]
- William D. Clinger. Hygienic Macros through Explicit Renaming. In
- 'Lisp Pointers', IV(4): 25-28, December 1991.
- [Donald 92]
- Bruce Donald and Jonathan A. Rees. Program Mobile Robots in
- Scheme! In 'Proceedings of the 1992 IEEE International Conference
- on Robotics and Automation', 2681-2688.
- [Friedman 00]
- Daniel Friedman and Erik Hilsdale. 'Writing Macros in
- Continuation-Passing Style'. Worksop on Scheme and Functional
- Programming, September 2000.
- [Kelsey 89]
- Richard Kelsey. 'Compilation by Program Transformation'. PhD
- thesis, Yale University, 1989.
- [Kelsey 97]
- Richard Kelsey. 'Pre-Scheme: A Scheme Dialect for Systems
- Programming'. June 1997.
- [Museme]
- Franklyn Turbak and Dan Winship. 'Museme: a multi-user simulation
- environment for Scheme'.
- <http://www.bloodandcoffee.net/campbell/code/museme.tar.gz>
- [Rees 96]
- Jonathan A. Rees. 'A Security Kernel based on the
- Lambda-Calculus'. PhD thesis, AI Memo 1564, Massachusetts
- Institute of Technology, Artificial Intelligence Laboratory, 1996.
- [Reppy 99]
- John Reppy. 'Concurrent Programming in ML'. Cambridge University
- Press, 1999.
- [Shivers 94]
- Olin Shivers. 'A Scheme Shell'. Tech Report 635, Massachusetts
- Institute of Technology, Laboratory for Computer Science, 1994.
- [Shivers 96]
- Olin Shivers. 'A Universal Scripting Framework, or Lambda: the
- Ultimate "Little Language"'. 'Concurrency and Parallelism,
- Programming, Networking, and Security', pp. 254-265, 1996, Joxan
- Jaffar and Roland H. C. Yap (eds).
- [Shivers et al. 04]
- Olin Shivers, Brian D. Carlstrom, Martin Gasbichler, and Michael
- Sperber. 'Scsh Reference Manual', for scsh release 0.6.6
- <http://www.scsh.net/docu/docu.html>
- [SRFI 1]
- Olin Shivers. 'SRFI 1: List Library' Scheme Requests for
- Implementation, 1999.
- <http://srfi.schemers.org/srfi-1/>
- [SRFI 7]
- Richard Kelsey. 'SRFI 7: Feature-Based Program Configuration
- Language' Scheme Requests for Implementation, 1999.
- <http://srfi.schemers.org/srfi-7/>
- [SRFI 9]
- Richard Kelsey. 'SRFI 9: Defining Record Types' Scheme Requests
- for Implementation, 1999.
- <http://srfi.schemers.org/srfi-9/>
- [SRFI 22]
- Martin Gasbichler and Michael Sperber 'SRFI 22: Running Scheme
- Scripts on Unix' Scheme Requests for Implementation, 2002.
- <http://srfi.schemers.org/srfi-22/>
- [SRFI 34]
- Richard Kelsey and Michael Sperber. 'SRFI 34: Exception Handling
- for Programs'. Scheme Requests for Implementation, 2002.
- <http://srfi.schemers.org/srfi-34/>
- [SRFI 35]
- Richard Kelsey and Michael Sperber. 'SRFI 35: Conditions'. Scheme
- Requests for Implementation, 2002.
- <http://srfi.schemers.org/srfi-35/>
- File: scheme48.info, Node: Concept index, Next: Binding index, Prev: References, Up: Top
- Concept index
- *************
|