# **validate_ir.md — Validação do IR (Neuro Lang v0.1)**

## 📘 **Objetivo**

Garantir que o IR gerado pelo frontend:

* é **estruturalmente válido**,
* é **executável pela VM Holodeck**,
* não contém erros que causariam crashes, loops impossíveis,
* obedece estritamente à semântica do NL v0.1.

O validador é o guarda de fronteira entre:

```
AST → IR  → (validate_ir) → VM / Optimizações / Backend futuro
```

Sem validação rigorosa, tudo o que vem depois é instável.

---

# 🌑 **1. Escopo deste validador v0.1**

O validador **NÃO**:

* interpreta IR,
* otimiza IR,
* transforma IR,
* reescreve funções.

Ele **apenas verifica** que o IR é bem formado.

---

# 🌒 **2. Estrutura de entrada**

O IR recebido é um objeto lógico:

```
ProgramIR = {
    functions: {
        "fib/1": FunctionIR,
        "__main__/0": FunctionIR,
        ...
    }
}
```

Cada `FunctionIR` contém:

```
name: "fib"
arity: 1
instructions: [ Instr, Instr, ... ]
labels: { "L_else": index, ... }
```

O validador opera exclusivamente sobre este formato.

---

# 🌕 **3. Regras de validação obrigatórias**

Abaixo seguem as regras **mínimas** mas fundamentais.

---

## ✔ **3.1. Nome e aridade**

Para cada função:

* `name` é string não vazia
* `arity` ≥ 0
* nomes são únicos dentro do programa

Erros:

```
[IR-01] Duplicate function: fib/1
[IR-02] Invalid arity in function foo/-1
```

---

## ✔ **3.2. Labels são coerentes**

Para cada função:

* todos os labels apontados por `JUMP` ou `JUMP_IF_FALSE` devem existir
* o índice do label deve estar dentro dos limites
* labels não usados são permitidos (v0.1)

Erros:

```
[IR-10] Jump to undefined label: L_xpto in fib/1
[IR-11] Label L1 resolves to out-of-range instruction index 999
```

---

## ✔ **3.3. Instruções têm formato válido**

Cada instrução precisa obedecer ao SPEC_IR.md:

Exemplos de checks:

### `PUSH_CONST`

* tem exatamente 1 operando
* operando é inteiro

### `LOAD_VAR`

* operando é string
* corresponde a um argumento válido da função

### `CALL`

* forma: `CALL name arity`
* função `name/arity` deve existir

### `ADD`, `SUB`, `LT`, `RET`

* sem operandos
* são reconhecidas no conjunto de primitivas v0.1

Erros:

```
[IR-20] Unknown opcode: PUSHKONST
[IR-21] Invalid operand for PUSH_CONST: 'abc'
[IR-22] LOAD_VAR y refers to non-existent variable in fib/1
[IR-23] CALL foo 2: function foo/2 not found
```

---

## ✔ **3.4. Stack safety (mínima)**

O validador NÃO simula a execução completa —
mas impõe condições necessárias:

### Antes de `ADD`, `SUB`, `LT`

Stack mínima esperada ≥ 2

### Antes de `RET`

Stack mínima esperada ≥ 1

*(não é suficiente para garantir stack correctness total, mas reduz 90% dos erros típicos.)*

Erros:

```
[IR-30] ADD requires stack size >= 2
[IR-31] RET requires stack size >= 1
```

---

## ✔ **3.5. Entrada e saída da função**

Regras:

* Cada função deve **terminar num RET**
* Nenhuma função pode terminar “no vazio”
* Todos os caminhos possíveis devem levar a RET (cheque simples, sem CFG)

Erros:

```
[IR-40] Missing RET at end of function fib/1
```

---

# 🌖 **4. Processo de validação**

Ordem recomendada:

1. **validar metadados**
   nome, aridade, duplicados

2. **scan de instruções**
   tipo, operandos, aridade dos CALLs

3. **resolver labels**

4. **stack-safety mínima (linear)**
   simulação local, não recursiva

5. **verificar retorno final**

---

# 🌘 **5. Saída do validador**

O validador devolve:

```
OK → IR_VALID
ERRO → IR_INVALID + lista de mensagens
```

Formato humano:

```
[IR-20] Unknown opcode: MULTIPLY at fib/1: instr 7
```

Formato estruturado (para uso interno do Neurotron):

```
{
  "status": "error",
  "errors": [
     { "code": "IR-20", "msg": "Unknown opcode MULTIPLY", "func": "fib/1", "instr": 7 }
  ]
}
```

---

# 🌑 **6. Exemplos de validação**

### ✔ Exemplo válido

Fib v0.1 esperado.

Validador retorna:

```
IR_VALID
```

### ❌ Exemplo inválido

```
func foo/1:
  LOAD_VAR x
  ADD
  RET
```

Erros:

```
[IR-30] ADD requires stack size >= 2 in foo/1: instr 1
```

---

# 🌟 **7. Motivação pedagógica**

Este validador simples serve para:

* manter o pipeline robusto,
* evitar erros silenciosos no interpretador,
* garantir que o compilador avança com confiança,
* construir uma base sólida para otimizações futuras,
* facilitar o aprendizado de *como* compiladores reais validam programas.

O Neurotron verá:

* o IR cru,
* o IR validado,
* a VM a executar esse IR.

*Três espelhos complementares.*

---

# 💗 Fim do `validate_ir.md`