diff --git a/src/atom_finder/classifier.clj b/src/atom_finder/classifier.clj index c63b76b..9460e33 100644 --- a/src/atom_finder/classifier.clj +++ b/src/atom_finder/classifier.clj @@ -43,7 +43,7 @@ (def atoms [ - (ValidatedAtom :preprocessor-in-statement define-parent? non-toplevel-defines) + (ValidatedAtom :preprocessor-in-statement preprocessor-parent? all-non-toplevel-preprocessors) (ValidatedAtom :logic-as-control-flow logic-as-control-flow-atom? logic-as-control-flow-atoms) (ValidatedAtom :conditional conditional-atom? (default-finder conditional-atom?)) (ValidatedAtom :reversed-subscript reversed-subscript-atom? (default-finder reversed-subscript-atom?)) @@ -53,6 +53,7 @@ (ValidatedAtom :omitted-curly-braces omitted-curly-braces-atom? (default-finder omitted-curly-braces-atom?)) (ValidatedAtom :assignment-as-value assignment-as-value-atom? (default-finder assignment-as-value-atom?)) (ValidatedAtom :macro-operator-precedence macro-def-precedence-atom? macro-operator-precedence-atoms) + (ValidatedAtom :implicit-predicate implicit-predicate-atom? (default-finder implicit-predicate-atom?)) ] ) diff --git a/src/atom_finder/classifier/implicit-predicate.clj b/src/atom_finder/classifier/implicit-predicate.clj new file mode 100644 index 0000000..564d9cf --- /dev/null +++ b/src/atom_finder/classifier/implicit-predicate.clj @@ -0,0 +1,38 @@ +(in-ns 'atom-finder.classifier) +(import '(org.eclipse.cdt.core.dom.ast IASTIfStatement IASTForStatement IASTWhileStatement IASTDoStatement IASTBinaryExpression IASTUnaryExpression)) + +(def implicit-types #{IASTIfStatement IASTForStatement IASTWhileStatement IASTDoStatement IASTConditionalExpression}) +; If statement as an implicit type: C99 6.8.4.1/1 +; For/While/Do statements as implicit types: C99 6.8.5/2 +; Ternary operator as an implicit type: C99 6.5.15/1 + +(declare implicit-expression?) + +(defn remove-parentheses +[expr] +(cond + (== IASTUnaryExpression/op_not (.getOperator expr)) true + (== IASTUnaryExpression/op_bracketedPrimary (.getOperator expr)) + (not (implicit-expression? (.getOperand expr))) + :else false)) + +(defn implicit-expression? + "Does this expression have a logical operator in it?" + [expr] + (not (cond + (instance? IASTBinaryExpression expr) + (contains? logical-operators (.getOperator expr)) + (instance? IASTUnaryExpression expr) + (remove-parentheses expr) + :else false))) + +(defn implicit-predicate-atom? + "Does this AST node have an implicit predicate atom" + [node] + (cond + (instance? IASTForStatement node) (implicit-expression? (.getConditionExpression node)) + (instance? IASTIfStatement node) (implicit-expression? (.getConditionExpression node)) + (instance? IASTWhileStatement node) (implicit-expression? (.getCondition node)) + (instance? IASTDoStatement node) (implicit-expression? (.getCondition node)) + (instance? IASTConditionalExpression node) (implicit-expression? (.getLogicalConditionExpression node)) + :else false)) diff --git a/src/atom_finder/classifier_util.clj b/src/atom_finder/classifier_util.clj index c20cea8..5fd26bd 100644 --- a/src/atom_finder/classifier_util.clj +++ b/src/atom_finder/classifier_util.clj @@ -129,4 +129,13 @@ (if (or (nil? node) (instance? IASTFunctionDefinition node)) node - (enclosing-function (parent node)))) \ No newline at end of file + (enclosing-function (parent node)))) + +(def logical-operators #{IASTBinaryExpression/op_equals + IASTBinaryExpression/op_greaterEqual + IASTBinaryExpression/op_greaterThan + IASTBinaryExpression/op_lessThan + IASTBinaryExpression/op_lessEqual + IASTBinaryExpression/op_logicalAnd + IASTBinaryExpression/op_logicalOr + IASTBinaryExpression/op_notequals}) diff --git a/src/test/resources/implicit-predicate.c b/src/test/resources/implicit-predicate.c new file mode 100644 index 0000000..c127ab2 --- /dev/null +++ b/src/test/resources/implicit-predicate.c @@ -0,0 +1,43 @@ +int main() +{ + int y = 5; + + (y == 5) ? y = 5 : y == 7; + + for (int x = 4; 4 != 4; x++); + + for (int x = 5; 4 - 4; x++); // + + for (int x = 4; 4 == 4; x++); + + (y = 4) ? y : y++; // + + for (int x = 4; 8 * 9 + 4; x++); // + + if (3 < 6) + if (3 | 6); // + + if (6 & 8) // + if (2 ^ 9); // + + if (3 > 6); + + ((y != 5)) ? y : y; + + if (sizeof(34)); // + + if ((y >= 6)); + + while (y || 3) + while (y); // + + while (y <= 34); + + (((y = 2))) ? 4 : 5; // + + while (!(y && y)); + + if (!(5 == y)); + + return; +} diff --git a/test/atom_finder/classifier_test.clj b/test/atom_finder/classifier_test.clj index 07185cf..d8dcc29 100644 --- a/test/atom_finder/classifier_test.clj +++ b/test/atom_finder/classifier_test.clj @@ -151,3 +151,7 @@ (deftest test-assignment-as-value-atom? (testing "assignment-as-value-atom? finds all atoms in snippet study code" (test-atom-lines "assignment-as-value.c" "" (default-finder assignment-as-value-atom?)))) + +(deftest test-implicit-predicate-atom? + (testing "implicit-predicate-atom? finds all atoms in sample code") + (test-atom-lines "implicit-predicate.c" "" (default-finder implicit-predicate-atom?)))