184 lines
4.1 KiB
C++
184 lines
4.1 KiB
C++
#pragma once
|
|
#include "prelude/string.hpp"
|
|
#include "parser/nodes.hpp"
|
|
#include "ir/value.hpp"
|
|
#include "ir/op.hpp"
|
|
#include "ir/block.hpp"
|
|
|
|
namespace IR
|
|
{
|
|
|
|
class ExternOp : public Op
|
|
{
|
|
public:
|
|
ExternOp(StringView symbol)
|
|
: m_symbol(symbol) {}
|
|
~ExternOp() {}
|
|
|
|
OP_TYPE(EXTERN)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
sb.AppendIndent(indent);
|
|
sb << "EXTRN " << m_symbol.c_str();
|
|
return sb.view();
|
|
}
|
|
public:
|
|
const StringView& symbol() const { return m_symbol; }
|
|
private:
|
|
StringView m_symbol;
|
|
};
|
|
|
|
// TODO: Make function return value (i.e. inhreit the OpValued class instead)
|
|
class FnOp : public Op
|
|
{
|
|
public:
|
|
FnOp(StringView name, const View<StringView>& params, Block&& block)
|
|
: m_name(name), m_params(params), m_body(block) {}
|
|
~FnOp() {}
|
|
|
|
OP_TYPE(FN)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
sb.AppendIndent(indent);
|
|
sb << "LABEL " << m_name.c_str() << ':' << '\n';
|
|
sb << m_body.Format(indent);
|
|
return sb.view();
|
|
}
|
|
public:
|
|
const StringView& name() const { return m_name; }
|
|
const Block& body() const { return m_body; }
|
|
const View<StringView>& params() const { return m_params; }
|
|
private:
|
|
StringView m_name;
|
|
ValueView m_slots;
|
|
View<StringView> m_params;
|
|
Block m_body;
|
|
};
|
|
|
|
class LoadConstOp : public OpValued
|
|
{
|
|
public:
|
|
LoadConstOp(Value 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:
|
|
LoadOp(Value dest, StringView addr)
|
|
: OpValued(dest), m_addr(addr) {}
|
|
~LoadOp() {}
|
|
|
|
OP_TYPE(LOAD)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
sb.AppendIndent(indent);
|
|
sb << result().Format() << " = LOAD \"" << m_addr.c_str() << "\"";
|
|
return sb.view();
|
|
}
|
|
public:
|
|
const StringView& addr() const { return m_addr; }
|
|
private:
|
|
StringView m_addr;
|
|
};
|
|
|
|
class StoreOp : public Op
|
|
{
|
|
public:
|
|
StoreOp(StringView addr, Value src)
|
|
: m_addr(addr), m_src(src) {}
|
|
~StoreOp() {}
|
|
|
|
OP_TYPE(STORE)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
sb.AppendIndent(indent);
|
|
sb << "STORE \"" << m_addr.c_str() << "\", " << m_src.Format();
|
|
return sb.view();
|
|
}
|
|
public:
|
|
const StringView& addr() const { return m_addr; }
|
|
Value src() const { return m_src; }
|
|
private:
|
|
StringView m_addr;
|
|
Value m_src;
|
|
};
|
|
|
|
class AddOp : public OpValued
|
|
{
|
|
public:
|
|
AddOp(Value dest, Value lhs, Value rhs)
|
|
: OpValued(dest), m_lhs(lhs), m_rhs(rhs) {}
|
|
~AddOp() {}
|
|
|
|
OP_TYPE(ADD)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
sb.AppendIndent(indent);
|
|
sb << result().Format() << " = ADD " << m_lhs.Format() << ", " << m_rhs.Format();
|
|
return sb.view();
|
|
}
|
|
public:
|
|
Value lhs() const { return m_lhs; }
|
|
Value rhs() const { return m_rhs; }
|
|
private:
|
|
Value m_lhs;
|
|
Value m_rhs;
|
|
};
|
|
|
|
class CallOp : public OpValued
|
|
{
|
|
public:
|
|
CallOp(Value dest, StringView callee, ValueView args)
|
|
: OpValued(dest), m_callee(callee), m_args(args) {}
|
|
~CallOp() {}
|
|
|
|
OP_TYPE(CALL)
|
|
public:
|
|
StringView Format(int indent) const override
|
|
{
|
|
StringBuilder sb;
|
|
for (size_t i = 0; i < m_args.size; ++i)
|
|
{
|
|
sb.AppendIndent(indent);
|
|
sb << "PARAM " << m_args.data[i].Format() << '\n';
|
|
}
|
|
sb.AppendIndent(indent);
|
|
sb << result().Format() << " = CALL " << m_callee.c_str();
|
|
return sb.view();
|
|
}
|
|
public:
|
|
const StringView& callee() const { return m_callee; }
|
|
const ValueView& args() const { return m_args; }
|
|
private:
|
|
StringView m_callee;
|
|
ValueView m_args;
|
|
};
|
|
|
|
} // namespace IR
|