123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705 |
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv=Content-Type content="text/html; charset=utf8">
- <title>The Text Editor sam</title>
- </meta>
- </head>
- <body>
- <p style="margin-top: 0; margin-bottom: 0.50in"></p>
- <p style="margin-top: 0; margin-bottom: 0.21in"></p>
- <p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
- <span style="font-size: 12pt"><b>The Text Editor </b></span><span style="font-size: 12pt"><tt>sam</tt></span><span style="font-size: 12pt"><b></b></span></p>
- <p style="margin-top: 0; margin-bottom: 0.21in"></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
- <span style="font-size: 10pt"><i>Rob Pike</i></span></p>
- <p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
- <span style="font-size: 10pt"><i>rob@plan9.bell-labs.com</i></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="margin-top: 0; margin-bottom: 0.33in"></p>
- <p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
- <span style="font-size: 10pt"><i>ABSTRACT</i></span></p>
- <p style="margin-top: 0; margin-bottom: 0.19in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.50in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is an interactive multi-file text editor intended for
- bitmap displays.
- A textual command language
- supplements the mouse-driven, cut-and-paste interface
- to make complex or
- repetitive editing tasks easy to specify.
- The language is characterized by the composition of regular expressions
- to describe the structure of the text being modified.
- The treatment of files as a database, with changes logged
- as atomic transactions, guides the implementation and
- makes a general ‘undo’ mechanism straightforward.
- </span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is implemented as two processes connected by a low-bandwidth stream,
- one process handling the display and the other the editing
- algorithms. Therefore it can run with the display process
- in a bitmap terminal and the editor on a local host,
- with both processes on a bitmap-equipped host, or with
- the display process in the terminal and the editor in a
- remote host.
- By suppressing the display process,
- it can even run without a bitmap terminal.
- </span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">This paper is reprinted from Software—Practice and Experience,
- Vol 17, number 11, pp. 813-845, November 1987.
- The paper has not been updated for the Plan 9 manuals. Although
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- has not changed much since the paper was written, the system around it certainly has.
- Nonetheless, the description here still stands as the best introduction to the editor.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.50in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Introduction
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is an interactive text editor that combines cut-and-paste interactive editing with
- an unusual command language based on the composition of regular expressions.
- It is written as two programs: one, the ‘host part,’ runs on a UNIX system
- and implements the command language and provides file access; the other, the
- ‘terminal part,’ runs asynchronously
- on a machine with a mouse and bitmap display
- and supports the display and interactive editing.
- The host part may be even run in isolation on an ordinary terminal
- to edit text using the command
- language, much like a traditional line editor,
- without assistance from a mouse or display.
- Most often,
- the terminal part runs on a Blit<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> terminal
- (actually on a Teletype DMD 5620, the production version of the Blit), whose
- host connection is an ordinary 9600 bps RS232 link;
- on the SUN computer the host and display processes run on a single machine,
- connected by a pipe.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- edits uninterpreted
- ASCII text.
- It has no facilities for multiple fonts, graphics or tables,
- unlike MacWrite,<sup></sup></span><sup><span style="font-size: 6pt">2</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> Bravo,<sup></sup></span><sup><span style="font-size: 6pt">3</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> Tioga<sup></sup></span><sup><span style="font-size: 6pt">4</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- or Lara.<sup></sup></span><sup><span style="font-size: 6pt">5</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- Also unlike them, it has a rich command language.
- (Throughout this paper, the phrase
- </span><span style="font-size: 10pt"><i>command language
- </i></span><span style="font-size: 10pt">refers to
- textual commands; commands activated from the mouse form the
- </span><span style="font-size: 10pt"><i>mouse</i></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><i>language.</i></span><span style="font-size: 10pt">)
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- developed as an editor for use by programmers, and tries to join
- the styles of the UNIX text editor
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">6,7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- with that of interactive cut-and-paste editors by
- providing a comfortable mouse-driven interface
- to a program with a solid command language driven by regular expressions.
- The command language developed more than the mouse language, and
- acquired a notation for describing the structure of files
- more richly than as a sequence of lines,
- using a dataflow-like syntax for specifying changes.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The interactive style was influenced by
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- an early cut-and-paste editor for the Blit, and by
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- the Blit window system.
- </span><span style="font-size: 10pt"><tt>Mux</tt></span><span style="font-size: 10pt">
- merges the original Blit window system,
- </span><span style="font-size: 10pt"><tt>mpx</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- with cut-and-paste editing, forming something like a
- multiplexed version of
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- that edits the output of (and input to) command sessions rather than files.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The first part of this paper describes the command language, then the mouse
- language, and explains how they interact.
- That is followed by a description of the implementation,
- first of the host part, then of the terminal part.
- A principle that influenced the design of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is that it should have no explicit limits, such as upper limits on
- file size or line length.
- A secondary consideration is that it be efficient.
- To honor these two goals together requires a method for efficiently
- manipulating
- huge strings (files) without breaking them into lines,
- perhaps while making thousands of changes
- under control of the command language.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">’s
- method is to
- treat the file as a transaction database, implementing changes as atomic
- updates. These updates may be unwound easily to ‘undo’ changes.
- Efficiency is achieved through a collection of caches that minimizes
- disc traffic and data motion, both within the two parts of the program
- and between them.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The terminal part of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is fairly straightforward.
- More interesting is how the two halves of the editor stay
- synchronized when either half may initiate a change.
- This is achieved through a data structure that organizes the
- communications and is maintained in parallel by both halves.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The last part of the paper chronicles the writing of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- and discusses the lessons that were learned through its development and use.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The paper is long, but is composed largely of two papers of reasonable length:
- a description of the user interface of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- and a discussion of its implementation.
- They are combined because the implementation is strongly influenced by
- the user interface, and vice versa.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>The Interface
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is a text editor for multiple files.
- File names may be provided when it is invoked:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>sam file1 file2 ...</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">and there are commands
- to add new files and discard unneeded ones.
- Files are not read until necessary
- to complete some command.
- Editing operations apply to an internal copy
- made when the file is read; the UNIX file associated with the copy
- is changed only by an explicit command.
- To simplify the discussion, the internal copy is here called a
- </span><span style="font-size: 10pt"><i>file</i></span><span style="font-size: 10pt">,
- while the disc-resident original is called a
- </span><span style="font-size: 10pt"><i>disc file.
- </i></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is usually connected to a bitmap display that presents a cut-and-paste
- editor driven by the mouse.
- In this mode, the command language is still available:
- text typed in a special window, called the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><i>window,</i></span><span style="font-size: 10pt">
- is interpreted
- as commands to be executed in the current file.
- Cut-and-paste editing may be used in any window — even in the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window to construct commands.
- The other mode of operation, invoked by starting
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- with the option
- </span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
- (for ‘no download’),
- does not use the mouse or bitmap display, but still permits
- editing using the textual command language, even on an ordinary terminal,
- interactively or from a script.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The following sections describe first the command language (under
- </span><span style="font-size: 10pt"><tt>sam\fP-d
- and in the
- </tt></span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt"><tt>
- window), and then the mouse interface.
- These two languages are nearly independent, but connect through the
- </tt></span><span style="font-size: 10pt"><i>current</i></span><span style="font-size: 10pt"><tt>
- </tt></span><span style="font-size: 10pt"><i>text,</i></span><span style="font-size: 10pt"><tt>
- described below.
- </tt></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>The Command Language
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A file consists of its contents, which are an array of characters
- (that is, a string); the
- </span><span style="font-size: 10pt"><i>name</i></span><span style="font-size: 10pt">
- of the associated disc file; the
- </span><span style="font-size: 10pt"><i>modified bit
- </i></span><span style="font-size: 10pt">that states whether the contents match those of
- the disc file;
- and a substring of the contents, called the
- </span><span style="font-size: 10pt"><i>current text
- </i></span><span style="font-size: 10pt">or
- </span><span style="font-size: 10pt"><i>dot</i></span><span style="font-size: 10pt">
- (see Figures 1 and 2).
- If the current text is a null string, dot falls between characters.
- The
- </span><span style="font-size: 10pt"><i>value</i></span><span style="font-size: 10pt">
- of dot is the location of the current text; the
- </span><span style="font-size: 10pt"><i>contents</i></span><span style="font-size: 10pt">
- of dot are the characters it contains.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- imparts to the text no two-dimensional interpretation such as columns
- or fields; text is always one-dimensional.
- Even the idea of a ‘line’ of text as understood by most UNIX programs
- — a sequence of characters terminated by a newline character —
- is only weakly supported.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><i>current file
- </i></span><span style="font-size: 10pt">is the file to which editing commands refer.
- The current text is therefore dot in the current file.
- If a command doesn’t explicitly name a particular file or piece of text,
- the command is assumed to apply to the current text.
- For the moment, ignore the presence of multiple files and consider
- editing a single file.
- </span><span style="font-size: 10pt"></span></p><center><img src="fig1.gif" /></center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 1. A typical
- </i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
- screen, with the editing menu presented.
- The
- </i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
- (command language) window is in the middle, with file windows above and below.
- (The user interface makes it easy to create these abutting windows.)
- The partially obscured window is a third file window.
- The uppermost window is that to which typing and mouse operations apply,
- as indicated by its heavy border.
- Each window has its current text highlighted in reverse video.
- The
- </i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
- window’s current text is the null string on the last visible line,
- indicated by a vertical bar.
- See also Figure 2.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Commands have one-letter names.
- Except for non-editing commands such as writing
- the file to disc, most commands make some change
- to the text in dot and leave dot set to the text resulting from the change.
- For example, the delete command,
- </span><span style="font-size: 10pt"><tt>d</tt></span><span style="font-size: 10pt">,
- deletes the text in dot, replacing it by the null string and setting dot
- to the result.
- The change command,
- </span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">,
- replaces dot by text delimited by an arbitrary punctuation character,
- conventionally
- a slash. Thus,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>c/Peter/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces the text in dot by the string
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
- Similarly,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>a/Peter/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(append) adds the string after dot, and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>i/Peter/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(insert) inserts before dot.
- All three leave dot set to the new text,
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Newlines are part of the syntax of commands:
- the newline character lexically terminates a command.
- Within the inserted text, however, newlines are never implicit.
- But since it is often convenient to insert multiple lines of text,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- has a special
- syntax for that case:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>a</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>some lines of text</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>to be inserted in the file,</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>terminated by a period</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>on a line by itself</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>.</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">In the one-line syntax, a newline character may be specified by a C-like
- escape, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>c/\n/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces dot by a single newline character.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- also has a substitute command,
- </span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>s/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/</tt></span><span style="font-size: 9pt"><i>replacement</i></span><span style="font-size: 9pt"><tt>/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">substitutes the replacement text for the first match, in dot,
- of the regular expression.
- Thus, if dot is the string
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
- the command
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>s/t/st/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">changes it to
- </span><span style="font-size: 10pt"><tt>Pester</tt></span><span style="font-size: 10pt">.
- In general,
- </span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">
- is unnecessary, but it was inherited from
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- and it has some convenient variations.
- For instance, the replacement text may include the matched text,
- specified by
- </span><span style="font-size: 10pt"><tt>&</tt></span><span style="font-size: 10pt">:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>s/Peter/Oh, &, &, &, &!/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">There are also three commands that apply programs
- to text:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>< </tt></span><span style="font-size: 9pt"><i>UNIX program</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces dot by the output of the UNIX program.
- Similarly, the
- </span><span style="font-size: 10pt"><tt>></tt></span><span style="font-size: 10pt">
- command
- runs the program with dot as its standard input, and
- </span><span style="font-size: 10pt"><tt>|</tt></span><span style="font-size: 10pt">
- does both. For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>| sort</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces dot by the result of applying the standard sorting utility to it.
- Again, newlines have no special significance for these
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- commands.
- The text acted upon and resulting from these commands is not necessarily
- bounded by newlines, although for connection with UNIX programs,
- newlines may be necessary to obey conventions.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">One more command:
- </span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
- prints the contents of dot.
- Table I summarizes
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- commands.
- </span><span style="font-size: 10pt"></span></p><center><img src="sam0.png"></center>
- </center>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The value of dot may be changed by
- specifying an
- </span><span style="font-size: 10pt"><i>address</i></span><span style="font-size: 10pt">
- for the command.
- The simplest address is a line number:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>3</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">refers to the third line of the file, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>3d</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">deletes the third line of the file, and implicitly renumbers
- the lines so the old line 4 is now numbered 3.
- (This is one of the few places where
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- deals with lines directly.)
- Line
- </span><span style="font-size: 10pt"><tt>0</tt></span><span style="font-size: 10pt">
- is the null string at the beginning of the file.
- If a command consists of only an address, a
- </span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
- command is assumed, so typing an unadorned
- </span><span style="font-size: 10pt"><tt>3</tt></span><span style="font-size: 10pt">
- prints line 3 on the terminal.
- There are a couple of other basic addresses:
- a period addresses dot itself; and
- a dollar sign
- (</span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">)
- addresses the null string at the end of the file.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">An address is always a single substring of the file.
- Thus, the address
- </span><span style="font-size: 10pt"><tt>3</tt></span><span style="font-size: 10pt">
- addresses the characters
- after the second newline of
- the file through the third newline of the file.
- A
- </span><span style="font-size: 10pt"><i>compound address
- </i></span><span style="font-size: 10pt">is constructed by the comma operator
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><i>address1</i></span><span style="font-size: 9pt"><tt>,</tt></span><span style="font-size: 9pt"><i>address2</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">and addresses the substring of the file from the beginning of
- </span><span style="font-size: 10pt"><i>address1</i></span><span style="font-size: 10pt">
- to the end of
- </span><span style="font-size: 10pt"><i>address2</i></span><span style="font-size: 10pt">.
- For example, the command
- </span><span style="font-size: 10pt"><tt>3,5p</tt></span><span style="font-size: 10pt">
- prints the third through fifth lines of the file and
- </span><span style="font-size: 10pt"><tt>.,$d</tt></span><span style="font-size: 10pt">
- deletes the text from the beginning of dot to the end of the file.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">These addresses are all absolute positions in the file, but
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- also has relative addresses, indicated by
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">.
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>$-3</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">is the third line before the end of the file and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>.+1</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">is the line after dot.
- If no address appears to the left of the
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">,
- dot is assumed;
- if nothing appears to the right,
- </span><span style="font-size: 10pt"><tt>1</tt></span><span style="font-size: 10pt">
- is assumed.
- Therefore,
- </span><span style="font-size: 10pt"><tt>.+1</tt></span><span style="font-size: 10pt">
- may be abbreviated to just a plus sign.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- operator acts relative to the end of its first argument, while the
- </span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
- operator acts relative to the beginning. Thus
- </span><span style="font-size: 10pt"><tt>.+1</tt></span><span style="font-size: 10pt">
- addresses the first line after dot,
- </span><span style="font-size: 10pt"><tt>.-</tt></span><span style="font-size: 10pt">
- addresses the first line before dot, and
- </span><span style="font-size: 10pt"><tt>+-</tt></span><span style="font-size: 10pt">
- refers to the line containing the end of dot. (Dot may span multiple lines, and
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- selects the line after the end of dot, then
- </span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
- backs up one line.)
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The final type of address is a regular expression, which addresses the
- text matched by the expression. The expression is enclosed in slashes, as in
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The expressions are the same as those in the UNIX program
- </span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">6,7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- and include closures, alternations, and so on.
- They find the
- </span><span style="font-size: 10pt"><i>leftmost longest
- </i></span><span style="font-size: 10pt">string that matches the expression, that is,
- the first match after the point where the search is started,
- and if more than one match begins at the same spot, the longest such match.
- (I assume familiarity with the syntax for regular expressions in UNIX programs.<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">)
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>/x/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">matches the next
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- character in the file,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>/xx*/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">matches the next run of one or more
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">’s,
- and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>/x|Peter/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">matches the next
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
- For compatibility with other UNIX programs, the ‘any character’ operator,
- a period,
- does not match a newline, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>/.*/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">matches the text from dot to the end of the line, but excludes the newline
- and so will not match across
- the line boundary.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Regular expressions are always relative addresses.
- The direction is forwards by default,
- so
- </span><span style="font-size: 10pt"><tt>/Peter/</tt></span><span style="font-size: 10pt">
- is really an abbreviation for
- </span><span style="font-size: 10pt"><tt>+/Peter/</tt></span><span style="font-size: 10pt">.
- The search can be reversed with a minus sign, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt></tt></span><span style="font-size: 9pt"><tt>-/Peter/</tt></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">finds the first
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
- before dot.
- Regular expressions may be used with other address forms, so
- </span><span style="font-size: 10pt"><tt>0+/Peter/</tt></span><span style="font-size: 10pt">
- finds the first
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
- in the file and
- </span><span style="font-size: 10pt"><tt>$-/Peter/</tt></span><span style="font-size: 10pt">
- finds the last.
- Table II summarizes
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- addresses.
- </span><span style="font-size: 10pt"></span></p><center><img src="sam1.png"></center>
- </center>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The language discussed so far will not seem novel
- to people who use UNIX text editors
- such as
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">.<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- Moreover, the kinds of editing operations these commands allow, with the exception
- of regular expressions and line numbers,
- are clearly more conveniently handled by a mouse-based interface.
- Indeed,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- mouse language (discussed at length below) is the means by which
- simple changes are usually made.
- For large or repetitive changes, however, a textual language
- outperforms a manual interface.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Imagine that, instead of deleting just one occurrence of the string
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
- we wanted to eliminate every
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
- What’s needed is an iterator that runs a command for each occurrence of some
- text.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">’s
- iterator is called
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
- for extract:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>x/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">finds all matches in dot of the specified expression, and for each
- such match, sets dot to the text matched and runs the command.
- So to delete all the
- </span><span style="font-size: 10pt"><tt>Peters:</tt></span><span style="font-size: 10pt">
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>0,$ x/Peter/ d</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(Blanks in these examples are to improve readability;
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- neither requires nor interprets them.)
- This searches the entire file
- (</span><span style="font-size: 10pt"><tt>0,$</tt></span><span style="font-size: 10pt">)
- for occurrences of the string
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
- and runs the
- </span><span style="font-size: 10pt"><tt>d</tt></span><span style="font-size: 10pt">
- command with dot set to each such occurrence.
- (By contrast, the comparable
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- command would delete all
- </span><span style="font-size: 10pt"><i>lines</i></span><span style="font-size: 10pt">
- containing
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">;
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- deletes only the
- </span><span style="font-size: 10pt"><tt>Peters</tt></span><span style="font-size: 10pt">.)
- The address
- </span><span style="font-size: 10pt"><tt>0,$</tt></span><span style="font-size: 10pt">
- is commonly used, and may be abbreviated to just a comma.
- As another example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/Peter/ p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">prints a list of
- </span><span style="font-size: 10pt"><tt>Peters,</tt></span><span style="font-size: 10pt">
- one for each appearance in the file, with no intervening text (not even newlines
- to separate the instances).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Of course, the text extracted by
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- may be selected by a regular expression,
- which complicates deciding what set of matches is chosen —
- matches may overlap. This is resolved by generating the matches
- starting from the beginning of dot using the leftmost-longest rule,
- and searching for each match starting from the end of the previous one.
- Regular expressions may also match null strings, but a null match
- adjacent to a non-null match is never selected; at least one character
- must intervene.
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, c/AAA/</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>x/B*/ c/-/</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">produces as output
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>-A-A-A-</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">because the pattern
- </span><span style="font-size: 10pt"><tt>B*</tt></span><span style="font-size: 10pt">
- matches the null strings separating the
- </span><span style="font-size: 10pt"><tt>A</tt></span><span style="font-size: 10pt">’s.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command has a complement,
- </span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">,
- with similar syntax, that executes the command with dot set to the text
- </span><span style="font-size: 10pt"><i>between</i></span><span style="font-size: 10pt">
- the matches of the expression.
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, c/AAA/</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>y/A/ c/-/</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">produces the same result as the example above.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
- commands are looping constructs, and
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- has a pair of conditional commands to go with them.
- They have similar syntax:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>g/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(guard)
- runs the command exactly once if dot contains a match of the expression.
- This is different from
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
- which runs the command for
- </span><span style="font-size: 10pt"><i>each</i></span><span style="font-size: 10pt">
- match:
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- loops;
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- merely tests, without changing the value of dot.
- Thus,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/Peter/ d</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">deletes all occurrences of
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
- but
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, g/Peter/ d</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">deletes the whole file (reduces it to a null string) if
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
- occurs anywhere in the text.
- The complementary conditional is
- </span><span style="font-size: 10pt"><tt>v</tt></span><span style="font-size: 10pt">,
- which runs the command if there is
- </span><span style="font-size: 10pt"><i>no</i></span><span style="font-size: 10pt">
- match of the expression.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">These control-structure-like commands may be composed to construct more
- involved operations. For example, to print those lines of text that
- contain the string
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/.*\n/ g/Peter/ p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- breaks the file into lines, the
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- selects those lines containing
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
- and the
- </span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
- prints them.
- This command gives an address for the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command (the whole file), but because
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- does not have an explicit address, it applies to the value of
- dot produced by the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command, that is, to each line.
- All commands in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- except for the command to write a file to disc use dot for the
- default address.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Composition may be continued indefinitely.
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/.*\n/ g/Peter/ v/SaltPeter/ p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">prints those lines containing
- </span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
- but
- </span><span style="font-size: 10pt"><i>not</i></span><span style="font-size: 10pt">
- those containing
- </span><span style="font-size: 10pt"><tt>SaltPeter</tt></span><span style="font-size: 10pt">.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Structural Regular Expressions
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Unlike other UNIX text editors,
- including the non-interactive ones such as
- </span><span style="font-size: 10pt"><tt>sed</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>awk</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is good for manipulating files with multi-line ‘records.’
- An example is an on-line phone book composed of records,
- separated by blank lines, of the form
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>Herbert Tic</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>44 Turnip Ave., Endive, NJ</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>201-5555642</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.15in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>Norbert Twinge</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>16 Potato St., Cabbagetown, NJ</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>201-5553145</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.15in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>...</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The format may be encoded as a regular expression:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>(.+\n)+</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">that is, a sequence of one or more non-blank lines.
- The command to print Mr. Tic’s entire record is then
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/(.+\n)+/ g/^Herbert Tic$/ p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">and that to extract just the phone number is
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/(.+\n)+/ g/^Herbert Tic$/ x/^[0-9]*-[0-9]*\n/ p</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The latter command breaks the file into records,
- chooses Mr. Tic’s record,
- extracts the phone number from the record,
- and finally prints the number.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A more involved problem is that of
- renaming a particular variable, say
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">,
- to
- </span><span style="font-size: 10pt"><tt>num</tt></span><span style="font-size: 10pt">
- in a C program.
- The obvious first attempt,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/n/ c/num/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">is badly flawed: it changes not only the variable
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
- but any letter
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
- that appears.
- We need to extract all the variables, and select those that match
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
- and only
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The pattern
- </span><span style="font-size: 10pt"><tt>[A-Za-z_][A-Za-z_0-9]*</tt></span><span style="font-size: 10pt">
- matches C identifiers.
- Next
- </span><span style="font-size: 10pt"><tt>g/n/</tt></span><span style="font-size: 10pt">
- selects those containing an
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">.
- Then
- </span><span style="font-size: 10pt"><tt>v/../</tt></span><span style="font-size: 10pt">
- rejects those containing two (or more) characters, and finally
- </span><span style="font-size: 10pt"><tt>c/num/</tt></span><span style="font-size: 10pt">
- changes the remainder (identifiers
- </span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">)
- to
- </span><span style="font-size: 10pt"><tt>num</tt></span><span style="font-size: 10pt">.
- This version clearly works much better, but there may still be problems.
- For example, in C character and string constants, the sequence
- </span><span style="font-size: 10pt"><tt>\n</tt></span><span style="font-size: 10pt">
- is interpreted as a newline character, and we don’t want to change it to
- </span><span style="font-size: 10pt"><tt>\num.</tt></span><span style="font-size: 10pt">
- This problem can be forestalled with a
- </span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
- command:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>, y/\\n/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(the second
- </span><span style="font-size: 10pt"><tt>\</tt></span><span style="font-size: 10pt">
- is necessary because of lexical conventions in regular expressions),
- or we could even reject character constants and strings outright:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>,y/’[^’]*’/ y/"[^"]*"/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
- commands in this version exclude from consideration all character constants
- and strings.
- The only remaining problem is to deal with the possible occurrence of
- </span><span style="font-size: 10pt"><tt>\’</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>\"</tt></span><span style="font-size: 10pt">
- within these sequences, but it’s easy to see how to resolve this difficulty.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The point of these composed commands is successive refinement.
- A simple version of the command is tried, and if it’s not good enough,
- it can be honed by adding a clause or two.
- (Mistakes can be undone; see below.
- Also, the mouse language makes it unnecessary to retype the command each time.)
- The resulting chains of commands are somewhat reminiscent of
- shell pipelines.<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- Unlike pipelines, though, which pass along modified
- </span><span style="font-size: 10pt"><i>data</i></span><span style="font-size: 10pt">,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- commands pass a
- </span><span style="font-size: 10pt"><i>view</i></span><span style="font-size: 10pt">
- of the data.
- The text at each step of the command is the same, but which pieces
- are selected is refined step by step until the correct piece is
- available to the final step of the command line, which ultimately makes the change.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">In other UNIX programs, regular expressions are used only for selection,
- as in the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- command, never for extraction as in the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
- command.
- For example, patterns in
- </span><span style="font-size: 10pt"><tt>awk</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- are used to select lines to be operated on, but cannot be used
- to describe the format of the input text, or to handle newline-free text.
- The use of regular expressions to describe the structure of a piece
- of text rather than its contents, as in the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command,
- has been given a name:
- </span><span style="font-size: 10pt"><i>structural regular expressions.
- </i></span><span style="font-size: 10pt">When they are composed, as in the above example,
- they are pleasantly expressive.
- Their use is discussed at greater length elsewhere.<sup></sup></span><sup><span style="font-size: 6pt">10</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Multiple files
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- has a few other commands, mostly relating to input and output.
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>e discfilename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces the contents and name of the current file with those of the named
- disc file;
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>w discfilename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">writes the contents to the named disc file; and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>r discfilename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">replaces dot with the contents of the named disc file.
- All these commands use the current file’s name if none is specified.
- Finally,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>f discfilename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">changes the name associated with the file and displays the result:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>’-. discfilename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">This output is called the file’s
- </span><span style="font-size: 10pt"><i>menu line,
- </i></span><span style="font-size: 10pt">because it is the contents of the file’s line in the button 3 menu (described
- in the
- next section).
- The first three characters are a concise notation for the state of the file.
- The apostrophe signifies that the file is modified.
- The minus sign indicates the number of windows
- open on the file (see the next section):
- </span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
- means none,
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- means one, and
- </span><span style="font-size: 10pt"><tt>*</tt></span><span style="font-size: 10pt">
- means more than one.
- Finally, the period indicates that this is the current file.
- These characters are useful for controlling the
- </span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">
- command, described shortly.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- may be started with a set of disc files (such as all the source for
- a program) by invoking it with a list of file names as arguments, and
- more may be added or deleted on demand.
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>B discfile1 discfile2 ...</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">adds the named files to
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- list, and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>D discfile1 discfile2 ...</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">removes them from
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- memory (without effect on associated disc files).
- Both these commands have a syntax for using the shell<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- (the UNIX command interpreter) to generate the lists:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>B <echo *.c</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">will add all C source files, and
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>B <grep -l variable *.c</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">will add all C source files referencing a particular variable
- (the UNIX command
- </span><span style="font-size: 10pt"><tt>grep\fP-l
- lists all files in its arguments that contain matches of
- the specified regular expression).
- Finally,
- </tt></span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt"><tt>
- without arguments deletes the current file.
- </tt></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">There are two ways to change which file is current:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>b filename</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">makes the named file current.
- The
- </span><span style="font-size: 10pt"><tt>B</tt></span><span style="font-size: 10pt">
- command
- does the same, but also adds any new files to
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- list.
- (In practice, of course, the current file
- is usually chosen by mouse actions, not by textual commands.)
- The other way is to use a form of address that refers to files:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>"</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>" </tt></span><span style="font-size: 9pt"><i>address</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">refers to the address evaluated in the file whose menu line
- matches the expression (there must be exactly one match).
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>"peter.c" 3</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">refers to the third line of the file whose name matches
- </span><span style="font-size: 10pt"><tt>peter.c</tt></span><span style="font-size: 10pt">.
- This is most useful in the move
- (</span><span style="font-size: 10pt"><tt>m</tt></span><span style="font-size: 10pt">)
- and copy
- (</span><span style="font-size: 10pt"><tt>t</tt></span><span style="font-size: 10pt">)
- commands:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>0,$ t "peter.c" 0</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">makes a copy of the current file at the beginning of
- </span><span style="font-size: 10pt"><tt>peter.c</tt></span><span style="font-size: 10pt">.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">
- command
- is a looping construct, like
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
- that refers to files instead of strings:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>X/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">runs the command in all
- files whose menu lines match the expression. The best example is
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>X/’/ w</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">which writes to disc all modified files.
- </span><span style="font-size: 10pt"><tt>Y</tt></span><span style="font-size: 10pt">
- is the complement of
- </span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">:
- it runs the command on all files whose menu lines don’t match the expression:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>Y/\.c/ D</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">deletes all files that don’t have
- </span><span style="font-size: 10pt"><tt>.c</tt></span><span style="font-size: 10pt">
- in their names, that is, it keeps all C source files and deletes the rest.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Braces allow commands to be grouped, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> </tt></span><span style="font-size: 9pt"><i>command1</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> </tt></span><span style="font-size: 9pt"><i>command2</i></span><span style="font-size: 9pt"><tt></tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">is syntactically a single command that runs two commands.
- Thus,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>X/\.c/ ,g/variable/ {</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> f</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> , x/.*\n/ g/variable/ p</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">finds all occurrences of
- </span><span style="font-size: 10pt"><tt>variable</tt></span><span style="font-size: 10pt">
- in C source files, and prints
- out the file names and lines of each match.
- The precise semantics of compound operations is discussed in the implementation
- sections below.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Finally,
- the undo command,
- </span><span style="font-size: 10pt"><tt>u</tt></span><span style="font-size: 10pt">,
- undoes the last command,
- no matter how many files were affected.
- Multiple undo operations move further back in time, so
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>u</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>u</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(which may be abbreviated
- </span><span style="font-size: 10pt"><tt>u2</tt></span><span style="font-size: 10pt">)
- undoes the last two commands. An undo may not be undone, however, nor
- may any command that adds or deletes files.
- Everything else is undoable, though, including for example
- </span><span style="font-size: 10pt"><tt>e</tt></span><span style="font-size: 10pt">
- commands:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>e filename</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>u</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">restores the state of the file completely, including its name, dot,
- and modified bit. Because of the undo, potentially dangerous commands
- are not guarded by confirmations. Only
- </span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">,
- which destroys the information necessary to restore itself, is protected.
- It will not delete a modified file, but a second
- </span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">
- of the same file will succeed regardless.
- The
- </span><span style="font-size: 10pt"><tt>q</tt></span><span style="font-size: 10pt">
- command, which exits
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
- is similarly guarded.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Mouse Interface
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is most commonly run
- connected to a bitmap display and mouse for interactive editing.
- The only difference in the command language
- between regular, mouse-driven
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>sam\fP-d
- is that if an address
- is provided without a command,
- </tt></span><span style="font-size: 10pt"><tt>sam\fP-d
- will print the text referenced by the address, but
- regular
- </tt></span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt"><tt>
- will highlight it on the screen — in fact,
- dot is always highlighted (see Figure 2).
- </tt></span><span style="font-size: 10pt"></span></p><center><img src="fig3.gif" /></center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 2. A
- </i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
- window. The scroll bar down the left
- represents the file, with the bubble showing the fraction
- visible in the window.
- The scroll bar may be manipulated by the mouse for convenient browsing.
- The current text,
- which is highlighted, need not fit on a line. Here it consists of one partial
- line, one complete line, and final partial line.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Each file may have zero or more windows open on the display.
- At any time, only one window in all of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is the
- </span><span style="font-size: 10pt"><i>current window,
- </i></span><span style="font-size: 10pt">that is, the window to which typing and mouse actions refer;
- this may be the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window (that in which commands may be typed)
- or one of the file windows.
- When a file has multiple windows, the image of the file in each window
- is always kept up to date.
- The current file is the last file affected by a command,
- so if the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window is current,
- the current window is not a window on the current file.
- However, each window on a file has its own value of dot,
- and when switching between windows on a single file,
- the file’s value of dot is changed to that of the window.
- Thus, flipping between windows behaves in the obvious, convenient way.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The mouse on the Blit has three buttons, numbered left to right.
- Button 3 has a list of commands to manipulate windows,
- followed by a list of ‘menu lines’ exactly as printed by the
- </span><span style="font-size: 10pt"><tt>f</tt></span><span style="font-size: 10pt">
- command, one per file (not one per window).
- These menu lines are sorted by file name.
- If the list is long, the Blit menu software will make it more manageable
- by generating a scrolling menu instead of an unwieldy long list.
- Using the menu to select a file from the list makes that file the current
- file, and the most recently current window in that file the current window.
- But if that file is already current, selecting it in the menu cycles through
- the windows on the file; this simple trick avoids a special menu to
- choose windows on a file.
- If there is no window open on the file,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- changes the mouse cursor to prompt the user to create one.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The commands on the button 3 menu are straightforward (see Figure 3), and
- are like the commands to manipulate windows in
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- the Blit’s window system.
- </span><span style="font-size: 10pt"><tt>New</tt></span><span style="font-size: 10pt">
- makes a new file, and gives it one empty window, whose size is determined
- by a rectangle swept by the mouse.
- </span><span style="font-size: 10pt"><tt>Zerox</tt></span><span style="font-size: 10pt">
- prompts for a window to be selected, and
- makes a clone of that window; this is how multiple windows are created on one file.
- </span><span style="font-size: 10pt"><tt>Reshape</tt></span><span style="font-size: 10pt">
- changes the size of the indicated window, and
- </span><span style="font-size: 10pt"><tt>close</tt></span><span style="font-size: 10pt">
- deletes it. If that is the last window open on the file,
- </span><span style="font-size: 10pt"><tt>close</tt></span><span style="font-size: 10pt">
- first does a
- </span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">
- command on the file.
- </span><span style="font-size: 10pt"><tt>Write</tt></span><span style="font-size: 10pt">
- is identical to a
- </span><span style="font-size: 10pt"><tt>w</tt></span><span style="font-size: 10pt">
- command on the file; it is in the menu purely for convenience.
- Finally,
- </span><span style="font-size: 10pt"><tt>~~sam~~</tt></span><span style="font-size: 10pt">
- is a menu item that appears between the commands and the file names.
- Selecting it makes the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window the current window,
- causing subsequent typing to be interpreted as commands.
- </span><span style="font-size: 10pt"></span></p><center><img src="fig2.gif" /></center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 3. The menu on button 3.
- The black rectangle on the left is a scroll bar; the menu is limited to
- the length shown to prevent its becoming unwieldy.
- Above the
- </i></span><span style="font-size: 8pt"><tt>~~sam~~</tt></span><span style="font-size: 8pt"><i>
- line is a list of commands;
- beneath it is a list of files, presented exactly as with the
- </i></span><span style="font-size: 8pt"><tt>f</tt></span><span style="font-size: 8pt"><i>
- command.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">When
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- requests that a window be swept, in response to
- </span><span style="font-size: 10pt"><tt>new</tt></span><span style="font-size: 10pt">,
- </span><span style="font-size: 10pt"><tt>zerox</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>reshape</tt></span><span style="font-size: 10pt">,
- it changes the mouse cursor from the usual arrow to a box with
- a small arrow.
- In this state, the mouse may be used to indicate an arbitrary rectangle by
- pressing button 3 at one corner and releasing it at the opposite corner.
- More conveniently,
- button 3 may simply be clicked,
- whereupon
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- creates the maximal rectangle that contains the cursor
- and abuts the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window.
- By placing the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window in the middle of the screen, the user can define two regions (one above,
- one below) in which stacked fully-overlapping
- windows can be created with minimal fuss (see Figure 1).
- This simple user interface trick makes window creation noticeably easier.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The cut-and-paste editor is essentially the same as that in Smalltalk-80.<sup></sup></span><sup><span style="font-size: 6pt">11</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- The text in dot is always highlighted on the screen.
- When a character is typed it replaces dot, and sets dot to the null
- string after the character. Thus, ordinary typing inserts text.
- Button 1 is used for selection:
- pressing the button, moving the mouse, and lifting the button
- selects (sets dot to) the text between the points where the
- button was pressed and released.
- Pressing and releasing at the same point selects a null string; this
- is called clicking. Clicking twice quickly, or
- </span><span style="font-size: 10pt"><i>double clicking,
- </i></span><span style="font-size: 10pt">selects larger objects;
- for example, double clicking in a word selects the word,
- double clicking just inside an opening bracket selects the text
- contained in the brackets (handling nested brackets correctly),
- and similarly for
- parentheses, quotes, and so on.
- The double-clicking rules reflect a bias toward
- programmers.
- If
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- were intended more for word processing, double-clicks would probably
- select linguistic structures such as sentences.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">If button 1 is pressed outside the current window, it makes the indicated
- window current.
- This is the easiest way to switch between windows and files.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Pressing button 2 brings up a menu of editing functions (see Figure 4).
- These mostly apply to the selected text:
- </span><span style="font-size: 10pt"><tt>cut</tt></span><span style="font-size: 10pt">
- deletes the selected text, and remembers it in a hidden buffer called the
- </span><span style="font-size: 10pt"><i>snarf buffer,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>paste</tt></span><span style="font-size: 10pt">
- replaces the selected text by the contents of the snarf buffer,
- </span><span style="font-size: 10pt"><tt>snarf</tt></span><span style="font-size: 10pt">
- just copies the selected text to the snarf buffer,
- </span><span style="font-size: 10pt"><tt>look</tt></span><span style="font-size: 10pt">
- searches forward for the next literal occurrence of the selected text, and
- </span><span style="font-size: 10pt"><tt><mux></tt></span><span style="font-size: 10pt">
- exchanges snarf buffers with the window system in which
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is running.
- Finally, the last regular expression used appears as a menu entry
- to search
- forward for the next occurrence of a match for the expression.
- </span><span style="font-size: 10pt"></span></p><center><img src="fig4.gif" /></center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 4. The menu on button 2.
- The bottom entry tracks the most recently used regular expression, which may
- be literal text.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The relationship between the command language and the mouse language is
- entirely due to the equality of dot and the selected text chosen
- with button 1 on the mouse.
- For example, to make a set of changes in a C subroutine, dot can be
- set by double clicking on the left brace that begins the subroutine,
- which sets dot for the command language.
- An address-free command then typed in the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window will apply only to the text between the opening and closing
- braces of the function.
- The idea is to select what you want, and then say what you want
- to do with it, whether invoked by a menu selection or by a typed command.
- And of course, the value of dot is highlighted on
- the display after the command completes.
- This relationship between mouse interface and command language
- is clumsy to explain, but comfortable, even natural, in practice.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>The Implementation
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The next few sections describe how
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is put together, first the host part,
- then the inter-component communication,
- then the terminal part.
- After explaining how the command language is implemented,
- the discussion follows (roughly) the path of a character
- from the temporary file on disc to the screen.
- The presentation centers on the data structures,
- because that is how the program was designed and because
- the algorithms are easy to provide, given the right data
- structures.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Parsing and execution
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The command language is interpreted by parsing each command with a
- table-driven recursive
- descent parser, and when a complete command is assembled, invoking a top-down
- executor.
- Most editors instead employ a simple character-at-a-time
- lexical scanner.
- Use of a parser makes it
- easy and unambiguous to detect when a command is complete,
- which has two advantages.
- First, escape conventions such as backslashes to quote
- multiple-line commands are unnecessary; if the command isn’t finished,
- the parser keeps reading. For example, a multiple-line append driven by an
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command is straightforward:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>x/.*\n/ g/Peter/ a</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>one line about Peter</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>another line about Peter</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>.</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Other UNIX editors would require a backslash after all but the last line.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The other advantage is specific to the two-process structure of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
- The host process must decide when a command is completed so the
- command interpreter can be called. This problem is easily resolved
- by having the lexical analyzer read the single stream of events from the
- terminal, directly executing all typing and mouse commands,
- but passing to the parser characters typed to the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- command window.
- This scheme is slightly complicated by the availability of cut-and-paste
- editing in the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window, but that difficulty is resolved by applying the rules
- used in
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">:
- when a newline is typed to the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window, all text between the newline and the previously typed newline
- is made available to the parser.
- This permits arbitrary editing to be done to a command before
- typing newline and thereby requesting execution.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The parser is driven by a table because the syntax of addresses
- and commands is regular enough
- to be encoded compactly. There are few special cases, such as the
- replacement text in a substitution, so the syntax of almost all commands
- can be encoded with a few flags.
- These include whether the command allows an address (for example,
- </span><span style="font-size: 10pt"><tt>e</tt></span><span style="font-size: 10pt">
- does not), whether it takes a regular expression (as in
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">),
- whether it takes replacement text (as in
- </span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">
- or
- </span><span style="font-size: 10pt"><tt>i</tt></span><span style="font-size: 10pt">),
- which may be multi-line, and so on.
- The internal syntax of regular expressions is handled by a separate
- parser; a regular expression is a leaf of the command parse tree.
- Regular expressions are discussed fully in the next section.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The parser table also has information about defaults, so the interpreter
- is always called with a complete tree. For example, the parser fills in
- the implicit
- </span><span style="font-size: 10pt"><tt>0</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">
- in the abbreviated address
- </span><span style="font-size: 10pt"><tt>,</tt></span><span style="font-size: 10pt">
- (comma),
- inserts a
- </span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
- to the left of an unadorned regular expression in an address,
- and provides the usual default address
- </span><span style="font-size: 10pt"><tt>.</tt></span><span style="font-size: 10pt">
- (dot) for commands that expect an address but are not given one.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Once a complete command is parsed, the evaluation is easy.
- The address is evaluated left-to-right starting from the value of dot,
- with a mostly ordinary expression evaluator.
- Addresses, like many of the data structures in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
- are held in a C structure and passed around by value:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>typedef long Posn; /* Position in a file */</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>typedef struct Range{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Posn p1, p2;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}Range;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>typedef struct Address{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Range r;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> File *f;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}Address;</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">An address is encoded as a substring (character positions
- </span><span style="font-size: 10pt"><tt>p1</tt></span><span style="font-size: 10pt">
- to
- </span><span style="font-size: 10pt"><tt>p2</tt></span><span style="font-size: 10pt">)
- in a file
- </span><span style="font-size: 10pt"><tt>f</tt></span><span style="font-size: 10pt">.
- (The data type
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- is described in detail below.)
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The address interpreter is an
- </span><span style="font-size: 10pt"><tt>Address</tt></span><span style="font-size: 10pt">-valued
- function that traverses the parse tree describing an address (the
- parse tree for the address has type
- </span><span style="font-size: 10pt"><tt>Addrtree</tt></span><span style="font-size: 10pt">):
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>Address</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>address(ap, a, sign)</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Addrtree *ap;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Address a;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> int sign;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Address a2;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> do</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> switch(ap->type){</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> case ’.’:</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a=a.f->dot;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> break;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> case ’$’:</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a.r.p1=a.r.p2=a.f->nbytes;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> break;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> case ’"’: </tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a=matchfile(a, ap->aregexp)->dot; </tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> break;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> case ’,’:</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a2=address(ap->right, a, 0);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a=address(ap->left, a, 0);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> if(a.f!=a2.f || a2.r.p2<a.r.p1)</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> error(Eorder);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a.r.p2=a2.r.p2;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> return a;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> /* and so on */</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> }</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> while((ap=ap->right)!=0);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> return a;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Throughout, errors are handled by a non-local
- </span><span style="font-size: 10pt"><tt>goto</tt></span><span style="font-size: 10pt">
- (a
- </span><span style="font-size: 10pt"><tt>setjmp/longjmp</tt></span><span style="font-size: 10pt">
- in C terminology)
- hidden in a routine called
- </span><span style="font-size: 10pt"><tt>error</tt></span><span style="font-size: 10pt">
- that immediately aborts the execution, retracts any
- partially made changes (see the section below on ‘undoing’), and
- returns to the top level of the parser.
- The argument to
- </span><span style="font-size: 10pt"><tt>error</tt></span><span style="font-size: 10pt">
- is an enumeration type that
- is translated to a terse but possibly helpful
- message such as ‘?addresses out of order.’
- Very common messages are kept short; for example the message for
- a failed regular expression search is ‘?search.’
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Character addresses such as
- </span><span style="font-size: 10pt"><tt>#3</tt></span><span style="font-size: 10pt">
- are trivial to implement, as the
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- data structure is accessible by character number.
- However,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- keeps no information about the position of newlines — it is too
- expensive to track dynamically — so line addresses are computed by reading
- the file, counting newlines. Except in very large files, this has proven
- acceptable: file access is fast enough to make the technique practical,
- and lines are not central to the structure of the command language.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The command interpreter, called
- </span><span style="font-size: 10pt"><tt>cmdexec</tt></span><span style="font-size: 10pt">,
- is also straightforward. The parse table includes a
- function to call to interpret a particular command. That function
- receives as arguments
- the calculated address
- for the command
- and the command tree (of type
- </span><span style="font-size: 10pt"><tt>Cmdtree</tt></span><span style="font-size: 10pt">),
- which may contain information such as the subtree for compound commands.
- Here, for example, is the function for the
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>v</tt></span><span style="font-size: 10pt">
- commands:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>int</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>g_cmd(a, cp)</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Address a;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> Cmdtree *cp;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> compile(cp->regexp);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> if(execute(a.f, a.r.p1, a.r.p2)!=(cp->cmdchar==’v’)){</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> a.f->dot=a;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> return cmdexec(a, cp->subcmd);</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> }</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> return TRUE; /* cause execution to continue */</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">(</span><span style="font-size: 10pt"><tt>Compile</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
- are part of the regular expression code, described in the next section.)
- Because the parser and the
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- data structure do most of the work, most commands
- are similarly brief.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Regular expressions
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The regular expression code in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is an interpreted, rather than compiled on-the-fly, implementation of Thompson’s
- non-deterministic finite automaton algorithm.<sup></sup></span><sup><span style="font-size: 6pt">12</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- The syntax and semantics of the expressions are as in the UNIX program
- </span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,
- including alternation, closures, character classes, and so on.
- The only changes in the notation are two additions:
- </span><span style="font-size: 10pt"><tt>\n</tt></span><span style="font-size: 10pt">
- is translated to, and matches, a newline character, and
- </span><span style="font-size: 10pt"><tt>@</tt></span><span style="font-size: 10pt">
- matches any character. In
- </span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,
- the character
- </span><span style="font-size: 10pt"><tt>.</tt></span><span style="font-size: 10pt">
- matches any character except newline, and in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- the same rule seemed safest, to prevent idioms like
- </span><span style="font-size: 10pt"><tt>.*</tt></span><span style="font-size: 10pt">
- from spanning newlines.
- </span><span style="font-size: 10pt"><tt>Egrep</tt></span><span style="font-size: 10pt">
- expressions are arguably too complicated for an interactive editor —
- certainly it would make sense if all the special characters were two-character
- sequences, so that most of the punctuation characters wouldn’t have
- peculiar meanings — but for an interesting command language, full
- regular expressions are necessary, and
- </span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">
- defines the full regular expression syntax for UNIX programs.
- Also, it seemed superfluous to define a new syntax, since various UNIX programs
- (</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">,
- </span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">)
- define too many already.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The expressions are compiled by a routine,
- </span><span style="font-size: 10pt"><tt>compile</tt></span><span style="font-size: 10pt">,
- that generates the description of the non-deterministic finite state machine.
- A second routine,
- </span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">,
- interprets the machine to generate the leftmost-longest match of the
- expression in a substring of the file.
- The algorithm is described elsewhere.<sup></sup></span><sup><span style="font-size: 6pt">12,13</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>Execute</tt></span><span style="font-size: 10pt">
- reports
- whether a match was found, and sets a global variable,
- of type
- </span><span style="font-size: 10pt"><tt>Range</tt></span><span style="font-size: 10pt">,
- to the substring matched.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A trick is required to evaluate the expression in reverse, such as when
- searching backwards for an expression.
- For example,
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>-/P.*r/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">looks backwards through the file for a match of the expression.
- The expression, however, is defined for a forward search.
- The solution is to construct a machine identical to the machine
- for a forward search except for a reversal of all the concatenation
- operators (the other operators are symmetric under direction reversal),
- to exchange the meaning of the operators
- </span><span style="font-size: 10pt"><tt>^</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">,
- and then to read the file backwards, looking for the
- usual earliest longest match.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Execute</tt></span><span style="font-size: 10pt">
- generates only one match each time it is called.
- To interpret looping constructs such as the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- must therefore synchronize between
- calls of
- </span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
- to avoid
- problems with null matches.
- For example, even given the leftmost-longest rule,
- the expression
- </span><span style="font-size: 10pt"><tt>a*</tt></span><span style="font-size: 10pt">
- matches three times in the string
- </span><span style="font-size: 10pt"><tt>ab</tt></span><span style="font-size: 10pt">
- (the character
- </span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">,
- the null string between the
- </span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>b</tt></span><span style="font-size: 10pt">,
- and the final null string).
- After returning a match for the
- </span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- must not match the null string before the
- </span><span style="font-size: 10pt"><tt>b</tt></span><span style="font-size: 10pt">.
- The algorithm starts
- </span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
- at the end of its previous match, and
- if the match it returns
- is null and abuts the previous match, rejects the match and advances
- the initial position one character.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Memory allocation
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The C language has no memory allocation primitives, although a standard
- library routine,
- </span><span style="font-size: 10pt"><tt>malloc</tt></span><span style="font-size: 10pt">,
- provides adequate service for simple programs.
- For specific uses, however,
- it can be better to write a custom allocator.
- The allocator (or rather, pair of allocators) described here
- work in both the terminal and host parts of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
- They are designed for efficient manipulation of strings,
- which are allocated and freed frequently and vary in length from essentially
- zero to 32 Kbytes (very large strings are written to disc).
- More important, strings may be large and change size often,
- so to minimize memory usage it is helpful to reclaim and to coalesce the
- unused portions of strings when they are truncated.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Objects to be allocated in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- are of two flavors:
- the first is C
- </span><span style="font-size: 10pt"><tt>structs</tt></span><span style="font-size: 10pt">,
- which are small and often addressed by pointer variables;
- the second is variable-sized arrays of characters
- or integers whose
- base pointer is always used to access them.
- The memory allocator in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is therefore in two parts:
- first, a traditional first-fit allocator that provides fixed storage for
- </span><span style="font-size: 10pt"><tt>structs</tt></span><span style="font-size: 10pt">;
- and second, a garbage-compacting allocator that reduces storage
- overhead for variable-sized objects, at the cost of some bookkeeping.
- The two types of objects are allocated from adjoining arenas, with
- the garbage-compacting allocator controlling the arena with higher addresses.
- Separating into two arenas simplifies compaction and prevents fragmentation due
- to immovable objects.
- The access rules for garbage-compactable objects
- (discussed in the next paragraph) allow them to be relocated, so when
- the first-fit arena needs space, it moves the garbage-compacted arena
- to higher addresses to make room. Storage is therefore created only
- at successively higher addresses, either when more garbage-compacted
- space is needed or when the first-fit arena pushes up the other arena.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Objects that may be compacted declare to the
- allocator a cell that is guaranteed to be the sole repository of the
- address of the object whenever a compaction can occur.
- The compactor can then update the address when the object is moved.
- For example, the implementation of type
- </span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
- (really a variable-length array)
- is:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>typedef struct List{</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> int nused;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt> long *ptr;</tt></span></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>}List;</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>ptr</tt></span><span style="font-size: 10pt">
- cell must always be used directly, and never copied. When a
- </span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
- is to be created the
- </span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
- structure is allocated in the ordinary first-fit arena
- and its
- </span><span style="font-size: 10pt"><tt>ptr</tt></span><span style="font-size: 10pt">
- is allocated in the garbage-compacted arena.
- A similar data type for strings, called
- </span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">,
- stores variable-length character arrays of up to 32767 elements.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A related matter of programming style:
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- frequently passes structures by value, which
- simplifies the code.
- Traditionally, C programs have
- passed structures by reference, but implicit allocation on
- the stack is easier to use.
- Structure passing is a relatively new feature of C
- (it is not in the
- standard reference manual for C<sup></sup></span><sup><span style="font-size: 6pt">14</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">), and is poorly supported in most
- commercial C compilers.
- It’s convenient and expressive, though,
- and simplifies memory management by
- avoiding the allocator altogether
- and eliminating pointer aliases.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Data structures for manipulating files
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Experience with
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- showed that the requirements
- of the file data structure were few, but strict.
- First, files need to be read and written quickly;
- adding a fresh file must be painless.
- Second, the implementation must place no arbitrary upper limit on
- the number or sizes of files. (It should be practical to edit many files,
- and files up to megabytes in length should be handled gracefully.)
- This implies that files be stored on disc, not in main memory.
- (Aficionados of virtual memory may argue otherwise, but the
- implementation of virtual
- memory in our system is not something to depend on
- for good performance.)
- Third, changes to files need be made by only two primitives:
- deletion and insertion.
- These are inverses of each other,
- which simplifies the implementation of the undo operation.
- Finally,
- it must be easy and efficient to access the file, either
- forwards or backwards, a byte at a time.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- data type is constructed from three simpler data structures that hold arrays
- of characters.
- Each of these types has an insertion and deletion operator, and the
- insertion and deletion operators of the
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- type itself are constructed from them.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The simplest type is the
- </span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">,
- which is used to hold strings in main memory.
- The code that manages
- </span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
- guarantees that they will never be longer
- than some moderate size, and in practice they are rarely larger than 8 Kbytes.
- </span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
- have two purposes: they hold short strings like file names with little overhead,
- and because they are deliberately small, they are efficient to modify.
- They are therefore used as the data structure for in-memory caches.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The disc copy of the file is managed by a data structure called a
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">,
- which corresponds to a temporary file. A
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- has no storage in main memory other than bookkeeping information;
- the actual data being held is all on the disc.
- To reduce the number of open files needed,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- opens a dozen temporary UNIX files and multiplexes the
- </span><span style="font-size: 10pt"><tt>Discs</tt></span><span style="font-size: 10pt">
- upon them.
- This permits many files to
- be edited; the entire
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- source (48 files) may be edited comfortably with a single
- instance of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
- Allocating one temporary file per
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- would strain the operating system’s limit on the number of open files.
- Also, spreading the traffic among temporary files keeps the files shorter,
- and shorter files are more efficiently implemented by the UNIX
- I/O subsystem.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- is an array of fixed-length blocks, each of which contains
- between 1 and 4096 characters of active data.
- (The block size of our UNIX file system is 4096 bytes.)
- The block addresses within the temporary file and the length of each
- block are stored in a
- </span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">.
- When changes are made the live part of blocks may change size.
- Blocks are created and coalesced when necessary to try to keep the sizes
- between 2048 and 4096 bytes.
- An actively changing part of the
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- therefore typically has about a kilobyte of slop that can be
- inserted or deleted
- without changing more than one block or affecting the block order.
- When an insertion would overflow a block, the block is split, a new one
- is allocated to receive the overflow, and the memory-resident list of blocks
- is rearranged to reflect the insertion of the new block.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Obviously, going to the disc for every modification to the file is
- prohibitively expensive.
- The data type
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
- consists of a
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- to hold the data and a
- </span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">
- that acts as a cache.
- This is the first of a series of caches throughout the data structures in
- </span><span style="font-size: 10pt"><tt>sam.</tt></span><span style="font-size: 10pt">
- The caches not only improve performance, they provide a way to organize
- the flow of data, particularly in the communication between the host
- and terminal.
- This idea is developed below, in the section on communications.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">To reduce disc traffic, changes to a
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
- are mediated by a variable-length string, in memory, that acts as a cache.
- When an insertion or deletion is made to a
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
- if the change can be accommodated by the cache, it is done there.
- If the cache becomes bigger than a block because of an insertion,
- some of it is written to the
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- and deleted from the cache.
- If the change does not intersect the cache, the cache is flushed.
- The cache is only loaded at the new position if the change is smaller than a block;
- otherwise, it is sent directly to the
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">.
- This is because
- large changes are typically sequential,
- whereupon the next change is unlikely to overlap the current one.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">A
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- comprises a
- </span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">
- to hold the file name and some ancillary data such as dot and the modified bit.
- The most important components, though, are a pair of
- </span><span style="font-size: 10pt"><tt>Buffers</tt></span><span style="font-size: 10pt">,
- one called the transcript and the other the contents.
- Their use is described in the next section.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The overall structure is shown in Figure 5.
- Although it may seem that the data is touched many times on its
- way from the
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">,
- it is read (by one UNIX system call) directly into the cache of the
- associated
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">;
- no extra copy is done.
- Similarly, when flushing the cache, the text is written
- directly from the cache to disc.
- Most operations act directly on the text in the cache.
- A principle applied throughout
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is that the fewer times the data is copied, the faster the program will run
- (see also the paper by Waite<sup></sup></span><sup><span style="font-size: 6pt">15</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">).
- </span><span style="font-size: 10pt"></span></p><center><img src="sam2.png"></center>
- </center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 5. File data structures.
- The temporary files are stored in the standard repository for such files
- on the host system.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The contents of a
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- are accessed by a routine that
- copies to a buffer a substring of a file starting at a specified offset.
- To read a byte at a time, a
- per-</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- array is loaded starting from a specified initial position,
- and bytes may then be read from the array.
- The implementation is done by a macro similar to the C standard I/O
- </span><span style="font-size: 10pt"><tt>getc</tt></span><span style="font-size: 10pt">
- macro.<sup></sup></span><sup><span style="font-size: 6pt">14</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- Because the reading may be done at any address, a minor change to the
- macro allows the file to be read backwards.
- This array is read-only; there is no
- </span><span style="font-size: 10pt"><tt>putc</tt></span><span style="font-size: 10pt">.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Doing and undoing
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- has an unusual method for managing changes to files.
- The command language makes it easy to specify multiple variable-length changes
- to a file millions of bytes long, and such changes
- must be made efficiently if the editor is to be practical.
- The usual techniques for inserting and deleting strings
- are inadequate under these conditions.
- The
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- data structures are designed for efficient random access to long strings,
- but care must be taken to avoid super-linear behavior when making
- many changes simultaneously.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- uses a two-pass algorithm for making changes, and treats each file as a database
- against which transactions are registered.
- Changes are not made directly to the contents.
- Instead, when a command is started, a ‘mark’ containing
- a sequence number is placed in the transcript
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
- and each change made to the file, either an insertion or deletion
- or a change to the file name,
- is appended to the end of the transcript.
- When the command is complete, the transcript is rewound to the
- mark and applied to the contents.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">One reason for separating evaluation from
- application in this way is to simplify tracking the addresses of changes
- made in the middle of a long sequence.
- The two-pass algorithm also allows all changes to apply to the
- </span><span style="font-size: 10pt"><i>original</i></span><span style="font-size: 10pt">
- data: no change can affect another change made in the same command.
- This is particularly important when evaluating an
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command because it prevents regular expression matches
- from stumbling over changes made earlier in the execution.
- Also, the two-pass
- algorithm is cleaner than the way other UNIX editors allow changes to
- affect each other;
- for example,
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s
- idioms to do things like delete every other line
- depend critically on the implementation.
- Instead,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- simple model, in which all changes in a command occur effectively
- simultaneously, is easy to explain and to understand.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The records in the transcript are of the form ‘‘delete substring from
- locations
- 123 to 456’’ and ‘‘insert 11 characters ‘hello there’ at location 789.’’
- (It is an error if the changes are not at monotonically greater
- positions through the file.)
- While the update is occurring, these numbers must be
- offset by earlier changes, but that is straightforward and
- local to the update routine;
- moreover, all the numbers have been computed
- before the first is examined.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Treating the file as a transaction system has another advantage:
- undo is trivial.
- All it takes is to invert the transcript after it has been
- implemented, converting insertions
- into deletions and vice versa, and saving them in a holding
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">.
- The ‘do’ transcript can then be deleted from
- the transcript
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
- and replaced by the ‘undo’ transcript.
- If an undo is requested, the transcript is rewound and the undo transcript
- executed.
- Because the transcript
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
- is not truncated after each command, it accumulates
- successive changes.
- A sequence of undo commands
- can therefore back up the file arbitrarily,
- which is more helpful than the more commonly implemented self-inverse form of undo.
- (</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- provides no way to undo an undo, but if it were desired,
- it would be easy to provide by re-interpreting the ‘do’ transcript.)
- Each mark in the transcript contains a sequence number and the offset into
- the transcript of the previous mark, to aid in unwinding the transcript.
- Marks also contain the value of dot and the modified bit so these can be
- restored easily.
- Undoing multiple files is easy; it merely demands undoing all files whose
- latest change has the same sequence number as the current file.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Another benefit of having a transcript is that errors encountered in the middle
- of a complicated command need not leave the files in an intermediate state.
- By rewinding the transcript to the mark beginning the command,
- the partial command can be trivially undone.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">When the update algorithm was first implemented, it was unacceptably slow,
- so a cache was added to coalesce nearby changes,
- replacing multiple small changes by a single larger one.
- This reduced the number
- of insertions into the transaction
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
- and made a dramatic improvement in performance,
- but made it impossible
- to handle changes in non-monotonic order in the file; the caching method
- only works if changes don’t overlap.
- Before the cache was added, the transaction could in principle be sorted
- if the changes were out of order, although
- this was never done.
- The current status is therefore acceptable performance with a minor
- restriction on global changes, which is sometimes, but rarely, an annoyance.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The update algorithm obviously paws the data more than simpler
- algorithms, but it is not prohibitively expensive;
- the caches help.
- (The principle of avoiding copying the data is still honored here,
- although not as piously:
- the data is moved from contents’ cache to
- the transcript’s all at once and through only one internal buffer.)
- Performance figures confirm the efficiency.
- To read from a dead start a hundred kilobyte file on a VAX-11/750
- takes 1.4 seconds of user time, 2.5 seconds of system time,
- and 5 seconds of real time.
- Reading the same file in
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- takes 6.0 seconds of user time, 1.7 seconds of system time,
- and 8 seconds of real time.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- uses about half the CPU time.
- A more interesting example is the one stated above:
- inserting a character between every pair of characters in the file.
- The
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- command is
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>,y/@/ a/x/</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">and takes 3 CPU seconds per kilobyte of input file, of which
- about a third is spent in the regular expression code.
- This translates to about 500 changes per second.
- </span><span style="font-size: 10pt"><tt>Ed</tt></span><span style="font-size: 10pt">
- takes 1.5 seconds per kilobyte to make a similar change (ignoring newlines),
- but cannot undo it.
- The same example in
- </span><span style="font-size: 10pt"><tt>ex</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- a variant of
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- done at the University of California at Berkeley,
- which allows one level of undoing, again takes 3 seconds.
- In summary,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- performance is comparable to that of other UNIX editors, although it solves
- a harder problem.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Communications
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The discussion so far has described the implementation of the host part of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">;
- the next few sections explain how a machine with mouse and bitmap display
- can be engaged to improve interaction.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is not the first editor to be written as two processes,<sup></sup></span><sup><span style="font-size: 6pt">16</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- but its implementation
- has some unusual aspects.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">There are several ways
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- host and terminal parts may be connected.
- The first and simplest is to forgo the terminal part and use the host
- part’s command language to edit text on an ordinary terminal.
- This mode is invoked by starting
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- with the
- </span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
- option.
- With no options,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- runs separate host and terminal programs,
- communicating with a message protocol over the physical
- connection that joins them.
- Typically, the connection is an RS-232 link between a Blit
- (the prototypical display for
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">)
- and a host running
- the Ninth Edition of the UNIX operating system.<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- (This is the version of the system used in the Computing Sciences Research
- Center at AT&T Bell Laboratories [now Lucent Technologies, Bell Labs], where I work. Its relevant
- aspects are discussed in the Blit paper.<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">)
- The implementation of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- for the SUN computer runs both processes on the same machine and
- connects them by a pipe.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The low bandwidth of an RS-232 link
- necessitated the split between
- the two programs.
- The division is a mixed blessing:
- a program in two parts is much harder to write and to debug
- than a self-contained one,
- but the split makes several unusual configurations possible.
- The terminal may be physically separated from the host, allowing the conveniences
- of a mouse and bitmap display to be taken home while leaving the files at work.
- It is also possible to run the host part on a remote machine:
- </span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 9pt"><tt>sam -r host</tt></span></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">connects to the terminal in the usual way, and then makes a call
- across the network to establish the host part of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- on the named machine.
- Finally, it cross-connects the I/O to join the two parts.
- This allows
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- to be run on machines that do not support bitmap displays;
- for example,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is the editor of choice on our Cray X-MP/24.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>-r</tt></span><span style="font-size: 10pt">
- involves
- </span><span style="font-size: 10pt"><i>three</i></span><span style="font-size: 10pt">
- machines: the remote host, the terminal, and the local host.
- The local host’s job is simple but vital: it passes the data
- between the remote host and terminal.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The host and terminal exchange messages asynchronously
- (rather than, say, as remote procedure calls) but there is no
- error detection or correction
- because, whatever the configuration, the connection is reliable.
- Because the terminal handles mundane interaction tasks such as
- popping up menus and interpreting the responses, the messages are about
- data, not actions.
- For example, the host knows nothing about what is displayed on the screen,
- and when the user types a character, the message sent to the host says
- ‘‘insert a one-byte string at location 123 in file 7,’’ not ‘‘a character
- was typed at the current position in the current file.’’
- In other words, the messages look very much like the transaction records
- in the transcripts.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Either the host or terminal part of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- may initiate a change to a file.
- The command language operates on the host, while typing and some
- mouse operations are executed directly in the terminal to optimize response.
- Changes initiated by the host program must be transmitted to the terminal,
- and
- vice versa.
- (A token is exchanged to determine which end is in control,
- which means that characters typed while a time-consuming command runs
- must be buffered and do not appear until the command is complete.)
- To maintain consistent information,
- the host and terminal track changes through a per-file
- data structure that records what portions of the file
- the terminal has received.
- The data structure, called a
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- (a weak pun: it’s a file with holes)
- is held and updated by both the host and terminal.
- A
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- is a list of
- </span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
- holding those parts of the file known to the terminal,
- separated by counts of the number of bytes in the interstices.
- Of course, the host doesn’t keep a separate copy of the data (it only needs
- the lengths of the various pieces),
- but the structure is the same on both ends.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- in the terminal doubles as a cache.
- Since the terminal keeps the text for portions of the file it has displayed,
- it need not request data from the host when revisiting old parts of the file
- or redrawing obscured windows, which speeds things up considerably
- over low-speed links.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">It’s trivial for the terminal to maintain its
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">,
- because all changes made on the terminal apply to parts of the file
- already loaded there.
- Changes made by the host are compared against the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- during the update sequence after each command.
- Small changes to pieces of the file loaded in the terminal
- are sent in their entirety.
- Larger changes, and changes that fall entirely in the holes,
- are transmitted as messages without literal data:
- only the lengths of the deleted and inserted strings are transmitted.
- When a command is completed, the terminal examines its visible
- windows to see if any holes in their
- </span><span style="font-size: 10pt"><tt>Rasps</tt></span><span style="font-size: 10pt">
- intersect the visible portion of the file.
- It then requests the missing data from the host,
- along with up to 512 bytes of surrounding data, to minimize
- the number of messages when visiting a new portion of the file.
- This technique provides a kind of two-level lazy evaluation for the terminal.
- The first level sends a minimum of information about
- parts of the file not being edited interactively;
- the second level waits until a change is displayed before
- transmitting the new data.
- Of course,
- performance is also helped by having the terminal respond immediately to typing
- and simple mouse requests.
- Except for small changes to active pieces of the file, which are
- transmitted to the terminal without negotiation,
- the terminal is wholly responsible for deciding what is displayed;
- the host uses the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- only to tell the terminal what might be relevant.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">When a change is initiated by the host,
- the messages to the terminal describing the change
- are generated by the routine that applies the transcript of the changes
- to the contents of the
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">.
- Since changes are undone by the same update routine,
- undoing requires
- no extra code in the communications;
- the usual messages describing changes to the file are sufficient
- to back up the screen image.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- is a particularly good example of the way caches are used in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
- First, it facilitates access to the active portion of the text by placing
- the busy text in main memory.
- In so doing, it provides efficient access
- to a large data structure that does not fit in memory.
- Since the form of data is to be imposed by the user, not by the program,
- and because characters will frequently be scanned sequentially,
- files are stored as flat objects.
- Caches help keep performance good and linear when working with such
- data.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Second, the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- and several of the other caches have some
- </span><span style="font-size: 10pt"><i>read-ahead;</i></span><span style="font-size: 10pt">
- that is, the cache is loaded with more information than is needed for
- the job immediately at hand.
- When manipulating linear structures, the accesses are usually sequential,
- and read-ahead can significantly reduce the average time to access the
- next element of the object.
- Sequential access is a common mode for people as well as programs;
- consider scrolling through a document while looking for something.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Finally, like any good data structure,
- the cache guides the algorithm, or at least the implementation.
- The
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- was actually invented to control the communications between the host and
- terminal parts, but I realized very early that it was also a form of
- cache. Other caches were more explicitly intended to serve a double
- purpose: for example, the caches in
- </span><span style="font-size: 10pt"><tt>Files</tt></span><span style="font-size: 10pt">
- that coalesce updates not only reduce traffic to the
- transcript and contents
- </span><span style="font-size: 10pt"><tt>Buffers</tt></span><span style="font-size: 10pt">,
- they also clump screen updates so that complicated changes to the
- screen are achieved in
- just a few messages to the terminal.
- This saved me considerable work: I did not need to write special
- code to optimize the message traffic to the
- terminal.
- Caches pay off in surprising ways.
- Also, they tend to be independent, so their performance improvements
- are multiplicative.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Data structures in the terminal
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The terminal’s job is to display and to maintain a consistent image of
- pieces of the files being edited.
- Because the text is always in memory, the data structures are
- considerably simpler than those in the host part.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- typically has far more windows than does
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
- the window system within which its Blit implementation runs.
- </span><span style="font-size: 10pt"><tt>Mux</tt></span><span style="font-size: 10pt">
- has a fairly small number of asynchronously updated windows;
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- needs a large number of synchronously updated windows that are
- usually static and often fully obscured.
- The different tradeoffs guided
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- away from the memory-intensive implementation of windows, called
- </span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">17</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- used in
- </span><span style="font-size: 10pt"><tt>mux.</tt></span><span style="font-size: 10pt">
- Rather than depending on a complete bitmap image of the display for each window,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- regenerates the image from its in-memory text
- (stored in the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">)
- when necessary, although it will use such an image if it is available.
- Like
- </span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">,
- though,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- uses the screen bitmap as active storage in which to update the image using
- </span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">.<sup></sup></span><sup><span style="font-size: 6pt">18,19</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- The resulting organization, pictured in Figure 6,
- has a global array of windows, called
- </span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">,
- each of which holds an image of a piece of text held in a data structure
- called a
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">,
- which in turn represents
- a rectangular window full of text displayed in some
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">.
- Each
- </span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
- appears in a global list that orders them all front-to-back
- on the display, and simultaneously as an element of a per-file array
- that holds all the open windows for that file.
- The complement in the terminal of the
- </span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
- on the host is called a
- </span><span style="font-size: 10pt"><tt>Text</tt></span><span style="font-size: 10pt">;
- each connects its
- </span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">
- to the associated
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">.
- </span><span style="font-size: 10pt"></span></p><center><img src="sam3.png"></center>
- </center>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 6. Data structures in the terminal.
- </i></span><span style="font-size: 8pt"><tt>Flayers</tt></span><span style="font-size: 8pt"><i>
- are also linked together into a front-to-back list.
- </i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>
- are discussed in the next section.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- for a
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- contains the image of the text.
- For a fully visible window, the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- will be the screen (or at least the
- </span><span style="font-size: 10pt"><tt>Layer</tt></span><span style="font-size: 10pt">
- in which
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is being run),
- while for partially obscured windows the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- will be off-screen.
- If the window is fully obscured, the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- will be null.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- is a kind of cache.
- When making changes to the display, most of the original image will
- look the same in the final image, and the update algorithms exploit this.
- The
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- software updates the image in the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- incrementally; the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- is not just an image, it is a data structure.<sup></sup></span><sup><span style="font-size: 6pt">18,19</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- The job of the software that updates the display is therefore
- to use as much as possible of the existing image (converting the
- text from ASCII characters to pixels is expensive) in a sort of two-dimensional
- string insertion algorithm.
- The details of this process are described in the next section.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- software has no code to support overlapping windows;
- its job is to keep a single
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- up to date.
- It falls to the
- </span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
- software to multiplex the various
- </span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
- onto the screen.
- The problem of maintaining overlapping
- </span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">
- is easier than for
- </span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">17</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
- because changes are made synchronously and because the contents of the window
- can be reconstructed from the data stored in the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">;
- the
- </span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">
- software
- makes no such assumptions.
- In
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
- the window being changed is almost always fully visible, because the current
- window is always fully visible, by construction.
- However, when multi-file changes are being made, or when
- more than one window is open on a file,
- it may be necessary to update partially obscured windows.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">There are three cases: the window is
- fully visible, invisible (fully obscured), or partially visible.
- If fully visible, the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- is part of the screen, so when the
- </span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
- update routine calls the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- update routine, the screen will be updated directly.
- If the window is invisible,
- there is no associated
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">,
- and all that is necessary is to update the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- data structure, not the image.
- If the window is partially visible, the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- routine is called to update the image in the off-screen
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">,
- which may require regenerating it from the text of the window.
- The
- </span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
- code then clips this
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- against the
- </span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
- of all
- </span><span style="font-size: 10pt"><tt>Frames</tt></span><span style="font-size: 10pt">
- in front of the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- being modified, and the remainder is copied to the display.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">This is much faster than recreating the image off-screen
- for every change, or clipping all the changes made to the image
- during its update.
- Unfortunately, these caches can also consume prohibitive amounts of
- memory, so they are freed fairly liberally — after every change to the
- front-to-back order of the
- </span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">.
- The result is that
- the off-screen
- </span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
- exist only while multi-window changes are occurring,
- which is the only time the performance improvement they provide is needed.
- Also, the user interface causes fully-obscured windows to be the
- easiest to make —
- creating a canonically sized and placed window requires only a button click
- — which reduces the need for caching still further.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Screen update
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Only two low-level primitives are needed for incremental update:
- </span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">,
- which copies rectangles of pixels, and
- </span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
- (which in turn calls
- </span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">),
- which draws a null-terminated character string in a
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">.
- A
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- contains a list of
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">,
- each of which defines a horizontal strip of text in the window
- (see Figure 7).
- A
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- has a character string
- </span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">,
- and a
- </span><span style="font-size: 10pt"><tt>Rectangle</tt></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">
- that defines the location of the strip in the window.
- (The text in
- </span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">
- is stored in the
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- separately from the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- associated with the window’s file, so
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- are self-contained.)
- The invariant is that
- the image of the
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- can be reproduced by calling
- </span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
- with argument
- </span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">
- to draw the string in
- </span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">,
- and the resulting picture fits perfectly within
- </span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">.
- In other words, the
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- define the tiling of the window.
- The tiling may be complicated by long lines of text, which
- are folded onto the next line.
- Some editors use horizontal scrolling to avoid this complication,
- but to be comfortable this technique requires that lines not be
- </span><span style="font-size: 10pt"><i>too</i></span><span style="font-size: 10pt">
- long;
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- has no such restriction.
- Also, and perhaps more importantly, UNIX programs and terminals traditionally fold
- long lines to make their contents fully visible.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Two special kinds of
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- contain a single
- character: either a newline or a tab.
- Newlines and tabs are white space.
- A newline
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- always extends to the right edge of the window,
- forcing the following
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- to the next line.
- The width of a tab depends on where it is located:
- it forces the next
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- to begin at a tab location.
- Tabs also
- have a minimum width equivalent to a blank (blanks are
- drawn by
- </span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
- and are not treated specially); newlines have a minimum width of zero.
- </span><span style="font-size: 10pt"></span></p><center><img src="sam4.png"></center>
- </center>
- <p style="margin-top: 0; margin-bottom: 0.08in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 8pt"><i>Figure 7. A line of text showing its
- </i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>.
- The first two blank
- </i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>
- contain tabs; the last contains a newline.
- Spaces are handled as ordinary characters.
- </i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="margin-top: 0; margin-bottom: 0.02in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The update algorithms always use the
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
- image of the text (either the display or cache
- </span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">);
- they never examine the characters within a
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- except when the
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- needs to be split in two.
- Before a change, the window consists of a tiling of
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">;
- after the change the window is tiled differently.
- The update algorithms rearrange the tiles in place, without
- backup storage.
- The algorithms are not strictly optimal — for example, they can
- clear a pixel that is later going to be written upon —
- but they never move a tile that doesn’t need to be moved,
- and they move each tile at most once.
- </span><span style="font-size: 10pt"><tt>Frinsert</tt></span><span style="font-size: 10pt">
- on a Blit can absorb over a thousand characters a second if the strings
- being inserted are a few tens of characters long.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Consider
- </span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">.
- Its job is to delete a substring from a
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- and restore the image of the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">.
- The image of a substring has a peculiar shape (see Figure 2) comprising
- possibly a partial line,
- zero or more full lines,
- and possibly a final partial line.
- For reference, call this the
- </span><span style="font-size: 10pt"><i>Z-shape.
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Frdelete</tt></span><span style="font-size: 10pt">
- begins by splitting, if necessary, the
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- containing the ends of
- the substring so the substring begins and ends on
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- boundaries.
- Because the substring is being deleted, its image is not needed,
- so the Z-shape is then cleared.
- Then, tiles (that is, the images of
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">)
- are copied, using
- </span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">,
- from immediately after the Z-shape to
- the beginning of the Z-shape,
- resulting in a new Z-shape.
- (</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- whose contents would span two lines in the new position must first be split.)
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Copying the remainder of the
- </span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
- tile by tile
- this way will clearly accomplish the deletion but eventually,
- typically when the copying algorithm encounters a tab or newline,
- the old and new
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- coordinates of the tile
- to be copied are the same.
- This correspondence implies
- that the Z-shape has its beginning and ending edges aligned
- vertically, and a sequence of at most two
- </span><span style="font-size: 10pt"><tt>bitblts</tt></span><span style="font-size: 10pt">
- can be used to copy the remaining tiles.
- The last step is to clear out the resulting empty space at the bottom
- of the window;
- the number of lines to be cleared is the number of complete lines in the
- Z-shape closed by the final
- </span><span style="font-size: 10pt"><tt>bitblts.</tt></span><span style="font-size: 10pt">
- The final step is to merge horizontally adjacent
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- of plain text.
- The complete source to
- </span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">
- is less than 100 lines of C.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>frinsert</tt></span><span style="font-size: 10pt">
- is more complicated because it must do four passes:
- one to construct the
- </span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
- list for the inserted string,
- one to reconnoitre,
- one to copy (in opposite order to
- </span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">)
- the
- </span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
- to make the hole for the new text,
- and finally one to copy the new text into place.
- Overall, though,
- </span><span style="font-size: 10pt"><tt>frinsert</tt></span><span style="font-size: 10pt">
- has a similar flavor to
- </span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">,
- and needn’t be described further.
- </span><span style="font-size: 10pt"><tt>Frinsert</tt></span><span style="font-size: 10pt">
- and its subsidiary routines comprise 211 lines of C.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The terminal source code is 3024 lines of C,
- and the host source is 5797 lines.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Discussion
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>History
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">The immediate ancestor of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- was the original text editor for the Blit, called
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- inherited
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">’s
- two-process structure and mouse language almost unchanged, but
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- suffered from several drawbacks that were addressed in the design of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
- The most important of these was the lack of a command language.
- Although
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- was easy to use for simple editing, it provided no direct help with
- large or repetitive editing tasks. Instead, it provided a command to pass
- selected text through a shell pipeline,
- but this was no more satisfactory than could be expected of a stopgap measure.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Jim</tt></span><span style="font-size: 10pt">
- was written primarily as a vehicle for experimenting with a mouse-based
- interface to text, and the experiment was successful.
- </span><span style="font-size: 10pt"><tt>Jim</tt></span><span style="font-size: 10pt">
- had some spin-offs:
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
- the second window system for the Blit, is essentially a multiplexed
- version of the terminal part of
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">;
- and the debugger
- </span><span style="font-size: 10pt"><tt>pi</tt></span><span style="font-size: 10pt">’s
- user interface<sup></sup></span><sup><span style="font-size: 6pt">20</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> was closely modeled on
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">’s.
- But after a couple of years,
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- had become difficult to maintain and limiting to use,
- and its replacement was overdue.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">I began the design of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- by asking
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- customers what they wanted.
- This was probably a mistake; the answers were essentially a list of features
- to be found in other editors, which did not provide any of the
- guiding principles I was seeking.
- For instance, one common request was for a ‘‘global substitute,’’
- but no one suggested how to provide it within a cut-and-paste editor.
- I was looking for a scheme that would
- support such specialized features comfortably in the context of some
- general command language.
- Ideas were not forthcoming, though, particularly given my insistence
- on removing all limits on file sizes, line lengths and so on.
- Even worse, I recognized that, since the mouse could easily
- indicate a region of the screen that was not an integral number of lines,
- the command language would best forget about newlines altogether,
- and that meant the command language had to treat the file as a single
- string, not an array of lines.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Eventually, I decided that thinking was not getting me very far and it was
- time to try building.
- I knew that the terminal part could be built easily —
- that part of
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- behaved acceptably well — and that most of the hard work was going
- to be in the host part: the file interface, command interpreter and so on.
- Moreover, I had some ideas about how the architecture of
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- could be improved without destroying its basic structure, which I liked
- in principle but which hadn’t worked out as well as I had hoped.
- So I began by designing the file data structure,
- starting with the way
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- worked — comparable to a single structure merging
- </span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
- which I split to make the cache more general
- — and thinking about how global substitute could be implemented.
- The answer was clearly that it had to be done in two passes,
- and the transcript-oriented implementation fell out naturally.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- was written bottom-up,
- starting from the data structures and algorithms for manipulating text,
- through the command language and up to the code for maintaining
- the display.
- In retrospect, it turned out well, but this implementation method is
- not recommended in general.
- There were several times when I had a large body of interesting code
- assembled and no clue how to proceed with it.
- The command language, in particular, took almost a year to figure out,
- but can be implemented (given what was there at the beginning of that year)
- in a day or two. Similarly, inventing the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- data structure delayed the
- connection of the host and terminal pieces by another few months.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- took about two years to write, although only about four months were
- spent actually working on it.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Part of the design process was unusual:
- the subset of the protocol that maintains the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- was simulated, debugged
- and verified by an automatic protocol analyzer,<sup></sup></span><sup><span style="font-size: 6pt">21</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> and was bug-free
- from the start.
- The rest of the protocol, concerned mostly
- with keeping menus up to date,
- was unfortunately too unwieldy for such analysis,
- and was debugged by more traditional methods, primarily
- by logging in a file all messages in and out of the host.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Reflections
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is essentially the only interactive editor used by the sixty or so members of
- the computing science research center in which I work.
- The same could not be said of
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">;
- the lack of a command language kept some people from adopting it.
- The union of a user interface as comfortable as
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">’s
- with a command language as powerful as
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s†
- </span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">is essential to
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- success.
- When
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- was first made available to the
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- community,
- almost everyone switched to it within two or three days.
- In the months that followed, even people who had never adopted
- </span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
- started using
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- exclusively.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">To be honest,
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- still gets occasional use, but usually when
- something quick needs to be done and the overhead of
- downloading the terminal part of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- isn’t worth the trouble.
- Also, as a ‘line’ editor,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- </span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
- is a bit odd;
- when using a good old ASCII terminal, it’s comforting to have
- a true line editor.
- But it is fair to say that
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- command language has displaced
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s
- for most of the complicated editing that has kept line editors
- (that is, command-driven editors) with us.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">’s
- command language is even fancier than
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s,
- and most
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- customers don’t come near to using all its capabilities.
- Does it need to be so sophisticated?
- I think the answer is yes, for two reasons.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">First, the
- </span><span style="font-size: 10pt"><i>model</i></span><span style="font-size: 10pt">
- for
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- command language is really relatively simple, and certainly simpler than that of
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">.
- For instance, there is only one kind of textual loop in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- — the
- </span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
- command —
- while
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- has three (the
- </span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
- command, the global flag on substitutions, and the implicit loop over
- lines in multi-line substitutions).
- Also,
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s
- substitute command is necessary to make changes within lines, but in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- the
- </span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">
- command is more of a familiar convenience than a necessity;
- </span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">
- and
- </span><span style="font-size: 10pt"><tt>t</tt></span><span style="font-size: 10pt">
- can do all the work.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Second,
- given a community that expects an editor to be about as powerful as
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">,
- it’s hard to see how
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- could really be much simpler and still satisfy that expectation.
- People want to do ‘‘global substitutes,’’ and most are content
- to have the recipe for that and a few other fancy changes.
- The sophistication of the command language is really just a veneer
- over a design that makes it possible to do global substitutes
- in a screen editor.
- Some people will always want something more, however, and it’s gratifying to
- be able to provide it.
- The real power of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- command language comes from composability of the operators, which is by
- nature orthogonal to the underlying model.
- In other words,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is not itself complex, but it makes complex things possible.
- If you don’t want to do anything complex, you can ignore the
- complexity altogether, and many people do so.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Sometimes I am asked the opposite question: why didn’t I just make
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- a real programmable editor, with macros and variables and so on?
- The main reason is a matter of taste: I like the editor
- to be the same every time I use it.
- There is one technical reason, though:
- programmability in editors is largely a workaround for insufficient
- interactivity.
- Programmable editors are used to make particular, usually short-term,
- things easy to do, such as by providing shorthands for common actions.
- If things are generally easy to do in the first place,
- shorthands are not as helpful.
- </span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- makes common editing operations very easy, and the solutions to
- complex editing problems seem commensurate with the problems themselves.
- Also, the ability to edit the
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- window makes it easy to repeat commands — it only takes a mouse button click
- to execute a command again.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Pros and cons
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- has several other good points,
- and its share of problems.
- Among the good things is the idea of
- structural regular expressions,
- whose usefulness has only begun to be explored.
- They were arrived at serendipitously when I attempted to distill the essence of
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s
- way of doing global substitution and recognized that the looping command in
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- was implicitly imposing a structure (an array of lines) on the file.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Another of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- good things is its undo capability.
- I had never before used an editor with a true undo,
- but I would never go back now.
- Undo
- </span><span style="font-size: 10pt"><i>must</i></span><span style="font-size: 10pt">
- be done well, but if it is, it can be relied on.
- For example,
- it’s safe to experiment if you’re not sure how to write some intricate command,
- because if you make a mistake, it can be fixed simply and reliably.
- I learned two things about undo from writing
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">:
- first, it’s easy to provide if you design it in from the beginning, and
- second, it’s necessary, particularly if the system has some subtle
- properties that may be unfamiliar or error-prone for users.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">’s
- lack of internal limits and sizes is a virtue.
- Because it avoids all fixed-size tables and data structures,
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is able to make global changes to files that some of our other
- tools cannot even read.
- Moreover, the design keeps the performance linear when doing such
- operations, although I must admit
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- does get slow when editing a huge file.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Now, the problems.
- Externally, the most obvious is that it is poorly integrated into the
- surrounding window system.
- By design, the user interface in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- feels almost identical to that of
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
- but a thick wall separates text in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- from the programs running in
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">.
- For instance, the ‘snarf buffer’ in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- must be maintained separately from that in
- </span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">.
- This is regrettable, but probably necessary given the unusual configuration
- of the system, with a programmable terminal on the far end of an RS-232 link.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
- is reliable; otherwise, people wouldn’t use it.
- But it was written over such a long time, and has so many new (to me)
- ideas in it, that I would like to see it done over again to clean
- up the code and remove many of the lingering problems in the implementation.
- The worst part is in the interconnection of the host and terminal parts,
- which might even be able to go away in a redesign for a more
- conventional window system.
- The program must be split in two to use the terminal effectively,
- but the low bandwidth of the connection forces the separation to
- occur in an inconvenient part of the design if performance is to be acceptable.
- A simple remote procedure call
- protocol driven by the host, emitting only graphics
- commands, would be easy to write but wouldn’t have nearly the
- necessary responsiveness. On the other hand, if the terminal were in control
- and requested much simpler file services from the host, regular expression
- searches would require that the terminal read the entire file over its RS-232
- link, which would be unreasonably slow.
- A compromise in which either end can take control is necessary.
- In retrospect, the communications protocol should have been
- designed and verified formally, although I do not know of any tool
- that can adequately relate the protocol to
- its implementation.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Not all of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- users are comfortable with its command language, and few are adept.
- Some (venerable) people use a sort of
- ‘‘</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- subset’’ of
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- command language,
- and even ask why
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- command language is not exactly
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s.
- (The reason, of course, is that
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- model for text does not include newlines, which are central to
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">.
- Making the text an array of newlines to the command language would
- be too much of a break from the seamless model provided by the mouse.
- Some editors, such as
- </span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">,
- are willing to make this break, though.)
- The difficulty is that
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’s
- syntax is so close to
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">’s
- that people believe it
- </span><span style="font-size: 10pt"><i>should</i></span><span style="font-size: 10pt">
- be the same.
- I thought, with some justification in hindsight,
- that making
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- similar to
- </span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
- would make it easier to learn and to accept.
- But I may have overstepped and raised the users’
- expectations too much.
- It’s hard to decide which way to resolve this problem.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Finally, there is a tradeoff in
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- that was decided by the environment in which it runs:
- </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
- is a multi-file editor, although in a different system there might instead be
- multiple single-file editors.
- The decision was made primarily because starting a new program in a Blit is
- time-consuming.
- If the choice could be made freely, however, I would
- still choose the multi-file architecture, because it allows
- groups of files to be handled as a unit;
- the usefulness of the multi-file commands is incontrovertible.
- It is delightful to have the source to an entire program
- available at your fingertips.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>Acknowledgements
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">Tom Cargill suggested the idea behind the
- </span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
- data structure.
- Norman Wilson and Ken Thompson influenced the command language.
- This paper was improved by comments from
- Al Aho,
- Jon Bentley,
- Chris Fraser,
- Gerard Holzmann,
- Brian Kernighan,
- Ted Kowalski,
- Doug McIlroy
- and
- Dennis Ritchie.
- </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"><b>REFERENCES
- </b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 1. R. Pike,
- ‘The Blit: a multiplexed graphics terminal,’
- </span><span style="font-size: 10pt"><i>AT&T Bell Labs. Tech. J.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>63</b></span><span style="font-size: 10pt">,
- (8),
- 1607-1631 (1984).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 2. L. Johnson,
- </span><span style="font-size: 10pt"><i>MacWrite,</i></span><span style="font-size: 10pt">
- Apple Computer Inc., Cupertino, Calif. 1983.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 3. B. Lampson,
- ‘Bravo Manual,’
- in
- </span><span style="font-size: 10pt"><i>Alto User’s Handbook,
- </i></span><span style="font-size: 10pt">pp. 31-62,
- Xerox Palo Alto Research Center,
- Palo Alto, Calif.
- 1979.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 4. W. Teitelman,
- ‘A tour through Cedar,’
- </span><span style="font-size: 10pt"><i>IEEE Software,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>1</b></span><span style="font-size: 10pt">
- (2), 44-73 (1984).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 5. J. Gutknecht,
- ‘Concepts of the text editor Lara,’
- </span><span style="font-size: 10pt"><i>Comm. ACM,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>28</b></span><span style="font-size: 10pt">,
- (9),
- 942-960 (1985).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 6. Bell Telephone Laboratories,
- </span><span style="font-size: 10pt"><i>UNIX Programmer’s Manual,
- </i></span><span style="font-size: 10pt">Holt, Rinehart and Winston, New York 1983.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 7. B. W. Kernighan and R. Pike,
- </span><span style="font-size: 10pt"><i>The Unix Programming Environment,
- </i></span><span style="font-size: 10pt">Prentice-Hall, Englewood Cliffs, New Jersey 1984.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 8. </span><span style="font-size: 10pt"><i>Unix Time-Sharing System Programmer’s Manual, Research Version, Ninth Edition,
- Volume 1,
- </i></span><span style="font-size: 10pt">AT&T Bell Laboratories, Murray Hill, New Jersey 1986.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt"> 9. </span><span style="font-size: 10pt"><i>Unix Time-Sharing System Programmer’s Manual, 4.1 Berkeley Software Distribution,
- Volumes 1 and 2C,
- </i></span><span style="font-size: 10pt">University of California, Berkeley, Calif. 1981.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">10. R. Pike,
- ‘Structural Regular Expressions,’
- </span><span style="font-size: 10pt"><i>Proc. EUUG Spring Conf., Helsinki 1987,
- </i></span><span style="font-size: 10pt">Eur. Unix User’s Group, Buntingford, Herts, UK 1987.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">11. A. Goldberg,
- </span><span style="font-size: 10pt"><i>Smalltalk-80 – The Interactive Programming Environment,
- </i></span><span style="font-size: 10pt">Addison-Wesley, Reading, Mass. 1984.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">12. K. Thompson,
- ‘Regular expression search algorithm,’
- </span><span style="font-size: 10pt"><i>Comm. ACM,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>11</b></span><span style="font-size: 10pt">,
- (6),
- 419-422 (1968).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">13. A. V. Aho, J. E. Hopcroft and J. D. Ullman,
- </span><span style="font-size: 10pt"><i>The Design and Analysis of Computer Algorithms,
- </i></span><span style="font-size: 10pt">Addison-Wesley, Reading, Mass. 1974.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">14. B. W. Kernighan and D. M. Ritchie,
- </span><span style="font-size: 10pt"><i>The C Programming Language,
- </i></span><span style="font-size: 10pt">Prentice-Hall, Englewood Cliffs, New Jersey 1978.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">15. W. M. Waite,
- ‘The cost of lexical analysis,’
- </span><span style="font-size: 10pt"><i>Softw. Pract. Exp.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>16</b></span><span style="font-size: 10pt">,
- (5),
- 473-488 (1986).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">16. C. W. Fraser,
- ‘A generalized text editor,’
- </span><span style="font-size: 10pt"><i>Comm. ACM,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>23</b></span><span style="font-size: 10pt">,
- (3),
- 154-158 (1980).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">17. R. Pike,
- ‘Graphics in overlapping bitmap layers,’
- </span><span style="font-size: 10pt"><i>ACM Trans. on Graph.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>2</b></span><span style="font-size: 10pt">,
- (2)
- 135-160 (1983).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">18. L. J. Guibas and J. Stolfi,
- ‘A language for bitmap manipulation,’
- </span><span style="font-size: 10pt"><i>ACM Trans. on Graph.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>1</b></span><span style="font-size: 10pt">,
- (3),
- 191-214 (1982).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">19. R. Pike, B. Locanthi and J. Reiser,
- ‘Hardware/software trade-offs for bitmap graphics on the Blit,’
- </span><span style="font-size: 10pt"><i>Softw. Pract. Exp.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>15</b></span><span style="font-size: 10pt">,
- (2),
- 131-151 (1985).
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">20. T. A. Cargill,
- ‘The feel of Pi,’
- </span><span style="font-size: 10pt"><i>Winter USENIX Conference Proceedings,
- Denver 1986,
- </i></span><span style="font-size: 10pt">62-71,
- USENIX Assoc., El Cerrito, CA.
- </span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
- <p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
- <span style="font-size: 10pt">21. G. J. Holzmann,
- ‘Tracing protocols,’
- </span><span style="font-size: 10pt"><i>AT&T Tech. J.,
- </i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>64</b></span><span style="font-size: 10pt">,
- (10),
- 2413-2434 (1985).
- </span></p><p style="margin-top: 0; margin-bottom: 0.50in"></p>
- </body>
- </html>
|