X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fparser.cpp;h=31f9fcb65cc7ffe4da48cacd8cc41e0c7787dba5;hp=c924606f09c018c33388b020ec23100aa5a291f4;hb=6dcf74922f46b086ad394c19fd6ce083a635b290;hpb=fd44325059d59d32d47ef3feb6d41d846f7f36f0 diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index c924606f..31f9fcb6 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -294,6 +294,8 @@ RefPtr Parser::parse_global_declaration() } else if(is_qualifier(token)) return parse_variable_declaration(); + else if(token=="virtual") + return parse_function_declaration(); else if(is_type(token)) { if(tokenizer.peek_token(2)=="(") @@ -434,8 +436,9 @@ void Parser::parse_block(Block &block, bool require_braces, RefPtr (Parser::* tokenizer.expect("}"); } -RefPtr Parser::parse_expression(unsigned precedence) +RefPtr Parser::parse_expression(const Operator *outer_oper) { + unsigned outer_precedence = (outer_oper ? outer_oper->precedence+(outer_oper->assoc==Operator::RIGHT_TO_LEFT) : 20); RefPtr left; VariableReference *left_var = 0; while(1) @@ -447,7 +450,8 @@ RefPtr Parser::parse_expression(unsigned precedence) if(token==i->token && (!left || i->type!=Operator::PREFIX) && (left || i->type!=Operator::POSTFIX)) oper = i; - if(token==";" || token==")" || token=="]" || token=="," || (oper && precedence && oper->precedence>=precedence)) + bool lower_precedence = (oper && oper->type!=Operator::PREFIX && oper->precedence>=outer_precedence); + if(token==";" || token==")" || token=="]" || token=="," || token==":" || lower_precedence) { if(left) return left; @@ -481,6 +485,8 @@ RefPtr Parser::parse_expression(unsigned precedence) } else if(oper && oper->type==Operator::BINARY) left = parse_binary(left, *oper); + else if(oper && oper->type==Operator::TERNARY) + left = parse_ternary(left, *oper); else throw parse_error(tokenizer.get_location(), token, "an operator"); left_var = 0; @@ -509,7 +515,7 @@ RefPtr Parser::parse_expression(unsigned precedence) RefPtr unary = create_node(); unary->oper = oper; tokenizer.parse_token(); - unary->expression = parse_expression(oper->precedence); + unary->expression = parse_expression(oper); left = unary; } else @@ -551,10 +557,22 @@ RefPtr Parser::parse_binary(const RefPtr &left, co tokenizer.expect("]"); } else - binary->right = parse_expression(oper.precedence+(oper.assoc==Operator::RIGHT_TO_LEFT)); + binary->right = parse_expression(&oper); return binary; } +RefPtr Parser::parse_ternary(const RefPtr &cond, const Operator &oper) +{ + RefPtr ternary = create_node(); + ternary->condition = cond; + ternary->oper = &oper; + tokenizer.expect("?"); + ternary->true_expr = parse_expression(&oper); + tokenizer.expect(":"); + ternary->false_expr = parse_expression(&oper); + return ternary; +} + RefPtr Parser::parse_function_call(const VariableReference &var) { RefPtr call = create_node(); @@ -734,6 +752,7 @@ RefPtr Parser::parse_function_declaration() { RefPtr func = create_node(); + func->virtua = check("virtual"); func->return_type = expect_type(); func->name = expect_identifier(); tokenizer.expect("("); @@ -752,6 +771,8 @@ RefPtr Parser::parse_function_declaration() } tokenizer.expect(")"); + func->overrd = check("override"); + string token = tokenizer.peek_token(); if(token=="{") { @@ -775,7 +796,8 @@ RefPtr Parser::parse_interface_block() throw parse_error(tokenizer.get_location(), iface->interface, "an interface qualifier"); iface->name = expect_identifier(); - parse_block(iface->members, true, &Parser::parse_variable_declaration_with_layout); + iface->members = new Block; + parse_block(*iface->members, true, &Parser::parse_variable_declaration_with_layout); if(!check(";")) { iface->instance_name = expect_identifier();