Compare commits

...

3 Commits

Author SHA1 Message Date
8a2d98e69e feat: remove unused imports, todos and typos 2026-01-01 16:09:51 +01:00
ad17a59d65 feat: move allocator and slots into codegen folder 2026-01-01 16:09:33 +01:00
7995dd2bdf feat: write plan for future dev 2026-01-01 16:09:21 +01:00
5 changed files with 42 additions and 36 deletions

32
TODO.md
View File

@@ -1,6 +1,33 @@
0. Define how many physical regs are available, which are caller-saved and callee-saved
1. Implement if-else and while statements
# Milestones
## Clean codebase structure
0. Prelude classes like FileIO, strings null-termination etc.
1. Diagnostic helper class for logging
2. Remove "void" valuehandle class and use it as ValueHandle::Type instead
3. Function multiple arguments support
4. Implement if-else and while statements
## Types support in language
## Stack based code generation
0. Stack based codegen, i.e. for fasm x86_64
## IR Optimizations aka const folding, deadcode elimination
## Register allocation
## First beta assembly code generation with registers
## ...
-------------------------------------------------
# References for IR optimizations
2. Find out what use[B] and def[B] are for each block
3. Define successors and predecessors of each block and make them accessible
4. Compute liveIn[B] and liveOut[B] for each block
@@ -19,6 +46,7 @@
- Spill to stack slots
- Add “CALL clobbers regs” rule
# References for register allocation
function's reserved registers:
EAX, ECX, EDX

View File

@@ -1,18 +1,19 @@
#pragma once
#include "prelude/string.hpp"
#include "ir/slot.hpp"
#include "codegen/slot.hpp"
#define AVAILABLE_REGISTERS 4
#define AVAILABLE_STACK_SIZE 4096
template<typename Slot, typename SlotAddr = const StringView&>
template <typename Slot, typename SlotAddr = const StringView &>
class Allocator
{
public:
virtual ~Allocator() {};
public:
virtual const Slot& Allocate(SlotAddr addr) = 0;
virtual const Slot& Resolve(SlotAddr addr) = 0;
virtual const Slot &Allocate(SlotAddr addr) = 0;
virtual const Slot &Resolve(SlotAddr addr) = 0;
};
class SlotAllocator : public Allocator<IR::IRSlot>
@@ -20,8 +21,9 @@ class SlotAllocator : public Allocator<IR::IRSlot>
public:
SlotAllocator() = default;
~SlotAllocator() = default;
public:
const IR::IRSlot& Allocate(const StringView& addr) override
const IR::IRSlot &Allocate(const StringView &addr) override
{
if (m_regs < AVAILABLE_REGISTERS)
{
@@ -38,7 +40,7 @@ public:
assert(0 && "failed to allocate local");
}
const IR::IRSlot& Resolve(const StringView& addr) override
const IR::IRSlot &Resolve(const StringView &addr) override
{
for (size_t i = 0; i < m_slots.size; ++i)
{
@@ -50,10 +52,13 @@ public:
assert(0 && "could not resolve stack offset for specified address");
}
public:
View<IR::IRSlot> slots() const { return m_slots.view(); }
public:
unsigned int GetStackSize() const { return m_offset_counter; }
public:
int m_regs = 0;
unsigned int m_offset_counter = 0;

View File

@@ -2,8 +2,6 @@
#include <unordered_map>
#include "prelude/string.hpp"
#include "parser/ast.hpp"
#include "ir/slot.hpp"
#include "ir/allocator.hpp"
#include "ir/value.hpp"
#include "ir/ops.hpp"
@@ -158,7 +156,6 @@ namespace IR
}
public:
// TODO: think about safety (copying m_ops->data before giving)
OpView ops() const { return OpView(m_ops->data, m_ops->size); }
private:

View File

@@ -32,7 +32,7 @@ namespace IR
StringView m_symbol;
};
// TODO: Make function return value (i.e. inhreit the OpValued class instead)
// TODO: Make function return value (i.e. inherit the OpValued class instead)
class FnOp : public Op
{
public:
@@ -87,30 +87,6 @@ namespace IR
ValueHandle::Type *m_typ;
};
// class LoadConstOp : public OpValued
// {
// public:
// LoadConstOp(ValueHandle *dest, long value)
// : OpValued(dest), m_value(value) {}
// ~LoadConstOp() {}
// OP_TYPE(LOAD_CONST)
// public:
// StringView Format(int indent) const override
// {
// StringBuilder sb;
// sb.AppendIndent(indent);
// sb << result()->Format() << " = LOAD_CONST " << m_value;
// return sb.view();
// }
// public:
// long value() const { return m_value; }
// private:
// long m_value;
// };
class LoadOp : public OpValued
{
public: