# **SPEC_IR.md — Neuro IR v0.1 (Holodeck Minimal Edition)**

*versão mínima necessária para compilar e executar `fib`*

---

## 📘 **1. Objetivo**

Este documento define o **Neuro IR v0.1**, o conjunto mínimo de instruções intermediárias usado pelo Holodeck VM para executar programas escritos na linguagem **Neuro**.

A versão 0.1 foca apenas no necessário para suportar:

* inteiros
* funções globais
* chamadas de função
* operações aritméticas (`+`, `-`)
* comparação (`<`)
* controlo de fluxo via jump condicional
* retorno de valor
* programa principal (`__main__/0`)

Este IR é **stack-based** e destina-se a ser interpretado pela VM do Holodeck.

Versões futuras (v0.2, v0.3) poderão adicionar:

* heap, objetos, GC,
* loops nativos,
* registos,
* operações bitwise,
* otimizações SSA,
* geração de ELF.

Esta versão é minimalista por design.

---

# 📗 **2. Modelo de Execução**

---

## **2.1. Stack de operandos**

A VM opera sobre uma pilha LIFO contendo apenas **inteiros**.

* Instruções como `ADD`, `SUB`, `LT` consomem 2 valores e produzem 1.
* Outras instruções apenas empurram valores (`PUSH_CONST`, `LOAD_VAR`).

Exemplo:

Antes de `ADD`:

```
[..., 2, 3]
```

Depois:

```
[..., 5]
```

---

## **2.2. Frames de função**

Cada chamada de função cria um **frame** contendo:

| Campo      | Significado                                     |
| ---------- | ----------------------------------------------- |
| `env`      | Mapa `{nome → valor}` com argumentos da função  |
| `ip`       | Instruction Pointer (índice da instrução atual) |
| `code`     | Lista de instruções da função                   |
| `ret_addr` | Endereço de retorno para o chamador             |

Os frames são mantidos numa **call stack**.

* `CALL` empilha um novo frame.
* `RET` desempilha e devolve controlo.

---

## **2.3. Funções e labels**

Uma função é representada como:

```
func <name>/<arity>:
    <lista de instruções>
```

Exemplo:

```
func fib/1:
    ...
```

Labels marcam posições no código:

```
L_else:
```

Um label **não é** uma instrução — é apenas um destino para saltos.

---

# 📙 **3. Formato geral do IR**

Um programa IR contém:

* zero ou mais funções de utilizador
* uma função obrigatória:

```
func __main__/0:
```

A VM inicia a execução fazendo:

```
CALL __main__ 0
```

---

# 📕 **4. Instruções do IR v0.1**

Esta secção define, formalmente, todas as instruções da versão inicial.

---

## **4.1. `PUSH_CONST n`**

Empurra um inteiro para a stack.

```
PUSH_CONST <int>
```

**Stack:**

```
[...] → [..., n]
```

---

## **4.2. `LOAD_VAR name`**

Carrega o valor da variável `name` (arg. da função) para a stack.

```
LOAD_VAR <identifier>
```

**Stack:**

```
[...] → [..., value]
```

Se a variável não existir → erro.

---

## **4.3. Operações aritméticas**

### **ADD**

Soma dois inteiros:

```
[..., a, b] → [..., a + b]
```

---

### **SUB**

Subtrai:

```
[..., a, b] → [..., a - b]
```

---

## **4.4. Comparação**

### **LT**

Menor-que:

```
[..., a, b] → [..., (a < b ? 1 : 0)]
```

Retorna **1** ou **0**.

---

## **4.5. Controlo de fluxo**

### **JUMP label**

Salta incondicionalmente para um label na mesma função.

```
JUMP L_else
```

Stack não é alterada.

---

### **JUMP_IF_FALSE label**

Consome o topo da stack; se for **0**, salta para o label.

```
[..., cond] → [...]
```

Se `cond == 0` → faz jump.
Se diferente de 0 → continua linearmente.

---

## **4.6. Chamadas e retorno**

### **CALL func nargs**

Chama uma função declarada no programa.

```
CALL fib 1
```

Processo:

1. Consome `nargs` valores da stack (últimos são os últimos argumentos).
2. Cria novo frame com:

   * `env = { arg_name[i] = value[i] }`
3. Guarda `ret_addr` no frame chamador.
4. Transfere controlo para a função chamada.

Stack do chamador: usa os argumentos e esvazia-os.

---

### **RET**

Retorna um valor ao chamador.

```
[..., v] → [..., v]   # mas na stack do chamador
```

Processo:

1. Consome valor de retorno `v`.
2. Desempilha frame.
3. Empurra `v` na stack do chamador.
4. Continua na instrução após o `CALL`.

Se estiver em `__main__` → encerra a VM.

---

# 📘 **5. Labels**

Labels têm a forma:

```
L_<name>:
```

Sempre seguidos de `:`
Não consomem stack, não afetam execução diretamente.

---

# 📗 **6. Exemplo completo (fib)**

## Função `fib/1`

```text
func fib/1:
  LOAD_VAR x
  PUSH_CONST 3
  LT
  JUMP_IF_FALSE L_else

  PUSH_CONST 1
  RET

L_else:
  LOAD_VAR x
  PUSH_CONST 1
  SUB
  CALL fib 1

  LOAD_VAR x
  PUSH_CONST 2
  SUB
  CALL fib 1

  ADD
  RET
```

---

## Função principal

```text
func __main__/0:
  PUSH_CONST 40
  CALL fib 1
  RET
```

---

# 📙 **7. Regras de Validação (v0.1)**

O IR é inválido se:

* uma função referir um label inexistente.
* `CALL` referir função não declarada.
* instruções consumirem valores sem stack suficiente.
* a função `__main__/0` não existir.
* múltiplas funções com o mesmo nome/aridade.

---

# 📕 **8. Limitações do v0.1**

* Sem variáveis locais além dos argumentos.
* Sem loops nativos.
* Sem divisão, multiplicação, modulo.
* Sem tipos além de inteiros.
* Sem heap ou GC.
* Sem exceções.
* Sem otimizações.

Essas capacidades serão introduzidas em v0.2–v0.5.

---

# 🧠 **9. Filosofia de Design**

O Neuro IR v0.1 é:

* **didático** — ideal para visualização e estudo,
* **transparente** — cada instrução tem efeito claro e simples,
* **determinístico** — adequado para TRM e raciocínio neurotrónico,
* **extensível** — pronto para ganhar registos ou SSA,
* **minimalista** — apenas o necessário para recursão e matemática simples.

Este IR é o *espelho operacional* do compilador Neuro.

---

# 🌑 **Fim do SPEC_IR.md**