Large Functions Update

This commit is contained in:
mmichlol
2026-02-07 21:29:34 +01:00
parent 3916b4ff7a
commit d736f2786e
3 changed files with 306 additions and 152 deletions

View File

@@ -46,6 +46,7 @@ std::string generateAssembly(const CompilerState& state) {
result += "extern rand\n";
result += "extern srand\n";
result += "extern time\n";
result += "extern MessageBoxA\n";
// 2. SEKCJA DATA (Tylko raz!)
result += "section .data\n";
@@ -97,7 +98,10 @@ std::string generateAssembly(const CompilerState& state) {
instr.type == OpType::DIV ||
instr.type == OpType::MOD ||
instr.type == OpType::LOGIC_AND ||
instr.type == OpType::LOGIC_OR);
instr.type == OpType::LOGIC_OR ||
instr.type == OpType::MSGBOX ||
instr.type == OpType::ARRAY_DECLARE ||
instr.type == OpType::ARRAY_SET);
if (isWriteOp && stackMap.find(instr.arg1) == stackMap.end() && instr.arg1 != "RAX") {
stackMap[instr.arg1] = currentStack;
@@ -107,7 +111,32 @@ std::string generateAssembly(const CompilerState& state) {
switch (instr.type) {
case OpType::ASSIGN: {
std::string src = instr.arg2;
if (instr.arg3 == "STRING") {
// ODCZYT TABLICY: x = t[i]
if (instr.arg3.find("ARRAY_IDX:") == 0) {
std::string indexStr = instr.arg3.substr(10); // Pobierz "i"
std::string arrName = instr.arg2; // Pobierz "t"
std::string dst = getVarLocation(instr.arg1, stackMap);
int baseOffset = stackMap[arrName];
// £adujemy indeks do RCX
if (isNumber(indexStr)) result += " mov rcx, " + indexStr + "\n";
else result += " mov rcx, " + getVarLocation(indexStr, stackMap) + "\n";
result += " imul rcx, 8\n"; // index * 8
// Obliczamy adres
result += " mov rdx, rbp\n";
result += " sub rdx, " + std::to_string(baseOffset) + "\n";
result += " sub rdx, rcx\n";
// Odczytujemy wartoϾ z tablicy do RAX
result += " mov rax, [rdx]\n";
// Zapisujemy do zmiennej docelowej
result += " mov " + dst + ", rax\n"; // Lub eax, zale¿y jak masz
}
else if (instr.arg3 == "STRING") {
// Przypisanie stringa: ³adujemy ADRES (LEA)
result += " lea rax, [rel " + src + "]\n";
std::string dst = getVarLocation(instr.arg1, stackMap);
@@ -255,6 +284,76 @@ std::string generateAssembly(const CompilerState& state) {
result += " jmp " + instr.arg1 + "\n";
break;
}
case OpType::ARRAY_DECLARE: {
std::string name = instr.arg1;
int size = std::stoi(instr.arg2);
// Rezerwujemy miejsce dla ca³ej tablicy
// t[0] bêdzie pod aktualnym currentStack
stackMap[name] = currentStack;
// Przesuwamy wskaŸnik stosu o (rozmiar * 8 bajtów)
// Zak³adamy, ¿e ka¿dy element to 64-bit (dla bezpieczeñstwa i prostoty assemblera)
currentStack += (size * 8);
// W ASM nie musimy generowaæ ¿adnego kodu! (Miejsce ju¿ jest z sub rsp, 256)
// O ile tablica mieœci siê w tych 256 bajtach.
// Jeœli chcesz byæ PRO: dodaj na pocz¹tku funkcji "sub rsp, (currentStack + zapas)"
break;
}
case OpType::ARRAY_SET: {
std::string arrName = instr.arg1; // t
std::string indexStr = instr.arg2; // i
std::string valStr = instr.arg3; // val
// 1. Obliczamy wartoϾ do wpisania
if (isNumber(valStr)) {
result += " mov rax, " + valStr + "\n";
}
else {
std::string valLoc = getVarLocation(valStr, stackMap);
// Jeœli to zmienna ze stosu, to movsxd (rozszerzenie znaku) lub mov
result += " mov rax, " + valLoc + "\n"; // Zak³adamy 64-bit (lub eax dla 32)
}
// 2. Obliczamy adres elementu tablicy
// Adres = [rbp - offset_bazowy - (index * 8)]
// U nas stackMap trzyma offset_bazowy.
// Poniewa¿ stos roœnie w DÓ£, a my rezerwowaliœmy w DÓ£:
// t[0] -> offset
// t[1] -> offset + 8
// Czekaj, rbp-8, rbp-16...
// Im wiêkszy offset w stackMap, tym ni¿ej w pamiêci.
// stackMap["t"] = 8. [rbp-8].
// t[1] powinno byæ [rbp-16].
// Czyli Wzór: [rbp - (base_offset + index*8)]
int baseOffset = stackMap[arrName];
// £adujemy indeks do RCX
if (isNumber(indexStr)) {
result += " mov rcx, " + indexStr + "\n";
}
else {
std::string idxLoc = getVarLocation(indexStr, stackMap);
result += " mov rcx, " + idxLoc + "\n"; // Pobierz indeks ze zmiennej
}
// Obliczamy przesuniêcie bajtowe: index * 8
result += " imul rcx, 8\n";
// Poniewa¿ adres to RBP - (base + index*8) -> RBP - base - index*8
// Musimy to sprytnie zmontowaæ.
// Obliczmy finalny adres w RDX.
result += " mov rdx, rbp\n";
result += " sub rdx, " + std::to_string(baseOffset) + "\n"; // RDX = adres t[0]
result += " sub rdx, rcx\n"; // RDX = adres t[i]
// Zapisujemy wartoϾ (RAX) pod adres (RDX)
result += " mov [rdx], rax\n";
break;
}
case OpType::LABEL: {
result += instr.arg1 + ":\n";
break;
@@ -339,6 +438,45 @@ std::string generateAssembly(const CompilerState& state) {
result += " ret\n";
break;
}
case OpType::MSGBOX: {
// Konwencja Windows x64:
// RCX = HWND (0 = brak okna nadrzêdnego)
// RDX = TreϾ (Text)
// R8 = Tytu³ (Caption)
// R9 = Typ (0 = przycisk OK)
std::string title = instr.arg1;
std::string text = instr.arg2;
// --- 1. Ustawiamy RDX (TreϾ) ---
if (text.find("str_") == 0) {
// Jeœli to litera³ (np. str_5), ³adujemy jego adres (LEA)
result += " lea rdx, [rel " + text + "]\n";
}
else {
// Jeœli to zmienna, pobieramy jej wartoœæ ze stosu (która jest adresem)
std::string loc = getVarLocation(text, stackMap);
result += " mov rdx, " + loc + "\n";
}
// --- 2. Ustawiamy R8 (Tytu³) ---
if (title.find("str_") == 0) {
result += " lea r8, [rel " + title + "]\n";
}
else {
std::string loc = getVarLocation(title, stackMap);
result += " mov r8, " + loc + "\n";
}
// --- 3. Pozosta³e argumenty (Sta³e) ---
result += " mov rcx, 0\n"; // HWND = NULL
result += " mov r9, 0\n"; // MB_OK
// --- 4. Wywo³anie ---
// Stos (shadow space) jest ju¿ przygotowany na pocz¹tku funkcji (sub rsp, 256)
result += " call MessageBoxA\n";
break;
}
}
}