program.cpp 2.07 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
12
13
{
    std::unordered_map<const instruction*, argument> results;
    argument result;
    for(auto& ins:instructions)
    {
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
25
26
27
        else
        {
            std::vector<argument> values(ins.arguments.size());
            std::transform(ins.arguments.begin(), ins.arguments.end(), values.begin(), [&](instruction * i) {
                return results.at(i);
            });
Paul's avatar
Paul committed
28
            result = ins.op.compute(values);
Paul's avatar
Paul committed
29
30
31
        }
        results.emplace(std::addressof(ins), result);
    }
Paul's avatar
Paul committed
32
    return literal{result.get_shape(), result.data()};
Paul's avatar
Paul committed
33
34
}

Paul's avatar
Paul committed
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void program::print() const
{
    std::unordered_map<const instruction*, std::string> names;
    int count = 0;

    for(auto& ins:instructions)
    {
        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
54
55
56
57
            if (ins.lit.get_shape().elements() > 10)
                std::cout << "{ ... }";
            else
                std::cout << "{" << ins.lit << "}";
Paul's avatar
Paul committed
58
59
60
61
62
63
64
        }

        if(!ins.arguments.empty())
        {
            char delim = '(';
            for(auto&& arg:ins.arguments)
            {
Paul's avatar
Paul committed
65
                assert(this->has_instruction(arg) && "Instruction not found");
Paul's avatar
Paul committed
66
67
68
69
70
71
72
73
74
75
76
                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
77
        count++;
Paul's avatar
Paul committed
78
79
80
    }
}

Paul's avatar
Paul committed
81
82
}