Free Pascal
Free Pascal (também conhecido pela sigla FPC) é um compilador 32 bits/64 bits para a linguagem Pascal (dialetos: Borland Pascal, Delphi Object Pascal e algumas extensões do Mac-Pascal), escrito em Pascal e distribuído sob a licença GPL. Ele possui alto grau de compatibilidade com o antigo Turbo Pascal, bem como com versões recentes do Delphi (até a versão 7) e roda em várias arquiteturas (x86, x86-64, PowerPC, SPARC, ARM) e sistemas operacionais (Linux, FreeBSD, Mac OS X/Darwin, Mac OS Classic, DOS, Win32, OS/2, Netware (libc e classic) e MorphOS). Sua RTL (RunTime Library - biblioteca de tempo de execução) é extensa, disponibilizando uma grande quantidade de funções, rotinas e classes prontas para o programador. O projeto atualmente é liderado por Florian Klaëmpfl, mas conta com vários desenvolvedores, espalhados principalmente pela Europa. Características do Free Pascal
HistóriaO Free Pascal começou em meados da década de 1990, quando a Borland descontinuou os compiladores Turbo Pascal e Borland Pascal, deixando para trás uma grande comunidade de programadores. O Turbo Pascal e o Borland Pascal eram o topo de linha de compiladores da Borland e ainda custavam bem menos que os concorrentes (o Turbo Pascal era vendido por US$49,99). Nessa época vários projetos foram iniciados para produzir um compilador Pascal que amparasse essa comunidade. Um deles foi o FPK-Pascal, que depois se tornaria o Free Pascal e se mostrou exatamente o que a comunidade queria: um compilador Pascal de 32bits moderno, robusto, estável e confiável. Com isso, o Free Pascal começou a ganhar mais e mais adeptos e os gurus da programação em Pascal começaram a escrever seus programas com ele. Com o advento do Delphi, o sucessor da linha de compiladores Pascal da Borland, que era o carro-chefe da Borland no desenvolvimento de aplicações comerciais para Windows 32bits, o Free Pascal acabou passando de um substituto para o Turbo Pascal a um compilador compativel com Delphi porém de código-fonte aberto, licenciado sob a GPL. A partir daí, o FPC ganhou uma comunidade ainda maior, com os servidores de download chegando a marca de aproximadamente 512GB/mês. Inicialmente, o FPC foi escrito pelo estudante Florian Paul Klaempfl e daí vem a sigla FPK-Pascal, que em 1997 se tornou Free Pascal. Nos primeiros estágios, o FPC era escrito em Pascal com o compilador Turbo Pascal, que é de 16bits, mas já produzia código 32bits para o estender go32v1, oriundo do DJGPP. Dois anos depois, o compilador já era capaz de compilar a si próprio, no processo conhecido como bootstraping, e que é utilizado até hoje para compilar o FPC. O projeto foi publicado na internet na mesma época em que usava o go32v1 para produzir código 32 bit e outros desenvolvedores começaram a trabalhar nele. Um deles, Michael van Canneyt, foi o responsável por portar o FPC para Linux, conseguindo uma versão 100% funcional 5 anos antes da Borland lançar o Kylix. Enquanto isso, a versão para DOS apresentava muitos progressos e foi migrada para o go32v2, um estender mais moderno do DJGPP. Nessa época, a compatibilidade com o Turbo Pascal foi abandonada em favor de um novo modo de compatibilidade com o Delphi para as próximas versões, onde também foi incluído suporte para compilar binários nativos Win32 que usa o formato PE (Portable Executable) da Microsoft. Atualmente, a versão estável é a 2.0.4 lançada em 28 de agosto de 2006. Essa versão é, basicamente, uma versão de correções para a versão 2.0.0, lançada em maio de 2005. Trata-se de um compilador moderno e de código-fonte aberto, com uma ampla, multi-plataforma e bem documentada RTL (o FPC vem com mais de 1.800 páginas de documentação), compatível com Delphi (7 até o momento) e que, de fato, não fica devendo em nada nem para linguagem C nem para os outros compiladores Pascal. Nessa versão, o FPC faz inlining corretamente, gera código melhor e ainda pode usar várias convenções de chamada, o que abre as portas para a programação visual em ambientes Windows. Existe um gerenciador melhor para o heap e tanto o compilador como a RTL tem suporte a multithreading e a internacionalização ajuda a traduzir sua aplicação para outras linguagens, sendo que o suporte a WideStrings (UNICODE) permite o uso dos conjuntos de caracteres mais incomuns. Além disso, a compatibilidade com o Delphi também foi melhorada, com o uso de alguns hacks para emular certas funcionalidades. O FPC também possui algumas extensões próprias, como parsing de constantes de 64 bits, interfaces e arrays dinâmicos. DesignO FPC passou por duas grandes mudancas em seu design: quando da migração para a versão 1.0. x e para a versão 2.0. x. Na versao 1.0. x o FPC ganhou um gerador de código melhor, um novo alocador de registradores e um novo parser. Nessa versão, o scanner converte o código em tokens que depois passam pelo processo de parsing. Depois o compilador faz o primeiro passo para avaliar expressões constantes e coletar informações para o gerador de código. O segundo passo consiste em gerar o código de fato e passá-lo por um otimizador dependente de CPU. Nessa versão o FPC é dito ser um compilador de dois passos. A versão 2.0. x tem uma arquitetura nova, de três passos: avaliação de constantes, coleta de informações e otimizações de alto nível e geração de código que é separada em front-end e back-end. Todos os passos são construídos em cima de uma arquitetura de classes e componentes reutilizáveis. Dessa forma, fica mais simples adicionar suporte a novos processadores, por exemplo. Basta sobrescrever os métodos necessários do gerador de código, o que facilita também a reescrita do compilador para outros sistemas operacionais. A arquitetura de classes também permite cada gerador de código poder aproveitar as vantagens de cada processador sem reescrever muito código, pois qualquer parte do gerador pode ser sobrescrita. Por exemplo, a linha x86 tem modos de endereçamento poderosos que podem ser utilizados para melhorar o desempenho para os índices dos arrays. Assim, basta sobrescrever a parte do gerador que gera os índices dos arrays para tirar vantagem desses modos e o desempenho aumenta. Processadores que fazem muito uso dessas vantagens são os da linha x86 e ARM. figura compilador 2.0. x Por último, tem-se um novo alocador de registradores. Fazendo a alocação dos registradores depois da geração do código, o compilador pode tomar decisões muito mais inteligentes a respeito da alocação dos registradores da CPU Quanto as bibliotecas, o grande progresso foi na versão para UNIX onde é possível compartilhar código entre os diferentes sistemas operacionais dessa família. VersõesO FPC evoluiu muito ao longo dos mais de 10 anos de desenvolvimento (o projeto começou em junho de 1993). Versões anteriores a 0.99.5 são consideradas muito obsoletas pelos desenvolvedores e, apenas após essa versão, foi introduzido um sistema de numeração de versões. Nesse sistema, versões com último número par eram versões de lançamento para os usuários e versões com último número ímpar eram versões de desenvolvimento. A partir das versões 1.0. x, o sistema de numeração de versões mudou para um sistema novo que lembrava o do núcleo Linux. Nesse novo sistema, a versões diferem no segundo número(ex: 1.0. x para 1.1. x) e o terceiro número fica para correções. Com a arquitetura antiga das versões 1.0.x era muito difícil reescrever o compilador para outras plataformas, mesmo assim existe um port dele para microprocessadores 68000, da Motorola (usado em microcomputadores Macintosh antigos e os Amiga). Geralmente, os programadores usam a versão de lançamento, pois ela é considerada estável. Nessas versões, os problemas são revelados após curto período de tempo e existem maneiras de contorná-los. Pacotes para desenvolvedores são gerados diariamente e refletem o estado atual do compilador. Essas versões de desenvolvimento tem novas características e novos bugs. Para uso corrente, recomenda-se usar as versões de lançamento (preferencialmente a série estável 2.0.x). Logo, vemos que a versão estável (2.0.x) deriva da série 0.99.x (entre 0.99.12b e 0.99.14). A partir desse ponto, foi criada a série 1.1.x, que deu origem à versão 1.9.x, que, por fim, chegou a estável atual, que é a 2.0.2. Nota-se também que já foi criada a série 2.1.x (a partir da série 2.0.x) mas ela ainda tem uma versão estável. A versão mais atual é a versão 2.4.4. LinguagemA linguagem Pascal foi criada pelo professor Niklaus Wirth, do ETH de Zurique, em 1970, baseando-se no ALGOL. Ela foi criada inicialmente com o intuito de ensinar programação, mas depois revelou-se uma linguagem de propósito geral, que pode ser usada para qualquer tarefa em desenvolvimento de software. A Borland, por sua vez, criou a variante mais conhecida do Pascal, o Turbo Pascal, em 1983, vendendo por correspondência uma solução integrada (editor + compilador + linker) por US$ 49,95, apenas 10% do preço de outros compiladores comerciais. O Turbo Pascal foi desenvolvido até a versão 7.0, sendo substituído no plano de negócios da Borland pelo Delphi. Apesar do Pascal ser originalmente uma linguagem estruturada, a Borland introduziu no Pascal o paradigma de orientação a objetos a partir do Turbo Pascal 5.5 (que hoje é de livre distribuição). O FPC suporta a imensa maioria das construções usadas no Delphi e no Turbo Pascal. Ele implementa os dialetos Borland Pascal e Object Pascal (utilizado no Delphi) mais algumas extensões extra do Mac-Pascal e alguns patches para garantir compatibilidade com os dialetos padronizados (ISO/IEC 7185). É notável a grande comunidade de programadores que Pascal possui entre usuários de Macs, tanto que os primeiros Macintosh e o Apple Lisa dependiam muito de Pascal e as APIs em C do MacOS tem que lidar com tipos de dados do Pascal. A linguagem Pascal tem uma sintaxe muito clara e simples, porém poderosa, suportando o uso de ponteiros, enumerações e tipos de dados packed. Pascal foi criticada por muito tempo sob a alegação de que não servia para outro nicho que não fosse o acadêmico. Brian Kernigham, um dos desenvolvedores da linguagem C, em seu artigo "Por que Pascal não é a minha linguagem favorita" aponta vários problemas com a linguagem Pascal, os quais felizmente, hoje em dia, não estão mais presentes nas implementações mais atuais. Apesar disso, Kernigham acabou por acertar prevendo que o Pascal teria problemas por causa da incompatiblidade entre compiladores e padrões, com a Borland de um lado e o padrão ISO do outro. Felizmente, o FPC está vindo para derrubar essas incompatibilidades. Note-se ainda que o FPC implementa algumas extensões que não existem nem no Delphi, nem no Turbo Pascal. Algumas delas são: retorno tipos de dados complexos como records e arrays, sobrecarga de funções e de operadores. Alem disso, o Free Pascal suporta o uso da linguagem Assembly no código-fonte, permitindo o uso da sintaxe Intel 80x86 ou AT&T, convertendo entre uma e outra se necessário. Programação orientada a objetos (POO)Com o Turbo Pascal 5.5, escrito em assembly por Anders Hejlsberg e que, na época, era funcionário da Borland, o Pascal ganhou suporte ao paradigma de orientação a objetos inspirado pelos escritos de Larry Tesler (Object Pascal Report - Apple, 1985) e Bjarne Stroustroup (The C++ Programming Language - Addison-Wesley, 1986). Seu debugger também ganhou modificações para suportar o novo paradigma. O Turbo Pascal se destacava também pela altíssima velocidade de compilação (~34000 linhas/minuto) e pela qualidade do código gerado. O FPC suporta o paradigma de orientação a objetos muito bem, tendo compatibilidade com a maioria dos códigos modernos feitos em Delphi ou legados do Turbo Pascal que usem POO. Em delphi, os programas são do tipo GUI por padrão sendo necessário o uso da diretiva {$APPTYPE CONSOLE} para criar programas em modo console. O FPC suporta essa diretiva, mas por padrão os programas são para modo console, sendo necessário utilizar uma outra diretiva: {$APPTYPE GUI} para escrever programas com GUI para Windows. O compilador suporta tanto o estilo antigo do Turbo Pascal de utilizar objetos, pelo uso da palavra reservada object e onde todos os objetos herdam de TObject quanto o estilo novo do Delphi, onde tudo gira em volta da palavra reservada class e onde todas as classes herdam de TClass. TObject e TClass estão definidos na unit System. Para usar extensões orientadas a objetos devem ser usados quando os parâmetros do compilador: -S2 (para modo Object Pascal) ou -Sd (para modo Delphi). Os mesmos efeitos podem ser conseguidos utilizando as diretivas {$MODE OBJFPC} ou {$MODE Delphi} colocadas no código-fonte. Para descrições detalhadas destes e de outros modos de operação do compilador, consulte o Apêndice D do Free Pascal Programmer's Manual (http://www.freepascal.org/docs-html/prog/prog.html). IDEDado o sucesso do Free Pascal e sua grande comunidade de usuários, acabaram por surgir vários projetos para prover uma IDE para o compilador. Um deles é a própria IDE que vem junto com o pacote oficial do compilador. Ela é escrita usando a FreeVision, que é um port para o Free Pascal da famosa biblioteca de widgets modo console da Borland, a Turbo Vision. A IDE oficial, disponível apenas para DOS, Windows e Linux, está muito bem documentada no capítulo 6 do Free Pascal User's Manual (http://www.freepascal.org/docs-html/user/user.html) e tenta se aproximar do visual e das características da IDE do Turbo Pascal; dessa forma os programadores vindos dele se sentem confortáveis para usá-la. imagem IDE FPC Outras IDEs para o FPC são:
BibliotecasO FPC vem com um conjunto muito vasto de bibliotecas e componentes prontos para serem usados pelo programador. Esse conjunto engloba a FCL (Free Component Library), que é um conjunto de classes não-visuais que o programador deve usar para executar tarefas rotineiras no desenvolvimento de software e que tenta se aproximar o máximo possível da VCL do Delphi. A FCL é distribuída junto com o pacote oficial do Free Pascal; seus principais componentes são:
Além da FCL, o Free Pascal conta ainda com a RTL e com alguns pacotes extra. A RTL (RunTime Library) é o conjunto de componentes que fornece as rotinas para execução básica do programa (como as funções writeln e readln, equivalentes a printf e scanf do C). Ela possui muitas funções e classes prontas para serem usadas e que tem boa compatibilidade com aquelas presentes no Delphi e Turbo Pascal. Por cima destas últimas estão rotinas básicas para acesso ao teclado, ao mouse e a gráficos em modo console de uma maneira multiplataforma. Existem ainda rotinas matemáticas, de sockets, impressora, strings, para acessar o estender go32v2 do DOS e para acessar o conjunto de instruções MMX do processador. A documentação completa de todas as units da RTL está em: Os pacotes extra, que também vem com o Free Pascal, fornecem um conjunto de classes para dar uma abordagem orientada a objetos para algumas bibliotecas conhecidas. Eles são bastante úteis e funcionam muito bem. Dentre os principais estão:
Existem ainda pacotes para: GTK, OpenGL, libPNG, SVGALib, tcl e X11. Para encontrar muitas outras bibliotecas e units para o FPC, vá em: http://www.freepascal.org/contrib/db.php3 ExemploPara exemplificar o uso do Free Pascal, um programa completo será mostrado aqui. Trata-se de uma ferramenta desenvolvida com o propósito de extrair informações de roms do console Sega Genesis/Mega Drive. Ela ilustra vários aspectos do Free Pascal e não foram feitas quaisquer otimizações ou depuração; o código-fonte está comentado para explicar os comandos usados. É uma ferramenta apenas para uso educacional sem quaisquer garantias quanto ao seu funcionamento. Todas as funções e comandos utilizados estão documentados em http://www.freepascal.org/docs-html/rtl/index.html // isto é um comentário // o FPC também aceita comentários no estilo turbo pascal, usando { e } // // Sega Genesis ROM tool - feito com o FreePascal 2.0.0 // ultima alteração: 30.07.2005 // // algoritmo para cálculo do checksum do arquivo .bin e informações // sobre o formato da rom extraídos de THE COMPLETE DOCUMENTATION ABOUT GENESIS // ROM FORMAT - versão 1.2 por Felipe Xnak (felipe@ComPorts.com) e // Volker Oth (dOnut) (volkeroth@aol.com) // a versão mais atual deste documento pode ser encontrada em // http://www.classicgaming.com/launchtool // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA program SegaGenRomTool; //A unit system para Win32 é incluída por padrão uses Sysutils; //funções extra para manipulação de strings procedure RomCheck(filename: string); var rom: File of byte; rom_size: DWord; // número inteiro de 32bits sem sinal i: byte; // número inteiro de 8bits sem sinal buffer_48b: array [1..48] of byte; //buffer de 48 bytes buffer_16b: array [1..16] of byte; //buffer de 16 bytes bytes_read: DWord; // número inteiro de 32bits sem sinal chksum: Word; // número inteiro de 16bits sem sinal j: byte; // número inteiro de 8bits sem sinal begin //atribui o arquivo a rom assign(rom, filename); //abre o arquivo para leitura reset(rom); rom_size:=FileSize(rom); writeln(); writeln('Opening ', filename); writeln('-> Size: ', rom_size, ' bytes'); //pula os primeiros 256 bytes Seek(rom, 256); //le 16 bytes com o nome do console blockread(rom, buffer_16b, 16); write('-> Console: '); for j:=1 to 16 do begin write(chr(buffer_16b[j])); //escreve na tela cada caracter do buffer end; writeln(); //le 16 bytes com a data blockread(rom, buffer_16b, 16); write('-> Date: '); for j:=1 to 16 do begin write(chr(buffer_16b[j])); end; writeln(); //le o nome original da rom blockread(rom, buffer_48b, 48); write('-> Original rom name: '); for j:=1 to 48 do begin write(chr(buffer_48b[j])); end; writeln(); //read 'international' rom name blockread(rom, buffer_48b, 48); write('-> International rom name: '); for j:=1 to 48 do begin write(chr(buffer_48b[j])); end; writeln(); //le informações sobre o tipo de produto blockread(rom, i, 1); if chr(i) = 'G' then begin blockread(rom, i, 1); if chr(i) = 'M' then writeln('-> Product Type: Game'); end else if chr(i) = 'A' then begin blockread(rom, i,1); if chr(i) = 'I' then writeln('-> Product Type: Educational'); end else writeln('-> Product Type: ?'); //le informações sobre o suporte a I/O da rom seek(rom, 400); blockread(rom, buffer_16b, 16); writeln('-> I/O Support:'); for j:= 1 to 16 do begin case chr(buffer_16b[j]) of 'J': writeln(' ->Joypad'); '6': writeln(' ->6-button joystick'); 'K': writeln(' ->Keyboard'); 'P': writeln(' ->Printer'); 'B': writeln(' ->Control Ball'); 'F': writeln(' ->Floppy disk drive'); 'L': writeln(' ->Activator'); '4': writeln(' ->Team Play'); '0': writeln(' ->Joystick for MS'); 'R': writeln(' ->Serial RS-232C'); 'T': writeln(' ->Tablet'); 'V': writeln(' ->Paddle Controller'); 'C': writeln(' ->CD-ROM'); 'M': writeln(' ->Mega Mouse'); else continue; end; end; //posição para cálculo do checksum seek(rom, 512); bytes_read:=512; chksum := 0; while bytes_read < rom_size do begin //algoritmo de calculo de checksum blockread(rom, i,1); //le próximo byte chksum := chksum + i*256; inc(bytes_read); blockread(rom, i,1); chksum := chksum + i; inc(bytes_read); end; writeln('-> Calculated checksum: ', hexstr(chksum, 4)); //volta o ponteiro para o começo da rom seek(rom,0); //o checksum fica armazenado nos bytes 399 e 400 seek(rom, 398); write('-> Read checksum: '); blockread(rom, i,1); write(hexstr(i,2)); blockread(rom, i,1); write(hexstr(i,2)); writeln(); close(rom); end; //retirado do manual da RTL Function FileExists (Name : String) : boolean; Var F : File; begin {$I-} //desliga geração de código para verificar erros Assign (F,Name); //faz o teste Reset (F); {$I+} //liga geração de código para verificar erros FileExists:=(IoResult()=0) and (Name<>''); //usa a função IoResult para verificar Close (F); end; //início do programa begin writeln('Sega Genesis ROM Tool 1.0'); if Paramcount = 0 then writeln(' Usage: ', ExtractFileName(paramstr(0)), ' romname.bin') else if paramcount = 1 then if FileExists(paramstr(1)) then begin RomCheck(paramstr(1)); end else begin writeln('File ', paramstr(1), ' not found!'); end else begin writeln('Usage: ', ExtractFileName(paramstr(0)), ' romname.bin'); end; end. //fim do programa Ferramentas extraO FPC conta ainda com um conjunto de ferramentas linha de comando extra para ajudar o programador a desenvolver seu software. São elas:
TP Lex and Yacc: usados para criar units em Pascal a partir de um vocabulário Lex e uma gramática Yacc; escritos por Albert Graef. Bibliografia
|