4646 from sympy .codegen .ast import (Variable , IntBaseType , FloatBaseType , String ,
4747 Integer , Float , FunctionPrototype , FunctionDefinition , FunctionCall ,
4848 none , Return , Assignment , Type )
49+ from sympy .codegen .cnodes import (PreDecrement , PostDecrement ,
50+ PreIncrement , PostIncrement )
4951 from sympy .core import Add , Mod , Mul , Pow , Rel
50- from sympy .logic .boolalg import And , as_Boolean , Or
52+ from sympy .logic .boolalg import And , as_Boolean , Not , Or
5153 from sympy import Symbol , sympify , true , false
5254 import sys
5355 import tempfile
@@ -287,7 +289,7 @@ def transform_var_decl(self, node):
287289 value = val
288290
289291 else :
290- raise NotImplementedError ("Only bool, int " \
292+ raise NotImplementedError ("Only bool, int "
291293 "and float are supported" )
292294
293295 elif (child .kind == cin .CursorKind .CALL_EXPR ):
@@ -298,34 +300,33 @@ def transform_var_decl(self, node):
298300 )
299301
300302 # when val is combination of more than two expr and
301- # integer(or float)
302- elif (child .kind == cin .CursorKind .BINARY_OPERATOR ):
303+ # integer(or float) i.e. it has binary operator
304+ # Or var decl has parenthesis in the rhs(as a parent Clang node)
305+ # Or it has unary operator
306+ # Or it has boolean literal on rhs i.e. true or false
307+ elif (child .kind == cin .CursorKind .BINARY_OPERATOR
308+ or child .kind == cin .CursorKind .PAREN_EXPR
309+ or child .kind == cin .CursorKind .UNARY_OPERATOR
310+ or child .kind == cin .CursorKind .CXX_BOOL_LITERAL_EXPR ):
303311 if (node .type .kind == cin .TypeKind .INT ):
304312 type = IntBaseType (String ('integer' ))
305313 elif (node .type .kind == cin .TypeKind .FLOAT ):
306314 type = FloatBaseType (String ('real' ))
307315 elif (node .type .kind == cin .TypeKind .BOOL ):
308316 type = Type (String ('bool' ))
309317 else :
310- raise NotImplementedError ("Only bool, int " \
318+ raise NotImplementedError ("Only bool, int "
311319 "and float are supported" )
312320 value = val
313321
314- elif (child .kind == cin .CursorKind .CXX_BOOL_LITERAL_EXPR ):
315- if (node .type .kind == cin .TypeKind .INT ):
316- type = IntBaseType (String ('integer' ))
317- value = Integer (val )
318- elif (node .type .kind == cin .TypeKind .FLOAT ):
319- type = FloatBaseType (String ('real' ))
320- value = Float (val )
321- elif (node .type .kind == cin .TypeKind .BOOL ):
322- type = Type (String ('bool' ))
323- value = sympify (val )
324- else :
325- raise NotImplementedError ("Only bool, int " \
326- "and float are supported" )
327322 else :
328- raise NotImplementedError ()
323+ raise NotImplementedError ("Given "
324+ "variable declaration \" {}\" "
325+ "is not possible to parse yet!"
326+ .format (" " .join (
327+ t .spelling for t in node .get_tokens ()
328+ )
329+ ))
329330
330331 except StopIteration :
331332
@@ -339,7 +340,7 @@ def transform_var_decl(self, node):
339340 type = Type (String ('bool' ))
340341 value = false
341342 else :
342- raise NotImplementedError ("Only bool, int " \
343+ raise NotImplementedError ("Only bool, int "
343344 "and float are supported" )
344345
345346 return Variable (
@@ -735,6 +736,72 @@ def transform_decl_stmt(self, node):
735736
736737 return statement
737738
739+ def transform_paren_expr (self , node ):
740+ """Transformation function for Parenthesized expressions
741+
742+ Returns the result from its children nodes
743+
744+ """
745+ return self .transform (next (node .get_children ()))
746+
747+ def transform_unary_operator (self , node ):
748+ """Transformation function for handling unary operators
749+
750+ Returns
751+ =======
752+
753+ unary_expression: Codegen AST node
754+ simplified unary expression represented as Codegen AST
755+
756+ Raises
757+ ======
758+
759+ NotImplementedError
760+ If dereferencing operator(*), address operator(&) or
761+ bitwise NOT operator(~) is encountered
762+
763+ """
764+ # supported operators list
765+ operators_list = ['+' , '-' , '++' , '--' , '!' ]
766+ tokens = [token for token in node .get_tokens ()]
767+
768+ # it can be either pre increment/decrement or any other operator from the list
769+ if tokens [0 ].spelling in operators_list :
770+ child = self .transform (next (node .get_children ()))
771+ # (decl_ref) e.g.; int a = ++b; or simply ++b;
772+ if isinstance (child , str ):
773+ if tokens [0 ].spelling == '+' :
774+ return Symbol (child )
775+ if tokens [0 ].spelling == '-' :
776+ return Mul (Symbol (child ), - 1 )
777+ if tokens [0 ].spelling == '++' :
778+ return PreIncrement (Symbol (child ))
779+ if tokens [0 ].spelling == '--' :
780+ return PreDecrement (Symbol (child ))
781+ if tokens [0 ].spelling == '!' :
782+ return Not (Symbol (child ))
783+ # e.g.; int a = -1; or int b = -(1 + 2);
784+ else :
785+ if tokens [0 ].spelling == '+' :
786+ return child
787+ if tokens [0 ].spelling == '-' :
788+ return Mul (child , - 1 )
789+ if tokens [0 ].spelling == '!' :
790+ return Not (sympify (bool (child )))
791+
792+ # it can be either post increment/decrement
793+ # since variable name is obtained in token[0].spelling
794+ elif tokens [1 ].spelling in ['++' , '--' ]:
795+ child = self .transform (next (node .get_children ()))
796+ if tokens [1 ].spelling == '++' :
797+ return PostIncrement (Symbol (child ))
798+ if tokens [1 ].spelling == '--' :
799+ return PostDecrement (Symbol (child ))
800+ else :
801+ raise NotImplementedError ("Dereferencing operator, "
802+ "Address operator and bitwise NOT operator "
803+ "have not been implemented yet!" )
804+
738805 def transform_binary_operator (self , node ):
739806 """Transformation function for handling binary operators
740807
@@ -747,9 +814,10 @@ def transform_binary_operator(self, node):
747814 Raises
748815 ======
749816
750- NotImplementedError if shift or
751- bitwise operator
752- is passed
817+ NotImplementedError
818+ If a bitwise operator or
819+ unary operator(which is a child of any binary
820+ operator in Clang AST) is encountered
753821
754822 """
755823 # get all the tokens of assignment
@@ -782,8 +850,13 @@ def transform_binary_operator(self, node):
782850 # keep adding the expression to the
783851 # combined variables stack unless
784852 # '(' is found
785- while (len ( operators_stack ) != 0
853+ while (operators_stack
786854 and operators_stack [- 1 ] != '(' ):
855+ if len (combined_variables_stack ) < 2 :
856+ raise NotImplementedError (
857+ "Unary operators as a part of "
858+ "binary operators is not "
859+ "supported yet!" )
787860 rhs = combined_variables_stack .pop ()
788861 lhs = combined_variables_stack .pop ()
789862 operator = operators_stack .pop ()
@@ -796,11 +869,15 @@ def transform_binary_operator(self, node):
796869
797870 # token is an operator (supported)
798871 elif token .spelling in operators_list :
799- while (len ( operators_stack ) != 0
872+ while (operators_stack
800873 and self .priority_of (token .spelling )
801874 <= self .priority_of (
802875 operators_stack [- 1 ])):
803-
876+ if len (combined_variables_stack ) < 2 :
877+ raise NotImplementedError (
878+ "Unary operators as a part of "
879+ "binary operators is not "
880+ "supported yet!" )
804881 rhs = combined_variables_stack .pop ()
805882 lhs = combined_variables_stack .pop ()
806883 operator = operators_stack .pop ()
@@ -810,11 +887,16 @@ def transform_binary_operator(self, node):
810887
811888 # push current operator
812889 operators_stack .append (token .spelling )
813- else :
890+
891+ # token is a bitwise operator
892+ elif token .spelling in ['&' , '|' , '^' , '<<' , '>>' ]:
814893 raise NotImplementedError (
815- "Shift operator " \
816- "and bitwise operator are not " \
894+ "Bitwise operator has not been "
817895 "implemented yet!" )
896+ else :
897+ raise NotImplementedError (
898+ "Given token {} is not implemented yet!"
899+ .format (token .spelling ))
818900
819901 # token is an identifier(variable)
820902 elif token .kind == cin .TokenKind .IDENTIFIER :
@@ -832,10 +914,17 @@ def transform_binary_operator(self, node):
832914 combined_variables_stack .append (
833915 [token .spelling , 'boolean' ])
834916 else :
835- raise NotImplementedError ()
917+ raise NotImplementedError (
918+ "Given token {} is not implemented yet!"
919+ .format (token .spelling ))
836920
837921 # process remaining operators
838- while (len (operators_stack ) != 0 ):
922+ while operators_stack :
923+ if len (combined_variables_stack ) < 2 :
924+ raise NotImplementedError (
925+ "Unary operators as a part of "
926+ "binary operators is not "
927+ "supported yet!" )
839928 rhs = combined_variables_stack .pop ()
840929 lhs = combined_variables_stack .pop ()
841930 operator = operators_stack .pop ()
0 commit comments