feat: abstract value for IR
This commit is contained in:
@@ -2,15 +2,16 @@
|
||||
|
||||
#include "codegen/codegen.hpp"
|
||||
#include "ir/slot.hpp"
|
||||
#include "ir/value.hpp"
|
||||
|
||||
class StackFasmX86_64Generator : public CodeGenerator
|
||||
{
|
||||
public:
|
||||
~StackFasmX86_64Generator() override = default;
|
||||
private:
|
||||
StringView GetTempAddr(IR::Tmp reg)
|
||||
StringView GetTempAddr(IR::Value reg)
|
||||
{
|
||||
return std::move((StringBuilder() << 't' << reg).view());
|
||||
return std::move((StringBuilder() << reg.Format()).view());
|
||||
}
|
||||
|
||||
StringView GetSlotAddr(const IR::IRSlot& slot)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include "prelude/string.hpp"
|
||||
#include "ir/slot.hpp"
|
||||
#include "parser/ast.hpp"
|
||||
#include "ir/slot.hpp"
|
||||
#include "ir/allocator.hpp"
|
||||
#include "ir/value.hpp"
|
||||
|
||||
namespace IR
|
||||
{
|
||||
@@ -23,11 +24,6 @@ enum class OpType
|
||||
#define OP_TYPE(x) \
|
||||
OpType GetType() const override { return OpType::x; }
|
||||
|
||||
using Tmp = int;
|
||||
|
||||
using TmpView = View<Tmp>;
|
||||
using TmpBuilder = Builder<Tmp>;
|
||||
|
||||
class Op
|
||||
{
|
||||
public:
|
||||
@@ -43,13 +39,13 @@ using OpBuilder = Builder<Op*>;
|
||||
class Valued
|
||||
{
|
||||
public:
|
||||
Valued(Tmp dest)
|
||||
Valued(Value dest)
|
||||
: m_dest(dest) {}
|
||||
~Valued() = default;
|
||||
public:
|
||||
Tmp result() const { return m_dest; }
|
||||
Value result() const { return m_dest; }
|
||||
private:
|
||||
Tmp m_dest;
|
||||
Value m_dest;
|
||||
};
|
||||
|
||||
class ExternOp : public Op
|
||||
@@ -100,14 +96,14 @@ public:
|
||||
private:
|
||||
StringView m_name;
|
||||
OpView m_ops;
|
||||
View<Tmp> m_slots;
|
||||
ValueView m_slots;
|
||||
View<StringView> m_params;
|
||||
};
|
||||
|
||||
class LoadConstOp : public Op, public Valued
|
||||
{
|
||||
public:
|
||||
LoadConstOp(Tmp dest, long value)
|
||||
LoadConstOp(Value dest, long value)
|
||||
: Valued(dest), m_value(value) {}
|
||||
~LoadConstOp() {}
|
||||
|
||||
@@ -117,7 +113,7 @@ public:
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb.AppendIndent(indent);
|
||||
sb << 't' << result() << " = LOAD_CONST " << m_value;
|
||||
sb << result().Format() << " = LOAD_CONST " << m_value;
|
||||
return sb.view();
|
||||
}
|
||||
public:
|
||||
@@ -129,7 +125,7 @@ private:
|
||||
class LoadOp : public Op, public Valued
|
||||
{
|
||||
public:
|
||||
LoadOp(Tmp dest, StringView addr)
|
||||
LoadOp(Value dest, StringView addr)
|
||||
: Valued(dest), m_addr(addr) {}
|
||||
~LoadOp() {}
|
||||
|
||||
@@ -139,7 +135,7 @@ public:
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb.AppendIndent(indent);
|
||||
sb << 't' << result() << " = LOAD \"" << m_addr.c_str() << "\"";
|
||||
sb << result().Format() << " = LOAD \"" << m_addr.c_str() << "\"";
|
||||
return sb.view();
|
||||
}
|
||||
public:
|
||||
@@ -151,7 +147,7 @@ private:
|
||||
class StoreOp : public Op
|
||||
{
|
||||
public:
|
||||
StoreOp(StringView addr, Tmp src)
|
||||
StoreOp(StringView addr, Value src)
|
||||
: m_addr(addr), m_src(src) {}
|
||||
~StoreOp() {}
|
||||
|
||||
@@ -161,21 +157,21 @@ public:
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb.AppendIndent(indent);
|
||||
sb << "STORE \"" << m_addr.c_str() << "\", t" << m_src;
|
||||
sb << "STORE \"" << m_addr.c_str() << "\", " << m_src.Format();
|
||||
return sb.view();
|
||||
}
|
||||
public:
|
||||
const StringView& addr() const { return m_addr; }
|
||||
Tmp src() const { return m_src; }
|
||||
Value src() const { return m_src; }
|
||||
private:
|
||||
StringView m_addr;
|
||||
Tmp m_src;
|
||||
Value m_src;
|
||||
};
|
||||
|
||||
class AddOp : public Op, public Valued
|
||||
{
|
||||
public:
|
||||
AddOp(Tmp dest, Tmp lhs, Tmp rhs)
|
||||
AddOp(Value dest, Value lhs, Value rhs)
|
||||
: Valued(dest), m_lhs(lhs), m_rhs(rhs) {}
|
||||
~AddOp() {}
|
||||
|
||||
@@ -185,21 +181,21 @@ public:
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb.AppendIndent(indent);
|
||||
sb << 't' << result() << " = ADD " << m_lhs << ", " << m_rhs;
|
||||
sb << result().Format() << " = ADD " << m_lhs.Format() << ", " << m_rhs.Format();
|
||||
return sb.view();
|
||||
}
|
||||
public:
|
||||
Tmp lhs() const { return m_lhs; }
|
||||
Tmp rhs() const { return m_rhs; }
|
||||
Value lhs() const { return m_lhs; }
|
||||
Value rhs() const { return m_rhs; }
|
||||
private:
|
||||
Tmp m_lhs;
|
||||
Tmp m_rhs;
|
||||
Value m_lhs;
|
||||
Value m_rhs;
|
||||
};
|
||||
|
||||
class CallOp : public Op, public Valued
|
||||
{
|
||||
public:
|
||||
CallOp(Tmp dest, StringView callee, TmpView args)
|
||||
CallOp(Value dest, StringView callee, ValueView args)
|
||||
: Valued(dest), m_callee(callee), m_args(args) {}
|
||||
~CallOp() {}
|
||||
|
||||
@@ -211,18 +207,18 @@ public:
|
||||
for (size_t i = 0; i < m_args.size; ++i)
|
||||
{
|
||||
sb.AppendIndent(indent);
|
||||
sb << "PARAM t" << m_args.data[i] << '\n';
|
||||
sb << "PARAM " << m_args.data[i].Format() << '\n';
|
||||
}
|
||||
sb.AppendIndent(indent);
|
||||
sb << 't' << result() << " = CALL " << m_callee.c_str();
|
||||
sb << result().Format() << " = CALL " << m_callee.c_str();
|
||||
return sb.view();
|
||||
}
|
||||
public:
|
||||
const StringView& callee() const { return m_callee; }
|
||||
const TmpView& args() const { return m_args; }
|
||||
const ValueView& args() const { return m_args; }
|
||||
private:
|
||||
StringView m_callee;
|
||||
TmpView m_args;
|
||||
ValueView m_args;
|
||||
};
|
||||
|
||||
class IRBuilder
|
||||
@@ -232,14 +228,14 @@ public:
|
||||
: m_root(root) {}
|
||||
public:
|
||||
// TODO: support other literals
|
||||
Tmp ParseIntLiteral(const IntLiteralNode* literal)
|
||||
Value ParseIntLiteral(const IntLiteralNode* literal)
|
||||
{
|
||||
auto dst = AllocateRegister();
|
||||
m_ops.Push(new LoadConstOp(dst, literal->integer()));
|
||||
return dst;
|
||||
}
|
||||
|
||||
Tmp ParseVariable(const VariableNode* var)
|
||||
Value ParseVariable(const VariableNode* var)
|
||||
{
|
||||
// auto dst = AllocateRegister();
|
||||
// m_ops.Push(new LoadOp(dst, var->name()));
|
||||
@@ -251,10 +247,10 @@ public:
|
||||
return m_locals[var->name()];
|
||||
}
|
||||
|
||||
Tmp ParseFnCall(const FnCallNode* fn)
|
||||
Value ParseFnCall(const FnCallNode* fn)
|
||||
{
|
||||
// TODO: support multiple args
|
||||
auto argRegs = TmpBuilder();
|
||||
auto argRegs = ValueBuilder();
|
||||
if (fn->arg() != nullptr)
|
||||
{
|
||||
auto arg = ParseExpression(fn->arg());
|
||||
@@ -265,7 +261,7 @@ public:
|
||||
return dst;
|
||||
}
|
||||
|
||||
Tmp ParseFactor(const Node* factor)
|
||||
Value ParseFactor(const Node* factor)
|
||||
{
|
||||
switch(factor->GetType())
|
||||
{
|
||||
@@ -276,10 +272,10 @@ public:
|
||||
}
|
||||
|
||||
assert(0 && "unreachable");
|
||||
return Tmp();
|
||||
return Value();
|
||||
}
|
||||
|
||||
Tmp ParseExpression(const Node* expression)
|
||||
Value ParseExpression(const Node* expression)
|
||||
{
|
||||
if (expression->GetType() == NodeType::Expression)
|
||||
{
|
||||
@@ -343,17 +339,17 @@ public:
|
||||
// TODO: think about safety (copying m_ops.data before giving)
|
||||
OpView ops() const { return OpView(m_ops.data, m_ops.size); }
|
||||
private:
|
||||
Tmp AllocateRegister()
|
||||
Value AllocateRegister()
|
||||
{
|
||||
return m_tmp_counter++;
|
||||
return Value(m_value_counter++);
|
||||
}
|
||||
private:
|
||||
OpBuilder m_ops;
|
||||
const Node* m_root = nullptr;
|
||||
|
||||
unsigned int m_tmp_counter = 0;
|
||||
unsigned int m_value_counter = 0;
|
||||
|
||||
std::unordered_map<StringView, Tmp> m_locals;
|
||||
std::unordered_map<StringView, Value> m_locals;
|
||||
};
|
||||
|
||||
} // namespace IR
|
||||
|
||||
26
include/ir/value.hpp
Normal file
26
include/ir/value.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "prelude/string.hpp"
|
||||
|
||||
namespace IR
|
||||
{
|
||||
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
Value(unsigned int id) : m_id(id) {}
|
||||
Value() : m_id(0) {}
|
||||
public:
|
||||
StringView Format() const
|
||||
{
|
||||
auto sb = StringBuilder();
|
||||
sb.AppendFormat("%%%d", m_id);
|
||||
return sb.view();
|
||||
}
|
||||
private:
|
||||
unsigned int m_id;
|
||||
};
|
||||
|
||||
using ValueView = View<Value>;
|
||||
using ValueBuilder = Builder<Value>;
|
||||
|
||||
} // namespace IR
|
||||
Reference in New Issue
Block a user