Crivo de Eratóstenes Simples em XBase (Clipper)
Publicado por Perfil removido (última atualização em 10/02/2016)
[ Hits: 4.154 ]
Atenção: código Clipper em Caixa Alta é Nostálgico!
Esta é uma homenagem a uma linguagem que foi extremamente popular no Brasil durante a segunda metade dos anos 80 e a primeira metade dos anos 90.
Alguns chamam-na de Clipper. Outros de XBase.
Tudo começou com um sistema de banco de dados chamado dBase. Ele possuía uma sintaxe de operações mais simples que SQL.
Vinha também com uma linguagem de programação embutida, que permitia criar interfaces modo texto de uma forma absurdamente simples e era extremamente satisfatório para as atividades em MS-DOS.
A coisa toda era feita geralmente com um programa multiuso chamado Sidekick. Ele vinha com editor de texto, tabela ASCII, calculadora e outras firulas.
Ele tinha uma característica peculiar, chamada de programa que termina e fica na memória. Através das teclas <Ctrl>+<Alt> ,o programa era chamado e utilizado seu editor. Com outro uso das teclas, ele voltava para a memória. Com isto não era necessário usar Wordstar.
Vale lembrar que esse programa usava um truque divulgado por uns livros na época. Na era da multitarefa isto é dispensável.
Ou mesmo no Unix, com seus comandos bg e fg.
É por isto que me espanto em comparar MS-DOS dos anos 80/90 com o que Unix fornece.
Para melhorar a performance dos programas feitos para dBase, dois amigos tiveram a ideia de escrever um compilador usando programação em C e Assembly. Resolveram chamar-lhe de Clipper.
Uma coisa que chamou a atenção é que cada versão lançada vinha com o nome da estação do ano da época. Logo chamaram-nas de Clipper Winter '85, Clipper Autumn '86 e a popular Clipper Summer '87.
Tenho até hoje um livro comprado à época, detalhando esta versão. Quem se lembra do Antonio Vidal?
Continuando, após a versão de 1987, Clipper deu uma salto para ser independente da plataforma dBase, que se não me engano teve as versões 1, 2, 3 (a mais popular tida por muitos como a melhor, chamada dBase III Plus) e a 4. Clipper deslanchou com versões 5.0, 5.0.X, 5.1, 5.2, 5.3 ...
Clipper funcionava, por exemplo, em um disquete onde vinha o próprio compilador, um linkeditor (que podia ser o Plink, o Tlink ou o Rtlink) e livrarias de código nomeadas como CLIPPER.LIB e EXTEND.LIB.
Ainda havia uma coisa chamada overlay que era uma quebra de partes do programa compilado por causa da memória da máquina ser muito pequena. Overlays eram lidas de cada vez para não comprometer a memória.
Falamos de algo da época dos 386 e 486. Pentium? Ainda não...
Uma coisa cultural da época eram os sistemas de fluxo de caixa feitos em Clipper. O lugar mais icônico de sistemas Clipper eram as videolocadoras. E lugares bons de se encontrar sisteminhas Clipper à venda prontos eram em bancas de jornal.
Houve algumas empresas negociando a marca Clipper na jogada, com interesses comerciais diversos, como a Oracle, por exemplo, de olho em migrar as bases de dados para seu carro-chefe.
Clipper foi passado de mão em mão até seus compiladores perderem poder comercial. Nantucket, Borland, Computer Associates etc.
Por volta de 1998, 1999 (?) houve um programador da Usenet que teve a ideia de criar um compilador do tipo do Clipper só que no modelo Open Source (quem conhece uma historinha parecida? Usenet... compartilhar códigos... etc.) e o projeto foi para frente. Chama-se Harbour.
Harbour é um jogo de palavras com Clipper. Clipper é um veleiro rápido e Harbour é porto.
Ainda surgiram alguns projetos, como o xHarbour, que me pareceu extremamente ambicioso e que tentou ser um fork do Harbour só que bem mais comercial. Da última vez que li algo, parece que tiveram muitos problemas entre eles. E o Harbour continuou firme e forte sem puxão de tapete. Também teve o Clip, projeto russo. Abandonado.
O código aqui exposto mostra os rudimentos básicos da linguagem (como todo código de crivo bem o faz).
Ainda existem funções e procedimentos inimaginados como @ ...TO ... e @ ... BOX ... que dadas as coordenadas, desenham molduras na tela.
@ ... SAY e @ ... GET ... PICTURE ... que também com coordenadas, exibem texto e recebem dados em formato de formulário, navegando pela tela com as setas.
As funções SAVESCREEN() e RESTSCREEN() ,que salvavam e restauravam respectivamente em/de variáveis partes da tela e que através de manipulação de dados das cores da tela nas variáveis faziam efeitos de sombra na tela, como o Dialog o faz.
E funções incríveis como a DBEDIT() que permitia navegação completa pela base de dados.
Links:
- O básico
* https://pt.wikipedia.org/wiki/Clipper_(linguagem_de_programa%C3%A7%C3%A3o)
* https://en.wikipedia.org/wiki/Clipper_(programming_language)
* https://es.wikipedia.org/wiki/Clipper_(lenguaje_de_programaci%C3%B3n)
- Abandonwares
* http://vetusware.com/download/dBASE%20III%20PLUS%203/?id=4877
* http://vetusware.com/download/Clipper%20Autumn%2086%20Autumn%2086/?id=7260
* http://vetusware.com/download/Clipper%20Summer87/?id=8144
* http://vetusware.com/download/CA-Clipper%205.3b%20Intl/?id=8460
Essas acima são boas para se testar no DOSBOX, DOSEMU ou no WINE como comando de DOS
- Artigos do VOL
* https://www.vivaolinux.com.br/artigo/Clip-no-Slackware-(compilador-Clipper)
* https://www.vivaolinux.com.br/artigo/Compilador-Clipper-opensource-compile-sem-problemas-os-sistemas...
- Site do Harbour
* https://harbour.github.io/index.html
- Site do xHarbour
* http://www.xharbour.org/
- Páginas brasileiras
* http://www.vagucs.com.br/
* http://www.pctoledo.com.br/
Agora quanto ao programa:
A partir da versão 5.0 veio uma enxurrada de comandos e operadores que deixou o Clipper/XBase mais parecido com C.
O sinal de igual simples nativo em Summer '87 ganhou os dois pontos, ficando semelhante à atribuição em Pascal. E o sinal de diferente é <>.
Comentários podem ser feitos como em C, com duas barras // ou barra e asterisco abre e fecha /* ... */
Para declarar uma matriz (array) com alocação dinâmica usa-se a sintaxe PRIMES := {} de modo simples.
O comando AADD(VAR,VALOR) cria uma nova posição ao final do array VAR e coloca VALOR como conteúdo desta posição.
Laços while são escritos como DO WHILE e encerrados com ENDDO, tudo junto.
A estrutura IF segue um modelo semelhante: IF ... ELSEIF ... ELSE ... ENDIF. No código ELSEIF não aparece.
O comando SQRT() calcula a raiz quadrada de um dado número.
O comando INT() trunca as casas decimais de um número não-inteiro e assim retorna um inteiro.
Índices de matrizes usam colchetes.
Há operador de incremento como em C, como por exemplo VAR++ ou VAR+=3.
Os valores e operadores lógicos aparentemente vieram do Fortran. Para verdadeiro e falso usa-se .T. e .F., para negação, e e ou usa-se .NOT, .AND. e .OR., respectivamente.
A operação de módulo, ou resto de divisão, é feita com a função MOD(A,B), onde A é o dividendo e B é o divisor, retornando o resto da divisão.
Laço FOR é feito com uma contagem em uma variável e ao final do laço é escrito NEXT junto com o nome da variável.
O comando ? imprime uma mensagem na tela com quebra de linha. É semelhante a um comando chamado PRINT, mas usa-se ? para abreviação.
O comando ?? faz o mesmo sem quebra de linha. Uma sequência de ?? imprimirá mensagens na mesma linha.
A função STR() converte um número em string alfanumérica. Isto é feito para se concatenar com aquele espaço em branco entre aspas que aparece no código.
A função TRIM() serve para remover espaços em branco do lado esquerdo e direito de uma string. Por algum motivo não funciona neste exemplo.
O operador + presente ao final do código serve como concatenador de strings.
// ISTO EH UM COMENTARIO // CODIGO CLIPPER EM CAIXA ALTA EH NOSTALGICO SET DATE TO BRITISH //MUDA PADRAO DE DATAS SET CENTURY ON // MUDA PADRÃO PARA ANOS COM QUATRO DIGITOS SET COLOR TO W+*/N+ // MUDA COR DE TELA PRIMES := {} // INICIA ARRAY DINAMICO // ABAIXO INICIA VARIAVEIS I := 0 J := 0 L := 0 M := 0 P := 0 Q := 0 K := 0.0 N := 0.0 // ABAIXO INSERE ELEMENTOS NO ARRAY COM VALORES AADD(PRIMES,2) AADD(PRIMES,3) // ABAIXO ACERTA VARIAVEIS PARA INICIAR J := 0 L := 3 M := L P := 1000 Q := 170 K := 0.0 N := 5.0 // ABAIXO PREENCHE VETOR COM NUMEROS 1 DO WHILE M <= Q AADD(PRIMES,1) M++ ENDDO DO WHILE N < P I := INT(N) // TRANSFORMA EM INTEIRO, TRUNCA CASAS DECIMAIS J := 1 K := SQRT(N) // RAIZ QUADRADA // VERIFICA SE UM PRIMO DA TABELA DIVIDE UM NUMERO DA VEZ DO WHILE PRIMES[J]<K .AND. MOD(I,PRIMES[J]) <> 0 J++ ENDDO // SE PASSAR NO TESTE ACRESCENTA UM NOVO PRIMO NA TABELA IF PRIMES[J] > K PRIMES[L] := I L++ ENDIF // VAI PARA PROXIMO NUMERO IF MOD(I,3) = 2 N += 2.0 ELSE N += 4.0 ENDIF ENDDO // EXIBE NUMEROS OBTIDOS FOR M := 1 TO L-1 ? TRIM(STR(PRIMES[M])) + " " NEXT M ??
Perguntas e respostas com Assembly e NASM
Método de Gauss-Seidel em SCILAB
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI