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