tokenizer.expect("}");
}
-RefPtr<Expression> Parser::parse_expression(unsigned precedence)
+RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
{
+ unsigned outer_precedence = (outer_oper ? outer_oper->precedence+(outer_oper->assoc==Operator::RIGHT_TO_LEFT) : 20);
RefPtr<Expression> left;
VariableReference *left_var = 0;
while(1)
if(token==i->token && (!left || i->type!=Operator::PREFIX) && (left || i->type!=Operator::POSTFIX))
oper = i;
- bool lower_precedence = (oper && oper->type!=Operator::PREFIX && precedence && oper->precedence>=precedence);
- if(token==";" || token==")" || token=="]" || token=="," || lower_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;
}
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;
RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
unary->oper = oper;
tokenizer.parse_token();
- unary->expression = parse_expression(oper->precedence);
+ unary->expression = parse_expression(oper);
left = unary;
}
else
tokenizer.expect("]");
}
else
- binary->right = parse_expression(oper.precedence+(oper.assoc==Operator::RIGHT_TO_LEFT));
+ binary->right = parse_expression(&oper);
return binary;
}
+RefPtr<TernaryExpression> Parser::parse_ternary(const RefPtr<Expression> &cond, const Operator &oper)
+{
+ RefPtr<TernaryExpression> ternary = create_node<TernaryExpression>();
+ 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<FunctionCall> Parser::parse_function_call(const VariableReference &var)
{
RefPtr<FunctionCall> call = create_node<FunctionCall>();