X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramparser.cpp;h=83a2879f4feeaa92ba5e947149b45064b134ae44;hp=07fa19de655e774aa0765e5bd20f3c0d14f58d48;hb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;hpb=16a9d75c8e124a0faf89c56533792cb97a214e37 diff --git a/source/programparser.cpp b/source/programparser.cpp index 07fa19de..83a2879f 100644 --- a/source/programparser.cpp +++ b/source/programparser.cpp @@ -70,18 +70,20 @@ ProgramParser::~ProgramParser() delete module; } -Module &ProgramParser::parse(const string &s, const string &n) +Module &ProgramParser::parse(const string &s, const string &n, unsigned i) { source = s; source_name = n; + source_index = i; parse_source(); return *module; } -Module &ProgramParser::parse(IO::Base &io, const string &n) +Module &ProgramParser::parse(IO::Base &io, const string &n, unsigned i) { source = string(); source_name = n; + source_index = i; while(!io.eof()) { char buffer[4096]; @@ -341,7 +343,7 @@ bool ProgramParser::is_qualifier(const string &token) bool ProgramParser::is_builtin_type(const string &token) { - static Regex re("^(void|float|int|bool|[ib]?vec[234]|mat[234](x[234])?|sampler((1D|2D)(Array)?(Shadow)?|Cube(Shadow)?|3D))$"); + static Regex re("^(void|float|int|bool|[ib]?vec[234]|mat[234](x[234])?|sampler((1D|2D|Cube)(Array)?(Shadow)?|3D))$"); return re.match(token); } @@ -367,8 +369,10 @@ void ProgramParser::preprocess() string token = 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=="version" || token=="line") + token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="line") throw runtime_error(format_error(format("Unsupported preprocessor directive '%s'", token))); else if(!token.empty()) throw runtime_error(format_syntax_error("a preprocessor directive")); @@ -376,6 +380,18 @@ void ProgramParser::preprocess() iter = line_end; } +void ProgramParser::preprocess_version() +{ + expect("version"); + string token = parse_token(); + unsigned version = lexical_cast(token); + cur_stage->required_version = Version(version/100, version%100); + + token = parse_token(); + if(!token.empty()) + throw runtime_error(format_syntax_error("end of line")); +} + void ProgramParser::preprocess_pragma() { expect("pragma"); @@ -443,6 +459,8 @@ RefPtr ProgramParser::parse_global_declaration() if(is_interface_qualifier(token) && peek_token(1)==";") { RefPtr iface_lo = new InterfaceLayout; + iface_lo->source = source_index; + iface_lo->line = current_line; iface_lo->layout.qualifiers = layout->qualifiers; iface_lo->interface = parse_token(); expect(";"); @@ -496,6 +514,8 @@ RefPtr ProgramParser::parse_statement() else if(token=="break" || token=="continue" || token=="discard") { RefPtr jump = new Jump; + jump->source = source_index; + jump->line = current_line; jump->keyword = parse_token(); expect(";"); @@ -506,6 +526,8 @@ RefPtr ProgramParser::parse_statement() else if(!token.empty()) { RefPtr expr = new ExpressionStatement; + expr->source = source_index; + expr->line = current_line; expr->expression = parse_expression(); expect(";"); @@ -522,7 +544,9 @@ RefPtr ProgramParser::parse_import() expect("import"); RefPtr import = new Import; - import->module = parse_token(); + import->source = source_index; + import->line = current_line; + import->module = expect_identifier(); expect(";"); return import; } @@ -531,6 +555,8 @@ RefPtr ProgramParser::parse_precision() { expect("precision"); RefPtr precision = new Precision; + precision->source = source_index; + precision->line = current_line; precision->precision = parse_token(); if(!is_precision_qualifier(precision->precision)) @@ -717,6 +743,8 @@ RefPtr ProgramParser::parse_struct_declaration() { expect("struct"); RefPtr strct = new StructDeclaration; + strct->source = source_index; + strct->line = current_line; strct->name = expect_identifier(); parse_block(strct->members, true); @@ -729,6 +757,8 @@ RefPtr ProgramParser::parse_struct_declaration() RefPtr ProgramParser::parse_variable_declaration() { RefPtr var = new VariableDeclaration; + var->source = source_index; + var->line = current_line; string token = peek_token(); while(is_qualifier(token)) @@ -770,6 +800,8 @@ RefPtr ProgramParser::parse_variable_declaration() RefPtr ProgramParser::parse_function_declaration() { RefPtr func = new FunctionDeclaration; + func->source = source_index; + func->line = current_line; func->return_type = expect_type(); func->name = expect_identifier(); @@ -806,6 +838,8 @@ RefPtr ProgramParser::parse_function_declaration() RefPtr ProgramParser::parse_interface_block() { RefPtr iface = new InterfaceBlock; + iface->source = source_index; + iface->line = current_line; iface->interface = parse_token(); if(!is_interface_qualifier(iface->interface)) @@ -830,8 +864,10 @@ RefPtr ProgramParser::parse_interface_block() RefPtr ProgramParser::parse_conditional() { expect("if"); - expect("("); RefPtr cond = new Conditional; + cond->source = source_index; + cond->line = current_line; + expect("("); cond->condition = parse_expression(); expect(")"); @@ -850,8 +886,10 @@ RefPtr ProgramParser::parse_conditional() RefPtr ProgramParser::parse_for() { expect("for"); - expect("("); RefPtr loop = new Iteration; + loop->source = source_index; + loop->line = current_line; + expect("("); string token = peek_token(); if(is_type(token)) loop->init_statement = parse_statement(); @@ -880,8 +918,10 @@ RefPtr ProgramParser::parse_for() RefPtr ProgramParser::parse_while() { expect("while"); - expect("("); RefPtr loop = new Iteration; + loop->source = source_index; + loop->line = current_line; + expect("("); loop->condition = parse_expression(); expect(")"); @@ -894,6 +934,8 @@ RefPtr ProgramParser::parse_passthrough() { expect("passthrough"); RefPtr pass = new Passthrough; + pass->source = source_index; + pass->line = current_line; if(cur_stage->type==GEOMETRY) { expect("["); @@ -908,6 +950,8 @@ RefPtr ProgramParser::parse_return() { expect("return"); RefPtr ret = new Return; + ret->source = source_index; + ret->line = current_line; if(peek_token()!=";") ret->expression = parse_expression(); expect(";");