]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programcompiler.cpp
Record statement source lines and emit #line directives to output
[libs/gl.git] / source / programcompiler.cpp
index 50e4f5851df3cb11aecb1277763f622bb3a8d6f1..518b31e17f0d76213f2de8c52160cb3602f346b5 100644 (file)
@@ -58,7 +58,7 @@ void ProgramCompiler::compile(const string &source, const string &src_name)
        module = new Module();
        ProgramParser parser;
        imported_names.insert(src_name);
        module = new Module();
        ProgramParser parser;
        imported_names.insert(src_name);
-       append_module(parser.parse(source, src_name));
+       append_module(parser.parse(source, src_name, 1));
        process();
 }
 
        process();
 }
 
@@ -69,7 +69,7 @@ void ProgramCompiler::compile(IO::Base &io, Resources *res, const string &src_na
        module = new Module();
        ProgramParser parser;
        imported_names.insert(src_name);
        module = new Module();
        ProgramParser parser;
        imported_names.insert(src_name);
-       append_module(parser.parse(io, src_name));
+       append_module(parser.parse(io, src_name, 1));
        process();
 }
 
        process();
 }
 
@@ -199,7 +199,7 @@ void ProgramCompiler::import(const string &name)
        if(!io)
                throw runtime_error(format("module %s not found", name));
        ProgramParser import_parser;
        if(!io)
                throw runtime_error(format("module %s not found", name));
        ProgramParser import_parser;
-       append_module(import_parser.parse(*io, fn));
+       append_module(import_parser.parse(*io, fn, imported_names.size()));
 }
 
 void ProgramCompiler::generate(Stage &stage)
 }
 
 void ProgramCompiler::generate(Stage &stage)
@@ -307,6 +307,7 @@ void ProgramCompiler::BlockModifier::visit(Block &block)
 
 
 ProgramCompiler::Formatter::Formatter():
 
 
 ProgramCompiler::Formatter::Formatter():
+       source_line(1),
        indent(0),
        parameter_list(false)
 { }
        indent(0),
        parameter_list(false)
 { }
@@ -335,11 +336,34 @@ void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s)
 void ProgramCompiler::Formatter::append(const string &text)
 {
        formatted += text;
 void ProgramCompiler::Formatter::append(const string &text)
 {
        formatted += text;
+       for(string::const_iterator i=text.begin(); i!=text.end(); ++i)
+               if(*i=='\n')
+                       ++source_line;
 }
 
 void ProgramCompiler::Formatter::append(char c)
 {
        formatted += c;
 }
 
 void ProgramCompiler::Formatter::append(char c)
 {
        formatted += c;
+       if(c=='\n')
+               ++source_line;
+}
+
+void ProgramCompiler::Formatter::set_source(unsigned index, unsigned line)
+{
+       if(index!=source_index || (index && line!=source_line))
+       {
+               if(index==source_index && line==source_line+1)
+                       formatted += '\n';
+               else
+               {
+                       unsigned l = line;
+                       if(stage->required_version<Version(3, 30))
+                               --l;
+                       formatted += format("#line %d %d\n", l, index);
+               }
+       }
+       source_index = index;
+       source_line = line;
 }
 
 void ProgramCompiler::Formatter::visit(Literal &literal)
 }
 
 void ProgramCompiler::Formatter::visit(Literal &literal)
@@ -420,6 +444,7 @@ void ProgramCompiler::Formatter::visit(Block &block)
        {
                if(i!=block.body.begin())
                        append('\n');
        {
                if(i!=block.body.begin())
                        append('\n');
+               set_source((*i)->source, (*i)->line);
                append(spaces);
                (*i)->visit(*this);
        }
                append(spaces);
                (*i)->visit(*this);
        }
@@ -549,7 +574,9 @@ void ProgramCompiler::Formatter::visit(Conditional &cond)
                Conditional *else_cond = dynamic_cast<Conditional *>(cond.else_body.body.front().get());
                if(cond.else_body.body.size()==1 && else_cond)
                {
                Conditional *else_cond = dynamic_cast<Conditional *>(cond.else_body.body.front().get());
                if(cond.else_body.body.size()==1 && else_cond)
                {
-                       append(format("\n%selse ", string(indent*2, ' ')));
+                       append('\n');
+                       set_source(else_cond->source, else_cond->line);
+                       append(format("%selse ", string(indent*2, ' ')));
                        else_cond->visit(*this);
                }
                else
                        else_cond->visit(*this);
                }
                else