program.cpp 2.14 KB
Newer Older
Paul's avatar
Paul committed
1
#include <rtg/program.hpp>
Paul's avatar
Paul committed
2
#include <rtg/stringutils.hpp>
Paul's avatar
Paul committed
3
#include <iostream>
Paul's avatar
Paul committed
4
5
6
7
#include <algorithm>

namespace rtg {

Paul's avatar
Paul committed
8
literal program::eval(std::unordered_map<std::string, argument> params) const
Paul's avatar
Paul committed
9
10
11
{
    std::unordered_map<const instruction*, argument> results;
    argument result;
Paul's avatar
Paul committed
12
    for(auto& ins : instructions)
Paul's avatar
Paul committed
13
    {
Paul's avatar
Paul committed
14
        if(ins.op.name() == "@literal")
Paul's avatar
Paul committed
15
16
17
        {
            result = ins.lit.get_argument();
        }
Paul's avatar
Paul committed
18
        else if(starts_with(ins.op.name(), "@param"))
Paul's avatar
Paul committed
19
        {
Paul's avatar
Paul committed
20
            result = params.at(ins.op.name().substr(7));
Paul's avatar
Paul committed
21
        }
Paul's avatar
Paul committed
22
23
24
        else
        {
            std::vector<argument> values(ins.arguments.size());
Paul's avatar
Paul committed
25
26
27
28
            std::transform(ins.arguments.begin(),
                           ins.arguments.end(),
                           values.begin(),
                           [&](instruction* i) { return results.at(i); });
Paul's avatar
Paul committed
29
            result = ins.op.compute(values);
Paul's avatar
Paul committed
30
31
32
        }
        results.emplace(std::addressof(ins), result);
    }
Paul's avatar
Paul committed
33
    return literal{result.get_shape(), result.data()};
Paul's avatar
Paul committed
34
35
}

Paul's avatar
Paul committed
36
37
38
39
40
void program::print() const
{
    std::unordered_map<const instruction*, std::string> names;
    int count = 0;

Paul's avatar
Paul committed
41
    for(auto& ins : instructions)
Paul's avatar
Paul committed
42
43
44
45
46
47
48
49
50
51
52
53
54
    {
        std::string var_name = "@" + std::to_string(count);
        if(starts_with(ins.op.name(), "@param"))
        {
            var_name = ins.op.name().substr(7);
        }

        std::cout << var_name << " = ";

        std::cout << ins.op.name();

        if(ins.op.name() == "@literal")
        {
Paul's avatar
Paul committed
55
            if(ins.lit.get_shape().elements() > 10)
Paul's avatar
Paul committed
56
57
58
                std::cout << "{ ... }";
            else
                std::cout << "{" << ins.lit << "}";
Paul's avatar
Paul committed
59
60
61
62
63
        }

        if(!ins.arguments.empty())
        {
            char delim = '(';
Paul's avatar
Paul committed
64
            for(auto&& arg : ins.arguments)
Paul's avatar
Paul committed
65
            {
Paul's avatar
Paul committed
66
                assert(this->has_instruction(arg) && "Instruction not found");
Paul's avatar
Paul committed
67
68
69
70
71
72
73
74
75
76
77
                std::cout << delim << names.at(arg);
                delim = ',';
            }
            std::cout << ")";
        }

        std::cout << " -> " << ins.result;

        std::cout << std::endl;

        names.emplace(std::addressof(ins), var_name);
Paul's avatar
Paul committed
78
        count++;
Paul's avatar
Paul committed
79
80
81
    }
}

Paul's avatar
Paul committed
82
} // namespace rtg