+#include <msp/strings/utils.h>
#include "glsl_error.h"
#include "preprocessor.h"
#include "tokenizer.h"
preprocess_pragma();
else if(token=="version")
preprocess_version();
+ else if(token=="line")
+ preprocess_line();
else if(token=="define" || token=="undef" || token=="if" || token=="ifdef" || token=="ifndef" || token=="else" ||
- token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="line")
+ token=="elif" || token=="endif" || token=="error" || token=="extension")
throw invalid_shader_source(tokenizer.get_location(), "Unsupported preprocessor directive '%s'", token);
else if(!token.empty())
throw parse_error(tokenizer.get_location(), token, "a preprocessor directive");
throw parse_error(tokenizer.get_location(), token, "end of line");
}
+void Preprocessor::preprocess_line()
+{
+ tokenizer.expect("line");
+ unsigned line_number = lexical_cast<unsigned>(tokenizer.parse_token());
+
+ int source_index = -1;
+ string token = tokenizer.parse_token();
+ if(!token.empty())
+ source_index = lexical_cast<unsigned>(token);
+
+ token = tokenizer.parse_token();
+ if(!token.empty())
+ throw parse_error(tokenizer.get_location(), token, "end of line");
+
+ signal_line.emit(source_index, line_number);
+}
+
void Preprocessor::preprocess_pragma()
{
tokenizer.expect("pragma");
string token = tokenizer.peek_token();
if(token=="stage")
preprocess_stage();
+ else if(token=="source")
+ preprocess_source();
else
throw invalid_shader_source(tokenizer.get_location(), "Unrecognized MSP pragma '%s'", token);
Stage::Type stage = Stage::SHARED;
if(token=="vertex")
stage = Stage::VERTEX;
+ else if(token=="tess_control")
+ stage = Stage::TESS_CONTROL;
+ else if(token=="tess_eval")
+ stage = Stage::TESS_EVAL;
else if(token=="geometry")
stage = Stage::GEOMETRY;
else if(token=="fragment")
stage = Stage::FRAGMENT;
+ else if(token=="compute")
+ stage = Stage::COMPUTE;
else
throw parse_error(tokenizer.get_location(), token, "stage identifier");
tokenizer.expect(")");
signal_stage_change.emit(stage);
}
+void Preprocessor::preprocess_source()
+{
+ tokenizer.expect("source");
+ tokenizer.expect("(");
+ unsigned source_index = lexical_cast<unsigned>(tokenizer.parse_token());
+ tokenizer.expect(",");
+ string filename = tokenizer.parse_token();
+ if(filename[0]!='"')
+ throw parse_error(tokenizer.get_location(), filename, "a string literal");
+ filename = c_unescape(filename.substr(1, filename.size()-2));
+ tokenizer.expect(")");
+
+ signal_source.emit(source_index, filename);
+}
+
} // namespace SL
} // namespace GL
} // namespace Msp