Aula 16: Verificação de Tipos e Escopo
Objetivos
- Implementar o Type Checker.
- Entender sistemas de tipos estáticos vs dinâmicos.
Conteúdo
A verificação de tipos é a principal tarefa da análise semântica. Seu objetivo é garantir que as operações do programa respeitam as regras da álgebra de tipos da linguagem.
Sistemas de Tipos
- Estático (Compile-time): Java, C++, Rust. Tipos verificados antes da execução. Garante ausência de certos erros, melhora performance.
- Dinâmico (Run-time): Python, JS. Tipos verificados durante a execução. Mais flexível, mas pode falhar na mão do usuário.
- Forte vs Fraco: C é estático mas fraco (permite somar char com int implicitamente, ponteiros void). Haskell é estático e forte.
Implementando Type Checking
Geralmente feito com um Visitor pós-ordem (Bottom-Up): 1. Visita as folhas, determinando seus tipos (literais ou lookup na tabela de símbolos). 2. Sobe para os pais: - Nó Soma: Verifica se Esq.tipo == Int e Dir.tipo == Int. Se sim, Soma.tipo = Int. Se não, Erro. - Nó Atribuição (x = E): Verifica se x.tipo é compatível com E.tipo (considerando coerções/promções, se houver).
Polimorfismo e Inferência
Linguagens modernas complicam isso com Genéricos (Listvar x = 10 \(\to\) x é int). Isso exige algoritmos de unificação (Hindley-Milner).
Referências
- Aho, A. V., Lam, M. S., Sethi, R., & Ullman, J. D. (2006). Compilers: Principles, Techniques, and Tools.
- Cooper, K., & Torczon, L. (2011). Engineering a Compiler.