Forth (linguagem de programação)
Forth é uma linguagem de programação procedural orientada a pilha e um ambiente interativo projetado por Charles H. "Chuck" Moore e usado pela primeira vez por outros programadores em 1970. Embora não seja um acrônimo, o nome da linguagem em seus primeiros anos era frequentemente escrito em letras maiúsculas como FORTH. As implementações FORTH-79 e FORTH-83, que não foram escritas por Moore, tornaram-se padrões de fato, e uma padronização oficial da linguagem foi publicada em 1994 como ANS Forth. Uma ampla gama de derivados do Forth existiu antes e depois do ANS Forth. A implementação do software livre Gforth é mantida ativamente, assim como vários sistemas suportados comercialmente.
Forth normalmente combina um compilador com um shell de comando integrado, onde o usuário interage por meio de sub-rotinas chamadas palavras. As palavras podem ser definidas, testadas, redefinidas e depuradas sem recompilar ou reiniciar todo o programa. Todos os elementos sintáticos, incluindo variáveis, operadores e fluxo de controle, são definidos como palavras. Uma pilha é usada para passar parâmetros entre as palavras, levando a um estilo de notação polonesa reversa.
Durante grande parte da existência do Forth, a técnica padrão era compilar em código encadeado, que pode ser interpretado mais rapidamente que o bytecode. Um dos primeiros benefícios do Forth era o tamanho: todo um ambiente de desenvolvimento - incluindo compilador, editor e programas de usuário - poderia caber na memória em um sistema de 8 bits ou similarmente limitado. Não mais limitados pelo espaço, existem implementações modernas que geram código de máquina otimizado como outros compiladores de linguagem. A relativa simplicidade de criar um sistema Forth básico levou a muitas variantes pessoais e proprietárias, como o Forth personalizado usado para implementar o videogame mais vendido de 1986 Starflight da Electronic Arts.
Forth é usado no carregador de inicialização do Open Firmware, em aplicativos espaciais como a espaçonave Philae e em outros sistemas embarcados que envolvem interação com hardware.
Moore mais tarde desenvolveu uma série de microprocessadores para executar código compilado semelhante ao Forth diretamente e experimentou linguagens menores baseadas nos conceitos do Forth, incluindo cmForth e colorForth. A maioria dessas linguagens foi projetada para dar suporte aos próprios projetos de Moore, como o design de chips.
Usos
Forth tem um nicho em aplicações astronômicas e espaciais, bem como uma história em sistemas embarcados. As ROMs de inicialização do Open Firmware usadas pela Apple, IBM, Sun e OLPC XO-1 contêm um ambiente Forth.
Forth tem sido freqüentemente usado para criar um novo hardware. Forth foi o primeiro software residente no novo chip Intel 8086 em 1978, e MacFORTH foi o primeiro sistema de desenvolvimento residente para o Macintosh 128K em 1984.
A Atari, Inc. usou uma elaborada demonstração animada escrita em Forth para mostrar os recursos dos computadores Atari 400 e 800 em lojas de departamentos. Três videogames da Electronic Arts, publicados na década de 1980, foram escritos em Forth: Worms? (1983), Starflight (1986) e Lords of Conquest (1986).
Ashton-Tate's RapidFile (1986), um programa de banco de dados de arquivo simples, e VP-Planner da Paperback Software International (1983), um programa de planilhas que compete com o Lotus 1-2-3, foram escritos em Forth.
A Canon Cat (1987) usa Forth para a programação do sistema.
A Rockwell produziu microcomputadores de chip único com kernels Forth residentes: o R65F11 e o R65F12. ASYST foi uma expansão Forth para medição e controle em PCs.
História
Forth evoluiu a partir do sistema de programação pessoal de Charles H. Moore, que estava em desenvolvimento contínuo desde 1968. Forth foi exposto pela primeira vez a outros programadores no início dos anos 1970, começando com Elizabeth Rather na Rádio Astronomia Nacional dos Estados Unidos Observatório (NRAO). Após seu trabalho na NRAO, Charles Moore e Elizabeth Rather formaram a FORTH, Inc. em 1973, refinando e transportando os sistemas Forth para dezenas de outras plataformas na década seguinte.
Forth é assim chamado porque em 1968 "o arquivo contendo o interpretador foi rotulado FOURTH, para software de 4ª (próxima) geração, mas o sistema operacional IBM 1130 restringiu os nomes de arquivo a cinco caracteres." Moore viu o Forth como um sucessor das linguagens de programação de terceira geração compile-link-go, ou software para "quarta geração" hardware.
O microFORTH da FORTH, Inc. foi desenvolvido para os microprocessadores Intel 8080, Motorola 6800, Zilog Z80 e RCA 1802, a partir de 1976. O MicroFORTH foi posteriormente usado por amadores para gerar sistemas Forth para outras arquiteturas, como como o 6502 em 1978. O Forth Interest Group foi formado em 1978. Ele promoveu e distribuiu sua própria versão da linguagem, FIG-Forth, para a maioria das marcas de computadores domésticos.
Forth era popular no início dos anos 1980, porque era adequado para a memória limitada dos microcomputadores. A facilidade de implementação da linguagem levou a muitas implementações. O computador doméstico britânico Jupiter ACE possui Forth em seu sistema operacional residente em ROM. Insoft GraFORTH é uma versão do Forth com extensões gráficas para o Apple II.
A prática comum foi codificada nos padrões de fato FORTH-79 e FORTH-83 nos anos de 1979 e 1983, respectivamente. Esses padrões foram unificados pela ANSI em 1994, comumente referidos como ANS Forth.
A partir de 2018, a fonte da versão 1130 original do FORTH foi recuperada e agora está sendo atualizada para rodar em um sistema 1130 restaurado ou emulado.
Visão geral
Forth enfatiza o uso de funções pequenas e simples chamadas palavras. Palavras para tarefas maiores requerem muitas palavras menores, cada uma realizando uma subtarefa distinta. Um grande programa Forth é uma hierarquia de palavras. Essas palavras, sendo módulos distintos que se comunicam implicitamente por meio de um mecanismo de pilha, podem ser prototipadas, construídas e testadas independentemente. O nível mais alto do código Forth pode se assemelhar a uma descrição em inglês do aplicativo. Forth tem sido chamada de linguagem de meta-aplicação: uma linguagem que pode ser usada para criar linguagens orientadas a problemas.
Forth depende do uso explícito de uma pilha de dados e da notação polonesa reversa, que é comumente usada em calculadoras da Hewlett-Packard. No RPN, o operador é colocado após seus operandos, ao contrário da notação infixa mais comum, em que o operador é colocado entre seus operandos. A notação pós-fixada torna a linguagem mais fácil de analisar e estender; A flexibilidade de Forth torna uma gramática BNF estática inapropriada e não possui um compilador monolítico. Estender o compilador requer apenas escrever uma nova palavra, em vez de modificar uma gramática e alterar a implementação subjacente.
Usando RPN, pode-se obter o resultado da expressão matemática (25 * 10 + 50)
desta forma:
25 10. * 50 + CR . 300 Está bem.
Primeiro os números 25 e 10 são colocados na pilha.
A palavra *
pega os dois primeiros números da pilha, multiplica-os e coloca o produto de volta na pilha.
Em seguida, o número 50 é colocado na pilha.
A palavra +
adiciona os dois primeiros valores, empurrando a soma. CR
(retorno de carro) inicia a saída em uma nova linha. Finalmente, .
imprime o resultado. Como tudo foi concluído com sucesso, o sistema Forth imprime OK
.
Mesmo os recursos estruturais de Forth são baseados em pilha. Por exemplo:
: FLOOR5 (n) DUP 6 < IF DROP 5 ELSE 1 - Não. A ;
Os dois pontos indicam o início de uma nova definição, neste caso uma nova palavra (novamente, palavra é o termo usado para uma sub-rotina) chamada FLOOR5
. O texto entre parênteses é um comentário, avisando que esta palavra espera um número na pilha e retornará um número possivelmente alterado (na pilha).
A sub-rotina usa os seguintes comandos: DUP
duplica o número na pilha; 6
coloca um 6 no topo da pilha; <
compara os dois primeiros números na pilha (6 e a entrada DUP
ed) e os substitui por um valor verdadeiro ou falso; IF
recebe um valor verdadeiro ou falso e escolhe executar comandos imediatamente após ele ou pular para ELSE
; DROP
descarta o valor na pilha; 5
coloca um 5 no topo da pilha; e THEN
finaliza a condicional.
A palavra FLOOR5
é equivalente a esta função escrita na linguagem de programação C usando o operador ternário '?:'
- Não. piso5(- Não. v) ( retorno (v < 6) ? 5 : (v - Não. 1);?
Esta função é escrita de forma mais sucinta como:
: FLOOR5 (n) 1... 5 Max. ;
Isso pode ser executado da seguinte maneira:
1 FLOOR5 CR . 5 Está bem. 8 FLOOR5 CR . 7 Está bem.
Primeiro, um número (1 ou 8) é colocado na pilha, FLOOR5
é chamado, que exibe o número novamente e empurra o resultado. CR
move a saída para uma nova linha (novamente, isso está aqui apenas para facilitar a leitura). Por fim, uma chamada para .
mostra o resultado e imprime.
Instalações
A gramática de Forth não tem especificação oficial. Em vez disso, é definido por um algoritmo simples. O interpretador lê uma linha de entrada do dispositivo de entrada do usuário, que é então analisada em busca de uma palavra usando espaços como delimitador; alguns sistemas reconhecem caracteres de espaço em branco adicionais. Quando o intérprete encontra uma palavra, ele a procura no dicionário. Se a palavra for encontrada, o interpretador executa o código associado à palavra e retorna para analisar o restante do fluxo de entrada. Se a palavra não for encontrada, a palavra será considerada um número e será feita uma tentativa de convertê-la em um número e colocá-la na pilha; se for bem-sucedido, o interpretador continua analisando o fluxo de entrada. Caso contrário, se a pesquisa e a conversão do número falharem, o interpretador imprime a palavra seguida por uma mensagem de erro indicando que a palavra não foi reconhecida, libera o fluxo de entrada e aguarda uma nova entrada do usuário.
A definição de uma nova palavra começa com a palavra :
(dois pontos) e termina com a palavra ;
(ponto e vírgula). Por exemplo,
: X DUP 1+ . . ;
compilará a palavra X
e tornará o nome localizável no dicionário. Quando executado digitando 10 X
no console, isso imprimirá 11 10
.
A maioria dos sistemas Forth inclui um montador para escrever palavras usando os recursos do processador. Os montadores Forth geralmente usam uma sintaxe polonesa reversa na qual os parâmetros de uma instrução precedem a instrução. Um montador polonês reverso típico prepara os operandos na pilha e o mnemônico copia toda a instrução na memória como a última etapa. Um montador Forth é, por natureza, um montador de macro, de modo que é fácil definir um alias para registradores de acordo com sua função no sistema Forth: por exemplo, "dsp" para o registro usado como o ponteiro da pilha de dados.
Sistema operacional, arquivos e multitarefa
A maioria dos sistemas Forth é executada em um sistema operacional host, como Microsoft Windows, Linux ou uma versão do Unix, e usa o sistema de arquivos do sistema operacional host para arquivos de origem e de dados; o ANSI Forth Standard descreve as palavras usadas para E/S. Todos os sistemas Forth modernos usam arquivos de texto normais como fonte, mesmo que estejam incorporados. Um sistema embarcado com um compilador residente obtém sua fonte através de uma linha serial.
Os sistemas Classic Forth tradicionalmente não usam sistema operacional nem sistema de arquivos. Em vez de armazenar o código em arquivos, o código-fonte é armazenado em blocos de disco gravados em endereços de disco físico. A palavra BLOCK
é empregada para traduzir o número de um bloco de tamanho de 1K de espaço em disco no endereço de um buffer contendo os dados, que é gerenciado automaticamente pelo sistema Forth. O uso de blocos tornou-se raro desde meados da década de 1990. Em um sistema hospedado, esses blocos também são alocados em um arquivo normal em qualquer caso.
Multitarefa, mais comumente agendamento round-robin cooperativo, está normalmente disponível (embora palavras e suporte multitarefa não sejam cobertos pelo ANSI Forth Standard). A palavra PAUSE
é usada para salvar o contexto de execução da tarefa atual, para localizar a próxima tarefa e restaurar seu contexto de execução. Cada tarefa tem suas próprias pilhas, cópias privadas de algumas variáveis de controle e uma área de rascunho. A troca de tarefas é simples e eficiente; como resultado, os multitarefas Forth estão disponíveis até mesmo em microcontroladores muito simples, como Intel 8051, Atmel AVR e TI MSP430.
Outras facilidades não padronizadas incluem um mecanismo para emitir chamadas para o sistema operacional host ou sistemas de janelas, e muitos fornecem extensões que empregam o agendamento fornecido pelo sistema operacional. Normalmente, eles têm um conjunto maior e diferente de palavras da palavra PAUSE
independente do Forth para criação, suspensão, destruição e modificação de prioridade de tarefa.
Autocompilação e compilação cruzada
Um sistema Forth completo com todo o código-fonte irá compilar a si mesmo, uma técnica comumente chamada de meta-compilação ou auto-hospedagem, pelos programadores Forth (embora o termo não corresponda exatamente à meta-compilação como normalmente é definiram). O método usual é redefinir o punhado de palavras que colocam os bits compilados na memória. As palavras do compilador usam versões especialmente nomeadas de busca e armazenamento que podem ser redirecionadas para uma área de buffer na memória. A área de buffer simula ou acessa uma área de memória começando em um endereço diferente do buffer de código. Esses compiladores definem palavras para acessar a memória do computador de destino e a memória do computador host (compilando).
Depois que as operações de busca e armazenamento são redefinidas para o espaço de código, o compilador, montador, etc. são recompilados usando as novas definições de busca e armazenamento. Isso efetivamente reutiliza todo o código do compilador e do interpretador. Em seguida, o código do sistema Forth é compilado, mas esta versão é armazenada no buffer. O buffer na memória é gravado no disco e são fornecidas maneiras de carregá-lo temporariamente na memória para teste. Quando a nova versão parece funcionar, ela é escrita sobre a versão anterior.
Existem inúmeras variações de tais compiladores para diferentes ambientes. Para sistemas embarcados, o código pode ser escrito em outro computador, uma técnica conhecida como compilação cruzada, através de uma porta serial ou até mesmo um único bit TTL, mantendo os nomes das palavras e outras partes não executáveis do dicionário na compilação original. computador. As definições mínimas para tal compilador Forth são as palavras que buscam e armazenam um byte e a palavra que comanda a execução de uma palavra Forth. Freqüentemente, a parte mais demorada de escrever uma porta remota é construir o programa inicial para implementar busca, armazenamento e execução, mas muitos microprocessadores modernos têm recursos de depuração integrados (como a CPU32 da Motorola) que eliminam essa tarefa.
Estrutura da linguagem
A estrutura básica de dados do 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 encadeadas com os links procedendo da palavra definida mais recente (mais recentemente) para a mais antiga, até que um valor sentinela, geralmente um ponteiro NULL, seja encontrado. Uma troca de contexto faz com que uma pesquisa de lista comece em uma folha diferente. Uma pesquisa de lista encadeada continua à medida que a ramificação se funde no tronco principal, levando eventualmente de volta à sentinela, a raiz. Pode haver vários dicionários. Em casos raros, como metacompilação, um dicionário pode ser isolado e autônomo. O efeito se assemelha ao de espaços de nomes aninhados e pode sobrecarregar palavras-chave dependendo do contexto.
Uma palavra definida geralmente consiste em cabeçalho e corpo com o cabeçalho consistindo no campo de nome (NF) e no link campo (LF) e corpo que consiste no campo de código (CF) e no campo de parâmetro (PF).
Cabeçalho e corpo de uma entrada de dicionário são tratados separadamente porque 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 embarcados) as cabeças ocupam memória desnecessariamente. No entanto, alguns compiladores cruzados podem colocar cabeças no destino se for esperado que o próprio destino suporte um Forth interativo.
O formato exato de uma entrada de dicionário não é prescrito e as implementações variam.
Estrutura do compilador
O compilador em si não é um programa monolítico. Consiste em palavras Forth visíveis para o sistema e utilizáveis por um programador. Isso permite que um programador altere as palavras do compilador para fins especiais.
O "tempo de compilação" sinalizador no campo de nome é definido para palavras com "tempo de compilação" comportamento. A maioria das palavras simples executa o mesmo código, sejam elas digitadas em uma linha de comando ou incorporadas ao código. Ao compilá-los, o compilador simplesmente coloca o código ou um ponteiro encadeado para a palavra.
Os exemplos clássicos de palavras em tempo de compilação são as estruturas de controle como IF
e WHILE
. Quase todas as estruturas de controle do 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, encontradas apenas em algumas implementações, como a palavra de retorno condicional ?EXIT usada no preForth de Ulrich Hoffmann, todas as palavras de fluxo de controle de Forth são executadas durante a compilação para compilar vários combinações de palavras primitivas junto com seus endereços de ramificação. Por exemplo, IF
e WHILE
, e as palavras que correspondem a elas, configure BRANCH
(ramificação incondicional) e ?BRANCH
(retira um valor da pilha e ramifica se for falso). As palavras de fluxo de controle de loop contadas funcionam de maneira semelhante, 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, aninhamento e correção de endereços de ramificação. O trecho:
... DUP 6 < IF DROP 5 ELSE 1 - Não. A ...
muitas vezes seria compilado para a seguinte sequência dentro de uma definição:
... DUP LIT 6 < ? BRANQUEADO 5 DROP LIT 5 BRANQUEADO 3 LIT 1 - Não. ...
Os números após BRANCH
representam endereços de salto relativos. LIT
é a palavra primitiva para empurrar um "literal" número na pilha de dados. (Código mais rápido e mais curto seria compilado usando ponteiros para constantes em vez de LIT
e dados incorporados, se qualquer um dos números envolvidos tivesse sido definido separadamente como constantes. Haveria mudanças semelhantes se outras palavras fossem usadas em vez de constantes, e assim por diante.)
Estado de compilação e estado de interpretação
A palavra : (dois pontos) analisa um nome como um parâmetro, cria uma entrada de dicionário (uma definição de dois pontos) e entra no estado de compilação. O interpretador continua a ler palavras delimitadas por espaço do dispositivo de entrada do usuário. Se uma palavra for encontrada, o interpretador executa a semântica de compilação associada à palavra, em vez da semântica de interpretação. A semântica de compilação padrão de uma palavra é anexar sua semântica de interpretação à definição atual.
A palavra ;
(ponto e vírgula) finaliza a definição atual e retorna ao estado de interpretação. É um exemplo de palavra cuja semântica de compilação difere do padrão. A semântica de interpretação de ;
(ponto-e-vírgula), a maioria das palavras de fluxo de controle e várias outras palavras são indefinidas no ANS Forth, o que significa que elas devem ser usadas apenas dentro de definições e não na linha de comando interativa.
O estado do interpretador pode ser alterado manualmente com as palavras [
(colchete esquerdo) e ]
(colchete direito) que inserem o estado de interpretação ou o estado de compilação, respectivamente. Essas palavras podem ser usadas com a palavra LITERAL
para calcular um valor durante uma compilação e inserir o valor calculado na definição de dois pontos atual. LITERAL
tem a semântica de compilação para pegar um objeto da pilha de dados e anexar semântica à definição de dois pontos atual para colocar esse objeto na pilha de dados.
No ANS Forth, o estado atual do interpretador pode ser lido a partir do sinalizador STATE
que contém o valor true quando em estado de compilação e false caso contrário. Isso permite a implementação das chamadas palavras de estado inteligente com comportamento que muda de acordo com o estado atual do interpretador.
Palavras imediatas
A palavra IMMEDIATE
marca a definição de dois pontos mais recente como uma palavra imediata, substituindo efetivamente sua semântica de compilação por sua semântica de interpretação. As 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 palavra imediata. No ANS Forth, a palavra POSTPONE
recebe um nome como parâmetro e acrescenta a semântica de compilação da palavra nomeada à definição atual, mesmo que a palavra tenha sido marcada como imediata. Forth-83 definiu palavras separadas COMPILE
e [COMPILE]
para forçar a compilação de palavras não imediatas e imediatas, respectivamente.
Palavras sem nome e tokens de execução
Em ANS Forth, palavras sem nome podem ser definidas com a palavra :NONAME
que compila as seguintes palavras até o próximo ;
(ponto e vírgula) e deixa um token de execução na pilha de dados. O token de execução fornece um identificador opaco para a semântica compilada, semelhante aos ponteiros de função da linguagem de programação C.
Tokens de execução podem ser armazenados em variáveis. A palavra EXECUTE
pega um token de execução da pilha de dados e executa a semântica associada. A palavra COMPILE,
(compilar-vírgula) pega um token de execução da pilha de dados e anexa a semântica associada à definição atual.
A palavra '
(tick) recebe o nome de uma palavra como parâmetro e retorna o token de execução associado a essa palavra na pilha de dados. No estado de interpretação, ' RANDOM-WORD EXECUTE
é equivalente a RANDOM-WORD
.
Analisando palavras e comentários
As palavras :
(dois pontos), POSTPONE
, '
(tick) são exemplos de palavras de análise que recebem seus argumentos do dispositivo de entrada do usuário em vez da pilha de dados. Outro exemplo é a palavra (
(paren) que lê e ignora as seguintes palavras até e incluindo o próximo parêntese direito e é usada para colocar comentários em uma definição de dois pontos. Da mesma forma, a palavra
(barra invertida) é usado para comentários que continuam até o final da linha atual. Para serem analisados corretamente, (
(parênteses) e (barra invertida) devem ser separados por espaço em branco do seguinte texto de comentário.
Estrutura do código
Na maioria dos sistemas Forth, o corpo de uma definição de código consiste em linguagem de máquina ou alguma forma de código encadeado. O Forth original que segue o padrão informal FIG (Forth Interest Group), é um TIL (Threaded Interpretive Language). Isso também é chamado de código de encadeamento indireto, mas Forths de encadeamento direto e de sub-rotina também se tornaram populares nos tempos modernos. Os Forths modernos mais rápidos, como SwiftForth, VFX Forth e iForth, compilam Forth para código de máquina nativo.
Objetos de dados
Quando uma palavra é uma variável ou outro objeto de dados, o CF aponta para o código de tempo de execução associado à palavra de definição que a criou. Uma palavra definidora tem uma característica de "comportamento definidor" (criar uma entrada de dicionário e possivelmente alocar e inicializar o espaço de dados) e também especifica o comportamento de uma instância da classe de palavras construída por essa palavra definidora. Exemplos incluem:
VARIABLE
- Nomeia um local de memória uninitializado, de uma célula. Comportamento de uma instância
VARIABLE
retorna seu endereço na pilha. CONSTANT
- Nomeia um valor (especificado como um argumento para
CONSTANT
). O comportamento da instância retorna o valor. CREATE
- Nomes um local; o espaço pode ser alocado neste local, ou pode ser definido para conter uma string ou outro valor inicializado. O comportamento da instância retorna o endereço do início deste espaço.
Forth também fornece um recurso pelo qual um programador pode definir novas palavras de definição específicas do aplicativo, especificando um comportamento de definição personalizado e um comportamento de instância. Alguns exemplos incluem buffers circulares, bits nomeados em uma porta de E/S e arrays indexados automaticamente.
Os objetos de dados definidos por essas e outras palavras semelhantes têm escopo global. 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). O quarto estilo de programação usa muito poucos objetos de dados nomeados em comparação com outras linguagens; normalmente, esses objetos de dados são usados para conter dados que são usados por várias palavras ou tarefas (em uma implementação multitarefa).
Forth não reforça a consistência do uso do tipo de dados; é responsabilidade do programador usar os operadores apropriados para buscar e armazenar valores ou executar outras operações nos dados.
Exemplos
“Olá, mundo!”
: AJUDA (--) CR " Olá, Mundo!" ;
AUXÍLIO Olá, Mundo!
A palavra CR
(Carriage Return) faz com que a seguinte saída seja exibida em uma nova linha. A palavra de análise ."
(ponto-aspas) lê uma string delimitada por aspas duplas e anexa o código à definição atual para que a string analisada seja exibida na execução. O caractere de espaço que separa a palavra ."
da string Hello, World!
não é incluído como parte da string. É necessário para que o analisador reconheça ."
como uma palavra Forth.
Um sistema Forth padrão também é um interpretador, e a mesma saída pode ser obtida digitando o seguinte fragmento de código no console Forth:
CR .(Olá, Mundo!)
.(
(ponto-paren) é uma palavra imediata que analisa uma string delimitada por parênteses e a exibe. Assim como a palavra ."
o espaço O caractere que separa .(
de Hello, World!
não faz parte da string.
A palavra CR
vem antes do texto a ser impresso. Por convenção, o interpretador Forth não inicia a saída em uma nova linha. Também por convenção, o interpretador espera pela entrada no final da linha anterior, após um prompt ok
. Não há nenhum "flush-buffer" ação no CR
de Forth, como às vezes é em outras linguagens de programação.
Misturando estados de compilação e interpretação
Aqui está a definição de uma palavra EMIT-Q
que quando executada emite o único caractere Q
:
: EMIT-Q 81 (o valor ASCII para o caracter 'Q') EMPRESA ;
Esta definição foi escrita para usar o valor ASCII do caractere Q
(81) diretamente. O texto entre parênteses é um comentário e é ignorado pelo compilador. A palavra EMIT
obtém um valor da pilha de dados e exibe o caractere correspondente.
A seguinte redefinição de EMIT-Q
usa as palavras [
(colchete esquerdo), ]
(colchete direito), CHAR
e LITERAL
para alternar temporariamente para o estado do interpretador, calcule o valor ASCII do caractere Q
, retorne ao estado de compilação e anexe o valor calculado ao atual definição de dois pontos:
: EMIT-Q Não. CHAR Q ] LITERIAL EMPRESA ;
A palavra de análise CHAR
recebe uma palavra delimitada por espaço como parâmetro e coloca o valor de seu primeiro caractere na pilha de dados. A palavra [CHAR]
é uma versão imediata de CHAR
. Usando [CHAR]
, a definição de exemplo para EMIT-Q
poderia ser reescrita assim:
: EMIT-Q [CHAR] Q EMPRESA ; Emite o único personagem 'Q'
Esta definição usou (barra invertida) para o comentário descritivo.
Ambos CHAR
e [CHAR]
são predefinidos em AND Forth. Usando IMMEDIATE
e POSTPONE
, [CHAR]
poderia ser definido assim:
: [CHAR] CHAR AMOR LITERIAL ; IMEDIAÇÃO
Um programa de cifra RC4 completo
Em 1987, Ron Rivest desenvolveu o sistema de cifra RC4 para RSA Data Security, Inc. Sua descrição segue:
Temos um conjunto de 256 bytes, todos diferentes. Cada vez que o array é usado ele muda trocando dois bytes. Os swaps são controlados por contadores Eu... e JJ, cada um inicialmente 0. Para obter um novo Eu..., adicione 1. Para obter um novo JJ, adicione o byte array no novo Eu.... Troque os bytes de array em Eu... e JJ. O código é o byte de array na soma dos bytes de array em Eu... e JJ. Este é XORed com um byte do texto simples para criptografar, ou o cifratexto para descriptografar. O array é inicializado pela primeira vez configurando-o para 0 a 255. Então passe por ele usando Eu... e JJ, recebendo o novo JJ adicionando-lhe o byte array em Eu... e um byte chave, e trocando os bytes de array em Eu... e JJ. Finalmente, Eu... e JJ estão prontos para 0. Todas as adições são modulo 256.
A seguinte versão Standard Forth usa apenas as palavras Core e Core Extension.
0 valor I 0 valor JJ0 valor Chaveiro 0 valor Chaveirocriar SArray 256. Todos array de estado de 256 bytes: Linha de montagem Chaveiro mod Chaveiro ;: get_byte + C.C. ;: set_byte + C! ;: O que é? 255 e ;: Reabilitação: 0 A I 0 A JJ ;: I_update 1 + O que é? A I ;: j_update I SArray get_byte + O que é? A JJ ;: O que se passa? JJ SArray get_byte I SArray get_byte JJ SArray set_byte I SArray set_byte;: rc4_init (KeyAddr KeyLen --) 256. min A Chaveiro A Chaveiro 256. 0 - Sim. Eu... Eu... SArray set_byte LOCAL Reabilitação: BEGIN I Linha de montagem get_byte JJ + j_update O que se passa? I 255 < PORTUGAL I I_update REPEITAÇÃO Reabilitação:;: rc4_byte I I_update JJ j_update O que se passa? I SArray get_byte JJ SArray get_byte + O que é? SArray get_byte xor;
Esta é uma das muitas maneiras de testar o código:
Hexcriar AKey 61 c, 8A c, 63 c, D2 c, FB c,: teste de teste cr 0 - Sim. rc4_byte . LOCAL cr ;AKey 5 rc4_init2C F9 4C E DC 5 teste de teste saída deve ser: F1 38 29 C9 DE
Implementações
Como Forth é simples de implementar e não possui implementação de referência padrão, existem várias versões da linguagem. Além de oferecer suporte às variedades padrão de sistemas de computador desktop (POSIX, Microsoft Windows, macOS), muitos desses sistemas Forth também visam uma variedade de sistemas integrados. Aqui estão listados alguns dos sistemas que estão em conformidade com o padrão ANS Forth de 1994.
- ASYST, um sistema Forth-like para coleta e análise de dados
- Gforth, uma implementação portátil da ANS Forth do Projeto GNU
- noForth, uma implementação da ANS Forth (tanto quanto possível) para microcontroladores Flash (MSP430 & Risc-V)
- Open Firmware, um padrão de bootloader e Firmware baseado no ANS Forth
- pForth, Forth portátil escrito em C
- SP-Forth, ANS Forth implementação do Grupo de Interesse Forth russo (RuFIG)
- Swift Forth, geração de código de máquina de implementação da Forth, Inc.
- VFX Forth, otimizando o código nativo Forth
Contenido relacionado
GIMP
Criptoanálise diferencial
Mandriva LinuxGenericName