Skip to content

Commit 97ac532

Browse files
committed
chore: Update parseDirective to return ParsedDirective variant
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 2c6b24c commit 97ac532

File tree

1 file changed

+80
-30
lines changed

1 file changed

+80
-30
lines changed

src/parser/cxx/preprocessor.cc

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,13 @@
2626
#include <cxx/diagnostics_client.h>
2727
#include <cxx/lexer.h>
2828
#include <cxx/literals.h>
29+
#include <cxx/preprocessor.h>
2930
#include <cxx/private/path.h>
30-
31-
// fmt
32-
#include <format>
33-
34-
// utf8
3531
#include <utf8/unchecked.h>
3632

37-
// stl
38-
#include <cxx/preprocessor.h>
39-
4033
#include <algorithm>
4134
#include <cassert>
35+
#include <format>
4236
#include <forward_list>
4337
#include <fstream>
4438
#include <functional>
@@ -1167,8 +1161,15 @@ struct Preprocessor::Private {
11671161
TokList *loc = nullptr;
11681162
};
11691163

1164+
struct ParsedIfDirective {
1165+
std::function<void()> resume;
1166+
};
1167+
1168+
using ParsedDirective =
1169+
std::variant<std::monostate, ParsedIncludeDirective, ParsedIfDirective>;
1170+
11701171
[[nodiscard]] auto parseDirective(SourceFile *source, TokList *start)
1171-
-> std::optional<ParsedIncludeDirective>;
1172+
-> ParsedDirective;
11721173

11731174
[[nodiscard]] auto parseIncludeDirective(TokList *directive, TokList *ts)
11741175
-> std::optional<ParsedIncludeDirective>;
@@ -1203,7 +1204,9 @@ struct Preprocessor::Private {
12031204
[[nodiscard]] auto copyLine(TokList *ts, bool inMacroBody = false)
12041205
-> TokList *;
12051206

1206-
[[nodiscard]] auto constantExpression(TokList *ts) -> long;
1207+
[[nodiscard]] auto prepareConstantExpression(TokList *ts) -> TokList *;
1208+
1209+
[[nodiscard]] auto evaluateConstantExpression(TokList *ts) -> long;
12071210
[[nodiscard]] auto conditionalExpression(TokList *&ts) -> long;
12081211
[[nodiscard]] auto binaryExpression(TokList *&ts) -> long;
12091212
[[nodiscard]] auto binaryExpressionHelper(TokList *&ts, long lhs, int minPrec)
@@ -1672,7 +1675,10 @@ auto Preprocessor::Private::expand(
16721675
// skip the rest of the line
16731676
it = skipLine(it, last);
16741677

1675-
if (auto parsedInclude = parseDirective(source, start.toTokList())) {
1678+
auto parsedDirective = parseDirective(source, start.toTokList());
1679+
1680+
if (auto parsedInclude =
1681+
std::get_if<ParsedIncludeDirective>(&parsedDirective)) {
16761682
NeedToResolveInclude status{
16771683
.preprocessor = *preprocessor_,
16781684
.include = parsedInclude->header,
@@ -1692,6 +1698,10 @@ auto Preprocessor::Private::expand(
16921698
it = last;
16931699

16941700
return status;
1701+
} else if (auto directive =
1702+
std::get_if<ParsedIfDirective>(&parsedDirective)) {
1703+
// suspend and resolve the dependencies
1704+
directive->resume();
16951705
}
16961706
} else if (skipping) {
16971707
it = skipLine(++it, last);
@@ -1707,10 +1717,10 @@ auto Preprocessor::Private::expand(
17071717
}
17081718

17091719
auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
1710-
-> std::optional<ParsedIncludeDirective> {
1720+
-> ParsedDirective {
17111721
auto directive = start->next;
17121722

1713-
if (!lookat(directive, TokenKind::T_IDENTIFIER)) return std::nullopt;
1723+
if (!lookat(directive, TokenKind::T_IDENTIFIER)) return std::monostate{};
17141724

17151725
dependencies_.clear();
17161726

@@ -1725,7 +1735,11 @@ auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
17251735
case PreprocessorDirectiveKind::T_INCLUDE_NEXT:
17261736
case PreprocessorDirectiveKind::T_INCLUDE: {
17271737
if (skipping) break;
1728-
return parseIncludeDirective(directive, ts);
1738+
auto includeDirective = parseIncludeDirective(directive, ts);
1739+
if (includeDirective.has_value()) {
1740+
return *includeDirective;
1741+
}
1742+
break;
17291743
}
17301744

17311745
case PreprocessorDirectiveKind::T_DEFINE: {
@@ -1781,12 +1795,25 @@ auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
17811795
if (skipping) {
17821796
pushState(std::tuple(true, false));
17831797
} else {
1784-
const auto value = constantExpression(ts);
1785-
if (value) {
1786-
pushState(std::tuple(skipping, false));
1787-
} else {
1788-
pushState(std::tuple(true, !skipping));
1789-
}
1798+
auto expression = prepareConstantExpression(ts);
1799+
1800+
auto resume = [=, this] {
1801+
// evaluate the deps
1802+
for (auto &d : dependencies_) {
1803+
auto resolved = resolve(d.include, d.isIncludeNext);
1804+
d.value = resolved.has_value();
1805+
}
1806+
1807+
const auto value = evaluateConstantExpression(expression);
1808+
1809+
if (value) {
1810+
pushState(std::tuple(skipping, false));
1811+
} else {
1812+
pushState(std::tuple(true, !skipping));
1813+
}
1814+
};
1815+
1816+
return ParsedIfDirective{.resume = std::move(resume)};
17901817
}
17911818

17921819
break;
@@ -1796,12 +1823,25 @@ auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
17961823
if (!evaluating) {
17971824
setState(std::tuple(true, false));
17981825
} else {
1799-
const auto value = constantExpression(ts);
1800-
if (value) {
1801-
setState(std::tuple(!evaluating, false));
1802-
} else {
1803-
setState(std::tuple(true, evaluating));
1804-
}
1826+
auto expression = prepareConstantExpression(ts);
1827+
1828+
auto resume = [=, this] {
1829+
// evaluate the deps
1830+
for (auto &d : dependencies_) {
1831+
auto resolved = resolve(d.include, d.isIncludeNext);
1832+
d.value = resolved.has_value();
1833+
}
1834+
1835+
const auto value = evaluateConstantExpression(expression);
1836+
1837+
if (value) {
1838+
setState(std::tuple(!evaluating, false));
1839+
} else {
1840+
setState(std::tuple(true, evaluating));
1841+
}
1842+
};
1843+
1844+
return ParsedIfDirective{.resume = std::move(resume)};
18051845
}
18061846

18071847
break;
@@ -1899,7 +1939,7 @@ auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
18991939
break;
19001940
} // switch
19011941

1902-
return std::nullopt;
1942+
return std::monostate{};
19031943
}
19041944

19051945
auto Preprocessor::Private::parseIncludeDirective(TokList *directive,
@@ -2348,18 +2388,28 @@ auto Preprocessor::Private::copyLine(TokList *ts, bool inMacroBody)
23482388
return line;
23492389
}
23502390

2351-
auto Preprocessor::Private::constantExpression(TokList *ts) -> long {
2391+
auto Preprocessor::Private::prepareConstantExpression(TokList *ts)
2392+
-> TokList * {
23522393
auto line = copyLine(ts);
2394+
23532395
dependencies_.clear();
2396+
23542397
auto it = expandTokens(TokIterator{line}, TokIterator{},
23552398
/*inConditionalExpression*/ true);
2399+
2400+
auto expression = it.toTokList();
2401+
2402+
return expression;
2403+
}
2404+
2405+
auto Preprocessor::Private::evaluateConstantExpression(TokList *ts) -> long {
23562406
// evaluate the deps
23572407
for (auto &d : dependencies_) {
23582408
auto resolved = resolve(d.include, d.isIncludeNext);
23592409
d.value = resolved.has_value();
23602410
}
2361-
auto e = it.toTokList();
2362-
return conditionalExpression(e);
2411+
2412+
return conditionalExpression(ts);
23632413
}
23642414

23652415
auto Preprocessor::Private::conditionalExpression(TokList *&ts) -> long {

0 commit comments

Comments
 (0)