You are on page 1of 166

StartingFORTH AbouttheAuthor

LeoBrodie'sinabilitytoexpresseventhemostcomplextechnical conceptswithoutaddingatwistofhumorcomesfromanearlylove ofcomedy.HespecializedinplaywritingatUCLAandhashad severalcomediesproducedthereandinlocaltheater.Hehasalso writtenfreelancemagazinearticlesandhasworkedasacopywriter foranaddagency.Whenacompanyhewasworkingforinstalleda computer,hebecameinspiredtotrydesigningamicroprocessor basedtoy.Althoughhenevergotthetoyrunning,helearnedalot aboutcomputersandprogramming.HenowworksatForth,Inc.asatechnicalandmarketingwriter, wherehecanplayonthecomputersasthemusedetermineswithouthavingtobeafanaticalcomputer jockey,andisallowedtowritebookssuchasthis. Leo'sotherinterestsincludesinging,drivingclassicVolvos,anddancingto50'smusic.

Foreword
TheForthcommunitycancelebrateasignificanteventwith thepublicationofStartingForth.Agreatereffort,talent, andcommitmenthavegoneintothisbookthanintoany previousintroductorymanual.I,particularly,ampleasedat thisevidenceofthegrowingpopularityofForth,the language. IdevelopedForthovertheperiodofsomeyearsasan interfacebetweenmeandthecomputersIprogrammed.The traditionallanguageswerenotprovidingthepower,ease,or flexibilitythatIwanted.Idisregardedmuchconventional wisdominordertoincludeexactlythecapabilitiesneeded byaproductiveprogrammer.Themostimportantoftheseis theabilitytoaddwhatevercapabilitieslaterbecome necessary. ThefirsttimeIcombinedtheideasIhadbeendeveloping intoasingleentity,IwasworkingonanIBM1130,a"third generation"computer.TheresultseemedsopowerfulthatI consideredita"fourthgenerationcomputerlanguage."IwouldhavecalleditFOURTH,exceptthatthe 1130permittedonlyfivecharacteridentifiers.SoFOURTHbecameFORTH,anicerplayonwords

anyway. OneprinciplethatguidedtheevolutionofForth,andcontinuestoguideitsapplication,isbluntly:KeepIt Simple.Asimplesolutionhaselegance.Itistheresultofexactingefforttounderstandtherealproblem andisrecognizedbyitscompellingsenseofrightness.Istressthispointbecauseitcontradictsthe conventionalviewthatpowerincreaseswithcomplexity.Simplicityprovidesconfidence,reliability, compactness,andspeed. StartingForthwaswrittenandillustratedbyLeoBrodie,aremarkablycapablepersonwhoseinsightand imaginationwillbecomeapparent.Thisbookisanoriginalanddetailedprescriptionforlearning.It deftlyguidesthenoviceoverthethresholdsofunderstandingthatallForthprogrammersmustcross. AlthoughIamtheonlypersonwhohasneverhadtolearnForth,Idoknowthatitsstudyisaformidable one.Aswithahumanlanguage,theusageofmanywordsmustbememorized.Forbeginners,Leo'sdroll commentsandsuperblycastcharactersappeartomakethisstudyeasyandenjoyable.Forthoselike myselfwhoalreadyknowForth,aquickreadingprovidesadelightfultripandfreshviewsoffamiliar terrain.ButIhopethisbookisnotsoeasyandenjoyablethatitseemstrivial.Bewarnedthatthereis heavycontenthereandthatyoucanlearnmuchaboutcomputersandcompilersaswellasabout programming. Forthprovidesanaturalmeansofcommunicationbetweenmanandthesmartmachinesheissurrounding himselfwith.Thisrequiresthatitsharecharacteristicsofhumanlanguages,includingcompactness, versatility,andextensibility.Icannotimagineabetterlanguageforwritingprograms,expressing algorithms,orunderstandingcomputers.Asyoureadthisbook,Ihopethatyoumaycometoagree. CharlesH.Moore InventorofForth

AboutThisBook
WelcometoStartingForth,yourintroductiontoanexcitingandpowerfulcomputerlanguagecalled Forth. Ifyou'reabeginnerwhowantstolearnmoreaboutcomputers,Forthisagreatwaytolearn.Forthismore funtowriteprogramswiththananylanguagethatIknowof.(Seethe"IntroductionforBeginners",and checkWikipedia) IfyouareaseasonedprofessionalwhowantstolearnForth,thisbookisjustwhatyouneed.Forthisa verydifferentapproachtocomputers,sodifferentthateveryone,fromnewcomerstooldhands,learns Forthbestfromthegroundup.Ifyou'readeptatothercomputerlanguages,putthemoutofyourmindfor now,andrememberonlywhatyouknowaboutcomputers.(Seethe"IntroductionforProfessionals.") SincemanypeoplewithdifferentbackgroundsareinterestedinForth,I'vearrangedthisbooksothat you'llonlyhavetoreadwhatyouneedtoknow,withfootnotesaddressedtodifferentkindsofreaders. ThefirsthalfofChap.7providesabackgroundtocomputerarithmeticforbeginnersonly. ThisbookexplainshowtowritesimpleapplicationsinForth.ItincludesallstandardForthwordsthat youneedtowriteahighlevelsingletaskapplication.Thiswordsetisanextremelypowerfulone, includingeverythingfromsimplemathoperatorstocompilercontrollingwords.(ANSForthstandard online)

Excludedfromthisbookareallcommandsthatarerelatedtotheassembler,targetcompilerandother specializedutilities.ThesecommandsareavailableonsomeversionsofForthsuchaseForthandmost commercialimplementations.(Forthvendors) I'vechosenexamplesthatwillactuallyworkonaForthsystemwithaterminalandadisk.Don'tinfer fromthisthatForthislimitedtobatchorstringhandlingtasks,sincethereisreallynolimittoForth's usefulness. Herearesomefeaturesofthisbookthatwillmakeiteasytouse: Allcommandsarelistedtwice:first,inthesectioninwhichthewordisintroduced,andsecond,inthe summaryattheendofthatchapter. Eachchapteralsohasareviewoftermsandasetofexerciseproblems,withanswers. Several"HandyHints"havebeenincludedtorevealproceduraltipsoroptionalroutinesthatareusefulfor learnersbutthatdon'tmeritanexplanationastohoworwhytheywork. Apersonalnote:Forthisaveryunusuallanguage.Itviolatesmanycardinalrulesofprogramming.My firstreactiontoForthwasextremelysceptical,butasItriedtodevelopcomplicatedapplicationsIbegan toseeitsbeautyandpower.Youoweittoyourselftokeepanopenmindwhilereadingaboutsomeofits peculiarities.I'llwarnyounow:fewprogrammerswholearnForthevergobacktootherlanguages. Goodluck,andenjoylearning! LeoBrodie FORTH,Inc. Copyrightnotice

Acknowledgements

TheoriginalprinteditionofStarting FORTHiscopyrightedbyFORTH, Inc.andallrightsarereserved. PermissionhasbeengrantedtoMarcel ForconsultationonForthtechniqueandstyle:Dean Hendrixtomakethisonlineversion Sanderson,MichaelLaManna,JamesDewey, oftheworkavailableandtomake EdwardK.Conklin,andElizabethD.Rather,allof certainmodificationstotheoriginal FORTHInc.;forprovidinginsightsintotheartof printedwork.Furtherreproduction teachingForthandforwritingseveralofthe Copyright (exceptfortheprintingofsinglecopies problemsinthisbook:KimHarrisoftheForth forpersonaluse),modification, InterestGroup;forproofreading,editorial distribution,postingonotherweb suggestions,andenormousamountsofwork sites,orunauthorizeduseofeitherthe formattingthepages:CarolynA.Rosenberg;for printedoronlineversionofStarting helpwithtypingandothernecessities:SueLinstrot, FORTHbyanypartyotherthan CarolynLubisich,KevinWeaver,KrisCramer,and MarcelHendrixisexpresslyforbidden StephanieBrownBrodie;forhelpwiththegraphics: withoutpriorwrittenpermissionfrom: WinnieShows,NatashaElbert,BarbaraRoberts,and FORTH,Inc. JohnDotsonofSunrisePrintery(RedondoBeach, 5155W.RosecransBlvd.#1018 CA);fortechnicalassistance:BillPattersonand Hawthorne,CA90250 GaryFriendlander;forconstructivecriticism,much More patienceandlove:StephanieBrownBrodie;andfor information USA +1(310)9789454[fax] +1(310)4913356[phone] I'dliketothankthefollowingpeoplewhohelpedto makethisbookpossible:

inventingForth:CharlesH.Moore.

StartingForth,FirstEditionisfrom1981.Thesewebpagesweredesignedin2003,whenitbecame apparentthatSFwouldneverbereissuedbythecopyrightholder.Asmallsupplyofabout500books wasallthatwasleft. Whenyoucangetholdoftheoriginal,doso. InthistranscriptForthcodehasbeenANSified.Thesamplesshouldrunon,atleast,iForthand SwiftForth.Wherenecessary,statementsthatwerevalidin1981havebeenexchangedwithstatements moreappropriatefor2003(whenthistributewaswritten). StartingForthisfullofverydifficulttoreproducegraphics.Theseenormouslyenhancethetext's mnemonicvalue,andareinvaluableforafirsttimeForthuser.Ihavethereforeadded"substitute"graphic elements,roughlyatthesamespotwheretheyareintheoriginal.Theoriginalgraphicsare,ofcourse, muchbetter. InthistranscriptIhaveassumeda32bit,byteaddressingForth,with8bitcharacters.Theaddress returnedbyWORDisassumedtobeHERE.ThisallowsthecommontrickofALLOTinglengthofstr CHARSafterusingWORDinordertocompilestringstrtomemory.Multitaskingissuesareignored (e.g.no>TYPE,justTYPE).Divisionissymmetric,notfloored,andtwo'scomplementisassumed throughout.MostForthsshouldnothaveproblemswillthis.Chapter7exploitsextendedusesofnumber conversion.SomeForthsarebrokeninthisrespect,butiForthandSwiftForthdosupporttheseneat features.

Introductions
IntroductionforBeginners:WhatisaComputerLanguage?
Atfirstwhenbeginnersheartheterm"computerlanguage,"theywonder,"Whatkindof languagecouldacomputerpossiblyspeak?Itmustbeawfullyhardforpeopletounderstand. Itprobablylookslike:
976#!@NX714&+

ifitlookslikeanythingatall." Actuallyacomputerlanguageshouldnotbedifficulttounderstand.Itspurposeissimplytoserveasa convenientcompromiseforcommunicationbetweenapersonandacomputer. Considerthemarionette.Youcanmakeamarionette"walk"simplybyworkingthewoodencontrol, withouteventouchingthestrings.Youcouldsaythatrockingthecontrolmeans"walking"inthe languageofthemarionette.Thepuppeteerguidesthemarionetteinawaythatthemarionettecan understandandthatthepuppeteercaneasilymaster. Computersaremachinesjustlikethemarionette.Theymustbetoldexactlywhattodo,inspecific language.Andsoweneedalanguagewhichpossessestwoseeminglyoppositetraits:

Ontheonehand,itmustbepreciseinitsmeaningtothecomputer,conveyingalltheinformationthatthe computerneedstoknowtoperformtheoperation.Ontheotherhand,itmustbesimpleandeasytouse bytheprogrammer. Manylanguageshavebeendevelopedsincethebirthofcomputers:Fortranistheelderstatesmanofthe field;COBOLisstillthestandardlanguagefordataprocessing;BASICwasdesignedasabeginner's languagealongtheroadtowardlanguageslikeFortranandCOBOL;CandJavaarethegeneralpurpose applicationlanguagesofthe90's.Thisbookisaboutaverydifferentkindoflanguage:Forth.Forth's popularityhaskeptconstantoverthepastseveralyears,anditspopularityissharedamongprogrammers inallfields. Allthelanguagesmentionedabove,includingForth,arecalled"highlevel"languages.It'simportantfor beginnerstorecognizethedifferencebetweenahighlevellanguageandthecomputeritrunson.Ahigh levellanguagelooksthesametoaprogrammerregardlessofwhichmakeormodelofcomputerit's runningon.Buteachmakeormodelhasitsowninternallanguage,or"machinelanguage."Toexplain whatamachinelanguageis,let'sreturntothemarionette. Imaginethatthereisnowoodencontrolandthatthepuppeteerhastodealdirectlywiththestrings.Each stringcorrespondstoexactlyonepartofthemarionette'sbody.Theharmoniouscombinationsof movementsoftheindividualstringscouldbecalledthemarionette's"machinelanguage." Nowtiethestringstoacontrol.Thecontrolislikeahighlevellanguage.Withasimpleturnofthewrist, thepuppeteercanmovemanystringssimultaneously. Soitiswithahighlevelcomputerlanguage,where thesimpleandfamiliarsymbol"+"causesmany internalfunctionstobeperformedintheprocessof addition. Here'sacleverthingaboutacomputer:itcanbe programmedtotranslatehighlevelsymbols(suchas "+")intothecomputer'sownmachinelanguage.Then itcanproceedtocarryoutthemachineinstructions. Ahighlevellanguageisacomputerprogramthat translateshumanlyunderstandablewordsand symbolsintothemachinelanguageoftheparticularmakeandmodelofcomputer. What'sthedifferencebetweenForthandotherhighlevellanguages?Toputitverybriefly:ithastodo withthecompromisebetweenmanandcomputer.Alanguageshouldbedesignedfortheconvenienceof itshumanusers,butatthesametimeforcompatibilitywiththeoperationofthecomputer. Forthisuniqueamonglanguagesbecauseitssolutiontothisproblemisunique.Thisbookwillexplain how.

IntroductionforProfessionals:ForthintheRealWorld
Forthenjoyedarisingtideofpopularityuptoaround1994,(ANSandISOForthstandards),perhaps mostvisiblyamongenthusiastsandhobbyists.After1996orsoForth'spopularityhasstayedrelatively constant.ButthisdevelopmentisonlyanewwrinkleinthehistoryofForth.Forthhasbeeninusefrom 1972on,incriticalscientificandindustrialapplications.Infact,ifyouuseaminiormicrocomputer professionally,chancesarethatForthcanrunyourapplicationmoreefficientlythanthelanguageyou're

presentlyusing. Nowyou'llprobablyaskrhetorically,"IfForthissoefficient,howcomeI'mnotusingit?"Theansweris thatyou,likemostpeople,don'tknowwhatForthis. ToreallygetanunderstandingofForth,youshouldreadthisbookand,ifpossible,findaForthsystem andtryitforyourself.Forthoseofyouwhoarestillatthebookstorebrowsing,however,thissectionwill answertwoquestions:"WhatisForth?"and"Whatisitgoodfor?" Forthismanythings:


ahighlevellanguage anassemblylanguage anoperatingsystem abootloaderanddevicedriverlayerforoperatingsystems achipdesignCADsystem asetofdevelopmenttools asoftwaredesignphilosophy

Asalanguage,Forthbeginswithapowerfulsetofstandardcommands,thenprovidesthemechanicsby whichyoucandefineyourowncommands.Thestructuralprocessofbuildingdefinitionsuponprevious definitionsisForth'sequivalentofhighlevelcoding.Alternatively,wordsmaybedefineddirectlyin assemblermnemonics,usingForth'sassembler.Allcommandsareinterpretedbythesameinterpreterand compiledbythesamecompiler,givingthelanguageextremeflexibility. ThehighestlevelofyourcodewillresembleanEnglishlanguagedescriptionofyourapplication.Forth hasbeencalleda"metaapplicationlanguage"alanguagethatyoucanusetocreateproblemoriented languages. Asanoperatingsystem,Forthdoeseverythingthattraditionaloperatingsystemsdo,including interpretation,compilation,assembling,virtualmemoryhandling,I/O,textediting,etc. ButbecausetheForthoperatingsystemismuchsimplerthanitstraditionalcounterpartsduetoForth's design,itrunsmuchmorequickly,muchmoreconveniently,andinmuchlessmemory. WhatisForthgoodfor?Forthoffersasimplemeanstomaximizeaprocessor'sefficiency.Forexample: Forthisfast.HighlevelForthexecutesasfastasotherhighlevellanguagesandbetween20to75% slowerthanequivalentassemblylanguageprograms,whiletimecriticalcodemaybewritteninassembler torunatfullprocessorspeed.Withoutatraditionaloperatingsystem,Fortheliminatesredundancyand needlessruntimeerrorchecking. Forthcompiledcodeiscompact.Forthapplicationsrequirelessmemorythantheirequivalentassembly languageprogramsandconsumelesspower(importantforhandheldsandportablegadgets!)Writtenin Forth,theentireoperatingsystemanditsstandardwordsetresideinlessthan8Kbytes.Supportfora targetapplicationmayrequirelessthan1Kbytes. Forthistransportable.Ithasbeenimplementedonjustabouteveryminiandmicrocomputerknownto theindustry.MostmicrocontrollersandDSPs,eventinyones,alsohaveaForthimplementation. Forthhasbeenknowntocutprogramdevelopmenttimebyafactoroftenforequivalentassembly languageprogrammingandbyafactoroftwoforequivalenthighlevelprogramminginCorJava. ProductivityincreasesbecauseForthepitomizes"structuredprogramming"andbecauseitisinteractive andmodular.

HereareafewsamplesofForthintherealworld(FORTH,Inc.,MPE):

AVCO/TextronSystems,buildingautomationandauxiliaryservicesforKingKhaledInternational Airport(SaudiArabia).SystemcontainsninePDP11/44s,3788086basedcomputers,and320 8085basedsecurityprocessors,collectivelymonitoringandcontrollingover36,000points. EastmanKodakCompany,qualitycontrolsystemmonitoringphotographicfilmdensity.Includes filmmotioncontrol,automaticrecognitionoffilm densitysteps,andcustomIEEE488businterface. FederalExpress,handheldSuperT racker,carriedby everyFedExdeliveryagent.Containsbarcodereader, keyboard,2x20linedisplay.Performsextensive packageentryandtrackingfunctions,includingcross indexfromairportcodetoall10,000USzipcodes. Includessmartpoweroffsequencingtoextendbattery life. NASAGoddardSpaceFlightCenter: 1. Controlof50footlong,sixjointarmforSpaceShuttlesimulator.Extensivemathroutines converttwothreeaxisjoystickcommandsintorequiredjointvelocitiesinsixdifferentco ordinatesystems. Multitaskingoperatingsystem,Forthlanguagecompiler, andlibrariesforUT69R000radiationhardened microprocessorusedinSpaceShuttleinstrumentation. DevelopmentoftheForthbasedSmallPayload AccomodationsInterfaceModule(SPAIM),which interfacestheShuttleSolarBackscatterUltraviolet (SSBUV)instrumenttotheSpaceShuttle'savionic systems.TheSSBUVinstrumentisusedtocalibrate ozonemeasuringinstrumentsaboardNOAAsatellites. OwensCorningFiberglas,OwensCorninghasused Forthformanyyearsasthebasicfirmwareinits distributedindustrialcontrollers.Thesecontrollers performawidevarietyoffunctions,managingwinders, weighingdevices,etc.,usedinthemanufactureof variousfiberglassproducts.PlantsinKoreaandMexico alsouseFORTH,Inc.'sEXPRESStoprovide supervisorycontrolandreportingfunctions. SaturnCorp,distributedHVACsystemforentireSaturnautomobileassemblyplant,controlling overtwohundred40hp.heatingcoolinghumidifyingunits(withZ80s)overatwotier networkusingPCsastextandgraphicalsystemmonitors.Outsideairsensorsprovideinputsfor intelligentsetpointcontrolandeconomicuseofgasheatingandchilledwatercoolingsystems. SacramentoMunicipalUtilitiesDistrict(California): photovoltaicarraysinthestatecapitolfeatureEXPRESSto provideuserconfigurablelivetrending,historicaltrending, alarm/exceptionreporting,ruletracking,I/Osystemexerciser, classbasedrealtimedatabase,graphicalprocessdisplays, simultaneousmultiplevendorI/Osystemscanning,I/Oand processsimulationfordevelopment,andmultipleremote

terminalaccesswithfullgraphics.CustomdriversfortheDigitronicsSixnet(TM)I/Osystemwere providedinoneweek;EXPRESSalreadysupportsModicon,AllenBradle y,OPTO22 OPTOMUXandPAMUX,plusothers. UniversityofMinnesota,PCbasedsystemfortelescopecontrolanddatataking(overIEEE488 bus),dataanalysisandgraphicsdisplay.Includesprovisionforremoteobserving,usingacustom protocoltomultiplexpacketsfromthreeindependentdatastreamsoverasingletelephoneline. VertexRSI(Div.ofTripointGlobal),softwareforcustomsatellitetrackingreceivers.Includes frequencysynthesizercontrol,remoteRS232commandport,vacuum fluorescentgraphicsdisplay. Amobilephonemanufacturerisintroducinganewgamesenginederived fromtheSENDITproject.ThisusesaForthbasedvirtualmachineto reducethesizeofgamesinthephone,andtopermitmorefunctionalityto beprovidedinthephonewithoutincreasingmemorysize. ArecentconsultancyprojectbasedonMPE8051andARMhardware, willintroduceanewrangeofvendingmachinestothemarket. ConstructionComputerSoftware(CCS)inCapeTownproducethe MARSandCANDYapplicationswhichareastandardallovertheworld. TheCCSsoftwareisanexampleofalargescaleWindowsapplication writteninProForthforWindows,andtheVFXForthversionalready consistsofover850,000linesofcode.CCSsoftwarewasusedtoplanthe newChaiTakairportinHongKong.TheCCSwebsiteishere. BarefootAuditorisusedbyMicrosoftforcollectinginformationabout theirownPCs,andwaswrittenusingoneofMPE'sForthsystems. BarefootAuditorhasbeenavailableonseveralmagazinecoverdisks recently,andmoreinformationisavailablefromPathfinder.

MicrossElectronics,useMPE'sProForthforWindowsattheheartoftheircommerciallaundry controlsystems,andMPE'sForth6crosscompilersforthePLCsperformingrealtimecontrol. Thesesystemsareinstalledinmanycountries,andyoumayhavesleptinsheetswashedbythe MicrossTracknetcontrolsystems. Forthvirtualmachinerunspaymentterminals:EuropayInternational'sOpenTerminal Architecture(OTA).OTAusesavirtualmachine(VM)architecturetodeliverpaymentterminal applicationsdirectlytopaymentterminalsregardlessoftheirhardwareorCPU.TheOTAVMhas beeninstalledonarangeofCPUsandisnowbeingdeployed.TheOTAprojectinvolvedupto30 programmersworkinginseverallocationsontwocontinents.OTAisdescribedhere.

There'sacatchwemustadmit.ItisthatForthmakesyouresponsibleforyourcomputer'sefficiency.To drawananalogy:amanualtransmissionistoughertomasterthananautomatic,yetformanydriversit offersimprovedcontroloverthevehicle. Similarly,Forthistoughertomasterthantraditionalhighlevellanguages,whichessentiallyresembleone another(i.e.,afterlearningone,itisnotdifficulttolearnanother).Oncemastered,however,Forthgives youthecapabilitytominimizeCPUtimeandmemoryspace,aswellasanorganizingphilosophyby whichyoucandramaticallyreduceprojectdevelopmenttime.

Andremember,allofForth'selementsenjoythesameprotocol,includingoperatingsystem(sometimes), compiler,interpreters,texteditor,virtualmemory,assembler,andmultiprogrammer.Thelearningcurve forForthismuchshorterthanthatforalltheseseparateelementsaddedtogether. Ifallofthissoundsexcitingtoyou,turnthepageandstartForth.

1FundamentalForth
Inthischapterwe'llacquaintyouwithsomeoftheuniquepropertiesoftheForthlanguage.Afterafew introductorypageswe'llhaveyousittingataForthterminal.

ALivingLanguage
Imaginethatyou'reanofficemanagerandyou'vejusthiredanew,eagerassistant.Onthefirstday,you teachtheassistanttheproperformatfortypingcorrespondence.(Theassistantalreadyknowshowto type.)Bytheendoftheday,allyouhavetodoissay"Pleasetypethis." Onthesecondday,youexplainthefilingsystem.Ittakesallmorningtoexplainwhereeverythinggoes, butbytheafternoonallyouhavetosayis"Pleasefilethis." Bytheendoftheweek,youcancommunicateinakindofshorthand,where"Pleasesendthisletter" means"Typeit,getmetosignit,photocopyit,filethecopy,andmailtheoriginal."Bothyouandyour assistantarefreetocarryoutyourbusinessmorepleasantlyandefficiently. Goodorganizationandeffectivecommunicationrequirethatyou 1. defineusefultasksandgiveeachtaskaname,then 2. grouprelatedtaskstogetherinlargertasksandgiveeachoftheseaname,andsoon. Forthletsyouorganizeyourownproceduresandcommunicatethemtoacomputerinjustthisway (exceptyoudon'thavetosay"please"). Asanexample,imagineamicroprocessorcontrolledwashingmachineprogrammedinForth.The ultimatecommandinyourexampleisnamedWASHER.HereisthedefinitionofWASHER,aswrittenin Forth:
:WASHERWASHSPINRINSESPIN;

InForth,thecolonindicatesthebeginningofanewdefinition.Thefirstwordafterthecolon,WASHER, isthenameofthenewprocedure.Theremainingwords,WASH,SPIN,RINSEandSPIN,comprisethe "definition"ofthenewprocedure.Finally,thesemicolonindicatestheendofthedefinition. EachofthewordscomprisingthedefinitionofWASHERhasalreadybeendefinedinourwashing machineapplication.Forexample,let'slookatourdefinitionofRINSE:


:RINSEFAUCETSOPENTILLFULLFAUCETSCLOSE;

Inthisdefinitionwearereferringtothings(faucets)aswellasactions(openandclose).Theword TILLFULLhasbeendefinedtocreatea"delayloop"whichdoesnothingbutmarktimeuntilthewater levelswitchhasbeenactivated,indicatingthatthetubisfull. Ifweweretotracethesedefinitionsback,wewouldeventuallyfindthattheyarealldefinedintermsofa groupofveryusefulcommandsthatformthebasisofallForthsystems.Forexample,acompleteANS Forthwithallextensionsincludes371suchcommands.Manyofthesecommandsarethemselves"colon definitions"justlikeourexamplewords;othersaredefineddirectlyinthemachinelanguageofthe particularcomputer.InForth,adefinedcommandiscalleda"word."

Theabilitytodefineawordintermsofotherwordsiscalled"extensibility."Extensibilityleadstoastyle ofprogrammingthatisextremelysimple,naturallywellorganized,andaspowerfulasyouwantittobe. Whetheryourapplicationrunsanassemblyline,acquiresdataforascientificenvironment,maintainsa businessapplication,orplaysagame,youcancreateyourown"livinglanguage"ofwordsthatrelateto yourparticularneed. Inthisbookwe'llcoverthemostusefulofthestandardForthcommands.

AllThisand...Interactive!
OneofForth'smanyuniquefeaturesisthatitletsyou"execute" awordbysimplynamingthe word.Ifyou'reworkingataterminalkeyboard,thiscanbeassimpleastypinginthewordandpressing theRETURNkey. Ofcourse,youcanalsousethesamewordinthedefinitionofanyotherword,simplybyputtingitsname inthedefinition. Forthiscalledan"interactive"languagebecauseitcarriesoutyourcommandstheinstantthatyouenter them. We'regoingtogiveanexamplethatyoucantryyourself,showingtheprocessofcombiningsimple commandsintomorepowerfulcommands.We'llusesomesimpleForthwordsthatcontrolyourterminal screen.Butfirst,let'sgetacquaintedwiththemechanicsof"talking"toForththroughyourterminal's keyboard. TakeaseatatyourrealorimaginaryForthterminal.We'll assumethatsomeonehasbeenkindenoughtoset everythingupforyou,orthatyouhavefollowedalltheinstructions givenforloadingForthonyourparticularcomputer. Nowpressthekeylabeled:
RETURN

Thecomputerwillrespondbysaying
ok

TheRETURNkeyisyourwayoftellingForthtoacknowledgeyourrequest.TheokisForth'swayof sayingthatit'sdoneeverythingyouaskedittodowithoutanyhangups.Inthiscase,youdidn'taskittodo anything,soForthobedientlydidnothingandsaidok. Nowenterthis:


15SPACES

Ifyoumakeatypingmistake,youcancorrectitbyhittingthe"backspace"key. Backupto themistake,enterthecorrectletter,andcontinue.Whenyouhavetypedthelinecorrectly,pressthe RETURNkey.(OnceyoupressRETURN,it'stoolatetocorrecttheline.) Inthisbook,weusethesymbol tomarkthepointwhereyoumustpresstheRETURNkey.

Wealsounderlinethecomputer'soutput(eventhoughthecomputerdoesnot)toindicatewhoistyping what. Here'swhathashappened:


15SPACES ok

Assoonasyoupressedthereturnkey,Forthprintedfifteenblankspacesandthen,havingprocessedyour request,respondedok(attheendofthefifteenthspace). Nowenterthis:


42EMIT *ok

Thephrase"42EMIT"tellsForthtoprintanasterisk(we'lldiscussthiscommandlateroninthebook.) HereForthprintedanasterisk,thenrespondedok. Wecanputmorethanonecommandonthesameline.Forexample:


15SPACES42EMIT42EMIT **ok

ThistimeForthprintedfifteenspacesandtwoasterisks.Anoteaboutenteringwordsand/ornumbers:we canseparatethemfromanotherbyasmanyspacesaswewantforclarity.Buttheymustbeseparatedby atleastonespaceforForthtobeabletorecognizethemaswordsand/ornumbers. Insteadofenteringthephrase


42EMIT

overandover,let'sdefineitasawordcalled"STAR." Enterthis:
:STAR42EMIT; ok

HereSTARisthename;"42EMIT"isthedefinition.Noticethatwesetoffthecolonandsemicolon

fromadjacentwordswithaspace.Also,tomakeForthdefinitionseasyforhumanbeingstoread,we conventionallyseparatethenameofthedefinitionfromitscontentswiththreespaces. AfteryouhaveenteredtheabovedefinitionsandpressedRETURN,Forthrespondsok,signifyingthatit hasrecognizedyourdefinitionandwillrememberit.Nowenter


STAR *ok

Voila!Forthexecutesyourdefinitionof"STAR"andprintsanasterisk. ThereisnodifferencebetweenawordsuchasSTARthatyoudefineyourselfandawordsuchasEMIT thatisalreadydefined.Inthisbook,however,wewillprintthosewordsthatarealreadydefinedinblue, sothatyoucanmoreeasilytellthedifference. AnothersystemdefinedwordisCR,whichperformsacarriagereturnandlinefeedatyourterminal. Forexample,enterthis:


CR ok

Asyoucansee,Forthexecutedacarriagereturn,thenprintedok(onthenextline). Nowtrythis:
CRSTARCRSTARCRSTAR * * *ok

Let'sputaCRinadefinition,likethis:
:MARGINCR30SPACES; ok

Nowwecanenter
MARGINSTARMARGINSTARMARGINSTAR

andgetthreestarslinedupvertically,thirtyspacesinfromtheleft. OurMARGINSTARcombinationwillbeusefulforwhatweintendtodo,solet'sdefine
:BLIPMARGINSTAR; ok

Wewillalsoneedtoprintaahorizontalrowofstars.Solet'senterthefollowingdefinition(we'llexplain howitworksinalaterchapter):
:STARS0DOSTARLOOP; ok

Nowwecansay
5STARS *****ok

or
35STARS ***********************************ok

oranynumberofstarsimaginable. WewillneedawordwhichperformsMARGIN,thenprintsfivestars.Let'sdefineitlikethis:
:BARMARGIN5STARS; ok

Nowwecanenter
BARBLIPBARBLIPBLIPCR

andgetaletter"F"(forForth)madeupofstars.Itshouldlooklikethis:
***** * ***** * *

Thefinalstepistomakethisnewprocedureaword.Let'scalltheword"F":
:FBARBLIPBARBLIPBLIPCR; ok

You'vejustseenanexampleofthewaysimpleForthcommandscanbecomeafoundationformore complexcommands.AForthapplication,whenlisted,consistsofaseriesofincreasinglypowerful definitionsratherthanasequenceofinstructionstobeexecutedinorder. TogiveyouasampleofwhataForthapplicationreallylookslike,here'salistingofourexperimental application:


(LargeletterF) :STAR42EMIT; :STARS0DOSTARLOOP; :MARGINCR30SPACES; :BLIPMARGINSTAR; :BARMARGIN5STARS; :FBARBLIPBARBLIPBLIPCR;

TheDictionary
EachwordanditsdefinitionareenteredintoForth's"dictionary."Thedictionaryalreadycontainedmany wordswhenyoustarted,butyourownwordsarenowinthedictionaryaswell. Whenyoudefineanewword,Forthtranslatesyourdefinitionintodictionaryformandwrites

theentryinthedictionary.Thisprocessiscalled"compiling." Forexample,whenyouentertheline
:STAR[CHAR]*EMIT; ok

thecompilercompilesthenewdefinition(itdoesthesameas"42EMIT"butdoesn'tusemagic numbers)intothedictionary.Thecompilerdoesnotprinttheasterisk. Onceawordisinthedictionary,howisitexecuted?Let'ssayyouenterthefollowinglinedirectlyatyour terminal(notinsideadefinition):


STAR30SPACES

ThiswillactivateawordcalledINTERPRET,alsoknownasthe"textinterpreter."Thetextinterpreter scanstheinputstream,lookingforstringsofcharactersseparatedbyspaces.Whenastringis found,itislookedupinthedictionary.Ifthewordisinthedictionary,itispointedouttoa wordcalledEXECUTE.EXECUTEexecutesthedefinition(inthiscaseanasteriskisprinted).Finally, theinterpretersayseverything's"ok." Iftheinterpretercannotfindthestringinthedictionary,hecallsthenumberrunner(called NUMBER).NUMBERknowsanumberwhenheseesone.IfNUMBERfindsanumber,he runsitofftoatemporarystoragelocationfornumbers. Whathappenswhenyoutrytoexecuteawordthatisnotinthedictionary?Enterthisandseewhat happens:
XLERB XLERB?

WhenthetextinterpretercannotfindXLERBinthedictionary,ittriestopassitoffon NUMBER.NUMBERshinesiton.Thentheinterpreterreturnsthestringtoyouwitha questionmark(SomeForthsprintvariouserrormessagesalongwiththis.) ANSForthallowsuptothirtyonecharactersofanametobestoredinthedictionary.Anameshould containonlygraphiccharacters. Tosummarize:whenyoutypeapredefinedwordattheterminal,itgetsinterpretedandthenexecuted. Nowrememberwesaidthat:isaword?Whenyoutypetheword:,asin


:STAR[CHAR]*EMIT;

thefollowingoccurs: Thetextinterpreterfindsthecolonintheinputstream,andpointsitouttoEXECUTE.Thecompiler translatesthedefinitionintodictionaryformandwritesitinthedictionary.Whenthecompilergetstothe semicolon,hestops,andexecutionreturnstothetextinterpreter,whogivesthemessageok.

SayWhat?
InForth,awordisacharacterorgroupofcharactersthathaveadefinition.Almostanycharactercanbe usedinnamingaword.Thereasonsthatsomeofthecontrolcharacterscannotbeusedare: becausethecomputerthinksyou'vefinishedentering. becausethecomputerthinksyouaretryingtocorrecta backspace typingerror. space becausethecomputerthinksit'stheendoftheword. HereisaForthwordwhosenameconsistsoftwopunctuationmarks.Thewordis."anditispronounced dotquote.Youcanuse."insideadefinitiontotypeastringoftextatyourterminal.Here'sanexample:
:GREET."Hello,IspeakForth"; ok

return

We'vejustdefinedawordcalledGREET.It'sdefinitionconsistsofjustoneForthword,.",followedby thetextthatwewanttyped.Thequotationmarkattheendofthetextwillnotbetyped;itmarkstheend ofthetext.It'scalleda"delimiter." WhenenteringthedefinitionofGREET,don'tforgettheclosing;toendthedefinition. Let'sexecuteGREET:


GREET Hello,IspeakForthok

TheStack:Forth'sWorksiteforArithmetic
Acomputerwouldnotbemuchgoodifitcouldn'tdoarithmetic.Ifyouneverstudiedcomputersbefore,it mayseemprettyamazingthatacomputer(orevenapocketcalculator)candoarithmeticatall.Wecan't citeallthemechanicsinthisbook,butbelieveus,it'snotamiracle. Ingeneral,computersperformtheiroperationsbybreakingeverythingtheydointoridiculouslytiny piecesofinformationandridiculouslyeasythingstodo.Toyouandme,"3+4"isjust"7,"withouteven thinking.Toacomputer,"3+4"isactuallyaverylonglistofthingstodoandremember. Withoutgettingtoospecific,let'ssayyouhaveapocketcalculatorwhichexpectsitsbuttonstobepushed inthisorder:

inordertoperformtheadditionanddisplaytheresult.Here'sageneralizedpictureofwhatmightoccur: Whenyoupress

thenumber3goesintooneplace(calledBoxA).

theintendedoperation(addition)isrememberedsomehow.

thenumber4isstoredintoasecondplace(calledBoxB).

thecalculatorperformstheoperationthatisstoredinthe"NextOperation"Boxonthecontentsofthe numberboxesandleavestheresultinBoxA. Manycalculatorsandcomputersapproacharithmeticproblemsinawaysimilartowhatwe'vejust described.Youmaynotbeawareofit,butthesemachinesareactuallystoringnumbersinvarious locationsandthenperformingoperationsonthem. InForth,thereisonecentrallocationwherenumbersaretemporarilystoredbeforebeingoperatedon. Thatlocationiscalledthe"stack."Numbersare"pushedontothestack,"andthenoperationsworkonthe numbersonthestack. Thebestwaytoexplainthestackistoillustrateit.Ifyouenterthefollowinglineatyourterminal:


34+. 7ok

hereiswhathappens,keybykey. Recallthatwhenyouenteranumberatyourterminal,the textinterpreterhandsitovertoNUMBER,whorunsitto somelocation.Thatlocation,itcannowbetold,isthestack. Inshort,whenyouenterthenumberthreefromtheterminal, youpushitontothestack.

Nowthefourgoesontothe"top"ofthestackandpushesthethreedownward. Thenextwordintheinputstreamcanbefoundinthedictionary.+hasbeenpreviouslydefinedto"take thetoptwonumbersoffthestack,addthem,andpushtheresultbackontothestack."

Thenextword,.,isalsofoundinthedictionary.Ithasbeenpreviouslydefinedtotakethenumberoffthe stackandprintitattheterminal.

PostfixPower
Nowwait,yousay.WhydoesForthwantyoutotype
34+

insteadof
3+4

whichismorefamiliartomostpeople? Forthuses"postfix"notation(socalledbecausetheoperatorisaffixedafterthenumbers)ratherthan "infix"notation(socalledbecausetheoperatorisaffixedinbetweenthenumbers)sothatallwords which"need"numberscangetthemfromthestack. Forexample:


theword+getstwonumbersfromthestackandaddsthem; theword.getsonenumberfromthestackandprintsit; thewordSPACESgetsonenumberfromthestackandprintsthatmanyspaces; thewordEMITgetsanumberthatrepresentsacharacterandprintsthatcharacter; eventhewordSTARS,whichwedefinedourselves,getsanumberfromthestackandprintsthat manystars.

Whenalloperatorsaredefinedtoworkonthevaluesthatarealreadyonthestack,interactionbetween manyoperationsremainssimpleevenwhentheprogramgetscomplex. EarlierwepointedoutthatForthletsyouexecuteawordineitheroftwoways:bysimplynamingit,orby puttingitinthedefinitionofanotherwordandnamingthatword.Postfixispartofwhatmakesthis possible. Justasanexample,let'ssupposewewantedawordthatwillalwaysaddthenumber4towhatevernumber isonthestack(fornootherpurposethantoillustrateourpoint).Let'scalltheword


FOURMORE

Wecoulddefineitthisway:

:FOURMORE4+;

andtestitthisway:
3FOURMORE. 7ok

andagain:
10FOURMORE. 6ok

The"4"insidethedefinitiongoesontothestack,justasitwouldifitwereoutsideadefinition.Thenthe +addsthetwonumbersonthestack.Since+alwaysworksonthestack,itdoesn'tcarethatthe"4"came frominsidethedefinitionandthethreefromoutside. Aswebegintogivesomemorecomplicatedexamples,thevalueofthestackandofpostfixarithmetic willbecomeincreasinglyapparenttoyou.Themoreoperatorsthatareinvolved,themoreimportantitis thattheyallbeableto"communicate"witheachother.

KeepTrackofYourStack
We'vejustbeguntodemonstratethephilosophybehindthestackandpostfixnotation.Beforewe continue,however,let'slookmorecloselyatthestackinactionandgetaccustomedtoitspeculiarities. Forth'sstackisdescribedasa"lastin,firstout"(LIFO).Youcanseefromtheearlierillustrationwhythis isso.Thethreewaspushedontothestackfirst,thenthefourpushedontopofit.Latertheadding machinetookthefourofffirstbecauseitwasontop.Hence"lastin,firstout." Ingeneral,theonlyaccessiblevalueatanygiventimeisthetopvalue.Let'suseanotheroperation,the.to furtherdemonstrate.Rememberthateach.removesonenumberfromthestackandprintsit.Fourdots, therefore,removefournumbersandprintthem.
2468.... 8642ok

Thesystemreadsinputfromlefttorightandexecuteseachwordinturn.

Forinput,therightmostvalueonthescreenwillenduponthetopofthestack. Foroutput,therightmostvalueonthescreencamefromthebottomofthestack.

Let'sseewhatkindoftroublewecangetourselvesinto.Type:
102030....

(that'sfourdots)thenRETURN.Whatyougetis:
102030.... 3020100Stackempty

Eachdotremovesonevalue.Thefourthdotfoundthattherewasnovalueleftonthestacktosendtothe terminal,andittoldyouso. Thiserroriscalled"stackunderflow."(Noticethatastackunderflowisnot"ok.") Theoppositecondition,whenthestackcompletelyfillsup,iscalled"stackoverflow."The stackissodeep,however,thatthisconditionshouldneveroccurexceptwhenyou'vedonesomething terriblywrong. It'simportanttokeeptrackofnewwords'"stackeffects";thatis,thesortofnumbersawordneedstohave onthestackbeforeyouexecuteit,andthesortofnumbersitwillleaveonthestackafterwards. Ifyoumaintainalistofyournewlycreatedwordswiththeirmeaningsasyougo,youoranyoneelsecan easilyunderstandtheword'soperations.InForth,suchalistiscalleda"glossary." Tocommunicatestackeffectsinavisualway,Forthprogrammersconventionallyuseaspecialstack notationintheirglossariesortablesofwords.We'reintroducingthestacknotationnowsothatyou'llhave itunderyourbeltwhenyoubeginthenextchapter. Hereisthebasicform:
(beforeafter)

Thedashseparatesthethingsthatshouldbeonthestack(beforeyouexecutetheword)fromthethings thatwillbeleftthereafterwards.Forexample,here'sthestacknotationfortheword.:
.(n)

(Theletter"n"standsfor"number.")Thisshowsthat.expectsonenumberonthestack(before)and leavesnonumberonthestack(after). Here'sthestacknotationfortheword+.


+(n1n2sum)

Whenthereismorethanonen,wenumberthemn1,n2,n3,etc.,consecutively.Thenumbers1and2do notrefertoapositiononthestack.Stackpositionisindicatedbytheorderinwhichtheitemsarewritten; therightmostitemoneithersideofthearrowisthetopmostitemonthestack.Forexample,inthestack notationof+,then2isontop: Sinceyouprobablyhavethehangofitbynow,we'llbeleavingoutthe symbolexceptwhen

wefeelit'sneededforclarity.Youcanusuallytellwheretopress"return"becausethecomputer's responseisalwaysunderlined. Here'salistoftheForthwordsyou'velearnedsofar,includingtheirstacknotations("n"standsfor number;"c"standsforcharacter): :xxxxyyy; () CR SPACES () (n) Createsanewdefinitionwiththenamexxx,consistingofwordor wordsyyy. Performsacarriagereturnandlinefeedatyourterminal. Printsthegivennumberofblankspacesatyourterminal.

Printsoneblankspaceatyourterminal. Transmitsacharactertotheoutputdevice. Printsthecharacterstringxxxatyourterminal.The"character ."xxx" () terminatesthestring. + (n1n2sum) Adds. . (n) Printsanumber,followedbyonespace. Inthenextchapterwe'lltalkaboutgettingthecomputertoperformsomefancierarithmetic. SPACE EMIT ReviewofTerms togenerateadictionaryentryincomputermemoryfromsourcetext(thewrittenoutform ofadefinition).Distinctfrom"execute." inForth,alistofwordsanddefinitionsincludingboth"system"definitions(predefined) Dictionary and"user"definitions(whichyouinvent).Adictionaryresidesincomputermemoryin compiledform. toperform.Specifically,toexecuteawordistoperformtheoperationsspecifiedinthe Execute compileddefinitionoftheword. acharacteristicofacomputerlanguagewhichallowsaprogrammertoaddnewfeatures Extensibility ormodifyexistingones. alistofwordsdefinedinForth,showingtheirstackeffectsandanexplanationofwhat Glossary theydo,whichservesasareferenceforprogrammers. Infixnotation themethodofwritingoperatorsbetweentheoperandstheyaffect,asin"2+5." thetexttobereadbythetextinterpreter.Thismaybetextthatyouhavejusttypedinat Inputstream yourterminal,oritmaybetextthatisstoredondisk. (whenreferringtoForth'stextinterpreter)toreadtheinputstream,thentofindeachword Interpret inthedictionaryor,failingthat,toconvertittoanumber. (lastin,firstout)thetypeofstackwhichForthuses.AcanoftennisballsisaLIFO LIFO structure;thelastballyoudropinistheoneyoumustremovefirst. Postfix themethodofwritingoperatorsaftertheoperandstheyaffect,asin"25+"for"2+5." notation AlsoknownasReversePolishNotation. inForth,aregionofmemorywhichiscontrolledinsuchawaythatdatacanbestoredor Stack removedinalastin,firstout(LIFO)fashion. theerrorconditionthatoccurswhentheentireareaofmemoryallowedforthestackis Stackoverflow completelyfilledwithdata. Stack theerrorconditionthatoccurswhenanoperationexpectsavalueonthestack,butthere underflow isnovaliddataonthestack. Word inForth,thenameofadefinition. Compile

() (c)

ProblemsChapter1
Note:beforeyouworktheseproblems,rememberthesesimplerules:
Every:needsa;.

and
Every."needsa".

1. DefineawordcalledGIFTwhich,whenexecuted,willtypeoutthenameofsomegift.For example,youmighttry:
:GIFT."Bookends";

NowdefineawordcalledGIVERwhichwillprintoutaperson'sfirstname.Finally,definea wordcalledTHANKSwhichincludesthenewForthwordsGIFTandGIVER,andprintsouta messagesomethinglikethis:


DearStephanie, thanksfortheBookends.ok

[answer] 2. DefineawordcalledTEN.LESSwhichtakesanumberonthestack,subtractsten,andreturns theansweronthestack.(Hint:youcanuse+.)[answer] 3. AfterenteringthewordsinProb.1,enteranewdefinitionforGIVERtoprintsomeoneelse's name,thenexecuteTHANKSagain.CanyouexplainwhyTHANKSstillprintsoutthefirstgiver's name?[answer]

2HowToGetResults
Inthischapter,we'lldiverightintosomespecificsthatyouneedtoknowbeforewegoon.Specifically, we'llintroducesomeofthearithmeticinstructionsbesides+andsomespecialoperatorsforrearranging theorderofnumbersonthestack,sothatyou'llbeabletowritemathematicalequationsinForth.

ForthArithmeticCalculatorStyle
HerearethefoursimplestintegerarithmeticoperatorsinForth: + (n1n2sum) Adds. (n1n2diff) Subtracts(n1n2). * (n1n2prod) Multiplies. / (n1n2quot) Divides(n1/n2). Unlikecalculators,computerterminalsdon'thavespecialkeysformultiplicationordivision.Insteadwe

use*and/.

Inthefirstchapter,welearnedthatwecanaddtwonumbersbyputtingthembothonthestack,then executingtheword+,thenfinallyexecutingtheword.(dot)togettheresultprintedatourterminal.
175+.22ok

WecanusethismethodwithallofForth'sarithmeticoperators.Inotherwords,wecanuseForthlikea calculatortogetanswers,evenwithoutwritinga"program."Tryamultiplicationproblem:
78*.56ok

Bynowwe'veseenthattheoperatorcomesafterthenumbers.Inthecaseofsubtractionanddivision, though,wemustalsoconsidertheorderofnumbers("74"isnotthesameas"47"). Justrememberthisrule: Toconverttopostfix,simplymovetheoperatortotheendoftheexpression: Infix Postfix 3+4 34+ 500300 500300 6x5 65* 20/4 204/ Sotodothesubtractionproblem:
74=

simplytypein
74.3ok

ForAdventuresomeNewcomersSittingataTerminal Ifyou'reoneofthosepeoplewholiketofoolaroundandfigurethingsoutforthemselves withoutreadingthisbook,thenyou'reboundtodiscoveracoupleofweirdthings.Firstoff,as wetoldyou,theseoperatorsareintegeroperators.Thatnotonlymeansthatyoucan'tdo calculationswithdecimalvalues,like


10.002.25+

italsomeansthatyoucanonlygetintegerresults,asin
214/.5okinsteadof5.25ok

Anotherthingisthatifyoutrytomultiply:

100000001000*.

orsomesuchlargenumbers,you'llgetacrazyanswer.Sowe'retellingyouupfrontthatwith theoperatorsintroducedsofarandwith.toprinttheresults,youcan'thaveanynumbersthat arehigherthan+2147483647orlowerthan2147483648.Numberswithinthisrangearecalled "singlelengthsignednumbers." Notice,inthelistofForthwordsafewpagesback,theletter"n,"whichstandsfor"number." SinceForthusessinglelengthnumbersmoreoftenthanothertypesofnumbers,the"n" signifiesthatthenumbermustbesinglelength.Andyes,thereareotheroperatorsthatextend thisrange("doublelength"operators,whichareindicatedby"d"). Allofthesemysterieswillbeexplainedintime,sostaytuned.

Theorderofnumbersstaysthesame.Let'stryadivisionproblem:
204/.5ok

Theword/isdefinedtodividethesecondnumberonthestackbythetopnumber. Whatdoyoudoifyouhavemorethanoneoperatorinanexpression,like:
4+(17*12)

youask?Let'stakeitstepbystep:theparenthesestellyoutofirstmultiplyseventeenbytwelve,thenadd four.SoinForthyouwouldwrite:
1712*4+.208ok

andhere'swhy: 17and12goontothestack.*multipliesthemandreturnstheresult. Thenthefourgoesontothestack,ontopof204.+rollsouttheaddingmachineandadds themtogether,returningonlytheresult. Orsupposeyouwanttoaddfivenumbers.YoucandoitinForthlikethis:


1720+132+3+9+.181ok

Nowhere'saninterestingproblem:
(3+9)*(4+6)

Tosolveitwehavetoaddthreetoninefirst,thenaddfourtosix,thenfinallymultiplythetwosums.In Forth,wecanwrite
39+46+*.120ok

Thepictureattherightisshowingwhathappens.

Noticethatweveryconvenientlysavedthesumtwelveonthestackwhilewewentonaboutthebusiness ofaddingfourtosix. Rememberthatwe'renotconcernedyetwithwritingdefinitions.WearesimplyusingForthasa calculator. Ifyou'relikemostbeginners,youprobablywouldliketotryyourhandatafewpracticeproblemsuntil youfeelmorecomfortablewithpostfix.

PostfixPracticeProblems(Quizzie2a)
Convertthefollowinginfixequationstopostfix"calculatorstyle."Forexample,
ab+c

wouldbecome
ab*c+

1. 2. 3. 4. 5.

c(a+b) (3ab)/4+c (0.5ab)/100 (n+1)/n x(7x+5) Convertthefollowingpostfixexpressionstoinfix:

6. abba+/ 7. ab10*/ [answer]

ForthArithmeticDefinitionStyle
InChap.1wesawthatwecoulddefinenewwordsintermsofnumbersandotherpredefined words.Let'sexploresomefurtherpossibilities,usingsomeofournewlylearnedmath operators. Let'ssaywewanttoconvertvariousmeasurementstoinches.Weknowthat
1yard=36inches

and
1foot=12inches

sowecandefinethesetwowords:
:YARDS>IN36*;ok :FT>IN12*;ok

wherethenamessymbolize"yardstoinches"and"feettoinches."Here'swhattheydo:
10YARDS>IN.360ok

2FT>IN.24ok

Ifwealwayswantourresulttobeininches,wecandefine:
:YARDS36*;ok :FEET12*;ok :INCHES;ok

Sothatwecanusethephrase
10YARDS2FEET+9INCHES+.393ok

NoticethatthewordINCHESdoesn'tdoanythingexceptremindthehumanuserwhatthenineisfor.If wereallywanttogetfancy,wecanaddthesethreedefinitions:
:YARDYARDS;ok :FOOTFEET;ok :INCH;ok

sothattheusercanenterthesingularformofanyofthenounsandstillgetthesameresult:
1YARD2FEET+1INCH+.61ok 2YARDS1FOOT+.84ok

Sofarwehaveonlydefinedwordswhosedefinitions ForSemanticFreaks containasinglemathoperator.Butit'sperfectly possibletoputmanyoperatorsinsideadefinition,if Inmathematics,theword"argument"refersto anindependentvariableofafunction.Computer that'swhatyouneedtodo. linguistshaveborrowedthistermtoreferto Let'ssaywewantawordthatcomputesthesumof numbersbeingoperatedonbyoperators.They fivenumbersonthestack.Afewpagesbackwe havealsoborrowedtheword"parameters"to summedfivenumberslikethis: describeprettymuchthesamething.
1720+132+3+9+.181ok

Butwecanalsoenter
172013239++++.181ok

Wegetthesameanswer,eventhoughwe'veclusteredallthenumbersintoonegroupandalltheoperators intoanothergroup.Wecanwriteourdefinitionlikethis:
:5#SUM++++;ok

andexecuteitlikethis:
1720132395#SUM.181ok

Ifweweregoingtokeep5#SUMforfutureuse,wecouldenteritintoourevergrowingglossary,along withanotethatit"expectsfivearguments"onthestack,whichitwilladdtogether.

Hereisanotherequationtowriteadefinition for:
(a+b)*c

ForBeginnersWhoLikeWordProblems

Ifajet plane AswesawinQuizzie2a,thisexpressioncan fliesat an bewritteninpostfixas average cab+* air speed Thuswecouldwriteourdefinition of600 :SOLUTION+*;ok mph andifitflieswithatailwindof25mph,howfarwillit aslongaswemakesurethatweenterthe travelinfivehours? argumentsintheproperorder; Ifwedefine
cabSOLUTION :FLIGHTDISTANCE+*;

DefinitionStylePractice Problems(Quizzie2b)

wecouldenter
560025FLIGHTDISTANCE.3125ok

Convertthefollowinginfixexpressionsinto Tryitwithdifferentvalues,includingheadwinds Forthdefinitionsandshowthestackorder (negativevalues). requiredbyyourdefinitions.Sincethisis Quizzie2b,youcannameyourdefinitions2B1,2B2,etc. 1. ab+cwouldbecome:2B1*+; whichexpectsthisstackorder:(cbaresult) 2. (a4b)/6+c 3. a/(8b) 4. 0.5ab/100 5. a(2a+3) 6. (ab)/c [answer]

TheDivisionOperators
Theword/isForth'ssimplestdivisionoperator.Slashsuppliesonlythequotient;anyremainderislost.If youtype:
224/.5ok

Yougetonlythequotientfive,nottheremaindertwo. Ifyou'rethinkingofapocketcalculator'spercentoperator,thenfiveisnotthefullanswer. But/isonlyoneofseveraldivisionoperatorssuppliedbyForthtogiveyoutheflexibilityto tellthecomputerexactlywhatyouwantittodo. Forexample,let'ssayyouwanttosolvethisproblem:"HowmanydollarbillscanIgetinexchangefor22

quarters?"Therealanswer,ofcourse,isexactly5,not5.5.Acomputerizedmoneychanger,forexample, wouldnotknowhowtogiveyou5.5dollarbills. HerearetwomoreForthdivsionoperators: /MOD (n1n2remquot) MOD (n1n2rem) Divides.Returnstheremainderandquotient. Returnstheremainderfromdivision.

Theseoperatorsarebothsigned,and"truncating."We'llseewhatthismeansinthechapteroncomputer numbers. /MODgivesboththeremainderandthequotient;MOD(from"modulo")givestheremainderonly.(For /MOD,thestacknotationinthetableindicatesthatthequotientwillbeontopofthestack,andthe remainderbelow.Remember,therightmostrepresentsthetopmost.) Let'strythefirstone:


224/MOD..52ok

Samurai Here/MODperformsthedivisionandputsboththequotientandtheremainderonthe /MOD stack.Thefirstdotprintsthequotientbecausethequotientwasontop. (slash'solderWithwhatwe'velearnedsofar,wecaneasilydefinethisword: brother)


:QUARTERS4/MOD.."onesand" .."quarters";

Sothatyoucantype:
22QUARTERS

withthisresult:
22QUARTERS5onesand2quartersok

Thesecondwordinthetable,MOD,leavesonlytheremainder.Forexamplein: 224MOD.2ok thetwoistheremainder.

StackManeuvers
IfyouworkedProb.6inthelastset,youdiscoveredthattheinfixequation
(ab)/c

cannotbesolvedwithadefinitionunlessthereissomewaytorearrangevaluesonthestack. Well,thereisaway:byusinga"stackmanipulationoperator"calledSWAP.

SWAP
ThewordSWAPisdefinedtoswitchtheorderofthetoptwostackitems.

Aswiththeotherstackmanipulationoperators,youcantestSWAPatyourterminalin"calculatorstyle"; thatis,itdoesn'thavetobecontainedwithinadefinition. Firstenter


12..21ok

thenagain,thistimewithSWAP:
12SWAP..12ok

ThusProb.6canbesolvedwiththisphrase:
SWAP/

with(cab)onthestack. Let'sgivea,b,andcthesetestvalues:
a=10b=4c=2

thenputthemonthestackandexecutethephrase,likeso:
2104SWAP/.3ok

Hereisalistofseveralstackmanipulationoperators,includingSWAP SWAP (n1n2n2n1) DUP (nnn) OVER (n1n2n1n2n1) ROT (n1n2n3n2n3n1) DROP (n) Reversesthetoptwostackitems. Duplicatesthetopstackitem. Makesacopyoftheseconditemandpushesitontop. Rotatesthethirditemtothetop. Discardsthetopstackitem.

DUP
Thenextstackmanipulationoperatoronthelist,DUP,simplymakesasecondcopy (duplicate)ofthetopstackitem. Forexample,ifwehave"a"onthestack,wecancompute:
a2

asfollows:
DUP*

inwhichthefollowingstepsoccur: Operation Contents ofstack

DUP *

a aa a2

OVER
Nowsomebodytellsyoutoevaluatetheexpression:
a*(a+b)

giventhefollowingstackorder:
(ab)

But,yousay,I'mgoingtoneedanewmanipulationoperator:Iwanttwocopiesofthe"a,"andthe"a"is underthe"b."Here'sthewordyouneed:OVER.OVERsimplymakesacopyofthe"a"andleapfrogsit overthe"b":


(ababa)

Nowtheexpression
a*(a+b)

caneasilybewritten
OVER+*

Here'swhathappens: Operation OVER + * Contents ofstack ab aba a(b+a) a*(b+a)

WhenwritingequationsinForth,it'sbestto"factorthemout"first.Forexample,ifsomebodyasksyouto evaluate:
a2+ab

inForth,you'llfinditquitecomplicated(andmaybeevenimpossible)usingthewordswe'veintroduced sofar...unlessyoufactorouttheexpressiontoread:
a*(a+b)

whichistheexpressionwejustevaluatedsoeasily.

ROT
ThefourthstackmanipulatoronthelistisROT(pronouncedrote),whichisshortfor"rotate."ROT transformsthetopthreestackvaluesfrom(abc)to(bca). Forexample,ifweneedtoevaluatetheexpression:
abbc

weshouldfirstfactoroutthe"b"s:
b*(ac)

Nowifourstartingstackorderisthis:
(cba)

wecanuse:
ROT*

inwhichthefollowingstepswilloccur: Operation ROT * Contents ofstack cba bac b(ac) b*(ac)

DROP
ThefinalstackmanipulationoperatoronthelistisDROP.Allitdoesisdiscardthetopstackvalue. Prettysimple,huh?We'llseesomegoodusesforDROPlateron. AHandyHint ANondestructiveStackPrint Beginnerswhoarejustlearningtomanipulatenumbersonthestackinusefulwaysveryoftenfind themselvestypingaseriesofdotstoseewhat'sonthestackaftertheirmanipulations.Theproblem withdots,though,isthattheydon'tleavethenumbersonthestackforfuturemanipulation. TheForthword.Sprintsoutallthevaluesthathappentobeonthestack"nondestructively";thatis, withoutremovingthem.Let'stestit,firstwithnothingonthestack:
.S<0>ok

Asyoucansee,inthisversionof.S,weseeatleastonenumber.Thisisthenumberofitemsactually

onthestack. Nowlet'strywithnumbersonthestack:
123.S<3>123ok ROT.S<3>231ok

StackManipulationandMathDefinitions(Quizzie2c)
1. Writeaphrasewhichflipsthreeitemsonthestack,leavingthemiddlenumberinthemiddle;that is,
abcbecomescba

2. WriteaphrasethatdoeswhatOVERdoes,withoutusingOVER. 3. WriteadefinitioncalledROT,whichrotatesthetopthreestackitemsintheoppositedirection fromROT;thatis,


abcbecomescab

Writedefinitionsforthefollowingequations,giventhestackeffectsshown: 4. (n+1)/n(nresult) 5. x(7x+5)(xresult) 6. 9a2ba(abresult) [answer]

PlayingDoubles
Thenextfourstackmanipulationoperatorsshouldlookvaguelyfamiliar: 2SWAP (d1d2d2d1) 2DUP (ddd) Reversesthetoptwopairsofnumbers. Duplicatesthetoppairofnumbers.

2OVER (d1d2d1d2d1) Makesacopyofthesecondpairofnumbersandpushesitontop. 2DROP (d) Discardsthetoppairofnumbers.

Theprefix"2"indicatesthatthesestackmanipulationoperatorshandlenumbersinpairs. Theletter"d"inthestackeffectscolumnstandsfor"double.""Double"hasa specialsignificancethatwewilldiscusswhenwetalkabout"n"and"u." The"2"manipulatorslistedabovearesostraightforward,wewon'tevenboreyouwithexamples.

Onemorething:therearestillsomestackmanipulatorswehaven'ttalkedaboutyet,sodon'tgocrazyby tryingtoomuchfancyfootworkonthestack. Here'salistoftheForthwordswe'vecoveredinthischapter: + * / /MOD MOD SWAP DUP OVER ROT DROP 2SWAP 2DUP 2OVER 2DROP (n1n2sum) (n1n2diff) (n1n2prod) (n1n2quot) (n1n2remquot) (n1n2rem) (n1n2n2n1) (nnn) (n1n2n1n2n1) (n1n2n3n2n3n1) (n) (d1d2d2d1) (ddd) (d1d2d1d2d1) (d) Adds. Subtracts(n1n2). Multiplies. Divides(n1/n2). Divides.Returnstheremainderandquotient. Returnstheremainderfromdivision. Reversesthetoptwostackitems. Duplicatesthetopstackitem. Makesacopyoftheseconditemandpushesitontop. Rotatesthethirditemtothetop. Discardsthetopstackitem. Reversesthetoptwopairsofnumbers. Duplicatesthetoppairofnumbers. Makesacopyofthesecondpairofnumbersandpushesitontop. Discardsthetoppairofnumbers. ReviewofTerms

Doublelength numbers Singlelength numbers

integerswhichencompassarangeofover18,446,744,073,709,551,615to +18,446,744,073,709,551,615(andwhichwe'llintroduceofficiallyinChap.7). integerswhichfallwithintherangeof2billionto+2billion:theonlynumberswhich arevalidastheargumentsorresultsofanyoftheoperatorswe'vediscussedsofar.

ProblemsChapter2
1. What'sthedifferencebetweenDUPDUPand2DUP?[answer] 2. Writeaphrasewhichwillreversetheorderofthetopfouritemsonthestack;thatis,
(12344321)

[answer] 3. Writeadefinitioncalled3DUPwhichwillduplicatethetopthreenumbersonthestack;for example,


(123123123)

[answer]

Writedefinitionsforthefollowinginfixequations,giventhestackeffectsshown: 4. a2+ab+c(cabresult)[answer] 5. (ab)/(a+b)(abresult)[answer] 6. Writeasetofwordstocomputeprisonsentencesforhardenedcriminalssuchthatthejudgecan enter:


CONVICTEDOFARSONHOMICIDETAXEVASIONok WILLSERVE35yearsok

oranyseriesofcrimebeginningwiththewordCONVICTEDOFandendingwithWILL SERVE.Usethesesentences
HOMICIDE20years ARSON10years BOOKMAKING2years TAXEVASION5years

[answer] 7. You'retheinventoryprogrammeratMaria'sEggRanch.DefineawordcalledEGG.CARTONS whichexpectsonthestackthetotalnumberofeggslaidbythechickenstodayandprintsoutthe numberofcartonsthatcanbefilledwithadozeneach,aswellasthenumberofleftovereggs. [answer]

3TheEditor(AndStaff)
Uptillnowyou'vebeencompilingnewdefinitionsintothedictionarybytypingthematyourterminal. Thischapterintroducesanalternatemethod,usingdiskstorage. Let'sbeginwithsomeobservationsthatspecificallyconcernthedictionary.

AnotherLookattheDictionary
Ifyou'vebeenexperimentingwitharealcomputer,youmayhavediscoveredsomethingswehaven't mentionedyet.Inanycase,it'stimetomentionthem. DiscoveryOne:Youcandefinethesamewordmorethanonceindifferent waysonlythemostrecentdefinitionwillbeexecuted. Forexample,ifyouhaveentered:
:GREET."Hello,IspeakForth.";ok

thenyoushouldgetthisresult:
GREETHello,IspeakForth.ok

Andifyouredefine:
:GREET."Hithere!";ok

yougetthemostrecentdefinition:
GREETHithere!ok

HasthefirstGREETbeenerased?No,it'sstillthere,butthemostrecentGREETisexecutedbecauseof thesearchorder.Thetextinterpreteralwaysstartsatthe"backofthedictionary"wherethemostrecent entryis.Thedefinitionhefindsfirstistheoneyoudefinedlast.ThisistheoneheshowstoEXECUTE. WecanprovethattheoldGREETisstillthere.Trythis:


FORGETGREETok

and
GREETHello,IspeakForth.ok

(theoldGREETagain!)

ThewordFORGETlooksupagivenwordinthedictionaryand,ineffect,removesitfromthedictionary alongwithanythingyoumayhavedefinedsincethatword.FORGET,liketheinterpreter,searches startingfromtheback;heonlyremovesthemostrecentlydefinedversionsoftheword(alongwithany wordsthatfollow).SonowwhenyoutypeGREETattheterminal,theinterpreterfindstheoriginal GREET. FORGETisagoodwordtoknow;hehelpsyoutoweedoutyourdictionarysoitwon'toverflow.(The dictionarytakesupmemoryspace,soaswithanyotheruseofmemory,youwanttoconserveit.) SomeForthsdonothaveFORGET.Inthatcaseyouneedtoplantheforgettinginadvance,e.g.:


MARKERwork

definesthenulldefinitionworktomarkthecurrentsystemstateforyou.Whenyouexecuteworkat somelatertime,thesystemstateisrestoredtothatineffectwhenworkwasdefined.Inparticular,all wordsdefinedafterthemarkerwordworkarecompletelyremovedfromthedictionary. DiscoveryTwo:Whenyouenterdefinitionsfromtheterminal(asyouhave beendoing),yoursourcetext isnotsaved.

Onlythecompiledformofyourdefinitionissavedinthedictionary.Sowhatifyouwanttomakeaminor changetoawordalreadydefined?Thisiswherea"texteditor"comesin.Withthiseditor,youcansave yoursourcetextandmodifyitifyouwantto.Inthisdayandagewecanassumethateveryonehasaccess toatexteditor.ThedocumentationofyourForthsystemshoulddiscusstheprocedurestoeasilyuseyour favoritetexteditorfromwithintheForthenvironment.(OnamodernOS,doubleclickthefileyouwant toedit.Afterfinishingyoureditingbusiness,typeINCLUDEontheForthcommandline.Addatleastone

trailingspace,thendragyourfileintheForthwindowanddropitonthecommandline.Type .) Atexteditorstoresyoursourcetextondisk.Sowe'dbetterintroducethediskandthewaytheForth systemusesit.

HowForthUsestheDisk
AllForthsystemsusediskmemory.EventhoughdiskmemoryisnotabsolutelynecessaryforaForth system,it'sdifficulttoimagineForthwithoutit. Tounderstandwhatdiskmemorydoes,compareitwithcomputermemory(RAM).Thedifferenceis analogoustothedifferencebetweenafilingcabinetandarollingcardindex. Sofaryou'vebeenusingcomputermemory,whichislikethecardindex.Thecomputercanaccessthis memoryalmostinstantaneously,soprogramsthatarestoredinRAMcanrunveryfast.Unfortunately,this kindofmemoryissometimesverylimited(e.g.inembeddedcontrollers)andrelativelyexpensive. Ontheotherhand,thediskiscalleda"bulkmemory"device,because,likeafilingcabinet,itcanstorea lotofinformationatamuchcheaperpriceperunitofinformationthanthememoryinsidethecomputer. Bothkindsofmemorycanbewrittentoandreadfrom. Thecompilercompilesalldictionaryentriesintocomputermemorysothatthedefinitionswillbequickly accessible.Theperfectplacetostoresourcetext,however,isonthedisk,whichiswhatForthdoes.You caneithersendsourcetextdirectlyfromthekeyboardtotheinterpreter(asyouhavebeendoing),oryou cansaveyoursourcetextonthediskandthenlaterreaditoffthediskandsendittothetextinterpreter. Diskmemoryisdividedinto unitscalled"blocks."Eachblock holds1,024charactersofsource textorbinarydata,traditionally organizedas16linesof64 characters.TheANSForth standarddoesnotspecifyhow manyblocksthereare.The documentationofyourForth systemshouldtellyouthis. WithcurrentForths,disk memoryresidesinOSfiles. Therearewaystoattachspecific OSfilestothe"Forthdisk."Due tothespecial16by64formatof Forthblocks,OSutilities considerthemasbinarydataand cannotgenerallyprint,list,filteroreditthem.Forthsystemshavestandardizedfacilitiestohandlesome ofthesetasksbythemselves. AssumingyouareusingiForth,thenthefollowingshouldinstructdiskmemorytocomefromsomefile:

USEblocks.fbok

Tolistablock,simplytypetheblocknumberandthewordLIST,asin:
1LIST 0 1(LargeletterFMHX21:2907/01/89) 2 3:STAR[CHAR]*EMIT; 4:STARS0DOSTARLOOP; 5:MARGINCR30SPACES; 6:BLIPMARGINSTAR; 7:BARMARGIN5STARS; 8:FBARBLIPBARBLIPBLIPCR; 9 10 11 12 13 14 15 ok

Theaboveiswhatablocklookslikewhenit'slistedonyourterminal. Togiveyouabetterideaofhowallofthiscouldbeused,we'llassumethatblock1containsthe definitionsshownabove.Exceptforline1,everythinglooksfamiliar:thesearethedefinitionsyouusedto printalargeletter"F"atyourterminal. Nowifyouweretotype:


1LOAD F

youwouldsendblock1totheinputstreamandthenontothetextinterpreter.Thetextinterpreterdoes notcarewherehistextcomesfrom.Recognizingthecolons,hewillhaveallthedefinitionscompiled,and thenwillexecutethenewwordF. (interpret...) Nowfortheunfinishedbusiness:line1.Thewordsinsidetheparentheses areforhumansonly;theyareneithercompilednorexecuted.Theword((leftparenthesis)tellsthetext interpretertoskipallthefollowingtextuptotheterminatingrightparenthesis.Because(isaword,it mustbesetoffwithaspace.Theclosingparenthesisisnotaword,itissimplyacharacterthatislooked forby(,calledadelimiter.(Recallthatthedelimiterfor."istheclosingquotemark.) Tosummarize,thethreeANSForthcommandswe'velearnedsofarthatconcerndiskblocksare: LIST LOAD (n) Listsadiskblock. (n) Loadsadiskblock(compilesorexecutes). Causesthestringxxxtobeignoredbythetext interpreter.Thecharacter)isthedelimiter.

(xxx) ()

BlockbufferBasics
Wehavediscussedblocksmainlybecauseofhistoricalreasons.Blocksarehardlyeverusedforsource textstorageanymore.Thepreferredwaytohandlesourceisinstandardtextfiles,usingtheword INCLUDEtoloadthem:
INCLUDEblocks.forthok

Themainadvantageisthatblocks.forthcanbeeditedandmanagedwithstandardtextfileutilities. However,nowwe'reatit,we'llmentionafewotherwordstoaccessandmodifyblocksondisk. Thebasicwordthatbringsablockinfromthedisk,afterfirstfindinganavailablebufferandstoringits contentsondiskifnecessary,isBLOCK.Forinstance,ifyousay


1BLOCK

thesystemwillcopyblock1ofthecurrentlyopenfileintooneofthesystembuffers.BLOCKalsoleaves onthestacktheaddressofthebeginningofthebuffer(1024bytes,remember)thatitused.Thecontents ofthisbufferareguaranteedtostayvaliduntilyouexecuteawordfromthesetofprocedureswith "multitaskingimpact,"likeEMITorTYPE.Ifyouatanytimemodifythebuffercontentsandthen executethewordUPDATE,Forthwillremembertofirstwritetheblockbacktodiskwhenitneedsto reusethebuffer.If,forsomereason,youexecuteUPDATEandthendecidethatyoudon'twanttohave theblocksrewrittenafterall,useEMPTYBUFFERStoinvalidatethem.ThisworksbecauseForthdoes notimmediatelywritethediskafteryouuseUPDATE.Toforcewritingoutthebuffersrightnow,usethe wordFLUSH. Here'salistoftheForthwordswe'vecoveredinthischapter: DesignateOStextfilexxxasthe"Forthdisk." Listsadiskblock. Loadsadiskblock(compilesorexecutes). Causesthestringxxxtobeignoredbythetextinterpreter.The (xxx) () character)isthedelimiter. Marksthemostrecentlyreferencedblockasmodified.Theblockwill UPDATE () laterbeautomaticallytransferredtomassstorageifitsbufferis neededtostoreadifferentblockorifFLUSHisexecuted. Marksallblockbuffersasemptywithoutnecessarilyaffectingtheir EMPTYBUFFERS () actualcontents.Updatedblocksarenotwrittentomassstorage. Leavestheaddressofthefirstbyteinblocku.Iftheblockisnot alreadyinmemory,itistransferredfrommassstorageintowhichever BLOCK (uaddr) memorybufferhasbeenleastrecentlyaccessed.Iftheblock occupyingthatbufferhasbeenupdated(i.e.,modified),itisrewritten ontomassstoragebeforeblockuisreadintothebuffer. INCLUDExxx () Loadthetextfilexxx(compilesorexecutes). FORGETxxx () Forgetsalldefinitionsbacktoandincludingxxx. Createsawordxxxwhich,whenexecuted,restoresthedictionaryto MARKERxxx () thestateithadjustpriortothedefinitionofxxx.Inparticular,remove xxxandallsubsequentworddefinitions. USExxx LIST LOAD () (n) (n)

ReviewofTerms Block Buffer Null definition inForth,adivisionofdiskmemorycontainingupto1024charactersofsourcetext. atemporarystorageareafordata. adefinitionthatdoesnothing,writtenintheform:


:NAME;

thatis,anameonlywillbecompiledintothedictionary.Anulldefinitionservesasa "bookmark"inthedictionary,forFORGETtofind. alocationinmemorywhereanumbercanbestored(orchanged)asareferenceto Pointer somethingelse. inForth,thewrittenoutformofadefinitionordefinitionsinEnglishlikewordsand Sourcetext punctuation,asopposedtothecompiledformthatisenteredintothedictionary.

4Decisions,Decisions,...
Inthischapterwe'lllearnhowtoprogramthecomputertomake"decisions."Thisisthemomentwhen youturnyourcomputerintosomethingmorethananordinarycalculator.

TheConditionalPhrase
Let'sseehowtowriteasimpledecisionmakingstatementinForth.Imagineweareprogramminga mechanicaleggcartonpacker.Somesortofmechanicaldevicehascountedtheeggsontheconveyorbelt, andnowwehavethenumberofeggsonthestack.TheForthphrase:
12=IFFILLCARTONTHEN

testswhetherthenumberonthestackisequalto12,andifitis,thewordFILLCARTONisexecuted.If it'snot,executionmovesrightalongtothewordsthatfollowTHEN.

Theword=takestwovaluesofthestackandcomparesthemtoseeiftheyareequal.

Iftheconditionistrue,IFallowstheflowofexecutiontocontinuewiththenextwordinthedefinition.

Butiftheconditionisfalse,IFcausestheflowofexecutiontoskiptoTHEN,fromwhichpointexecution willproceed. Let'stryit.Definethisexampleword:


:?FULL12=IF."It'sfull"THEN;ok 11?FULLok 12?FULLIt'sfullok

Notice:anIF...THENstatementmustbecontainedwithinadefinition.Youcan'tjustenterthesewordsin "calculatorstyle." Don'tbemisledbythetraditionalEnglishmeaningsoftheForthwordsIFandTHEN.Thewordsthat followIFareexecutediftheconditionistrue.ThewordsthatfollowTHENarealwaysexecuted,as thoughyouweretellingthecomputer,"Afteryoumakethechoice,thencontinuewiththerestofthe definition."(Inthisexample,theonlywordafterTHENis;,whichendsthedefinition.) Let'slookatanotherexample.Thisdefinitioncheckswhetherthetemperatureofalaboratoryboileristoo hot.Itexpectstofindthetemperatureonthestack:


:?TOOHOT220>IF."Dangerreduceheat"THEN;

Ifthetemperatureonthestackisgreaterthan220,thedangermessagewillbeprintedattheterminal. Youcanexecutethisoneyourself,byenteringthedefinition,thentypinginavaluejustbeforetheword.
290?TOOHOTDangerreduceheatok 130?TOOHOTok

RememberthateveryIFneedsaTHENtocomehometo.Bothwordsmustbeinthesamedefinition. HereisapartiallistofcomparisonoperatorsthatyoucanusebeforeanIF...THENstatement: = < > 0= 0< 0>

Thewords<and>expectthesamestackorderasthearithmeticoperators,thatis: Infix Postfix 2<10 isequivalentto 210< 17>39 isequivalentto 1739>

Thewords0=,0<and0>expectonlyonevalueonthestack.Thevalueiscomparedwithzero. Anotherword,INVERT,doesn'ttestanyvalueatall;itsimplyreverseswhateverconditionhasjustbeen tested.Forexample,thephrase:


...=INVERTIF...

willexecutethewordsafterIF,ifthetwonumbersonthestackarenotequal.

TheAlternativePhrase
ForthallowsyoutoprovideanalternativephraseinanIFstatement,withthewordELSE. Thefollowingexampleisadefinitionwhichtestswhetheragivennumberisavaliddayofthemonth:
:?DAY32<IF."Looksgood"ELSE."noway"THEN;

Ifthenumberonthestackislessthanthirtytwo,themessage"Looksgood"willbeprinted. Otherwise,"noway"willbeprinted. ImaginethatIFpullsarailroadtrackswitch,dependingontheoutcomeofthetest.Executionthentakes oneoftwopossibleroutes,buteitherway,thetracksrejoinatthewordTHEN. Bytheway,incomputerterminology,thiswholebusinessofreroutingthepathofexecutioniscalled "branching."

Here'samoreusefulexample.Youknowthatdividinganynumberbyzeroisimpossible,soifyoutryit onacomputer,you'llgetanincorrectanswer.Wemightdefineawordwhichonlyperformsdivisionifthe denominatorisnotzero.Thefollowingdefinitionexpectsstackitemsinthisorder:


(numeratordenominatorquotient) :/CHECK DUP0=IF."invalid"DROP ELSE/ THEN;

NoticethatwefirsthavetoDUPthedenominatorbecausethephrase
0=IF

willdestroyitintheprocess. AlsonoticethatthewordDROPremovesthedenominatorifdivisionwon'tbeperformed,sothatwhether wedivideornot,thestackeffectwillbethesame.

NestedIF...THENStatements
It'spossibletoputanIF...THEN(orIF...ELSE...THEN)statementinsideanotherIF...THENstatement. Infact,youcangetascomplicatedasyoulike,solongaseveryIFhasoneTHEN. Considerthefollowingdefinition,whichdeterminesthesizeofcommercialeggs(extralarge,large,etc.) giventheirweightinouncesperdozen:

:EGGSIZEDUP18<IF."reject"ELSE DUP21<IF."small"ELSE DUP24<IF."medium"ELSE DUP27<IF."large"ELSE DUP30<IF."extralarge"ELSE ."error" THENTHENTHENTHENTHENDROP;

OnceEGGSIZEhasbeenentered,herearesomeresultsyou'dget:
23EGGSIZEmediumok 29EGGSIZEextralargeok 40EGGSIZEerrorok

We'dliketopointoutafewthingsaboutEGGSIZE: Theentiredefinitionisaseriesof"nested"IF...THENstatements.Theword"nested"doesnotrefertothe factthatwe'redealingwitheggs,buttothefactthatthestatementsnestinsideoneanother,likeasetof mixingbowls. ThefiveTHENsatthebottomcloseoffthefiveIFsinreverseorder,thatis:

AlsonoticethataDROPisnecessaryattheendofthedefinitiontogetridoftheoriginalvalue. Finally,noticethatthedefinitionisvisuallyorganizedtobereadeasilybyhumanbeings.MostForth programmerswouldratherwastealittlespacethanletthingsgetanymoreconfusedthantheyhavetobe.

ACloserLookatIF
Howdoesthecomparisonoperator(=,<,>,orwhichever)letIFknowwhetherthecondition istrueorfalse?BysimplyleavingTRUEorFALSEonthestack.ATRUE(allbitshigh) meansthattheconditionistrue;aFALSE(allbitslow)meansthattheconditionisfalse. Incomputerjargon,whenonepieceofprogramleavesavalueasasignalforanotherpieceofprogram, thatvalueiscalleda"flag." Tryenteringthefollowingphrasesattheterminal,letting.showyouwhat'sonthestackasaflag.
54>.1ok 54<.0ok

(It'soktousecomparisonoperatorsdirectlyatyourterminallikethis,butrememberthatanIF...THEN statementmustbewhollycontainedwithinadefinitionbecauseitinvolvesbranching.) IFwilltakeaTRUEasaflagthatmeanstrueandaFALSEasaflagthatmeansfalse.Nowlet'stakea closerlookatINVERT,whichreversestheflagonthestack.


FALSEINVERT.1ok TRUEINVERT.0ok

Nowwe'llletyouinonalittlesecret:IFwilltakeanynonzerovaluetomeantrue. Toproveit,tryenteringthistest:

:TESTIF."non"THEN."zero";

Eventhoughthereisnocomparisonoperatorintheabovedefinition,you'llstillget
0TESTzerook 1TESTnonzerook 400TESTnonzerook

Sowhat,youask?Well,thefactthatanarithmeticzeroisidenticaltoaflagthatmeans"false"leadsto someinterestingresults. Foronething,ifallyouwanttotestiswhetheranumberiszero,youdon'tneedacomparisonoperatorat all.Forexample,aslightlysimplerversionof/CHECK,whichwesawearlier,couldbe


:/CHECKDUPIF/ELSE."invalid"DROPTHEN;

Here'sanotherinterestingresult.Sayyouwanttotestwhetheranumberisanevenmultipleoften,suchas 10,20,30,40etc.Y ouknowthatthephrase


10MOD

dividesbytenandreturnstheremainderonly.Anevenmultipleoftenwouldproduceazeroremainder, sothephrase
10MOD0=

givestheappropriate"true"or"false"flag. Stillanotherinterestingresultisthatyoucanuse(minus)asacomparisonoperatorwhichtestswhether twovaluesare"notequal."Whenyousubtracttwoequalnumbers,yougetzero(false);whenyousubtract twounequalnumbers,yougetanonzerovalue.However,nowwemusttalkabitabout"wellformed flags." Ifyouthinkaboutit,both0=andINVERTdoalmostthesamething.However,0=changesthenumber0 tothenumber1andanynonzeronumberto0,whileINVERTchangesallzerobitsinanumbertoone bitsandtheonebitsinthatnumbertozerobits.Onlywhenthenumberisa"wellformedflag",i.e., either0or1,theresultof0=andINVERTisthesame.Allcomparisonoperatorsreturnwellformed flags,fitforeither0=orINVERT.However,whenyouusetocomparetwonumbers,aswedidabove, theflagwillnotbewellformedwhenthetwonumbersdifferinvalue,andonly0=canbeusedtosafely reversethemeaningofthecomparison. Afinalresultisdescribedinthenextsection.

ALittleLogic
It'spossibletotakeseveralflagsfromvarioustestsandcombinethemintoasingleflagforoneIF statement.Youmightcombinethemasan"either/or"decision,inwhichyoumaketwocomparisontests. Ifeitherorbothofthetestsaretrue,thenthecomputerwillexecutesomething.Ifneitheristrue,itwon't. Here'sarathersimplemindedexample,justtoshowyouwhatwemean.Sayyouwanttoprintthename "ARTICHOKE"ifaninputnumberiseithernegativeoramultipleoften. HowdoyoudothisinForth?Considerthephrase:
DUP0<SWAP10MOD0=+

Here'swhathappenswhentheinputnumberissay,30: Operator Contentsofstack DUP 0< SWAP 10MOD0= 30 3030 300 030 01

Operation

Duplicatesitsowecantestittwice. Isitnegative?No(zero). Swapstheflagwiththenumber. Isitevenlydivisibleby10?Yes(true).

+ 1 Addtheflags. Addstheflags?Whathappenswhenyouaddflags?Herearefourpossibilities:

Loandbehold,theresultflagistrueifeitherorbothconditionsaretrue.Inthisexample,theresultis1, whichmeans"true."Iftheinputnumberhadbeen30,thenbothconditionwouldhavebeentrueandthe sumwouldhavebeenminustwo.Minustwois,ofcourse,nonzero.SoasfarasIFisconcerned,2isas trueas1. Oursimplemindeddefinition,thenwouldbe:


:VEGETABLEDUP0<SWAP10MOD0=+ IF."ARTICHOKE"THEN;

Hereisanimprovedversionofapreviousexamplecalled?DAY. Theold?DAYonlycaughtentriesoverthirtyone.Butnegativenumbersshouldn'tbeallowedeither.How aboutthis:


:?DAYDUP1<SWAP31>+ IF."Noway"ELSE."Looksgood"THEN;

Theabovetwoexampleswillalwaysworkbecauseany"true"flagswillalwaysbeexactly"1."Insome cases,however,aflagmaybeanynonzerovalue,notjust"1,"inwhichcaseit'sdangeroustoaddthem with+.Forexample:


11+.0ok

givesusamathematicallycorrectanswer,butnottheanswerwewantif1and1areflags. Forthisreason,ForthsuppliesawordcalledOR,whichwillreturnthecorrectflagevenincaseof1and 1.An"ordecision"isthecomputertermforthekindofflagwe'vebeendiscussing.Forexample,if eitherthefrontdoororthebackdoorisopen(orboth),flieswillcomein. Anotherkindofdecisioniscalledan"and"decision.Inan"and"decision,bothconditionsmustbetrue fortheresulttobetrue.Forexample,thefrontdoorandthebackdoormustbothbeopenforabreezeto comethrough.Iftherearethreeormoreconditions,theymustallbetrue.


FortheCuriousNewcomer Theuseofwordslike"or"and"and"tostructurepartofanapplicationiscalled"logic."Aformofnotation forlogicalstatementswasdevelopedinthenineteenthcenturybyGeorgeBoole;itisnowcalledBoolean

algebra.Thustheterm"aBooleanflag"(orevenjust"aBoolean")simplyreferstoaflagthatwillbeusedina logicalstatement.

Howcanwedothis"anddecision"inForth?ByusingthehandywordAND.Here'swhatANDwoulddo withthefourpossiblecombinationsofflagswesawearlier:

Inotherwords,onlythecombination"11AND"producesaresultof"true."Let'ssaywe'relookingfor acardboardboxthat'sbigenoughtofitadiskdrivewhichmeasures:
height6" width19" length22"

Theheight,width,andlengthrequirementsallmustbesatisfiedfortheboxtobebigenough.Ifwehave thedimensionsonthestack,thenwecandefine:
:BOXTEST(lengthwidthheight) 6>ROT22>ROT19>ANDAND IF."Bigenough"THEN;

Noticethatwe'veputacommentinsidethedefinition,toremindusofstackeffects.Thisisparticularly wisewhenthestackorderispotentiallyconfusingorhardtoremember. YoucantestBOXTESTwiththefollowingphrase:


23207BOXTESTBigenoughok

Asyourapplicationsbecomemoresophisticated,youwillbeabletowritestatementsinForththatlook likepostfixEnglishandareveryeasytoread.Justdefinetheindividualwordswithinthedefinitionto checksomeconditionsomewhere,thenleaveaflagonthestack. Anexampleis:


:SNAPSHOTLIGHT?FILM?ANDIFPHOTOGRAPHTHEN;

whichchecksthatthereisavailablelightandthatthereisfilminthecamerabeforetakingthepicture. Anotherexample,whichmightbeusedinacomputerdatingapplication,is:
:MATCH HUMOROUSSENSITIVEAND ART.LOVINGMUSIC.LOVINGORAND SMOKING0=AND IF."Ihavesomeoneyoushouldmeet"THEN;

wherewordslikeHUMOROUSandSENSITIVEhavebeendefinedtocheckarecordinadiskfilethat containsinformationonotherapplicantsoftheappropriatesex.

TwoWordswithBuiltinIF
?DUP Theword?DUPduplicatesthetopstackvalueonlyifitisnonzero.Thiscaneliminateafewsurplus words.Forexample,thedefinition:

:/CHECKDUPIF/ELSEDROPTHEN;

canbeshortenedto
:/CHECK?DUPIF/THEN;

ABORT" Itmayhappenthatsomewhereinacomplexapplicationanerrormightoccur(suchasadivisionbyzero), waydowninoneofthelowlevelwords.Whenthishappensyoudon'tjustwantthecomputertokeepon going,andyoualsodon'twantittoleaveanythingonthestack. Ifyouthinksuchanerrormightoccur,youcanusethewordABORT".ABORT"expectsaflagonthe stack:a"true"flagtellsitto"abort,"whichinturnclearsthestacksandreturnsexecutiontotheterminal, waitingforsomeonetotypesomething.ABORT"alsoprintsthenameofthelastinterpretedword,as wellaswhatevermessageyouwant. Let'sillustrate.Wehopeyou'renotsickof/CHECKbynow,becausehereisyetanotherversion:


:/CHECKDUP0=ABORT"zerodenominator"/;

Inthisversion,ifthedenominatoriszero,anynumbersthathappentobeonthestackwillbedropped andtheterminalwillshow:
80/CHECK Error2 zerodenominator?

Justasanexperiment,tryputting/CHECKinsideanotherdefinition:
:ENVELOPE/CHECK."Theansweris".;

andtry
84ENVELOPETheansweris2ok 80ENVELOPE Error2 zerodenominator?

Thepointisthatwhen/CHECKaborts,therestofENVELOPEisskipped. AusefulwordtouseinconjunctionwithABORT"is?STACK,whichchecksforstackunderflowand returnsatrueflagifitfindsit.Thusthephrase:


?STACKABORT"stackempty"

abortsifthestackhasunderflowed. Forthusestheidenticalphrase,infact.Butitwaitsuntilallyourdefinitionshavestoppedexecuting beforeitperformsthe?STACKtest,becausecheckingcontinuouslythroughoutexecutionwould needlesslyslowdownthecomputer.You'refreetoinserta?STACKABORT"phraseatanycriticalor notyettestedportionofyourapplication.


ForComputerPhilosophers Forthprovidescertainerrorcheckingautomatically.ButbecausetheForthoperatingsystemissoeasyto modify,userscanreadilycontroltheamountoferrorcheckingtheirsystemwilldo.Thisflexibilityletsusers

maketheirowntradeoffsbetweenconvenienceandexecutionspeed.

Here'salistoftheForthwordswe'vecoveredinthischapter: IFxxx ELSEyyy THENzzz = < > 0= 0< 0> AND OR ?DUP IF:(f) (n1n2f) (n1n2ndiff) (n1n2f) (n1n2f) (nf) (nf) (nf) (n1n2and) (n1n2or) (nnn)or (00) Iffistrue(nonzero)executesxxx;otherwiseexecutesyyy;continues executionwithzzzregardless.ThephraseELSEyyyisoptional. Returnstrueifn1andn2areequal. Returnstrue(i.e.,thenonzerodifference)ifn1andn2arenotequal. Returnstrueifn1islessthann2. Returnstrueifn1isgreaterthann2. Returnstrueifniszero(i.e.,reversethetruthvalue). Returnstrueifnisnegative. Returnstrueifnispositive. ReturnsthelogicalAND. ReturnsthelogicalOR. Duplicatesonlyifnisnonzero. Iftheflagistrue,typesoutanerrormessage,followedbythetext. Alsoclearsthestacksandreturnscontroltotheterminal.Iffalse, takesnoaction. Returnstrueifastackunderflowconditionhasoccurred. ReviewofTerms

ABORT"xx" (f) ?STACK (f)

asageneralcomputerterm,toabruptlyceaseexecutionifaconditionoccurswhichthe programisnotdesignedtohandle,inordertoavoidproducingnonsenseorpossibly doingdamage. "And"decisiontwoconditionsthatarecombinedsuchthatifbothofthemaretrue,theresultistrue. breakingthenormallystraightforwardflowofexecution,dependingoncond itionsin Branching effectatthetimeofexecution.Branchingallowsthecomputertoresponddifferentlyto differentconditions. ingeneral,acommandthatcomparesonevaluewithanother(forexample,determines Comparison whetheroneisgreaterthantheother),andsetsaflagaccordingly,whichnormallywill operator becheckedbyaconditionaloperator.InForth,acomparisonoperatorleavestheflagon thestack. asageneralcomputerterm,avaluestoredinmemorywhichservesasasignalasto Flag whethersomeknownconditionistrueorfalse.Oncethe"flagisset,"anynumberof routinesinvariouspartsofaprogrammaycheck(orreset)theflag,asnecessary. incomputerterminology,thesystemofrepresentingconditionsintheformof"logical variables,"whichcanbeeithertrueorfalse,andcombiningthesevariablesusingsuch Logic "logicaloperators"as"and,""or,"and"not,"toformstatementswhichmaybetrueor false. Nesting placingabranchingstructurewithinanouterbranchingstructure. Abort

"Or"decision twoconditionsthatarecombinedsuchthatifeitheroneofthemistrue,theresultistrue.

ProblemsChapter4
1. Whatwillthephrase
0=0=

leaveonthestackwhentheargumentis 1? 0? 200? [answer] 2. Explainwhatanartichokehastodowithanyofthis. 3. DefineawordcalledCARDwhich,givenaperson'sageonthestack,printsouteitherofthesetwo messages(dependingontherelevantlawsinyourarea):


ALCOHOLICBEVERAGESPERMITTEDor UNDERAGE

[answer] 4. DefineawordcalledSIGN.TESTthatwilltestanumberonthestackandprintoutoneofthree messages:


POSITIVEor ZEROor NEGATIVE

[answer] 5. InChap.1,wedefinedawordcalledSTARSinsuchawaythatitalwaysprintsatleastonestar, evenifyousay


0STARS*ok

UsingthewordSTARS,defineanewversionofSTARSthatcorrectsthisproblem.[answer] 6. WritethedefinitionforthewordWITHINwhichexpectsthreearguments:
(nlolimithilimit)

andleavesa"true"flagonlyif"n"iswithintherange
lowlimit<=n<hilimit

[answer] 7. Here'sanumberguessinggame(whichyoumayenjoywritingmorethananyonewillenjoy playing).Firstyousecretlyenteranumberontothestack(youcanhideyournumberafterentering

itbyexecutingthewordPAGE,whichclearstheterminalscreen).Thenyouaskanotherplayerto enteraguessfollowedbythewordGUESS,asin
100GUESS

Thecomputerwilleitherrespond"TOOHIGH,""TOOLOW,"or"CORRECT!"Writethe definitionofGUESS,makingsurethattheanswernumberwillstayonthestackthroughrepeated guessinguntilthecorrectanswerisguessed,afterwhichthestackshouldbeclear.[answer] 8. UsingnestedtestsandIF..ELSE...THENstatements,writeadefinitioncalledSPELLERwhich willspelloutanumberonthestack,from4to4.Ifthenumberisoutsidethisrange,itwillprint themessage"OUTOFRANGE."Forexample:


2SPELLERtwook 4SPELLERnegativefourok 7SPELLEROUTOFRANGEok

Makeitasshortaspossible.(Hint:TheForthwordABSgivestheabsolutevalueofanumberon thestack.)[answer] 9. UsingyourdefinitionofWITHINfromProb.6,writeanothernumberguessinggame,called TRAP,inwhichyoufirstenterasecretvalue,thenasecondplayertriestohomeinonitby trappingitbetweentwonumbers,asinthisdialogue:


01000TRAPBETWEENok 330660TRAPBETWEENok 440550TRAPNOTBETWEENok 330440TRAPBETWEENok

andsoon,untiltheplayerguessestheanswer:
391391TRAPYOUGOTIT!ok

Hint:youmayhavetomodifytheargumentstoWITHINsothatTRAPdoesnotsay"BETWEEN" whenonlyoneoftheargumentsisequaltothehiddenvalue.[answer]

5ThePhilosophyofFixedPoint
Inthischapterwe'llintroduceanewbatchofarithmeticoperators.Alongthewaywe'lltackletheproblem ofhandlingdecimalpointsusingonlywholenumberarithmetic.

QuickieOperators
Let'sstartwiththerealeasystuff.Youshouldhavenotroublefiguringoutwhatthewordsinthe followingtabledo. 1+ (nn+1) Addsone.

1 (nn1) 2+ (nn+1) 2 (nn2) 2* (nn*2) 2/ (nn/2)

Subtractsone. Addstwo. Subtractstwo. Multipliesbytwo(arithmeticleftshift). Dividesbytwo(arithmeticrightshift).

ThereasontheyhavebeendefinedaswordsinyourForthsystemisthattheyareusedveryfrequentlyin mostapplicationsandevenintheForthsystemitself. Theonlyreasontouseawordsuchas1+,insteadofoneand+,istradition.InmodernForths1+saves neitherspacenorcompileorexecutiontime.

MiscellaneousMathOperators
Here'satableoffourmiscellaneousmathoperators.Likethequickieoperators,these functionsshouldbeobviousfromtheirnames. ABS NEGATE MIN MAX (n|n|) (nn) (n1n2nmin) (n1n2nmax) Returnstheabsolutevalue. Changesthesign. Returnstheminimum. Returnsthemaximum. AuntMin and UncleMax

Herearetwosimplewordproblems,usingABSandMIN: ABS Writeadefinitionwhichcomputesthedifferencebetweentwonumbers,regardlessoftheorderinwhich thenumbersareentered.


:DIFFERENCEABS;

Thisgivesthesameresultwhetherweenter
5237DIFFERENCE.15ok 3752DIFFERENCE.15ok

MIN Writeadefinitionwhichcomputesthecommissionthatfurnituresalespeoplewillreceiveifthey'vebeen promised$50or1/10ofthesalesprice,whicheverisless,oneachsaletheymake.


:COMMISSION10/50MIN;

Threedifferentvalueswouldproducetheseresults:
600COMMISSION.50ok

450COMMISSION.45ok 50COMMISSION.5ok

TheReturnStack
Wementionedbeforethattherewerestillsomestackmanipulationoperatorswehadn'tdiscussedyet. Nowit'stime. Uptillnowwe'vebeentalkingabout"thestack"asiftherewereonlyone.Butinfacttherearetwo: the"parameterstack"andthe"returnstack."Theparameterstackisusedmoreoftenby Forthprogrammers,soit'ssimplycalled"thestack"unlessthereiscausefordoubt. Asyou'veseen,theparameterstackholdsparameters(or"arguments")thatarebeingpassedfromwordto word.Thereturnstack,however,holdsanynumberof"pointers"whichtheForthsystemusestomakeits merrywaythroughthemazeofwordsthatareexecutingotherwords.We'llelaboratelateron. You,theuser,canemploythereturnstackasaskindof"extrahand"toholdvaluestemporarilywhileyou performoperationsontheparameterstack. Thereturnstackisalastinfirstoutstructure,justliketheparameterstack,soitcanholdmanyvalues. Buthere'sthecatch:whateveryouputonthereturnstackyoumustremoveagainbeforeyougettothe endofthedefinition(thesemicolon),becauseatthatpointtheForthsystemwillexpecttofindapointer there.Youcannotusethereturnstacktopassparametersfromonewordtoanother. Thefollowingtableliststhewordsassociatedwiththereturnstack.Remember,thestacknotationrefers totheparameterstack. Takesavalueofftheparameterstackandpushesitonto >R (n) thereturnstack. Takesavalueoffthereturnstackandpushesitontothe R> (n) parameterstack. I (n) Copiesthetopofthereturnstackwithoutaffectingit.

R@ (n) Copiesthetopofthereturnstackwithoutaffectingit. J (n)

Copiesthethirditemofthereturnstackwithoutaffecting it. Thewords>RandR>transferavaluetoandfromthereturnstack,respectively.Saywewantthe followingstackeffect:


(231321)

thisisthephrasethatwilldoit:
>RSWAPR>

Each>RanditscorrespondingR>mustbeusedtogetherinthesamedefinition. TheotherthreewordsIorR@andJonlycopyvaluesfromthereturnstackwithoutremovingthem. Thusthephrase:

>RSWAPR@

wouldproducethesameresultasfarasitgoes,butunlessyoucleanupyourtrashbeforethenext semicolonyouwillcrashthesystem. Toseehow>R,R>,R@,andImightbeused,imagineyouaresounluckyastoneedtosolvethe equation:


ax2+bx+c

withallfourvaluesonthestackinthefollowingorder:
(abcx)

(remembertofactoroutfirst). Operator parameterstack abcx >R abc SWAPROT cba R@ cbax * cbax + cax+b R>* cx(ax+b) + x(ax+b)+c Goaheadandtryit.Loadthefollowingdefinition:
:QUADRATIC(abcxn) >RSWAPROTR@*+R>*+;

returnstack x x x x x

Nowtestit:
2793QUADRATIC48ok

AnIntroductiontoFloatingPointArithmetic
First,whatdoesfloatingpointmean?Takeapocketcalculator,forexample.Here'swhatthedisplaylooks likeaftereachstep: Youenter: 1.50x 2.23 = Display reads: 1.5 2.23 3.345

Thedecimalpoint"floats"acrossthedisplayasnecessary.Thisiscalleda"floatingpointdisplay." "Floatingpointrepresentation"isawaytostorenumbersincomputermemoryusingaformofscientific notation.Inscientificnotation,twelvemillioniswritten:

12x106

sincetentothesixthpowerequalsonemillion.Inacomputertwelvemillionisstoredastwonumbers:12 and6,whereitisunderstoodthat6isthepoweroftentobemultipliedby12,while3.345couldbestored as3345and3. Theideaoffloatingpointrepresentationisthatthecomputercanrepresentanenormousrangeof numbers,fromatomictoastronomic,withtworelativelysmallnumbers. Whatisfixedpointrepresentation?Itissimplythemethodofstoringnumbersinmemorywithoutstoring thepositionsofeachnumber'sdecimalpoint.Forexample,inworkingwithdollarsandcents,allvalues canbestoredincents.Theprogram,ratherthaneachindividualnumber,canrememberthelocationof thedecimalpoint. Forexample,let'scomparefixedpointandfloatingpointrepresentationsofdollarsandcentsvalues. Realworld Fixedpoint Floatingpoint value: representation: representation: 1.23 123 123(2) 10.98 1098 1098(2) 100.00 10000 1(2) 58.60 5860 586(1) Asyoucansee,withfixedpointallthevaluesmustconformtothesame"scale."Thedecimalpoints mustbeproperly"aligned"(inthiscasetwoplacesinfromtheright)eventhoughtheyarenotactually represented.Withfixedpoint,thecomputertreatsallthenumbersasthoughtheywereintegers.Ifthe programneedstoprintoutananswer,however,itsimplyinsertsthedecimalpointtwoplacesinfromthe rightbeforeitsendsthenumbertotheterminalortotheprinter.

WhyFixedPointisUseful
AForthprogrammerismostinterestedinmaximizingtheefficiencyofthemachine.Thatmeansheor shewantstomaketheprogramrunasfastaspossibleandrequireaslittlecomputermemoryaspossible. Unfortunately,notallprocessorsorcontrollersofferhardwarefloatingpointsupport.Therefore,insome environments,programsthatusefloatingpointfeaturesareredirectedthroughanemulationlibrary. Emulationcodecanbeuptothreetimesslowerthantheequivalentfixedpointcalculation.Ofcourse, thisdifferenceisonlyreallynoticeableinprogramswhichhavetodoalotofcalculationsbeforesending resultstoaterminalortakingsomeaction.Thecatchisthatcodefromanemulationlibraryisalsomany timeslargerthanitsfixedpointcounterpart,whichisquiteuneconomicalforsmallembeddedcontrollers andsuch. Youshouldnotecarefullythatwhenaprocessorsupportshardwarefloatingpoint,itisalmostalways muchfasterandmorecompactthanthefixedpointequivalent.Thespeeddifferencecanbebetween3 and15times. Everythingyoucandowithfloatingpoint,youcandowithfixedpointtoo,aswe'llshowinthe following.Butthereisonethingyoushouldminimizeasmuchaspossible,andthatisswitchingbackand forthbetweenfixedandfloatingpointformats.Formatconversionandadditionalscalingstepscostas muchorevenmoretimethandoingthecalculationsthemselves.

Forthhelpsprogrammersusefixedpointbysupplyingthemwithauniquesetofhighlevelcommands called"scalingoperators."We'llintroducethefirstofthesecommandsinthenextsection.(Thefinal exampleinChap.12illustratestheuseofscalingtechniques.)

StarslashtheScalar
Here'samathoperatorthatisasusefulasitisunusual:*/. Multiplies,thendivides(n1*n2/n3).Usesa doublelengthintermediateresult. Asitsnameimplies,*/performsmultiplication,thendivision.Forexample,let'ssaythatthestack containsthesethreenumbers: */ (n1n2n3nresult)
(22532100)

*/willfirstmultiply225by32,thendividetheresultby100. Thisoperatorisparticularlyusefulasanintegerarithmeticsolutiontoproblemssuchaspercentage calculations. Forexample,youcoulddefinetheword%likethis:


:%100*/;

StarandSlash: Practise,practise...

sothatbyenteringthenumber225andthenthephrase:
32%

you'dendupwith32%of225(thatis,72)onthestack. Themethodoffirstmultiplyingtwointegers,thendividingby100isidenticaltotheapproachmost peopletakeinsolvingsuchproblemsonpaper:


225 0.32x 4.50 67.5 72.00

*/isnot*anda/throwntogether,though.Itusesa"doublelengthintermediateresult."Whatdoesthat mean,youask? Sayyouwanttocompute34%of912,345,678.Rememberthatsingleprecisionoperators,like*and/, onlyworkwithargumentsandresultswithintherangeofasinglelengthnumber.Ifyouweretoenterthe phrase:


91234567834*100/

you'dgetanincorrectresult,becausethe"intermediateresult"(inthiscase,theresultofthe multiplication),exceeds2147483647,asshownintheleftcolumninthispictorialsimulation. But*/usesadoublelengthintermediateresult,sothatitsrangewillbelargeenoughtoholdtheresultof anytwosinglelengthnumbersmultipliedtogether.Thephrase:


91234567834100*/

returnsthecorrectanswerbecausetheendresultfallswithintherangeofsinglelengthnumbers. Thepreviousexamplebringsupanotherquestion:howtoroundoff. Let'sassumethatthisistheproblem: If32%ofthestudentseatingattheschoolcafetariausuallybuybananas,howmanybananas shouldbeonhandforacrowdof225?Naturally,weareonlyinterestedinwholebananas,so we'dliketoroundoffanydecimalremainder. Asourdefinitionnowstands,anyvaluetotherightofthedecimalissimplydropped.Inotherwords,the resultis"truncated." 32%of: Result: 225=72.00 72exactlycorrect 226=72.32 72correct,roundeddown(truncated) 227=72.64 72truncated,notrounded Thereisaway,however,withanydecimalvalueof.5orhigher,toroundupwardstothenextwhole banana.WecoulddefinethewordR%,for"roundedpercent,"likethis:
:R%10*/5+10/;

sothatthephrase:
22732R%.

willgiveyou73,whichiscorrectlyroundedup. Noticethatwefirstdivideby10ratherthanby100.Thisgivesusanextradecimalplacetoworkwith,to whichwecanaddfive: Operation */ 5+ 10/ Stack Contents 2273210 726 731 73

Thefinaldivisionbytensetsthevaluetoitsrightfuldecimalposition.Tryitandsee.

Adisadvantagetothismethodofroundingisthatyouloseonedecimalplaceofrangeinthefinalresult; thatis,itcanonlygoashighas214,748,364ratherthan2,147,483,647.Butifthat'saproblem,youcan alwaysusedoublelengthnumbers,whichwe'llintroducelater,andstillbeabletoround.

SomePerspectiveonScaling
Let'sbackupforaminute.Takethesimpleproblemofcomputingtwothirdsof171.Basically,thereare twowaystogoaboutit. 1. Wecouldcomputethevalueofthefraction2/3bydividing2by3toobtaintherepeatingdecimal

.6666666,etc.Thenwecouldmultiplythisvalueby171.Theresultwouldbe113.9999999,etc., whichisnotquiterightbutwhichcouldberoundedupto114. 2. Wecouldmultiply171by2toget342.Thenwecoulddividethisby3toget114. Noticethatthesecondwayissimplerandmoreaccurate. Mostcomputerlanguagessupportthefirstway."Youcan'thaveafractionliketwothirdshangingaround insideacomputer,"itisbelieved,"youmustexpressitas.6666666,etc." Forthsupportsthesecondway.*/letsyouhaveafractionliketwothirds,asin:


17123*/

Nowthatwehavealittleperspective,let'stakeaslightlymorecomplicatedexample: Wewanttodistribute$150inproportiontotwovalues:
7,105? 5,145 ? 12,250150

Again,wecouldsolve theproblemthisway:
(7,105/12,250)x150

and
(5,145/12,250)x150

butforgreateraccuracyweshouldsay:
(7,105x150)/12,250

and
(5,145x150)/12,250

whichinForthiswritten:
710515012250*/.87ok

and
514515012250*/.63ok

Itcanbesaidthatthevalues87and63are"scaled"to7105and5145.Calculatingpercentages,aswedid earlier,isalsoaformofscaling.Forthisreason,*/iscalleda"scalingoperator." AnotherscalingoperatorinForthis*/MOD: Multiplies,thendivides (n1*n2/n3).Returnsthe */MOD (n1n2n3nremnresult) remainderandthequotient. Usesadoublelength intermediateresult.

We'llletyoudreamupagoodexamplefor*/MODyourself.

UsingRationalApproximations
Sofarwe'veonlyusedscalingoperationstoworkonrational numbers.Theycanalsobeused onrationalapproximationsofirrationalconstants,suchasorthe.Forexample,therealvalueofis:
3.14159265358979,etc.

buttostaywithintheboundsofsinglelengtharithmetic,wecouldwritethephrase:
3141610000*/

andgetaprettygoodapproximation. Nowwecanwriteadefinitiontocomputetheareaofacircle,givenitsradius.We'lltranslatetheformula:
r2

intoForth.Thevalueoftheradiuswillbeonthestack,soweDUPitandmultiplyitbyitself,thenstar slashtheresult:
:PIDUP*3141610000*/;

Tryitwithacirclewhoseradiusis10inches:
10PI.314ok

Butforevenmoreaccuracy,wemightwonderifthereisapairofintegersbeside3146and10000thatisa closerapproximationto.Surprisingly,thereis.Thefraction:
355113*/

isaccuratetomorethansixplacesbeyondthedecimal,asopposedtolessthanfourplaceswith31416. Ournewandimproveddefinition,then,is:
:PIDUP*355113*/;

Itturnsoutthatyoucanapproximatenearlyanyconstantbymanydifferentpairsofintegers,allnumbers lessthan32768,withanerrorlessthan108. HandyTableofRationalApproximationstoVariousConstants Number Approximation Error =3.141... =3.141... 2=1.414...


3

355/113 1068966896/340262731 19601/13860 18817/10864 28667/10564 22936/7253

8.5x108 1.0x1020 1.5x109 1.1x109 5.5x109 5.7x109

2=1.732... e=2.718...

10=3.162...

122=1.059...

26797/25293 2040/11103

1.0x109 1.1x108 1.0x107

log(2)/1.6384=0.183...

ln(2)/16.384=0.042... 485/11464 Here'salistoftheForthwordswe'vecoveredinthischapter: 1+ 1 2+ 2 2* 2/ ABS NEGATE MIN MAX (nn+1) (nn1) (nn+1) (nn2) (nn*2) (nn/2) (n|n|) (nn) (n1n2nmin) (n1n2nmax)

Addsone. Subtractsone. Addstwo. Subtractstwo. Multipliesbytwo(arithmeticleftshift). Dividesbytwo(arithmeticrightshift). Returnstheabsolutevalue. Changesthesign. Returnstheminimum. Returnsthemaximum. Takesavalueofftheparameterstackandpushesitontothe >R (n) returnstack. Takesavalueoffthereturnstackandpushesitontothe R> (n) parameterstack. I (n) Copiesthetopofthereturnstackwithoutaffectingit. R@ (n) Copiesthetopofthereturnstackwithoutaffectingit. J (n) Copiesthethirditemofthereturnstackwithoutaffectingit. Multiplies,thendivides(n1*n2/n3).Usesadoublelength */ (n1n2n3nresult) intermediateresult. Multiplies,thendivides(n1*n2/n3).Returnstheremainderand */MOD (n1n2n3nremnresult) thequotient.Usesadoublelengthintermediateresult. ReviewofTerms adoublelengthvaluewhichiscreatedtemporarilybyatwopartoperator,suchas*/, Doublelength sothatthe"intermediateresult"(theresultofthefirstoperation)isallowedtoexceed intermediateresult therangeofasinglelengthnumber,evenwhentheinitialargumentsandthefinal resultarenot. arithmeticwhichdealswithnumberswhichdonotthemselvesindicatethelocation Fixedpoint ofdecimalpoints.Instead,foranygroupofnumbers,theprogramassumesthe arithmetic locationofthedecimalpointorkeepsthedecimallocationforallsuchnumbersasa separatenumber. arithmeticwhichdealswithnumberswhichthemselvesindicatethelocationoftheir Floatingpoint decimalpoints.Theprogrammustbeabletointerpretthetruevalueofeach arithmetic individualnumberbeforeanyarithmeticcanbeperformed. Parameterstack inForth,theregionofmemorywhichservesascommongroundbetweenvarious operationstopassarguments(numbers,flags,orwhatever)fromoneoperationto

Returnstack

Scaling

another. inForth,aregionofmemorydistinctfromtheparameterstackwhichtheForth systemusestohold"returnaddresses"(tobediscussedinChap.9),amongother things.Theusermaykeepvaluesonthereturnstacktemporarily,undercertain conditions. theprocessofmultiplying(ordividing)anumberbyaratio.Alsoreferstothe processofmultiplying(ordividing)anumberbyapoweroftensothatallvaluesina setofdatamayberepresentedasintegerswiththedecimalpointsassumedtobein thesameplaceforallvalues.

ProblemsChapter5

1. TranslatethefollowingalgebraicexpressionintoaForthdefinition:
ab c

given(abc)[answer] 2. Giventhesefournumbersonthestack:
(67012345)

writeanexpressionthatprintsthelargestvalue.[answer] 3. In"calculatorstyle,"convertthefollowingtemperatures,usingtheseformulas:
oC=(oF32)/1.8 oK=oC+273 oF=(oCx1.8)+32

4. 5. 6. 7. 8.

(Fornow,expressallargumentsandresultsinwholedegrees.) 1. 0oFinCentigrade 212oFinCentigrade 32oFinCentigrade 16oCinFahrenheit 233oKinCentigrade [answer] NowdefinewordstoperformtheconversionsinProb.3.Usethefollowingnames:


F>CF>KC>FC>KK>FK>C

Testthemwiththeabovevalues.[answer]

6ThrowitforaLoop
InChap.4welearnedtoprogramthecomputertomake"decisions"bybranchingtodifferentpartsofa definitiondependingontheoutcomeofcertaintests.Conditionalbranchingisoneofthethingsthatmake computersasusefulastheyare. Inthischapter,we'llseehowtowritedefinitionsinwhichexecutioncanconditionallybranchbacktoan earlierpartofthesamedefinition,sothatsomesegmentwillrepeatagainandagain.Thistypeofcontrol constructiscalleda"loop."Theabilitytoperformloopsisprobablythemostsignificantthingthatmakes computersaspowerfulastheyare.Ifwecanprogramthecomputertomakeoutonepayrollcheck,we canprogramittomakeoutathousandofthem. Fornowwe'llwriteloopsthatdosimplethingslikeprintingnumbersatyourterminal.Inlaterchapters, we'lllearntodomuchmorewiththem.

DefiniteLoopsDO...LOOP
Onetypeofloopstructureiscalleda"definiteloop."You,theprogrammer,specifythenumberoftimes theloopwillloop.InForth,youdothisbyspecifyingabeginningnumberandanendingnumber(in reverseorder)beforethewordDO.Thenyouputthewordswhichyouwanttohaverepeatedbetweenthe wordsDOandLOOP.Forexample
:TEST100DOCR."Hello"LOOP;

willprintacarriagereturnand"Hello"tentimes,becausezerofromtenisten.
TEST Hello Hello Hello Hello Hello Hello Hello Hello Hello Hellook

LikeanIF...THENstatement,whichalsoinvolvesbranching,aDO...LOOPstatementmustbecontained withina(single)definition. Theteniscalledthe"limit"andthezeroiscalledthe"index."


FORMULA: limitindexDO...LOOP

HereiswhathappensinsideaDO...LOOP:

FirstDO

putstheindexandthelimitontheloopcontrolstack. Thenexecution proceeds tothewords insidetheloop, uptillthe word LOOP.

Iftheindexislessthanthelimit,LOOPreroutesexecutionbacktoDO,andaddsonetotheindex. Eventuallytheindexreachesten,andLOOPletsexecutionmoveontothenextwordinthedefinition.

RememberthattheForthwordIcopiesthetopoftheloopcontrolstackontotheparameterstack.You canuseItogetholdofthecurrentvalueoftheindexeachtimearound.Considerthedefinition
:DECADE100DOI.LOOP;

whichexecuteslikethis:
DECADE0123456789ok

Ofcourse,youcouldpickanyrangeofnumbers(withintherangeof2147483648to+2147483647):
:SAMPLE243250DOI.LOOP; SAMPLE250249248247246245244ok

Noticethatevennegativenumbersincreasebyoneeachtime.Thelimitisalwayshigherthantheindex. YoucanleaveanumberonthestacktoserveasanargumenttosomethinginsideaDOloop.Forinstance,
:MULTIPLICATIONSCR111DODUPI*.LOOPDROP;

willproducethefollowingresults:
7MULTIPLICATIONS 7142128354249566370ok

Herewe'resimplymultiplyingthecurrentvalueoftheindexbyseveneachtimearound.Noticethatwe havetoDUPtheseveninsidetheloopsothatacopywillbeavailableeachtimeandthatwehaveto DROPitafterwecomeoutoftheloop. Acompoundinterestproblemgivesustheopportunitytodemonstratesometrickierstackmanipulations insideaDOloop. Givenastartingbalance,say$1000,andaninterestrate,say6%,let'swriteadefinitiontocomputeand printatablelikethis:

10006COMPOUND YEAR1BALANCE1060 YEAR2BALANCE1124 YEAR3BALANCE1191 etc.

fortwentyyears. Firstwe'llloadR%,ourpreviouslydefinedwordfromChap.5,thenwe'lldefine
:COMPOUND(amtint) CRSWAP211DO."YEAR"I.3SPACES 2DUPR%+DUP."BALANCE".CR LOOP2DROP;

Eachtimethroughtheloop,wedoa2DUPsothatwealwaysmaintainarunningbalanceandan unchangedinterestrateforthenextgoround.Whenwe'refinallydone,we2DROPthem.

GettingIFfy
TheindexcanalsoserveasaconditionforanIFstatement.Inthiswayyoucanmakesomethingspecial happenoncertainpassesthroughtheloopbutnotonothers.Here'sasimpleexample:
:RECTANGLE2560DOI16MOD0=IFCRTHEN ."*" LOOP;

RECTANGLEwillprint256stars,andateverysixteenthstaritwillalsoperformacarriagereturnatyour terminal.Theresultshouldlooklikethis:
**************** **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** ****************

Andhere'sanexamplefromtheworldofnurseryrhymes.We'llletyoufigurethisoneout.
:POEMCR111DOI.."Little" I3MOD0=IF."indians"CRTHEN LOOP ."indianboys.";

NestedLoops
InthelastsectionwedefinedawordcalledMULTIPLICATIONS,whichcontainsaDO...LOOP.Ifwe wantedto,wecouldputMULTIPLICATIONSinsideanotherDO...LOOP,likethis:
:TABLECR111DOIMULTIPLICATIONSLOOP;

Nowwe'llgetamultiplicationtablethatlookslikethis:
12345678910 2468101214161820 36912151821242730 etc. 102030405060708090100

becausetheIintheouterloopsuppliestheargumentforMULTIPLICATIONS. YoucanalsonestDOloopsinsideoneanotherallinthesamedefinition:
:TABLECR111DO 111DOIJ*5U.RLOOP CRLOOP;

Noticethisphraseintheinnerloop:
IJ*

InChap.5wementionedthatthewordJcopiesthethirditemontheloopcontrolstackontothe parameterstack.Itsohappensthatinthiscasethethirditemontheloopcontrolstackistheindexofthe outerloop. Thusthephrase"IJ*"multipliesthetwoindexestocreatethevalueinthetable. Nowwhataboutthisphrase?


5U.R

Thisisnothingmorethanafancy.thatisusedtoprintnumbersintableformsothattheylineup vertically.Thefiverepresentsthenumberofspaceswe'vedecidedeachcolumninthetableshouldbe. Theoutputofthenewtablewilllooklikethis:


12345678910 2468101214161820 36912151821242730etc.

Eachnumbertakesfivespaces,nomatterhowmanydigitsitcontains.(U.Rstandsfor"unsignednumber print,rightjustified."Theterm"unsigned,"youmayrecall,meansyoucannotuseitfornegative numbers.)

+LOOP
Ifyouwanttheindextogoupbysomenumberotherthanoneeachtimearound,youcanusetheword

+LOOPinsteadofLOOP.+LOOPexpectsonthestackthenumberbywhichyouwanttheindexto change.Forexample,inthedefinition
:PENTAJUMPS500DOI.5+LOOP;

theindexwillgoupbyfiveeachtime,withthisresult:
PENTAJUMPS051015202530354045ok

whilein
:FALLING100DOI.1+LOOP;

theindexwillgodownbyoneeachtime,withthisresult:
FALLING012345678910ok

Theargumentfor+LOOP,whichiscalledthe"increment,"cancomefromanywhere,butitmustbeput onthestackeachtimearound.Considerthisexperimentalexample:
:INCCOUNTDOI.DUP+LOOPDROP;

Thereisnoincrementinsidethedefinition;instead,itwillhavetobeonthestackwhenINCCOUNTis executed,alongwiththelimitandindex.Watchthis: Stepupbyone:


150INCCOUNT01234ok

Stepupbytwo:
250INCCOUNT024ok

Stepdownbythree:
31010INCCOUNT10741258ok

Ournextexampledemonstratesanincrementthatchangeseachtimethroughtheloop.
:DOUBLING327671DOI.I+LOOP;

Heretheindexitselfisusedastheincrement(I+LOOP),sothatstartingwithone,theindexdoubles eachtime,likethis:
DOUBLING 1248163264128256512102420484096819216384ok

Noticethatinthisexamplewedon'teverwanttheargumentfor+LOOPtobezero,becauseif itwerewe'dnevercomeoutoftheloop.Wewouldhavecreatedwhatisknownasan"infinite

loop."

DOingitForthStyle
ThereareafewthingstorememberbeforeyougooffandwritesomeDOloopsofyourown. First,keepthissimpleguideinmind: Reasonsfortermination Executionmakesitsexitfromaloopwhen,ingoingup,theindexhasreachedorpassedthelimit.

Or,wheningoingdown,theindexhaspassedthelimitnotwhenithasmerelyreachedit. ButaDOloopalwaysexecutesatleastonce(thisexamplewillloopmillionsoftimesonatrueANS Forthsystem,sobeprepared):


:TEST10010DOI.1+LOOP; TEST10987...

Second,rememberthatthewordsDOandLOOParebranchingcommandsandthatthereforetheycan onlybeexecutedinsideadefinition.Thismeansthatyoucannotdesign/testyourloopdefinitionsin "calculatorstyle"unlessyousimulatetheloopyourself. Let'sseehowafledglingForthprogrammermightgoaboutdesign/testingthedefinitionofCOMPOUND (fromthefirstsectionofthischapter).Beforeaddingthe."messages,theprogrammermightbeginby jottingdownthisversiononapieceofpaper:


:COMPOUND(amtint) SWAP211DOI.2DUPR%+DUP.CRLOOP2DROP;

Theprogrammermightestthisversionattheterminal,using.or.Stochecktheresultofeachstep.The "conversation"mightlooklikethis:

AHandyHint HowtoCleartheStack Sometimesabeginnerwillunwittinglywritealoopwhichleavesawholelotofnumbersonthestack. Forexample


:FIVES1000DOI5.LOOP;

insteadof
:FIVES1000DOI5*.LOOP;

Ifyouseethishappentoanyone(surelyitwillneverhappentoyou!)andifyouseethebeginnertyping inanendlesssuccessionofdotstoclearthestack,recommendtypingin
XX

XXisnotaForthword,sothetextinterpreterwillexecutethewordABORT",whichamongotherthings clearsallstacks.Thebeginnerwillbeendlesslygrateful.

IndefiniteLoops
WhileDOloopsarecalleddefiniteloops,Forthalsosupports"indefinite"loops.Thistypeofloopwill repeatindefinitelyoruntilsomeeventoccurs.Astandardformofindefiniteloopis
BEGIN...UNTIL

TheBEGIN...UNTILlooprepeatsuntilaconditionis"true." Theuseageis
BEGINxxxfUNTIL

where"xxx"standsforthewordsthatyouwanttoberepeated,and"f"standsforaflag.Aslongasthe flagiszero(false),theloopwillcontinuetoloop,butwhentheflagbecomesnonzero(true),theloop willend.

AnexampleofadefinitionthatusesaBEGIN...UNTILstatementisonewementionedearlier,inour washingmachineexample:
:TILLFULLBEGIN?FULLUNTIL;

whichweusedinthehigherleveldefinition
:FILLFAUCETSOPENTILLFULLFAUCETSCLOSE;

?FULLwillbedefinedtoelectronicallycheckaswitchinthewashtubthatindicateswhenthewater reachesthecorrectlevel.Itwillreturnzeroiftheswitchisnotactivatedandaoneifitis.TILLFULL doesnothingbutrepeatedlymakethistestoverandover(millionsoftimespersecond)untiltheswitchis finallyactivated,atwhichtimeexecutionwillcomeoutoftheloop.Thenthe;inTILLFULLwill returntheflowofexecutiontotheremainingwordsinFILL,andthewaterfaucetswillbeturnedoff. Sometimesaprogrammerwilldeliberatelywanttocreateaninfiniteloop.InForth,thebestwayiswith theform


:BEGINxxx0UNTIL

Thezerosuppliesa"false"flagtothewordUNTIL,sotheloopwillrepeateternally. Beginnersusuallywanttoavoidinfiniteloops,becauseexecutingonemeansthattheylosecontrolofthe computer(inthesensethatonlythewordsinsidethelooparebeingexecuted).Butinfiniteloopsdohave

theiruses.Forinstance,thetextinterpreterispartofaninfiniteloopcalledQUIT,whichwaitsforinput, interpretsit,executesit,prints"ok,"thenwaitsforinputonceagain.Inmostmicroprocessorcontrolled machines,thehighestleveldefinitioncontainsaninfiniteloopthatdefinesthemachine'sbehavior. Anotherformofindefiniteloopisusedinthisformat:


BEGINxxfWHILEyyyREPEAT

Herethetestoccurshalfwaythroughtheloopratherthanattheend.Aslongasthetestistrue,theflow ofexecutioncontinueswiththerestoftheloop,thenreturnstothebeginningagain.Ifthetestisfalse,the loopends.

NoticethattheeffectofthetestisoppositethatintheBEGIN...UNTILconstruction.Heretheloop repeatswhilesomethingistrue(ratherthanuntilit'strue). Theindefiniteloopstructureslendthemselvesbesttocasesinwhichyou'rewaitingforsomeexternal eventtohappen,suchastheclosingofaswitchorthermostat,orthesettingofaflagbyanotherpartof anapplicationthatisrunningsimultaneously.Sofornow,insteadofgivingexamples,wejustwantyouto rememberthattheindefiniteloopstructuresexist.

TheIndefinitelyDefiniteLoop
Thereisawaytowriteadefiniteloopsothatitstopsshortoftheprescribedlimitifatruthcondition changesstate,byusingthewordLEAVE.LEAVEcausesthelooptoendimmediately. WatchhowwerewriteourearlierdefinitionofCOMPOUND.Insteadofjustlettingtheloopruntwenty times,let'sgetittoquitaftertwentytimesorassoonasourmoneyhasdoubled,whicheveroccursfirst. We'llsimplyaddthisphrase:
2000>IFLEAVETHEN

likethis:
:DOUBLED 61000211DOCR."YEAR"I2U.R 2DUPR%+DUP."BALANCE". DUP2000>IFCRCR."morethandoubledin" I.."years"LEAVE THEN LOOP2DROP;

Theresultwilllooklikethis:
DOUBLED YEAR1BALANCE1060 YEAR2BALANCE1124 YEAR3BALANCE1191 YEAR4BALANCE1262 YEAR5BALANCE1338 YEAR6BALANCE1418 YEAR7BALANCE1503 YEAR8BALANCE1593 YEAR9BALANCE1609

YEAR10BALANCE1790 YEAR11BALANCE1897 YEAR12BALANCE2011 morethandoubledin12yearsok

OneoftheproblemsattheendofthischapterasksyoutoreworkDOUBLEDsothatitexpectsthe parametersofinterestandstartingbalance,andcomputesbyitselfthedoublebalancethatLEAVEwill trytoreach. TwoHandyHints:PAGEandQUIT Togiveaneaterappearancetoyourloopoutputs(suchastablesandgeometricshapes),youmightwant toclearthescreenfirstbyusingthewordPAGE.YoucanexecutePAGEinteractivelylikethis:


PAGERECTANGLE

whichwillclearthescreenbeforeprintingtherectanglethatwedefinedearlierinthischapter.Oryou couldputPAGEatthebeginningofthedefinition.likethis:
:RECTANGLEPAGE2560DOI16MOD0=IFCRTHEN."*"LOOP;

Ifyoudon'twantthe"ok"toappearuponcompletionofexecution,usethewordQUIT.Again,youcan useQUITinteractively:
RECTANGLEQUIT

oryoucanmakeQUITthelastwordinthedefinition(justbeforethesemicolon). Here'salistoftheForthwordswe'vecoveredinthischapter: DO:(limitindex) DO...LOOP Setsupafiniteloop,giventheindexrange. LOOP:() DO:(limitindex) LikeDO...LOOPexceptaddsthevalueofn(instead DO...+LOOP +LOOP:() ofalwaysone)totheindex. LEAVE () Terminatetheloopimmediately. BEGIN...UNTIL UNTIL:(f) Setsupanindefiniteloopwhichendswhenfistrue. BEGINxxx Setsupanindefiniteloopwhichalwaysexecutesxxxand WHILEyyy WHILE:(f) alsoyyyiffistrue.Endswhenfisfalse. REPEAT Printstheunsignedsinglelengthnumber,rightjustified U.R (uwidth) withinthefieldwidth. Clearstheterminalscreenandresetstheterminal'scursor PAGE () totheupperlefthandcorner. Terminatesexecutionforthecurrenttaskandreturns QUIT () controltotheterminal. ReviewofTerms

aloopstructureinwhichthewordscontainedwithinthelooprepeatadefinitenumberof times.InForth,thisnumberdependsonthestartingandendingcounts(indexandlimit) whichareplacedonthestackpriortotheexecutionofthewordDO. aloopstructureinwhichthewordscontainedwithintheloopcontinuetorepeatwithoutany Infinite chanceofanexternaleventstoppingthem,exceptforclosingtheForthwindoworshutting loop downorresettingthecomputer. aloopstructureinwhichthewordscontainedwithintheloopcontinuetorepeatuntilsome Indefinite truthconditionchangesstate(truetofalseorfalsetotrue).InForth,theindefiniteloops loop beginwiththewordBEGIN. definite loop

ProblemsChapter6
InProblems1trough6,youwillcreateseveralwordswhichwillprintoutpatternsofstars(asterisks). ThesewillinvolvetheuseofDOloopsandBEGIN...UNTILloops. 1. FirstcreateawordnamedSTARSwhichwillprintoutnstarsonthesameline,givennonthe stack:
10STARS **********ok

[answer] 2. NextdefineBOXwhichprintsoutarectangleofstars,giventhewidthandheight(numberof lines),usingthestackorder(widthheight).


103BOX ********** ********** **********ok

[answer] 3. Nowcreateawordnamed\STARSwhichwillprintaskewedarrayofstars(arhomboid),given theheightonthestack.UseaDOloopand,forsimplicity,makethewidthaconstanttenstars.


3\STARS ********** ********** **********ok

[answer] 4. Nowcreateawordwhichslantsthestarstheotherdirection:callit/STARS.Itshouldtakethe heightasastackinputanduseaconstanttenwidth.UseaDOloop.[answer] 5. Nowredefinethislastword,usingaBEGIN...UNTILloop.[answer] 6. WriteadefinitioncalledDIAMONDSwhichwillprintoutthegivennumberofdiamondshapes,as showninthisexample.


2DIAMONDS * *** *****

******* ********* *********** ************* *************** ***************** ******************* ******************* ***************** *************** ************* *********** ********* ******* ***** *** * * *** ***** ******* ********* *********** ************* *************** ***************** ******************* ******************* ***************** *************** ************* *********** ********* ******* ***** *** *

[answer] 7. InourdiscussionofLEAVEwegaveanexamplewhichcomputed6%compoundinterestona startingbalanceof$1000for20yearsoruntilthebalancehaddoubled,whichevercamefirst. Rewritethisdefinitionsothatitwillexpectastartingbalanceandinterestrateonthestackand willLEAVEwhenthisstartingbalancehasdoubled.[answer] 8. Defineawordcalled**thatwillcomputeexponentialvalues,likethis:


72**.49ok

(sevensquared)
24**.16ok

(twotothefourthpower) Forsimplicity,assumepositiveexponentsonly(butmakesure**workscorrectlywhenthe exponentisonetheresultshouldbethenumberitself).[answer]

7ANumberofKindsofNumbers
Sofarwe'veonlytalkedaboutsignedsinglelengthnumbers.Inthischapterwe'llintroduce unsignednumbersanddoublelengthnumbers,aswellasawholepasselofnewoperators togoalongwiththem. Thischapterisdividedintwosections: Forbeginnersthissectionexplainshowacomputerlooksatnumbersandexactlywhatis meantbythetermssignedorunsignedandbysinglelengthordoublelength. ForeveryonethissectioncontinuesourdiscussionofForthforbeginnersandexpertsalike, andexplainshowForthhandlessignedandunsigned,singleanddoublelengthnumbers.

Section1ForBeginners
SignedversusUnsignedNumbers
Alldigitalcomputersstorenumbersinbinaryform.InForth,thestackis(normally)thirtytwobitswide (a"bit"isa"binarydigit").Belowisaviewofthirtytwobits,showingthevalueofeachbit:

Ifeverybitweretocontaina1,thetotalwouldbe4294967295.Thusin32bitswecanexpressanyvalue between0and4294967295.Becausethiskindofnumberdoesnotletusexpressnegativevalues,wecall itan"unsignednumber."Wehavebeenindicatingunsignednumberswiththeletter"u"inourtablesand stacknotations. Butwhataboutnegativenumbers?Inordertobeabletoexpressapositiveornegativenumber,weneed tosacrificeonebitthatwillessentiallyindicatesign.Thisbitistheoneatthefarleft,the"highorder bit."In31bitswecanexpressanumberashighas2147483647.Whenthesignbitcontains1,thenwecan goanequaldistancebackintothenegativenumbers.Thuswithin32bitswecanrepresentanynumber from2147483648to+2147483647.Thisshouldlookfamiliartoyouastherangeofasinglelength number,whichwehavebeenindicatingwiththeletter"n." Beforeweleaveyouwithanymisconceptions,we'dbetterclarifythewaynegativenumbersare represented.Youmightthinkthatit'sasimplematterofsettingthesignbittoindicatewhetheranumber ispositiveornegative,butitdoesn'tworkthatway. Toexplainhownegativenumbersarerepresented,let'sreturntodecimalnotationandexamineacounter suchasthatfoundonmanyWWWinternetpages. Let'ssaythecounterhasthreedigits,notfive.Asmorepeoplevisitthepage,thecounterwheelsturnand thenumberincreases.Startingonceagainwiththecounterat0,nowimagineyoubadlyregrethaving visitedthepageandcould"unvisit"itbyrollingthecounterwheelsbackward.Thefirstnumberyousee is999,whichis,inasense,thesameas1.Thenextnumberwillbe998,whichisthesameas2,andso on.

Therepresentationofsignednumbersinacomputerissimilar. Startingwiththenumber
0000,0000,0000,0000,0000,0000,0000,0000

andgoingbackwardsonenumber,weget
1111,1111,1111,1111,1111,1111,1111,1111(thirtytwoones)

whichstandsfor4294967295inunsignednotationaswellasfor1insignednotation.Thenumber
1111,1111,1111,1111,1111,1111,1111,1110

whichstandsfor4294967294inunsignednotation,represents2insignednotation. Here'sachartthatshowshowabinarynumberonthestackcanbeusedeitherasanunsignednumberor asasignednumber:

Thisbizarreseemingmethodforrepresentingnegativevaluesmakesitpossibleforthecomputertouse thesameproceduresforsubtractionasforaddition. Toshowhowthisworks,let'stakeaverysimpleproblem:


2 1

Subtractingonefromtwoisthesameasaddingtwoplusnegativeone.Insinglelengthbinarynotation, thetwolookslikethis:
0000,0000,0000,0000,0000,0000,0000,0010

whilenegativeonelookslikethis:
1111,1111,1111,1111,1111,1111,1111,1111

Thecomputeraddsthemupthesamewaywewouldonpaper;thatiswhenthetotalofanycolumn exceedsone,itcarriesaoneintothenextcolumn.Theresultlookslikethis:
0000,0000,0000,0000,0000,0000,0000,0010 +1111,1111,1111,1111,1111,1111,1111,1111 10000,0000,0000,0000,0000,0000,0000,0001

Asyoucansee,thecomputerhadtocarryaoneintoeverycolumnallthewayacross,andendedupwith aoneinthethirtythirdplace.Butsincethestackisonlythirtytwobitswide,theresultissimply
0000,0000,0000,0000,0000,0000,0000,0001

whichisthecorrectanswer,one. Weneedn'texplainhowthecomputerconvertsapositivenumbertonegative,butwewilltellyouthatthe processiscalled"two'scomplementing."

ArithmeticShift
Whilewe'reonthesubjectofhowacomputerperformscertainmathematicaloperations,we'llexplain whatismeantbythemysteriousphrasesbackinChap.5:"arithmeticleftshift"and"arithmeticright shift." AForthInstantReplay 2* 2/ LSHIFT RSHIFT (nn*2) (nn/2) (nun*2^u) (nn/2^u) Multipliesbytwo(arithmeticleftshift) Dividesbytwo(arithmeticrightshift) Logicalleftshiftoverupositions Logicalrightshiftoverupositions

Toillustrate,let'spickanumber,saysix,andwriteitinbinaryform:
0000,0000,0000,0000,0000,0000,0000,0110

(4+2).Nowlet'sshifteverydigitoneplacetotheleft,andputazerointhevacantplaceintheone's column.
0000,0000,0000,0000,0000,0000,0000,1100

Thisisthebinaryrepresentationoftwelve(8+4),whichisexactlydoubletheoriginalnumber.Thisworks inallcases,anditalsoworksinreverse.Ifyoushifteverydigitoneplacetotherightandfillthevacant digitwithazero,theresultwillalwaysbehalfoftheoriginalvalue. Inarithmeticshift,thesignbitdoesnotgetshifted.Thismeansthatapositivenumberwillstaypositive andanegativenumberwillstaynegativewhenyoudivideormultiplyitbytwo. Whenthehighorderbitshiftswithalltheotherbits,thetermis"logicalshift."InForthyoucandoa logicalshiftofupto32placeswiththewordsLSHIFTandRSHIFT. Theimportantthingforyoutoknowisthatmostcomputerscanshiftdigitsmuchmorequickythanthey cangothroughallthefolderolofnormaldivisionormultiplication.Whenspeediscritical,it'smuch bettertosay
2*

than
2*

anditmayevenbebettertosay
2*2*2*

than
8*

dependingonyourparticularmodelofcomputer,butthistopicisgettingtootechnicalforrightnow.

AnIntroductiontoDoublelengthNumbers
Adoublelengthnumberisjustwhatyouprobablyexpecteditwouldbe:anumberthatisrepresentedin sixtyfourbitsinsteadofthirtytwo.Signeddoublelengthnumbershavearangeof+/ 18,446,744,073,709,551,615. InForth,adoublelengthnumbertakestheplaceoftwosinglelengthnumbersonthestack.Operators like2DUPareusefuleitherfordoublelengthnumbersorforpairsofsinglelengthnumbers. Onemorethingweshouldexplain:tothenonForthspeakingcomputerworld,theterm"doubleword" meansa32bitvalue,orfourbytes.ButinForth,"word"meansadefinedcommand.Soinordertoavoid confusion,Forthprogrammersrefertoa32bitvalueasa"cell."Adoublelengthnumberrequirestwo cells.

OtherNumberBases
Asyougetmoreinvolvedinprogramming,you'llneedtoemployothernumberbasesbesidesdecimaland binary,particularlyhexadecimal(base16)andoctal(base8).Sincewe'llbetalkingaboutthesetwo numberbaseslateroninthischapter,wethinkyoumightlikeanintroductionnow. Computerpeoplebeganusinghexadecimalandoctalnumbersforonemainreason:computersthinkin binaryandhumanbeingshaveahardtimereadinglongbinarynumbers.Forpeople,it'smucheasierto convertbinarytohexadecimalthanbinarytodecimal,becausesixteenisanevenpoweroftwo,whileten isnot.Thesameistruewithoctal.Soprogrammersusuallyusehexoroctaltoexpressthebinary numbersthatthecomputerusesforthingslikeaddressesandmachinecodes.Hexadecimal(orsimply "hex")looksstrangeatfirstsinceitusesthelettersAthroughF. Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Let'stakeasinglelengthbinarynumber: Binary Hexadecimal 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 A 1011 B 1100 C 1101 D 1110 E 1111 F

00000000000000000111101110100001

Toconvertthisnumbertohexadecimal,wefirstsubdivideitintoeightunitsoffourbitseach:
|0000|0000|0000|0000|0111|1011|1010|0001|

thenconverteach4bitunittoitshexequivalent:
|0|0|0|0|7|B|A|1|

orsimply7BA1. Octalnumbersuseonlythenumerals0through7.Becausenowadaysmostcomputersusehexadecimal representation,we'llskipanoctalconversionexample. We'llhavemoreonconversionsinthesectiontitled"NumberConversions"laterinthischapter.

TheASCIICharacterSet
Ifthecomputerusesbinarynotationtostorenumbers,howdoesitstorecharactersandothersymbols? Binary,again,butinaspecialcodethatwasadoptedasanindustrystandardmanyyearsago.Thecodeis calledtheAmericanStandardCodeforInformationInterchange,usuallyabbreviatedASCII. Table71showseachASCIIcharacterinthesystem,itsISO6461983,ISO7bitcodedcharactersetfor informationinterchange,InternationalReferenceVersionequivalent(IRV),anditshexadecimalform. Thecharactersinthefirstcolumn(ASCIIcodes01Fhex)arecalled"controlcharacters"becausethey indicatethattheterminalorcomputerissupposedtodosomethinglikeringitsbell,backspace,starta newline,etc.Theremainingcharactersarecalled"printingcharacters"becausetheyproducevisible charactersincludingletters,thenumeralszerothroughnine,allavailablesymbolsandeventheblank space(hex20).TheonlyexceptionisDEL(hex7F)whichisasignaltothecomputertoignorethelast charactersent. InChap.1weintroducedthewordEMIT.EMITtakesanASCIIcodeonthestackandsendsittothe terminalsothattheterminalwillprintitasacharacter.Forexample,
65EMITAok 66EMITBok

etc.(We'reusingthedecimal,ratherthanthehex,equivalentbecausethat'swhatyourcomputerismost likelyexpectingrightnow.) WhynottestEMIToneveryprintingcharacter,"automatically"?


:PRINTABLES12732DOIEMITSPACELOOP;

PRINTABLESwillemiteveryprintablecharacterintheASCIIset;thatis,thecharactersfromdecimal 32todecimal126.(We'reusingtheASCIIcodesasourDOloopindex.)
PRINTABLES!"#$%&'()*+,./...ok

Table7.1Standardgraphiccharacters&Equivalents Hex ASCII Hex ASCII HexIRV ASCII HexIRV ASCII HexIRV ASCII HexIRV ASCII HexIRV ASCII HexIRV ASCII

00NUL 10DLE 01SOH 11DC1 02STX 12DC2 03ETX 13DC3 04EOT 14DC4 05ENQ 15NAK 06ACK 16SYN 07BEL 17ETB 08BS 09HT 0ALF 0BVT 0CFF 0DCR 0ESM 0FSI 18CAN 19EM 1ASUB 1BESC 1CFS 1DGS 1ERS 1FUS

20 21!! 22"" 23## 24$ 25%% 26&& 27'' 28(( 29)) 2A** 2B++ 2C,, 2D 2E.. 2F//

3000 3111 3222 3333 3444 3555 3666 3777 3888 3999 3A:: 3B;; 3C<< 3D== 3E>> 3F??

40@@ 41AA 42BB 43CC 44DD 45EE 46FF 47GG 48HH 49II 4AJJ 4BKK 4CLL 4DMM 4ENN 4FOO

50PP 51QQ 52RR 53SS 54TT 55UU 56VV 57WW 58XX 59YY 5AZZ 5B[[ 5C\\ 5D]] 5E^^ 5F

60`` 61aa 62bb 63cc 64dd 65ee 66ff 67gg 68hh 69ii 6Ajj 6Bkk 6Cll 6Dmm 6Enn 6Foo

70pp 71qq 72rr 73ss 74tt 75uu 76vv 77ww 78xx 79yy 7Azz 7B{{ 7C|| 7D}} 7E~~

Beginnersmaybeinterestedinsomeofthecontrolcharactersaswell.Forinstance,trythis:
7 EMITok

Youshouldhaveheardsomesortofbeep,whichisthevideoterminal'sversionofthemechanical printer's"typewriterbell." Othercontrolcharactersthataregoodtoknowincludethefollowing: name operation decimalequivalent BS backspace 8 LF linefeed 10 CR carriagereturn 13 Experimentwiththesecontrolcharacters,andseewhattheydo. ASCIIisdesignedsothateachcharactercanberepresentedbyonebyte.Thetablesinthisbookusethe letter"c"toindicateabytevaluethatisbeingusedasacodedASCIIcharacter.

BitLogic
ThewordsANDandOR(whichweintroducedinChap.4)use"bitlogic";thatis,eachbitistreated independently,andthereareno"carries"fromonebitplacetothenext.Forexample,let'sseewhat happenswhenweANDthesetwobinarynumbers:
0000,0000,0000,0000,0000,0000,1111,1111 0000,0000,0000,0000,0110,0101,1010,0010AND

0000,0000,0000,0000,0000,0000,1010,0010

Foranyresultbittobe"1,"therespectivebitsinbothargumentsmustbe"1."Noticeinthisexamplethat theargumentontopcontainsallzeroesinthehighorderbytesandallonesintheloworderbyte.The effectonthesecondargumentinthisexampleisthatthelowordereightbitsarekeptbutthehighorder twentyfourbitsareallsettozero.Herethefirstargumentisbeingusedasa"mask,"tomaskoutthe highorderbytesofthesecondargument. ThewordORalsousesbitlogic.Forexample,


1000,0100,0010,0001,1000,1001,0000,1001 0110,0110,0110,0110,0000,0011,1100,1000OR 1110,0110,0110,0111,1000,1011,1100,1001

A"1"ineitherargumentproducesa"1"intheresult.Again,eachcolumnistreatedseparately,withno carries. Bycleveruseofmasks,wecouldevenusea32bitvaluetohold32separateflags.Forexample,wecould findoutwhetherthisbit


1000,0100,0010,0001,1000,1001,0000,1001 ^

is"1"or"0"bymaskingoutallotherflags,likethis:
1000,0100,0010,0001,1000,1001,0000,1001 0000,0000,0000,0000,1000,0000,0000,0000AND 0000,0000,0000,0000,1000,0000,0000,0000

Sincethebitwas"1,"theresultis"true."Haditbeen"0,"theresultwouldhavebeen"0"or"false." Wecouldsettheflagto"0"withoutaffectingtheotherflagsbyusingthistechnique:
1000,0100,0010,0001,1000,1001,0000,1001 1111,1111,1111,1111,0111,1111,1111,1111AND 1000,0100,0010,0001,0000,1001,0000,1001 ^

Weusedamaskthatcontainsall"1"sexceptforthebitwewantedtosetto"0."Wecansetthesameflag backto"1"byusingthistechnique:
1000,0100,0010,0001,0000,1001,0000,1001 0000,0000,0000,0000,1000,0000,0000,0000OR 1000,0100,0010,0001,1000,1001,0000,1001 ^

Section2ForEverybody
SignedandUnsignedNumbers
BackinChap.1weintroducedthewordNUMBER.IfthewordFINDcan'tfindanincomingstringinthe dictionary,ithandsitovertothewordNUMBER.NUMBERthenattemptstoconvertthestringintoa numberexpressedinbinaryform.IfNUMBERsucceeds,itpushesthebinaryequivalentontothestack.

ThismeansthatNUMBERdoesnotcheckwhetherthenumberyou'veenteredasasinglelengthnumber exceedstheproperrange.Ifyouenteragiantnumber,NUMBERconvertsitbutonlysavestheleast significantthirtytwodigits. NUMBERdoesnotdoanyrangechecking.Becauseofthis,NUMBERcanconverteithersignedor unsignednumbers. Forinstance,ifyouenteranynumberbetween2147483648and4294967295,NUMBERwillconvertitas anunsignednumber.Anyvaluebetween2147483648and1willbestoredasatwo'scomplement integer. Thisisanimportantpoint:thestackcanbeusedtoholdeithersignedorunsignednumbers.Whethera binaryvalueisinterpretedassignedorunsigneddependsontheoperatorsthatyouapplytoit.Youdecide whichformisbetterforagivensituation,thensticktoyourchoice. We'veintroducedtheword.,whichprintsavalueonthestackasasignednumber:
4294967295.1ok

ThewordU.printsthebinaryrepresentationasanunsignednumber:
4294967295U.4294967295ok

U.

(u)

Printstheunsignedsinglelengthnumber,followedbyaspace.

Inthisbooktheletter"n"signifiessignedsinglelengthnumbers,whiletheletter"u"signifiesunsigned singlelengthnumbers.(We'vealreadyintroducedU.R,whichprintsanunsignedsinglelengthnumber rightjustifiedwithinagivencolumnwidth.) Hereisatableofadditionalwordsthatuseunsignednumbers: UM* UM/MO D U< (u1u2ud) (udu1u2u3) (u1u2f) Multipliestwosinglelengthnumbers.Returnsadoublelength result.Allvaluesareunsigned. Dividesadoublelengthbyasinglelengthnumber.Returnsa singlelengthquotientu2andremainderu3.Allvaluesare unsigned. Leavestrueifu1<u2,wherebotharetreatedassinglelength unsignedintegers.

NumberBases
WhenyoufirststartForth,allnumberconversionsusebaseten(decimal),forbothinputandoutput.

Youcaneasilychangethebasebyexecutingoneofthefollowingcommands: HEX OCTAL () () Setsthebasetosixteen. Setsthebasetoeight(availableonsomesystems).

DECIMAL

()

Returnsthebasetoten.

Whenyouchangethenumberbase,itsstayschangeduntilyouchangeitagain.Sobesuretodeclare DECIMALassoonasyou'redonewithanothernumberbase. Thesecommandsmakeiteasytodonumberconversionsin"calculatorstyle." Forexample,toconvertdecimal100intohexadecimal,enter


DECIMAL100HEX.64ok

ToconverthexFintodecimal(rememberyouarealreadyinhex),enter
0FDECIMAL.15ok

Makeitahabit,startingrightnow,toprecedeeachhexadecimalvaluewithazero,asin
0A0B0F

ThispracticeavoidsmixupswithpossiblypredefinedwordsasDEADBEEF,BAD,DECetc. Beginnerswhowanttoseewhatnumberslooklikeinbinarynotationmayenterthisdefinition:
:BINARY2BASE!;

ThenewwordBINARYwilloperatejustlikeOCTALorHEXbutwillchangethenumberbasetotwo. OnsystemswhichdonothavethewordOCTAL,experimentersmaydefine
:OCTAL8BASE!;

DoublelengthNumbers
Doublelengthnumbersprovidearangeof+/18,446,744,073,709,551,615.ANSForthsystemssupport doublelengthnumberstosomedegree.Thewaytoenteradoublelengthnumberontothestack(whether fromthekeyboardorfromafile)istopunctuateitwithoneofthesefivepunctuationmarks:
,./:

Forexample,whenyoutype
200,000

NUMBERrecognizesthecommaasasignalthatthisvalueshouldbeconvertedtodoublelength. NUMBERthenpushesthevalueontothestackastwoconsecutive"cells"(cellistheForthtermfor singlelength),thehighordercellontop.

TheForthwordD.printsadoublelengthnumberwithoutanypunctuation. D. (d) Printsthesigneddoublelengthnumber,followedbyonespace.

Inthisbook,theletter"d"standsforadoublelengthsignedinteger. Forexample,havingenteredadoublelengthnumber,ifyouwerenowtoexecuteD.,thecomputerwould respond:


D.200000ok

Noticethatallofthefollowingnumbersareconvertedinexactlythesameway:
12345.D.12345ok 123.45D.12345ok 12345D.12345ok 1/23/45D.12345ok 1:23:45D.12345ok

Butthisisnotthesame:
12345

becausethisvaluewouldbeconvertedasanegative,singlelengthnumber.(Thisistheonlycaseinwhich ahyphenisinterpretedasaminussignandnotaspunctuation.) Inthenextsectionwe'llshowyouhowtodefineyourownequivalentstoD.whichwillprintwhatever punctuationyouwantalongwiththenumber.

NumberFormattingDoublelengthUnsigned
$200.0012/31/8037284936:32:5998.6

Theabovenumbersrepresentthekindsofoutputyoucancreatebydefiningyourown"number formattingwords"inForth.Thissectionwillshowyouhow. Thesimplestnumberformattingdefinitionwecouldwritewouldbe


:UD.<##S#>TYPE;

UD.willprintanunsigneddoublelengthnumber.Thewords<#and#>(respectivelypronounced bracketnumberandnumberbracket)signifythebeginningandtheendofthenumberconversion process.Inthisdefinition,theentireconversionisbeingperformedbythesingleword#S(pronounced numbers).#SconvertsthevalueonthestackintoASCIIcharacters.Itwillonlyproduceasmanydigitsas arenecessarytorepresentthenumber;itwillnotproduceleadingzeroes.Butitalwaysproducesatleast onedigit,whichwillbezeroifthevaluewaszero.Forexample:


12,345UD.12345ok 12.UD.12ok 0.UD.0ok

ThewordTYPEprintsthecharactersthatrepresentthenumberatyourterminal.Noticethatthereisno spacebetweenthenumberandthe"ok."Togetaspace,youwouldsimplyaddthewordSPACE,likethis:
:UD.<##S#>TYPESPACE;

Nowlet'ssaywehaveaphonenumberonthestack,expressedasadoublelengthunsignedinteger.For example,wemayhavetypedin:
3728493

(rememberthatthehyphentellsNUMBERtotreatthisasadoublelengthvalue).Wewanttodefinea wordwhichwillformatthisvaluebackasaphonenumber.Let'scallit.PH#(for"printthephone number")anddefineitthus:


:.PH#<#####[CHAR]HOLD#S#>TYPESPACE;

Ourdefinitionof.PH#haseverythingthatUD.has,andmore.TheForthword# (pronouncednumber)producesasingledigitonly.Anumberformattingdefinitionisreversed fromtheorderinwhichthenumberwillbeprinted,sothephrase


####

producestherightmostfourdigitsofthephonenumber. Nowit'stimetoinsertthehyphen.Using[CHAR]wecangetthecodevalueofthisASCIIcharacteron thestack.TheForthwordHOLDtakesthisASCIIcodeandinsertsitintotheformattednumbercharacter string. Wenowhavethreedigitsleft.Wemightusethephrase


###

butitiseasiertosimplyusetheword#S,whichwillautomaticallyconverttherestofthenumberforus. IfyouaremorefamiliarwithASCIIcodesrepresentedinhexadecimalform,youcanusethisdefinition instead:


HEX:.PH#<#####02DHOLD#S#>TYPESPACE; DECIMAL

Eitherway,thecompileddefinitionwillbeexactlythesame. Nowlet'sformatanunsigneddoublelengthnumberasadate,inthefollowingform:
6/15/03

Hereisthedefinition:
:.DATE<###[CHAR]/HOLD##[CHAR]/HOLD#S#>TYPESPACE;

Let'sfollowtheabovedefinition,rememberingthatitiswritteninreverseorderfromthe output.Thephrase
##[CHAR]/HOLD

producestherightmosttwodigits(representingtheyear)andtherightmostslash.Thenextoccurenceof thesamephraseproducesthemiddletwodigits(representingtheday)andtheleftmostslash.Finally#S producestheleftmosttwodigits(representingthemonth). Wecouldhavejustaseasilydefined


##[CHAR]/HOLD

asitsownwordandusedthiswordtwiceinthedefinitionof.DATE. Sinceyouhavecontrolovertheconversionprocess,youcanactuallyconvertdifferentdigitsindifferent numberbases,afeaturewhichisusefulinformattingsuchnumbersashoursandminutes.Forexample, let'ssaythatyouhavethetimeinsecondsonthestack,andyouwantawordwhichwillprinthh:mm:ss. Youmightdefineitthisway:


:SEXTAL6BASE!; ::00#SEXTAL#DECIMAL[CHAR]:HOLD; :SEC<#:00:00#S#>TYPESPACE;

Wewillusetheword:00toformatthesecondsandminutes.Bothsecondsandminutesaremodulo60, sotherightdigitcangoashighasnine,buttheleftdigitcanonlygouptofive.Thusinthedefinitionof :00weconvertthefirstdigit(theoneontheright)asadecimalnumber,thengointo"sextal"(base6) andconverttheleftdigit.Finally,wereturntodecimalandinsertthecoloncharacter.After:00converts thesecondsandtheminutes,#Sconvertstheremaininghours. Forexample,ifwehad4500secondsonthestack,wewouldget


4500.SEC1:15:00ok

Table72summarizestheForthwordsthatareusedinnumberformatting.(Notethe"KEY"atthe bottom,whichservesasareminderofthemeaningsof"n,""d,"etc.) Table72NumberFormatting <# # #S cHOLD SIGN #> Beginsthenumberconversionprocess.Expectstheunsigneddoublelengthnumberon thestack. Convertsonedigitandputsitintoanoutputcharacterstring.#alwaysproducesa digitifyou'reoutofsignificantdigits,you'llstillgetazeroforevery#. Convertsthenumberuntiltheresultiszero.Alwaysproducesatleastonedigit(0ifthe valueiszero). Inserts,atthecurrentpositioninthecharacterstringbeingformatted,acharacterwhose ASCIIvalueisonthestack.HOLD(orawordwhichusesHOLD)mustbeused between<#and#>. Insertsaminussignintheoutputstringifthetopofstackisnegative.Usuallyused withROTimmediatelybefore#>foraleadingminussign. Completesnumberconversionbyleavingthecharactercountandaddressonthestack (thesearetheappropriateargumentsforTYPE). Stackeffectsfornumberformatting phrase <#...#> stack (udaddru) typeofarguments doublelengthunsigned doublelengthsigned(wherenisthehighordercellofd and|d|istheabsolutevalueofd). KEY n,n1,... singlelengthsigned

<#...ROTSIGN#> (n|d|addru)

d,d1,... doublelengthsigned u,u1,... singlelengthunsigned addr c address ASCIIcharactervalue

NumberFormattingSignedandSinglelength
Sofarwehaveformattedonlyunsigneddoublelengthnumbers.The<#...#>formexpectsonlyunsigned doublelengthnumbers,butwecanuseitforothertypesofnumbersbymakingcertainarrangementson thestack. Forinstance,let'slookatasimplifiedversionofthesystemdefinitionofD.(whichprintsasigned doublelengthnumber):
:D.TUCKDABS<##SROTSIGN#>TYPESPACE;

ThephraseROTSIGNinsertsaminusstringinthecharacterstringifthethirdnumberonthestackis negative.Wehavepreparedforthistestbyputtingacopyofthehighordercell(theonewiththesignbit) atthebottomofthestack,byusingthewordTUCK. Because<#expectsonlyunsigneddoublelengthnumbers,wemusttaketheabsolutevalueofour doublelengthsignednumber,withthewordDABS.Wenowhavetheproperarrangementofarguments onthestackforthe<#...#>phrase.Insomecases,suchasaccounting,wemaywantanegativenumberto bewritten


12345

inwhichcasewewouldplacethephraseROTSIGNattheleftsideofour<#...#>phrase,likethis:
<#ROTSIGN#S#>

Let'sdefineawordwhichwillprintasigneddoublelengthnumberwithadecimal pointandtwodecimalplacestotherightofthedecimal.Sincethisistheformmost oftenusedforwritingdollarsandcents,let'scallit.$anddefineitlikethis:

:.$TUCKDABS<###[CHAR].HOLD#SROTSIGN[CHAR]$HOLD#> TYPESPACE;

Let'stryit:
2000.00.$$2000.00ok

oreven
2,000.00.$$2000.00ok

Werecommendthatyousave.$,sincewe'llbeusingitinsomefutureexamples. Youcanalsowritespecialformatsforsinglelengthnumbers.Forexample,ifyouwanttousean unsignedsinglelengthnumber,simplyputazeroonthestackbeforetheword<#.Thiseffectively changesthesinglelengthnumberintoadoublelengthnumberwhichissosmallthatithasnothing(zero) inthehighordercell.

Toformatasignedsinglelengthnumber,againyoumustsupplyazeroasahighordercell.Butyoumust alsoleaveacopyofthesignednumberinthethirdstackpositionforROTSIGN,andyoumustleavethe absolutevalueofthenumberinthesecondstackposition.Thephrasetodoallthisis


DUPABS0

Herearethe"setup"phrasesthatareneededtoprintvariouskindsofnumbers: Numbertobeprinted doublelength,unsigned 63bit,plussign singlelength,unsigned 31bit,plussign (nothingneeded) TUCKDABS (tosavethesigninthethirdstackpositionforROTSIGN) 0 (togiveadummyhighorderpart) DUPABS0 (tosavethesign) Precede<#by

DoublelengthOperators
Hereisalistofdoublelengthmathoperators: D.R D+ D DNEGATE DMAX DMIN D= D0= D< DU< (dwidth) (d1d2dsum) (d1d2ddiff) (dd) (d1d2dmax) (d1d2dmin) (d1d2f) (df) (d1d2f) (ud1ud2f) Printsthesigneddoublelengthnumber,rightjustifiedwithin thefieldwidth. Addstwodoublelengthnumbers. Subtractstwodoublelengthnumbers(d1d2). Changesthesignofadoublelengthnumber. Returnsthemaximumoftwodoublelengthnumbers(d1d2). Returnstheminimumoftwodoublelengthnumbers(d1d2). Returnstrueifd1andd2areequal. Returnstrueifdiszero. Returnstrueifd1islessthand2. Returnstrueifud1islessthanud2.Bothnumbersare unsigned.

Theinitial"D"signifiesthattheseoperatorsmayonlybeusedfordoublelengthoperations,whereasthe initial"2,"asin2SWAPand2DUP,signifiesthattheseoperatorsmaybeusedeitherfordoublelength numbersorforpairsofnumbers.

Here'sanexampleusingD+:
200,000300,000D+D.500000ok

MixedlengthOperators
Here'satableofveryusefulForthwordswhichoperateonacombinationofsingleanddoublelength numbers: M+ (dndsum) Addsadoublelengthnumbertoasingle lengthnumber.Returnsadoublelength result. Divided1byn1,givingthesymmetric quotientn3andtheremaindern2.Input andoutputstackargumentsaresigned. Anambiguousconditionexistsifn1is zeroorifthequotientliesoutsidethe rangeofasinglecellsignedinteger. Divided1byn1,givingthefloored quotientn3andtheremaindern2.Input andoutputstackargumentsaresigned. Anambiguousconditionexistsifn1is zeroorifthequotientliesoutsidethe rangeofasinglecellsignedinteger. Multipliestwosinglelengthnumbers. Returnsadoublelengthresult.Allvalues aresigned.

SM/R (dn1n2n3) EM

FM/M (dn1n2n3) OD

M*

(n1n2dprod)

Multipliesadoublelengthnumberbya singlelengthnumberanddividesthe M*/ (d+n1n2dresult) triplelengthresultbyasinglelength number(d*n/n).Returnsadoublelength result.Allvaluesaresigned. Here'sanexampleusingM+:


200,0007M+D.200007ok

Or,usingM*/,wecanredefineourearlierversionof%sothatitwillacceptadoublelengthargument:
:%100M*/;

asin
200.5015%D.3007ok

Ifyouhaveloadedthedefinitionof.$wegaveinthelastHandyHint,youcanenter
200.5015%.$$30.07ok

WecanredefineourearlierdefinitionofR%togetaroundeddoublelengthresult,likethis:
:R%10M*/5M+10SM/REMNIP;

then
987.6515R%.$$30.08ok

NoticethatM*/istheonlyreadymadeForthwordwhichperformsmultiplicationonadoublelength argument.Tomultiply200,000by3,forinstance,wemustsupplya"1"asadummydenominator:
200,00031M*/D.600000ok

since
3 1

isthesameas3. M*/isalsotheonlyreadymadeForthwordthatperformsdivisionwithadoublelengthresult.Soto divide200,000by4,forinstance,wemustsupplya"1"asadummynumerator:


200,00014M*/D.50000ok

NumbersinDefinitions
Whenadefinitioncontainsanumber,suchas
:SCOREMORE20+;

thenumberiscompiledintothedictionaryinbinaryform,justasitlooksonthestack.

Thenumber'sbinaryvaluedependsonthenumberbaseatthetimeyoucompilethedefinition.For example,ifyouweretoenter
HEX:SCOREMORE14+;DECIMAL

thedictionarydefinitionwouldcontainthehexvalue14,whichisthesameasthedecimalvalue20 (16+4).Henceforth,SCOREMOREwillalwaysaddtheequivalentofthedecimal20tothevalueonthe stack,regardlessofthecurrentnumberbase. If,ontheotherhand,youweretoputthewordHEXinsidethedefinition,thenyouwouldchangethe numberbasewhenyouexecutethedefinition. Forexample,ifyouweretodefine:


DECIMAL :EXAMPLEHEX20.DECIMAL;

thenumberwouldbecompiledasthebinaryequivalentofdecimal20,sinceDECIMALwascurrentat compilationtime. Atexecutiontime,here'swhathappens:

EXAMPLE14ok

Thenumberisoutputinhexadecimal. Fortherecord,anumberthatappearsinsideadefinitioniscalleda"literal."(Unlikethewordsintherest ofthedefinitionwhichalludetootherdefinitions,anumbermustbetakenliterally.) HereisalistoftheForthwordswe'vecoveredinthischapter: Unsignedoperators U. UM* (u) (u1u2ud) Printstheunsignedsinglelengthnumber,followedbyonespace. Multipliestwosinglelengthnumbers.Returnsadoublelengthresult. Allvaluesareunsigned. Dividesadoublelengthbyasinglelengthnumber.Returnsasingle lengthquotientandremainder.Allvaluesareunsigned. Leavestrueifu1<u2,wherebotharetreatedassinglelengthunsigned integers. Numberbases HEX OCTAL DECIMAL () () () Setsthebasetosixteen. Setsthebasetoeight(availableonsomesystems). Returnsthebasetoten. Numberformattingoperators <# # #S Beginsthenumberconversionprocess.Expectstheunsigneddoublelengthnumberonthe stack. Convertsonedigitandputsitintoanoutputcharacterstring.#alwaysproducesadigitif you'reoutofsignificantdigits,you'llstillgetazeroforevery#. Convertsthenumberuntiltheresultiszero.Alwaysproducesatleastonedigit(0ifthevalue iszero).

UM/MO (udu1u2u3) D U< (u1u2f)

Inserts,atthecurrentpositioninthecharacterstringbeingformatted,acharacterwhose cHOLD ASCIIvalueisonthestack.HOLD(orawordwhichusesHOLD)mustbeusedbetween<# and#>. SIGN #> Insertsaminussignintheoutputstringifthetopofstackisnegative.UsuallyusedwithROT immediatelybefore#>foraleadingminussign. Completesnumberconversionbyleavingthecharactercountandaddressonthestack(these aretheappropriateargumentsforTYPE). Stackeffectsfornumberformatting phrase <#...#> stack (daddru) typeofarguments doublelengthunsigned doublelengthsigned(wherenisthehighordercellofd and|d|istheabsolutevalueofd).

<#...ROTSIGN#> (n|d|addru)

Doublelengthoperators

D+ D DMAX DMIN D= D0= D< DU< D.R

(d1d2dsum) Addstwodoublelengthnumbers. (d1d2ddiff) Subtractstwodoublelengthnumbers(d1d2). Changesthesignofadoublelengthnumber. (d1d2dmax) Returnsthemaximumoftwodoublelengthnumbers(d1d2). (d1d2dmin) Returnstheminimumoftwodoublelengthnumbers(d1d2). (d1d2f) (df) (d1d2f) (ud1ud2f) (dwidth) Returnstrueifd1andd2areequal. Returnstrueifdiszero. Returnstrueifd1islessthand2. Returnstrueifud1islessthanud2.Bothnumbersareunsigned. Printsthesigneddoublelengthnumber,rightjustifiedwithinthefield width. Mixedlengthoperators Addsadoublelengthnumbertoasinglelengthnumber.Returnsa doublelengthresult. Divided1byn1,givingthesymmetricquotientn3andtheremainder n2.Inputandoutputstackargumentsaresigned.Anambiguous conditionexistsifn1iszeroorifthequotientliesoutsidetherange ofasinglecellsignedinteger. Divided1byn1,givingtheflooredquotientn3andtheremainder n2.Inputandoutputstackargumentsaresigned.Anambiguous conditionexistsifn1iszeroorifthequotientliesoutsidetherange ofasinglecellsignedinteger. Multipliestwosinglelengthnumbers.Returnsadoublelength result.Allvaluesaresigned.

DNEGATE (dd)

M+

(dndsum)

SM/REM (dn1n2n3)

FM/MOD (dn1n2n3)

M* M*/

(n1n2dprod)

Multipliesadoublelengthnumberbyasinglelengthnumberand (d+n1n2dresult) dividesthetriplelengthresultbyasinglelengthnumber(d*n/n). Returnsadoublelengthresult.Allvaluesaresigned. KEY

n,n1,... singlelengthsigned d,d1,... doublelengthsigned u,u1,... singlelengthunsigned addr c address ASCIIcharactervalue ReviewofTerms Arithmeticleftand theprocessofshiftingallbitsinanumber,exceptthesignbit,totheleftorright,in rightshift effectdoublingorhalvingthe(assumedsigned)number,respectively.

Logicalleftand rightshift

theprocessofshiftingallbitsinanumber,includingthesignbit,totheleftor right,ineffectdoublingorhalvingthe(assumedunsigned)number,respectively. astandarizedsystemofrepresentinginput/outputcharactersasbytevalues. ASCII AcronymforAmericanStandardCodeforInformationInterchange.(Pronounced askkey) Binary numberbase2. Byte thestandardtermforan8bitvalue. Cell theForthtermforasinglecellvalue. Decimal numberbase10. Hexadecimal numberbase16. ingeneral,anumberofsymbolwhichrepresentsonlyitself;inForth,anumber Literal thatappearsinsideadefinition. avaluewhichcanbe"superimposed"overanother,hidingcertainbitsand Mask revealingonlythosebitsthatweareinterestedin. theprocessofprintinganumber,usuallyinaspecialformsuchas3/13/03or Numberformatting $47.93. Octal numberbase8. Signbithighorder thebitwhich,forasignednumber,indicateswhetheritispositiveornegativeand, bit foranunsignednumber,representsthebitofthehighestmagnitude. foranynumber,thenumberofequalabsolutevaluebutoppositesign.Tocalculate Two'scomplement 104,thecomputerfirstproducesthetwo'scomplementof4,(i.e.,4),then computes10+(4). Unsignednumber anumberwhichisassumedtobepositive. Unsignedsingle anintegerwhichfallswithintherangeof0to2147483647. lengthnumber Word InForth,adefineddictionaryentry,elsewhere,atermfora16bitvalue. producesaquotientqandaremainderrbydividingoperandabyoperandb. Integerdivision Divisionoperationsreturnq,r,orboth.Theidentityb*q+r=aholdsforallaand b. isintegerdivisioninwhichtheremaindercarriesthesignofthedivisororiszero, Flooreddivision andthequotientisroundedtoitsarithmeticfloor. isintegerdivisioninwhichtheremaindercarriesthesignofthedividendoriszero Symmetricdivision andthequotientisthemathematicalquotient"roundedtowardszero"or "truncated".

ProblemsChapter7
1. VeronicaWainwrightcouldn'tremembertheupperlimitforasignedsinglelengthnumber,and shehadnobooktoreferto,onlyaForthterminal.SoshewroteadefinitioncalledNMAX,using

aBEGIN...UNTILloop.Whensheexecutedit,shegot
2147483647ok

Whatwasherdefinition?[answer] 2. SinceyounowknowthatANDandORemploybitlogic,explainwhythefollowingexamplemust useORinsteadof+:


:MATCHhumoroussensitiveAND artlovingmusiclovingORAND smoking0=AND IF."Ihavesomeoneyoushouldmeet"THEN;

3. Writeadefinitionthat"rings"yourterminal'sbellthreetimes.Makesurethatthereisenoughofa delaybetweenthebellssothattheyaredistinguishable.Eachtimethebellrings,theword "BEEP"shouldappearontheterminalscreen.[answer] a. Rewritethetemperatureconversiondefinitionswhichyoucreatedfortheproblemsin Chap.5.Thistimeassumethattheinputandresultingtemperaturesaretobedouble lengthsignedintegerswhicharescaled(i.e.,multiplied)byten.Forexample,if10.5 degreesisentered,itisa32bitintegerwithavalueof105.[answer] 4. Writeaformattedoutputwordnamed.DEGwhichwilldisplayadoublelengthsignedinteger scaledbytenasastringofdigits,adecimalpoint,andonefractionaldigit. Forexample:
12.3.DEG 12.3ok

[answer] 5. Solvethefollowingconversions: 0.0oFinCentigrade 212.0oFinCentigrade 20.0oFinCentigrade 16.0oCinFahrenheit 40.0oCinFahrenheit 100.0oKinCentigrade 100.0oKinFahrenheit 233.0oKinCentigrade 233.0oKinFahrenheit a. Writearoutinewhichevaluatesthequadraticequation
7x2+20x+5

givenx,andreturnsadoublelengthresult. 6. Howlargeanxwillworkwithoutoverflowingsixtyfourbitsasasignednumber? 7. Writeawordwhichprintsthenumbers0through16(decimal)indecimal,hexadecimal,and binaryforminthreecolumns.E.g.,


DECIMAL0HEX0BINARY0 DECIMAL1HEX1BINARY1

DECIMAL2HEX2BINARY10 ... DECIMAL16HEX10BINARY10000 [answer]

8. Ifyouenter
..

(twoperiodsnotseparatedbyaspace)andthesystemresponds"ok,"whatdoesthistellyou? [answer] 9. Writeadefinitionforaphonenumberformattingwordthatwillalsoprinttheareacodewitha slashifandonlyifthenumberincludesanareacode.E.g.,


5551234.PH#5551234ok 213/3728493.PH#213/3728493ok [answer]

8Variables,Constants,andArrays
Aswehaveseenthroughouttheprevioussevenchapters,Forthprogrammersusethestacktostore numberstemporarilywhiletheyperformcalculationsortopassargumentsfromonewordtoanother. Whenprogrammersneedtostorenumbersmorepermanently,theyusevariablesandconstants. Inthischapter,we'lllearnhowForthtreatsvariablesandconstants,andintheprocesswe'llseehowto directlyaccesslocationsinmemory.

Variables
Let'sstartwithanexampleofasituationinwhichyou'dwanttouseavariabletostoretheday'sdate. Firstwe'llcreateavariablecalledDATE.Wedothisbysaying
VARIABLEDATE

Iftodayisthetwelfth,wenowsay
12DATE!

thatis,weputtwelveonthestack,thengivethenameofthevariable,thenfinallyexecutetheword!, whichispronouncedstore.ThisphrasestoresthenumbertwelveintothevariableDATE. Conversely,wecansay


DATE@

thatis,wecannamethevariable,thenexecutetheword@,whichispronouncedfetch.Thisphrase fetchesthetwelveandputsitonthestack.Thusthephrase
DATE@.12ok

printsthedate. Tomakematterseveneasier,thereisaForthwordwhosedefinitionisthis:
:?@.;

Soinsteadof"DATEfetchdot,"wecansimplytype
DATE?12ok

ThevalueofDATEwillbetwelveuntilwechangeit.Tochangeit,wesimplystoreanewnumber
13DATE!ok DATE?13ok

Conceivablywecoulddefineadditionalvariablesforthemonthandyear:
VARIABLEDATEVARIABLEMONTHVARIABLEYEAR

thendefineawordcalled!DATE(for"storethedate")likethis:
:!DATEYEAR!DATE!MONTH!;

tobeusedlikethis:
73103!DATEok

thendefineawordcalled.DATE(for"printthedate")likethis:
:.DATEMONTH?DATE?YEAR?;

YourForthsystemalreadyhasanumberofvariablesdefined;oneiscalledBASE.BASEcontainsthe numberbasethatyou'recurrentlyworkingin.Infact,thedefinitionofHEXandDECIMAL(and OCTAL,ifyoursystemhasit)aresimply


:DECIMAL10BASE!; :HEX16BASE!; :OCTAL8BASE!;

YoucanworkinanynumberbasebysimplystoringitintoBASE.
ForExperts Athreelettercodesuchasanairportterminalname,canbestoredasasinglelengthunsignednumberinbase 36.Forexample: :ALPHA36BASE!;ok ALPHAok ZAPU.ZAPok

Somewhereinthedefinitionsofthesystemwordswhichperforminputandoutputnumberconversions, youwillfindthephrase
BASE@

becausethecurrentvalueofBASEisusedintheconversionprocess.Thusasingleroutinecanconvert numbersinanybase.Thisleadsustomakeaformalstatementabouttheuseofvariables:

InForth,variablesareappropriateforanyvaluethatisusedinsidea definitionwhichmayneedtochangeatanytimeafterthedefinitionhas alreadybeencompiled.

ACloserLookatVariables
WhenyoucreateavariablesuchasDATEbyusingthephrase
VARIABLEDATE

youarereallycompilinganewword,calledDATE,intothedictionary.Asimplifiedviewwouldlooklike theviewbelow. 4 D A T E DATEislikeanyotherwordinyourdictionaryexceptthatyoudefineditwith thewordVARIABLEinsteadoftheword:.Asaresult,youdidn'thaveto definewhatyourdefinitionwoulddo,thewordVARIABLEitselfspellsout whatissupposedtohappen.Andhereiswhathappens: Whenyousay


12DATE!

instructioncode appropriatefor variables spaceforthe actualvalue tobestored

Twelvegoesontothestack,afterwhichthetextinterpreterlooksupDATEin thedictionaryand,findingit,pointsitouttoEXECUTE.

EXECUTEexecutesavariablebycopyingtheaddressofthevariable's"empty"cell(where thevaluewillgo)ontothestack. Theword!takestheaddress(ontop)andthevalue(underneath),andstoresthevalueinto thatlocation.Whatevernumberusedtobeatthataddressisreplacedbythenewnumber. (Torememberwhatordertheargumentsbelongin,thinkofsettingdownyourparcel,thenstickingthe addresslabelontop.) Theword@expectsoneargumentonly:anaddress,whichinthiscaseissuppliedbythe nameofthevariable,asin


DATE@

Usingthevalueonthestackasanaddress,theword@pushesthecontentsofthatlocationontothestack, "dropping"theaddress.(Thecontentsofthelocationremainintact.)

UsingaVariableasaCounter
InForth,avariableisidealforkeepingacountofsomething.Toreuseoureggpackerexample,wemight keeptrackofhowmanyeggsgodowntheconveyorbeltinasingleday.(Thisexamplewillworkatyour terminal,soenteritaswego.) Firstwecandefine
VARIABLEEGGS

tokeepthecountin.Tostartwithacleanslateeverymorning,wecouldstoreazerointoEGGSby executingawordwhosedefinitionlookslikethis:
:RESET0EGGS!;

Thensomewhereinoureggpackingapplication,wewoulddefineawordwhichexecutesthefollowing phraseeverytimeaneggpassesanelectriceyeontheconveyor:
1EGGS+!

Theword+!addsthegivenvaluetothecontentsofthegivenaddress.(Itdoesn'tbothertotellyouwhat thecontentsare.)Thusthephrase
1EGGS+!

incrementsthecountofeggsbyone.Forpurposesofillustration,let'sputthisphraseinsideadefinition likethis:
:EGG1EGGS+!;

Attheendoftheday,wewouldsay
EGGS?

tofindouthowmanyeggswentbysincemorning. Let'stryit:
RESETok EGGok EGGok EGGok EGGS?3ok

Here'sareviewofthewordswe'vecoveredinthechaptersofar: VARIABLExxx ! @ ? +! () Createsavariablenamedxxx;thewordxxxreturnsitsaddress xxx:(addr) whenexecuted. (naddr) (addrn) (addr) (naddr) Storesasinglelengthnumberintotheaddress. Replacestheaddresswithitscontents. Printsthecontentsoftheaddress,followedbyonespace. Addsasinglelengthnumbertothecontentsoftheaddress.

Constants
Whilevariablesarenormallyusedforvaluesthatmaychange,constants areusedforvaluesthatwon'tchange.InForth,wecreateaconstantand setitsvalueatthesametime,likethis:
220CONSTANTLIMIT

instructioncode appropriatefor constants 220

HerewehavedefinedaconstantnamedLIMIT,andgivenitthevalue220.Nowwecanusetheword LIMITinplaceofthevalue,likethis:
:?TOOHOTLIMIT>IF."Dangerreduceheat"THEN;

Ifthenumberonthestackisgreaterthan220,thenthewarningmessagewillbeprinted. Noticethatwhenwesay
LIMIT

wegetthevalue,nottheaddress.Wedon'tneedthe"fetch." Thisisanimportantdifferencebetweenvariablesandconstants.Thereasonforthedifferenceisthatwith variables,weneedtheaddresstohavetheoptionoffetchingorstoring.Withconstantswealwayswant thevalue;weabsolutelyneverstore.(Ifyoureallyneedtostoreanewvalueintoa"constant",youshould useaVALUE.) Oneuseforconstantsistonameahardwareaddress.Forexample,amicroprocessorcontrolledportable cameraapplicationmightcontainthisdefinition:


:PHOTOGRAPHSHUTTEROPENTIMEEXPOSESHUTTERCLOSE;

HerethewordSHUTTERhasbeendefinedasaconstantsothatexecutionofSHUTTERreturnsthe hardwareaddressofthecamera'sshutter.Itmight,forexample,bedefined:
HEX FFFF3E27CONSTANTSHUTTER DECIMAL

ThewordsOPENandCLOSEmightbedefinedsimplyas
:OPEN1SWAP!; :CLOSE0SWAP!;

sothatthephrase
SHUTTEROPEN

writesa"1"totheshutteraddress,causingtheshuttertoopen. Herearesomesituationswhenit'sgoodtodefinenumbersasconstants: 1. Whenit'simportantthatyoumakeyourapplicationmorereadable.OneoftheelementsofForth styleisthatdefinitionsshouldbeselfdocumenting,asisthedefinitionofPHOTOGRAPHabove. 2. Whenit'smoreconvenienttouseanameinsteadofthenumber.Forexample,ifyouthinkyou mayhavetochangethevalue(because,forinstance,thehardwaremightgetchanged)youwill onlyhavetochangethevalueonceinthefilewheretheconstantisdefinedthenrecompileyour application. 3. (OnlytrueforlesssophisticatedForthcompilers)Whenyouareusingthesamevaluemanytimes inyourapplication.Inthecompiledformofadefinition,referencetoaconstantrequiresless memoryspace. CONSTANTxxx (n) Createsaconstantnamedxxxwiththevaluen;thewordxxxreturnsn xxx:(n) whenexecuted.

DoublelengthVariablesandConstants
Youcandefineadoublelengthvariablebyusingtheword2VARIABLE.Forexample,
2VARIABLEDATE

NowyoucanusetheForthwords2!(pronouncedtwostore)and2@(pronouncedtwofetch)toaccess thisdoublelengthvariable.Youcanstoreadoublelengthnumberintoitbysimplysaying
800,000DATE2!

andfetchitbackwith
DATE2@D.800000ok

Oryoucanstorethefullmonth/date/yearintoit,likethis:
7/17/03DATE2!

andfetchitbackwith
DATE2@.DATE7/17/03ok

assumingthatyou'veloadedtheversionof.DATEwegaveinthelastchapter. YoucandefineadoublelengthconstantbyusingtheForthword2CONSTANT,likethis:
200,0002CONSTANTAPPLES

NowthewordAPPLESwillplacethedoublelengthnumberonthestack.
APPLESD.200000ok

Ofcourse,wecando:
400,0002CONSTANTMUCH :MUCHMORE200,000D+MUCHD+;

inordertobeabletosay
APPLESMUCHMORED.800000ok

Astheprefix"2"remindsus,wecanalsouse2CONSTANTtodefineapairofsinglelengthnumbers. Thereasonforputtingtwonumbersunderthesamenameisamatterofconvenienceandofsavingspace inthedictionary. Asanexample,recall(fromChap.5)thatwecanusethephrase


355113*/

tomultiplyanumberbyacrudeapproximationof.Wecouldstorethesetwointegersasa2CONSTANT asfollows:
3551132CONSTANTPI

thensimplyusethephrase
PI*/

asin
10000PI*/.31415ok

Hereisareviewofthedoublelengthdatastructurewords: (d) xxx:(d) () 2VARIABLExxx xxx:(addr) 2CONSTANTxxx 2! 2@ (daddr) (addrd) Createsadoublelengthconstantnamedxxxwiththevalued; thewordxxxreturnsdwhenexecuted. Createsadoublelengthvariablenamedxxx;thewordxxx returnsitsaddresswhenexecuted. Storesadoublelengthnumberintotheaddress. Returnsthedoublelengthcontentsoftheaddress.

Arrays
Asyouknow,thephrase
VARIABLEDATE

A code

createsadefinitionwhichconceptuallylookslikethatattheright. Nowifyousay
1CELLSALLOT

roomfora singlelengthvalue

anadditionalcellisallottedinthedefinition,likethis: 4 D A T E Theresultisthesameasifyouhadused2VARIABLE.Bychangingthe argumenttoALLOT,however,youcandefineanynumberofvariablesunder thesamename.Suchagroupofvariablesiscalledan"array." Forexample,let'ssaythatinourlaboratory,wehavenotjustone,butfive burnersthatheatvariouskindsofliquids. Wecanmakeourword?TOOHOTcheckthatallfiveburnershavenot exceededtheirindividuallimitifwedefineLIMITusinganarrayratherthan aconstant. Let'sgivethearraythenameLIMITS,likethis:
VARIABLELIMITS4CELLSALLOT

code roomfora singlelength value ditto

Thephrase"4CELLSALLOT"givesthearrayanextra 6 fourcells(fivecellsinall). Supposewewantthelimitforburner0tobe220.We canstorethisvaluebysimplysaying


220LIMITS!

S address 3160 3164 3168 316C 3170

code roomforburner0'slimit roomforburner1'slimit roomforburner2'slimit roomforburner3'slimit roomforburner4'slimit

becauseLIMITSreturnstheaddressofthefirstcellin thearray.Supposewewantthelimitforburner1tobe

340.Wecanstorethisvaluebyadding1CELLStotheaddressoftheoriginalcell,likethis:
340LIMITS1CELLS+!

Wecanstorelimitsforburners2,3,and4byaddingthe"offsets"2CELLS,3CELLS,and4CELLS, respectively,totheoriginaladdress.Wecandefinetheconvenientword
:LIMIT(burner#addr)CELLSLIMITS+;

totakeaburnernumberonthestackandcomputeanaddressthatreflectstheappropriateoffset. Nowifwewantthevalue170tobethelimitforburner2,wesimplysay
1702LIMIT!

orsimilarly,wecanfetchthelimitforburner2withthephrase
2LIMIT?170ok

ThistechniqueincreasestheusefulnessofthewordLIMIT,sothatwecanredefine?TOOHOTas follows:
:?TOOHOT(tempburner#) LIMIT@>IF."Dangerreduceheat"THEN;

whichworkslikethis:
2100?TOOHOTok 2300?TOOHOTDangerreduceheatok 3001?TOOHOTok 3501?TOOHOTDangerreduceheatok

etc.

AnotherExampleUsinganArrayforCounting
Meanwhile,backattheeggranch: Here'sanotherexampleofanarray.Inthisexample,eachelementofthearrayisusedasaseparate counter.Thuswecankeeptrackofhowmanycartonsof"extralarge"eggsthemachinehaspacked,how many"large,"andsoforth. RecallfromourpreviousdefinitionofEGGSIZE(inChap.4)thatweusedfourcategoriesofacceptable eggs,plustwocategoriesof"badeggs."
0CONSTANTREJECT 1CONSTANTSMALL 2CONSTANTMEDIUM 3CONSTANTLARGE 4CONSTANTEXTRALARGE 5CONSTANTERROR

Solet'screateanarraythatissixcellslong:
VARIABLECOUNTS5CELLSALLOT

Thecountswillbeincrementedusingtheword+!,sowemustbeabletosetalltheelementsofthearray tozerobeforewebegincounting.Thephrase
COUNTS6CELLS0FILL

willfill6cells,startingattheaddressofCOUNTS,withzeros.IfyourForthsystemincludestheword ERASE,it'sbettertouseitinthissituation.ERASEfillsthegivennumberofbyteswithzeroes.Useit likethis:


COUNTS6CELLSERASE

FILL (addrnb) Fillsnbytesofmemory,beginningattheaddress,withvalueb. ERASE (addrn) Storeszeroesintonbytesofmemory,beginningattheaddress. Forconvenience,wecanputthephraseinsideadefinition,likethis:


:RESETCOUNTS6CELLSERASE;

Nowlet'sdefineawordwhichwillgiveustheaddressofoneofthecounters,dependingonthecategory numberitisgiven(0through5),likethis:
:COUNTERCELLSCOUNTS+;

andanotherwordwhichwilladdonetothecounterwhosenumberisgiven,likethis:
:TALLYCOUNTER1SWAP+!;

The"1"servesastheincrementfor+!,andSWAPputstheargumentsfor+!intheordertheybelong,i.e., (naddr). Now,forinstance,thephrase


LARGETALLY

willincrementthecounterthatcorrespondstolargeeggs. Nowlet'sdefineawordwhichconvertstheweightperdozenintoacategorynumber:
:CATEGORY(weightcategory) DUP18<IFREJECTELSE DUP21<IFSMALLELSE DUP24<IFMEDIUMELSE DUP27<IFLARGEELSE DUP30<IFEXTRALARGEELSE ERROR THENTHENTHENTHENTHENNIP;

(Bythetimewe'llgettotheNIP,wewillhavetwovaluesonthestack:theweightwhichwehavebeen DUPpingandthecategorynumber,whichwillbeontop.Wewantonlythecategorynumber;"NIP" eliminatestheweight.) Forinstance,thephrase


25CATEGORY

willleavethenumber3(LARGE)onthestack.TheabovedefinitionofCATEGORYresemblesourold

definitionofEGGSIZE,but,inthetrueForthstyleofkeepingwordsasshortaspossible,wehave removedtheoutputmessagesfromthedefinition.Instead,we'lldefineanadditionalwordwhichexpectsa categorynumberandprintsanoutputmessage,likethis:


:LABEL(category) CASE REJECTOF."reject"ENDOF SMALLOF."small"ENDOF MEDIUMOF."medium"ENDOF LARGEOF."large"ENDOF EXTRALARGEOF."extralarge"ENDOF ERROROF."error"ENDOF ENDCASE;

Forexample:
SMALLLABELsmallok

NowwecandefineEGGSIZEusingthreeofourownwords:
:EGGSIZECATEGORYDUPLABELTALLY;

Thusthephrase
23EGGSIZE

willprint
mediumok

atyourterminalandupdatethecounterformediumeggs. Howwillwereadthecountersattheendoftheday?Wecouldcheckeachcellinthearrayseparately withaphrasesuchas


LARGECOUNTER?

(whichwouldtellushowmany"large"cartonswerepacked).Butlet'sgetalittlefancieranddefineour ownwordtoprintatableoftheday'sresultsinthisformat:
QUANTITYSIZE 1reject 112small 132medium 143large 159extralarge 0error

Sincewehavealreadydevisedcategorynumbers,wecansimplyuseaDOandindexonthecategory number,likethis:
:REPORT() PAGE."QUANTITYSIZE"CRCR 60DOICOUNTER@5U.R 7SPACES ILABELCR LOOP;

(Thephrase"ICOUNTER@5U.R"takesthecategorynumbergivenbyI,indexesintothearray, andprintsthecontentsoftheproperelementinafivecolumnfield.)

FactoringDefinitions
ThisisagoodtimetotalkaboutfactoringasitappliestoForthdefinitions.We'vejustseenanexamplein whichfactoringsimplifiedourproblem. OurfirstdefinitionofEGGSIZEfromChap.4,categorizedeggsbyweightandprintedthenameofthe categoriesattheterminal.Inourpresentversionwefactoredoutthe"categorizing"andthe"printing" intotwoseparatewords.WecanusethewordCATEGORYtoprovidetheargumenteitherfortheprinting wordorthecountertallyingword(orboth).Andwecanusetheprintingword,LABEL,inboth EGGSIZEandREPORT. AsCharlesMoore,theinventorofForth,haswritten: AgoodForthvocabularycontainsalargenumberofsmallwords.Itisnotenoughtobreaka problemintosmallpieces.Theobjectistoisolatewordsthatcanbereused. Forexample,intherecipe: Getacanoftomatosauce. Opencanoftomatosauce. Pourtomatosauceintopan. Getcanofmushrooms. Opencanofmushrooms. Pourmushroomsintopan. youcan"factorout"thegetting,opening,andpouring,sincetheyarecommontobothcans.Thenyoucan givethefactoredoutprocessanameandsimplywrite:
TOMATOESADD MUSHROOMSADD

andanychefwho'sgraduatedfromthePostfixSchoolofCookerywillknowexactlywhatyoumean. Notonlydoesfactoringmakeaprogrameasiertowrite(andfix!),itsavesmemoryspace,too.Areusable wordsuchasADDgetsdefinedonlyonce.Themorecomplicatedtheapplication,thegreaterthesavings. HereisanotherthoughtaboutForthstylebeforeweleavetheeggranch.Recallourdefinitionof EGGSIZE


:EGGSIZECATEGORYDUPLABELTALLY;

CATEGORYgaveusavaluewhichwewantedtopasontobothLABELandTALLY,soweincludedthe DUP.Tomakethedefinition"cleaner,"wemighthavebeentemptedtotaketheDUPoutandputitinside thedefinitionofLABEL,atthebeginning.Thuswemighthavewritten:


:EGGSIZECATEGORYLABELTALLY;

whereCATEGORYpassesthevaluetoLABEL,andLABELpassesitontoTALLY.Certainlythis approachwouldhaveworked.Butthen,whenwedefinedREPORT,wewouldhavehadtosay

ILABELDROP

insteadofsimply
ILABEL

Forthprogrammerstendtofollowthisconvention:whenpossible,wordsshoulddestroytheirown parameters.Ingeneral,it'sbettertoputtheDUPinsidethe"callingdefinition"(EGGSIZE,here)thanin the"called"definition(LABEL,here).

AnotherExample"Looping"throughanArray
We'dliketointroducealittletechniquethatisrelevanttoarrays.Wecanbestillustratethistechniqueby writingourowndefinitionofaForthwordcalledDUMP.DUMPisusedtoprintoutthecontentsofa seriesofmemoryaddresses.Theusageis
addrcountDUMP

Forinstance,wecouldenter
COUNTS6DUMP

toprintthecontentsofoureggcountingarraycalledCOUNTS.SinceDUMPisprimarilydesignedasa programmingtooltoprintoutthecontentsofmemorylocations,itprintseitherbytebybyteorcellby cell,dependingonthetypeofaddressingourcomputeruses.OurversionofDUMPwillprintcellby cell. ObviouslyDUMPwillinvolveaDOloop.Thequestionis:whatshouldweuseforanindex?Although wemightusethecountitself(06)astheloopindex,it'sbettertousetheaddressastheindex. TheaddressofCOUNTSwillbethestartingindexfortheloop,whiletheaddressplusthecountwillserve asthelimit,likethis:


:DUMP(addrcellcount) CELLSOVER+SWAP DOCRI@5U.R 1CELLS+LOOP;

Thekeyphrasehereis
CELLSOVER+SWAP

whichimmediatelyprecedestheDO. Theendingandstartingaddressesarenowonthestack,readytoserveasthelimitandindex fortheDOloop.Sinceweare"indexingontheaddresses,"onceweareinsidetheloopwe merelyhavetosay


I@5U.R

toprintthecontentsofeachelementofthearray.Sinceweareexaminingcells(@fetchesasinglelength, singlecellvalue),weincrementtheindexbyonecelleachtime,byusing
1CELLS+LOOP

ByteArrays
Forthletsyoucreateanarrayinwhicheachelementconsistsofasinglebyteratherthanafullcell.Thisis usefulanytimeyouarestoringaseriesofnumberswhoserangefitsintothatwhichcanbeexpressed withineightbits. Therangeofanunsigned8bitnumberis0to255.BytearraysarealsousedtostoreASCIIcharacter strings.Thebenefitofusingabytearrayinsteadofacellarrayisthatyoucangetthesameamountof datain25%(32bitForth)ofthememoryspace. Themechanicsofusingabytearrayarethesameasusingacellarrayexceptthat 1. youdon'thavetouseCELLStomanipulatetheoffset,sinceeachelementcorrespondstoone addressunit,and 2. youmustusethewordsC!andC@insteadof!and@.Thesewords,whichoperateonbytevalues only,havetheprefix"C"becausetheirtypicaluseisacceptingASCIIcharacters. C! C@ (baddr) (addrb) Storesan8bitvalueintotheaddress. Fetchesan8bitvaluefromtheaddress.

InitializinganArray
Manysituationscallforanarraywhosevaluesneverchangeduringtheoperationoftheapplicationand whichmayaswellbestoredintothearrayatthesametimethatthearrayiscreated,justasCONSTANTs are.ForthprovidesthemeanstoaccomplishthisthroughthetwowordsCREATEand,(pronounced createandcomma). SupposewewantpermanentvaluesinourLIMITSarray.Insteadofsaying
VARIABLELIMITS4CELLSALLOT

wecansay
CREATELIMITS220,340,170,100,190,

Usuallytheabovelinewouldbeincludedfromadiskfile,butitalsoworksinteractively. LikethewordVARIABLE,CREATEputsanewnameinthedictionaryatcompiletimeandreturnsthe addressofthatdefinitionwhenitisexecuted.Butitdoesnot"allot"anybytesforavalue. Theword,takesanumberoffthestackandstoresitintothearray.Soeachtimeyouexpressanumber andfollowitwith,,youaddonecelltothearray.

ForNewcomers Ingrainedhabits,learnedfromEnglishwriting,leadsomenewcomerstoforgettotypethefinal,intheline. Rememberthat,doesnotseparatethenumbers,itcompilesthem.

YoucanaccesstheelementsinaCREATEarrayjustasyouwouldtheelementsinaVARIABLEarray.

Forexample:
LIMITSCELL+@.340ok

Youcanevenstorenewvaluesintothearray,justasyouwouldintoaVARIABLEarray. ToinitializeabytearraythathasbeendefinedwithCREATE,youcanusethewordC,(ccomma).For instance,wecouldstoreeachofthevaluesusedinoureggsortingdefinitionCATEGORYasfollows:


CREATESIZES18C,21C,24C,27C,30C,255C,

ThiswouldallowustoredefineCATEGORYusingaDOloopratherthanasaseriesofnestedIF...THEN statements,asfollows
:CATEGORY60DODUPSIZESI+C@<IFDROPILEAVETHENLOOP;

Notethatwehaveaddedamaximum(255)tothearraytosimplifyourdefinitionregardingcategory5. IncludingtheinitializationoftheSIZESarray,thisversiontakesonlythreelinesofsourcetextas opposedtosixandtakeslessspaceinthedictionary,too.


ForPeopleWhoDon'tLikeGuessingHowItWorks Theideahereisthis:sincetherearefivepossiblecategories,wecanusethecategorynumbersasourloop index.Eachtimearound,wecomparethenumberonthestackagainsttheelementinSIZES,offsetbythe currentloopindex.Assoonastheweightonthestackisgreaterthanoneoftheelementsinthearray,we leavetheloopanduseItotellushowmanytimeswehadloopedbeforewe"left."Sincethisnumberisour offsetintothearray,itwillalsobeourcategorynumber.

Here'salistoftheForthwordswe'vecoveredinthischapter: CONSTANTxxx VARIABLExxx CREATExxx ! @ ? +! ALLOT , C! C@ FILL BASE 2CONSTANTxxx (n) xxx:(n) () xxx:(addr) () xxx:(addr) (naddr) (addrn) (addr) (naddr) (n) (n) (baddr) (addrb) (addrnb) (n) (d) xxx:(d) Createsaconstantnamedxxxwiththevaluen;thewordxxxreturns nwhenexecuted. Createsavariablenamedxxx;thewordxxxreturnsitsaddresswhen executed. Createsadictionaryentry(headandcodepointeronly)namedxxx; thewordxxxreturnsitsaddresswhenexecuted. Storesasinglelengthnumberintotheaddress. Replacestheaddresswithitscontents. Printsthecontentsoftheaddress,followedbyonespace. Addsasinglelengthnumbertothecontentsoftheaddress. Addsnbytestothebodyofthemostrecentlydefinedword. Compilesnintothenextavailablecellinthedictionary. Storesan8bitvalueintotheaddress. Fetchesan8bitvaluefromtheaddress. Fillsnbytesofmemory,beginningattheaddress,withvalueb. Avariablewhichcontainsthevalueofthenumberbasebeingused bythesystem. Createsadoublelengthconstantnamedxxxwiththevalued;the wordxxxreturnsdwhenexecuted.

2VARIABLExxx 2! 2@ C, DUMP ERASE

() xxx:(addr) (daddr) (addrd) (b) (addru) (addrn)

Createsadoublelengthvariablenamedxxx;thewordxxxreturnsits addresswhenexecuted. Storesadoublelengthnumberintotheaddress. Returnsthedoublelengthcontentsoftheaddress. Compilesbintothenextavailablebyteinthedictionary. Displaysubytesofmemory,startingattheaddress. Storeszeroesintonbytesofmemory,beginningattheaddress. KEY n,n1,... singlelengthsigned d,d1,... doublelengthsigned u,u1,... singlelengthunsigned ud,ud1,... doublelengthunsigned addr address c ASCIIcharactervalue b 8bitbyte f Booleanflag ReviewofTerms

aseriesofmemorylocationswithasinglename.Valuescanbestoredandfetchedintothe individuallocationsbygivingthenameofthearrayandaddinganoffsettotheaddress. Constant avaluewhichhasaname.Thevalueisstoredinmemoryandusuallyneverchanges. asitappliestoprogramminginForth,simplifyingalargejobbyextractingthoseelements Factoring whichmightbereusedanddefiningthoseelementsasoperations. Fetch toretrieveavaluefromagivenmemorylocation. Initialize togiveavariable(orarray)itsinitialvalue(s)beforetherestoftheprogrambegins. anumberwhichcanbeaddedtotheaddressofthebeginningofanarraytoproducethe Offset addressofthedesiredlocationwithinthearray. Store toplaceavalueinagivenmemorylocation. Variable alocationinmemorywhichhasanameandinwhichvaluesarefrequentlystoredandfetched. Array

ProblemsChapter8
1. WritetwowordscalledBAKEPIEandEATPIE.Thefirstwordincreasesthenumber ofavailablePIESbyone.Theseconddecreasesthenumberbyoneandthanksyouforthe pie.Butiftherearenopies,ittypes"Whatpie?"(makesureyoustartoutwithnopies.)
EATPIEWhatpie? BAKEPIEok

EATPIEThankyou!ok

2. WriteawordcalledFREEZEPIESwhichtakesalltheavailablepiesandaddsthemto thenumberofpiesinthefreezer.Rememberthatfrozenpiescannotbeeaten.
BAKEPIEBAKEPIEFREEZEPIESok PIES?0ok FROZENPIES?2ok

[answer] 2. Defineawordcalled.BASEwhichprintsthecurrentvalueofthevariableBASEindecimal.Test itbyfirstchangingBASEtosomevalueotherthanten.(Thisoneistrickierthanitmayseem.)


DECIMAL.BASE10ok HEX.BASE16ok

[answer] 3. DefineanumberformattingwordcalledM.whichprintsadoublelengthnumberwithadecimal point.Thepositionofthedecimalpointwitinthenumberismovableanddependsonthevalueof avariablethatyouwilldefineasPLACES.Forexample,ifyoustorea"1"intoPLACES,youwill get


200,000M.20000.0ok

thatis,withthedecimalpointoneplacefromtheright.AzeroinPLACESshouldproduceno decimalpointatall.[answer] 4. Inordertokeeptrackoftheinventoryofcoloredpencilsinyouroffice,createanarray,eachcell ofwhichcontainsthecountofadifferentcoloredpencil.Defineasetofwordssothat,for example,thephrase


REDPENCILS

returnstheaddressofthecellthatcontainsthecountofredpencils,etc.Thensetthesevariables toindicatethefollowingcounts:
23redpencils 15bluepencils 12greenpencils 0orangepencils

[answer] 5. Ahistogramisagraphicrepresentationofaseriesofvalues.Eachvalueisshownbytheheightor lengthofabar.Inthisexerciseyouwillcreateanarrayofvaluesandprintahistogramwhich displaysalineof"*"sforeachvalue.Firstcreateanarraywithabouttencells.Initializeeach elementofthearraywithavalueintherangeofzerotoseventy.ThendefineawordPLOTwhich willprintalineforeachvalue.Oneachlineprintthenumberofthecellfollowedbyanumberof "*"sequaltothecontentsofthatcell. Forexample,ifthearrayhasfourcellsandcontainsthevalues1,2,3and4,thenPLOTwould produce:


1* 2** 3*** 4****

[answer] 6. Createanapplicationthatdisplaysatictactoeboard,sothattwohumanplayerscanmaketheir movesbyenteringthemfromthekeyboard.Forexample,thephrase


4X!

putsan"X"inbox4(countingstartswith1)andproducesthisdisplay:
|| X|| ||

Thenthephrase
3O!

putsan"O"inbox3andprintsthedisplay:
||O X|| ||

Useabytearraytorememberthecontentsoftheboard,withthevalue1tosignify"X,"a1to signifya"O,"anda0tosignifyanemptybox.[answer]

9UndertheHood
Let'sstopforachaptertoliftForth'shoodandseewhatgoesoninside. Someoftheinformationcontainedhereinwe'vegivenearlier,but,attheriskofredundancy,we'renow goingtoviewtheForth"machine"asawhole,toseehowitallfitstogether.

InsideINTERPRET
Backinthefirstchapterwelearnedthatthetextinterpreter,whosenameisINTERPRET,pickswordsout oftheinputstreamandtriestofindtheirdefinitionsinthedictionary.Ifitfindsaword,INTERPREThas itexecuted. Wecanperformtheseseparateoperationsourselvesbyusingwordsthatperformthecomponentfunctions ofINTERPRET.Forinstance,theword'(pronouncedtick)findsadefinitioninthedictionaryand returnsitsexecutiontoken.IfwehavedefinedGREETaswedidinChap.1,wecannowsay
'GREETU.4956608ok

anddiscovertheexecutiontokenofGREET(whateverithappenstobe). WemayalsodirectlyuseEXECUTE.INTERPRETwillexecuteadefinition,givenitsexecutiontoken ("xt")onthestack.Thuswecansay

'GREETEXECUTEHello,IspeakForthok

andaccomplishthesamethingasifwehadmerelysaidGREET,onlyinamoreroundaboutway. Iftickcannotfindawordinthedictionary,itexecutesABORT"andprintsanerrormessage. Forth'stextinterpreterusesawordrelatedtotickthatreturnsazeroflagifthewordisfound.Thename andusageofthewordvaries,buttheconditionalstructureoftheINTERPRETphrasealwayslookslike this:


(findtheword)IF(converttoanumber) ELSE(executetheword) THEN

thatis,ifthestringisnotadefinedwordinthedictionary,INTERPRETtriestoconvertitasanumber.If itisadefinedword,INTERPRETexecutesit. Theword'hasseveraluses.Forinstance,youcanusethephrase


'GREET.

tofindoutwhetherGREEThasbeendefined,withoutactuallyhavingtoexecuteit(itwilleitherprintthe xtorrespondwithanerror).

YoucanalsousethexttoDUMPthecontentsofthedefinition,likethis:
'GREET12CELLSDUMP A054620:6813400000000000603D030A1548656C h.@.....`=...Hel A054630:6C6F2C204920737065616B20466F7274lo,Ispeak Fort A054640:68202020380241000000000000000000h 8.A......... ok

Oryoucanuseticktoimplementsomethingcalled"vectoredexecution."Whichbringsustothenext section...

VectoredExecution
Whileitsoundshairy,theideaofvectoredexecutionisreallyquitesimple.Insteadofexecutinga definitiondirectly,aswedidwiththephrase
'GREETEXECUTE

wecanexecuteitindirectlybykeepingitsxtinavariable,thenexecutingthecontentsofthevariable,like this:
'GREETpointer! pointer@EXECUTE

Theadvantageisthatwecanchangethepointerlater,sothatasinglewordcanbemadetoperform differentthingsatdifferenttimes. Hereisanexamplethatyoucantryyourself:

(1):HELLO."Hello"; (2):GOODBYE."Goodbye"; (3)VARIABLE'aloha'HELLO'aloha! (4):ALOHA'aloha@EXECUTE;

Inthefirsttwolines,we'vesimplycreatedwordswhichprintthestrings"Hello"and"Goodbye."Inline 3,we'vedefinedavariablecalled'aloha.Thiswillbeourpointer.We'veinitializedthepointerwiththe xtofHELLO.Inline4,we'vedefinedthewordALOHAtoexecutethedefinitionwhosextisin'aloha. NowifweexecuteALOHA,wewillget


ALOHAHellook

Alternatively,ifweexecutethephrase
'GOODBYE'aloha!

tostorethextofGOODBYEinto'aloha,wewillget
ALOHAGoodbyeok

Thusthesameword,ALOHA,candotwodifferentthings. Noticethatwenamedourpointer'aloha(whichwewouldpronouncetickaloha).Sincetickprovides anxt,weuseitasaprefixtosuggest"thextof"ALOHA.ItisaForthconventiontousethisprefixfor vectoredexecutionpointers. Tickalwaysgoestothenextwordintheinputstream.Whatifweputtickinsideadefinition?Whenwe executethedefinition,tickwillfindthenextwordintheinputstream,notthenextwordinthedefinition. Thuswecoulddefine


:SAY''aloha!;

thenenter
SAYHELLOok ALOHAHellook

or
SAYGOODBYEok ALOHAGoodbyeok

tostorethextofeitherHELLOorGOODBYEinto'aloha. Butwhatifwewantticktousethenextwordinthedefinition?Wemustusetheword['](brackettick bracket)insteadoftick.Forexample:


:COMING[']HELLO'aloha!; :GOING[']GOODBYE'aloha!;

Nowwecansay
COMINGok ALOHAHellook GOINGok ALOHAGoodbyeok

Herearethecommandswe'vecoveredsofar: 'xxx (addr) Attemptstofindtheexecutiontokenofxxx(thewordthatfollowsinthe inputstream)inthedictionary.

compiletime () Usedonlyinacolondefinition,compilestheexecutiontokenofthenext ['] runtime wordinthedefinitionasaliteral. (addr)

TheStructureofaDictionaryEntry
Alldefinitions,whethertheyhavebeendefinedby:,byVARIABLE,byVALUE,byCREATE,orbyany other"definingword,"sharethesebasicparts:
namefield linkfield codepointerfield datafield

UsingthevariableDATEasanexample,here'showthesecomponentsarearrangedwithineach dictionaryentry.Inthisdiagram,eachhorizontallinerepresentsonecellinthedictionary:

NotwoForthsystemsarealikeinthisrespect.Theremaybemorebasicparts,theirsizemaydiffer,and theorderofthecomponentsalmostcertainlydiffers. Inthisbookwe'reonlyconcernedwiththefunctionsofthefourcomponents,notwiththeirorderinsidea dictionaryentry.

Name
Inourexample,thefirstbytecontainsthenumberofcharactersinthefullnameofthedefinedword (therearefourlettersinDATE).ThenextfourbytescontaintheASCIIrepresentationsofthefourletters inthenameofthedefinedword. Noticethe"precedencebit"inthediagram.Thisbitisusedduringcompilationtoindicatewhetherthe wordissupposedtobeexecutedduringcompilation,ortosimplybecompiledintothenewdefinition. MoreonthisinChap.11.

Link
The"link"cellcontainstheaddressofthepreviousdefinitioninthedictionarylist.Thelinkcellcanbe usedinlinearlysearchingthedictionary.Tosimplifythingsabit,imaginethatitworksthisway: Eachtimethecompileraddsanewwordtothedictionary,hesetsthelinkfieldtopointtothe addressofthepreviousdefinition.HereheissettingthelinkfieldofCUISINARTtopointto thedefinitionofCAR. Atsearchtime,tick(orbrackettickbracket,etc.)startswiththemostrecentwordandfollows the"chain"backwards,usingtheaddressineachlinkcelltolocatethenextdefinitionback.

Thelinkfieldofthefirstdefinitioninthedictionarycontainsazero,whichtellsticktogiveup;theword isnotinthedictionary.

CodePointer
Nextisthe"codepointer."Thextcontainedinthispointeriswhatdistinguishesavariable fromaconstantoracolondefinition.Itistheaddressoftheinstructionthatisexecutedfirst whenaparticulartypeofwordisexecuted.Conceptually,inthecaseofavariable,thepointerpointsto codethatpushestheaddressofthevariableonthedatastack.Inthecaseofaconstant,thepointerpoints tocodethatpushesthecontentsoftheconstantonthedatastack.Inthecaseofacolondefinition,the pointerpointstocodethatexecutestherestofthewordsinthecolondefinition.Inpracticethereare manywaystoimplementthisconcept,includingnativecoderealizations. Thecodethatispointedtoiscalledthe"runtimecode"becauseitisusedwhenawordofthattypeis executed(notwhenawordofthattypeisdefinedorcompiled). Allvariables(conceptually)havethesamecodepointer;allconstantshavethesamecodepointeroftheir own,andsoon.

Datafield
Followingthecodepointeristhedatafield.Invariablesandconstants,thedatafieldisonlyonecell.Ina 2VARIABLEora2CONSTANT,thedatafieldistwocells.Inanarray,thedatafieldcanbeaslongas youwantit.Inacolondefinition,thelengthofthedatafielddependsonthelengthofthedefinition,as we'llexplaininthenextsection.Strictlyspeaking,thecolondefinitionofamodernForthdoesnothavea datafield. ThextthatissuppliedbytickandexpectedbyEXECUTEisthecodepointerdefinedabove.The beginningofthedatafieldcanbefoundwith>BODY,awordthatcomputesthedatafieldgivenanxt. >BODYdoesnotworkforcolondefinitions.SomeForthsmayevenforbidtheuseof>BODYonany systemdatastructure(variablesconstants,user,etc.).

TheBasicStructureofaColonDefinition
Whiletheformatoftheheadandcodepointeristhesameforalltypesofdefinitions,theformatofthe datafieldvariesfromtypetotype.Let'slookatthedatafieldofacolondefinition. Thedatafieldofacolondefinitioncontainsthextsofthepreviouslydefinedwordswhichcomprisethe definition.HereisthedictionaryentryforthedefinitionofPHOTOGRAPH,whichisdefinedas
:PHOTOGRAPHSHUTTEROPENTIMEEXPOSESHUTTERCLOSE;

WhenPHOTOGRAPHisexecuted,thedefinitionsthatarepointedtobythesuccessivextsare executedinturn.Themechanismwhichreadsthelistofxtsandexecutesthedefinitionsthey pointtoiscalledthe"addressinterpreter." Theword;attheendofthedefinitioncompilesthextofawordcalledEXIT.Asyoucanseeinthe figure,thextofEXITresidesinthelastcellofthedictionaryentry.Theaddressinterpreterwillexecute EXITwhenitgetstothisaddress,justasitexecutestheotherwordsinthedefinition.EXITterminates theexecutionoftheaddressinterpreter,aswewillseeinthenextsection.

NestedLevelsofExecution
ThefunctionofEXITistoreturntheflowofexecutiontothenexthigherleveldefinitionthatreferstothe currentdefinition.Let'sseehowthisworksinsimplifiedterms. SupposethatDINNERconsistsofthreecourses:
:DINNERSOUPENTREEDESSERT;

andthattonight'sENTREEconsistssimplyof
:ENTREECHICKENRICE;

WeareexecutingDINNERandwehavejustfinishedtheSOUP.Thepointerthatisusedby theaddressinterpreteriscalledthe"interpreterpointer".SincethenextcourseaftertheSOUP istheENTREE,ourinterpreterpointerispointingtothecellthatcontainsthextofENTREE. Theactiontheaddressinterpreterperformscanbeseenas"subroutinecalling"allthextsinthelist,with thereturnstackusedtokeepreturnadresses,andtheEXITworkingasthemachine'sRTS(returnfrom subroutine)instruction.

OneStepBeyond
Nowyou'reofcoursewondering:whathappenswhenwefinallyexecutetheEXITinDINNER.Whose returnaddressisonthereturnstack?Whatdowereturnto? Well,rememberthatDINNERhasjustbeenexecutedbyEXECUTE,whichisacomponentof INTERPRET.INTERPRETisaloopwhichcheckstheentireinputstream.Assumingthatweentered afterDINNER,thenthereisnothingmoretointerpret.SowhenweexitINTERPRET,where doesthatleaveus?Intheoutermostdefinitionofeachterminal,calledQUIT. QUIT,insimplifiedform,lookslikethis:
:QUITBEGIN(clearreturnstack) (acceptinput) INTERPRET ."ok"CR AGAIN;

(Theparentheticalcommentsrepresentwordsandphrasesnotyetcovered.)Wecanseethataftertheword INTERPRETcomesadotquotemessage,"ok,"andaCR,whichofcoursearewhatweseeafter interpretationhasbeencompleted. Nextisthephrase


AGAIN

whichunconditionallyreturnsustothebeginningoftheloop,whereweclearthereturnstackandonce againwaitforinput. IfweexecuteQUITatanylevelofexecution,wewillimmediatelyceaseexecutionofourapplicationand reenterQUIT'sloop.Thereturnstackwillbecleared(regardlessofhowmanylevelsofreturnaddresses wehadthere,sincewecouldneveruseanyofthemnow)andthesystemwillwaitforinput.Youcansee

whyQUITcanbeusedtokeepthemessage"ok"fromappearingatourterminal. ThedefinitionofABORT"usesQUIT.

AbandoningtheNest
It'spossibletoincludeEXITinthemiddleofadefinition.Forexample,ifweweretoredefineENTREE asfollows:
:ENTREECHICKENEXITRICE;

thenwhenwesubsequentlyexecuteDINNER,wewillexitrightafterCHICKENandreturntothenext courseaftertheENTREE,i.e.,DESSERT. EXITiscommonlyusedtoexitfromdeeplynestedconditionalstructures. EXIT () Whencompiledwithinacolondefinition,terminatesexecutionatthatpoint. QUIT () Clearsallstacksandreturnscontroltotheterminal.Nomessageisgiven.

ForthGeography
ThisisthememorymapofatypicalForthsystem:

SystemVariables
Thissectionofmemorycontains"systemvariables"whicharecreatedbythebasicForthcoreandused bytheentiresystem.Theyarenotgenerallyusedbytheuser.

UserDictionary
Thedictionarywillgrowintohighermemoryasyouaddyourowndefinitions.Thenextavailablecellin thedictionaryatanytimeispointedtobyavariablecalledCP.Duringtheprocessofcompilation,the pointerCPisadjustedcellbycellastheentryisbeingaddedtothedictionary.ThusCPisthecompiler's bookmark;itpointstotheplaceinthedictionarywherethecompilercannextcompile. CPisalsousedbythewordALLOT,whichadvancesCPbythenumberofbytesgiven.Forexample,the phrase
5CELLSALLOT

addstwentytoCPsothatthecompilerwillleaveroominthedictionaryforafivecellarray. ArelatedwordisHERE,whichissimplydefinedas
:HERECP@;

toputthevalueofCPonthestack.Theword,(comma),whichstoresasinglelengthvalueintothenext availablecellinthedictionary,issimplydefined
:,HERE!CELLALLOT;

thatis,itstoresavalueintoHEREandadvancesthedictionarypointeronecelltoleaveroomforit. YoucanuseHEREtodeterminehowmuchmemoryanypartofyourapplicationrequires,simplyby comparingtheHEREfrombeforewiththeHEREaftercompilation.Forexample,


HERES"random.frt"INCLUDEDHERESWAP.196ok

indicatesthatthedefinitionsloadedbythefilerandom.frtfilled196bytesofmemoryspaceinthe dictionary.

ThePad
AtacertaindistancefromHEREinyourdictionary,youwillfindasmallregionofmemorycalledthe "pad."Likeascratchpad,itisusuallyusedtoholdASCIIcharacterstringsthatarebeingmanipulated priortobeingsentouttoaterminal.Forexample,thenumberformattingwordsusethepadtoholdthe ASCIInumeralsduringtheconversionprocess,priortoTYPE. Thesizeofthepadisindefinite.Inmostsystemstherearehundredsofkilobytesbetweenthebeginning ofthepadandthetopoftheparameterstack. Sincethepad'sbeginningaddressisdefinedrelativetothelastdictionaryentry,itmoveseverytimeyou addanewdefinitionorexecuteFORGETorMARKER.Thisarrangementprovessafe,however,because thepadisneverusedwhenanyoftheseeventsareoccurring.ThewordPADreturnsthecurrentaddress ofthebeginningofthepad.Itisdefinedsimply:
:PADHERE340+;

thatis,itreturnsanaddressthatisafixednumberofbytesbeyondHERE.(Theactualnumbervaries.)

ParameterStack
Farabovethepadinmemoryistheareareservedfortheparameterstack.Althoughweliketoimagine thatvaluesactuallymoveupordownsomewhereaswe"popthemoff"and"pushthemon,"inreality nothingmoves.Theonlythingthatchangesisapointertothe"top"ofthestack. Asyoucanseebelow,whenwe"putanumberonthestack,"whatreallyhappensisthatthepointeris "decremented"(sothatitpointstothenextavailablelocationtowardslowmemory),thenournumberis storedwherethepointerispointing.Whenwe"removeanumberfromthestack,"thenumberisfetched fromthelocationwherethepointerispointing,thenthepointerisincremented.Anynumbersabovethe stackpointeronourmaparemeaningless.

Asnewvaluesareaddedtothestack,it"growstowardslowmemory." ThestackpointerisfetchedwiththewordSP@(pronouncedspfetch).SinceSP@providestheaddress ofthetopstacklocation,thephrase


SP@@

fetchesthecontentsofthetopofstack.Thisoperation,ofcourse,isidenticaltothatofDUP.Ifwehad fivevaluesonthestack,wecouldcopythefifthonedownwiththephrase

SP@4CELLS+@

(butthisisnotconsideredgoodprogrammingpractice). ThebottomofthestackispointedtobyavariablecalledSP0(spzero).SP0alwayscontainstheaddress ofthenextcellbelowthe"emptystack"cell. Noticethatwithdoublelengthnumbers,thehighordercellisstoredatthelowermemoryaddress whetheronthestackorinthedictionary.Theoperators2@and2!keeptheorderofthecellsconsistent.

InputMessageBuffer
TIBcontainsthestartingaddressforthe"inputmessagebuffer,"or"TerminalInputBuffer,"whichgrows towardshighmemory(thesamedirectionasthepad).Whenyouentertextfromtheterminal,itgets storedintothisbufferwherethetextinterpreterwillscanit.

ReturnStack
Abovethebufferresidesthereturnstack,whichoperatesidenticallytotheparameterstack.Thereareno highlevelForthwordsanalogoustoSP0andSP@thatrefertothereturnstack.

UserVariables
Thenextsectionofmemorycontains"uservariables."ThesevariablesincludeBASE,SP0,andmany othersthatwe'llcoverinanupcomingsection. ThiscompletesourjourneyacrossthememorymapofatypicalForthsystem.Herearethewordswe've justcoveredthatrelatetomemoryregionsintheForthsystem: HERE (addr) Returnsthenextavailabledictionarylocation. Returnsthebeginningaddressofascratchpadareausedtoholdcharacter stringsforintermediateprocessing. Uservariable.ReturntheaddressofthetopofthestackbeforeSP@is SP@ (addr) executed. PAD (addr) SP0 (addr) Uservariable.Containstheaddressofthebottomoftheparameterstack.

UserVariables
Thefollowinglistshowsmostoftheuservariables.Somewewon'tevermentionagain.Don'ttryto memorizethistable.Justrememberwhereyoucanfindit. TIB Containstheaddressofthestartoftheterminalinputbuffer. #TIB Containsthesizeoftheterminalinputbuffer. SCR Apointertothecurrentblocknumber(setbyLIST).

BASE Numberconversionbase. CP Dictionarypointer.Pointertothenextavailablebyte. >IN Apointertothecurrentpositionintheinputstream. BLK

Ifnonzero,apointertotheblockbeinginterpretedbyLOAD.Azeroindicates interpretationfromtheterminal(viatheinputmessagebuffer). Uservariablesarenotlikeordinaryvariables.Withanordinaryvariable(onedefinedbytheword VARIABLE),thevalueiskeptinthebodyofthedictionaryentry.Eachuservariable,ontheotherhand, iskeptinanarraycalledthe"usertable."Thedictionaryentryforeachuservariableislocatedelsewhere; itsbodycontainsanoffsetintotheusertable.Whenyouexecutethenameofauservariable,suchasCP, thisoffsetisaddedtothebeginningaddressoftheusertable,allowingyoutouse@or!inthenormal way. Themainadvantageofuservariablesisthatanynumberoftaskscanusethesamedefinitionofavariable andeachgetitsownvalue(becauseeachtaskhasnotonlyitsownstacks,butalsoitsownusertable). Eachtaskthatexecutes
BASE@

getsthevalueforBASEfromitsownusertable.Thissavesalotofroominthesystemwhilestill allowingeachtasktoexecuteindependently. UservariablesaredefinedbythewordUSER.Thesequenceofuservariablesinthetableandtheiroffset valuesvaryfromonesystemtoanother. Tosummarize,therearethreekindsofvariables:SystemvariablescontainvaluesusedbytheentireForth system.Uservariablescontainvaluesthatareuniqueforeachtask,eventhoughthedefinitionscanbe usedbyalltasksinthesystem.Regularvariablescanbeaccessibleeithersystemwideorwithinasingle taskonly. Here'salistoftheForthwordswe'vecoveredinthischapter: 'xxx (addr) Attemptstofindtheexecutiontokenofxxx(thewordthatfollowsinthe inputstream)inthedictionary.

[']

compiletime () Usedonlyinacolondefinition,compilestheexecutiontokenofthe runtime nextwordinthedefinitionasaliteral. (addr) Executesthedictionaryentrywhoseexecutiontokenisonthestack. Whencompiledwithinacolondefinition,terminatesexecutionatthat point. Clearsallstacksandreturnscontroltotheterminal.Nomessageis given. Returnsthenextavailabledictionarylocation.

EXECUTE (xt) EXIT QUIT HERE () () (addr)

PAD SCR BASE SP@ TIB #TIB SP0 >IN BLK

(addr) (addr) (addr) (addr) (addr) (addr) (addr) (addr) (addr)

Returnsthebeginningaddressofascratchpadareausedtohold characterstringsforintermediateprocessing. Uservariable.Apointertothecurrentblocknumber(setbyLIST). Uservariable.Numberconversionbase. Uservariable.ReturntheaddressofthetopofthestackbeforeSP@is executed. Uservariable.Containstheaddressofthestartoftheterminalinput buffer. Uservariable.Containsthesizeoftheterminalinputbuffer. Uservariable.Containstheaddressofthebottomoftheparameter stack. Uservariable.Apointertothecurrentpositionintheinputstream. Uservariable.Ifnonzero,apointertotheblockbeinginterpretedby LOAD.Azeroindicatesinterpretationfromtheterminal(viatheinput messagebuffer). ReviewofTerms

ThesecondofForth'stwointerpreters,theonewhichexecutesthedata(listofaddresses, listofcalls,machinecode,...)foundinthedictionaryentryofacolondefinition.The addressinterpreteralsohandlesthenestingofexecutionlevelsforwordswithinwords. Body thecodeanddatafieldofaForthdictionaryentry. Cfa codefieldaddress;theaddressofadictionaryentry'scodepointerfield. thecellinadictionaryentrywhichsomehowpointsoutthextoftheruntimecodeforthis Codepointer particulartypeofdefinition.Forexample,inadictionaryentrycompiledby:,thefield field wouldpointouttheaddressinterpreter. aForthwordwhichcreatesadictionaryentry.Examplesinclude:,CONSTANT, Defining word VARIABLE,etc. Head thenameandlinkfieldsofaForthdictionaryentry. Input theregionofmemorywithinaterminaltaskthatisusedtostoretextasitarrivesfromthe message terminal.Incomingsourcetextisinterpretedhere. buffer thecellinadictionaryentrywhichcontainstheaddressofthepreviousdefinition,usedin Linkfield searchingthedictionary. theareaofadictionaryentrywhichcontainsthenameofthedefinedword,alongwiththe Namefield numberofcharactersinthename. theregionofmemorywithinaterminaltaskthatisusedasascratchareatoholdcharacter Pad stringsforintermediateprocessing. Datafield theareaofadictionaryentrywhichcontainsthe"contents"ofadefinition:fora Address interpreter

CONSTANT,thevalueoftheconstant,foraVARIABLE,thevalueofthevariable;fora colondefinition,thelistofxtsofwordsthataretobeexecutedinturnwhenthedefinition isexecuted. aroutine,compiledinmemory,whichspecifieswhathappenswhenamemberofagiven Runtime classofwordsisexecuted.Theruntimecodeforacolondefinitionistheaddress code interpreter;theruntimecodeforavariablepushestheaddressofthevariable'sbodyon thestack. System oneofasetofvariablesprovidedbyForth,whicharereferredtosystemwide(byany variable task).Contrastwith"uservariables.". inForth,apartitioninmemorythatcontainsatminimumaparameterandareturnstack Task andasetofuservariables. oneofasetofvariablesprovidedbyForth,whosevaluesareuniqueforeachtask. Uservariable Contrastwith"systemvariables." themethodofspecifyingcodetobeexecutedbyprovidingnottheaddressofthecode Vectored itself,buttheaddressofalocationwhichcontainsthextofthecode.Thislocationisoften execution called"thevector."Ascircumstanceschangewithinthesystem,thevectorcanberesetto pointtosomeotherpieceofcode.

ProblemsChapter9
1. FirstreviewChap.2,Prob.6.Withoutchanginganyofthosedefinitions,writeawordcalled COUNTSwhichwillallowthejudgetooptionallyenterthenumberofcountsforanycrime.For instance,theentry
CONVICTEDOFBOOKMAKING3COUNTSTAXEVASIONWILLSERVE yearsok 17

willcomputethesentenceforonecountofbookmakingandthreecountsoftaxevasion.[answer] 2. What'sthebeginningaddressofyourprivatedictionary?[answer] 3. Inyoursystem,howfaristhepadfromthetopofyourprivatedictionary?[answer] 4. AssumingthatDATEhasbeendefinedbyVARIABLE,whatisthedifferencebetweenthesetwo phrases:


DATE.

and
'DATE.

Whatisthedifferencebetweenthesetwophrases:
BASE.

and
'BASE.

[answer] 5. Inthisexerciseyouwillcreatea"vectoredexecutionarray,"thatis,anarraywhichcontainsxtsof Forthwords.Youwillalsocreateanoperationwordwhichwillexecuteonewordstoredinthe arraywhentheoperationwordisexecuted. Defineaonedimensionalarrayofcellswhichwillreturnthenthelement'saddresswhengivena subscriptn.Defineseveralwordswhichoutputsomethingatyourterminalandtakenoinputs. Storethextsoftheseoutputwordsinvariouselementsofthearray.Storetheaddressofado nothingwordinanyremainingelementsofthearray.Defineawordwhichwilltakeavalidarray indexandexecutethewordwhoseaddressisstoredinthereferencedelement. Forexample,
1DOSOMETHINGHello,IspeakForth.ok 2DOSOMETHING12345678910ok 3DOSOMETHING ********** ********** ********** ********** **********ok 4DOSOMETHINGok 5DOSOMETHINGok [answer]

10I/OandYou
Inthischapter,we'llexplainhowForthhandlesI/O terminal. ofcharacterstringstoandfromdiskandthe Specifically,we'lldiscussdiskaccesscommands,outputcommands,stringmanipulationcommands, inputcommands,andnumberinputconversion.

OutputOperators
ThewordEMITtakesasingleASCIIrepresentationonthestack,usingtheloworderbyteonly,and printsthecharacteratyourterminal.Forexample,indecimal:
65EMITAok 66EMITBok

ThewordTYPEprintsanentirestringofcharactersatyourterminal,giventhestartingaddressofthe stringinmemoryandthecount,inthisform:
(addru)

We'vealreadyseenTYPEinournumberformattingdefinitionswithoutworryingabouttheaddressand count,becausetheyareautomaticallysuppliedby#>.

Let'sgiveTYPEanaddressthatweknowcontainsacharacterstring.Rememberthatthestartingaddress oftheterminalinputbufferisreturnedbyTIB?Supposeweenterthefollowingcommand:
TIB#TIB@TYPE

Thiswilltype15charactersfromtheterminalinputbuffer,whichcontainsthecommandwejustentered:
TIB#TIB@TYPE TIB#TIB@TYPEok

Let'sdigressforamomenttolookattheoperationof.".Atcompiletime,whenthecompilerencountersa dotquote,itcompilestheensuingstringrightintothedictionary,letterbyletter,uptothedelimiting doublequote.Tokeeptrackofthings,italsocompilesthecountofcharactersintothedictionaryentry. Giventhedefinition


:TEST."sample";

andlookingatbytesinthedictionaryhorizontallyratherthanvertically,hereiswhatthecompilerhas compiled: Ifwewantedto,wecouldtypetheword"SAMPLE"ourselves(withoutexecutingTEST)withthephrase


'TEST>BODYCELL+1+7TYPE

where
'TEST>BODY

givesusthebodyaddressofTEST,
CELL+1+

offsetsuspasttheaddressandthecount,tothebeginningofthestring(theletter"s"),and
7TYPE

typesthestring"sample." Thatlittleexercisemaynotseemtoouseful.Butlet'sgoastepfurther. RememberhowwedefinedLABELinoureggsizingapplication,usingnestedIF...THENstatements? WecanreworkourdefinitionusingTYPE.Firstlet'smakeallthelabelsthesamelengthand"stringthem together"withinasingledefinitionasastringarray.(Wecanabbreviatethelongestlabelto"XTRA LRG"sothatwecanmakeeachlabeleightcharacterslong,includingtrailingspaces.)


:"LABEL"."REJECTSMALLMEDIUMLARGEXTRALRGERROR";

Onceweenter
'"LABEL">BODYCELL+1+

togettheaddressofthestartofthestring,wecantypeanyparticularlabelbyoffsettingintothearray. Forexample,ifwewantlabel2,wesimplyaddsixteen(2x8)tothestartingaddressandtypetheeight charactersofthename:


16+8TYPE

Nowlet'sredefineLABELsothatittakesacategorynumberfromzerothroughfiveandusesittoindex intothestringarray,likethis:
:LABEL8*[']"LABEL">BODYCELL+1++8TYPESPACE;

Recallthattheword[']isjustlike'exceptthatitmayonlybeusedinsideadefinitiontocompilethe addressofthenextwordinthedefinition(inthiscase,"LABEL").Later,whenweexecuteLABEL, brackettickbracketfollowedbytobodywillpushthebodyaddressof"LABEL"ontothestack.The numbercorrespondingtoCELL+1+isadded,thenthestringoffsetisaddedtocomputetheaddressof theparticularlabelnamethatwewant. Thiskindofstringarrayissometimescalleda"superstring."Asanamingconvention,thenameofthe superstringusuallyhasquotesaroundit.Notethatthismethodisinpracticeneverused,asthesameresult canbehadwiththecompletelyportableANSForthwordC",asfollows:


:"LABEL"C"REJECTSMALLMEDIUMLARGEXTRALRGERROR"; :LABEL8*"LABEL"1++8TYPESPACE;

OurnewversionofLABELwillrunalittlefasterbecauseitdoesnothavetoperformaseriesof comparisontestsbeforeithitsuponthenumberthatmatchestheargument.Insteaditusestheargument tocomputetheaddressoftheappropriatestringtobetyped. Notice,though,thatiftheargumenttoLABELexceedstherangezerothroughfive,you'llgetgarbage.If LABELisonlygoingtobeusedwithinEGGSIZEintheapplication,there'snoproblem.Butifan"end user,"meaningaperson,isgoingtouseit,you'dbetter"clip"theindex,likethis:


:LABEL0MAX5MINLABEL;

TYPE (addru) Transmitsucharacters,beginningataddress,tothecurrentoutputdevice.

OutputtingStringsfromDisk
WementionedbeforethatthewordBLOCKcopiesagivenblockintoanavailablebufferandleavesthe addressofthebufferonthestack.Usingthisaddressasastartingpoint,wecanindexintooneofthe buffer's1,024bytesandtypeanystringwecareto.Forexample,toprintline0ofblock1,wecouldsay (assumingyou'veexecutedUSEblocks.fb)
CR1BLOCK64TYPE ok

Toprintlineeight,wecouldadd512(8x64)totheaddress,likethis:
CR1BLOCK512+64TYPE

Beforewegiveamoreinterestingexample,it'stimetointroduceawordthatiscloselyassociatedwith TYPE. Eliminatestrailingblanksfromthestringthatstartsatthe TRAILING (addru1addru2) addressbyreducingthecountfromu1(originalbytecount) tou2(shortenedbytecount).

TRAILINGcanbeusedimmediately HandyHint beforetheTYPEcommandsothat trailingblankswillnotbeprinted.For ARandomNumberGenerator instance,insertingitintoourfirst exampleabovewouldgiveus Thissimplerandomnumbergeneratorcanbeusefulforgames, althoughformoresophisticatedapplicationssuchassimulations, CR1BLOCK64 TRAILINGTYPE betterversionsareavailable.
ok (RandomnumbergenerationHighlevel) VARIABLErndHERErnd! :RANDOMrnd@31421*6927+DUPrnd!; :CHOOSE(u1u2)RANDOMUM*NIP; (whereCHOOSEreturnsarandominteger withintherange0=or<u2<u1.)

ThefollowingexampleusesTYPE
USEblocks.fb :POOF 16CHOOSE64* 2BLOCK+ CR64TRAILING TYPE;

Here'showtouseit: Tochoosearandomnumberbetweenzeroandten(butexclusive often)simplyenter


10CHOOSE

tryit:
POOF qualifiedok POOF flexibleok POOF totalok

andCHOOSEwillleavetherandomnumberonthestack.

InternalStringOperators
Thecommandsformovingcharacterstringsordataarraysareverysimple.Eachrequiresthree arguments:asourceaddress,adestinationaddress,andacount. Copiesaregionofmemoryubyteslong,bytebybytebeginningat CMOVE (addr1addr2u) addr1,tomemorybeginningataddr2.Themovebeginswiththe contentsofaddr1andproceedstowardhighmemory. Ifuisgreaterthanzero,copyuconsecutivecharactersfromthedata CMOVE (addr1addr2u) spacestartingatcaddr1tothatstartingatcaddr2,proceeding > characterbycharacterfromhigheraddressestoloweraddresses. Afterthismove,theubytesataddr2containexactlywhattheu MOVE (addr1addr2u) bytesataddr1containedbeforethemove(no"clobbering"occurs). Noticethatthesecommandsfollowcertainconventionswe'veseenbefore:

1. Whentheargumentsincludeasourceandadestination,thesourceprecedesthedestination. 2. Whentheargumentsincludeanaddressandacount(astheydowithTYPE),theaddressprecedes thecount. Andsowiththesethreewordstheargumentsare


(sourcedestinationcount)

TomovetheentirecontentsofabufferintothePAD,forexample,wewouldwrite
210BLOCKPAD1024CMOVE

althoughoncelladdressmachinesthemovemightbemadefasterifitwerecellbycell,likethis:
210BLOCKPAD1024MOVE

ThewordCMOVE>letsyoumoveastringtoaregionthatishigherinmemorybutthatoverlapsthe sourceregion. IfyouweretouseCMOVE,thefirstletterofthestringwouldgetcopiedtothe secondbyte,butthatwould"clobber"thesecondletterofthestring.Thefinal resultwouldbeastringcomposedofasinglecharacter. UsingCMOVE>inthissituationkeepsthestringfromclobberingitselfduringthemove. YouprobablynoticethatCMOVEcanbeusedtofillanarraywithacertainbyte.Onoldersystemsthe wordFILL,whichweintroducedearlier,mayhavebeendefinedusingthistrick.OnmodernForthsitis recommendedtoexplicitlyuseFILL,iffilliswhatyouwanttodo.Forexample,tostoreblanksinto1024 bytesofthepad,wesay
PAD1024CHARBLFILL

SinglecharacterInput
ThewordKEYawaitstheentryofasinglekeyfromyourterminalkeyboardandleavesthecharacter's ASCIIequivalentonthestackintheloworderbyte. Toexecuteitdirectly,youmustfollowitwithareturn,likethis:
KEY

Thecursorwilladvanceaspace,buttheterminalwillnotprintthe"ok";itiswaitingforyourinput.Press theletter"A,"forexample,andthescreenwill"echo"theletter"A,"followedbythe"ok."TheASCII valueisnowonthestack,soenter.:


KEYAok . 65ok

Thissavesyoufromhavingtolookinthetabletodetermineacharacter'sASCIIcode. YoucanalsoincludeKEYinsideadefinition.Executionofthedefinitionwillstop,whenKEYis encountered,untilaninputcharacterisreceived.Forexample,thefollowingdefinitionwilllistagiven numberofblocksinseries,startingwiththecurrentblock,andwaitforyoutopressanykeybeforeitlists thenextone:


:BLOCKS(count) SCR@+SCR@DOILISTKEYDROPLOOP;

InthiscasewedropthevalueleftbyKEYbecausewedon'tcarewhatitis.

Orwemightaddafeaturethatallowsuseithertoleavetheloopatanytimebypressingreturnorto continuebypressinganyotherkey,suchasasspace.Inthiscasewewillperformaconditionaltestonthe valuereturnedbyKEY.


13CONSTANT#EOL :BLOCKS(count) SCR@+ SCR@DOILIST KEY#EOL=(cr)IFLEAVETHEN LOOP;

NotethatinsomeForthsystems,thecarriagereturnkeyisreceivedasalinefeed(10)orasanull(zero). KEY (c) ReturnstheASCIIvalueofthenextavailablecharacterfromthecurrentinput device.

StringInputCommands,fromtheBottomup
Thereareseveralwordsinvolvedwithstringinput.We'llstartwiththelowerleveloftheseandproceedto somehigherlevelwords.Herearethewordswewillcoverinthissection: Receivesucharacters(oracarriagereturn)fromtheterminal ACCEPT (caddru1u2) keyboardandstoresthem,startingattheaddress.Thecountof receivedcharactersisreturned. Readsonewordfromtheinputstream,usingthecharacter(usually WORD (caddr) blank)asadelimiter.Movesthestringtotheaddress(HERE)with thecountinthefirstbyte,leavingtheaddressonthestack. ThewordACCEPTstopsexecutionofthetaskandwaitsforinputfromyourkeyboard.Itexpectsagiven numberofkeystrokesoracarriagereturn,whichevercomesfirst.Theincomingtextisstoredbeginningat theaddressgivenasanargument,thecountofreceivedcharactersisreturnedonthestack. Forexample,thephrase
TIB80ACCEPT

willawaituptoeightycharactersandstorethemintheTerminalInputBuffer(TIB).(Storingdirectlyin theTIBisnotstandard,bute.g.iForthhasnoproblemwiththistradition.) ThisphraseistheoneusedinthedefinitionofQUITtogettheinputforINTERPRET. Let'smoveontothenexthigherlevelstringinputoperator.We'vejustexplainedthatQUITcontainsthe phrase


...TIB80ACCEPT#TIB!INTERPRET...

buthowdoesthetextinterpreterscantheterminalinputbufferandpickouteachindividualwordthere? Withthephrase
BLWORD

WORDscanstheinputstreamlookingforthegivendelimiter,inthiscasespace,andmovesthesub stringintoadifferentbufferofitsown,withthecountinthefirstbyteofthebuffer.Finally,itleavesthe addressofthebufferonthestack,sothatINTERPRET(oranyoneelse)knowswheretofindit.WORD's bufferusuallybeginsatHERE,sotheaddressgivenisHERE.

WORDlooksforthegivendelimiterintheterminalinputbuffer,andmovesthesubstringtoWORD's bufferwiththecountinthefirstbyte. Whenyouareexecutingwordsdirectlyfromaterminal,WORDwillscantheinputbuffer,startingatTIB. Asitgoesalong,itadvancestheinputbufferpointer,called>IN,sothateachtimeyouexecuteWORD, youscanthenextwordintheinputstream.WORDknowstostopscanningwhen>IN@becomeslarger than#TIB@,thecountofreceivedcharacters. >INisa"relativepointer";thatis,itdoesnotcontaintheactualaddressbutratheranoffsetthatistobe addedtotheactualaddress,whichisisinthiscaseTIB.Forexample,afterWORDhasscannedthestring "STAR,"thevalueof>INisfive. WORDignoresinitialoccurencesofthedelimiter(untilanyothercharacterisencountered).Youcould type
STAR

(thatis,STARprecededbyseveralspaces)andgetexactlythesamestringinWORD'sbufferasshown above. We'llgetbacktoWORDlateroninthischapter.Fornow,though,let'sdefineawordthatusesWORD andthatismoreusefulforhandlingstringinput:


:TEXT(delimiter)PAD258BLFILLWORDCOUNTPADSWAPMOVE;

TEXT,likeWORD,takesadelimiterandscanstheinputstreamuntilitfindsthestringdelimitedbyit.It thenmovesthestringtothepad.WhatisespeciallyniceaboutTEXTisthatbeforeitmovesthestring,it blanksthepad.ThismakesitveryconvenientforusewithTYPE.Here'sasimpleexample:


CREATEmyname40ALLOT :I'MBLTEXTPADmyname40MOVE;

Inthefirstlinewedefineanarraycalledmyname.InthesecondlinewedefineawordcalledI'M whichwillallowustoenter
I'MEDWARDok

ThedefinitionofI'Mbreaksdownasfollows:thephrase
BLTEXT

scanstheremainderoftheinputstreamlookingforaspaceortheendoftheline,whichevercomesfirst. (ThedelimiterthatwegivetoTEXTisactuallyusedbyWORD,whichisincludedinthedefinitionof TEXT.)TEXTthenmovesthephrasetoaniceclean"pad." Thephrase


PADmyname40MOVE

movesfortybytesfromthepadintothearraycalledmyname,whereitwillsafelystayforaslongaswe needit. WecouldnowdefineGREETasfollows:

:GREET."Hello,"myname40TRAILINGTYPE.",IspeakForth.";

sothatbyexecutingGREET,weget
GREETHello,EDWARD,IspeakForth.ok

Unfortunately,ourdefinitionofI'Mislookingforaspaceasitsdelimiter.Thismeansthataperson namedMaryKaywillnotgetherfullnameintomyname. Togetthecompleteinputstream,wedon'twantto"see"anydelimiteratall,excepttheendofline. Insteadof"BLTEXT,"weshouldusethephrase


1TEXT

ASCII1isacontrolcharacterthatcan'tbeeversentfromthekeyboardandthereforewon'teverappearin theinputbuffer.Thus"1TEXT"isaconventionusedtoreadtheentireinputbuffer,uptothecarriage return.ByredefiningI'Minthisway,MaryKaycangethernameintomyname,spaceandall. Byusingotherdelimiters,suchascommas,wecan"accept"aseriesofstringsandstoreeachoftheminto adifferentarrayfordifferentpurposes.Considerthisexample,inwhichthewordVITALSusescommas asdelimiterstoseparatethreeinputfields:


(Formloveletter) CREATEname14ALLOT CREATEeyes12ALLOT CREATEme14ALLOT :VITALS [CHAR],TEXTPADname14MOVE [CHAR],TEXTPADeyes12MOVE 1TEXTPADme14MOVE; :LETTERPAGE ."Dear"name14TRAILINGTYPE."," CR."IgotoheavenwheneverIseeyourdeep" eyes12TRAILINGTYPE."eyes.Can" CR."yougotothemoviesFriday?" CR30SPACES."Love," CR30SPACESme14TRAILINGTYPE CR."P.S.Wearsomething"eyes12TRAILINGTYPE ."toshowoffthoseeyes!";

Whichallowsyoutoenter
VITALSAlice,blue,Fredok

thenenter
LETTER

Itworkseverytime. Sofarallofourinputhasbeen"Forthstyle";thatis,numbersprecedecommands(sothatacommand willfinditsnumberonthestack)andstringsfollowcommands(sothatacommandwillfinditsstringin theinputstream).ThisstylemakesuseofoneofForth'suniquefeatures:itawaitsyourcommands;itdoes notpromptyou.

Butifyouwantto,youmayputACCEPTinsideadefinitionsothatitwillrequestinputfromyouunder controlofthedefinition.Forexample,wecouldcombinethetwowordsI'MandGREETintoasingle wordwhich"prompts"userstoentertheirnames.Forexample,


GREET What'syourname?

atwhichpointexecutionstopssotheusercanenteraname:
GREET What'syourname?TravisMcGee Hello,TravisMcGee,IspeakForth.ok

Wecoulddothisasfollows:
:GREETCR."What'syourname?" TIB40ACCEPT#TIB!0>IN! 1TEXTCR."Hello," PAD40TRAILINGTYPE.",IspeakForth.";

We'veexplainedallthephrasesintheabovedefinitionexceptthisone:
#TIB!0>IN!

RememberthatTEXT,becauseitusesWORD,alwaysuses>INasitsreferencepoint.Butwhentheuser entersthewordGREETtoexecutethisdefinition,thestringGREETwillbestoredintheterminalinput bufferand>INwillbepointingbeyond"GREET".ACCEPTdoesnotuse>INasitsreference,soitwill storetheuser'snamebeginningatTIB,ontopofGREET.IfyouweretoexecuteTEXTnow,itwould missthefirstfivelettersoftheuser'sname.It'snecessarytoreset>INtozerosothatTEXTwilllook whereACCEPThasputthename.

NumberInputConversion
Whenyoutypeanumberatyourterminal,Forthautomaticallyconvertsthischaracterstringintoabinary valueandpushesitontothestack.Forthalsoprovidesacommandwhichletyouconvertacharacter stringthatbeginsatanymemorylocationintoabinaryvalue. ud2istheunsignedresultofconvertingthecharacterswithinthe stringspecifiedbycaddr1u1intodigits,usingthenumberin BASE,andaddingeachintoud1aftermultiplyingud1bythe numberinBASE.Conversioncontinueslefttorightuntila (ud1caddr1u1 >NUMBER characterthatisnotconvertible,includingany"+"or"",is ud2caddr2u2) encounteredorthestringisentirelyconverted.caddr2isthe locationofthefirstunconvertedcharacterorthefirstcharacter pasttheendofthestringifthestringwasentirelyconverted.u2is thenumberofunconvertedcharactersinthestring. Here'sanexamplethatuses>NUMBER:
:PLUS0.BLWORDCOUNT>NUMBER2DROPDROP+."=".;

PLUSallowsustoprovetoanyskepticthatForthcoulduseinfixnotationifitwantedto.Wecanenter

2PLUS13

=15ok

WhenPLUSisexecuted,the"2"willbeputonthestackinbinaryform,whilethe"3"willstillbeinthe inputstreamasastring.Thephrase
0.BLWORD

readsthestringandprovidestheaccumulatorfor>NUMBER;>NUMBERconvertsittobinaryandputs thedoublelengthresultplusanunconvertedstringonthestack.Wedropthestringandthetophalfofthe doublelengthresult.Now+addsthetwosinglelengthvaluesand.printstheresult. Notethatyoucanuse>NUMBERtocreateyourownspecializednumberinputconversionroutines.Since >NUMBERreturnstheaddressofthefirstunconvertiblecharacter,youcanmakedecisionsbasedon whetherthecharacterisahyphen,dot,orwhatever.Youcanalsomakedecisionsbasedonthelocationof thenonconvertiblecharacterwithinthenumber.Forinstance,youcanwritearoutinethatletsyouentera numberwithadecimalpointinitandthenscalesitaccordingly. Togiveagoodexampleoftheuseof>NUMBER,Figure101showsadefinitionofNUMBER.This versionreadsanyofthecharacters
:,./

asvalidpunctuationmarkswhichcausethevaluetobereturnedonthestackasadoublelengthinteger.If noneofthesecharactersappearinthestring,thevalueisreturnedassinglelength. definitionusesthewordWITHINaswedefineditintheproblemsforChap.4. This

HereweusethevariablePUNCTtocontainaflagthatindicateswhetherpunctuationwasencountered. Wesuggestthatyouuseanavailableuservariableinstead. Figure101.ADefinitionofNUMBER Createsaflagthatwillcontain trueifthenumbercontains validpunctuation. Initializeflag,nopunctuation hasoccured. Getthefirstdigit. Isitaminussign? Savetheflagonthereturn stack. Ifthefirstcharacteris"",adds 1totheaddressand decrementsthecharacter count.Thiseffectivelyskips the""character,pointingto

VARIABLEpunct

:NUMBER(addrunord) 0punct! OVERC@ [CHAR]= DUP>R IF1/STRINGTHEN

0.2SWAP BEGIN >NUMBER DUP WHILE OVERC@DUP[CHAR]:= SWAP[CHAR],[CHAR]/1+WITHINOR DUPpunct! 0=ABORT"?" 1/STRING

therealfirstdigit. providesthedoublelength zeroasanaccumulator. Beginsconversion;converts untilaninvaliddigit. Whiletherearestillcharacters left,fetchtheinvaliddigit. acolon,or acomma,hyphen,periodor slash. Setpuncttoindicatewhether validpunctuationhasoccurred. Otherwiseissueanerror message. Skipthepunctuationcharacter. Exitshereifablankis detected;otherwiserepeats conversion. Dropthestringfromthestack. Iftheflagonthereturnstackis true,negatesd. Iftherewasnopunctuation, returnsasinglelengthvalueby droppingthehighordercell.

REPEAT

2DROP R>IFDNEGATETHEN

punct@0=IFDROPTHEN;

ACloserLookatWORD
SofarwehaveonlytalkedaboutusingWORDtoscantheterminalinputbuffer(whichholdsthe charactersthatareACCEPTedfromtheterminal).Butifwerecallthatthephrase
BLWORD

isusedbythetextinterpreter,werealizethatWORDactuallyscanstheinputstream,whichiseitherthe terminalinputbuffer,astringbeingEVALUATEd,ordiskmemorybeingLOADedorINCLUDED. Toachievethisflexibility,WORDusesotherpointersinadditionto>IN.Theotherpointersmakesure WORDlooksinmemory(whendoingEVALUATE),ondisk(whendoingLOADorINCLUDED)orin theterminalinputbuffer. AusefulwordtouseinconjunctionwithWORDisCOUNT.RecallthatWORDleavesthelengthofthe

wordinthefirstbyteofWORD'sbufferandalsoleavestheaddressofthisbyteonthestack. ThewordCOUNTputsthecountonthestackandincrementstheaddress,likethis: leavingthestackwithastringaddressandacountasappropriateargumentsforTYPE,MOVE,etc. COUNTisusedinthedefinitionofTEXTwhichwegaveafewsectionsback. Convertsacharacterstring,whoselengthiscontainedinitsfirst COUNT (addraddr+1u) byte,intotheformappropriateforTYPE,byleavingtheaddressof thefirstcharacterandthelengthonthestack. WewillfurtherillustratetheuseofWORDinoneoftheexamplesinChap.12.

StringComparisons
HereisaForthwordthatyoucanusetocomparecharacterstrings: Comparethestringspecifiedbycaddr1andu1tothestring specifiedbycaddr2andu2.Thestringsarecompared,beginning atthegivenaddresses,characterbycharacteruptothelengthof theshorterstring,oruntiladifferenceisfound.Ifbothstringsare (caddr1u1 thesameuptothelengthoftheshorterstring,thenthelonger COMPARE caddr2u2n) stringisgreaterthantheshorterstring.nis1ifthestring specifiedbycaddr1andu1islessthanthestringspecifiedbyc addr2andu2.niszeroifthestringsareequal.nis1ifthestring specifiedbycaddr1andu1isgreaterthanthestringspecifiedby caddr2andu2. COMPAREcanbeusedtotestwhethertwocharacterstringsareequalorwhetheroneisalphabetically greaterorlesserthantheother. Here'salistoftheForthwordswe'vecoveredinthischapter: Transmitsucharacters,beginningataddress,tothecurrent outputdevice. Eliminatestrailingblanksfromthestringthatstartsatthe TRAILING (addru1addru2) addressbyreducingthecountfromu1(originalbytecount) tou2(shortenedbytecount). Afterthismove,theubytesataddr2containexactlywhat MOVE (addr1addr2u) theubytesataddr1containedbeforethemove(no "clobbering"occurs). Copiesaregionofmemoryubyteslong,bytebybyte beginningataddr1,tomemorybeginningataddr2.The CMOVE (addr1addr2u) movebeginswiththecontentsofaddr1andproceedstoward highmemory. TYPE (addru)

KEY ACCEPT

(c) (caddru1u2)

WORD

(caddr)

>NUMBER

(ud1caddr1u1 ud2caddr2u2)

COUNT

(addraddr+1u)

CMOVE>

(addr1addr2u)

COMPARE

(caddr1u1 caddr2u2n)

BLANK

(addru)

ReturnstheASCIIvalueofthenextavailablecharacterfrom thecurrentinputdevice. Receivesucharacters(oracarriagereturn)fromthe terminalkeyboardandstoresthem,startingattheaddress. Thecountofreceivedcharactersisreturned. Readsonewordfromtheinputstream,usingthecharacter (usuallyblank)asadelimiter.Movesthestringtothe address(HERE)withthecountinthefirstbyte,leavingthe addressonthestack. ud2istheunsignedresultofconvertingthecharacters withinthestringspecifiedbycaddr1u1intodigits,using thenumberinBASE,andaddingeachintoud1after multiplyingud1bythenumberinBASE.Conversion continueslefttorightuntilacharacterthatisnot convertible,includingany"+"or"",isencounteredorthe stringisentirelyconverted.caddr2isthelocationofthe firstunconvertedcharacterorthefirstcharacterpasttheend ofthestringifthestringwasentirelyconverted.u2isthe numberofunconvertedcharactersinthestring. Convertsacharacterstring,whoselengthiscontainedinits firstbyte,intotheformappropriateforTYPE,byleaving theaddressofthefirstcharacterandthelengthonthestack. Ifuisgreaterthanzero,copyuconsecutivecharactersfrom thedataspacestartingatcaddr1tothatstartingatcaddr2, proceedingcharacterbycharacterfromhigheraddressesto loweraddresses. Comparethestringspecifiedbycaddr1andu1tothestring specifiedbycaddr2andu2.Thestringsarecompared, beginningatthegivenaddresses,characterbycharacterup tothelengthoftheshorterstring,oruntiladifferenceis found.Ifbothstringsarethesameuptothelengthofthe shorterstring,thenthelongerstringisgreaterthanthe shorterstring.nis1ifthestringspecifiedbycaddr1and u1islessthanthestringspecifiedbycaddr2andu2.nis zeroifthestringsareequal.nis1ifthestringspecifiedby caddr1andu1isgreaterthanthestringspecifiedbyc addr2andu2. StoreASCIIblanksintoubytesofmemory,beginningat addr. ReviewofTerms

Relative pointer Superstring

Avariablewhichspecifiesalocationinrelationtothebeginningofanarrayorstringnot theabsoluteaddress. inForth,acharacterarraywhichcontainsanumberofstrings.Anyonestringmaybe

Virtual memory

accessedbyindexingintothearray. thetreatmentofmassstorage(suchasthedisk)asthoughitwereresidentmemory;also themechanismoftheoperatingsystemwhichmakesthistreatmentpossible.

ProblemsChapter10
1. Entersomefamousquotationsintoanavailableblock,say3.NowdefineawordcalledCHANGE whichtakestwoASCIIvaluesandchangesalloccurrenceswithinblock3ofthefirstcharacter intothesecondcharacter.Forexample,
CHARACHARECHANGE

willchangeallthe"A"sinto"E"s.[answer] 2. DefineawordcalledFORTUNEwhichwillprintapredictionatyourterminal,suchas"Youwill receivegoodnewsinthemail."Thepredictionshouldbechosenatrandomfromalistofsixteen orfewerpredictions.Eachpredictionissixtyfourcharacters,orless,long.[answer] 3. AccordingtoOrientallegend,Buddhaendowsallpersonsbornineachyearwithspecial,helpful characteristicsrepresentedbyoneoftwelveanimals.Adifferentanimalreignsovereachyear,and everytwelveyearsthecyclerepeatsitself.Forinstance,personsbornin1900aresaidtobeborn inthe"YearoftheRat."Theartoffortunetellingbasedontheseinfluencesofthenatalyearis called"Juneeshee." Hereistheorderofthecycle:
RatOxTigerRabbitDragonSnakeHorseRamMonkeyCockDogBoar

Writeawordcalled.ANIMALthattypesthenameoftheanimalcorrespondingtoitspositionin thecycleaslistedhere;e.g.,
0.ANIMALRATok

Nowwriteawordcalled(JUNEESHEE)whichtakesasanargumentayearofbirthandprints thenameoftheassociatedanimal.(1900istheyearoftheRat,1901istheOx,etc.) Finally,writeawordcalledJUNEESHEEwhichpromptstheuserforhis/heryearofbirthand printsthenameoftheperson'sJuneesheeanimal.Defineitsothattheuserwon'thavetopress "return"afterenteringtheyear.[answer] 4. RewritethedefinitionofLETTERthatappearsinthischaptersothatitusesnamesandpersonal descriptionsthathavebeeneditedintoablock,ratherthanenteredintocharacterarrays.Inthis way,youcankeepafileonmany"prospects"andproducealetterforanyonepersonwiththe appropriatedescriptions,justbysupplyinganargumenttoLETTER,asin


1LETTER

NowdefineLETTERSsothatitprintsoneletterforeachpersoninyourfile. 5. Inthisexerciseyouwillcreateanduseavirtualarray,thatis,anarraywhichresidesondiskbut

whichisreferencedlikeamemoryresidentarray(with@and!). Firstselectanunusedblock.Putthisblocknumberinavariable.Thendefineanaccessword whichacceptsacellsubscriptfromthestack,thencomputestheblocknumbercorrespondingto thissubscript,callsBLOCKandreturnsthememoryaddressofthesubscriptedcell.Thisaccess wordshouldalsocallUPDATE.Testyourworksofar. Nextusethefirstcellasacountofhowmanydataitemsarestoredinthearray.Defineaword PUTwhichwillstoreavalueintothenextavailablecellofthearray.Defineadisplayroutine whichwillprintthestoredelementsinthearray. NowusethisvirtualarrayfacilitytodefineawordENTERwhichwillacceptpairsofnumbers andstoretheminthearray. Finally,defineTABLEtoprintthedataenteredabove,eightmembersperline.[answer]

11Extendingthecompiler:Definingwordsand Compilingwords
Incomparisonwithconventionallanguages,Forth'scompileriscompletelybackwards.Traditional compilersarehugeprogramsdesignedtotranslateanyforeseeable,legalcombinationofavailable operatorsintomachinelanguage.InForth,however,mostoftheworkofcompilationisdonebyasingle definition,onlyafewlineslong.Specialstructureslikeconditionalsandloopsarenotcompiledbythe compilerbutbythewordsbeingcompiled(IF,DO,etc.) LestyouscoffatForth'ssimpleways,noticethatForthisuniqueamonglanguagesintheeasewithwhich youcanextendthecompiler.Definingnew,specializedcompilersisaseasyasdefininganyotherword, asyouwillsoonsee. Whenyou'vegotanextensiblecompiler,you'vegotaverypowerfullanguage!

Justaquestionoftime
Beforewegetfullyintothischapter,let'sreviewoneparticularconceptthatcanbeaproblemto beginningForthprogrammers.It'saquestionoftime. Wehaveusedtheterm"runtime"whenreferringtothingsthatoccurwhenawordisexecutedand "compiletime"whenreferringtothingsthathappenwhenawordiscompiled.Sofarsogood.Butthings getalittleconfusingwhenasinglewordhasbotharuntimeandacompiletimebehavior. Ingeneraltherearetwoclassesofwordswhichbehaveinbothways.Forpurposesofthisdiscussion, we'llcallthesetwoclasses"definingwords"and"compilingwords." Adefiningwordisaawordwhich,whenexecuted,compilesanewdefinition.Adefiningwordspecifies thecompiletimeandruntimebehaviorofeachmemberofthe"family"ofwordsthatitdefines.Using thedefiningwordCONSTANTasanexample,whenwesay
80CONSTANTMARGIN

weareexecutingthecompiletimebehaviorofCONSTANT;thatis,CONSTANTiscompilinganew constanttypedictionaryentrycalledMARGINandstoringthevalue80intoitsparameterfield.Butwhen wesay


MARGIN

weareexecutingtheruntimebehaviorofCONSTANT;thatis,CONSTANTispushingthevalue80onto thestack.We'llpursuedefiningwordsfurtherinthenextfewsections. Theothertypeofwordwhichpossessesdualbehavioristhe"compilingword."Acompilingwordisa wordthatweuseinsideacolondefinitionandthatactuallydoessomethingduringcompilationofthat definition. Oneexampleistheword.",whichatcompiletimecompilesatextstringintothedictionaryentrywith thecountinfront,andatruntimetypesit.OtherexamplesarecontrolstructurewordslikeIFandLOOP, whichalsohavecompiletimebehaviorsdistinctfromtheirruntimebehaviors.We'llexplorecompiling wordsafterwe'vediscusseddefiningwords.

HowtoDefineaDefiningWord
HerearethestandardForthdefiningwordswe'vecoveredsofar:
: VARIABLE 2VARIABLE CONSTANT 2CONSTANT CREATE

Whatdotheyallhaveincommon?Eachofthemisusedtodefineasetofwordswithsimilarcompile timeandruntimecharacteristics. Andhowareallthesedefiningwordsdefined?Firstwe'llanswerthisquestionmetaphorically. Let'ssayyou'reintheceramicsaltshakerbusiness.Ifyouplantomakeenoughsaltshakers, you'llfindit'seasiesttomakeamoldfirst.Amoldwillguaranteethatallyourshakerswillbe ofthesamedesign,whileallowingyoutomakeeachshakeradifferentcolor.Inmakingthemold,you mustconsidertwothings: 1. Howthemoldwillwork.(E.g.,howwillyougettheclayintoandoutofthemoldwithout breakingthemoldorlettingtheseamsshow?) 2. Howtheshakerwillwork.(E.g.,howmanyholesshouldtherebe?Howmuchsaltshouldithold? Etc.) TobringthisanalogybacktoForth,thedefinitionofadefiningwordmustspecifytwothings:the compiletimebehaviorandtheruntimebehaviorforthattypeofword. Holdthatthoughtamomentwhilewelookatthemostbasicofthedefiningwordsintheabovelist: CREATE.Atcompiletime,CREATEtakesanamefromtheinputstreamandcreatesadictionary headingforit. 7 E link X A M P L E Atruntime,CREATEpushesthebodyaddressofEXAMPLE

executiontoken (body)

ontothestack. WhathappensifweuseCREATEinsideadefinition?Considerthisexample,whichisthedefinitionfor VARIABLE:


:VARIABLECREATE0,;

WhenweexecuteVARIABLEasin
VARIABLEORANGES

WeareindirectlyusingCREATEtocreateadictionaryheadwiththenameORANGESandanxtthat pointstoCREATE'sruntimecode.Thenweareallottingacellforthevariableitself(with"0,"). SincetheruntimebehaviorofavariableisidenticaltothatofaworddefinedbyCREATE,VARIABLE doesnotneedtohaveruntimecodeofitsown,itcanuseCREATE'sruntimecode. Howdowespecifyadifferentruntimebehaviorinadefiningword?ByusingthewordDOES>,as shownhere:


:DEFININGWORDCREATE(compiletimeoperations) DOES>(runtimeoperations);

Toillustrate,thefollowingcouldbeavaliddefinitionforCONSTANT(althoughinfactCONSTANTis usuallydefinedinmachinecode):
:CONSTANTCREATE,DOES>@;

Toseehowthisdefinitionworks,imaginewe'reusingittodefineaconstantnamedTROMBONES,like this:
76CONSTANTTROMBONES

CREATE Createanewdictionaryentry(e.g.,TROMBONES) compiletime portion , Compilesthevalue(e.g.,76)fortheconstantfromthestackintothe constant'sparameterfield.

runtime portion

Markstheendofthecompiletimebehaviorandthebeginningoftherun DOES> timebehavior.Atruntime,DOES>willleavethebodyaddressoftheword beingdefinedonthestack. @ Fetchesthecontentsoftheconstant,usingthebodyaddressthatwillbeon thestackatruntime.

ThewordsthatprecedeDOES>specifywhatthemoldwilldo;thewordsthatfollowDOES>specify whattheproductofthemoldwilldo.

DOES>

runtime: (addr)

Usedincreatingadefiningword;markstheendofitscompiletimeportion andthebeginningofitsruntimeportion.Theruntimeoperationsarestated inhigherlevelForth.Atruntime,thebodyaddressofthedefinedwordwill beonthestack.

DefiningWordsYouCandefineYourself
Herearesomeexamplesofdefiningwordsthatyoucancreateyourself. Recallthatinourdiscussionof"StringInputCommands"inChap.10,wegaveanexamplethatemployed characterstringarrayscalledNAME,EYES,andME.Everytimeweusedoneofthesenames,wefollowed itwithacharactercount.Intheinputdefinition,wewrote
...PADNAME14MOVE

andintheoutputdefinitionwewrote
...NAME14TRAILINGTYPE...

andsoon. Let'seliminatethecountbycreatingadefiningwordcalledCHARACTERS,whoseproductdefinitions willleavetheaddressandcountonthestackwhenexecuted. We'lluseitlikethis:ifwesay


20CHARACTERSME

wewillcreateanarraycalledME,withtwentycharactersavailableforthecharacterstring. WhenweexecuteME,we'llgettheaddressofthearrayandthecountonthestack.Nowwecanwrite
PADMEMOVE

insteadof
PADME20MOVE

or
METRAILINGTYPE

insteadof
ME20TRAILINGTYPE

Here'showwemightdefineCHARACTERS: :CHARACTERS

CREATE compiletime portion DUP,ALLOT

Createanewdictionaryentry(e.g.,ME) Compilesthecount(e.g.,twenty)intothefirstcellofthearray forfuturereference.Thenallotsanadditionaltwentybytes beyondthecountforthestring.

DOES> DUP runtime portion CELL+ SWAP@

Marksthebeginningofruntimecode,leavingthebodyaddressofthe productwordonthestackatruntime. Copiesthebodyaddress. Advancestheaddresstopointpastthecount,tothestartofthecharacter string. Swapsthestringaddresswiththecountaddressandfetchesthecount. Thestacknowholds(addrcount).

; Wehavejustextendedourcompiler!OurnewwordCHARACTERSisadefiningwordthatcreatesadata structureandprocedurethatwefinduseful.CHARACTERSnotonlysimplifiesourinputandoutput definitions,italsoallowsustochangethelengthofanystring,shouldtheneedarise,inoneplaceonly (i.e.,wherewedefineit). Ournextexamplecouldbeusefulinanapplicationwherealargenumberofbyte(notCHAR!)arraysare needed.Let'screateadefiningwordcalledSTRINGasfollows:


:STRINGCREATEALLOTDOES>+;

tobeusedintheform
30STRINGVALVE

tocreateanarraythirtybytesinlength.Toaccessanybyteinthisarray,wemerelysay:
6VALVEC@

whichwouldgiveusthecurrentsettingofhydraulicvalve6atanoilpumpingstation.Atruntime, VALVEwilladdtheargument6tothebodyaddressleftbyDOES>,producingthecorrectbyteaddress. Ifourapplicationrequiresalargenumberofarraystobeinitializedtozero,wemightincludethe initializationinanalternatedefiningwordcalled0STRING:


:ERASEDHEREOVERERASEALLOT; :0STRINGCREATEERASEDDOES>+;

FirstwedefineERASEDtoERASEthegivennumberofbytes,startingatHERE,beforeALLOTingthe givennumberofbytes. ThenwesimplysubstituteERASEDforALLOTinournewversion.

Bychangingthedefinitionofadefiningword,youcanchangethecharacteristicsofallthemember wordsofthatfamily.Thisabilitymakesprogramdevelopmentmucheasier.Forinstance,youcan incorporatecertainkindsoferrorcheckingwhileyouaredevelopingtheprogram,theneliminatethem afteryouaresurethattheprogramrunscorrectly. HereisaversionofSTRINGwhich,atruntime,guaranteesthattheindexintothearrayisvalid:


:STRINGCREATEDUP,ALLOT DOES>2DUP@U<0=ABORT"Rangeerror"+CELL+;

whichbreaksdownasfollows: DUP,ALLOT DOES>2DUP@ Compilesthecountandallotsthegivennumberofbytes. Atruntime,giventheargumentonthestack,produces(argpfaarg count). Teststhattheargumentisnotlessthanthemaximum,i.e.,the storedcount.SinceU<isanunsignedcompare,negativearguments willappearasveryhighnumbersandthuswillalsofailthetest. Checkifthecomparisontestfails. Otherwiseaddstheargumenttothebodyaddress,plusan additionalcelltoskipthecount.

U<0= ABORT"Rangeerror" +CELL+

Here'sanotherwaythattheuseofdefiningwordscanhelpduringdevelopment.Let'ssayyousuddenly decidethatallofthearraysyou'vedefinedwithSTRINGaretoolargetobekeptincomputermemory andshouldbekeptondiskinstead.AllyouhavetodoisredefinetheruntimeportionofSTRING.This newSTRINGwillcomputewhichrecordonthediskagivenbytewouldbecontainedin,readtherecord intoabufferusingINCLUDED,andreturntheaddressofthedesiredbytewithinthebuffer.Astring definedinthiswaycouldspanmanyconsecutiverecords(usingthesametechniqueasinProb.5,Chap. 10). Youcanusedefiningwordstocreateallkindsofdatastructures.Sometimes,forinstance,it'susefulto createmultidimensionalarrays.Here'sanexampleofadefiningwordwhichcreatestwodimensional bytearraysofgivensize:
:ARRAY(#rows#cols) CREATEDUP,*ALLOT DOES>(member:rowcoladdr) ROTOVER@*++CELL+;

c0 c1 c2 c3 r0 r1 r2 r3

Tocreateanarrayfourbytesbyfourbytes,wewouldsay
44ARRAYBOARD

Toaccess,say,thebyteinrow2,column1,wecouldsay
21BOARDC@

Here'showourARRAYworksingeneralterms.Sincethecomputeronlyallowsustohaveone dimensionalarrays,wemustsimulatetheseconddimension.Whileourimaginaryarraylookslikethis

c0 c1 c2 c3 r0 0 1 2 3 r1 4 5 6 7 r2 8 9 10 11 r3 12 13 14 15 ourrealarraylookslikethis row# offs 0 0123 1 4567 2 891011 3 12131415

Ifyouwanttheaddressofthebyteinrow2,column1,itcanbecomputedbymultiplyingyourrow number(2)bythenumberofcolumnsineachrow(4)andthenaddingyourcolumnnumber(1),which indicatesthatyouwanttheninthbyteintherealarray.ThiscalculationiswhatmembersofARRAYmust doatruntime.You'llnoticethat,toperformthiscalculation,eachmemberwordneedstoknowhow manycolumnsareineachrowofitsparticulararray.Forthisreason,ARRAYmuststorethisvalueinto thebeginningofthearrayatcompiletime. Forthecurious,herearethestackeffectsoftheruntimeportionofarray: Operation ... ROT OVER@ * ++ CELL+ Contentsofstack rowcolpfa colpfarow colpfarow#cols colpfarowindex address correctedaddress

Itisnecessarytoaddacelltothecomputedaddressbecausethefirstcellofthearraycontainsthe numberofcolumns. Ourfinalexampleisthemostvisuallyexciting,ifnotthemostuseful.


\Shapes,usingadefiningword. DECIMAL :star[CHAR]*EMIT; :.rowCR80DO DUP128ANDIFstar ELSESPACE THEN 1LSHIFT LOOPDROP;

:SHAPECREATE80DOC,LOOP DOES>DUP7+DOIC@.row1+LOOPCR; HEX18183C5A99242424SHAPEman 8142241818242481SHAPEequis AAAAFEFE383838FESHAPEcastle DECIMAL

.ROWprintsapatternofstarsandspacesthatcorrespondtothe8bitnumberonthestack.Forinstance:
2BASE!ok 00111001.ROW ****ok DECIMALok

ThedefiningwordSHAPEtakeseightargumentsfromthestackanddefinesashapewhich,when executed,printsan8by8gridthatcorrespondstotheeightarguments.Forexample:
MAN ** ** **** **** **** ** ** ** ok

Insummary,definingwordscanbeextremelypowerfultools.Whenyoucreateanewdefiningword,you extendyourcompiler.TraditionallanguageslikeFortranorBASICdonotprovidethisflexibilitybecause thesetraditionalcompilersandinterpretersareinflexiblepackagesthatsay,"Usemyinstructionsetor forgetit!" Therealpowerofdefiningwordsisthattheycansimplifyyourproblem.Usingthemwell,youcan shortenyourprogrammingtime,reducethesizeofyourprogram,andimprovereadability.Forth's flexibilityinthisregardissoradicalincomparisonwithtraditionallanguagesthatmanypeopledon't evenbelieveit.Well,nowyou'veseenit. ThenextsectionintroducesstillanotherwaytoextendtheabilityofForth'scompiler.

HowtoControltheColonCompiler
Compilingwordsarewordsusedinsidecolondefinitionstodosomethingatcompiletime.Themost obviousexamplesofcompilingwordsarecontrolstructurewordssuchasIF,THEN,DO,LOOP,etc. BecauseForthprogrammersdon'toftenchangethewaytheseparticularwordswork,we'renotgoingto studythemanyfurther.Insteadwe'llexaminethegroupofwordsthatcontrolthecoloncompilerandthus canbeusedtocreateanytypeofcompilingword. Recallthatthecoloncompilerordinarilylooksupeachwordofasourcedefinitionandcompileseach word'saddressintothedictionaryentrythat'sall.Butthecoloncompilerdoesnotcompiletheaddressof acompilingworditexecutesit. Howdoesthecoloncompilerknowthedifference?Bycheckingthedefinition's"precedencebit."Ifthe bitis"off,"theaddressofthewordiscompiled.Ifthebitis"on,"thewordisexecutedimmediately;such

wordsarecalled"immediate"words. ThewordIMMEDIATEmakesaword"immediate."Itisusedintheform:
:namedefinition;IMMEDIATE

thatis,itisexecutedrightafterthecompilationofthedefinition. Togiveanimmediateexample,let'sdefine
:SAYHELLO."Hello";IMMEDIATE

WecanexecuteSAYHELLOinteractively,justaswecouldifitwerenotimmediate.
SAYHELLOHellook

ButifweputSAYHELLOinsideanotherdefinition,itwillexecuteatcompiletime:
:GREETSAYHELLO."IspeakForth";Hellook

ratherthanatexecutiontime:
GREETIspeakForthok

Beforewegoon,let'sclarifyourterminology.Forthfolksadheretoaconventionregardingtheterms"run time"and"compiletime."Inthisexample,thetermsaredefinedrelativetoGREET.Thuswewouldsay thatSAYHELLOhasa"compiletimebehavior"butno"runtimebehavior."Clearly,SAYHELLOdoes havearuntimebehaviorofitsown,butrelativetoGREETitdoesnot. Tokeepourlevelsstraight,let'scallGREETinthisexamplethe"compilee";thatis,thedefinitionwhose compilationwe'rereferringto.SAYHELLOhasnoruntimebehaviorinrelationtoitscompilee. Here'sanexampleofanimmediatewordthatyou'refamiliarwith:thedefinitionofthecompilingword BEGIN.It'ssimplerthanyoumighthavethought:


:BEGINHERE;IMMEDIATE

BEGINsimplysavestheaddressofHEREatcompiletimeonthestack.Why?Becausesoonerorlateran UNTILorREPEATisgoingtocomealong,andeitherhastoknowwhataddressinthedictionaryto returntointheeventthatitmustrepeat.ThisistheaddressthatBEGINleftonthestack. BEGIN'scompiletimebehaviorisleavingHEREonthestack.ButBEGINcompilesnothingintothe compilee;thereisnoruntimebehaviorforBEGIN. UnlikeBEGIN,mostcompilingwordsdohavearuntimebehavior.Tohavearuntimebehavior,aword hastocompileintothecompileetheaddressoftheruntimebehavior,whichmustalreadyhavebeen definedasaword. AgoodexampleisDO.LikeBEGIN,DOmustprovide,atcompiletime,aHEREforLOOPor+LOOP toreturnto.ButunlikeBEGIN,DOalsohasaruntimebehavior:itmustpushthelimitandindexonto thereturnstack. TheruntimebehaviorofDOisdefinedbyalowerlevelword,sometimescalled(DO)or2>R.The definitionofDOisthis:
:DOPOSTPONE2>RHERE;IMMEDIATE

... 2>R ... compileedefinition

ThewordPOSTPONEfindstheaddressofthenextwordinthedefinition(inthiscase2>R)and compilesitsaddressintothecompileedefinition,sothatatruntime2>Rwillbeexecuted.
Anotherexampleisthedefinitionof;.Atcompiletime,semicolonmustdothefollowingthings: 1. compiletheaddressofEXITintothedictionaryentrybeingcompiled, 2. exposethenewwordtothecoloncompiler,and 3. leavecompilationmode. Here'sthedefinitionofsemicolon: :;POSTPONEEXITREVEALPOSTPONE[;IMMEDIATE ThefirstphrasecompilesEXIT,providingtheruntimebehavior.Thesecondphrase,whichisthecompile timebehavior,firstexposesthewordbeingcompiledandthengetsoutofthecompiler. WhatisthereasonforREVEAL?Whenwordsareintheprocessofbeingcompiled,theyarenotyetfindable bythecoloncompiler.Thisisdonetomakeitpossibletoredefineexistingwordsintermsoftheolddefinition plusadditionalcode,forexample: :CRCRSPACE; IfduringthecompilationofthenewCRitsnamewerefindable,thenameoftheoriginalCRwouldbe blocked,andwewouldhavehadtodo,e.g.: :_cr_CR; :CR_cr_SPACE;

ThewordPOSTPONEcanalsobeusedtocompileanimmediatewordasthoughitwerenotimmediate. Givenourpreviousexample,inwhichSAYHELLOisanimmediatedefinition,wemightdefine
:GREETPOSTPONESAYHELLO."IspeakForth";ok

toforceSAYHELLOtobecompiledratherthanexecutedatcompiletime.Thus:
GREETHelloIspeakForthok

Besuretonotethe"intelligence"builtintoPOSTPONE.POSTPONEparsesthenextwordintheinput stream,decidesifitisimmediateornot,andproceedsaccordingly.Ifthewordwasnotimmediate, POSTPONEcompilestheaddressofthewordintoacompileedefinition;thinkofitasdeferred compilation.Ifthewordisimmediate,POSTPONEcompilestheaddressofthiswordintothedefinition currentlybeingdefined;thisisordinarycompilation,butofanimmediatewordwhichotherwisewould havebeenexecuted. Toreview,herearethetwowordswhichareusefulincreatingnewcompilingwords: IMMEDIATE () POSTPONExxx () Marksthemostrecentlydefinedwordasonewhich,whenencounteredduring compilation,willbeexecutedratherthanbeingcompiled. 1. Usedinthedefinitionofacompilingword.Whenthecompilingword,in turn,isusedinasourcedefinition,theexecutiontokenofxxxwillbe compiledintothedictionaryentrysothatwhenthenewdefinitionis

executed,xxxwillbeexecuted. 2. Usedinacolondefinition,causestheimmediatewordxxxtobecompiled asthoughitwerenotimmediate;xxxwillbeexecutedwhenthedefinition isexecuted.

MoreCompilercontrollingWords
Therearetwoothercompilercontrolwordsyoushouldknow.Thewords[and]canbeusedinsidea colondefinitiontostopcompilationandstartitagain,respectively.Whateverwordsappearbetweenthem willbeexecuted"immediately",i.e.,atcompiletime. Considerthisexample:
:SAYHELLO."Hello"; :GREET[SAYHELLO]."IspeakForth";Hellook GREETIspeakForthok

Inthisexample,SAYHELLOisnotanimmediateword,yetwhenwecompileGREET,SAYHELLO executes"immediately." ForabetterexamplewefirstneedtointroducethewordLITERAL. Asyoumayrecall,anumberthatappearsinacolondefinitioniscalleda"literal."Anexampleisthe"4" inthedefinition


:FOURMORE4+;

Theuseofaliteralinacolondefinitionrequirestwocells.Thefirst containstheexecutiontokenofaroutinewhich,whenexecuted,will pushthecontentsofthesecondcell(thenumberitself)ontothestack. Thenameofthisroutinemayvary;let'scallitthe"runtimecodefora literal,"orsimply(LITERAL).Whenthecoloncompilerencountersa number,itfirstcompilestheruntimecodeforaliteral,thencompiles thenumberitself. ThewordyouwillusemostoftentocompilealiteralisLITERAL(no parentheses).LITERALcompilesboththeruntimecodeandthevalue itself.Toillustrate:
:FOURMORE[4]LITERAL+;

9 F O U R M O R E link executiontoken (LITERAL) 4 + EXIT

HerethewordLITERALwillcompileasaliteralthe"4"thatweputonthestackbetweenthesquare brackets.Wegetadictionaryentrythatisidenticaltotheoneshownabove. ForamoreusefulapplicationofLITERAL,recallthatinChap.8wecreatedanarraycalledLIMITS thatconsistedoffivecells,eachofwhichcontainedthetemperaturelimitforadifferentburner.To simplifyaccesstothisarray,wecreatedawordcalledLIMIT.Thetwodefinitionslookedlikethis:


VARIABLELIMITS4CELLSALLOT :LIMIT(indexaddr)CELLSLIMITS+;

Nowlet'sassumewewillonlyaccessthearraythroughthewordLIMIT.Wecaneliminatetheheadof thearray(somebytesandonecell)byusingthisconstructioninstead:
HERE5CELLSALLOTBASE! :LIMIT(indexaddr)CELLS[BASE@]LITERAL+; DECIMAL

Inthefirstlineweputtheaddressofthebeginningofthearray(HERE)inthesystemvariableBASE (anyotherscratchvariablewillwork).Inthesecondline,wecompilethisaddressasaliteralintothe definitionofLIMIT. NowweknowallthereistoknowaboutLITERAL,wecanalso giveabetterexampleof[and].Imagineacolondefinitionin whichweneedtotypethebytefromrow2,column3,ofthe arrayBOARDwedefinedintheprevioussection.Togetthe addressofthisbyte,wecouldusethephrase


BOARD28(#cols)*3+CELL++

Newversion 5 CELLS headforLIMIT CELLS (LITERAL) addr + EXIT

Oldversion headforLIMITS 5 CELLS headforLIMIT CELLS LIMITS + EXIT

butit'stimeconsumingtoexecute
28*3+

everytimeweusethisdefinition.Alternatively,wecouldwrite
BOARD19CELL++

butit'suncleartohumanreadersexactlywhat19means,anditis irritatingthat,forportability,westillhavetowriteCELL+ although1CELLSisjustaconstant. ... 23 ... Thebestsolutionistowrite

(LITERAL) BOARD[28(#cols)*3+CELL+]LITERAL+ Herethearithmeticisperformedonlyonce,atcompiletime,andtheresultiscompiledas aliteral.

Here'sasillyexamplewhichmaygiveyousomeideasformorepracticalapplications. Thisdefinitionlet'syoupeekintotheinnardsoftheworditself:
:DUMPTHIS[HERE]LITERAL32DUMP."DUMPTHIS";

WhenyouexecuteDUMPTHIS,youwilldumpthememoryintowhichDUMPTHISwasdefined.You shouldseehowyourForthcompilestheliteralvalueof"here,"theliteral"32,"theexecutiontokenof DUMP,andthenhowitinlinesthestring"DUMPTHIS."(Atcompiletime,HEREpointstotheaddress ofthenextfreecodebyte.LITERALcompilesthisnumberintothedefinitionasaliteral,sothatitwill serveastheargumentforDUMPatruntime.) Bytheway,here'sthedefinitionofLITERAL:


:LITERALPOSTPONE(LITERAL),;IMMEDIATE

Firstitcompilestheaddressoftheruntimecode,thenitcompilesthevalueitself(usingcomma).

Tosummarize,herearetheadditionalcompilercontrolwordsweintroducedinthissection: compiletime( Usedonlyinsideacolondefinition.Atcompiletime,compilesavalue LITERAL ) fromthestackintothedefinitionasaliteral.Atruntime,thevalue runtime(n) willbepushedonthestack. [ ] () () Leavescompilationmode. Enterscompilationmode.

Curtaincalls
Thissectiongivesusachancetosay"Goodbye"tothetextinterpreterandthe coloncompilerandperhapstoseetheminanewlight. HereisadefinitionofINTERPRETthatwillworkinmostForthsystems:
:INTERPRET() BEGIN BLWORDFINDIFEXECUTE?STACKABORT"Stackempty" ELSENUMBER THEN AGAIN;

We'vecoveredeachofthewordscontainedinthisdefinition;wecandescribeINTERPRETinEnglishby simply"translating"itsdefinition,likethis:
Beginaloop.Withintheloop,trytolookupthenextwordfromtheinputstream.Ifit'snotdefined,tryto convertittoanumber.Ifitisdefined,executeit,thenchecktoseewhetherthestackisempty.(Ifitis,exitthe loopandprint"STACKEMPTY.")Thenrepeattheinfiniteloop.

Asyoucansee,theForthtextinterpreterisasimpleyetpowerfulstructure.Nowlet'scompareits structurewiththatofthecoloncompiler:
:]() BEGIN BLWORDFINDDUPIF1=IFEXECUTE?STACKABORT"Stackempty" ELSE, THEN ELSEDROP(NUMBER)POSTPONELITERAL

THEN AGAIN;

Thefirstthingyouprobablynoticedisthatthenameofthecoloncompilerisnot:,but].Thedefinition of:invokes]aftercreatingthedictionaryheadandperformingafewotheroddjobs. Thenextthingyoumayhavenoticedisthatthecompilerissomewhatsimilartotheinterpreter.Let's translatethedefinitionintoEnglish:


Beginaloop.Withintheloop,trytolookupthenextwordfromtheinputstream.Ifit'snotdefined,tryto convertittoanumberand,ifit'sanumber,compileitasaliteral. Ifitisdefined,FINDhastestedtheword'sprecedencebit.Ifthewordisimmediate,thenexecuteitandcheck toseewhetherthestackisempty.Ifitisnotimmediate,FINDreturnedanexecutiontokenthatcanbe compiled.Thenrepeattheinfiniteloop.

ComparethistoINTERPRETandyou'llseethat]couldbecalledaninterpreterwiththeabilitytodecide whethertoexecuteorcompileanygivenword.Itisthesimplicityofthisdesignthatlet'syouaddnew compilingwordssoeasily. Insummary,we'veshowntwowaystoextendtheForthcompiler: 1. Addnew,specializedcompilers,bycreatingnewdefiningwords. 2. Extendtheexistingcoloncompilerbycreatingnewcompilingwords. Whiletraditionalcompilerstrytobeuniversaltools,theForthcompilerisacollectionofseparate,simple tools...withroomformore. Whichapproachseemsmoreuseful:

Hereisasummaryofthewordswe'vecoveredinthischapter: runtime: (addr) Usedincreatingadefiningword;markstheendofits compiletimeportionandthebeginningofitsruntime portion.Theruntimeoperationsarestatedinhigherlevel Forth.Atruntime,thebodyaddressofthedefinedwordwill beonthestack. Marksthemostrecentlydefinedwordasonewhich,when encounteredduringcompilation,willbeexecutedratherthan beingcompiled. 1. Usedinthedefinitionofacompilingword.Whenthe compilingword,inturn,isusedinasource definition,theexecutiontokenofxxxwillbe compiledintothedictionaryentrysothatwhenthe newdefinitionisexecuted,xxxwillbeexecuted. 2. Usedinacolondefinition,causestheimmediate wordxxxtobecompiledasthoughitwerenot immediate;xxxwillbeexecutedwhenthedefinition

DOES>

IMMEDIATE

()

POSTPONExxx ()

isexecuted. Usedonlyinsideacolondefinition.Atcompiletime, compiletime() compilesavaluefromthestackintothedefinitionasa runtime(n) literal.Atruntime,thevaluewillbepushedonthestack. () () Leavescompilationmode. Enterscompilationmode.

LITERAL [ ]

ReviewofTerms
Compiletime behavior 1. whenreferringtodefiningwords:thesequenceofinstructionswhichwillbe carriedoutwhenthedefiningwordisexecutedtheseinstructionsperform thecompilationofthememberwords; 2. whenreferringtocompilingwords:thebehaviorofacompilingword, containedwithinacolondefinition,duringcompilationofthedefinition. adefinitionbeingcompiled.Inrelationtoacompilingword,thecompileeisthe definitionwhosecompilationthecompilingwordaffects. awordusedinsideacolondefinitiontotakesomeactionduringthecompilation process. awordwhich,whenexecuted,compilesanewdictionaryentry.Adefiningword specifiesthecompiletimeandruntimebehaviorofeachmemberofthe"family"of wordsthatitdefines. InForthdictionaryentries,abitwhichindicateswhetherawordshouldbeexecuted ratherthanbecompiledwhenitisencounteredduringcompilation. 1. whenreferringtodefiningwords:thesequenceofinstructionswhichwillbe carriedoutwhenanymemberisexecuted; 2. whenreferringtocompilingwords:aroutinewhichwillbeexecutedwhen thecompileeisexecuted.Notallcompilingwordshaveruntimebehavior.

Compilee Compilingword

Definingword

Precedencebit

Runtime behavior

ProblemsChapter11
1. DefineadefiningwordnamedLOADEDBYthatwilldefinewordswhichincludeafilewhen theyareexecuted.Example:
S"mail.forth"LOADEDBYCORRESPONDENCE

woulddefinethewordCORRESPONDENCE.WhenCORRESPONDENCEisexecuted,thefile mail.forthisincluded(Hint:SLITERALisNOTusefulhere).[answer] 2. DefineadefiningwordBASED.whichwillcreatenumberoutputwordsforspecificbases.For example,


16BASED.H.

woulddefineH.tobeawordwhichprintsthetopofthestackinhexbutdoesnotpermanently changeBASE.
DECIMAL 17DUPH.. 1117ok

[answer] 3. DefineadefiningwordcalledPLURALwhichwilltaketheaddressofawordsuchasCRor STARandcreateitspluralform,suchasCRSorSTARS.You'llprovidePLURALwiththe executiontokenofthesingularwordbyusingtick.Forinstance,thephrase


'CRPLURALCRS

willdefineCRSinthesamewayasthoughyouhaddefinedit
:CRS(times)0?DOCRLOOP;

[answer] 4. TheFrenchwordsforDOandLOOPareTOURNEandRETOURNE.UsingthewordsDOand LOOP,defineTOURNEandRETOURNEasFrench"aliases."Nowtestthembywritingyourselfa frenchloop.[answer] 5. WriteawordcalledLOOPSwhichwillcausetheremainderoftheinputstream,uptothecarriage return,tobeexecutedthenumberoftimesspecifiedbythevalueonthestack.Forexample,


7LOOPSCHAR*EMITSPACE *******ok

[answer]

12ThreeExamples
ProgramminginForthismoreofan"art"thanprogramminginanyotherlanguage.Likepaintersdrawing brushstrokes,Forthprogrammershavecompletecontroloverwheretheyaregoingandhowtheywillget there.CharlesMoorehaswritten,"AgoodprogrammercandoafantasticjobwithForth;abad programmercandoadisastrousjob."AgoodForthprogrammermustbeconsciousof"style." Forthstyleisnoteasilytaught;it'sasubjectthatdeservesabookofitsown.Someelementsofgood Forthstyleinclude:

simplicity, theuseofmanyshortdefinitionsratherthanafewlongerones, acorrespondencebetweenwordsandeasytounderstandactionsordatastructures, wellchosennames,and welllaidoutfiles,clearlycommented.

Onegoodwaytolearnstyle,asidefromtrialanderror,istostudyexistingForthapplications,including Forthitself.Inthisbookwe'veincludedthedefinitionsofmanyForthsystemwords,andweencourage youtocontinuethisstudyonyourown. ThischapterintroducesthreeapplicationswhichshouldserveasexamplesofgoodForthstyle. ThefirstexamplewillshowyouthetypicalprocessofprogramminginForth:startingoutwithaproblem andworkingstepbysteptowardsthesolution. Thesecondexampleinvolvesamorecomplexapplicationalreadywritten:youwillseetheuseofwell factoreddefinitionsandthecreationofanapplicationspecific"language." ThethirdexampledemonstratesthewaytotranslateamathematicalequationintoaForthdefinition;you willseethatworkingwithfixedpointarithmeticdoesnotnecessarilymeansacrificingspeedand compactness.

1.WORDgame
TheexampleinthissectionisarefinementofthebuzzphrasegeneratorweprogrammedbackinChap. 10.(Youmightwanttoreviewthatversionbeforereadingthissection.)Thepreviousversiondidnotkeep trackofitsowncarriagereturns,causingustoforceCRsintothedefinitionandcreatingaveryragged rightmargin.Thejobofdecidinghowmanywholewordscanfitonalineisareasonableapplicationfor acomputerandnotatrivialone. Theproblemisthis:todrafta"brief"whichconsistsoffourparagraphs,eachparagraphconsistingofan appropriateintroductionandsentence.Eachsentencewillconsistoffourrandomlychosenphraseslinked togetherbyfillerstocreategrammaticallylogicalsentencesandaperiodattheend. Thewordsandphraseshavealreadybeeneditedintothefilephrases.forth.Lookatthisfilenow, withoutlookingatwordgame.forth.(we'repretendingwehaven'twrittentheapplicationyet). Filephrases.forthdefinesthefourintroductions,compiledintotheINTROSstringarray.Thefour (ormore,INTROSisselforganizing)introductionsmustbeusedinsequence.Thesamefile phrases.forthcontainsfoursetsoffillers,inFILLER.Thefoursetsareusedinsequence,butany ofthethreeversionswithinaset(organizedincolumns)ischosenatrandom.Again,phrases.forth containsthethreecolumnsofbuzzwordsfromourpreviousversion,withsomeaddedwords.We've organizedthebuzzwordsinseparate1STADJECTIVE,2NDADJECTIVEandNOUNstringarrays. Youmighalsolookatatthesampleoutputthatprecedestheendofthissection,togetabetterideaofthe desiredresult. "Topdowndesign"isawidelyacceptedapproachtoprogrammingthatcanhelptoreducedevelopment time.Theideaisthatyoufirststudyyourapplicationasawhole,thenbreaktheproblemintosmaller processes,thenbreaktheseprocessesintostillsmallerunits.Onlywhenyouknowwhatalltheunits shoulddo,andhowtheywillconnecttogether,doyoubegintowritecode. TheForthlanguageencouragestopdowndesign.ButinForthyoucanactuallybegintowritetoplevel

definitionsimmediately.Alreadywecanimaginethatthe"ultimateword"inourapplicationmightbe calledPAPER,andthatitwillprobablybedefinedsomethinglikethis:
:PAPER40DOIINTROSENTENCELOOP;

whereINTROusestheloopindexasitsargumenttoselecttheappropriateintroduction.SENTENCE couldbedefined
:SENTENCE40DOIPHRASELOOPENDS;

wherePHRASEusestheloopindexasitsargumenttoselecttheappropriateset,thenchoosesoneofthe threeversionswithintheset.ENDStakescareofthefinal'.'andCRattheendofasentence. Usingourfavoriteeditor,wecanenterthesetopleveldefinitionsintowordgame.forth.Ofcoursewe can'tINCLUDEthisfileuntilwehavewrittenourlowerleveldefinitions. Incomplicatedapplications,Forthprogrammersoftentestthelogicoftheirtopleveldefinitionsbyusing "stubs"forthelowerlevelwords.Astubisatemporarydefinition.Itmightsimplyprintamessagetolet usknowitsbeenexecuted.Oritmaydonothingatall,exceptresolvethereferencetoitsnameinthe highleveldefinition. Whilethetopdownapproachhelpstoorganizetheprogrammingprocess,itisn'talwaysfeasibletocode inpurelytopdownfashion.Usuallywehavetofindouthowcertainlowlevelmechanismswillwork beforewecandesignthehigherleveldefinitions. Thebestcompromiseistokeepaperspectiveontheproblemasawholewhilelookingoutforlowlevel problemswhosesolutionsmayaffectthewholeapplication. Inourexampleapplication,wecanseethatitwillnolongerbepossibletoforceCRsatpredictable points.Insteadwe'vegottoinventamechanismwherebythecomputerwillperformcarriagereturns automatically. Theonlywaytosolvethisproblemistocounteverycharacterthatistyped.Beforeeachwordistyped, theapplicationmustdecidewhetherthereisroomtotypeitonthecurrentlineordoacarriagereturn first. Solet'sdefinethevariableLINECOUNTtokeepthecountandtheconstantRMARGINwiththevalue78, torepresentthemaximumcountperline.Eachtimewetypeawordwewilladditscountto LINECOUNT.Beforetypingeachwordwewillexecutethisphrase:
(lengthofnextword)LINECOUNT@+RMARGIN<0=IFCR

thatis,ifthelengthofthenextwordaddedtothecurrentlengthofthelineexceedsourrightmargin,then we'lldoacarriagereturn. Butwehaveanotherproblem:howdoweisolatewordswithaknowncountforeachword?Fornow,let's assumewehaveavailableawordSplitAtChar.Thiswordbreaksstringsapart,givenaspecific delimiter. Let'swriteouta"firstdraft"ofthislowlevelpartofourapplication.Itwilltypeasingleword,making appropriatecalculationsforcarriagereturn. BLSplitAt Char BreakstringintwoatfirstBL.Leavesthecountonthestack,with theaddressofthefirstcharacterunderneath.

DUP1+ LINECOUNT@+ RMARGIN> IFCR0 LINECOUNT! ELSESPACE THEN DUP1+ LINECOUNT+! TYPE

Leavestheincrementedcountandacopyoftheoriginalcountonthe stack. Computehowlongthecurrentlinewouldbeifaspaceplusthenew wordweretobeincludedonit. Decidesifitwouldexceedthemargin. Ifso,resetsthecarriageandthecount. Otherwise,leavesaspacebetweenthewords. Increasesthecountbythelengthofthewordtobetyped,plusone forthespace. TypesthewordusingthecountandtheaddressleftbySplitAt Char.

NowtheproblemisgettingSplitAtChartolookatthestringsinphrases.forth.Thisis handledbyINCLUDED,soifwesay
S"phrases.forth"INCLUDED

thenCREATEwillmakesureallnecessarystringsarecompiledinmemory. TohelpCREATEdothis,we'lldefinetheword$".Asyoucanseefromitsdefinition,$"compilesthe string(delimitedbyasecondquotationmark)intothedictionary,withthecountinthefirstbyte,and leavesitsaddressonthestackfor}$,}s$and}r$.Tocompilethecountandstringintothedictionary, wesimplyhavetoexecuteWORD,sinceWORD'sbufferisHERE.Wegetthestring'saddressasafillip, sinceWORDalsoleavesHERE. AllthatremainsistoALLOTtheappropriatenumberofbytes.Thisnumberisobtainedbyfetchingthe countfromthefirstbyteofthestringandaddingoneforthecount'sbyte. Wehavewritten$"tocompilethenextstringintothedictionary,butalsotopiletheaddressofthis stringonthestack,ontopoftheaddressesofotherstringsthatwerecompiledalreadyjustbeforethat.In ordertoletotherwordsknowhowmanystringaddressesareonthestack,$"alsoincrementsthetopof stack:
('string1'string2...stringNNnew_string_address)SWAP1+;

Inordertomakethisworkforthefirststring$"mustcompile,wehavetheconstant${puta0onthe stack. Wenowhave${and$"compilingourstringsforus,butatsomepointtheseaddressesmustbestoredin thedictionary.Therewecanchooseoneofthemtoprint,whenINTROorPHRASEneedtodoso. Becausethereisclearlyworktobedonebothatcompileandruntime,thisisanidealjobforadefining word.ThecompiletimeworkisdoneinCREATEpartswhichtypicallylookasfollows:


(u)DUP,(firstcompilecount)0?DO,LOOP(compileustring addresses)

whiletheruntimepartishandledinDOES>parts,doingsomethinglike

DOES>(ixbodycaddru)SWAPCELLS+CELL+@COUNT;

ThisDOES>partisactuallyusablefor}$,whichhastherathersimplejobtodeliverINTRO'sstring, selectedbyanindexonthestack.Otherwordsthatneedastringaddresswantmorerandomness,whichis easilyprovidedbyusingCHOOSE(seethelistingfor}s$and}r$). NowwehaveamechanismtopresentstringstoSplitAtChar,thenextquestionis:howdowe knowwhenwe'vegottentotheendofsuchastring? SincewearetypingwordbywordwhatSplitAtCharoutputs,weonlyhavetocheckwhetherthe charactercountofthesestringsislargerthanzero.OnceSplitAtChargetstotheendofitsinput string,itstartsreturningemptystrings. Forexample,thephrase


S"Hello,IspeakForth".PHRASE

shouldtypeoutthecontentsofthestring,wordbyword,performingcarriagereturnswherenecessary. Howshouldwestructureourdefinitionof.PHRASE?Let'sreexaminewhatitmustdo: 1. Determinewhetherthereisstillawordinthestringtobetyped. 2. Ifthereis,typetheword(withmarginchecking),thenrepeat.Ifthereisn't,exit. ThetwopartnatureofthisstructuresuggeststhatweneedaBEGIN...WHILE...REPEATloop.Let's writeourproblemthisway,ifonlytounderstanditbetter.


...BEGINANOTHER?WHILE.WORDREPEAT...

ANOTHER?willdostep1;.WORDwilldostep2. HowshouldANOTHER?determinewhetherthereisstillawordtobetypedfromthestring?Itsimply teststhetopofstacktoseeifthestringcountisnotyetzero,byusingthephraseDUP:


:ANOTHER?DUP;(#charsTRUE=stringnotempty)

The(notproperlyformed)flagwillserveastheargumentforWHILE. Howdowecomputethestringsfor.PHRASEtoworkon?Thisisaccomplishedbyexecutingoneofthe variouschildrenofourcompilingword}$,}r$or}s$.Thusourdefinitionof.PHRASEmightbe


:.PHRASE(caddru)BEGINANOTHER?WHILE.WORDREPEAT2DROP;

Weneedthe2DROPbecause,whenweexittheloop,wewillhavethefinaladdressofSplitAt Charandazerocountonthestack,neitherofwhichweneedanylonger. Howdowedefine.WORD?Actually,we'vedefineditalready,afewpagesback.However,itpaystosplit .WORDupintoafewotherusefulwords,sothatitlookslikethis:


:FITS?linecount@+RMARGIN>; :SPACE'linecount@IFSPACE1linecount+!THEN; :CR'CR0linecount!; :.WORD(addr1#chars1addr2#chars2) BLSplitAtChar DUP1+(space!)FITS?IFCR'THEN SPACE'TYPE';

Nowwehaveourwordtypingmechanism.Butlet'sseeifwe'reoverlookinganything.Forexample, considerthateverytimewestartanewparagraph,wemustremembertoresetLINECOUNTtozero. Otherwiseour.WORDwillthinkthatthecurrentlineisfullwhenitisn't.Weshouldaskourselvesthis question:isthereeveracaseinthisapplicationwherewewouldwanttoperformaCRwithoutresetting LINECOUNT?Theanswerisno,bytheverynatureoftheapplication.Forthisreasonwedefined


:CR'CR0LINECOUNT!;

tocreateaversionofCRthatisappropriateforthisapplication.WehaveusedthisCRinourdefinitionof .WORD. Weshouldalsoconsiderourhandlingofspacesbetweenwords.Byusingthephrase


IFCRELSESPACETHEN

beforetypingeachword,weguaranteethattherewillbeaspacebetweeneachpairofwordsonthesame linebutnospaceatthebeginningofsuccessivelines.Andsincewearetypingaspacebeforeeachword ratherthanafter,wecanplaceaperiodimmediatelyafteraword,aswemustattheendofasentence. Butthereisaproblemwiththislogic:atthebeginningofanewparagraph,wewillalwaysgetonespace beforethefirstword.Oursolution:toredefineSPACEsothatitwillbesensitivetowhetherornotwe're atthebeginningofaline,andwillnotspaceifweare:


:SPACELINECOUNT@IFSPACETHEN;

IfLINECOUNTis"0"thenweknowweareatthebeginningofaline,becauseofthewaywehave redefinedCR. WhileweareredefiningSPACE,itwouldbelogicaltoincludethephrase


1LINECOUNT+!

intheredefinition.Againourreasoningisthatweshouldneverperformaspacewithoutincrementingthe count. Let'sassumethatwehaveeditedourdefinitionsintowordgame.forth.Noticethatwehadverylittle typingtodo,comparedwiththeamountofthinkingwe'vedone.Forthsourcecodetendstobeconcise. NowwecandefineourinbetweenlevelwordswordslikeINTROandPHRASEthatwehavealready usedinourhighestlevelwords,butwhichwedidn'tdefinebecausewedidn'thavethelowlevel mechanism. Let'sstartwithINTRO.ThefinisheddefinitionofINTROlookslikethis:


:INTRO(u)CR'intros.PHRASE;

Ourmechanismhasgivenusaveryeasywaytoselectstrings.Wecantestthisdefinitionbyitself,as follows:
0INTRO(or1,2or3INTRO) Inthispaperwewilldemonstratethatok

NoticethatweputtheargumenttoINTROonthestackfirst. ThewaytogetaFILLERphraseisalittlemorecomplicated.AllofitishandledbytheDOES>partof} s$.Sincewearedealingwithsets,notlines,andsincethesetsallhavethreestrings,wemustmultiply

theloopindexforfillerby3.Topickoneofthe3versionswithintheset,wemustchoosearandom numberunderthree,addittotheindexsofar,convertittocells,thenaddthisresulttothebeginningof theset,takingintoaccountthecountofstringsinfront.Wecandefine


... DOES>(ix)DUP@1ROT3*3CHOOSE+CELLS+CELL+@COUNT;

TheDUP@1ROTistherebecausewecompiledthestringsinreverseorderoftheirspecification inphrases.forth,andthereforeneedtofindthecomplementoftheactualcompilednumberof strings. Againwecantestthisdefinitionbywriting


3FILLER tofunctionasok

Theremainingwordsintheapplicationaresimilartotheirpreviouscounterparts,statedintermsofthe newmechanism. Hereisasampleoftheoutput.(We'veaddedREDOasanafterthoughtsothatwe'dbeabletoprintthe samepartmorethanonce.)


Inthispaperwewilldemonstratethatbyusingsynchronizedthird generation capabilitybalancedbyqualifieddigitalprojectionsitbecomesnot unfeasibleforallbuttheleaststandaloneorganizationalhardwareto functionastransientundocumentedmobility. Ontheonehand,studieshaveshownthatbyapplyingavailableresources towardssynchronizedfailsafemobilitycoordinatedwithrandomcontext sensitivemobilityitispossibleforeventhemostresponsivemanagement mobilitytoavoidpartialunilateralengineering. Ontheotherhand,however,practicalexperienceindicatesthatwith structureddeploymentofstandalonefailsafeconceptscoordinatedwith optimalomnirangetimephasingitispossibleforeventhemostqualified monitoredutilitiestoavoidoptionalundocumentedutilities. Insummary,then,weproposethatbyusingtotalincrementalprogramming coordinatedwithrepresentativepolicyengineeringitispossibleforeven themostresponsivetransitionalengineeringtogenerateahighlevelof compatibleincrementalengineering.

2.FileAway!
Oursecondexampleconsistsofasimplefilingsystem.Itisamoderatelyusefulapplication,andagood onetolearnForthfrom.Wehavedividedthissectionintofourparts: 1. 2. 3. 4. A"HowTo"fortheenduser.Thiswillgiveyouanideaofwhattheapplicationcando. Notesonthewaytheapplicationisstructuredandthewaycertaindefinitionswork. Aglossaryofallthedefinitionsintheapplication. Alistingoftheapplication,includingthedatafilesthemselves.

HowtoUsetheSimpleFileSystem
Thiscomputerfilingsystemletsyoustoreandretrieveinformationquickyandeasily.Atthemoment,itis setuptohandlepeople'snames,occupations,andphonenumbers.Notonlydoesitallowyoutoenter, change,andremoverecords,italsoallowsyoutosearchthefileforanypieceofinformation.For example,ifyourhaveaphonenumber,youcanfindtheperson'sname;or,givenaname,youcanfindthe person'sjob,etc. Foreachpersonthereisa"record"whichcontainsfour"fields."Thenameswhichspecifyeachofthese fourfieldsare
SURNAMEGIVENJOBPHONE

("Given,"ofcourse,referstoaperson'sgivenname,orfirstname.)

FileRetrieval
YoucansearchthefileforthecontentsofanyfieldbyusingthewordFIND,followedbythefieldname andthecontents,asin
FINDJOBnewscaster DanRatherok

Ifany"job"fieldcontainsthestring"newscaster,"thenthesystemprintstheperson'sfullname.Ifno suchfieldexists,itprints"NOTINFILE." Onceyouhavefoundafield,therecordinwhichitwasfoundbecomes"current."Youcangetthe contentsofanyfieldinthecurrentrecordusingthewordGET.Forinstance,havingenteredtheline above,youcannowenter


GETphone 5559876ok

TheFINDcommandwillonlyfindthefirstinstanceofthefieldthatyouarelookingfor.Tofindoutif thereisanotherinstanceofthefieldthatyoulastfound,usethecommandANOTHER.Forexample,to findanotherpersonwhose"job"is"newscaster,"enter


ANOTHER JessicaSavitchok

and
ANOTHER FrankReynoldsok

Whentherearenomorepeoplewhosejobis"newscaster"inthefile,theANOTHERcommandwillprint "NOOTHER." Tolistallthenameswhosefieldcontainsthestringthatwaslastfound,usethecommandALL:


ALL DanRather

JessicaSavitch FrankReynolds ok

Sincethesurnameandgivennamearestoredseparately,youcanuseFINDtosearchthefileonthebasis ofeitherone.Butifyouknowtheperson'sfullname,youcanoftensavetimebylocatingbothfieldsat once,byusingthewordFULLNAME.FULLNAMEexpectsthefullnametobeenteredwiththelastname firstandthetwonamesseparatedbyacomma,asin


FULLNAMEWonder,Stevie StevieWonderok

(Theremustnotbeaspaceafterthecomma,becausethecommamarkstheendofthefirstfieldandthe beginningofthesecondfield.)LikeFINDandANOTHER,FULLNAMErepeatsthenametoindicatethat ithasbeenfound. YoucanactuallyfindanypairoffieldsbyusingthewordPAIR.Youmustspecifyboththefieldnames andtheircontents,separatedbyacomma.Forexample,tofindanewscasterwhosegivennameisDan, enter


PAIRJOBnewscaster,GIVENDan DanRatherok

FileMaintenance
Toenteranewrecord,usethecommandENTER,followedbythesurname,givenname,job,andphone, eachseparatedbyacommaonly.Forexample,
ENTERNureyev,Rudolf,Balletdancer,5551234 ok

Tochangethecontentsofasinglefieldwithinthecurrentrecord,usethecommandCHANGEfollowedby thenameofthefield,thenthenewstring.Forexample,
CHANGEJOBchoreographer ok

Tocompletelyremovethecurrentrecord,usethecommandREMOVE:
REMOVE ok

Comments
Thissectionismeantasaguide,forthenoviceForthprogrammer,totheglossaryandlistingwhich follow.We'lldescribethestructureofthisapplicationandcoversomeofthemorecomplicated definitions.Asyoureadthissection,studytheglossaryandlistingonyourown,andtrytounderstandas muchasyoucan. Turntothelistingnow.Neartheend,thisfilecontainsthedefinitionsforallnineendusercommands we'vejustdiscussed.Noticehowsimplethesedefinitionsare,comparedtotheirpower!

ThisisacharacteristicofawelldesignedForthapplication.NoticethatthewordFIND,theelemental filesearchword,isfactoredinsuchawaythatitcanbeusedinthedefinitionsofFIND,ANOTHER,and ALL,aswellasintheinternalword,(PAIR),whichisusedbyPAIRandbyFULLNAME. We'llexaminethesedefinitionsshortly,butfirstlet'slookattheoverallstructureofthisapplication. Oneofthebasiccharacteristicsofthisapplicationisthateachofthefourfieldshasanamewhichwecan enterinordertospecifytheparticularfield.Forexample,thephrase


SURNAMEPUT

willputthecharacterstringthatfollowsintheinputstreamintothe"surname"fieldofthecurrentrecord. Thephrase
SURNAME.FIELD

willprintthecontentsofthe"surname"fieldofthecurrentrecord,etc. Therearetwopiecesofinformationthatareneededtoidentifyeachfield:thefield'sstartingaddress relativetothebeginningofarecordandthelengthofthefield. Inthisapplication,arecordislaidoutlikethis: offset contents size 0 surname 16 16 given 16 32 job 24 56 phone 8

Forinstance,the"job"fieldstartsthirtytwobytesinfromthebeginningofeveryrecordandcontinues fortwentyfourbytes. Wechosetomakearecordexactlysixtyfourbyteslong,butthissystemcanbemodifiedtoholdrecords ofanylengthandanynumberoffields.


Toaddmorefields,justaddlineswiththelengthofthenewfield,followedbyRECORDnewfieldname. Forexample,toaddafieldFOOwhichisthirtybyteslong,do 30RECORDfoo etc.ThesystemautomaticallycomputesthevaluesofRLENGTHand#MAXRECS.

We'vetakenthetwopiecesofinformationforeachfieldandputthemintoadoublelengthtable associatedwitheachfieldname.ThistaskisperformedbythedefiningwordRECORD,atcompiletime. OurdefinitionofJOB,thereforeeventuallyexecutesCREATE,asin 3 J O link executiontoken 32 24


CREATEJOB32,24,

Theliteral32iscomputedbythesystem,whichkeepstrackoftheactualoffsetintoarecordthrough updatingRLENGTH. Thuswhenweenterthenameofafield,weareputtingonthestacktheaddressofthetablethatdescribes the"job"field.Wecanfetcheitherorbothpiecesofinformationrelativetothisaddress. Let'scalleachoftheseentriesa"fieldspecifyingtable,"ora"spectable"forshort. PartofthedesignforthisapplicationisderivedfromtherequirementsofFIND,ANOTHER,andALL; thatis,FINDnotonlyhastofindagivenstringwithinagiventypeoffield,butalsoneedsto "remember"thestringandthetypeoffieldsothatANOTHERandALLcansearchforthesamething. Wecanspecifythekindoffieldwithjustonevalue,theaddressofthespectableforthattypeoffield. Thismeansthatwecan"remember"thetypeoffieldbystoringthisaddressintoKEEP. KINDwascreatedforthispurpose,toindicatethe"kind"offield. Torememberthestring,wehavedefinedabuffercalledWHATtowhichthestringcanbemoved. ThewordKEEPservesthedualpurposeofstoringthegivenfieldtypeintoKINDandthegivencharacter stringintoWHAT.IfyoulookatthedefinitionoftheenduserwordFIND,youwillseethatthefirstthing itdoesisKEEPtheinformationonwhatisbeingsear chedfor.ThenFINDexecutestheinternalword FIND,whichusestheinformationinKINDandWHATtofindamatchingstring. ANOTHERandALLalsouseFIND,buttheydon'tuseKEEP.Insteadtheylookforfieldsthatmatchthe onemostrecently"kept"byFIND. SothatwecanGETanypieceofinformationfromtherecordwehavejust"found,"weneedapointerto the"current"record.Thisneedismetbythevalue#RECORD.TheoperationsofthewordsSET,TOP andDOWNshouldbefairlyobvioustoyou. ThewordRECORD@usesitsstackparametertocomputetheabsoluteaddress(thecomputermemory address,somewhereinthediskbuffer)ofthebeginningofthecurrentrecord.RECORD@alsomakessure thattherecordreallyisinthediskbuffer. Whileaspectablecontainstherelativeaddressofthefieldanditslength,weusuallyneedtoknowthe field'sabsoluteaddressandlengthforwordssuchasTYPE,MOVE,andPARSE.Lookatthedefinition ofthewordFIELDtoseehowitconvertstheaddressofaspectableintoanabsoluteaddressandlength. ThenexaminehowFIELDisappliedinthedefinitionof.FIELD. ThewordPUTalsoemploysFIELD.Itsphrase
>RKBD,R>>FLD_

leavesonthestackthearguments
addrofstringcountofstringabsoluteaddroffieldsizeoffield

forMOVEtomovethestringintotheappropriatefieldofthecurrentrecord.Beforewemovethestring, wefillthefieldwithspaces,toblankpossibleoldcontents.Also,wemakesurethelengthofthemoved stringisnotlargerthanthesizeofthefield. TherearetwothingsworthnotingaboutthedefinitionofFREE.Thefirstisthemethodusedto determinewhethertherecordisempty.We'vemadetheassumptionthatifthefirstbyteofarecordis empty,thenthewholerecordisempty,becauseofthewayENTERworks.Ifthefirstbytecontainsa characterwhoseASCIIvalueislessthanorequaltoBL,thenitisnotaprintingcharacterandthelineis

empty.Assoonasanemptyrecordisfound,LEAVEendstheloop.#RECORDwillcontainthenumberof thefreerecord. AnotherthingworthnotingaboutFREEisthatitabortsifthefileisfull,thatis,ifitrunsthroughallthe recordswithoutfindingoneempty.WecanuseaDOlooptorunthroughalltherecords,buthowcanwe tellthattheloophasrunoutbeforeithasfoundanemptyrecord? ThebestwayistoleaveaTRUEonthestack,toserveasaflag,beforebeginningtheloop.Ifanempty recordisfound,wecanchangetheflagtoFALSE(withthewordINVERT)beforeweleavetheloop. Whenwecomeoutoftheloop,we'llhaveaTRUEifweneverfoundanemptyrecord,aFALSEifwedid. ThisflagwillbetheargumentforABORT". WeuseasimilartechniqueinthedefinitionofFIND.FINDmustreturnaflagtothewordthat executedit:FIND,ANOTHER,ALLor(PAIR).Theflagindicateswhetheramatchwasfoundbefore theendofthefilewasreached.Eachoftheseouterwordsneedstomakeadifferentdecisionbasedonthe stateofthisflag.ThisflagisTRUEifamatchisnotfound(hencethenameFIND).Thedecisiontouse negativelogicwasbasedonthewayFINDisused. BecausetheflagneedstobeTRUEifamatchisnotfound,theeasiestwaytodesignthiswordistostart withaTRUEonthestackandchangeittoaFALSEonlyifamatchisfound. Nowthatyouunderstandthebasicdesignofthisapplication,youshouldhavenotroubleunderstanding therestofthelisting,usingtheglossaryasaguide.

FilerGlossary
/CR Aconstantthatdefinesthelengthinbytesofanewlinesequence. Aconstantthatdefinesthemaximumnumberofrecordsinthedata #MAXRECS file.Toincreasethisnumber,addlinescontainingRLENGTH spaces,followedbyanewline,tothedatafile. FILE Avaluethatholdsthehandleofthefilecontainingthedata. Avaluethatcontainstheaddressofthefieldspecifyingtableforthe KIND typeoffieldthatwaslastsearchedforbyFIND. RLENGTH Avaluethatcontainsthelengthinbytesofasinglerecord. #RECORD Avaluethatpointstothecurrentrecord. Adefiningwordtocreatefieldspecifyingtables.Takesthefield widthinbytesasaparameterandupdatesRLENGTH.Allusesof RECORD RECORDshouldhappenbefore#MAXRECSisdefined.Usage:10 RECORDfoo Returnstheaddressofthefieldspecifyingtableforthe"surname" SURNAME (lastname)field. Returnstheaddressofthefieldspecifyingtableforthe"given"(first GIVEN name)field. JOB Returnstheaddressofthefieldspecifyingtableforthe"job"field. Returnstheaddressofthefieldspecifyingtableforthe"phone" PHONE field. WHAT Returnstheaddressofabufferthatcontainsthestringthatisbeing

searchedfor,orwaslastsearchedfor,byFIND. RBUF Returnstheaddressofabufferthatcontainsthecurrentrecorddata. Makessureallchangeddataiscommittedtodisk,butdoesnotclose FLUSH thefile. UPDATE Writesthedataforthecurrentrecordtodisk. RECORD@ InsuresthatthespecifiedrecordisinRBUF. Giventheaddressofafieldspecifyingtable,returnstheaddressof >FLD_ theassociatedfieldinRBUF,alongwithitsassignedlength. Giventheaddressofafieldspecifyingtable,returnstheaddressof >FLD theassociatedfieldinRBUF,alongwithitsactuallength. Insuresthattheassociatedfieldinthecurrentrecordisinadisk FIELD bufferandreturnstheaddressofthefieldinthebufferalongwithits actuallength. Fromthecurrentrecord,typesthecontentsofthefieldthatis .FIELD associatedwiththefieldspecifyingtableataddr. SET Setstherecordpointertothespecifiedrecord. TOP Resetstherecordpointertothetopofthefile. DOWN Movestherecordpointerdownonerecord. .NAME Printsthefullnamefoundinthecurrentrecord. Movesacharacterstring,delimitedbyacommaorbyacarriage READ return,fromtheinputstreamtoatemporarybuffer,thenreturnsits addressandcount. Movesacharacterstring,delimitedbyacommaorbyacarriage PUT return,fromtheinputstreamintothefieldwhosefieldspecifying tableaddressisgivenonthestack. Movesacharacterstring,delimitedbyacommaorbyacarriage KEEP return,fromtheinputstreamintoWHAT,andsavestheaddressof thegivenfieldinKIND,forfutureusebyFIND. Startingatthetopofthefile,findsthefirstrecordthatisfree,thatis, FREE whosecountiszero.A bortsifthefileisfull. Beginningat#recordandproceedingdown,comparesthecontentsof FIND thefieldindicatedbyKINDagainstthecontentsofWHAT. Startingfromthetop,attemptstofindamatchonthecontentsof WHAT,usingKINDtoindicatethetypeoffield.Ifamatchismade, thenattemptstomatchasecondfield,whosetypeisindicatedby (PAIR) "field",withthecontents{caddru}.Ifbothmatch,printsthename; otherwiserepeatsuntilamatchismadeoruntiltheendofthefileis reached,inwhichcaseprintsanerrormessage. Findsthefirstfreerecord,thenmovesfourstringsdelimitedby ENTER commasintothesurname,given,jobandphonefieldsofthatrecord. Usage:ENTERlastname,firstname,job,phone REMOVE Erasesthecurrentrecord.

Changesthecontentsofthegivenfieldinthecurrentrecord. Usage:CHANGEfieldnamenewcontents Printsthecontentsofthegiventypeoffieldfromthecurrentrecord. GET Usage:GETfieldname Findstherecordinwhichthereisamatchbetweenthecontentsof FIND thegivenfieldandthegivenstring. Usage:FINDfieldnamestring Beginningwiththenextrecordafterthecurrentone,andusing ANOTHER KINDtodeterminetypeoffield,attemptstofindamatchonWHAT. Ifsuccessful,typesthename;otherwiseanerrormessage. Beginningatthetopofthefile,usesKINDtodeterminetypeoffield ALL andfindsallmatchesonWHAT.Typesthefullname(s). Findstherecordinwhichthereisamatchbetweenboththecontents ofthefirstgivenfieldandthefirstgivenstring,andalsothecontents PAIR ofthesecondgivenfieldandthesecondgivenstring.Commais delimiter. Usage:PAIRfield1string1,field2string2 Findstherecordinwhichthereisamatchonboththefirstandlast FULLNAME namesgiven. Usage:FULLNAMElastname,firstname CHANGE

FilerListing
Thelistingishere.

3.NoWeighting
Ourfinalexampleisamathproblemwhichmanypeoplewouldassumecouldonlybesolvedbyusing floatingpoint.Itwillillustratehowtohandleafairlycomplicatedequationwithfixedpointarithmetic anddemonstratethatforalltheadvantagesofusingfixedpoint,rangeandprecisionneednotsuffer.Of course,whenthehardwaredoeshavefloatingpointoneshouldpreferablyusethatinstead,andweshow howtodothat,too.Usingfixedpointhastheslightdisadvantagethat,inordertocorrectlycomputescale factors,wehavetoknowourForth'snumberofbitspercell.FormodernForthsthenumberofbitsper cellcanbe16,32,64,orevenhigher.Inordernottocomplicatethefollowingdescriptiontoomuch,we willassume16bithardware.Thatisprobablytheonlyenvironmentthisexamplewillbeusefulfor, anyway.Also,we'llassume1CHARSisequivalenttoonebyte. Inthisexamplewewillcomputetheweightofaconeshapedpileofmaterial,knowingtheheightofthe pile,theangleoftheslopeofthepile,andthedensityofthematerial. Tomaketheexamplemore"concrete,"let'sweighseveralhugepilesofsand,gravel,andcement.The slopeofeachpile,calledthe"angleofrepose,"dependsonthetypeofmaterial.Forexample,sandpiles itselfmoresteeplythangravel.

(Inrealitythesevaluesvarywidely,dependingon manyfactors;wehavechosenapproximateangles anddensitiesforpurposesofillustration.)

ForSceptics

Hereistheformulaforcomputingtheweightofa Thevolumeofacone,V,isgivenby conicalpilehfeettallwithanangleofreposeof ,wherebistheradiusofthebase thetadegrees,whereDisthedensityofthematerial inpoundspercubicfoot: andhistheheight.Wecancomputethebaseby knowingtheangleor,morespecifically,thetangent . oftheangle.Thetangentofanangleissimplythe ratioofthesegmentmarkedhtothesegment Thiswillbetheformulawhichwemustexpressin markedbinthisdrawing: Forth. Let'sdesignourapplicationsothatwecanenterthe nameofamaterialfirst,suchas
DRYSAND

thenentertheheightofapileandgettheresultfor drysand.

Ifwecall

Let'sassumethatforanyonetypeofmaterialthe densityandangleofreposenevervary.Wecanstore bothofthesevaluesforeachtypeofmaterialintoa table.Sinceweultimatelyneedeachangle'stangent, ratherthanthenumberofdegrees,wewillstorethe tangent.Forinstance,theangleofreposeforapile thisangle"theta",then .Thuswecan ofcementis35o,forwhichthetangentis.700.We willstorethisastheinteger700. computetheradiusofthebasewith . Bearinmindthatourgoalisnotjusttogetan answer;weareprogrammingacomputerordevice togettheanswerforusinthefastest,mostefficient, WhenwesubstitutethisintotheexpressionforV, andthenmultiplytheresultbythedensityDin poundspercubicfoot,wegettheformulashownin thetext.

andmostaccuratewaypossible.AsweindicatedinChap.5,towriteequationsusingfixedpoint arithmeticrequiresanextraamountofthought.Butonhardwarethatwouldhavetoemulatefloating point,theeffortpaysoffintwoways: 1. vastlyimprovedruntimespeed,whichcanbeveryimportantwhentherearemillions ofstepsinvolvedinasinglecalculation,orwhenwemustperformthousandsof calculationseveryminute.Also, 2. programsize,whichwouldbecriticalif,forinstance,wewantedtoputthisapplicationinahand helddevicespecificallydesignedasapilemeasuringcalculator.Forthisoftenusedinthistypeof instrument. Let'sapproachourproblembyfirstconsideringscale.Theheightofourpilesrangesfrom5to50feet.By workingoutourequationforapileofcement50feethigh,wefindthattheweightwillbenearly 3,500,000pounds. Butbecauseourpileswillnotbeshapedasperfectconesandbecauseourvaluesareaverages,wecannot expectbetterthanfourorfivedecimalplacesofaccuracy.Ifwescaleourresulttotons,wegetabout 17,500.Thisvaluewillcomfortablyfitwithintherangeofasinglelengthnumber,evenon16bit hardware.Forthisreason,let'swritethisapplicationentirelywithsinglelengtharithmeticoperators. (Althoughwewillassume16bithardwareinthefollowing,thecodeasshownwillrununmodifiedon anyANSForth.) Applicationswhichrequiregreateraccuracycanbewrittenusingdoublelengtharithmetic;toillustrate we'veevenwrittenasecondversionofthisapplicationusingdoublelengthmath,asyou'llseelateron. ButweintendtoshowtheaccuracythatForthcanachieveevenwith16bitmath. Byrunninganothertestwithapile40feethigh,wefindthatadifferenceofonetenthofafootinheight canmakeadifferenceof25tonsinweight.Sowedecidetoscaleourinputtofeetandinchesratherthan merelytowholefeet. We'dliketheusertobeabletoenter
15FOOT2INCHPILE

wherethewordsFOOTandINCHwillconvertthefeetandinchesintotenthsofaninch,andPILEwill dothecalculation.Here'showwemightdefineFOOTandINCH:
:FOOT10*; :INCH10012*/5+10/+;

TheuseofINCHisoptional. (Bytheway,wecouldaseasilyhavedesignedinputtobeintenthsofaninchwithadecimalpoint,like this:


15.2

Inthiscase,NUMBERwouldconverttheinputasadoublelengthvalue.Sinceweareonlydoingsingle lengtharithmetic,PILEcouldsimplybeginwithDROP,toeliminatethehighordercell.) InwritingthedefinitionofPILE,wemusttrytomaintainthemaximumnumberofplacesofprecision withoutoverflowing15bits.Accordingtotheformula,thefirstthingwemustdoiscubetheargument. Butlet'srememberthatwewillhaveanargumentwhichmaybeashighas50feet,whichwillbe500asa scaledinteger.Eventosquare500produces250,000,whichexceedsthecapacityofsinglelength

arithmeticusing16bitcells. Wemightreasonthat,soonerorlaterinthiscalculation,we'regoingtohavetodivideby2000toyieldan answerintons.Thusthephrase


DUPDUP2000*/

willsquaretheargumentandconvertittotonsatthesametime,takingadvantageof*/'sdoublelength intermediateresult.Using500asourtestargument,theabovephrasewillyield125. Butourpilemaybeassmallas5feet,whichwhensquaredisonly25.Todivideby2000wouldproduce azeroinintegerarithmetic,whichsuggeststhatwearescalingdowntoomuch. Toretainthemaximumaccuracy,weshouldscaledownnomorethannecessary.250,000canbesafely accomodatedbydividingby10.ThuswewillbeginourdefinitionofPILEwiththephrase


DUPDUP10*/

Theintegerresultatthisstagewillbescaledtooneplacetotherightofthedecimalpoint(25000for 2500.0). Nowwemustcubetheargument.Onceagain,straightmultiplicationwillproduceadoublelength32bits result,sowemustuse*/toscaledown.Wefindthatbyusing1000asourdivisor,wecanstayjustwithin singlelengthrange.Ourresultatthisstagewillbescaledtooneplacetotheleftofthedecimalpoint (12500for125000.)andstillbeaccurateto5digits. Accordingtoourformula,wemustmultiplyourargumentbypi.WeknowthatwecandothisinForth withthephrase


355113*/

whichcausesnoproblemswithscaling. Nextwemustdivideourargumentbythetangentsquared,whichwecandobydividingtheargumentby thetangenttwice.Becauseourtangentisscaledtothreedecimalplaces,todividebythetangentwe multiplyby1000anddividebythetablevalue.Thuswewillusethephrase


1000TAN(THETA)*/

Sincewemustperformthistwice,let'smakeitadefinition,called/TAN(fordividebythetangent)and usetheword/TANtwiceinourdefinitionofPILE.Ourresultatthispointwillbescaledtooneplaceto theleftofthedecimal(26711for267110,usingourmaximumtestvalues). Allthatremainsistomultiplybythedensityofthematerial,ofwhichthehighestis131poundspercubic foot.Toavoidoverflowing,let'stryscalingdownbytwodecimalplaceswiththephrase


DENSITY100*/

Butbytesting,wefindthattheresultatthispointfora50footpileofcementwillbe34,991,whichjust exceedsthe15bitlimit.Nowisagoodtimetotakethe2000intoaccount.Insteadof
DENSITY100*/

wecansay
DENSITY200*/

andouranswerwillnowbescaledtowholetons. Youwillfindthisversioninthelisting.Aswementioned,wehavealsowrittenthisapplicationusing doublelengtharithmetic.Inthisversionyouentertheheightasadoublelengthnumberscaledtotenths ofafoot,followedbythewordFEET,asin50.0feet. Byusingdoublelengthintegerarithmetic,weareabletocomputetheweightofthepiletothenearest wholepound.Therangeofdoublelength32bitintegerarithmeticcompareswiththatofsingleprecision floatingpointarithmetic.Belowisacomparisonoftheresultsobtainedusinga10decimaldigitpocket calculator,singlelengthForth,doublelength(32bit)Forth,andfloatingpointForth.Thetestassumesa 50footpileofcement,usingthetablevalues. calculator Forth16bitsinglelength inpounds 34,995,633 intons 17,497.816 17,495 17,497.817 17,495 17,497.817 17,497.816

Forth16bitdoublelength 34,995,634 Forth32bitsinglelength

Forth32bitdoublelength 34,995,634 Forthfloatingpoint Here'sanexampleofourapplication'soutput: 34,995,633

S"spiles.forth"INCLUDEDok cementok 10footpile=138tonsofcementok 10foot3inchpile=151tonsofcementok drysandok 10footpile=81tonsofdrysandok S"dpiles.forth"INCLUDEDcementok 10.0feet=279939poundsofcementor139.969tonsok S"fpiles.forth"INCLUDEDcementok 10efeet=279965.06373598pounds,or139.98253187tonsofcementok

Anoteon"
ThedefiningwordMATERIALtakesthreeargumentsforeachmaterial,oneofwhichistheaddressofa string..SUBSTANCEusesthisaddresstotypethenameofthematerial. ToputthestringinthedictionaryandtogiveanaddresstoMATERIAL,wehavedefinedawordcalled". Asyoucanseefromitsdefinition,"compilesthestring(delimitedbyasecondquotationmark)intothe dictionary,withthecountinthefirstbyte,andleavesitsaddressonthestackforMATERIAL.Tocompile thecountandstringintothedictionary,wesimplyhavetoexecuteWORD,sinceWORD'sbufferis HERE.Wegetthestring'saddressasafillip,sinceWORDalsoleavesHERE. AllthatremainsistoALLOTtheappropriatenumberofbytes.Thisnumberisobtainedbyfetchingthe countfromthefirstbyteofthestringandaddingoneforthecount'sbyte.

ABrowserInterfaceforFPILES
ThisinterfaceisForthsystemdependent.ItwillworkforiForth2.0,aftersomepreparations:

RuniForthonthefilefsserver.frt ExecutethewordPILESERVER. ManipulatethebelowFORMandpressSEND.Anewbrowserwindowopenswiththecalculation result.

cement wetsand drysand clay loosegravel packedgravel RESET

Send

ReviewofTerms
Stub inForth,atemporarydefinitioncreatedsolelytoallowtestingofahigherlevel definition. aprogrammingmethodologybywhichalargeapplicationisdividedintosmaller units,whichmaybefurthersubdividedasnecessary.Thedesignprocessstartswith theoverview,or"top,"andproceedsdowntothelowestlevelofdetail.Codingofthe lowlevelunitsbeginsonlyaftertheentirestructureoftheapplicationhasbeen designed.

Topdown Programming

200
Articles

TheprogramminglanguageForth

Author:AlbertNijhof Translation:MarcelHendrix 1. ControlstructuresI ThecompiletimeandruntimebehaviorofIFTHENBEGINetc. 2. ControlstructuresII 3. Withoutexception

4. 5. 6. 7. 8.

Exampleofaprogrammingstylethatminimizesconditionalbranches. Robotarm Thisprogramcoordinatesprocessesthatrunwithdifferentspeeds: they'llstartatthesametime,runsmoothly,andstopatthesametime. CATCHandTHROWI CATCHandTHROWII MANYTIMES Aboutmanipulatingtheinputstream. KISScommandsinForth Aboutpostfix,infixandprefix.

:;

You might also like