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

Use op class

parent 9c564ce8
#ifndef RTG_GUARD_BUILTIN_HPP #ifndef RTG_GUARD_BUILTIN_HPP
#define RTG_GUARD_BUILTIN_HPP #define RTG_GUARD_BUILTIN_HPP
#include <rtg/operand.hpp>
namespace rtg { namespace rtg {
namespace builtin { namespace builtin {
static const char * literal = "@literal"; struct literal
static const char * param = "@param"; {
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 ...@@ -12,15 +12,15 @@ struct instruction
{ {
instruction() {} instruction() {}
instruction(std::string n, shape r, std::vector<instruction*> args) instruction(operand o, shape r, std::vector<instruction*> args)
: name(std::move(n)), result(std::move(r)), arguments(std::move(args)) : op(std::move(o)), result(std::move(r)), arguments(std::move(args))
{} {}
instruction(literal l) 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; shape result;
std::vector<instruction*> arguments; std::vector<instruction*> arguments;
literal lit; literal lit;
......
...@@ -12,11 +12,10 @@ namespace rtg { ...@@ -12,11 +12,10 @@ namespace rtg {
struct program struct program
{ {
template<class... Ts> 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...}); shape r = op.compute_shape({args->result...});
instructions.push_back({name, r, {args...}}); instructions.push_back({op, r, {args...}});
return std::addressof(instructions.back()); return std::addressof(instructions.back());
} }
template<class... Ts> template<class... Ts>
...@@ -28,22 +27,15 @@ struct program ...@@ -28,22 +27,15 @@ struct program
instruction * add_parameter(std::string name, shape s) 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()); 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; literal eval(std::unordered_map<std::string, argument> params) const;
private: private:
// A list is used to keep references to an instruction stable // A list is used to keep references to an instruction stable
std::list<instruction> instructions; 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 ...@@ -10,22 +10,21 @@ literal program::eval(std::unordered_map<std::string, argument> params) const
argument result; argument result;
for(auto& ins:instructions) for(auto& ins:instructions)
{ {
if(ins.name == builtin::literal) if(ins.op.name() == "@literal")
{ {
result = ins.lit.get_argument(); 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 else
{ {
auto&& op = ops.at(ins.name);
std::vector<argument> values(ins.arguments.size()); std::vector<argument> values(ins.arguments.size());
std::transform(ins.arguments.begin(), ins.arguments.end(), values.begin(), [&](instruction * i) { std::transform(ins.arguments.begin(), ins.arguments.end(), values.begin(), [&](instruction * i) {
return results.at(i); return results.at(i);
}); });
result = op.compute(values); result = ins.op.compute(values);
} }
results.emplace(std::addressof(ins), result); results.emplace(std::addressof(ins), result);
} }
......
...@@ -36,11 +36,10 @@ struct sum_op ...@@ -36,11 +36,10 @@ struct sum_op
void literal_test() { void literal_test() {
rtg::program p; rtg::program p;
p.add_operator(sum_op{});
auto one = p.add_literal(1); auto one = p.add_literal(1);
auto two = p.add_literal(2); auto two = p.add_literal(2);
p.add_instruction("sum", one, two); p.add_instruction(sum_op{}, one, two);
auto result = p.eval({}); auto result = p.eval({});
EXPECT(result == rtg::literal{3}); EXPECT(result == rtg::literal{3});
EXPECT(result != rtg::literal{4}); EXPECT(result != rtg::literal{4});
...@@ -48,12 +47,11 @@ void literal_test() { ...@@ -48,12 +47,11 @@ void literal_test() {
void param_test() { void param_test() {
rtg::program p; rtg::program p;
p.add_operator(sum_op{});
auto x = p.add_parameter("x", {rtg::shape::int_type}); auto x = p.add_parameter("x", {rtg::shape::int_type});
auto y = p.add_parameter("y", {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({ auto result = p.eval({
{"x", rtg::literal{1}.get_argument()}, {"x", rtg::literal{1}.get_argument()},
{"y", rtg::literal{2}.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