feat: error handling, better prelude, double linked lists usage etc

This commit is contained in:
2026-01-02 22:06:56 +01:00
parent a453603b9b
commit 6176d549c1
10 changed files with 148 additions and 65 deletions

53
include/prelude/error.hpp Normal file
View File

@@ -0,0 +1,53 @@
#pragma once
#include "prelude/string.hpp"
#include <print>
struct Error
{
enum class Type
{
PARSE = 0,
TYPE,
COMPILE,
COUNT_ERROR_TYPES,
};
Type type;
StringView message;
StringView filename;
long line = 0;
long offset = 0;
public:
static Error CompileError(StringView filename, StringView message, long line = 0, long offset = 0)
{
return Error{Type::COMPILE, message, filename, line, offset};
}
static Error ParseError(StringView filename, StringView message, long line = 0, long offset = 0)
{
return Error{Type::PARSE, message, filename, line, offset};
}
static Error TypeError(StringView filename, StringView message, long line = 0, long offset = 0)
{
return Error{Type::TYPE, message, filename, line, offset};
}
};
constexpr const char* ErrorTypeNames[] = {
"ParseError",
"TypeError",
"CompileError",
};
class ErrorLogger
{
public:
static void Raise(const Error &error)
{
StringBuilder sb;
sb.AppendFormat("%s:%zu:%zu %s: %s", error.filename.c_str(), error.line, error.offset, ErrorTypeNames[static_cast<size_t>(error.type)], error.message.c_str());
std::println("{}", sb.c_str());
std::exit(1);
}
};

View File

@@ -40,7 +40,7 @@ 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)
if (fwrite(content.c_str(), sizeof(char), content.len(), m_handle) != content.len())
{
return false;
}
@@ -48,29 +48,21 @@ public:
}
public:
StringView ReadAll(bool* status = nullptr)
bool ReadAll(StringBuilder& sb)
{
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();
if (fseek(m_handle, 0, SEEK_END) != 0) return false;
auto size = ftell(m_handle);
if (size == -1 && status) return fail();
if (size == -1) return false;
StringBuilder sb;
sb.ensure_extra(size);
size_t wrote = fread(sb.data, sizeof(char), size, m_handle);
if (wrote == 0) return fail();
if (wrote == 0) return false;
sb.size = wrote;
return sb.view();
return true;
}
private:

View File

@@ -26,6 +26,17 @@ public:
return list;
}
public:
View<T> ToView()
{
Builder<T> b;
for(ListNode<T>* cur = Begin(); cur != nullptr; cur = cur->next)
{
b.Push(cur->value);
}
return b.view();
}
public:
void Append(ListNode<T>* node)
{

View File

@@ -67,7 +67,6 @@ public:
const T* end() const { return data + size; }
};
class StringView final : public View<char>
{
public:
@@ -102,6 +101,32 @@ public:
}
}
static StringView FromFormat(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
va_list args2;
va_copy(args2, args);
int len = std::vsnprintf(nullptr, 0, fmt, args2);
va_end(args2);
if (len < 0) {
va_end(args);
return StringView();
}
char* str = new char[len + 1];
std::vsnprintf(str, len + 1, fmt, args);
va_end(args);
return StringView(str);
}
size_t len() const { return strlen(data); }
const char* c_str() const { return data; }
};