a estrutura básica de dados de Forth é o “dicionário” que mapeia “palavras” para código executável ou estruturas de dados nomeadas. O dicionário é colocado na memória como uma árvore de listas vinculadas com os links procedendo da última palavra (mais recentemente) definida para a mais antiga, até que um valor Sentinela, geralmente um ponteiro nulo, é encontrado. Uma mudança de contexto faz com que uma pesquisa de lista comece em uma folha diferente. Uma pesquisa de lista ligada continua à medida que o ramo se funde no tronco principal levando eventualmente de volta para o Sentinela, o root.Pode haver vários dicionários. Em casos raros, como a meta-compilação, um dicionário pode ser isolado e isolado.O efeito se assemelha ao de aninhar espaços de nomes e pode sobrecarregar palavras-chave dependendo do contexto.
uma palavra definida geralmente consiste em cabeça e corpo com a cabeça consistindo do campo Nome (NF) e do campo de ligação (LF), e corpo consistindo do campo de código (CF) e do campo de parâmetro (PF).
A cabeça e o corpo de uma entrada de dicionário são tratados separadamente porque eles podem não ser contíguos. Por exemplo, quando UM programa Forth é recompilado para uma nova plataforma, a cabeça pode permanecer no computador de compilação, enquanto o corpo vai para a nova plataforma. Em alguns ambientes (como sistemas embutidos) as cabeças ocupam a memória desnecessariamente. No entanto, alguns compiladores cruzados podem colocar cabeças no alvo se o próprio alvo é esperado para suportar um Forth interativo.
dictionary entryEdit
The exact format of a dictionary entry is not prescribed, and implementations vary. No entanto, certos componentes estão quase sempre presentes, embora o tamanho exato e a ordem podem variar. Descrito como uma estrutura, uma entrada de dicionário que pode ficar desta forma:
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
O nome do campo começa com um prefixo dando o comprimento da palavra do nome (normalmente até 32 bytes), e vários bits de flags. A representação de caracteres do nome da palavra segue então o prefixo. Dependendo da implementação particular da Forth, pode haver um ou mais bytes NUL (‘\0’) para alinhamento.
O campo de ligação contém um ponteiro para a palavra previamente definida. O ponteiro pode ser um deslocamento relativo ou um endereço absoluto que aponta para o próximo irmão mais velho.
o ponteiro do campo de código será o endereço da palavra que irá executar o código ou dados no campo de parâmetro ou o início do Código da máquina que o processador irá executar diretamente. Para palavras definidas por dois pontos, o campo de código aponta para a palavra que irá salvar o atual Quarto ponteiro de instrução (IP) na pilha de retorno, e carregar o IP com o novo endereço a partir do qual continuar a execução de palavras. Isto é o mesmo que as instruções de chamada/retorno de um processador fazem.
estrutura do compilerEdit
o compilador em si não é um programa monolítico. Consiste em Forth palavras visíveis para o sistema, e utilizável por um programador. Isto permite que um programador altere as palavras do compilador para propósitos especiais.
a opção ” Tempo de compilação “no campo Nome é definida para palavras com o comportamento” tempo de compilação”. A maioria das palavras simples executam o mesmo código se eles são digitados em uma linha de comando, ou embutidos em código. Ao compilá-los, o compilador simplesmente coloca código ou um ponteiro roscado para a palavra.
Os exemplos clássicos de tempo de compilação palavras são as estruturas de controle, tais como IF
e WHILE
. Quase todas as estruturas de controle da Forth e quase todos os seus compiladores são implementados como palavras de tempo de compilação. Além de algumas palavras de fluxo de controle raramente usadas apenas encontradas em algumas implementações, como um retorno condicional, todas as palavras de fluxo de controle de Forth são executadas durante a compilação para compilar várias combinações de palavras primitivas, juntamente com seus endereços de ramo. Por exemplo, IF
e WHILE
, e as palavras que coincidem com aqueles, configurar BRANCH
(incondicional ramo) e ?BRANCH
pop (um valor na pilha, e um ramo, se ela é falsa). As palavras de fluxo de controle de loop contadas funcionam da mesma forma, mas configuram combinações de palavras primitivas que funcionam com um contador, e assim por diante. Durante a compilação, a pilha de dados é usada para suportar o balanceamento da estrutura de controle, nidificação e back-patching de endereços de branch. O fragmento:
... DUP 6 < IF DROP 5 ELSE 1 - THEN ...
deve ser compilado para a seguinte seqüência dentro de uma definição de:
... DUP LIT 6 < ?BRANCH 5 DROP LIT 5 BRANCH 3 LIT 1 - ...
Os números depois de BRANCH
representam um salto relativo endereços. LIT
é a palavra primitiva para empurrar um número “literal” para a pilha de dados.
Compilation state and interpretation stateEdit
the word :
(colon) parses a name as a parameter, creates a dictionary entry (A colon definition) and enters compilation state. O interpretador continua a ler as palavras delimitadas pelo espaço do dispositivo de entrada do utilizador. Se uma palavra é encontrada, o interpretador executa a semântica de compilação associada com a palavra, em vez da semântica de interpretação. A semântica de compilação padrão de uma palavra é adicionar sua semântica de interpretação à definição atual.
A Palavra ;
(ponto e vírgula) termina a definição actual e retorna ao estado de interpretação. É um exemplo de uma palavra cuja semântica de compilação difere do padrão. A interpretação semântica de ;
(semicolon), a maioria das palavras de fluxo de controle, e várias outras palavras são indefinidas EM and Forth, significando que elas só devem ser usadas dentro de definições e não na linha de comando interativa.
o estado interpretador pode ser alterado manualmente com as palavras (suporte direito) que entram estado de interpretação ou estado de compilação, respectivamente. Estas palavras podem ser usadas com a palavra para calcular um valor durante uma compilação e para inserir o valor calculado na definição actual de dois pontos. tem a semântica de compilação para pegar um objeto da pilha de dados e adicionar semântica à definição atual de dois pontos para colocar esse objeto na pilha de dados.
In ANS Forth, the current state of the interpreter can be read from the flag STATE
which contains the value true when in compilation state and false otherwise. Isto permite a implementação das chamadas palavras inteligentes de estado com comportamento que muda de acordo com o estado atual do intérprete.
wordsEdit
a palavra IMMEDIATE
marca a definição mais recente do cólon como uma palavra imediata, efetivamente substituindo sua semântica compilação com sua semântica de interpretação. Palavras imediatas são normalmente executadas durante a compilação, não compiladas, mas isso pode ser substituído pelo programador em qualquer estado. ;
é um exemplo de uma palavra imediata. In ANS Forth, the word takes a name as a parameter and appends the compilation semantics of the named word to the current definition even if the word was marked immediate. Forth-83 defined separate words COMPILE
and to force the compilation of non-immediate and immediate words, respectively.
palavras sem nome e execução tokensEdit
Na ANS por Diante, sem nome, as palavras podem ser definidas com a palavra :NONAME
que compila as seguintes palavras até a próxima ;
(ponto-e-vírgula) e deixa a execução do token sobre os dados da pilha. O token de execução fornece uma pega opaca para a semântica compilada, semelhante aos ponteiros de função da linguagem de programação C.os tokens de execução podem ser armazenados em variáveis. A palavra EXECUTE
toma um token de execução a partir da pilha de dados e executa a semântica associada. A palavra COMPILE,
(compile-vírgula) pega um token de execução da pilha de dados e adiciona a semântica associada à definição atual.
A Palavra '
(assinalar) toma o nome de uma palavra como um parâmetro e devolve o símbolo de execução associado a essa palavra na pilha de dados. Em estado de interpretação, ' RANDOM-WORD EXECUTE
é equivalente aRANDOM-WORD
.
Editar
palavras :
(cólon), POSTPONE
'
(tick) são exemplos de análise de palavras que levam seus argumentos a partir do dispositivo de entrada de utilizador em vez dos dados da pilha. Outro exemplo é a palavra (
(paren) que lê e ignora as seguintes palavras até e incluindo o próximo parêntesis direito e é usado para colocar comentários em uma definição de dois pontos. Similarmente, a palavra \
(barra invertida) é usada para comentários que continuam até o final da linha atual. Para ser processado corretamente, (
(paren) e \
(backslash) deve ser separado pelo espaço em branco do seguinte texto de comentários.
estrutura do codeEdit
na maioria dos sistemas Forth, o corpo de uma definição de código consiste em qualquer linguagem de máquina, ou alguma forma de código roscado. O Forth original que segue o padrão informal da FIG (Forth Interest Group), é um TIL (linguagem interpretativa roscada). Isto também é chamado de código indireto-roscado, mas bifurcados diretos e Subrotinos roscados também se tornaram populares nos tempos modernos. Os fortes modernos mais rápidos, como SwiftForth, VFX Forth, e iForth, compilam para o código de máquina nativo.
data objectsEdit
quando uma palavra é uma variável ou outro objeto de dados, o CF aponta para o código de tempo de execução associado com a palavra definidora que a criou. Uma palavra definidora tem um “comportamento definidor” característico (criando uma entrada de dicionário mais possivelmente alocando e inicializando espaço de dados) e também especifica o comportamento de uma instância da classe de palavras construída por esta palavra definidora. Os exemplos incluem::
VARIABLE
nomeia uma localização de memória de uma célula. Comportamento de instância de umVARIABLE
devolve o seu endereço na pilha.CONSTANT
nomeia um valor (especificado como um argumento paraCONSTANT
). O comportamento da instância devolve o valor.CREATE
nomeia um local; o espaço pode ser alocado neste local, ou pode ser configurado para conter uma cadeia de caracteres ou outro valor inicializado. O comportamento da instância devolve o endereço do início deste espaço.
Forth também fornece uma facilidade pela qual um programador pode definir novas palavras definidoras específicas de Aplicação, especificando tanto um comportamento definidor personalizado e comportamento de instância. Alguns exemplos incluem buffers circulares, bits nomeados em uma porta I/O, e arrays automaticamente indexados.
os objetos de dados definidos por estas e palavras similares são globais em escopo. A função fornecida por variáveis locais em outras linguagens é fornecida pela pilha de dados em Forth (embora Forth também tenha variáveis locais reais). Forth estilo de programação usa muito poucos objetos de dados nomeados em comparação com outras linguagens; tipicamente, esses objetos de dados são usados para conter dados que são usados por um número de palavras ou tarefas (em uma implementação multitarefa).
Forth não faz valer a consistência do uso do tipo de dados; é da responsabilidade do programador usar operadores apropriados para obter e armazenar valores ou realizar outras operações sobre dados.