Commit 1aad1ec3 authored by Paul's avatar Paul
Browse files

Use op class

parent 9c564ce8
#ifndef RTG_GUARD_BUILTIN_HPP
#define RTG_GUARD_BUILTIN_HPP
#include <rtg/operand.hpp>
namespace rtg {
namespace builtin {
static const char * literal = "@literal";
static const char * param = "@param";
struct literal
{
std::string name() const
{
return "@literal";
}
shape compute_shape(std::vector<shape> input) const
{
throw "builtin";
}
argument compute(std::vector<argument> input) const
{
throw "builtin";
}
};
struct param
{
std::string parameter;
std::string name() const
{
return "@param:" + parameter;
}
shape compute_shape(std::vector<shape> input) const
{
throw "builtin";
}
argument compute(std::vector<argument> input) const
{
throw "builtin";
}
};
}
......
......@@ -12,15 +12,15 @@ struct instruction
{
instruction() {}
instruction(std::string n, shape r, std::vector<instruction*> args)
: name(std::move(n)), result(std::move(r)), arguments(std::move(args))
instruction(operand o, shape r, std::vector<instruction*> args)
: op(std::move(o)), result(std::move(r)), arguments(std::move(args))
{}
instruction(literal l)
: name(builtin::literal), result(l.get_shape()), lit(std::move(l))
: op(builtin::literal{}), result(l.get_shape()), lit(std::move(l))
{}
std::string name;
operand op;
shape result;
std::vector<instruction*> arguments;
literal lit;
......
......@@ -12,11 +12,10 @@ namespace rtg {
struct program
{
template<class... Ts>
instruction * add_instruction(std::string name, Ts*... args)
instruction * add_instruction(operand op, Ts*... args)
{
auto&& op = ops.at(name);
shape r = op.compute_shape({args->result...});
instructions.push_back({name, r, {args...}});
instructions.push_back({op, r, {args...}});
return std::addressof(instructions.back());
}
template<class... Ts>
......@@ -28,22 +27,15 @@ struct program
instruction * add_parameter(std::string name, shape s)
{
instructions.push_back({builtin::param+std::move(name), s, {}});
instructions.push_back({builtin::param{std::move(name)}, s, {}});
return std::addressof(instructions.back());
}
void add_operator(operand op)
{
ops.emplace(op.name(), op);
}
literal eval(std::unordered_map<std::string, argument> params) const;
private:
// A list is used to keep references to an instruction stable
std::list<instruction> instructions;
std::unordered_map<std::string, operand> ops;
};
}
......
......@@ -10,22 +10,21 @@ literal program::eval(std::unordered_map<std::string, argument> params) const
argument result;
for(auto& ins:instructions)
{
if(ins.name == builtin::literal)
if(ins.op.name() == "@literal")
{
result = ins.lit.get_argument();
}
else if(starts_with(ins.name, builtin::param))
else if(starts_with(ins.op.name(), "@param"))
{
result = params.at(ins.name.substr(6));
result = params.at(ins.op.name().substr(7));
}
else
{
auto&& op = ops.at(ins.name);
std::vector<argument> values(ins.arguments.size());
std::transform(ins.arguments.begin(), ins.arguments.end(), values.begin(), [&](instruction * i) {
return results.at(i);
});
result = op.compute(values);
result = ins.op.compute(values);
}
results.emplace(std::addressof(ins), result);
}
......
......@@ -36,11 +36,10 @@ struct sum_op
void literal_test() {
rtg::program p;
p.add_operator(sum_op{});
auto one = p.add_literal(1);
auto two = p.add_literal(2);
p.add_instruction("sum", one, two);
p.add_instruction(sum_op{}, one, two);
auto result = p.eval({});
EXPECT(result == rtg::literal{3});
EXPECT(result != rtg::literal{4});
......@@ -48,12 +47,11 @@ void literal_test() {
void param_test() {
rtg::program p;
p.add_operator(sum_op{});
auto x = p.add_parameter("x", {rtg::shape::int_type});
auto y = p.add_parameter("y", {rtg::shape::int_type});
p.add_instruction("sum", x, y);
p.add_instruction(sum_op{}, x, y);
auto result = p.eval({
{"x", rtg::literal{1}.get_argument()},
{"y", rtg::literal{2}.get_argument()}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment