Trilha 02 · Como funciona

Linguagens e compiladores

De x = 5 + 3 a instruções de máquina: o compilador é o tradutor entre o humano e o hardware.

① Intuição

Uma tradução em várias etapas

Imagine traduzir um livro do português para o mandarim por intermédio do inglês. Você não vai direto do original ao destino — passa por etapas intermediárias, cada uma com um propósito. Um compilador faz o mesmo: o código fonte em Python ou JavaScript passa por várias transformações até virar instruções que a CPU entende.

Cada etapa tem uma representação diferente — texto, lista de tokens, árvore, bytecode, binário — e cada uma facilita um tipo de análise. É muito mais fácil verificar tipos na AST do que no binário final.

A ideia central: um compilador/interpretador não é mágica — é software que transforma texto em texto (ou em binário). Toda linguagem de programação, no fundo, é uma convenção sobre como escrever instruções de máquina de forma legível para humanos.
② Visualização interativa

Veja o pipeline do compilador ao vivo

Digite uma expressão simples como x = 7 + 2 e veja em tempo real as três etapas: tokenização, árvore sintática e bytecode gerado.

① TOKENS (lexer)
x=5+3
identnúmeroopkw
② ÁRVORE SINTÁTICA (parser)
Atribuição
alvo: "x"
valor:
Soma
esq: "5"
dir: "3"
③ BYTECODE (gerador)
PUSH 5
PUSH 3
ADD
STORE x
③ Explicação técnica

As etapas do compilador

# Caminho de x = 5 + 3 até execução

Código fonte:   x = 5 + 3

① Lexer:        [IDENT:x] [OP:=] [NUM:5] [OP:+] [NUM:3]

② Parser (AST):  Atribuição
                  ├── alvo: "x"
                  └── valor: Soma
                        ├── esq: "5"
                        └── dir: "3"

③ Gerador:      PUSH  5
                PUSH  3
                ADD
                STORE x

④ CPU executa:  pilha=[5], pilha=[5,3], pilha=[8], x=8

Compilado, interpretado e JIT

# Comparação: compilado vs. interpretado vs. JIT

Compilado (C, Rust, Go):
  código → compilador → binário nativo → execução direta
  Vantagem: rapidíssimo em execução
  Desvantagem: recompila a cada mudança

Interpretado (Python, Ruby):
  código → interpretador → executa linha a linha
  Vantagem: flexível, sem compilação
  Desvantagem: mais lento (overhead do interpretador)

JIT — Just-In-Time (Java JVM, V8/JS, PyPy):
  código → bytecode → JIT compila hot paths → nativo
  Vantagem: velocidade próxima ao compilado, com flexibilidade
Bytecode vs. código de máquina: o Python compila para bytecode (.pyc) que roda na CPython VM, não diretamente na CPU. O Java compila para bytecode JVM. O benefício é portabilidade — o mesmo bytecode roda em qualquer SO que tenha a VM instalada.
④ Projeto para programar

Construa um lexer e uma calculadora

Mini projeto: implemente um lexer para expressões aritméticas simples (2 + 3 * 4). Retorne uma lista de tokens: [{type:"NUMBER", value:2}, {type:"OP", value:"+"}, ...].

Projeto principal: implemente uma calculadora baseada em pilha usando notação pós-fixa (RPN). Ex: 2 3 + 4 *20. Adicione um parser que converta infix para RPN (algoritmo Shunting-Yard).

Desafio extra: adicione variáveis: x = 5; y = x + 3; print(y). Você precisará de um símbolo de tabela e de avaliar expressões com identificadores.

⑤ Exercícios rápidos

Teste sua intuição

O que o lexer (analisador léxico) faz?
Qual é a diferença principal entre compilada e interpretada?
O que é uma AST (Árvore de Sintaxe Abstrata)?
⑥ Aplicações no mundo real

Onde você encontra isso

🟦

TypeScript

Um transpilador: converte TypeScript em JavaScript. É basicamente um compilador cuja saída é código fonte de outra linguagem.

V8 / SpiderMonkey

Os motores JS do Chrome e Firefox compilam JavaScript para código nativo com JIT durante a execução.

🔧

LLVM

Infraestrutura de compilação usada por Clang, Swift, Rust e muitas outras. Você escreve o frontend; o LLVM otimiza e gera código de máquina.

🌐

WebAssembly

C, C++ e Rust podem ser compilados para WASM — bytecode que roda no navegador com desempenho próximo ao nativo.

← Anterior: Sistema operacional Próxima: Redes e internet →