program.cpp 1.86 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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")
        {
            std::cout << "{" << ins.lit << "}";
        }

        if(!ins.arguments.empty())
        {
            char delim = '(';
            for(auto&& arg:ins.arguments)
            {
                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
78
}