saqut-compiler/src/ir/instruction.hpp

144 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================================
// saQut IR — Instruction (Tek Talimat)
//
// Sanal makine bu talimatlara bakarak ne yapacağını anlar.
// Her talimatın bir "opcode"u (ne iş yapacağı) ve birkaç operandı vardır.
// Operandlar ya slot numarasıdır (fonksiyonun yerel değişken/geçici depoları)
// ya da doğrudan bir sayı/isim değeridir.
//
// SLOT NEDİR?
// Her fonksiyon çağrısı kendi "frame"ini açar.
// Frame içinde numaralı kutucuklar vardır: slot[0], slot[1], ...
// Parametreler slot 0'dan başlar. Sonrasında lokal değişkenler
// ve hesaplama sırasında oluşan geçici değerler gelir.
// "slots[5] = 42" demek "5 numaralı kutucuğa 42 değerini koy" demektir.
//
// HANGİ OPCODE HANGİ ALANI KULLANIR?
// LOAD_CONST : dest, intValue
// LOAD_SLOT : dest, src
// ADD/SUB/... : dest, left, right
// LESS/LEQ/... : dest, left, right (sonuç: 1=doğru, 0=yanlış)
// JMP : jumpTarget
// JIF_FALSE : cond, jumpTarget
// CALL : dest, functionName, argSlots
// RETURN : src
// CALLHOST : functionName, argSlots
// ============================================================================
#ifndef SAQUT_IR_INSTRUCTION
#define SAQUT_IR_INSTRUCTION
#include <string>
#include <vector>
// ----------------------------------------------------------------------------
// Opcode — Sanal Makinenin Anlayacağı İşlem Kodları
// ----------------------------------------------------------------------------
enum class Opcode {
// --- Değer yükleme ---
LOAD_CONST, // slots[dest] = intValue
// Örnek: LOAD_CONST dest=3 val=10 → slot[3] = 10
LOAD_SLOT, // slots[dest] = slots[src]
// Bir slotun değerini başka bir slota kopyalar.
// Atama işlemlerinde (x = y) kullanılır.
// --- Aritmetik (tümü: slots[dest] = slots[left] OP slots[right]) ---
ADD,
SUB,
MUL,
DIV, // UYARI: sıfıra bölme → runtime_error fırlatılır
MOD,
// --- Karşılaştırma (sonuç: 1 = doğru, 0 = yanlış) ---
LESS, // slots[left] < slots[right]
LESS_EQUAL, // slots[left] <= slots[right]
GREATER, // slots[left] > slots[right]
GREATER_EQUAL, // slots[left] >= slots[right]
EQUAL_EQUAL, // slots[left] == slots[right]
NOT_EQUAL, // slots[left] != slots[right]
// --- Kontrol akışı ---
JMP, // Koşulsuz atlama: ip = jumpTarget
JIF_FALSE, // Koşullu atlama: slots[cond] == 0 ise ip = jumpTarget
// --- Fonksiyon çağrısı ---
CALL, // Başka bir saQut fonksiyonunu çağır.
// Yeni frame açılır, argümanlar parametre slotlarına kopyalanır.
// Fonksiyon RETURN ile bitince sonuç slots[dest]'e yazılır.
RETURN, // Bu frame'i kapat, slots[src]'yi caller'a ilet.
// --- Dış dünya (FFI — Foreign Function Interface) ---
CALLHOST, // Host (C++) fonksiyonunu çağır. Şu an sadece "print" destekli.
// Dönüş değeri yok; sadece yan etki (stdout'a yazmak gibi).
};
// Hata ayıklama ve IR dump için okunabilir isim
inline const char* opcodeName(Opcode op) {
switch (op) {
case Opcode::LOAD_CONST: return "LOAD_CONST";
case Opcode::LOAD_SLOT: return "LOAD_SLOT";
case Opcode::ADD: return "ADD";
case Opcode::SUB: return "SUB";
case Opcode::MUL: return "MUL";
case Opcode::DIV: return "DIV";
case Opcode::MOD: return "MOD";
case Opcode::LESS: return "LESS";
case Opcode::LESS_EQUAL: return "LESS_EQUAL";
case Opcode::GREATER: return "GREATER";
case Opcode::GREATER_EQUAL: return "GREATER_EQUAL";
case Opcode::EQUAL_EQUAL: return "EQUAL_EQUAL";
case Opcode::NOT_EQUAL: return "NOT_EQUAL";
case Opcode::JMP: return "JMP";
case Opcode::JIF_FALSE: return "JIF_FALSE";
case Opcode::CALL: return "CALL";
case Opcode::RETURN: return "RETURN";
case Opcode::CALLHOST: return "CALLHOST";
}
return "UNKNOWN";
}
// ----------------------------------------------------------------------------
// Instruction — Tek bir IR talimatı
//
// Okunabilirlik öncelikli bir tasarım: her talimat TÜM alanları içerir,
// kullanılmayanlar varsayılan değerde (-1 veya boş) kalır.
// Bu yaklaşım bellek israfeder ama her talimatın hangi veriyle çalıştığı
// açıkça görünür — karmaşık union/variant yapısı gerekmez.
// ----------------------------------------------------------------------------
struct Instruction {
Opcode opcode;
// Hedef slot — sonucun yazılacağı yer (LOAD_CONST, ADD, CALL vb.)
int dest = -1;
// Kaynak slot — kopyalama veya döndürme için (LOAD_SLOT, RETURN)
int src = -1;
// Aritmetik/karşılaştırma operandları
int left = -1;
int right = -1;
// LOAD_CONST için yüklenecek sabit değer
int intValue = 0;
// JMP / JIF_FALSE için hedef instruction indeksi
// Üretim sırasında bilinmiyorsa -1 bırakılır, sonradan doldurulur (backpatch).
int jumpTarget = -1;
// JIF_FALSE için kontrol edilecek koşul slotu
int cond = -1;
// CALL / CALLHOST için çağrılacak fonksiyonun adı
std::string functionName;
// CALL / CALLHOST için argüman slot indeksleri (sırayla)
std::vector<int> argSlots;
explicit Instruction(Opcode op) : opcode(op) {}
};
#endif // SAQUT_IR_INSTRUCTION