]> git.tdb.fi Git - libs/gl.git/blob - source/programcompiler.h
Overhaul assignment tracking to work properly with conditionals
[libs/gl.git] / source / programcompiler.h
1 #ifndef MSP_GL_PROGRAMCOMPILER_H_
2 #define MSP_GL_PROGRAMCOMPILER_H_
3
4 #include <set>
5 #include "programparser.h"
6 #include "programsyntax.h"
7
8 namespace Msp {
9 namespace GL {
10
11 class Program;
12
13 class ProgramCompiler
14 {
15 private:
16         struct Visitor: ProgramSyntax::TraversingVisitor
17         {
18                 ProgramSyntax::Stage *stage;
19
20                 Visitor();
21
22                 virtual void apply(ProgramSyntax::Stage &);
23         };
24
25         struct Formatter: Visitor
26         {
27                 std::string formatted;
28                 unsigned indent;
29                 bool parameter_list;
30                 bool else_if;
31                 std::string block_interface;
32
33                 Formatter();
34
35                 virtual void visit(ProgramSyntax::Block &);
36                 virtual void visit(ProgramSyntax::Literal &);
37                 virtual void visit(ProgramSyntax::ParenthesizedExpression &);
38                 virtual void visit(ProgramSyntax::VariableReference &);
39                 virtual void visit(ProgramSyntax::MemberAccess &);
40                 virtual void visit(ProgramSyntax::UnaryExpression &);
41                 virtual void visit(ProgramSyntax::BinaryExpression &);
42                 virtual void visit(ProgramSyntax::Assignment &);
43                 virtual void visit(ProgramSyntax::FunctionCall &);
44                 virtual void visit(ProgramSyntax::ExpressionStatement &);
45                 virtual void visit(ProgramSyntax::Layout &);
46                 virtual void visit(ProgramSyntax::StructDeclaration &);
47                 virtual void visit(ProgramSyntax::VariableDeclaration &);
48                 virtual void visit(ProgramSyntax::InterfaceBlock &);
49                 virtual void visit(ProgramSyntax::FunctionDeclaration &);
50                 virtual void visit(ProgramSyntax::Conditional &);
51                 virtual void visit(ProgramSyntax::Iteration &);
52                 virtual void visit(ProgramSyntax::Return &);
53         };
54
55         struct VariableResolver: Visitor
56         {
57                 std::vector<ProgramSyntax::Block *> blocks;
58                 ProgramSyntax::StructDeclaration *type;
59                 bool anonymous;
60                 std::string block_interface;
61                 bool record_target;
62                 ProgramSyntax::VariableDeclaration *assignment_target;
63                 bool self_referencing;
64
65                 VariableResolver();
66
67                 virtual void apply(ProgramSyntax::Stage &);
68                 virtual void visit(ProgramSyntax::Block &);
69                 virtual void visit(ProgramSyntax::VariableReference &);
70                 virtual void visit(ProgramSyntax::MemberAccess &);
71                 virtual void visit(ProgramSyntax::BinaryExpression &);
72                 virtual void visit(ProgramSyntax::Assignment &);
73                 virtual void visit(ProgramSyntax::StructDeclaration &);
74                 virtual void visit(ProgramSyntax::VariableDeclaration &);
75                 virtual void visit(ProgramSyntax::InterfaceBlock &);
76         };
77
78         struct InterfaceGenerator: Visitor
79         {
80                 std::string in_prefix;
81                 std::string out_prefix;
82                 unsigned scope_level;
83                 std::map<std::string, ProgramSyntax::VariableDeclaration *> iface_declarations;
84                 bool remove_node;
85                 std::list<ProgramSyntax::Node *> insert_nodes;
86
87                 InterfaceGenerator();
88
89                 static std::string get_out_prefix(ProgramSyntax::StageType);
90                 virtual void apply(ProgramSyntax::Stage &);
91                 virtual void visit(ProgramSyntax::Block &);
92                 std::string change_prefix(const std::string &, const std::string &) const;
93                 bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &);
94                 void insert_assignment(const std::string &, ProgramSyntax::Expression *);
95                 virtual void visit(ProgramSyntax::VariableReference &);
96                 virtual void visit(ProgramSyntax::VariableDeclaration &);
97                 virtual void visit(ProgramSyntax::Passthrough &);
98         };
99
100         struct VariableRenamer: Visitor
101         {
102                 virtual void visit(ProgramSyntax::VariableReference &);
103                 virtual void visit(ProgramSyntax::VariableDeclaration &);
104         };
105
106         struct UnusedVariableLocator: Visitor
107         {
108                 struct AssignmentList
109                 {
110                         std::vector<ProgramSyntax::Node *> nodes;
111                         bool conditional;
112                         bool self_referencing;
113                 };
114
115                 typedef std::map<ProgramSyntax::VariableDeclaration *, AssignmentList> BlockAssignmentMap;
116
117                 std::set<ProgramSyntax::Node *> unused_nodes;
118                 std::map<ProgramSyntax::VariableDeclaration *, ProgramSyntax::Node *> aggregates;
119                 ProgramSyntax::Node *aggregate;
120                 std::vector<BlockAssignmentMap> assignments;
121                 ProgramSyntax::Assignment *assignment;
122                 bool assignment_target;
123
124                 UnusedVariableLocator();
125
126                 virtual void apply(ProgramSyntax::Stage &);
127                 virtual void visit(ProgramSyntax::VariableReference &);
128                 virtual void visit(ProgramSyntax::MemberAccess &);
129                 virtual void visit(ProgramSyntax::BinaryExpression &);
130                 virtual void visit(ProgramSyntax::Assignment &);
131                 void record_assignment(ProgramSyntax::VariableDeclaration &, ProgramSyntax::Node &, bool);
132                 virtual void visit(ProgramSyntax::ExpressionStatement &);
133                 virtual void visit(ProgramSyntax::StructDeclaration &);
134                 virtual void visit(ProgramSyntax::VariableDeclaration &);
135                 virtual void visit(ProgramSyntax::InterfaceBlock &);
136                 virtual void visit(ProgramSyntax::FunctionDeclaration &);
137                 void merge_down_assignments();
138                 virtual void visit(ProgramSyntax::Conditional &);
139                 virtual void visit(ProgramSyntax::Iteration &);
140         };
141
142         struct NodeRemover: Visitor
143         {
144                 std::set<ProgramSyntax::Node *> to_remove;
145
146                 virtual void visit(ProgramSyntax::Block &);
147                 virtual void visit(ProgramSyntax::VariableDeclaration &);
148         };
149
150         ProgramParser parser;
151         ProgramSyntax::Module *module;
152
153 public:
154         ProgramCompiler();
155
156         void compile(const std::string &);
157         void compile(IO::Base &);
158         void add_shaders(Program &);
159
160 private:
161         static ProgramSyntax::Module *create_builtins_module();
162         static ProgramSyntax::Module &get_builtins_module();
163         static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType);
164         void process();
165         void generate(ProgramSyntax::Stage &);
166         bool optimize(ProgramSyntax::Stage &);
167         static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
168         template<typename T>
169         static void apply(ProgramSyntax::Stage &);
170         std::string create_source(ProgramSyntax::Stage &);
171 };
172
173 } // namespace GL
174 } // namespace Msp
175
176 #endif