Skip to content

Instantly share code, notes, and snippets.

@matovitch
Created March 27, 2020 10:08
Show Gist options
  • Save matovitch/9ce1589e09a4c2a638572fa587e7397e to your computer and use it in GitHub Desktop.
Save matovitch/9ce1589e09a4c2a638572fa587e7397e to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
namespace node
{
enum class Kind
{
PROGRAM,
FUNCTION,
FUNCTION_BODY,
FUNCTION_ARGS,
TYPE,
IDENTIFIER
};
} // namespace node
template <node::Kind KIND>
struct TIndex
{
uint32_t _value;
};
template <node::Kind KIND>
struct TNode {};
template <>
struct TNode<node::Kind::PROGRAM>
{
TIndex<node::Kind::FUNCTION> _functions;
uint32_t _size;
};
template <>
struct TNode<node::Kind::FUNCTION>
{
TIndex<node::Kind::IDENTIFIER > _name;
TIndex<node::Kind::FUNCTION_ARGS > _args;
TIndex<node::Kind::TYPE > _returnType;
TIndex<node::Kind::FUNCTION_BODY > _body;
};
template <node::Kind KIND>
struct TPool
{
std::vector<TNode<KIND>> _nodes;
};
struct PoolSet
{
template <node::Kind KIND>
const TNode<KIND>& get(const TIndex<KIND> index) const;
template <node::Kind KIND>
TNode<KIND>& get(const TIndex<KIND> index);
template <node::Kind KIND>
TIndex<KIND> make();
std::vector<TNode<node::Kind::FUNCTION >> _function;
std::vector<TNode<node::Kind::FUNCTION_BODY >> _functionBody;
std::vector<TNode<node::Kind::FUNCTION_ARGS >> _functionArgs;
std::vector<TNode<node::Kind::IDENTIFIER >> _identifier;
std::vector<TNode<node::Kind::TYPE >> _type;
};
template <>
const TNode<node::Kind::FUNCTION>& PoolSet::get<node::Kind::FUNCTION>(const TIndex<node::Kind::FUNCTION> index) const
{
return _function[index._value];
};
template <>
const TNode<node::Kind::FUNCTION_BODY>& PoolSet::get<node::Kind::FUNCTION_BODY>(const TIndex<node::Kind::FUNCTION_BODY> index) const
{
return _functionBody[index._value];
};
template <>
const TNode<node::Kind::FUNCTION_ARGS>& PoolSet::get<node::Kind::FUNCTION_ARGS>(const TIndex<node::Kind::FUNCTION_ARGS> index) const
{
return _functionArgs[index._value];
};
template <>
const TNode<node::Kind::IDENTIFIER>& PoolSet::get<node::Kind::IDENTIFIER>(const TIndex<node::Kind::IDENTIFIER> index) const
{
return _identifier[index._value];
};
template <>
const TNode<node::Kind::TYPE>& PoolSet::get<node::Kind::TYPE>(const TIndex<node::Kind::TYPE> index) const
{
return _type[index._value];
};
template <>
TNode<node::Kind::FUNCTION>& PoolSet::get<node::Kind::FUNCTION>(const TIndex<node::Kind::FUNCTION> index)
{
return _function[index._value];
};
template <>
TNode<node::Kind::FUNCTION_BODY>& PoolSet::get<node::Kind::FUNCTION_BODY>(const TIndex<node::Kind::FUNCTION_BODY> index)
{
return _functionBody[index._value];
};
template <>
TNode<node::Kind::FUNCTION_ARGS>& PoolSet::get<node::Kind::FUNCTION_ARGS>(const TIndex<node::Kind::FUNCTION_ARGS> index)
{
return _functionArgs[index._value];
};
template <>
TNode<node::Kind::IDENTIFIER>& PoolSet::get<node::Kind::IDENTIFIER>(const TIndex<node::Kind::IDENTIFIER> index)
{
return _identifier[index._value];
};
template <>
TNode<node::Kind::TYPE>& PoolSet::get<node::Kind::TYPE>(const TIndex<node::Kind::TYPE> index)
{
return _type[index._value];
};
template <>
TIndex<node::Kind::FUNCTION> PoolSet::make<node::Kind::FUNCTION>()
{
_function.emplace_back();
return TIndex<node::Kind::FUNCTION>{static_cast<uint32_t>(_function.size() - 1)};
};
template <>
TIndex<node::Kind::FUNCTION_BODY> PoolSet::make<node::Kind::FUNCTION_BODY>()
{
_functionBody.back();
return TIndex<node::Kind::FUNCTION_BODY>{static_cast<uint32_t>(_functionBody.size() - 1)};
};
template <>
TIndex<node::Kind::FUNCTION_ARGS> PoolSet::make<node::Kind::FUNCTION_ARGS>()
{
_functionArgs.emplace_back();
return TIndex<node::Kind::FUNCTION_ARGS>{static_cast<uint32_t>(_functionArgs.size() - 1)};
};
template <>
TIndex<node::Kind::IDENTIFIER> PoolSet::make<node::Kind::IDENTIFIER>()
{
_identifier.emplace_back();
return TIndex<node::Kind::IDENTIFIER>{static_cast<uint32_t>(_identifier.size() - 1)};
};
template <>
TIndex<node::Kind::TYPE> PoolSet::make<node::Kind::TYPE>()
{
_type.emplace_back();
return TIndex<node::Kind::TYPE>{static_cast<uint32_t>(_type.size() - 1)};
};
int main()
{
PoolSet poolSet;
TNode<node::Kind::PROGRAM> program;
program._functions = poolSet.make<node::Kind::FUNCTION>();
program._size = 1;
poolSet.get(program._functions)._name = poolSet.make<node::Kind::IDENTIFIER >();
poolSet.get(program._functions)._args = poolSet.make<node::Kind::FUNCTION_ARGS >();
poolSet.get(program._functions)._returnType = poolSet.make<node::Kind::TYPE >();
poolSet.get(program._functions)._body = poolSet.make<node::Kind::FUNCTION_BODY >();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment