X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramparser.cpp;h=ca554f427464b8863b03ed8211c0f8598e2c7c03;hp=f38f39097615c94185c0d4bf7504d70e0dc7d646;hb=56beca9d8b4f7b4edac81411d31e24df88e84ac3;hpb=684fadb0eb3e6a7dc274d6ed26abd28d5787d60d diff --git a/source/programparser.cpp b/source/programparser.cpp index f38f3909..ca554f42 100644 --- a/source/programparser.cpp +++ b/source/programparser.cpp @@ -3,6 +3,8 @@ #include #include "programparser.h" +#undef interface + using namespace std; namespace Msp { @@ -68,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]; @@ -110,7 +114,7 @@ void ProgramParser::parse_source() source_end = source.end(); current_line = 1; allow_preprocess = true; - while(RefPtr statement = parse_global_declaration()) + while(RefPtr statement = parse_global_declaration()) cur_stage->content.body.push_back(statement); } @@ -263,7 +267,7 @@ void ProgramParser::skip_comment_and_whitespace() { if(*iter=='/') comment = 0; - else + else if(*iter!='*') comment = 3; } @@ -315,7 +319,12 @@ bool ProgramParser::is_interface_qualifier(const string &token) bool ProgramParser::is_sampling_qualifier(const string &token) { - return token=="centroid"; + return (token=="centroid" || token=="sample"); +} + +bool ProgramParser::is_interpolation_qualifier(const string &token) +{ + return (token=="smooth" || token=="flat" || token=="noperspective"); } bool ProgramParser::is_precision_qualifier(const string &token) @@ -325,7 +334,11 @@ bool ProgramParser::is_precision_qualifier(const string &token) bool ProgramParser::is_qualifier(const string &token) { - return (token=="const" || is_interface_qualifier(token) || is_sampling_qualifier(token) || is_precision_qualifier(token)); + return (token=="const" || + is_interface_qualifier(token) || + is_sampling_qualifier(token) || + is_interpolation_qualifier(token) || + is_precision_qualifier(token)); } bool ProgramParser::is_builtin_type(const string &token) @@ -415,7 +428,7 @@ void ProgramParser::preprocess_stage() cur_stage = &module->stages.back(); } -RefPtr ProgramParser::parse_global_declaration() +RefPtr ProgramParser::parse_global_declaration() { allow_stage_change = true; string token = peek_token(); @@ -432,6 +445,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(";"); @@ -449,7 +464,7 @@ RefPtr ProgramParser::parse_global_declaration() else if(is_interface_qualifier(token)) { string next = peek_token(1); - if(is_type(next) || is_precision_qualifier(next)) + if(is_type(next) || is_qualifier(next)) return parse_variable_declaration(); else return parse_interface_block(); @@ -469,13 +484,15 @@ RefPtr ProgramParser::parse_global_declaration() throw runtime_error(format_syntax_error("a global declaration")); } -RefPtr ProgramParser::parse_statement() +RefPtr ProgramParser::parse_statement() { string token = peek_token(); if(token=="if") return parse_conditional(); else if(token=="for") - return parse_iteration(); + return parse_for(); + else if(token=="while") + return parse_while(); else if(token=="passthrough") return parse_passthrough(); else if(token=="return") @@ -483,6 +500,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(";"); @@ -493,6 +512,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(";"); @@ -509,7 +530,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; } @@ -518,6 +541,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)) @@ -704,6 +729,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); @@ -716,27 +743,26 @@ 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(); - if(is_sampling_qualifier(token)) - { - var->sampling = parse_token(); - token = peek_token(); - if(!is_interface_qualifier(token)) - throw runtime_error(format_syntax_error("an interface qualifier")); - } - - if(is_interface_qualifier(token)) - var->interface = parse_token(); - else if(token=="const") + while(is_qualifier(token)) { - var->constant = true; parse_token(); + if(is_interface_qualifier(token)) + var->interface = token; + else if(is_sampling_qualifier(token)) + var->sampling = token; + else if(is_interpolation_qualifier(token)) + var->interpolation = token; + else if(is_precision_qualifier(token)) + var->precision = token; + else if(token=="const") + var->constant = true; + token = peek_token(); } - if(is_precision_qualifier(token)) - var->precision = parse_token(); - var->type = expect_type(); var->name = expect_identifier(); @@ -760,6 +786,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(); @@ -796,6 +824,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)) @@ -820,8 +850,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(")"); @@ -837,24 +869,46 @@ RefPtr ProgramParser::parse_conditional() return cond; } -RefPtr ProgramParser::parse_iteration() +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(); else { - RefPtr expr = new ExpressionStatement; - expr->expression = parse_expression(); + if(token!=";") + { + RefPtr expr = new ExpressionStatement; + expr->expression = parse_expression(); + loop->init_statement = expr; + } expect(";"); - loop->init_statement = expr; } - loop->condition = parse_expression(); + if(peek_token()!=";") + loop->condition = parse_expression(); expect(";"); - loop->loop_expression = parse_expression(); + if(peek_token()!=")") + loop->loop_expression = parse_expression(); + expect(")"); + + parse_block(loop->body, false); + + return loop; +} + +RefPtr ProgramParser::parse_while() +{ + expect("while"); + RefPtr loop = new Iteration; + loop->source = source_index; + loop->line = current_line; + expect("("); + loop->condition = parse_expression(); expect(")"); parse_block(loop->body, false); @@ -866,6 +920,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("["); @@ -880,6 +936,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(";");