finf
finf: Finf Is Not Forth
Visão Geral
Finf é uma linguagem de programação similar à Forth: herda alguns de seus conceitos, como o uso da pilha, notação polonesa reversa (RPN), palavras, etc, mas não é e nem vai ser Forth um dia. A versão atual não inclui um prompt interativo, como a maioria dos ambientes Forth; por conta disso, todo programa em finf começa na word “main”, assim como um programa em C.
A versão atual (0.1.5a) é escrita em C, incluindo o (simples, cheio de bugs e provavelmente não eficiente) parser e interpretador. Por enquanto o interpretador usa uma quantidade razoável de memória, o que deve melhorar em versões futuras, se o tempo e a paciência permitirem.
Palavras-Padrão do Repertório
As palavras que fazem parte do repertório do finf são:
| Operação com Pilha | |
|---|---|
| pick | Coloca na pilha o elemento de numero n |
| not | Nega o último elemento da pilha |
| over | a b — a b a |
| swap | a b — b a |
| dup | a — a a |
| rot | a b c — b c a |
| sp0 | Limpa a pilha |
| drop | Apaga o último elemento da pilha |
| nip | Apaga o penúltimo elemento da pilha |
| negate | Nega o último número na pilha |
| abs | Deixa o último numero na pilha com seu valor absoluto |
| min | Remove dois elementos da pilha e coloca o menor deles de volta |
| max | Remove dois elementos da pilha e coloca o maior deles de volta |
| showstack | Mostra o conteudo da pilha |
| Variáveis | |
| ! | Guarda o valor do penultimo elemento da pilha na variavel enderecada pelo ultimo elemento |
| @ | Recupera o valor da variavel enderecada pelo ultimo elemento da pilha |
| Saída | |
| emit | Remove um elemento da pilha e imprime-o (usando seu codigo ASCII) |
| . | Remove um elemento da pilha e imprime-o (inteiro) |
| Aritmética | |
| + | Remove dois elementos da pilha e empilha o resultado da soma |
| - | Remove dois elementos da pilha e empilha o resultado da subtracao do penúltimo com o último |
| * | Remove dois elementos da pilha e empilha o resultado da multiplicação |
| / | Remove dois elementos da pilha e empilha o quociente da divisão do penúltimo com o último |
| % | Remove dois elementos da pilha e empilha o resto da divisão do penúltimo com o último |
| Comparação | |
| = | Remove dois elementos da pilha e coloca 1 se forem iguais, 0 caso contrario |
| > | Remove dois elementos da pilha e coloca 1 se o último for maior que o penúltimo, 0 caso contrario |
| < | Remove dois elementos da pilha e coloca 1 se o último for menor que o penúltimo, 0 caso contrario |
| Repetição | |
| begin | Inicia um bloco de repetição |
| until | Remove um elemento da pilha; se for verdadeiro, pula para o início do bloco de repetição |
| Decisão | |
| if | Verifica se o último elemento da pilha é verdadeiro (!= 0), e executa tudo o que existir até o else; caso contrário, executa tudo o que estiver a partir do else. |
| else | Se a condição do if for verdadeira, pula para o then. Caso contrário, segue executando normalmente. |
| then | Finaliza a condição. |
| Miscelanea | |
| dump | Exibe o programa na memoria |
| exit | Sai da palavra atual (útil em loops ou decisões |
Falta ainda implementar mais algumas formas de repetiçaõ (do…while) e entrada de dados. Isso deverá aparecer em versões futuras. Fora isso, a linguagem está pronta, a ponto de fazer um simples “hello, world” ou resolver um bom número de problemas.
Resumindo: é apenas uma brincadeira, não é uma linguagem para uso sério. É mais uma prova de conceito do que qualquer outra coisa. Mas serve um bocado para entender como um compilador funciona, como uma máquina de pilha é internamente, e coisas do gênero.
Códigos, Exemplos e Explicações
Um exemplo bem simples pode ser visto no quadro abaixo:
:print emit ; :printn . ; :cr 10 print 13 print ; :variavel 0 ; :sto ! ; :rcl @ ; :varSto variavel sto ; :varRcl variavel rcl ; :main 10 10 + varSto sp0 -19823 varRcl printn cr ;
As palavras marcadas em azul são palavras pertencentes ao repositório padrão do finf. Já as marcadas em vermelho são as definidas pelo usuário. Uma definição é feita pelo caractere “:” logo no começo de uma linha, seguido do nome da palavra, que deve começar obrigatoriamente com uma letra (tanto maiúscula quanto minúscula); os demais caracteres podem ser até mesmo caracteres acentuados (embora isso não seja encorajado). O ponto-e-vírgula (“;”) é obrigatório para finalização da definição de uma palavra.
Para chamar uma palavra, basta escrever o nome dela; o interpretador irá guardar a posição atual, pular para a posição daquela palavra, continuar o fluxo normal de execução e voltar assim que encontrar o ponto-e-vírgula (“;”). O programa começa a ser executado a partir do main (e esta deve ser a última palavra a ser definida, pois o look-ahead não está implementado no finf — e provavelmente nem será).
O exemplo acima define algumas palavras de conveniência, coloca dois números na pilha, soma, armazena o valor em “variável”, limpa a pilha, adiciona um número qualquer, recupera o valor de “variável”, mostra na tela e, por fim, pula de linha. O exemplo deve mostrar o número “20″ na tela (é um teste para verificar se as variáveis estão funcionando a contento).
Um exemplo mais simples, embora um pouco maior, pode ser visto aqui. Esse mostra a palavra “fudeba” escrita em ASCII art. É um teste de chamada de palavras.
O código fonte do finf pode ser obtido aqui; é distribuído sob os termos da GNU GPL versão 2 e deve ser compilável na maioria dos compiladores C. Foi desenvolvido com gcc em GNU/Linux e há relatos de funcionar (com poucas modificações) com Visual C++ 6 em Windows XP.












Leave a Comment