From be55468e10915d377634aa850a95dcfb9093216d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 21 Jun 2019 14:24:56 +0300 Subject: [PATCH] Refactor ProgramCompiler::Formatter This is necessary for keeping track of output lines and translating error locations. --- source/programcompiler.cpp | 168 +++++++++++++++++++------------------ source/programcompiler.h | 3 +- 2 files changed, 90 insertions(+), 81 deletions(-) diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 5027dc9b..50e4f585 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -308,8 +308,7 @@ void ProgramCompiler::BlockModifier::visit(Block &block) ProgramCompiler::Formatter::Formatter(): indent(0), - parameter_list(false), - else_if(0) + parameter_list(false) { } void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s) @@ -319,145 +318,151 @@ void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s) if(ver) { - formatted += format("#version %d%02d", ver.major, ver.minor); + append(format("#version %d%02d", ver.major, ver.minor)); if(api==OPENGL_ES2 && ver>=Version(3, 0)) - formatted += " es"; + append(" es"); formatted += '\n'; } for(vector::const_iterator i=s.required_extensions.begin(); i!=s.required_extensions.end(); ++i) - formatted += format("#extension %s: require\n", (*i)->get_name()); + append(format("#extension %s: require\n", (*i)->get_name())); if(!s.required_extensions.empty()) formatted += '\n'; Visitor::apply(s); } +void ProgramCompiler::Formatter::append(const string &text) +{ + formatted += text; +} + +void ProgramCompiler::Formatter::append(char c) +{ + formatted += c; +} + void ProgramCompiler::Formatter::visit(Literal &literal) { - formatted += literal.token; + append(literal.token); } void ProgramCompiler::Formatter::visit(ParenthesizedExpression &parexpr) { - formatted += '('; + append('('); parexpr.expression->visit(*this); - formatted += ')'; + append(')'); } void ProgramCompiler::Formatter::visit(VariableReference &var) { - formatted += var.name; + append(var.name); } void ProgramCompiler::Formatter::visit(MemberAccess &memacc) { memacc.left->visit(*this); - formatted += format(".%s", memacc.member); + append(format(".%s", memacc.member)); } void ProgramCompiler::Formatter::visit(UnaryExpression &unary) { if(unary.prefix) - formatted += unary.oper; + append(unary.oper); unary.expression->visit(*this); if(!unary.prefix) - formatted += unary.oper; + append(unary.oper); } void ProgramCompiler::Formatter::visit(BinaryExpression &binary) { binary.left->visit(*this); - formatted += binary.oper; + append(binary.oper); binary.right->visit(*this); - formatted += binary.after; + append(binary.after); } void ProgramCompiler::Formatter::visit(Assignment &assign) { assign.left->visit(*this); - formatted += format(" %s ", assign.oper); + append(format(" %s ", assign.oper)); assign.right->visit(*this); } void ProgramCompiler::Formatter::visit(FunctionCall &call) { - formatted += format("%s(", call.name); + append(format("%s(", call.name)); for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) { if(i!=call.arguments.begin()) - formatted += ", "; + append(", "); (*i)->visit(*this); } - formatted += ')'; + append(')'); } void ProgramCompiler::Formatter::visit(ExpressionStatement &expr) { expr.expression->visit(*this); - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(Block &block) { - if(else_if) - --else_if; - unsigned brace_indent = indent; bool use_braces = (block.use_braces || (indent && block.body.size()!=1)); if(use_braces) - formatted += format("%s{\n", string(brace_indent*2, ' ')); + append(format("%s{\n", string(brace_indent*2, ' '))); SetForScope set(indent, indent+(indent>0 || use_braces)); string spaces(indent*2, ' '); for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) { if(i!=block.body.begin()) - formatted += '\n'; - formatted += spaces; + append('\n'); + append(spaces); (*i)->visit(*this); - else_if = 0; } if(use_braces) - formatted += format("\n%s}", string(brace_indent*2, ' ')); + append(format("\n%s}", string(brace_indent*2, ' '))); } void ProgramCompiler::Formatter::visit(Import &import) { - formatted += format("import %s;", import.module); + append(format("import %s;", import.module)); } void ProgramCompiler::Formatter::visit(Precision &prec) { - formatted += format("precision %s %s;", prec.precision, prec.type); + append(format("precision %s %s;", prec.precision, prec.type)); } void ProgramCompiler::Formatter::visit(Layout &layout) { - formatted += "layout("; + append("layout("); for(vector::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i) { if(i!=layout.qualifiers.begin()) - formatted += ", "; - formatted += i->identifier; + append(", "); + append(i->identifier); if(!i->value.empty()) - formatted += format("=%s", i->value); + append(format("=%s", i->value)); } - formatted += ')'; + append(')'); } void ProgramCompiler::Formatter::visit(InterfaceLayout &layout) { layout.layout.visit(*this); - formatted += format(" %s;", layout.interface); + append(format(" %s;", layout.interface)); } void ProgramCompiler::Formatter::visit(StructDeclaration &strct) { - formatted += format("struct %s\n", strct.name); + append(format("struct %s\n", strct.name)); strct.members.visit(*this); - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(VariableDeclaration &var) @@ -465,14 +470,14 @@ void ProgramCompiler::Formatter::visit(VariableDeclaration &var) if(var.layout) { var.layout->visit(*this); - formatted += ' '; + append(' '); } if(var.constant) - formatted += "const "; + append("const "); if(!var.interpolation.empty()) - formatted += format("%s ", var.interpolation); + append(format("%s ", var.interpolation)); if(!var.sampling.empty()) - formatted += format("%s ", var.sampling); + append(format("%s ", var.sampling)); if(!var.interface.empty() && var.interface!=block_interface) { string interface = var.interface; @@ -483,72 +488,75 @@ void ProgramCompiler::Formatter::visit(VariableDeclaration &var) else if((stage->type==VERTEX && var.interface=="out") || (stage->type==FRAGMENT && var.interface=="in")) interface = "varying"; } - formatted += format("%s ", interface); + append(format("%s ", interface)); } if(!var.precision.empty()) - formatted += format("%s ", var.precision); - formatted += format("%s %s", var.type, var.name); + append(format("%s ", var.precision)); + append(format("%s %s", var.type, var.name)); if(var.array) { - formatted += '['; + append('['); if(var.array_size) var.array_size->visit(*this); - formatted += ']'; + append(']'); } if(var.init_expression) { - formatted += " = "; + append(" = "); var.init_expression->visit(*this); } if(!parameter_list) - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(InterfaceBlock &iface) { SetForScope set(block_interface, iface.interface); - formatted += format("%s %s\n", iface.interface, iface.name); + append(format("%s %s\n", iface.interface, iface.name)); iface.members.visit(*this); - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(FunctionDeclaration &func) { - formatted += format("%s %s(", func.return_type, func.name); + append(format("%s %s(", func.return_type, func.name)); for(NodeArray::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) { if(i!=func.parameters.begin()) - formatted += ", "; + append(", "); SetFlag set(parameter_list); (*i)->visit(*this); } - formatted += ')'; + append(')'); if(func.definition==&func) { - formatted += '\n'; + append('\n'); func.body.visit(*this); } else - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(Conditional &cond) { - if(else_if) - formatted.replace(formatted.rfind('\n'), string::npos, 1, ' '); - - indent -= else_if; - - formatted += "if("; + append("if("); cond.condition->visit(*this); - formatted += ")\n"; + append(")\n"); cond.body.visit(*this); if(!cond.else_body.body.empty()) { - formatted += format("\n%selse\n", string(indent*2, ' ')); - SetForScope set(else_if, 2); - cond.else_body.visit(*this); + Conditional *else_cond = dynamic_cast(cond.else_body.body.front().get()); + if(cond.else_body.body.size()==1 && else_cond) + { + append(format("\n%selse ", string(indent*2, ' '))); + else_cond->visit(*this); + } + else + { + append(format("\n%selse\n", string(indent*2, ' '))); + cond.else_body.visit(*this); + } } } @@ -556,55 +564,55 @@ void ProgramCompiler::Formatter::visit(Iteration &iter) { if(!iter.init_statement && iter.condition && !iter.loop_expression) { - formatted += "while("; + append("while("); iter.condition->visit(*this); - formatted += ')'; + append(')'); } else { - formatted += "for("; + append("for("); if(iter.init_statement) iter.init_statement->visit(*this); else - formatted += ';'; + append(';'); if(iter.condition) { - formatted += ' '; + append(' '); iter.condition->visit(*this); } - formatted += ';'; + append(';'); if(iter.loop_expression) { - formatted += ' '; + append(' '); iter.loop_expression->visit(*this); } - formatted += ')'; + append(')'); } if(iter.body.body.empty()) - formatted += " { }"; + append(" { }"); else { - formatted += '\n'; + append('\n'); iter.body.visit(*this); } } void ProgramCompiler::Formatter::visit(Return &ret) { - formatted += "return"; + append("return"); if(ret.expression) { - formatted += ' '; + append(' '); ret.expression->visit(*this); } - formatted += ';'; + append(';'); } void ProgramCompiler::Formatter::visit(Jump &jump) { - formatted += jump.keyword; - formatted += ';'; + append(jump.keyword); + append(';'); } diff --git a/source/programcompiler.h b/source/programcompiler.h index 8c4f5453..9c20e090 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -46,7 +46,6 @@ private: std::string formatted; unsigned indent; bool parameter_list; - unsigned else_if; std::string block_interface; Formatter(); @@ -54,6 +53,8 @@ private: virtual void apply(ProgramSyntax::Stage &); const std::string &get_result() const { return formatted; } using Visitor::visit; + void append(const std::string &); + void append(char); virtual void visit(ProgramSyntax::Block &); virtual void visit(ProgramSyntax::Literal &); virtual void visit(ProgramSyntax::ParenthesizedExpression &); -- 2.43.0