feat: migrate from OpView to DoubleLinkedList<Op*> + multiple
funciton arguments
This commit is contained in:
@@ -10,8 +10,8 @@ using BlockID = unsigned int;
|
||||
class Block
|
||||
{
|
||||
public:
|
||||
Block(BlockID id, const OpView& ops)
|
||||
: m_id(id), m_ops(DoubleLinkedList<Op*>::FromView(ops)) {}
|
||||
Block(BlockID id, DoubleLinkedList<Op*> ops)
|
||||
: m_id(id), m_ops(ops) {}
|
||||
public:
|
||||
DoubleLinkedList<Op*>& ops() { return m_ops; }
|
||||
public:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <unordered_map>
|
||||
#include "parser/nodes.hpp"
|
||||
#include "prelude/error.hpp"
|
||||
#include "prelude/linkedlist.hpp"
|
||||
#include "prelude/string.hpp"
|
||||
#include "ir/value.hpp"
|
||||
#include "ir/ops.hpp"
|
||||
@@ -13,7 +14,7 @@ namespace IR
|
||||
{
|
||||
public:
|
||||
IRBuilder(const StringView &filename, const Node *root)
|
||||
: m_root(root), m_ops(new OpBuilder()), m_filename(filename) {}
|
||||
: m_root(root), m_ops(new DoubleLinkedList<Op*>), m_filename(filename) {}
|
||||
|
||||
public:
|
||||
// TODO: support other literals
|
||||
@@ -28,8 +29,8 @@ namespace IR
|
||||
auto value = ParseExpression(varDecl->value());
|
||||
// TODO: gather type information from var decl signature, aka local <int> v = 0;
|
||||
auto dst = AllocateNamed<Pointer>(value->GetType());
|
||||
m_ops->Push(new AllocateOp(dst, value->GetType()));
|
||||
m_ops->Push(new StoreOp(value, reinterpret_cast<Pointer *>(dst)));
|
||||
m_ops->Append(m_ops->New(new AllocateOp(dst, value->GetType())));
|
||||
m_ops->Append(m_ops->New(new StoreOp(value, reinterpret_cast<Pointer *>(dst))));
|
||||
m_locals.insert(std::make_pair(varDecl->name(), reinterpret_cast<Pointer *>(dst)));
|
||||
}
|
||||
|
||||
@@ -42,22 +43,21 @@ namespace IR
|
||||
assert(false);
|
||||
}
|
||||
auto dst = AllocateNamed<Instruction>(m_locals[var->name()]->GetValueType());
|
||||
m_ops->Push(new LoadOp(dst, m_locals[var->name()]));
|
||||
m_ops->Append(m_ops->New(new LoadOp(dst, m_locals[var->name()])));
|
||||
return reinterpret_cast<ValueHandle *>(dst);
|
||||
}
|
||||
|
||||
ValueHandle *ParseFnCall(const FnCallNode *fn)
|
||||
{
|
||||
// TODO: support multiple args
|
||||
auto argRegs = ValueBuilder();
|
||||
if (fn->arg() != nullptr)
|
||||
auto args = ValueBuilder();
|
||||
for (size_t i = 0; i < fn->args().size; ++i)
|
||||
{
|
||||
auto arg = ParseExpression(fn->arg());
|
||||
argRegs.Push(arg);
|
||||
auto arg = ParseExpression(fn->args().data[i]);
|
||||
args.Push(arg);
|
||||
}
|
||||
// TODO: gather return type of the function
|
||||
auto dst = AllocateNamed<Instruction>(new ValueHandle::Type {ValueHandle::Type::Kind::Int});
|
||||
m_ops->Push(new CallOp(dst, fn->name(), argRegs.view()));
|
||||
m_ops->Append(m_ops->New(new CallOp(dst, fn->name(), args.view())));
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -93,16 +93,16 @@ namespace IR
|
||||
switch (expr->op())
|
||||
{
|
||||
case ExpressionNode::Operator::Plus:
|
||||
m_ops->Push(new MathOp(dst, lhs, rhs, OpType::ADD));
|
||||
m_ops->Append(m_ops->New(new MathOp(dst, lhs, rhs, OpType::ADD)));
|
||||
break;
|
||||
case ExpressionNode::Operator::Multiply:
|
||||
m_ops->Push(new MathOp(dst, lhs, rhs, OpType::MUL));
|
||||
m_ops->Append(m_ops->New(new MathOp(dst, lhs, rhs, OpType::MUL)));
|
||||
break;
|
||||
case ExpressionNode::Operator::Minus:
|
||||
m_ops->Push(new MathOp(dst, lhs, rhs, OpType::SUB));
|
||||
m_ops->Append(m_ops->New(new MathOp(dst, lhs, rhs, OpType::SUB)));
|
||||
break;
|
||||
case ExpressionNode::Operator::Divide:
|
||||
m_ops->Push(new MathOp(dst, lhs, rhs, OpType::DIV));
|
||||
m_ops->Append(m_ops->New(new MathOp(dst, lhs, rhs, OpType::DIV)));
|
||||
break;
|
||||
default:
|
||||
assert(0 && "unreachable");
|
||||
@@ -131,12 +131,12 @@ namespace IR
|
||||
}
|
||||
}
|
||||
auto ops = EndBlock();
|
||||
auto block = Block(m_block_counter++, std::move(ops->view()));
|
||||
auto block = Block(m_block_counter++, *ops);
|
||||
operator delete(ops);
|
||||
return block;
|
||||
}
|
||||
|
||||
OpView Build()
|
||||
DoubleLinkedList<Op*>* Build()
|
||||
{
|
||||
assert(m_root->GetType() == NodeType::Program && "root should be a program");
|
||||
auto program = reinterpret_cast<const ProgramNode *>(m_root);
|
||||
@@ -144,30 +144,30 @@ namespace IR
|
||||
// Externs
|
||||
for (auto &extrn : program->externs())
|
||||
{
|
||||
m_ops->Push(new ExternOp(extrn->symbol()));
|
||||
m_ops->Append(m_ops->New(new ExternOp(extrn->symbol())));
|
||||
}
|
||||
|
||||
// Functions
|
||||
for (auto &fn : program->funcs())
|
||||
{
|
||||
auto block = ParseBlock(fn->body());
|
||||
m_ops->Push(new FnOp(fn->name(), fn->params(), std::move(block)));
|
||||
m_ops->Append(m_ops->New(new FnOp(fn->name(), fn->params(), std::move(block))));
|
||||
}
|
||||
|
||||
return OpView(m_ops->data, m_ops->size);
|
||||
return m_ops;
|
||||
}
|
||||
|
||||
public:
|
||||
OpView ops() const { return OpView(m_ops->data, m_ops->size); }
|
||||
const DoubleLinkedList<Op*>* ops() const { return m_ops; }
|
||||
|
||||
private:
|
||||
void StartBlock()
|
||||
{
|
||||
m_containers.Push(m_ops);
|
||||
m_ops = new OpBuilder();
|
||||
m_ops = new DoubleLinkedList<Op*>;
|
||||
}
|
||||
|
||||
OpBuilder *EndBlock()
|
||||
DoubleLinkedList<Op*> *EndBlock()
|
||||
{
|
||||
assert(m_containers.size > 0 && "containers stack is empty");
|
||||
auto current = m_ops;
|
||||
@@ -193,13 +193,13 @@ namespace IR
|
||||
const Node *m_root = nullptr;
|
||||
StringView m_filename;
|
||||
|
||||
OpBuilder *m_ops = nullptr;
|
||||
DoubleLinkedList<Op*> *m_ops = nullptr;
|
||||
unsigned int m_value_counter = 0;
|
||||
unsigned int m_block_counter = 0;
|
||||
|
||||
std::unordered_map<StringView, Pointer *> m_locals;
|
||||
|
||||
Builder<OpBuilder *> m_containers;
|
||||
Builder<DoubleLinkedList<Op*>*> m_containers;
|
||||
};
|
||||
|
||||
} // namespace IR
|
||||
|
||||
Reference in New Issue
Block a user