From d430b3995ab6656e9f050e9eb55442b27ace1129 Mon Sep 17 00:00:00 2001 From: LuisHsu Date: Thu, 21 Mar 2024 01:50:51 -0700 Subject: [PATCH] [PP] Conditional expression --- src/include/PreProcessor.hpp | 2 +- src/lib/PreProcessor/Expression.cpp | 32 ++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/include/PreProcessor.hpp b/src/include/PreProcessor.hpp index 9e15e07..74bacdf 100644 --- a/src/include/PreProcessor.hpp +++ b/src/include/PreProcessor.hpp @@ -91,7 +91,7 @@ struct PreProcessor { Result bitwise_inclusive_OR(); Result logical_AND(); Result logical_OR(); - Result conditional(); // TODO: + Result conditional(); template struct lshift { diff --git a/src/lib/PreProcessor/Expression.cpp b/src/lib/PreProcessor/Expression.cpp index 062a7ad..12570a2 100644 --- a/src/lib/PreProcessor/Expression.cpp +++ b/src/lib/PreProcessor/Expression.cpp @@ -107,7 +107,7 @@ PreProcessor::Expression::Result PreProcessor::Expression::relation_op(PreProces } PreProcessor::Expression::Result PreProcessor::Expression::eval(){ - return logical_OR(); // TODO: + return conditional(); // TODO: } PreProcessor::Expression::Result PreProcessor::Expression::primary(){ @@ -421,4 +421,34 @@ PreProcessor::Expression::Result PreProcessor::Expression::logical_OR(){ } } return res; +} + +PreProcessor::Expression::Result PreProcessor::Expression::conditional(){ + PreProcessor::Expression::Result cond = logical_OR(); + Line::iterator head = skip_whitespace(cur, end); + cur = head; + if(cur != end && cur->hold()){ + TokenType::Punctuator punct = cur->value(); + if(punct.type == TokenType::Punctuator::Query){ + cur = std::next(cur); + PreProcessor::Expression::Result operand_true = eval(); + if(cur != end && cur->hold() && ((TokenType::Punctuator)cur->value()).type == TokenType::Punctuator::Colon){ + cur = std::next(cur); + PreProcessor::Expression::Result operand_false = conditional(); + implicit_cast(operand_true, operand_false); + if(std::visit(overloaded { + [](auto val){ + return val != 0; + } + }, cond)){ + return operand_true; + }else{ + return operand_false; + } + }else{ + throw Exception::Error(head->value().pos, "missing ':' in conditional expression"); + } + } + } + return cond; } \ No newline at end of file