]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/preprocessor.cpp
Split tokenizer and preprocessor out of the GLSL parser
[libs/gl.git] / source / glsl / preprocessor.cpp
1 #include "glsl_error.h"
2 #include "preprocessor.h"
3 #include "tokenizer.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9 namespace SL {
10
11 Preprocessor::Preprocessor(Tokenizer &t):
12         tokenizer(t)
13 { }
14
15 void Preprocessor::preprocess()
16 {
17         tokenizer.expect("#");
18
19         string token = tokenizer.peek_token();
20         if(token=="pragma")
21                 preprocess_pragma();
22         else if(token=="version")
23                 preprocess_version();
24         else if(token=="define" || token=="undef" || token=="if" || token=="ifdef" || token=="ifndef" || token=="else" ||
25                 token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="line")
26                 throw invalid_shader_source(tokenizer.get_location(), "Unsupported preprocessor directive '%s'", token);
27         else if(!token.empty())
28                 throw parse_error(tokenizer.get_location(), token, "a preprocessor directive");
29 }
30
31 void Preprocessor::preprocess_version()
32 {
33         tokenizer.expect("version");
34         string token = tokenizer.parse_token();
35         unsigned version = lexical_cast<unsigned>(token);
36         signal_version.emit(Version(version/100, version%100));
37
38         token = tokenizer.parse_token();
39         if(!token.empty())
40                 throw parse_error(tokenizer.get_location(), token, "end of line");
41 }
42
43 void Preprocessor::preprocess_pragma()
44 {
45         tokenizer.expect("pragma");
46         string token = tokenizer.parse_token();
47         if(token=="MSP")
48                 preprocess_pragma_msp();
49 }
50
51 void Preprocessor::preprocess_pragma_msp()
52 {
53         string token = tokenizer.peek_token();
54         if(token=="stage")
55                 preprocess_stage();
56         else
57                 throw invalid_shader_source(tokenizer.get_location(), "Unrecognized MSP pragma '%s'", token);
58
59         token = tokenizer.parse_token();
60         if(!token.empty())
61                 throw parse_error(tokenizer.get_location(), token, "end of line");
62 }
63
64 void Preprocessor::preprocess_stage()
65 {
66         tokenizer.expect("stage");
67         tokenizer.expect("(");
68         string token = tokenizer.parse_token();
69         StageType stage = SHARED;
70         if(token=="vertex")
71                 stage = VERTEX;
72         else if(token=="geometry")
73                 stage = GEOMETRY;
74         else if(token=="fragment")
75                 stage = FRAGMENT;
76         else
77                 throw parse_error(tokenizer.get_location(), token, "stage identifier");
78         tokenizer.expect(")");
79
80         signal_stage_change.emit(stage);
81 }
82
83 } // namespace SL
84 } // namespace GL
85 } // namespace Msp