Skip to content

UnBCIC-TP2/r-python

Repository files navigation

RPython 🚀

Rust GitHub issues CI Status

Um compilador/interpretador experimental escrito em Rust para uma linguagem com sintaxe inspirada no Python, mas com regras explícitas de tipagem estática e blocos delimitados por end. O projeto nasceu como ferramenta acadêmica para explorar conceitos de construção de compiladores e interpretação de linguagens.

🔎 Precisa copiar o README inteiro? A versão crua está disponível em README.md, bastando abrir o arquivo em modo Raw no GitHub ou executar cat README.md após clonar o repositório.

🧭 Índice

📋 Visão Geral

RPython tem como foco:

  • Aprendizado de compiladores: o código-fonte serve como laboratório para parsing, análise semântica, verificação de tipos e interpretação.
  • Linguagem familiar: a sintaxe lembra Python, mas inclui recursos clássicos de linguagens fortemente tipadas (anotações obrigatórias em funções, declarações var/val, ADTs em desenvolvimento).
  • Ferramentas modernas: todo o pipeline é escrito em Rust, aproveitando segurança de memória e uma rica base de testes automatizados.

🏗️ Arquitetura em Alto Nível

  • Parser (src/parser) – Constrói a Árvore de Sintaxe Abstrata (AST) a partir do código-fonte utilizando nom.
  • IR/AST (src/ir) – Define as estruturas centrais da linguagem (expressões, declarações, tipos e construtores).
  • Environment (src/environment) – Implementa pilha de escopos para variáveis, funções e tipos.
  • Type Checker (src/type_checker) – Analisa programas para garantir consistência de tipos antes da execução. (Algumas funcionalidades avançadas ainda estão em desenvolvimento.)
  • Interpreter (src/interpreter) – Avalia a AST produzindo resultados de execução.
  • Pretty Printer (src/pretty_print) – Gera representações legíveis da AST, útil para debugging e tooling.

🧪 Catálogo de Features da Linguagem

Os módulos de AST, parser, verificação de tipos e interpretador já oferecem um conjunto sólido de recursos — de operações aritméticas a estruturas de controle, passando por coleções, funções tipadas e tratamento de erros. Consulte src/ir/ast.rs e src/parser/parser_stmt.rs para ver a implementação completa de cada construção apresentada abaixo. A seguir reunimos exemplos autoexplicativos para cada feature disponível hoje.

Literais e Operações Numéricas

val inteiro = 42;
val real = 3.14;

val soma = inteiro + 8;
val mix = real * 2.0 - inteiro;
val divisao = inteiro / 2;

Lógica Booleana e Comparações

val idade = 20;
val possui_autorizacao = False;

val maior_de_idade = idade >= 18;
val pode_participar = maior_de_idade or possui_autorizacao;
val precisa_aviso = not maior_de_idade and possui_autorizacao == False;

Listas e Tuplas

val lista_vazia = [];
val linguagens = ["RPython", "Rust", "Python"];
val pares = [(1, "um"), (2, "dois")];
val coordenada = (latitude, longitude, "Norte");

ℹ️ Listas e tuplas aparecem como ListValue e Tuple na AST, garantindo suporte a coleções homogêneas e heterogêneas (veja src/ir/ast.rs).

Declarações val/var e Atribuições

val nome = "RPython";      # imutável
var contador = 0;          # mutável

contador = contador + 1;
val saudacao = "Olá, " + nome;

ℹ️ Declarações val/var e reatribuições são modeladas por Statement::ValDeclaration, Statement::VarDeclaration e Statement::Assignment em src/ir/ast.rs.

Controle de Fluxo (if/elif/else, while, for)

if nota >= 9:
    conceito = "Excelente";
elif nota >= 7:
    conceito = "Bom";
else:
    conceito = "Recuperação";
end

var total = 0;
while total < 3:
    total = total + 1;
end

val numeros = [1, 2, 3];
var soma = 0;
for n in numeros:
    soma = soma + n;
end

ℹ️ O núcleo reconhece if/elif/else, laços while e for como variantes específicas da AST, preservando o bloco associado a cada controle de fluxo (implementações em src/ir/ast.rs e src/parser/parser_stmt.rs).

Funções Tipadas, Retorno e Recursão

def fibonacci(n: Int) -> Int:
    if n <= 1:
        return n;
    end
    return fibonacci(n - 1) + fibonacci(n - 2);
end;

val resultado = fibonacci(10);
asserttrue(resultado == 55, "Fib(10) deve ser 55");

ℹ️ Funções são representadas por Function + Statement::FuncDef, com anotações obrigatórias de tipos de parâmetros e retorno (src/ir/ast.rs e src/parser/parser_stmt.rs).

Assertions em Tempo de Execução

asserttrue(condicao, "Mensagem de sucesso");
assertfalse(condicao, "Mensagem de erro");
asserteq(resultado, esperado, "Valores devem ser iguais");
assertneq(id_atual, ultimo_id, "IDs não podem coincidir");

ℹ️ Há variantes dedicadas para cada assertiva (Assert, AssertTrue, AssertFalse, AssertEQ, AssertNEQ) que permitem mensagens customizadas e integração com o runner de testes (detalhes em src/ir/ast.rs).

Blocos de Teste Automatizado

test soma_basica():
    val resultado = 2 + 3;
    asserttrue(resultado == 5, "2 + 3 deve ser 5");
end

ℹ️ O interpretador expõe Statement::TestDef para registrar casos de teste e executá-los isoladamente com coleta de resultados (veja src/ir/ast.rs e src/interpreter/statement_execute.rs).

Valores Result e Propagação de Erros

def dividir(a: Int, b: Int) -> Result[Int, String]:
    if b == 0:
        return Err("Divisão por zero");
    end
    return Ok(a / b);
end;

def dividir_e_incrementar(a: Int, b: Int, inc: Int) -> Result[Int, String]:
    val quociente = dividir(a, b)?;   # Propaga Err automaticamente
    return Ok(quociente + inc);
end;

val resultado = dividir_e_incrementar(10, 2, 1);
assertfalse(is_error(resultado), "Esperávamos um Ok");

ℹ️ Resultado de erros utiliza as variantes COk, CErr, Propagate, IsError e Unwrap dentro da AST e do interpretador, cobrindo desde a construção até a propagação de falhas (src/ir/ast.rs e src/interpreter/expression_eval.rs).

Valores Maybe (Opcionais)

val nome = Just("RPython");

if is_nothing(nome):
    assertfalse(True, "Nome não deveria ser Nothing");
end

val texto = nome!;  # unwrap: lança erro se for Nothing

ℹ️ Valores opcionais contam com CJust, CNothing, IsNothing e Unwrap, permitindo presença ou ausência de dados com verificação estática (consulte src/ir/ast.rs e src/type_checker/expression_type_checker.rs).

Construtores de Tipos Algébricos (ADT)

data Forma:
    | Circulo Int
    | Retangulo Int Int
end

val figura = Circulo(5);

ℹ️ Tipos algébricos são descritos por Type::TAlgebraicData e ValueConstructor, habilitando construtores nomeados com múltiplos campos (src/ir/ast.rs).

💡 A sintaxe usa ; para separar instruções dentro de blocos e a palavra-chave end para finalizar estruturas de controle e definições.

⚙️ Guia Rápido

Pré-requisitos

  • Rust (última versão estável)
  • Cargo (já incluído na instalação padrão do Rust)
  • Git

Clonando o repositório

git clone https://github.com/UnBCIC-TP2/r-python.git
cd r-python

Compilação e testes

# Compilar o projeto
cargo build

# Executar a suíte de testes
cargo test

Executando exemplos

Você pode experimentar trechos da linguagem utilizando cargo test -- --nocapture para observar os programas de exemplo instrumentados no main. Em breve disponibilizaremos uma CLI dedicada para avaliar arquivos .rpy diretamente.

📚 Documentação Complementar

  • Environment Module – Escopos, tabelas de símbolos e política de resolução de nomes.
  • Parser Component – Estratégias de parsing com nom, gramática suportada e exemplos de AST.
  • Type Checker Module – Regras de tipagem, tipos suportados e roadmap do verificador. (Em evolução)

🤝 Contribuindo

Contribuições são muito bem-vindas! Antes de abrir issues ou enviar pull requests, consulte nossos guias:

Fique à vontade para sugerir melhorias na linguagem, adicionar novos exemplos ou expandir a documentação.

About

Linguagem de programação implementada em Rust com sintaxe semelhante ao python

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages