Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit Predicate Atom #12

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/atom_finder/classifier.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you changing this?

(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?))
Expand All @@ -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?))
]
)

Expand Down
38 changes: 38 additions & 0 deletions src/atom_finder/classifier/implicit-predicate.clj
Original file line number Diff line number Diff line change
@@ -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))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like this function removes parentheses, it looks like applies heuristics to unary operators. If instead you made it actually remove parentheses then you wouldn't need the cyclic reference either, you could just do something like:

(->> node remove-parentheses implicit-expression?)

Also, fix your indentation.


(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))
11 changes: 10 additions & 1 deletion src/atom_finder/classifier_util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,13 @@
(if (or (nil? node)
(instance? IASTFunctionDefinition node))
node
(enclosing-function (parent node))))
(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})
43 changes: 43 additions & 0 deletions src/test/resources/implicit-predicate.c
Original file line number Diff line number Diff line change
@@ -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++); // <true>

for (int x = 4; 4 == 4; x++);

(y = 4) ? y : y++; // <true>

for (int x = 4; 8 * 9 + 4; x++); // <true>

if (3 < 6)
if (3 | 6); // <true>

if (6 & 8) // <true>
if (2 ^ 9); // <true>

if (3 > 6);

((y != 5)) ? y : y;

if (sizeof(34)); // <true>

if ((y >= 6));

while (y || 3)
while (y); // <true>

while (y <= 34);

(((y = 2))) ? 4 : 5; // <true>

while (!(y && y));

if (!(5 == y));

return;
}
4 changes: 4 additions & 0 deletions test/atom_finder/classifier_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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" "<true>" (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" "<true>" (default-finder implicit-predicate-atom?)))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add individual tests to test at the node (not line) level? See for example: https://github.com/dgopstein/atom-finder/blob/master/test/atom_finder/classifier_test.clj#L14

Then add a few tests. For example I'm curious what your code says for !1 and !1 ? 2 : 3. In theory I think the first one should be an atom, and the second one shouldn't.