1 #include <msp/strings/format.h>
2 #include <msp/strings/utils.h>
5 #include "programcompiler.h"
13 using namespace ProgramSyntax;
15 ProgramCompiler::ProgramCompiler():
19 void ProgramCompiler::compile(const string &source)
21 module = &parser.parse(source);
24 void ProgramCompiler::compile(IO::Base &io)
26 module = &parser.parse(io);
29 void ProgramCompiler::add_shaders(Program &program)
32 throw invalid_operation("ProgramCompiler::add_shaders");
34 string global_source = "#version 150\n"+format_context(module->global_context);
35 if(module->vertex_context.present)
36 program.attach_shader_owned(new VertexShader(global_source+"\n"+format_context(module->vertex_context)));
37 if(module->geometry_context.present)
38 program.attach_shader_owned(new GeometryShader(global_source+"\n"+format_context(module->geometry_context)));
39 if(module->fragment_context.present)
40 program.attach_shader_owned(new FragmentShader(global_source+"\n"+format_context(module->fragment_context)));
42 program.bind_attribute(VERTEX4, "vertex");
43 program.bind_attribute(NORMAL3, "normal");
44 program.bind_attribute(COLOR4_FLOAT, "color");
45 program.bind_attribute(TEXCOORD4, "texcoord");
48 string ProgramCompiler::format_context(Context &context)
51 context.content.visit(formatter);
52 return formatter.formatted;
56 ProgramCompiler::Formatter::Formatter():
58 parameter_list(false),
62 void ProgramCompiler::Formatter::visit(Literal &literal)
64 formatted += literal.token;
67 void ProgramCompiler::Formatter::visit(ParenthesizedExpression &parexpr)
70 parexpr.expression->visit(*this);
74 void ProgramCompiler::Formatter::visit(VariableReference &var)
76 formatted += var.name;
79 void ProgramCompiler::Formatter::visit(MemberAccess &memacc)
81 memacc.left->visit(*this);
82 formatted += format(".%s", memacc.member);
85 void ProgramCompiler::Formatter::visit(UnaryExpression &unary)
88 formatted += unary.oper;
89 unary.expression->visit(*this);
91 formatted += unary.oper;
94 void ProgramCompiler::Formatter::visit(BinaryExpression &binary)
96 binary.left->visit(*this);
98 formatted += format(" %s ", binary.oper);
100 formatted += binary.oper;
101 binary.right->visit(*this);
102 formatted += binary.after;
105 void ProgramCompiler::Formatter::visit(FunctionCall &call)
107 formatted += format("%s(", call.name);
108 for(vector<NodePtr<Expression> >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
110 if(i!=call.arguments.begin())
117 void ProgramCompiler::Formatter::visit(ExpressionStatement &expr)
119 expr.expression->visit(*this);
123 void ProgramCompiler::Formatter::visit(Block &block)
132 formatted += format("%s{\n", string(indent*2, ' '));
135 bool change_indent = (!formatted.empty() && !else_if);
136 indent += change_indent;
137 string spaces(indent*2, ' ');
138 for(vector<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
140 if(i!=block.body.begin())
146 indent -= change_indent;
149 formatted += format("\n%s}", string(indent*2, ' '));
152 void ProgramCompiler::Formatter::visit(Layout &layout)
154 formatted += "layout(";
155 for(vector<Layout::Qualifier>::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i)
157 if(i!=layout.qualifiers.begin())
159 formatted += i->identifier;
160 if(!i->value.empty())
161 formatted += format("=%s", i->value);
163 formatted += format(") %s;", layout.interface);
166 void ProgramCompiler::Formatter::visit(StructDeclaration &strct)
168 formatted += format("struct %s\n", strct.name);
169 strct.members.visit(*this);
173 void ProgramCompiler::Formatter::visit(VariableDeclaration &var)
176 formatted += "const ";
177 if(!var.sampling.empty())
178 formatted += format("%s ", var.sampling);
179 if(!var.interface.empty())
180 formatted += format("%s ", var.interface);
181 formatted += format("%s %s", var.type, var.name);
186 var.array_size->visit(*this);
189 if(var.init_expression)
192 var.init_expression->visit(*this);
198 void ProgramCompiler::Formatter::visit(InterfaceBlock &iface)
200 formatted += format("%s %s\n", iface.interface, iface.name);
201 iface.members.visit(*this);
205 void ProgramCompiler::Formatter::visit(FunctionDeclaration &func)
207 formatted += format("%s %s(", func.return_type, func.name);
208 parameter_list = true;
209 for(vector<NodePtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
211 if(i!=func.parameters.begin())
215 parameter_list = false;
220 func.body.visit(*this);
226 void ProgramCompiler::Formatter::visit(Conditional &cond)
235 cond.condition->visit(*this);
238 cond.body.visit(*this);
239 if(!cond.else_body.body.empty())
241 formatted += format("\n%selse", string(indent*2, ' '));
243 cond.else_body.visit(*this);
248 void ProgramCompiler::Formatter::visit(Iteration &iter)
251 iter.init_statement->visit(*this);
253 iter.condition->visit(*this);
255 iter.loop_expression->visit(*this);
257 iter.body.visit(*this);
260 void ProgramCompiler::Formatter::visit(Return &ret)
262 formatted += "return ";
263 ret.expression->visit(*this);