Changeset fa74acf in sasmodels
- Timestamp:
- Dec 15, 2017 12:26:39 PM (7 years ago)
- Children:
- 98a4f14
- Parents:
- fb5c8c7
- git-author:
- Omer Eisenberg <omereis@…> (12/15/17 12:23:40)
- git-committer:
- Omer Eisenberg <omereis@…> (12/15/17 12:26:39)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/py2c.py
rfb5c8c7 rfa74acf 12 12 Variables definition in C 13 13 ------------------------- 14 Defining variables within the Translate function is a bit of a guess work, using following rules. 14 Defining variables within the Translate function is a bit of a guess work, 15 using following rules. 15 16 * By default, a variable is a 'double'. 16 17 * Variable in a for loop is an int. 17 * Variable that is references with brackets is an array of doubles. The variable within the brackets 18 is integer. For example, in the reference 'var1[var2]', var1 is a double array, and var2 is an integer. 19 * Assignment to an argument makes that argument an array, and the index in that assignment is 0. 18 * Variable that is references with brackets is an array of doubles. The 19 variable within the brackets is integer. For example, in the 20 reference 'var1[var2]', var1 is a double array, and var2 is an integer. 21 * Assignment to an argument makes that argument an array, and the index in 22 that assignment is 0. 20 23 For example, the following python code 21 def func 24 def func(arg1, arg2): 22 25 arg2 = 17. 23 26 is translated to the following C code 24 double func 27 double func(double arg1) 25 28 { 26 29 arg2[0] = 17.0; 27 30 } 28 31 For example, the following python code is translated to the following C code 29 def func (arg1, arg2): double func(double arg1) {32 def func(arg1, arg2): double func(double arg1) { 30 33 arg2 = 17. arg2[0] = 17.0; 31 34 } … … 35 38 Update Notes 36 39 ============ 37 11/22 14:15, O.E. Each 'visit_*' method is to build a C statement string. It shold insert 4 blanks per indentation level. 38 The 'body' method will combine all the strings, by adding the 'current_statement' to the c_proc string list 40 11/22 14:15, O.E. Each 'visit_*' method is to build a C statement string. It 41 shold insert 4 blanks per indentation level. 42 The 'body' method will combine all the strings, by adding 43 the 'current_statement' to the c_proc string list 39 44 11/2017, OE: variables, argument definition implemented. 40 Note: An argument is considered an array if it is the target of an assignment. In that case it is translated to <var>[0] 45 Note: An argument is considered an array if it is the target of an 46 assignment. In that case it is translated to <var>[0] 41 47 11/27/2017, OE: 'pow' basicly working 42 48 /12/2017, OE: Multiple assignment: a1,a2,...,an=b1,b2,...bn implemented 43 /12/2017, OE: Power function, including special cases of square(x) (pow(x,2)) and cube(x) (pow(x,3)), implemented in translate_power, 44 called from visit_BinOp 45 12/07/2017, OE: Translation of integer division, '\\' in python, implemented in translate_integer_divide, called from visit_BinOp 49 /12/2017, OE: Power function, including special cases of 50 square(x)(pow(x,2)) and cube(x)(pow(x,3)), implemented in 51 translate_power, called from visit_BinOp 52 12/07/2017, OE: Translation of integer division, '\\' in python, implemented 53 in translate_integer_divide, called from visit_BinOp 46 54 12/07/2017, OE: C variable definition handled in 'define_C_Vars' 47 : Python integer division, '//', translated to C in 'translate_integer_divide' 48 12/15/2017, OE: Precedence maintained by writing opening and closing parenthesesm '(',')', 49 in procedure 'visit_BinOp'. 55 : Python integer division, '//', translated to C in 56 'translate_integer_divide' 57 12/15/2017, OE: Precedence maintained by writing opening and closing 58 parenthesesm '(',')', in procedure 'visit_BinOp'. 50 59 """ 51 60 import ast … … 72 81 73 82 CMPOP_SYMBOLS = {} 74 CMPOP_SYMBOLS[ast.Eq] = '=='83 CMPOP_SYMBOLS[ast.Eq] = '==' 75 84 CMPOP_SYMBOLS[ast.NotEq] = '!=' 76 85 CMPOP_SYMBOLS[ast.Lt] = '<' … … 122 131 except: 123 132 return False 124 133 125 134 class SourceGenerator(NodeVisitor): 126 135 """This visitor is able to transform a well formed syntax tree into python … … 168 177 def write_c(self, x): 169 178 self.current_statement += x 170 179 171 180 def add_c_line(self, x): 172 181 string = '' 173 for i in range 182 for i in range(self.indentation): 174 183 string += (" ") 175 184 string += str(x) 176 self.c_proc.append 185 self.c_proc.append(str(string + "\n")) 177 186 x = '' 178 187 179 def add_current_line 180 if 181 self.add_c_line 188 def add_current_line(self): 189 if(len(self.current_statement) > 0): 190 self.add_c_line(self.current_statement) 182 191 self.current_statement = '' 183 192 184 def AddUniqueVar 185 if 186 self.C_Vars.append (str(new_var))187 188 def WriteSincos 193 def AddUniqueVar(self, new_var): 194 if((new_var not in self.C_Vars)): 195 self.C_Vars.append(str(new_var)) 196 197 def WriteSincos(self, node): 189 198 angle = str(node.args[0].id) 190 self.write_c (node.args[1].id + " = sin(" + angle + ");")199 self.write_c(node.args[1].id + " = sin(" + angle + ");") 191 200 self.add_current_line() 192 self.write_c (node.args[2].id + " = cos(" + angle + ");")201 self.write_c(node.args[2].id + " = cos(" + angle + ");") 193 202 self.add_current_line() 194 203 for arg in node.args: 195 self.AddUniqueVar 204 self.AddUniqueVar(arg.id) 196 205 197 206 def newline(self, node=None, extra=0): … … 200 209 self.write_c('# line: %s' % node.lineno) 201 210 self.new_lines = 1 202 if 203 self.Statements.append 211 if(len(self.current_statement)): 212 self.Statements.append(self.current_statement) 204 213 self.current_statement = '' 205 214 206 215 def body(self, statements): 207 if 208 self.add_current_line 216 if(len(self.current_statement)): 217 self.add_current_line() 209 218 self.new_line = True 210 219 self.indentation += 1 211 220 for stmt in statements: 212 221 target_name = '' 213 if (hasattr(stmt, 'targets')):214 if (hasattr(stmt.targets[0],'id')):222 if(hasattr(stmt, 'targets')): 223 if(hasattr(stmt.targets[0], 'id')): 215 224 target_name = stmt.targets[0].id # target name needed for debug only 216 225 self.visit(stmt) 217 self.add_current_line () # just for breaking point. to be deleted.226 self.add_current_line() # just for breaking point. to be deleted. 218 227 self.indentation -= 1 219 228 … … 234 243 # for C 235 244 for arg in node.args: 236 self.arguments.append 237 238 padding = [None] * 245 self.arguments.append(arg.arg) 246 247 padding = [None] *(len(node.args) - len(node.defaults)) 239 248 for arg, default in zip(node.args, padding + node.defaults): 240 249 if default is not None: 241 self.warnings.append ("Default Parameter unknown to C") 242 w_str = "Default Parameters are unknown to C: '" + arg.arg + " = " + str(default.n) + "'" 243 self.warnings.append (w_str) 250 self.warnings.append("Default Parameter unknown to C") 251 w_str = "Default Parameters are unknown to C: '" + arg.arg + \ 252 " = " + str(default.n) + "'" 253 self.warnings.append(w_str) 244 254 # self.write_python('=') 245 255 # self.visit(default) … … 258 268 self.visit(node.test) 259 269 if node.msg is not None: 260 self.write_python(', ')261 self.visit(node.msg)262 263 def define_C_Vars 264 if (hasattr(target, 'id')):270 self.write_python(', ') 271 self.visit(node.msg) 272 273 def define_C_Vars(self, target): 274 if(hasattr(target, 'id')): 265 275 # a variable is considered an array if it apears in the agrument list 266 276 # and being assigned to. For example, the variable p in the following 267 277 # sniplet is a pointer, while q is not 268 # def somefunc 278 # def somefunc(p, q): 269 279 # p = q + 1 270 280 # return 271 281 # 272 if 273 if 274 idx = self.arguments.index 282 if(target.id not in self.C_Vars): 283 if(target.id in self.arguments): 284 idx = self.arguments.index(target.id) 275 285 new_target = self.arguments[idx] + "[0]" 276 if 286 if(new_target not in self.C_Pointers): 277 287 target.id = new_target 278 self.C_Pointers.append 288 self.C_Pointers.append(self.arguments[idx]) 279 289 else: 280 self.C_Vars.append 281 282 def add_semi_colon 290 self.C_Vars.append(target.id) 291 292 def add_semi_colon(self): 283 293 semi_pos = self.current_statement.find(';') 284 if 294 if(semi_pos < 0): 285 295 self.write_c(';') 286 296 287 297 def visit_Assign(self, node): 288 self.add_current_line 298 self.add_current_line() 289 299 for idx, target in enumerate(node.targets): # multi assign, as in 'a = b = c = 7' 290 300 if idx: 291 301 self.write_c(' = ') 292 self.define_C_Vars 302 self.define_C_Vars(target) 293 303 self.visit(target) 294 if 295 tplTargets = list 304 if(len(self.Tuples) > 0): 305 tplTargets = list(self.Tuples) 296 306 self.Tuples.clear() 297 307 self.write_c(' = ') … … 299 309 self.visited_args = False 300 310 self.visit(node.value) 301 self.add_semi_colon 311 self.add_semi_colon() 302 312 # self.write_c(';') 303 self.add_current_line 304 for n, item in enumerate(self.Tuples):313 self.add_current_line() 314 for n, item in enumerate(self.Tuples): 305 315 self.visit(tplTargets[n]) 306 316 self.write_c(' = ') 307 317 self.visit(item) 308 self.add_semi_colon 309 self.add_current_line 310 if 318 self.add_semi_colon() 319 self.add_current_line() 320 if((self.is_sequence) and (not self.visited_args)): 311 321 for target in node.targets: 312 if (hasattr(target, 'id')):313 if ((target.id in self.C_Vars) and(target.id not in self.C_DclPointers)):314 if 315 self.C_DclPointers.append 316 if 322 if(hasattr(target, 'id')): 323 if((target.id in self.C_Vars) and(target.id not in self.C_DclPointers)): 324 if(target.id not in self.C_DclPointers): 325 self.C_DclPointers.append(target.id) 326 if(target.id in self.C_Vars): 317 327 self.C_Vars.remove(target.id) 318 328 self.current_statement = '' 319 329 320 330 def visit_AugAssign(self, node): 321 if 322 if 323 self.C_Vars.append 331 if(node.target.id not in self.C_Vars): 332 if(node.target.id not in self.arguments): 333 self.C_Vars.append(node.target.id) 324 334 self.visit(node.target) 325 335 self.write_c(' ' + BINOP_SYMBOLS[type(node.op)] + '= ') 326 336 self.visit(node.value) 327 self.add_semi_colon 337 self.add_semi_colon() 328 338 # self.write_c(';') 329 self.add_current_line 339 self.add_current_line() 330 340 331 341 def visit_ImportFrom(self, node): 332 342 self.newline(node) 333 self.write_python('from %s%s import ' % 343 self.write_python('from %s%s import ' %('.' * node.level, node.module)) 334 344 for idx, item in enumerate(node.names): 335 345 if idx: … … 349 359 def listToDeclare(self, Vars): 350 360 s = '' 351 if 352 s = ",".join 353 return 354 355 def write_C_Pointers 356 if (len(self.C_DclPointers) > 0):361 if(len(Vars) > 0): 362 s = ",".join(Vars) 363 return(s) 364 365 def write_C_Pointers(self, start_var): 366 if(len(self.C_DclPointers) > 0): 357 367 vars = "" 358 368 for c_ptr in self.C_DclPointers: 359 if 369 if(len(vars) > 0): 360 370 vars += ", " 361 if 371 if(c_ptr not in self.arguments): 362 372 vars += "*" + c_ptr 363 if 364 if 365 self.C_Vars.remove 366 if 373 if(c_ptr in self.C_Vars): 374 if(c_ptr in self.C_Vars): 375 self.C_Vars.remove(c_ptr) 376 if(len(vars) > 0): 367 377 c_dcl = " double " + vars + ";" 368 self.c_proc.insert 378 self.c_proc.insert(start_var, c_dcl + "\n") 369 379 start_var += 1 370 380 return start_var 371 381 372 def insert_C_Vars 382 def insert_C_Vars(self, start_var): 373 383 fLine = False 374 start_var = self.write_C_Pointers 375 if 384 start_var = self.write_C_Pointers(start_var) 385 if(len(self.C_IntVars) > 0): 376 386 for var in self.C_IntVars: 377 if 387 if(var in self.C_Vars): 378 388 self.C_Vars.remove(var) 379 389 s = self.listToDeclare(self.C_IntVars) 380 self.c_proc.insert 390 self.c_proc.insert(start_var, " int " + s + ";\n") 381 391 fLine = True 382 392 start_var += 1 383 384 if 393 394 if(len(self.C_Vars) > 0): 385 395 s = self.listToDeclare(self.C_Vars) 386 self.c_proc.insert 396 self.c_proc.insert(start_var, " double " + s + ";\n") 387 397 fLine = True 388 398 start_var += 1 389 # if 399 # if(len(self.C_IntVars) > 0): 390 400 # s = self.listToDeclare(self.C_IntVars) 391 # self.c_proc.insert 401 # self.c_proc.insert(start_var, " int " + s + ";\n") 392 402 # fLine = True 393 403 # start_var += 1 394 if (len(self.C_Vectors) > 0):404 if(len(self.C_Vectors) > 0): 395 405 s = self.listToDeclare(self.C_Vectors) 396 406 for n in range(len(self.C_Vectors)): 397 407 name = "vec" + str(n+1) 398 408 c_dcl = " double " + name + "[] = {" + self.C_Vectors[n] + "};" 399 self.c_proc.insert 409 self.c_proc.insert(start_var, c_dcl + "\n") 400 410 start_var += 1 401 411 self.C_Vars.clear() … … 404 414 self.C_Pointers.clear() 405 415 self.C_DclPointers 406 if 407 self.c_proc.insert 416 if(fLine == True): 417 self.c_proc.insert(start_var, "\n") 408 418 return 409 419 s = '' … … 412 422 if n < len(self.C_Vars) - 1: 413 423 s += ", " 414 if 415 self.c_proc.insert 416 self.c_proc.insert 417 418 def writeInclude 419 if 424 if(len(s) > 0): 425 self.c_proc.insert(start_var, " double " + s + ";\n") 426 self.c_proc.insert(start_var + 1, "\n") 427 428 def writeInclude(self): 429 if(self.MathIncludeed == False): 420 430 self.add_c_line("#include <math.h>\n") 421 431 self.add_c_line("static double pi = 3.14159265359;\n") 422 432 self.MathIncludeed = True 423 433 424 def ListToString 434 def ListToString(self, strings): 425 435 s = '' 426 436 for n in range(len(strings)): 427 437 s += strings[n] 428 if 438 if(n < (len(strings) - 1)): 429 439 s += ", " 430 return 431 432 def getMethodSignature 433 # args_str = ListToString 440 return(s) 441 442 def getMethodSignature(self): 443 # args_str = ListToString(self.arguments) 434 444 args_str = '' 435 445 for n in range(len(self.arguments)): 436 446 args_str += "double " + self.arguments[n] 437 if 447 if(n < (len(self.arguments) - 1)): 438 448 args_str += ", " 439 return 440 # self.strMethodSignature = 'double ' + self.name + ' 441 442 def InsertSignature 449 return(args_str) 450 # self.strMethodSignature = 'double ' + self.name + '(' + args_str + ")" 451 452 def InsertSignature(self): 443 453 args_str = '' 444 454 for n in range(len(self.arguments)): 445 455 args_str += "double " + self.arguments[n] 446 if 456 if(self.arguments[n] in self.C_Pointers): 447 457 args_str += "[]" 448 if 458 if(n < (len(self.arguments) - 1)): 449 459 args_str += ", " 450 self.strMethodSignature = 'double ' + self.name + ' 451 if 452 self.c_proc.insert 460 self.strMethodSignature = 'double ' + self.name + '(' + args_str + ")" 461 if(self.signature_line >= 0): 462 self.c_proc.insert(self.signature_line, self.strMethodSignature) 453 463 454 464 def visit_FunctionDef(self, node): … … 466 476 # for C 467 477 self.writeInclude() 468 self.getMethodSignature 478 self.getMethodSignature() 469 479 # for C 470 480 self.signature_line = len(self.c_proc) … … 474 484 self.body(node.body) 475 485 self.add_c_line("}\n") 476 self.InsertSignature 477 self.insert_C_Vars 486 self.InsertSignature() 487 self.insert_C_Vars(start_vars) 478 488 self.C_Pointers = [] 479 489 … … 522 532 if len(else_) == 0: 523 533 break 524 # elif hasattr 534 # elif hasattr(else_, 'orelse'): 525 535 elif len(else_) == 1 and isinstance(else_[0], ast.If): 526 536 node = else_[0] … … 530 540 self.write_c(' {') 531 541 self.body(node.body) 532 self.add_current_line 542 self.add_current_line() 533 543 self.add_c_line('}') 534 544 # break … … 540 550 break 541 551 542 def getNodeLineNo 552 def getNodeLineNo(self, node): 543 553 line_number = -1 544 if (hasattr(node,'value')):554 if(hasattr(node,'value')): 545 555 line_number = node.value.lineno 546 556 elif hasattr(node,'iter'): 547 557 if hasattr(node.iter,'lineno'): 548 558 line_number = node.iter.lineno 549 return 550 551 def GetNodeAsString 559 return(line_number) 560 561 def GetNodeAsString(self, node): 552 562 res = '' 553 if (hasattr(node,'n')):563 if(hasattr(node, 'n')): 554 564 res = str(node.n) 555 elif (hasattr(node,'id')):565 elif(hasattr(node, 'id')): 556 566 res = node.id 557 return 567 return(res) 558 568 559 569 def GetForRange(self, node): … … 569 579 self.current_statement = '' 570 580 self.current_statement = temp_statement 571 if 581 if(len(for_args) == 1): 572 582 stop = for_args[0] 573 elif 583 elif(len(for_args) == 2): 574 584 start = for_args[0] 575 585 stop = for_args[1] 576 elif 586 elif(len(for_args) == 3): 577 587 start = for_args[0] 578 588 stop = for_args[1] … … 580 590 else: 581 591 raise("Ilegal for loop parameters") 582 return 592 return(start, stop, step) 583 593 584 594 def visit_For(self, node): … … 586 596 # Iterator name is in node.target.id. 587 597 self.add_current_line() 588 # if 598 # if(len(self.current_statement) > 0): 589 599 # self.add_c_line(self.current_statement) 590 600 # self.current_statement = '' 591 601 fForDone = False 592 602 self.current_statement = '' 593 if (hasattr(node.iter,'func')):594 if (hasattr (node.iter.func,'id')):595 if 603 if(hasattr(node.iter, 'func')): 604 if(hasattr(node.iter.func, 'id')): 605 if(node.iter.func.id == 'range'): 596 606 self.visit(node.target) 597 607 iterator = self.current_statement 598 608 self.current_statement = '' 599 if 600 self.C_IntVars.append 609 if(iterator not in self.C_IntVars): 610 self.C_IntVars.append(iterator) 601 611 start, stop, step = self.GetForRange(node) 602 self.write_c ("for(" + iterator + "=" + str(start) + \612 self.write_c("for(" + iterator + "=" + str(start) + \ 603 613 " ; " + iterator + " < " + str(stop) + \ 604 614 " ; " + iterator + " += " + str(step) + ") {") 605 615 self.body_or_else(node) 606 self.write_c 616 self.write_c("}") 607 617 fForDone = True 608 if 609 line_number = self.getNodeLineNo 618 if(fForDone == False): 619 line_number = self.getNodeLineNo(node) 610 620 self.current_statement = '' 611 621 self.write_c('for ') … … 614 624 self.visit(node.iter) 615 625 self.write_c(':') 616 errStr = "Conversion Error in function " + self.name + ", Line #" + str 626 errStr = "Conversion Error in function " + self.name + ", Line #" + str(line_number) 617 627 errStr += "\nPython for expression not supported: '" + self.current_statement + "'" 618 628 raise Exception(errStr) … … 640 650 641 651 def visit_Print(self, node): 642 # XXX: python 2.6 only 652 # XXX: python 2.6 only 643 653 self.newline(node) 644 654 self.write_c('print ') … … 692 702 self.write_c('return') 693 703 else: 694 self.write_c('return 704 self.write_c('return(') 695 705 self.visit(node.value) 696 706 self.write_c(');') 697 # self.add_current_statement 698 self.add_c_line 707 # self.add_current_statement(self) 708 self.add_c_line(self.current_statement) 699 709 self.current_statement = '' 700 710 … … 729 739 730 740 def visit_Attribute(self, node): 731 errStr = "Conversion Error in function " + self.name + ", Line #" + str 741 errStr = "Conversion Error in function " + self.name + ", Line #" + str(node.value.lineno) 732 742 errStr += "\nPython expression not supported: '" + node.value.id + "." + node.attr + "'" 733 743 raise Exception(errStr) … … 742 752 else: 743 753 want_comma.append(True) 744 if (hasattr(node.func, 'id')):745 if 746 self.C_Functions.append 747 if 748 self.write_c 749 elif 754 if(hasattr(node.func, 'id')): 755 if(node.func.id not in self.C_Functions): 756 self.C_Functions.append(node.func.id) 757 if(node.func.id == 'abs'): 758 self.write_c("fabs ") 759 elif(node.func.id == 'int'): 750 760 self.write_c('(int) ') 751 elif 752 self.WriteSincos 761 elif(node.func.id == "SINCOS"): 762 self.WriteSincos(node) 753 763 return 754 764 else: … … 760 770 for arg in node.args: 761 771 write_comma() 762 self.visited_args = True 772 self.visited_args = True 763 773 self.visit(arg) 764 774 for keyword in node.keywords: … … 766 776 self.write_c(keyword.arg + '=') 767 777 self.visit(keyword.value) 768 if hasattr 778 if hasattr(node, 'starargs'): 769 779 if node.starargs is not None: 770 780 write_comma() 771 781 self.write_c('*') 772 782 self.visit(node.starargs) 773 if hasattr 783 if hasattr(node, 'kwargs'): 774 784 if node.kwargs is not None: 775 785 write_comma() … … 780 790 def visit_Name(self, node): 781 791 self.write_c(node.id) 782 if ((node.id in self.C_Pointers) and(not self.SubRef)):792 if((node.id in self.C_Pointers) and(not self.SubRef)): 783 793 self.write_c("[0]") 784 794 name = "" 785 795 sub = node.id.find("[") 786 if 796 if(sub > 0): 787 797 name = node.id[0:sub].strip() 788 798 else: 789 799 name = node.id 790 800 # add variable to C_Vars if it ins't there yet, not an argument and not a number 791 if ((name not in self.C_Functions) and (name not in self.C_Vars) and (name not in self.C_IntVars) and (name not in self.arguments) and (name.isnumeric () == False)): 792 if (self.InSubscript): 793 self.C_IntVars.append (node.id) 801 if((name not in self.C_Functions) and (name not in self.C_Vars) and \ 802 (name not in self.C_IntVars) and (name not in self.arguments) and \ 803 (name.isnumeric() == False)): 804 if(self.InSubscript): 805 self.C_IntVars.append(node.id) 794 806 else: 795 self.C_Vars.append 807 self.C_Vars.append(node.id) 796 808 797 809 def visit_Str(self, node): … … 816 828 s = "" 817 829 for idx, item in enumerate(node.elts): 818 if ((idx > 0) and(len(s) > 0)):830 if((idx > 0) and(len(s) > 0)): 819 831 s += ', ' 820 if (hasattr(item, 'id')):832 if(hasattr(item, 'id')): 821 833 s += item.id 822 elif (hasattr(item,'n')):834 elif(hasattr(item, 'n')): 823 835 s += str(item.n) 824 if 825 self.C_Vectors.append 836 if(len(s) > 0): 837 self.C_Vectors.append(s) 826 838 vec_name = "vec" + str(len(self.C_Vectors)) 827 839 self.write_c(vec_name) … … 843 855 self.write_python('}') 844 856 845 def get_special_power 857 def get_special_power(self, string): 846 858 function_name = '' 847 859 is_negative_exp = False 848 if 860 if(isevaluable(str(self.current_statement))): 849 861 exponent = eval(string) 850 862 is_negative_exp = exponent < 0 851 863 abs_exponent = abs(exponent) 852 if 864 if(abs_exponent == 2): 853 865 function_name = "square" 854 elif 866 elif(abs_exponent == 3): 855 867 function_name = "cube" 856 elif 868 elif(abs_exponent == 0.5): 857 869 function_name = "sqrt" 858 elif 870 elif(abs_exponent == 1.0/3.0): 859 871 function_name = "cbrt" 860 if 872 if(function_name == ''): 861 873 function_name = "pow" 862 874 return function_name, is_negative_exp 863 875 864 def translate_power 876 def translate_power(self, node): 865 877 # get exponent by visiting the right hand argument. 866 878 function_name = "pow" … … 871 883 self.current_statement = '' 872 884 self.visit(node.right) 873 exponent = self.current_statement.replace(' ', '')874 function_name, is_negative_exp = self.get_special_power 885 exponent = self.current_statement.replace(' ', '') 886 function_name, is_negative_exp = self.get_special_power(self.current_statement) 875 887 self.current_statement = temp_statement 876 if 877 self.write_c ("1.0 /(")878 self.write_c (function_name + "(")888 if(is_negative_exp): 889 self.write_c("1.0 /(") 890 self.write_c(function_name + "(") 879 891 self.visit(node.left) 880 if 892 if(function_name == "pow"): 881 893 self.write_c(", ") 882 894 self.visit(node.right) 883 895 self.write_c(")") 884 if 896 if(is_negative_exp): 885 897 self.write_c(")") 886 898 self.write_c(" ") 887 899 888 def translate_integer_divide 889 self.write_c ("(int)(")900 def translate_integer_divide(self, node): 901 self.write_c("(int)(") 890 902 self.visit(node.left) 891 self.write_c (") / (int)(")903 self.write_c(") /(int)(") 892 904 self.visit(node.right) 893 self.write_c 905 self.write_c(")") 894 906 895 907 def visit_BinOp(self, node): 896 908 self.write_c("(") 897 if 898 self.translate_power 899 elif 900 self.translate_integer_divide 909 if('%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.Pow]): 910 self.translate_power(node) 911 elif('%s' % BINOP_SYMBOLS[type(node.op)] == BINOP_SYMBOLS[ast.FloorDiv]): 912 self.translate_integer_divide(node) 901 913 else: 902 914 self.visit(node.left) … … 932 944 933 945 def visit_Subscript(self, node): 934 if 935 self.C_Pointers.append 946 if(node.value.id not in self.C_Pointers): 947 self.C_Pointers.append(node.value.id) 936 948 self.SubRef = True 937 949 self.visit(node.value) … … 951 963 if node.step is not None: 952 964 self.write_python(':') 953 if not 965 if not(isinstance(node.step, Name) and node.step.id == 'None'): 954 966 self.visit(node.step) 955 967 … … 1048 1060 1049 1061 def Iq1(q, porod_scale, porod_exp, lorentz_scale, lorentz_length, peak_pos, lorentz_exp=17): 1050 z1 = z2 = z = abs 1051 if 1062 z1 = z2 = z = abs(q - peak_pos) * lorentz_length 1063 if(q > p): 1052 1064 q = p + 17 1053 1065 p = q - 5 1054 1066 z3 = -8 1055 1067 inten = (porod_scale / q ** porod_exp 1056 + lorentz_scale / 1068 + lorentz_scale /(1 + z ** lorentz_exp)) 1057 1069 return inten 1058 1070 1059 1071 def Iq(q, porod_scale, porod_exp, lorentz_scale, lorentz_length, peak_pos, lorentz_exp=17): 1060 z1 = z2 = z = abs 1061 if 1072 z1 = z2 = z = abs(q - peak_pos) * lorentz_length 1073 if(q > p): 1062 1074 q = p + 17 1063 1075 p = q - 5 1064 elif 1076 elif(q == p): 1065 1077 q = p * q 1066 1078 q *= z1 1067 1079 p = z1 1068 elif 1080 elif(q == 17): 1069 1081 q = p * q - 17 1070 1082 else: … … 1072 1084 z3 = -8 1073 1085 inten = (porod_scale / q ** porod_exp 1074 + lorentz_scale / 1086 + lorentz_scale /(1 + z ** lorentz_exp)) 1075 1087 return inten 1076 1088 … … 1084 1096 if f is not None: 1085 1097 tree = ast.parse(inspect.getsource(f)) 1086 tree_source = to_source 1098 tree_source = to_source(tree) 1087 1099 print(tree_source) 1088 1100 1089 def translate 1101 def translate(functions, constants=0): 1090 1102 sniplets = [] 1091 1103 fname = functions[1] 1092 python_file = open 1104 python_file = open(fname, "r") 1093 1105 source = python_file.read() 1094 1106 python_file.close() 1095 tree = ast.parse 1096 sniplet = to_source 1107 tree = ast.parse(source) 1108 sniplet = to_source(tree, functions) # in the future add filename, offset, constants 1097 1109 sniplets.append(sniplet) 1098 return 1099 1100 def get_file_names 1110 return("\n".join(sniplets)) 1111 1112 def get_file_names(): 1101 1113 fname_in = "" 1102 1114 fname_out = "" 1103 if 1115 if(len(sys.argv) > 1): 1104 1116 fname_in = sys.argv[1] 1105 fname_base = os.path.splitext 1106 if (len(sys.argv) == 2):1107 fname_out = str 1117 fname_base = os.path.splitext(fname_in) 1118 if(len(sys.argv) == 2): 1119 fname_out = str(fname_base[0]) + '.c' 1108 1120 else: 1109 1121 fname_out = sys.argv[2] 1110 if (len(fname_in) > 0):1111 python_file = open 1112 if (len(fname_out) > 0):1113 file_out = open 1122 if(len(fname_in) > 0): 1123 python_file = open(sys.argv[1], "r") 1124 if(len(fname_out) > 0): 1125 file_out = open(fname_out, "w+") 1114 1126 return len(sys.argv), fname_in, fname_out 1115 1127 … … 1120 1132 fname_in = "" 1121 1133 fname_out = "" 1122 if (len(sys.argv) == 1):1123 print ("Usage:\npython parse01.py <infile> [<outfile>](if omitted, output file is '<infile>.c'")1134 if(len(sys.argv) == 1): 1135 print("Usage:\npython parse01.py <infile> [<outfile>](if omitted, output file is '<infile>.c'") 1124 1136 else: 1125 1137 fname_in = sys.argv[1] 1126 fname_base = os.path.splitext 1127 if (len(sys.argv) == 2):1128 fname_out = str 1138 fname_base = os.path.splitext(fname_in) 1139 if(len(sys.argv) == 2): 1140 fname_out = str(fname_base[0]) + '.c' 1129 1141 else: 1130 1142 fname_out = sys.argv[2] 1131 if (len(fname_in) > 0):1132 python_file = open 1133 if (len(fname_out) > 0):1134 file_out = open 1143 if(len(fname_in) > 0): 1144 python_file = open(sys.argv[1], "r") 1145 if(len(fname_out) > 0): 1146 file_out = open(fname_out, "w+") 1135 1147 functions = ["MultAsgn", "Iq41", "Iq2"] 1136 1148 tpls = [functions, fname_in, 0] 1137 c_txt = translate 1138 file_out.write 1149 c_txt = translate(tpls) 1150 file_out.write(c_txt) 1139 1151 file_out.close() 1140 1152 except Exception as excp: 1141 print 1153 print("Error:\n" + str(excp.args)) 1142 1154 print("...Done")
Note: See TracChangeset
for help on using the changeset viewer.