Forth ‘ s grundlæggende datastruktur er “ordbogen”, der kortlægger “ord” til eksekverbar kode eller navngivne datastrukturer. Ordbogen er lagt ud i hukommelsen som et træ af sammenkædede lister med linkene, der går fra det seneste (Senest) definerede ord til det ældste, indtil en sentinelværdi, normalt en NULL-markør, findes. En kontekstkontakt får en listesøgning til at starte ved et andet blad. En linket listesøgning fortsætter, når grenen smelter sammen i hovedstammen, der til sidst fører tilbage til sentinel, roden.Der kan være flere ordbøger. I sjældne tilfælde såsom meta-kompilering en ordbog kan være isoleret og stand-alone.Effekten ligner effekten af indlejrede navneområder og kan overbelaste nøgleord afhængigt af konteksten.
et defineret ord består generelt af hoved og krop med hovedet bestående af navnefeltet (NF) og linkfeltet (LF) og krop bestående af kodefeltet (CF) og parameterfeltet (PF).
hoved og krop i en ordbogspost behandles separat, fordi de muligvis ikke er sammenhængende. For eksempel, når et Forth-program kompileres igen til en ny platform, kan hovedet forblive på kompileringscomputeren, mens kroppen går til den nye platform. I nogle miljøer (såsom indlejrede systemer) optager hovederne unødvendigt hukommelse. Imidlertid, nogle cross-compilere kan sætte hoveder i målet, hvis målet selv forventes at understøtte en interaktiv Forth.
Dictionary entryEdit
det nøjagtige format for en ordbogspost er ikke foreskrevet, og implementeringerne varierer. Imidlertid er visse komponenter næsten altid til stede, selvom den nøjagtige størrelse og rækkefølge kan variere. Beskrevet som en struktur kan en ordbogspost se sådan ud:
structure byte: flag \ 3bit flags + length of word's name char-array: name \ name's runtime length isn't known at compile time address: previous \ link field, backward ptr to previous word address: codeword \ ptr to the code to execute this word any-array: parameterfield \ unknown length of data, words, or opcodes end-structure forthword
navnefeltet starter med et præfiks, der giver længden af ordets navn (typisk op til 32 bytes) og flere bits til flag. Tegnrepræsentationen af ordets navn følger derefter præfikset. Afhængig af den særlige implementering af Forth kan der være en eller flere NUL (‘\0’) bytes til justering.
linkfeltet indeholder en markør til det tidligere definerede ord. Markøren kan være en relativ forskydning eller en absolut adresse, der peger på det næstældste søskende.
kodefeltmarkøren vil enten være adressen på det ord, der udfører koden eller dataene i parameterfeltet eller begyndelsen af maskinkoden, som processoren udfører direkte. For kolon definerede ord, koden felt pointer peger på det ord, der vil gemme den aktuelle Forth instruktion pointer (IP) på returstakken, og indlæse IP med den nye adresse, hvorfra at fortsætte udførelsen af ord. Dette er det samme som hvad en processors opkald/returinstruktioner gør.
struktur af kompilatorenrediger
kompilatoren selv er ikke et monolitisk program. Den består af Forth ord synlige for systemet, og Anvendelig af en programmør. Dette gør det muligt for en programmør at ændre kompilatorens ord til særlige formål.
flaget “compile time” i feltet Navn er indstillet til ord med “compile time” – adfærd. De fleste enkle ord udfører den samme kode, uanset om de er skrevet på en kommandolinje eller indlejret i kode. Ved kompilering af disse placerer kompilatoren simpelthen kode eller en gevindpeger til ordet.
de klassiske eksempler på kompileringstidsord er kontrolstrukturer somIF
ogWHILE
. Næsten alle Forths kontrolstrukturer og næsten alle dens kompilatorer implementeres som kompileringstidsord. Bortset fra nogle sjældent anvendte kontrolstrømord, der kun findes i nogle få implementeringer, såsom et betinget afkast, udføres alle Forths kontrolstrømord under kompilering for at kompilere forskellige kombinationer af primitive ord sammen med deres grenadresser. For eksempelIF
ogWHILE
, og de ord, der matcher med dem, skal du opretteBRANCH
(ubetinget gren) og?BRANCH
(pop en værdi fra stakken og gren, hvis den er falsk). Tælles loop kontrol strømningsord arbejde på samme måde, men oprette kombinationer af primitive ord, der arbejder med en tæller, og så videre. Under kompilering bruges datastakken til at understøtte kontrolstrukturbalancering, indlejring og back-patching af filialadresser. Uddraget:
... DUP 6 < IF DROP 5 ELSE 1 - THEN ...
ville blive kompileret til følgende sekvens inde i en definition:
... DUP LIT 6 < ?BRANCH 5 DROP LIT 5 BRANCH 3 LIT 1 - ...
tallene efter BRANCH
repræsenterer relative springadresser. LIT
er det primitive ord for at skubbe et” bogstaveligt ” nummer på datastakken.
Kompileringstilstand og fortolkningstilstandredit
ordet:
(kolon) analyserer et navn som en parameter, opretter en ordbogspost (en kolondefinition) og går ind i kompileringstilstand. Tolken fortsætter med at læse rumafgrænsede ord fra brugerinputenheden. Hvis der findes et ord, udfører tolken kompileringssemantikken, der er forbundet med ordet, i stedet for fortolkningssemantikken. Standard kompilering semantik af et ord er at tilføje sin fortolkning semantik til den aktuelle definition.
ordet;
(semikolon) afslutter den aktuelle definition og vender tilbage til fortolkningstilstand. Det er et eksempel på et ord, hvis kompileringssemantik adskiller sig fra standard. Tolkningssemantikken af ;
(semikolon), de fleste styrestrømsord og flere andre ord er udefinerede i ANS frem, hvilket betyder, at de kun må bruges inden for definitioner og ikke på den interaktive kommandolinje.
tolketilstanden kan ændres manuelt med ordene (højre beslag), der indtaster henholdsvis fortolkningstilstand eller kompileringstilstand. Disse ord kan bruges med ordet
LITERAL
til at beregne en værdi under en kompilering og indsætte den beregnede værdi i den aktuelle kolondefinition. LITERAL
har kompileringssemantikken til at tage et objekt fra datastakken og tilføje semantik til den aktuelle kolondefinition for at placere objektet på datastakken.
i ANS Forth kan tolkens aktuelle tilstand læses fra flagetSTATE
som indeholder værdien sand, når den er i kompileringstilstand og falsk ellers. Dette muliggør implementering af såkaldte tilstands-smarte ord med adfærd, der ændrer sig i henhold til tolkens aktuelle tilstand.
umiddelbare ordredit
ordetIMMEDIATE
markerer den seneste kolondefinition som et øjeblikkeligt ord, der effektivt erstatter dets kompileringssemantik med dets fortolkningssemantik. Umiddelbare ord udføres normalt under kompilering, ikke kompileret, men dette kan tilsidesættes af programmereren i begge stater. ;
er et eksempel på et øjeblikkeligt ord. I ANS Forth tager ordet POSTPONE
et navn som en parameter og tilføjer kompileringssemantikken for det navngivne ord til den aktuelle definition, selvom ordet blev markeret øjeblikkeligt. Forth-83 definerede separate ord COMPILE
og for at tvinge kompilering af henholdsvis ikke-øjeblikkelige og øjeblikkelige ord.
unavngivne ord og udførelse tokensEdit
i ANS Forth kan unavngivne ord defineres med ordet:NONAME
som samler følgende ord op til det næste;
(semikolon) og efterlader et eksekveringstoken på datastakken. Udførelsestokenet giver et uigennemsigtigt håndtag til den kompilerede semantik, svarende til funktionspegerne i C-programmeringssproget.
udførelse tokens kan gemmes i variabler. Ordet EXECUTE
tager et eksekveringstoken fra datastakken og udfører den tilhørende semantik. Ordet COMPILE,
(compile-comma) tager et eksekveringstoken fra datastakken og tilføjer den tilknyttede semantik til den aktuelle definition.
ordet'
(tick) tager navnet på et ord som en parameter og returnerer det eksekveringstoken, der er knyttet til det ord på datastakken. I fortolkningstilstand svarer ' RANDOM-WORD EXECUTE
til RANDOM-WORD
.
Rediger
ordene:
(kolon),POSTPONE
'
(tick) er eksempler på parsing af ord, der tager deres argumenter fra brugerinputenheden i stedet for datastakken. Et andet eksempel er ordet (
(paren), der læser og ignorerer følgende ord til og med den næste højre parentes og bruges til at placere kommentarer i en kolondefinition. Tilsvarende bruges ordet \
(backslash) til kommentarer, der fortsætter til slutningen af den aktuelle linje. For at blive analyseret korrekt skal (
(paren) og \
(backslash) adskilles med mellemrum fra følgende kommentartekst.
struktur af codeEdit
i de fleste Forth-systemer består kroppen af en kodedefinition af enten maskinsprog eller en eller anden form for gevindkode. Den oprindelige Forth som følger den uformelle FIG standard (Forth interesse gruppe), er en to the (Threaded Interpretive Language). Dette kaldes også indirekte gevind kode, men direkte gevind og subrutine gevind Forths er også blevet populære i moderne tid. De hurtigste moderne Forths, som f.eks.
Data objectsEdit
når et ord er en variabel eller et andet dataobjekt, peger CF på den runtime-kode, der er knyttet til det definerende ord, der oprettede det. Et definerende ord har en karakteristisk” definerende adfærd ” (oprettelse af en ordbogspost plus muligvis tildeling og initialisering af datarum) og specificerer også opførslen af en forekomst af klassen af ord Konstrueret af dette definerende ord. Eksempler inkluderer:
VARIABLE
navngiver en uinitialiseret hukommelsesplacering med en celle. Instansadfærd af enVARIABLE
returnerer sin adresse på stakken.CONSTANT
navngiver en værdi (angivet som et argument tilCONSTANT
). Instansadfærd returnerer værdien.CREATE
navngiver en placering; plads kan tildeles på dette sted, eller det kan indstilles til at indeholde en streng eller anden initialiseret værdi. Instansadfærd returnerer adressen til begyndelsen af dette rum.
Forth giver også en facilitet, hvormed en programmør kan definere nye applikationsspecifikke definerende ord, der specificerer både en brugerdefineret definerende adfærd og instansadfærd. Nogle eksempler inkluderer cirkulære buffere, navngivne bits på en I / O-port og automatisk indekserede arrays.
dataobjekter defineret af disse og lignende ord er Globale i omfang. Funktionen leveret af lokale variabler på andre sprog leveres af datastakken i Forth (selvom Forth også har reelle lokale variabler). Forth programmeringsstil bruger meget få navngivne dataobjekter sammenlignet med andre sprog; typisk bruges sådanne dataobjekter til at indeholde data, der bruges af et antal ord eller opgaver (i en multitasked implementering).det er programmørens ansvar at bruge passende operatører til at hente og gemme værdier eller udføre andre handlinger på data.