feat: first prototype of optimizers + alloca optimizer

This commit is contained in:
2026-01-01 22:08:43 +01:00
parent 8a2d98e69e
commit 0b9cb7e7d9
12 changed files with 274 additions and 40 deletions

79
include/prelude/file.hpp Normal file
View File

@@ -0,0 +1,79 @@
#pragma once
#include "prelude/string.hpp"
#include <cstdio>
class File
{
public:
enum class Mode
{
WRITE,
READ,
};
private:
File(FILE* handle, Mode mode)
: m_handle(handle), m_mode(mode) {}
public:
static File Open(const StringView& filename, Mode mode)
{
StringBuilder sb;
switch(mode)
{
case Mode::WRITE:
sb.Append('w');
break;
case Mode::READ:
sb.Append('r');
break;
}
FILE* handle = fopen(filename.c_str(), sb.c_str());
return File(handle, mode);
}
private:
inline bool Writable() const { return m_mode == File::Mode::WRITE; }
inline bool Readable() const { return m_mode == File::Mode::READ; }
public:
bool Write(const StringView& content)
{
assert(Writable() && "attempt to write to a file in read only mode");
if (fwrite(content.c_str(), sizeof(char), content.size - 1, m_handle) == 0)
{
return false;
}
return true;
}
public:
StringView ReadAll(bool* status = nullptr)
{
auto fail = [&]() -> StringView {
if (status) *status = false;
return {};
};
if (status) *status = true;
assert(Readable() && "attempt to read from a file in write only mode");
if (fseek(m_handle, 0, SEEK_END) != 0) return fail();
auto size = ftell(m_handle);
if (size == -1 && status) return fail();
StringBuilder sb;
sb.ensure_extra(size);
size_t wrote = fread(sb.data, sizeof(char), size, m_handle);
if (wrote == 0) return fail();
sb.size = wrote;
return sb.view();
}
private:
FILE* m_handle;
Mode m_mode;
};

View File

@@ -0,0 +1,85 @@
#pragma once
#include <cstddef>
#include "prelude/string.hpp"
template<typename T>
struct ListNode
{
T value;
ListNode* prev = nullptr;
ListNode* next = nullptr;
};
template<typename T>
class DoubleLinkedList {
public:
DoubleLinkedList() = default;
public:
static DoubleLinkedList<T> FromView(const View<T> &view)
{
auto list = DoubleLinkedList<T>();
for (size_t i = 0; i < view.size; ++i)
{
list.Append(new ListNode<T>(view.data[i]));
}
return list;
}
public:
void Append(ListNode<T>* node)
{
if (IsEmpty())
{
node->next = nullptr;
node->prev = nullptr;
tail = node;
head = node;
} else {
head->next = node;
node->prev = head;
node->next = nullptr;
head = node;
}
m_size++;
}
void Prepend(ListNode<T>* node)
{
if (IsEmpty())
{
Append(node);
} else {
tail->prev = node;
node->next = tail;
node->prev = nullptr;
tail = node;
m_size++;
}
}
void SpliceFront(ListNode<T>* node)
{
if (m_size == 1 && tail == node && head == node) return;
assert((node->next || node->prev) && "node should be inside of the linked list");
if (node == tail) return;
if (node == head) {
node->prev->next = nullptr;
head = node->prev;
} else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
m_size--;
Prepend(node);
}
bool IsEmpty() const { return m_size == 0; }
ListNode<T>* Begin() const { return tail; }
ListNode<T>* End() const { return head; }
private:
ListNode<T>* head = nullptr;
ListNode<T>* tail = nullptr;
size_t m_size = 0;
};

View File

@@ -68,8 +68,6 @@ public:
};
// using StringView = View<char>;
class StringView final : public View<char>
{
public: