Changeset 7b1dcf9 in sasmodels
- Timestamp:
- Dec 18, 2017 4:36:32 PM (7 years ago)
- Children:
- 2694cb8
- Parents:
- 67cc0ff
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/py2c.py
r8224d24 r7b1dcf9 81 81 BOOLOP_SYMBOLS = {} 82 82 BOOLOP_SYMBOLS[ast.And] = '&&' 83 BOOLOP_SYMBOLS[ast.Or] 83 BOOLOP_SYMBOLS[ast.Or] = '||' 84 84 85 85 CMPOP_SYMBOLS = {} 86 CMPOP_SYMBOLS[ast.Eq] 86 CMPOP_SYMBOLS[ast.Eq] = '==' 87 87 CMPOP_SYMBOLS[ast.NotEq] = '!=' 88 88 CMPOP_SYMBOLS[ast.Lt] = '<' … … 145 145 self.new_lines = 0 146 146 self.c_proc = [] 147 # for C147 # for C 148 148 self.signature_line = 0 149 149 self.arguments = [] … … 181 181 def add_c_line(self, x): 182 182 string = '' 183 for iin range(self.indentation):183 for _ in range(self.indentation): 184 184 string += (" ") 185 185 string += str(x) … … 188 188 189 189 def add_current_line(self): 190 if (len(self.current_statement) > 0):190 if self.current_statement: 191 191 self.add_c_line(self.current_statement) 192 192 self.current_statement = '' 193 193 194 194 def AddUniqueVar(self, new_var): 195 if ((new_var not in self.C_Vars)):195 if new_var not in self.C_Vars: 196 196 self.C_Vars.append(str(new_var)) 197 197 … … 210 210 self.write_c('# line: %s' % node.lineno) 211 211 self.new_lines = 1 212 if (len(self.current_statement)):212 if self.current_statement: 213 213 self.Statements.append(self.current_statement) 214 214 self.current_statement = '' 215 215 216 216 def body(self, statements): 217 if (len(self.current_statement)):217 if self.current_statement: 218 218 self.add_current_line() 219 219 self.new_line = True 220 220 self.indentation += 1 221 221 for stmt in statements: 222 target_name = '' 223 if(hasattr(stmt, 'targets')): 224 if(hasattr(stmt.targets[0], 'id')): 225 target_name = stmt.targets[0].id # target name needed for debug only 222 #if hasattr(stmt, 'targets') and hasattr(stmt.targets[0], 'id'): 223 # target_name = stmt.targets[0].id # target name needed for debug only 226 224 self.visit(stmt) 227 225 self.add_current_line() # just for breaking point. to be deleted. … … 242 240 else: 243 241 want_comma.append(True) 244 # for C 242 243 # for C 245 244 for arg in node.args: 246 245 # CRUFT: 2.7 uses arg.id, 3.x uses arg.arg … … 254 253 for arg, default in zip(node.args, padding + node.defaults): 255 254 if default is not None: 256 # CRUFT: 2.7 uses arg.id, 3.x uses arg.arg257 255 # CRUFT: 2.7 uses arg.id, 3.x uses arg.arg 258 256 try: … … 281 279 282 280 def define_C_Vars(self, target): 283 if (hasattr(target, 'id')):284 # a variable is considered an array if it apears in the agrument list285 # and being assigned to. For example, the variable p in the following286 # sniplet is a pointer, while q is not287 # def somefunc(p, q):288 # p = q + 1289 # return290 #291 if (target.id not in self.C_Vars):292 if (target.id in self.arguments):281 if hasattr(target, 'id'): 282 # a variable is considered an array if it apears in the agrument list 283 # and being assigned to. For example, the variable p in the following 284 # sniplet is a pointer, while q is not 285 # def somefunc(p, q): 286 # p = q + 1 287 # return 288 # 289 if target.id not in self.C_Vars: 290 if target.id in self.arguments: 293 291 idx = self.arguments.index(target.id) 294 292 new_target = self.arguments[idx] + "[0]" 295 if (new_target not in self.C_Pointers):293 if new_target not in self.C_Pointers: 296 294 target.id = new_target 297 295 self.C_Pointers.append(self.arguments[idx]) … … 301 299 def add_semi_colon(self): 302 300 semi_pos = self.current_statement.find(';') 303 if (semi_pos > 0.0):304 self.current_statement = self.current_statement.replace(';', '')301 if semi_pos > 0.0: 302 self.current_statement = self.current_statement.replace(';', '') 305 303 self.write_c(';') 306 304 … … 312 310 self.define_C_Vars(target) 313 311 self.visit(target) 314 if (len(self.Tuples) > 0):312 if self.Tuples: 315 313 tplTargets = list(self.Tuples) 316 314 del self.Tuples[:] … … 327 325 self.add_semi_colon() 328 326 self.add_current_line() 329 if ((self.is_sequence) and (not self.visited_args)):327 if self.is_sequence and not self.visited_args: 330 328 for target in node.targets: 331 if (hasattr(target, 'id')):332 if ((target.id in self.C_Vars) and(target.id not in self.C_DclPointers)):333 if (target.id not in self.C_DclPointers):329 if hasattr(target, 'id'): 330 if target.id in self.C_Vars and target.id not in self.C_DclPointers: 331 if target.id not in self.C_DclPointers: 334 332 self.C_DclPointers.append(target.id) 335 if (target.id in self.C_Vars):333 if target.id in self.C_Vars: 336 334 self.C_Vars.remove(target.id) 337 335 self.current_statement = '' 338 336 339 337 def visit_AugAssign(self, node): 340 if (node.target.id not in self.C_Vars):341 if (node.target.id not in self.arguments):338 if node.target.id not in self.C_Vars: 339 if node.target.id not in self.arguments: 342 340 self.C_Vars.append(node.target.id) 343 341 self.visit(node.target) … … 365 363 self.generic_visit(node) 366 364 367 def listToDeclare(self, Vars): 368 s = '' 369 if(len(Vars) > 0): 370 s = ",".join(Vars) 371 return(s) 365 def listToDeclare(self, vars): 366 return ", ".join(vars) 372 367 373 368 def write_C_Pointers(self, start_var): 374 if (len(self.C_DclPointers) > 0):375 var s = ""369 if self.C_DclPointers: 370 var_list = [] 376 371 for c_ptr in self.C_DclPointers: 377 372 if(len(vars) > 0): 378 373 vars += ", " 379 if(c_ptr not in self.arguments): 380 vars += "*" + c_ptr 381 if(c_ptr in self.C_Vars): 382 if(c_ptr in self.C_Vars): 383 self.C_Vars.remove(c_ptr) 384 if(len(vars) > 0): 385 c_dcl = " double " + vars + ";" 386 self.c_proc.insert(start_var, c_dcl + "\n") 374 if c_ptr not in self.arguments: 375 var_list.append("*" + c_ptr) 376 if c_ptr in self.C_Vars: 377 self.C_Vars.remove(c_ptr) 378 if var_list: 379 c_dcl = " double " + ", ".join(var_list) + ";\n" 380 self.c_proc.insert(start_var, c_dcl) 387 381 start_var += 1 388 382 return start_var … … 391 385 fLine = False 392 386 start_var = self.write_C_Pointers(start_var) 393 if (len(self.C_IntVars) > 0):387 if self.C_IntVars: 394 388 for var in self.C_IntVars: 395 if (var in self.C_Vars):389 if var in self.C_Vars: 396 390 self.C_Vars.remove(var) 397 391 s = self.listToDeclare(self.C_IntVars) … … 400 394 start_var += 1 401 395 402 if (len(self.C_Vars) > 0):396 if self.C_Vars: 403 397 s = self.listToDeclare(self.C_Vars) 404 398 self.c_proc.insert(start_var, " double " + s + ";\n") 405 399 fLine = True 406 400 start_var += 1 407 if(len(self.C_Vectors) > 0): 401 402 if self.C_Vectors: 408 403 s = self.listToDeclare(self.C_Vectors) 409 404 for n in range(len(self.C_Vectors)): … … 412 407 self.c_proc.insert(start_var, c_dcl + "\n") 413 408 start_var += 1 409 414 410 del self.C_Vars[:] 415 411 del self.C_IntVars[:] … … 417 413 del self.C_Pointers[:] 418 414 self.C_DclPointers 419 if (fLine == True):415 if fLine: 420 416 self.c_proc.insert(start_var, "\n") 421 return422 s = ''423 for n in range(len(self.C_Vars)):424 s += str(self.C_Vars[n])425 if n < len(self.C_Vars) - 1:426 s += ", "427 if(len(s) > 0):428 self.c_proc.insert(start_var, " double " + s + ";\n")429 self.c_proc.insert(start_var + 1, "\n")430 431 def ListToString(self, strings):432 s = ''433 for n in range(len(strings)):434 s += strings[n]435 if(n < (len(strings) - 1)):436 s += ", "437 return(s)438 439 def getMethodSignature(self):440 args_str = ''441 for n in range(len(self.arguments)):442 args_str += "double " + self.arguments[n]443 if(n < (len(self.arguments) - 1)):444 args_str += ", "445 return(args_str)446 417 447 418 def InsertSignature(self): 448 arg s_str = ''449 for n in range(len(self.arguments)):450 args_str += "double " + self.arguments[n]451 if (self.arguments[n] in self.C_Pointers):452 args_str+= "[]"453 if(n < (len(self.arguments) - 1)):454 args_str += ", "419 arg_decls = [] 420 for arg in self.arguments: 421 decl = "double " + arg 422 if arg in self.C_Pointers: 423 decl += "[]" 424 arg_decls.append(decl) 425 args_str = ", ".join(arg_decls) 455 426 self.strMethodSignature = 'double ' + self.name + '(' + args_str + ")" 456 if (self.signature_line >= 0):427 if self.signature_line >= 0: 457 428 self.c_proc.insert(self.signature_line, self.strMethodSignature) 458 429 … … 463 434 self.arguments = [] 464 435 self.name = node.name 465 print("Parsing '" + self.name + "'") 466 args_str = "" 436 #if self.name not in self.required_functions[0]: 437 # return 438 #print("Parsing '" + self.name + "'") 467 439 468 440 self.visit(node.args) 469 self.getMethodSignature()441 # for C 470 442 self.signature_line = len(self.c_proc) 443 #self.add_c_line(self.strMethodSignature) 471 444 self.add_c_line("\n{") 472 445 start_vars = len(self.c_proc) + 1 … … 493 466 paren_or_comma() 494 467 self.visit(base) 495 # XXX: the if here is used to keep this module compatible 496 # with python 2.6. 468 # CRUFT: python 2.6 does not have "keywords" attribute 497 469 if hasattr(node, 'keywords'): 498 470 for keyword in node.keywords: … … 521 493 if len(else_) == 0: 522 494 break 523 #elif hasattr(else_, 'orelse'):495 #elif hasattr(else_, 'orelse'): 524 496 elif len(else_) == 1 and isinstance(else_[0], ast.If): 525 497 node = else_[0] 526 #self.newline()498 #self.newline() 527 499 self.write_c('else if ') 528 500 self.visit(node.test) … … 531 503 self.add_current_line() 532 504 self.add_c_line('}') 533 #break505 #break 534 506 else: 535 507 self.newline() … … 541 513 def getNodeLineNo(self, node): 542 514 line_number = -1 543 if (hasattr(node,'value')):515 if hasattr(node, 'value'): 544 516 line_number = node.value.lineno 545 517 elif hasattr(node, 'iter'): 546 518 if hasattr(node.iter, 'lineno'): 547 519 line_number = node.iter.lineno 548 return (line_number)520 return line_number 549 521 550 522 def GetNodeAsString(self, node): 551 523 res = '' 552 if (hasattr(node, 'n')):524 if hasattr(node, 'n'): 553 525 res = str(node.n) 554 elif (hasattr(node, 'id')):526 elif hasattr(node, 'id'): 555 527 res = node.id 556 return (res)528 return res 557 529 558 530 def GetForRange(self, node): … … 568 540 self.current_statement = '' 569 541 self.current_statement = temp_statement 570 if (len(for_args) == 1):542 if len(for_args) == 1: 571 543 stop = for_args[0] 572 elif (len(for_args) == 2):544 elif len(for_args) == 2: 573 545 start = for_args[0] 574 546 stop = for_args[1] 575 elif (len(for_args) == 3):547 elif len(for_args) == 3: 576 548 start = for_args[0] 577 549 stop = for_args[1] … … 579 551 else: 580 552 raise("Ilegal for loop parameters") 581 return (start, stop, step)553 return start, stop, step 582 554 583 555 def visit_For(self, node): 584 # node: for iterator is stored in node.target.585 # Iterator name is in node.target.id.556 # node: for iterator is stored in node.target. 557 # Iterator name is in node.target.id. 586 558 self.add_current_line() 587 559 fForDone = False 588 560 self.current_statement = '' 589 if (hasattr(node.iter, 'func')):590 if (hasattr(node.iter.func, 'id')):591 if (node.iter.func.id == 'range'):561 if hasattr(node.iter, 'func'): 562 if hasattr(node.iter.func, 'id'): 563 if node.iter.func.id == 'range': 592 564 self.visit(node.target) 593 565 iterator = self.current_statement 594 566 self.current_statement = '' 595 if (iterator not in self.C_IntVars):567 if iterator not in self.C_IntVars: 596 568 self.C_IntVars.append(iterator) 597 569 start, stop, step = self.GetForRange(node) 598 self.write_c("for(" + iterator + "=" + str(start) + \599 " ; " + iterator + " < " + str(stop) + \600 570 self.write_c("for(" + iterator + "=" + str(start) + 571 " ; " + iterator + " < " + str(stop) + 572 " ; " + iterator + " += " + str(step) + ") {") 601 573 self.body_or_else(node) 602 574 self.write_c("}") 603 575 fForDone = True 604 if (fForDone == False):576 if not fForDone: 605 577 line_number = self.getNodeLineNo(node) 606 578 self.current_statement = '' … … 636 608 637 609 def visit_Print(self, node): 638 # XXX: python 2.6 only610 # CRUFT: python 2.6 only 639 611 self.newline(node) 640 612 self.write_c('print ') … … 704 676 705 677 def visit_Raise(self, node): 706 # XXX: Python 2.6 / 3.0 compatibility678 # CRUFT: Python 2.6 / 3.0 compatibility 707 679 self.newline(node) 708 680 self.write_python('raise') … … 738 710 else: 739 711 want_comma.append(True) 740 if (hasattr(node.func, 'id')):741 if (node.func.id not in self.C_Functions):712 if hasattr(node.func, 'id'): 713 if node.func.id not in self.C_Functions: 742 714 self.C_Functions.append(node.func.id) 743 if (node.func.id == 'abs'):715 if node.func.id == 'abs': 744 716 self.write_c("fabs ") 745 elif (node.func.id == 'int'):717 elif node.func.id == 'int': 746 718 self.write_c('(int) ') 747 elif (node.func.id == "SINCOS"):719 elif node.func.id == "SINCOS": 748 720 self.WriteSincos(node) 749 721 return … … 776 748 def visit_Name(self, node): 777 749 self.write_c(node.id) 778 if ((node.id in self.C_Pointers) and(not self.SubRef)):750 if node.id in self.C_Pointers and not self.SubRef: 779 751 self.write_c("[0]") 780 752 name = "" 781 753 sub = node.id.find("[") 782 if (sub > 0):754 if sub > 0: 783 755 name = node.id[0:sub].strip() 784 756 else: 785 757 name = node.id 786 #add variable to C_Vars if it ins't there yet, not an argument and not a number787 if ( (name not in self.C_Functions) and (name not in self.C_Vars) and \788 (name not in self.C_IntVars) and (name not in self.arguments) and \789 (name not in self.C_Constants) and (name.isdigit() == False)):790 if (self.InSubscript):758 # add variable to C_Vars if it ins't there yet, not an argument and not a number 759 if (name not in self.C_Functions and name not in self.C_Vars and 760 name not in self.C_IntVars and name not in self.arguments and 761 name not in self.C_Constants and not name.isdigit()): 762 if self.InSubscript: 791 763 self.C_IntVars.append(node.id) 792 764 else: … … 814 786 s = "" 815 787 for idx, item in enumerate(node.elts): 816 if ((idx > 0) and(len(s) > 0)):788 if idx > 0 and s: 817 789 s += ', ' 818 if (hasattr(item, 'id')):790 if hasattr(item, 'id'): 819 791 s += item.id 820 elif (hasattr(item, 'n')):792 elif hasattr(item, 'n'): 821 793 s += str(item.n) 822 if (len(s) > 0):794 if s: 823 795 self.C_Vectors.append(s) 824 796 vec_name = "vec" + str(len(self.C_Vectors)) 825 797 self.write_c(vec_name) 826 vec_name += "#"827 798 return visit 828 799 … … 844 815 function_name = '' 845 816 is_negative_exp = False 846 if (isevaluable(str(self.current_statement))):817 if isevaluable(str(self.current_statement)): 847 818 exponent = eval(string) 848 819 is_negative_exp = exponent < 0 849 820 abs_exponent = abs(exponent) 850 if (abs_exponent == 2):821 if abs_exponent == 2: 851 822 function_name = "square" 852 elif (abs_exponent == 3):823 elif abs_exponent == 3: 853 824 function_name = "cube" 854 elif (abs_exponent == 0.5):825 elif abs_exponent == 0.5: 855 826 function_name = "sqrt" 856 elif (abs_exponent == 1.0/3.0):827 elif abs_exponent == 1.0/3.0: 857 828 function_name = "cbrt" 858 if (function_name == ''):829 if function_name == '': 859 830 function_name = "pow" 860 831 return function_name, is_negative_exp 861 832 862 833 def translate_power(self, node): 863 # get exponent by visiting the right hand argument.834 # get exponent by visiting the right hand argument. 864 835 function_name = "pow" 865 836 temp_statement = self.current_statement 866 # 'visit' functions write the results to the 'current_statement' class memnber867 # Here, a temporary variable, 'temp_statement', is used, that enables the868 # use of the 'visit' function837 # 'visit' functions write the results to the 'current_statement' class memnber 838 # Here, a temporary variable, 'temp_statement', is used, that enables the 839 # use of the 'visit' function 869 840 self.current_statement = '' 870 841 self.visit(node.right) … … 872 843 function_name, is_negative_exp = self.get_special_power(self.current_statement) 873 844 self.current_statement = temp_statement 874 if (is_negative_exp):845 if is_negative_exp: 875 846 self.write_c("1.0 /(") 876 847 self.write_c(function_name + "(") 877 848 self.visit(node.left) 878 if (function_name == "pow"):849 if function_name == "pow": 879 850 self.write_c(", ") 880 851 self.visit(node.right) 881 852 self.write_c(")") 882 if (is_negative_exp):853 if is_negative_exp: 883 854 self.write_c(")") 884 855 self.write_c(" ") … … 893 864 def visit_BinOp(self, node): 894 865 self.write_c("(") 895 if ('%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.Pow]):866 if '%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.Pow]: 896 867 self.translate_power(node) 897 elif ('%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.FloorDiv]):868 elif '%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.FloorDiv]: 898 869 self.translate_integer_divide(node) 899 870 else: … … 903 874 self.write_c(")") 904 875 905 #for C876 # for C 906 877 def visit_BoolOp(self, node): 907 878 self.write_c('(') … … 930 901 931 902 def visit_Subscript(self, node): 932 if (node.value.id not in self.C_Constants):933 if (node.value.id not in self.C_Pointers):903 if node.value.id not in self.C_Constants: 904 if node.value.id not in self.C_Pointers: 934 905 self.C_Pointers.append(node.value.id) 935 906 self.SubRef = True … … 980 951 self.visit(comprehension) 981 952 self.write_c(right) 982 #self.write_python(right)953 #self.write_python(right) 983 954 return visit 984 955 … … 1009 980 1010 981 def visit_Repr(self, node): 1011 # XXX: python 2.6 only982 # CRUFT: python 2.6 only 1012 983 self.write_c('`') 1013 984 self.visit(node.value) … … 1025 996 self.visit(node.target) 1026 997 self.write_C(' in ') 1027 #self.write_python(' in ')998 #self.write_python(' in ') 1028 999 self.visit(node.iter) 1029 1000 if node.ifs: … … 1060 1031 return snippets 1061 1032 1062 def get_file_names(): 1063 fname_in = "" 1064 fname_out = "" 1065 if(len(sys.argv) > 1): 1066 fname_in = sys.argv[1] 1067 fname_base = os.path.splitext(fname_in) 1068 if(len(sys.argv) == 2): 1069 fname_out = str(fname_base[0]) + '.c' 1070 else: 1071 fname_out = sys.argv[2] 1072 if(len(fname_in) > 0): 1073 python_file = open(sys.argv[1], "r") 1074 if(len(fname_out) > 0): 1075 file_out = open(fname_out, "w+") 1076 return len(sys.argv), fname_in, fname_out 1077 1078 if __name__ == "__main__": 1033 def main(): 1079 1034 import os 1080 1035 print("Parsing...using Python" + sys.version) 1081 try: 1082 fname_in = "" 1083 fname_out = "" 1084 if(len(sys.argv) == 1): 1085 print("Usage:\npython parse01.py <infile> [<outfile>](if omitted, output file is '<infile>.c'") 1086 else: 1087 fname_in = sys.argv[1] 1088 fname_base = os.path.splitext(fname_in) 1089 if(len(sys.argv) == 2): 1090 fname_out = str(fname_base[0]) + '.c' 1091 else: 1092 fname_out = sys.argv[2] 1093 if(len(fname_in) > 0): 1094 python_file = open(sys.argv[1], "r") 1095 if(len(fname_out) > 0): 1096 file_out = open(fname_out, "w+") 1097 functions = ["MultAsgn", "Iq41", "Iq2"] 1098 tpls = [functions, fname_in, 0] 1099 c_txt = translate(tpls) 1100 file_out.write(c_txt) 1101 file_out.close() 1102 except Exception as excp: 1103 print("Error:\n" + str(excp.args)) 1036 if len(sys.argv) == 1: 1037 print("""\ 1038 Usage: python py2c.py <infile> [<outfile>] 1039 1040 if outfile is omitted, output file is '<infile>.c' 1041 """) 1042 return 1043 1044 fname_in = sys.argv[1] 1045 if len(sys.argv) == 2: 1046 fname_base = os.path.splitext(fname_in)[0] 1047 fname_out = str(fname_base) + '.c' 1048 else: 1049 fname_out = sys.argv[2] 1050 1051 with open(fname_in, "r") as python_file: 1052 code = python_file.read() 1053 1054 translation = translate([code, fname_in, 1])[0] 1055 1056 with open(fname_out, "w") as file_out: 1057 file_out.write(translation) 1104 1058 print("...Done") 1059 1060 if __name__ == "__main__": 1061 main()
Note: See TracChangeset
for help on using the changeset viewer.