]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/preprocessor.cpp
Split tokenizer and preprocessor out of the GLSL parser
[libs/gl.git] / source / glsl / preprocessor.cpp
diff --git a/source/glsl/preprocessor.cpp b/source/glsl/preprocessor.cpp
new file mode 100644 (file)
index 0000000..3c19022
--- /dev/null
@@ -0,0 +1,85 @@
+#include "glsl_error.h"
+#include "preprocessor.h"
+#include "tokenizer.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+Preprocessor::Preprocessor(Tokenizer &t):
+       tokenizer(t)
+{ }
+
+void Preprocessor::preprocess()
+{
+       tokenizer.expect("#");
+
+       string token = tokenizer.peek_token();
+       if(token=="pragma")
+               preprocess_pragma();
+       else if(token=="version")
+               preprocess_version();
+       else if(token=="define" || token=="undef" || token=="if" || token=="ifdef" || token=="ifndef" || token=="else" ||
+               token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="line")
+               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");
+}
+
+void Preprocessor::preprocess_version()
+{
+       tokenizer.expect("version");
+       string token = tokenizer.parse_token();
+       unsigned version = lexical_cast<unsigned>(token);
+       signal_version.emit(Version(version/100, version%100));
+
+       token = tokenizer.parse_token();
+       if(!token.empty())
+               throw parse_error(tokenizer.get_location(), token, "end of line");
+}
+
+void Preprocessor::preprocess_pragma()
+{
+       tokenizer.expect("pragma");
+       string token = tokenizer.parse_token();
+       if(token=="MSP")
+               preprocess_pragma_msp();
+}
+
+void Preprocessor::preprocess_pragma_msp()
+{
+       string token = tokenizer.peek_token();
+       if(token=="stage")
+               preprocess_stage();
+       else
+               throw invalid_shader_source(tokenizer.get_location(), "Unrecognized MSP pragma '%s'", token);
+
+       token = tokenizer.parse_token();
+       if(!token.empty())
+               throw parse_error(tokenizer.get_location(), token, "end of line");
+}
+
+void Preprocessor::preprocess_stage()
+{
+       tokenizer.expect("stage");
+       tokenizer.expect("(");
+       string token = tokenizer.parse_token();
+       StageType stage = SHARED;
+       if(token=="vertex")
+               stage = VERTEX;
+       else if(token=="geometry")
+               stage = GEOMETRY;
+       else if(token=="fragment")
+               stage = FRAGMENT;
+       else
+               throw parse_error(tokenizer.get_location(), token, "stage identifier");
+       tokenizer.expect(")");
+
+       signal_stage_change.emit(stage);
+}
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp