ATOM FORTH
PORTH is een programmeertaal die ongeveer 13 jaar geleden door C.H.Moore is uitgevonden. De taal is zeer geschikt voor het besturen van apparatuur m.b.v. een computer. De meeste hogere programmeertalen zijn daarvoor te traag en het schrijven van machinetaal routines is lastig. Enkele eigenschappen van FORTH zijn: - FORTH programma's hebben een hoge executie-snelheid. - FORTH heeft weinig geheugenruimte nodig. - FORTH is uitbreidbaar. -FORTH is interactief. - FORTH is een gestructureerde taal. Op al deze eigenschappen komen we nog terug. 2. De STACK. Voor de berekeningen gebruikt FORTH een STACK (de parameter-STACK). Dit betekent - Alle getallen die worden ingetypt, komen boven op de STACK. - Alle operaties halen getallen van de STACK en zetten het resultaat van de bewerking weer op de STACK. We zullen een voorbeeld bekijken. We tikken in: 2 4 6 3 De getallen 2,4,6,3 staan nu op de STACK, de 3 bovenop en de 2 onderop. Vervolgens tikken we: + Nu worden de 6 en de 3 van de STACK gehaald en de som (6+3=) 9 weer op de STACK gezet. Deze bevat nu dus de getallen 2,4,9. Typen we nu: MAX dan worden de 4 en de 9 van de STACK gehaald en hun maximum (=9) wordt teruggezet. De STACK bevat nu de getallen 2t9. We typen nu: - De getallen 2 en 9 worden van de STACK gehaald en hun verschil (2-9=) -7 wordt weer teruggezet. Als we nu intypen: . dan wordt het bovenste element (-7) van de STACK gehaald en afgedrukt. De STACK is nu leeg. Kortom: het uitrekenen en afdrukken van 2-MAX(4t6+3) gaat in FORTH met: 246 3 + MAX -.(Ret.) Op het beeldscherm zal dan te zien zijn: 246 3 + MAX -.-7 OK Als de opdracht op de juiste manier is uitgevoerd reageert FORTH altijd met "OK". Van dit voorbeeld kunnen we verschillende dingen leren: - De STACK werkt volgens het "Last-in first-out" principe. Dit betekent dat het getal, dat het laatst op de STACK is gezet t er als eerste weer wordt afgehaald. We kunnen dit vergelijken met een stapel borden! ! - De spatie is in PORTH een scheidingsteken. De verschillende getallen worden alleen door een spatie gescheiden. - ACORN-FORTH werkt alleen met integer getallen. Er bestaan FORTH-versies die ook met "floating-point" getallen kunnen werken. ACORN-FORTH kent zowel enkele- als dubbele-precisie integers. Op het verschil komen we terug: voorlopig beperken wij ons tot de enkele precisie getallen. Dit zijn 16-BIj getallen, zodat de waarde die ze kunnen aannemen ligt tussen -32768 en 327E (ofwel tussen 0 en 65535. indien we ze beschouwen als getallen zonder teken) - FORTH is op de manier zoals we hebben voorgedaan te gebruiken alsof het een rekenmachine is. PORTH gebruikt een post-fix notatie, die de gebruikers var H.P. rekenmachines bekend zal voorkomen. We zullen een aantal STACK-operaties op een rijtje zetten: + Berekent de som van de bovenste twee elementen. - Berekent het verschil van de bovenste twee elementen. * Berekent het product van de bovenste twee e1ementen. / Berekent het quotiënt van de bovenste twee elementen. MOD Berekent de rest van de deling van de bovenste twee elementen. MAX Neemt de grootste van de bovenste twee elementen. MIN Neemt de kleinste van de bovenste twee elementen. ABS Berekent de absolute waarde van het bovenste getal. MINUS Draait het teken van het bovenste element om. 1+ Telt 1 op bij het bovenste element. 2+ Telt 2 op bij het bovenste element. 2* Vermenigvuldigt het bovenste element met 2. Dit is sneller dan: 2 * Dit waren enkele rekenkundige bewerkingen, maar er zijn ook andere bewerkingen op de STACK mogelijk: DUP Dupliceert het bovenste element. 1 2 DUP geeft: 122 DROP Verwijdert het bovenste element. 1 Z J DROP geeft: 12 SWAP Verwisselt de bovenste twee elementen. 12 SWAP geeft: 2 1 OVER Kopieert het 2e element van de STACK bovenop de STACK. 64 J 2 OVER geeft: ó 4 J 2 J ROT Verwijdert het 3e element en plaatst het boven op de STACK. 45678 ROT geeft: 457 ~ 6 I PICK Kopieert het I-de element van de STACK naar de top van de STACK. 1 2 J 4564 FICK geeft: 1234563 I ROLL Verwijdert het I-de element en plaatst het boven op de STACK. 1 234 564 ROLL geeft: 124 563 We zien nu dat: 1 PICK is equivalent aan DUF 2 PICK is equivalent aan OVER 2 ROLL is equivalent aan SWAP 3 ROLL is equivalent aan ROT FORTH kent ook logische operatoren: AND Berekent de BIT-voor-BIT logische AND van de twee bovenste elementen 1521 AND geeft: 5 OR Berekent de BIT-voor-BIT logische OR van de twee bovenste elementen 1521 ~ geeft: 31 XOR Berekent de BIT-voor-BIT logische Exclusieve-OR van de bovenste twee elementen. 1521 XOR geeft: 26 3. INPUT en OUTPUT in PORTH. PORTH kent de volgende INPUT/OUTPUT routines: . Haalt het bovenste getal van de STACK en drukt het af. EMIT Haalt het bovenste getal van de S1'ACK en drukt het af als ASCII character. 64 DUF EMIT .geeft: @ 64 OK KEY Leest een character in van het toetsenbord en zet het als getal op de STACK. ." Drukt een tekst af. De tekst moet worden afgesloten met "." HALLO" geeft: HALLO CR Spring naar het begin van de volgende regel. Inwendig rekent ACORN-FORTH altijd BINAIR. De INPUT en OUTPUT kan echter geschieden in elk gewenst talstelsel. Standaard zijn aanwezig de "decimale" en de "Hexadecimale" basis. Omschakelen gebeurt via d,J commando' s: "HEX en "DECIMAL" . Hoe je kan overgaan op een ander talstelsel wordt nog behandeld. 4. Het programmeren in FORTH. Programmeren in FORTH is eigenlijk.niets anders dan het toevoegen aan de standaard-FORTH functies van je eigen functies. Als je vindt dat een functie ontbreekt, dan maak je hem gewoon zelf. Deze zelfgemaakte functies zijn dan op dezelfde manier te gebruiken als de standaard-FORTH functies. We demonstreren dit weer aan de hand van een voorbeeld. We typen in: : XA2 DUP .; Wat hebben we nu eigenlijk gedaan: : Geeft aan dat we een nieuwe functie gaan definiëren. X^2 Dit is de naam van onze nieuwe operator. Deze wordt altijd meteen na de: gezet. DUP* Dit is wat de nieuwe operator moet doen. In dit geval moet dus het kwadraat van het bovenste getal op de STACK worden berekend. ; Hiermee wordt de definitie afgesloten. Typen we nu vervolgens: 5 X^2 . Dan zal de computer antwoorden met: 25 OK We zien dat de nieuwe functie op dezelfde manier gebruikt wordt als de standaard-FORTH functies. Hij kan dus ook in alle daarna volgende definities gebruikt worden. Bijvoorbeeld: : X^4 X^2 X^2 ; 3 X^4 . geeft nu: 81 OK In ACORN-FORTH mag een naam van een functie maximaal 31 karakters lang zijn. Een naam kan nooit spaties bevatten. Een FORTH programma bestaat uit een rij zelfgemaakte functies, die steeds verder gecombineerd worden. Het gehele FORTH programma wordt uiteindelijk gerepresenteerd door een enkel woord. Om een programma in FORTH te schrijven, moet de taak van het programma in steeds kleinere taakjes worden verdeeld. Uiteindelijk blijven dan zeer kleine taken over, die makkelijk in FORTH kunnen worden geschreven. Deze worden dan gecombineerd tot een heel computerprogramma. Wij zullen hiervan nog voorbeelden te zien krijgen. We zullen nog een operatie definiëren. : - 3 * ; We hebben nu de operatie "-" gedefinieerd als "vermenigvuldig met J". We zien dus dat verschillende functies dezelfde naam mogen hebben. Alleen de laatste definitie van een functie kunnen we nu gebruiken, dus: Als we intypen: 5 3 - . dan zal de computer reageren met: 9 OK We kunnen nu dus niet meer twee getallen van elkaar aftrekken. Daarom is er een functie in FORTH, die zorgt dat we deze definitie ongedaan kunnen maken: FORGET X^4 FORTH is nu "X^4" en alle latere definities vergeten. De standaard-FORTH functies zijn beschermd: FORGET DROP levert een foutmelding op. Als we willen weten welke definities we ter beschikking hebben dan kunnen we gebruik maken van: VLIST We krijgen dan een lijst van alle zelfgemaakte en alle standaard-FORTH definities. 5. Variabelen in FORTH. Het is in FORTH ook mogelijk om variabelen te gebruiken. Ze worden op de volgende manier gedefinieerd: 44 VARIABELEN HOEVEEL De variabelen met de naam "HOEVEEL" hebben we nu gedefinieerd en we hebben hem om te beginnen de waarde 44 gegeven. Als we de waarde van "HOEVEEL" willen gebruiken in een berekening, dan moet deze waarde eerst op de STACK worden gezet. HOEVEEL @ Op de top van de STACK staat nu de waarde van "HOEVEEL" (=44). Het veranderen van de waarde van een variabele gaat op de volgende manier: HOEVEEL ! Het bovenste getal is nu van de STACK gehaald en aan de variabele "HOEVEEL" toegekend. We kennen nog een bewerking voor variabelen: 1 HOEVEEL +! De waarde van "HOEVEEL" is nu met 1 opgehoogd. 6. De "DO-LOOP" in FORTH. We zullen een voorbeeld laten zien: : TELLER 6 1 DO I. LOOP ; Wat is er gebeurd? : Dit geeft aan dat we een nieuwe functie definiëren. TELLER Dit is de naam van de nieuwe functie. 6 1 De getallen 6 en 1 worden op de STACK gezet. DO Dit is het begin van onze "DO-LOOP". De getallen 6 en 1 worden van de STACK gehaald. De LOOP-index krijgt om te beginnen de waarde van het bovenste getal (=1). Zodra de LOOP-index de waarde van het tweede getal (=6) bereikt, wordt er gestopt. I De waarde van de LOOP-index wordt op de STACK gezet. . Het bovenste getal wordt van de STACK gehaald en afgedrukt. In dit geval is dat dus steeds de LOOP-index. LOOP Dit markeert het einde van de "DO-LOOP". De index wordt met 1 verhoogd en we gaan terug naar “DO". ; Einde van deze definitie. Typen we nu in: TELLER dan zal de computer reageren met: 12 34 5 OK We moeten op de volgende dingen letten: - Een DO-LOOP kan alleen binnen een definitie gebruikt worden. - DO haalt twee waarden van de STACK. Hoe deze waarden daar gekomen zijn doet er niet toe. Ze mogen dus ook buiten de definitie, waarin de DO-LOOP voorkomt, op de STACK worden gezet. - DO-LOOP's mogen genest worden. De functie "I. zet altijd de waarde van de index van de binnenste DO-LOOP op de STACK. Nog een paar voorbeeldjes: : TAFEL 11 1 DO DUP I * . LOOP ; 3 TAFEL geeft: 3 6 9 12 1518 21 24 27 30 OK : WACHT 0 DO LOOP ; 8 WACHT geeft een korte pauze. 3000 WACHT geeft een lange pauze. 7. De IF-ELSE-THEN constructie. Ook de IF-ELSE-THEN constructie kan alleen binnen een definitie voorkomen. We bekijken een voorbeeld: : GELIJK? = IF ." GELIJK" ELSE ." ONGELIJK " THEN ; Wat is er gebeurd? : GELIJK? Dit is de naam van de definitie. = De twee bovenste getallen van de STACK worden gehaald. Als ze gelijk zijn, dan wordt er een getal op de STACK gezet dat de logische waarde "WAAR" representeert, en als ze ongelijk zijn, dan wordt er een getal op de STACK gezet met de logische waarde "NIET-WAAR". IF Er wordt getest of op de STACK de logische waarde "WAAR" staat. Als dit zo is dan worden de operaties tussen "IF" en "ELSE" uitgevoerd. Staat op de STACK de logische waarde "NIET-'NAAR", dan worden de operaties tussen "ELSE" en "THEN" uitgevoerd. ." GELIJK " Druk af "GELIJK". ELSE Onderdeel van IF-THEN-ELSE constructie. ." ONGELIJK" Druk af "ONGELIJK". THEN Afsluiting van de IF-ELSE-THEN constructie. Na het uitvoeren van de operaties tussen "IF" en "ELSE" of tussen “ELSE" en "THEN", gaat het programma verder met de operaties na "THEN". ; Afsluiting van de definitie. 3 5 GELIJK? geeft: ONGELIJK OK 7 7 GELIJK? geeft: GELIJK OK Binnen FORTH wordt de logische waarde "NIET-WAAR" gerepresenteerd door het getal 0. Ieder getal ongelijk aan nul representeert" de logische waarde "WAAR”. De relationele operaties in FORTH, waartoe ook de operatie "=" behoort, zetten op de STACK het getal 1 als de uitkomst moet zijn "WAAR". Dus: 7 3 = . geeft: 0 OK 5 5 = . geeft: 1 OK FORTH kent de volgende relationele operaties: 0= Zet een 1 op de STACK als het bovenste getal gelijk is aan 0. Is het bovenste getal niet gelijk aan 0. dan komt er een 0 op de STACK. 0< Zet een 1 op de STACK als het bovenste getal negatief is. Is het bovenste getal niet-negatief dan komt er een 0 op de STACK. = Zet een 1 op de STACK als de twee bovenste getallen gelijk zijn. Zijn de twee getallen ongelijk dan komt er een 0 op de STACK. < Zet een 1 op de STACK als het bovenste getal kleiner is dan het tweede getal op de STACK. In alle andere gevallen komt er een 0 op de STA.CK. > Zet een 1 op de STACK als het bovenste getal groter is dan het tweede getal op de STACK. In alle andere gevallen komt er een 0 op de STACK. 5 5 <.. geeft: 0 OK 0 0 = . geeft: 1 OK 8 0 < . geeft: 0 OK -153 0< . geeft: 1 OK 8. BEGIN-UNTIL We bekijken een voorbeeld. : DRUK-AF-TOT-0 BEGIN DUP. O= UNTIL ; Verklaring: : DRUK-AF-TOT-0 Is het begin van de definitie. BEGIN Dit is het begin van de BEGIN-UNTIL constructie. DUP. Druk het bovenste getal van de STACK af. 0= Kijk of dit getal gelijk is aan 0. UNTIL Ga door totdat de voorgaande test het antwoord "WAAR" oplevert. Als de voorgaande test "NIET-WAAR" oplevert ga dan terug naar "BEGIN". ; Einde van de definitie. 1 2 3 0 4 7 3 1 DRUK-AF-TOT-0 geeft: 1 3 7 4 0 OK Als illustratie kan het volgende voorbeeld dienen. Het berekent de grootste gemene deler van twee getallen. : COPY OVER OVER ; : G-G-D BEGIN COPY -ABS ROT ROT MIN DUP 0= UNTIL DROP ; : GGD CR ." DE G.G.D. VAN " COPY .. ” EN " .." IS " G-G-D .; 9 15 GGD geeft: DE G.G.D. VAN 15 EN 9 IS 3 OK 221 119 GGD geeft: DE G.G.D. VAN 119 EN 221 IS 17 OK De berekening van het kleinste gemene veelvoud gaat als volgt: : KGV COPY * ROT ROT G-G-D / ; 8 12 KGV . geeft: 24 OK 9. BEGIN-WHILE-REPEAT. Ook nu beginnen we met een voorbeeld. : DELETEO BEGIN DUP 0= WHILE DROP REPEAT ; Verklaring: : Begin van de definitie. DELETEO Naam van deze functie. BEGIN Dit is het begin van de BEGIN-WHILE-REPEAT constructie. DUP O= We testen of het bovenste getal op de S~CK gelijk is aan 0. WHILE Als de voorgaande test als resultaat "WAAR" heeft, dan wordt verder gegaan met de volgende operatie. Was het resultaat "ONWAAR" ; dan springen we naar de operatie die staat achter "REPEAT" . DROP Als het bovenste getal gelijk is aan 0, verwijder het dan. REPEAT Spring terug naar “BEGIN” ; Einde van de definitie. Met deze operatie kunnen we alle nullen boven op de STACK verwijderen. 1 2 3 0 0 9 0 0 0 DELETEO …… geeft: 9 0 0 3 2 OK We kunnen nu een voorbeeld programmaatje laten zien. Het is een spelletje. De speler moet een getal tussen 1 en 1023 in gedachten nemen. De computer zal proberen het getal te raden. : MIDDEL OVER OVER + 2 / ; : VRAAG1 CR ." IS HET " MIDDEL. ." ? " KEY DUP EMIT ; : VRAAG2 CR .” GROTER OF KLEINER? " KEY DUP EMIT ; : RADEN 0 1024 BEGIN VRAAG1 78 = ASCII waarde "N" WHILE VRAAG2 71 = ASCII waarde "G" IF MIDDEL ROT DROP SWAP ELSE MIDDEL SWAP DROP THEN REPEAT DROP DROP CR ." GEVONDEN " CR ; Het spel zou als volgt kunnen verlopen: RADEN IS HET 512? N GROTER OF KLEINER? K IS HET 256? J GEVONDEN OK |