O objetivo do projeto é rodar um subset de Pascal na JVM. Para tal, iremos criar um compilador que entende este subset de Pascal e gere o assembly Java equivalente. De posse deste assembly, será utilizado um montador assembly Java para gerar o bytecode em um arquivo class, possibilitando assim que este arquivo seja executado na JVM.
Qual a motivação para o projeto? Aprender temas relacionados a compiladores. E, para tal, nada melhor do que criar um, por mais simples que seja.
POJ é um projeto com escopo simples (na medida do possível) e de fácil entendimento. O foco é ser utilizado para estudos.
- Git
- Go 1.22
- Make
- ANTLR 4.13.1: pacote está versionado junto com este projeto na pasta parser
- JAVA: para poder executar o ANTLR e para executar o arquivo class (bytecode java) gerado
- JASM 0.7.0: instruções sobre como baixar aqui
# Baixar o repositório do projeto
git clone git@github.com:alexgarzao/poj.git
# Executar os testes (opcional)
make test
# Construir o binário
make build
Após isso, o binário do POJ estará em na pasta bin.
Segue abaixo o passo-a-passo para compilar o "Hello world!".
# Executar o POJ para gerar o assembly Java (arquivo jasm)
./bin/poj ./tests/valid_pascal_programs/hello_world
# Executar o JASM (java assembler) para gerar o executável Java (arquivo class)
jasm hello_world.jasm
# Executar o arquivo class com a JVM
java hello_world
Uma forma mais enxuta é utilizar o make:
make compile-and-run-example program=hello_world
Abaixo é possível ver o clássico “Hello world!” em Pascal:
program Hello;
begin
writeln ('Hello world!');
end.
Abaixo temos o cálculo do fatorial, de forma recursiva:
program fatorial;
var numero : integer;
function fatorial(n : integer) : integer;
begin
if n<0 then fatorial := 0
else begin
if n<=1 then fatorial := 1
else fatorial := n * fatorial(n-1);
end;
end;
begin
write('Introduza numero inteiro: ');
readln(numero);
writeln;
writeln('O fatorial de ', numero, ' e: ', fatorial(numero));
end.
Abaixo temos um exemplo com entrada e saída de dados:
program NameAndAge;
var
MyName: String;
MyAge : Byte;
begin
Write('What is your name? '); Readln(MyName);
Write('How old are you? '); Readln(MyAge);
Writeln;
Writeln('Hello ', MyName);
Writeln('You are ', MyAge, ' years old');
end.
No momento, apenas o "Hello world!" pode ser compilado com o POJ. Para quem tiver interesse de ver a execução destes outros programas, sugiro utilizar o Free Pascal Compiler. Nas próximas semanas poderemos utilizar o POJ com todos estes exemplos :-)
O projeto ainda está em desenvolvimento e as próximas atualizações serão voltadas nas seguintes tarefas:
- Definir qual gerador de parser será utilizado
- Encontrar uma gramática de Pascal pronta no formato do gerador de parsers (ANTLR)
- Ajustar a gramática para reconhecer o subset de Pascal esperado
- No parser identificar a definição de procedimentos Pascal para determinar o bloco Pascal principal
- Encontrar um montador Java assembly (JASM)
- POJ gerar um código assembly Java válido para o assemblador
- Criar o README inicial
- Declaração e uso de variáveis string
- Saída de dados (terminal)
- Instrução If/Else
- Declaração e uso de variáveis inteiras
- Operações aritméticas sem precedência de operadores
- Instrução For
- Instrução Repeat
- Instrução While
- Operações aritméticas com precedência de operadores
- Entrada de dados (terminal)
- Declaração e uso de variáveis booleanas
- Declaração e uso de variáveis de ponto flutuante (Real)
- Declaração e uso de procedures
- Declaração e uso de funções
- Uso de funções recursivas
POJ utiliza a licença Apache.