Skip to content

Commit

Permalink
Added support for chained comparisons in compile-time constants
Browse files Browse the repository at this point in the history
  • Loading branch information
FlatAssembler committed Apr 30, 2024
1 parent f268730 commit 67e3366
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
28 changes: 28 additions & 0 deletions TreeNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ class TreeNode {
return LispExpression;
}
virtual int interpretAsACompileTimeIntegerConstant() const {
if ((text == "<" or text == ">" or text == "<=" or text == ">=") and
children.at(0).text == text) { // Chained comparisons (`a < b < c`).
TreeNode andNode("and", lineNumber, columnNumber),
secondChild(text, lineNumber, columnNumber);
secondChild.children = {children.at(0).children.at(1), children.at(1)};
andNode.children = {children.at(0), secondChild};
return andNode.interpretAsACompileTimeIntegerConstant();
}
if (isInteger(text))
return std::stoi(text, 0, 0);
if (text == "+" and children.size() == 2)
Expand Down Expand Up @@ -206,13 +214,27 @@ class TreeNode {
if (text == "=" and children.size() == 2)
return children[0].interpretAsACompileTimeIntegerConstant() ==
children[1].interpretAsACompileTimeIntegerConstant();
if (text == "<=" and children.size() == 2)
return children[0].interpretAsACompileTimeIntegerConstant() <=
children[1].interpretAsACompileTimeIntegerConstant();
if (text == ">=" and children.size() == 2)
return children[0].interpretAsACompileTimeIntegerConstant() >=
children[1].interpretAsACompileTimeIntegerConstant();
std::cerr << "Line " << lineNumber << ", Column " << columnNumber
<< ", Interpreter error: \"" << text
<< "\" isn't a valid token in a compile-time integer constant."
<< std::endl;
return 0;
}
virtual double interpretAsACompileTimeDecimalConstant() const {
if ((text == "<" or text == ">" or text == "<=" or text == ">=") and
children.at(0).text == text) { // Chained comparisons (`a < b < c`).
TreeNode andNode("and", lineNumber, columnNumber),
secondChild(text, lineNumber, columnNumber);
secondChild.children = {children.at(0).children.at(1), children.at(1)};
andNode.children = {children.at(0), secondChild};
return andNode.interpretAsACompileTimeDecimalConstant();
}
if (isInteger(text))
return std::stoi(text, 0, 0);
if (isDecimalNumber(text))
Expand Down Expand Up @@ -305,6 +327,12 @@ class TreeNode {
if (text == "=" and children.size() == 2)
return children[0].interpretAsACompileTimeDecimalConstant() ==
children[1].interpretAsACompileTimeDecimalConstant();
if (text == "<=" and children.size() == 2)
return children[0].interpretAsACompileTimeDecimalConstant() <=
children[1].interpretAsACompileTimeDecimalConstant();
if (text == ">=" and children.size() == 2)
return children[0].interpretAsACompileTimeDecimalConstant() >=
children[1].interpretAsACompileTimeDecimalConstant();
std::cerr
<< "Line " << lineNumber << ", Column " << columnNumber
<< ", Interpreter error: \"" << text
Expand Down
3 changes: 2 additions & 1 deletion tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ void interpreterTests() {
{"0x41='A' and 0xff=255", "1"},
{"0x42='A' or 0x2b=127", "0"},
{"5/2","2" /*A simple division in a compile-time integer constant was
crashing the compiler all the way up to version v1.4.3*/}
crashing the compiler all the way up to version v1.4.3*/},
{"3 >= 2 >= 1","1"}
});
for (unsigned int i = 0; i < tests.size(); i++) {
std::string result = std::to_string(
Expand Down

0 comments on commit 67e3366

Please sign in to comment.