bQUARKz 47c082adb1
dev/prometeuc-improvements (#5)
Co-authored-by: Nilton Constantino <nilton.constantino@visma.com>
Reviewed-on: #5
2026-03-24 13:40:19 +00:00
..
2026-03-24 13:40:19 +00:00
2026-03-24 13:40:19 +00:00
2026-03-24 13:40:19 +00:00

prometeu-bytecode

Contrato oficial (ABI) do ecossistema PROMETEU. Este crate define o conjunto de instruções (ISA), o formato de arquivo .pbc (Prometeu ByteCode) e ferramentas básicas de montagem (Assembler) e desmontagem (Disassembler).

Design

A PVM (Prometeu Virtual Machine) é uma máquina baseada em pilha (stack-based). A maioria das instruções opera nos valores do topo da pilha de operandos. O formato de dados padrão para multi-byte na ROM é Little-Endian.

Convenção de Notação da Pilha

Nas tabelas abaixo, usamos a seguinte notação para representar o estado da pilha: [a, b] -> [c] Significa que a instrução remove a e b da pilha (onde b estava no topo) e insere c no topo.


Conjunto de Instruções (ISA)

6.1 Controle de Execução

OpCode Valor Operandos Pilha Descrição
Nop 0x00 - [] -> [] Nenhuma operação.
Halt 0x01 - [] -> [] Interrompe a execução da VM permanentemente.
Jmp 0x02 addr: u32 [] -> [] Salto incondicional para o endereço absoluto addr.
JmpIfFalse 0x03 addr: u32 [bool] -> [] Salta para addr se o valor desempilhado for false.
JmpIfTrue 0x04 addr: u32 [bool] -> [] Salta para addr se o valor desempilhado for true.
Trap 0x05 - [] -> [] Interrupção para debugger (breakpoint).

6.2 Manipulação da Pilha

OpCode Valor Operandos Pilha Descrição
PushConst 0x10 idx: u32 [] -> [val] Carrega a constante do índice idx da Constant Pool.
Pop 0x11 - [val] -> [] Remove e descarta o valor do topo da pilha.
Dup 0x12 - [val] -> [val, val] Duplica o valor no topo da pilha.
Swap 0x13 - [a, b] -> [b, a] Inverte a posição dos dois valores no topo.
PushI64 0x14 val: i64 [] -> [i64] Empilha um inteiro de 64 bits imediato.
PushF64 0x15 val: f64 [] -> [f64] Empilha um ponto flutuante de 64 bits imediato.
PushBool 0x16 val: u8 [] -> [bool] Empilha um booleano (0=false, 1=true).
PushI32 0x17 val: i32 [] -> [i32] Empilha um inteiro de 32 bits imediato.
PopN 0x18 n: u16 [...] -> [...] Remove n valores da pilha de uma vez.

6.3 Aritmética

A VM realiza promoção automática de tipos (ex: i32 + f64 resulta em f64).

OpCode Valor Pilha Descrição
Add 0x20 [a, b] -> [a + b] Soma os dois valores do topo.
Sub 0x21 [a, b] -> [a - b] Subtrai b de a.
Mul 0x22 [a, b] -> [a * b] Multiplica os dois valores do topo.
Div 0x23 [a, b] -> [a / b] Divide a por b. Erro se b == 0.
Neg 0x3E [a] -> [-a] Inverte o sinal numérico.

6.4 Lógica e Comparação

OpCode Valor Pilha Descrição
Eq 0x30 [a, b] -> [bool] Testa igualdade.
Neq 0x31 [a, b] -> [bool] Testa desigualdade.
Lt 0x32 [a, b] -> [bool] a < b
Gt 0x33 [a, b] -> [bool] a > b
Lte 0x3C [a, b] -> [bool] a <= b
Gte 0x3D [a, b] -> [bool] a >= b
And 0x34 [a, b] -> [bool] AND lógico (booleano).
Or 0x35 [a, b] -> [bool] OR lógico (booleano).
Not 0x36 [a] -> [!a] NOT lógico.
BitAnd 0x37 [a, b] -> [int] AND bit a bit.
BitOr 0x38 [a, b] -> [int] OR bit a bit.
BitXor 0x39 [a, b] -> [int] XOR bit a bit.
Shl 0x3A [a, b] -> [int] Shift Left: a << b.
Shr 0x3B [a, b] -> [int] Shift Right: a >> b.

6.5 Variáveis e Memória

OpCode Valor Operandos Pilha Descrição
GetGlobal 0x40 idx: u32 [] -> [val] Carrega valor da global idx.
SetGlobal 0x41 idx: u32 [val] -> [] Armazena topo na global idx.
GetLocal 0x42 idx: u32 [] -> [val] Carrega local idx do frame atual.
SetLocal 0x43 idx: u32 [val] -> [] Armazena topo na local idx do frame atual.

6.6 Funções e Escopo

OpCode Valor Operandos Pilha Descrição
Call 0x50 addr: u32, args: u32 [a1, a2] -> [...] Chama addr. Os args valores no topo viram locais do novo frame.
Ret 0x51 - [val] -> [val] Retorna da função atual, limpando o frame e devolvendo o valor do topo.
PushScope 0x52 - [] -> [] Inicia um sub-escopo (bloco) para locais temporários.
PopScope 0x53 - [] -> [] Finaliza sub-escopo, removendo locais criados nele da pilha.

6.7 Heap (Memória Dinâmica)

OpCode Valor Operandos Pilha Descrição
Alloc 0x60 size: u32 [] -> [ref] Aloca size slots no heap e retorna uma referência.
LoadRef 0x61 offset: u32 [ref] -> [val] Lê valor do heap no endereço ref + offset.
StoreRef 0x62 offset: u32 [ref, val] -> [] Escreve val no heap no endereço ref + offset.

6.8 Sistema e Sincronização

OpCode Valor Operandos Pilha Descrição
Syscall 0x70 id: u32 [...] -> [...] Invoca uma função do sistema/firmware. A pilha depende da syscall.
FrameSync 0x80 - [] -> [] Marca o fim do processamento do frame lógico atual (60 FPS).

Estrutura do PBC (Prometeu ByteCode)

O PBC é o formato binário oficial para programas Prometeu.

// Exemplo de como carregar um arquivo PBC
let bytes = std::fs::read("game.pbc")?;
let pbc = prometeu_bytecode::pbc::parse_pbc(&bytes)?;

println!("ROM size: {} bytes", pbc.rom.len());
println!("Constants: {}", pbc.cp.len());

Assembler e Disassembler

Este crate fornece ferramentas para facilitar a geração e inspeção de código.

Montagem (Assembler)

use prometeu_bytecode::asm::{assemble, Asm, Operand};
use prometeu_bytecode::opcode::OpCode;

let instructions = vec![
    Asm::Op(OpCode::PushI32, vec![Operand::I32(10)]),
    Asm::Op(OpCode::PushI32, vec![Operand::I32(20)]),
    Asm::Op(OpCode::Add, vec![]),
    Asm::Op(OpCode::Halt, vec![]),
];

let rom_bytes = assemble(&instructions).unwrap();

Desmontagem (Disassembler)

use prometeu_bytecode::disasm::disasm;

let rom = vec![/* ... bytes ... */];
let code = disasm(&rom);

for instr in code {
    println!("{:04X}: {:?} {:?}", instr.pc, instr.opcode, instr.operands);
}