Changeset 5dd7cfb in sasmodels
- Timestamp:
- Jan 17, 2018 1:49:12 PM (7 years ago)
- Children:
- 6f91c91
- Parents:
- 6ceca44
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/py2c.py
rd5014e4 r5dd7cfb 147 147 import ast 148 148 from ast import NodeVisitor 149 try: # for debugging, astor lets us print out the node as python 150 import astor 151 except ImportError: 152 pass 149 153 150 154 BINOP_SYMBOLS = {} … … 193 197 return False 194 198 199 def render_expression(tree): 200 generator = SourceGenerator() 201 generator.visit(tree) 202 c_code = "".join(generator.current_statement) 203 return c_code 204 195 205 class SourceGenerator(NodeVisitor): 196 206 """This visitor is able to transform a well formed syntax tree into python … … 199 209 """ 200 210 201 def __init__(self, indent_with=" ", add_line_information=False, 202 constants=None, fname=None, lineno=0): 203 self.result = [] 211 def __init__(self, indent_with=" ", constants=None, fname=None, lineno=0): 204 212 self.indent_with = indent_with 205 self.add_line_information = add_line_information206 213 self.indentation = 0 207 self.new_lines = 0208 214 209 215 # for C … … 215 221 self.lineno_offset = lineno 216 222 self.warnings = [] 217 self.statements = []218 223 self.current_statement = "" 219 224 # TODO: use set rather than list for c_vars, ... … … 230 235 self.tuples = [] 231 236 self.required_functions = [] 232 self.is_sequence = False233 237 self.visited_args = False 234 235 def write_python(self, x):236 if self.new_lines:237 if self.result:238 self.result.append('\n' * self.new_lines)239 self.result.append(self.indent_with * self.indentation)240 self.new_lines = 0241 self.result.append(x)242 238 243 239 def write_c(self, statement): 244 240 # TODO: build up as a list rather than adding to string 245 241 self.current_statement += statement 242 243 def write_python(self, x): 244 raise NotImplementedError("shouldn't be trying to write pythnon") 246 245 247 246 def add_c_line(self, line): … … 267 266 self.add_unique_var(arg.id) 268 267 269 def newline(self, node=None, extra=0): 270 self.new_lines = max(self.new_lines, 1 + extra) 271 if node is not None and self.add_line_information: 272 self.write_c('// line: %s' % node.lineno) 273 self.new_lines = 1 274 if self.current_statement: 275 self.statements.append(self.current_statement) 276 self.current_statement = '' 268 def track_lineno(self, node): 269 #print("newline", node, [s for s in dir(node) if not s.startswith('_')]) 270 if hasattr(node, 'lineno'): 271 line = '#line %d "%s"\n' % (node.lineno+self.lineno_offset-1, self.fname) 272 self.c_proc.append(line) 277 273 278 274 def body(self, statements): … … 293 289 self.unsupported(node, "for...else/while...else not supported") 294 290 295 self. newline()291 self.track_lineno(node) 296 292 self.write_c('else:') 297 293 self.body(node.orelse) … … 327 323 328 324 def decorators(self, node): 325 if node.decorator_list: 326 self.unsupported(node.decorator_list[0]) 329 327 for decorator in node.decorator_list: 330 self. newline(decorator)328 self.trac_lineno(decorator) 331 329 self.write_python('@') 332 330 self.visit(decorator) … … 335 333 336 334 def visit_Assert(self, node): 337 self.newline(node) 335 self.unsupported(node) 336 337 self.track_lineno(node) 338 338 self.write_c('assert ') 339 339 self.visit(node.test) … … 369 369 def visit_Assign(self, node): 370 370 self.add_current_line() 371 self.track_lineno(node) 371 372 self.in_expr = True 372 373 for idx, target in enumerate(node.targets): # multi assign, as in 'a = b = c = 7' … … 379 380 del self.tuples[:] 380 381 self.write_c(' = ') 381 self.is_sequence = False382 382 self.visited_args = False 383 383 self.visit(node.value) … … 392 392 self.add_semi_colon() 393 393 self.add_current_line() 394 if self.is_sequence and not self.visited_args:395 for target in node.targets:396 if hasattr(target, 'id'):397 if target.id in self.c_vars and target.id not in self.c_dcl_pointers:398 if target.id not in self.c_dcl_pointers:399 self.c_dcl_pointers.append(target.id)400 if target.id in self.c_vars:401 self.c_vars.remove(target.id)394 #if self.is_sequence and not self.visited_args: 395 # for target in node.targets: 396 # if hasattr(target, 'id'): 397 # if target.id in self.c_vars and target.id not in self.c_dcl_pointers: 398 # if target.id not in self.c_dcl_pointers: 399 # self.c_dcl_pointers.append(target.id) 400 # if target.id in self.c_vars: 401 # self.c_vars.remove(target.id) 402 402 self.current_statement = '' 403 403 self.in_expr = False … … 417 417 def visit_ImportFrom(self, node): 418 418 return # import ignored 419 self. newline(node)419 self.track_lineno(node) 420 420 self.write_python('from %s%s import ' %('.' * node.level, node.module)) 421 421 for idx, item in enumerate(node.names): … … 426 426 def visit_Import(self, node): 427 427 return # import ignored 428 self. newline(node)428 self.track_lineno(node) 429 429 for item in node.names: 430 430 self.write_python('import ') … … 433 433 def visit_Expr(self, node): 434 434 #self.in_expr = True 435 self.newline(node)435 #self.track_lineno(node) 436 436 self.generic_visit(node) 437 437 #self.in_expr = False … … 506 506 warning_index = len(self.warnings) 507 507 508 self.newline(extra=1)509 508 self.decorators(node) 510 self. newline(node)509 self.track_lineno(node) 511 510 self.arguments = [] 512 511 self.visit(node.args) … … 525 524 526 525 def visit_ClassDef(self, node): 526 self.unsupported(node) 527 527 528 have_args = [] 528 529 def paren_or_comma(): … … 533 534 self.write_python('(') 534 535 535 self.newline(extra=2)536 536 self.decorators(node) 537 self. newline(node)537 self.track_lineno(node) 538 538 self.write_python('class %s' % node.name) 539 539 for base in node.bases: … … 559 559 def visit_If(self, node): 560 560 561 self.track_lineno(node) 561 562 self.write_c('if ') 562 563 self.in_expr = True … … 573 574 elif len(else_) == 1 and isinstance(else_[0], ast.If): 574 575 node = else_[0] 575 #self.newline()576 self.track_lineno(node) 576 577 self.write_c('else if ') 577 578 self.in_expr = True … … 584 585 #break 585 586 else: 586 self. newline()587 self.track_lineno(else_) 587 588 self.write_c('else {') 588 589 self.body(else_) … … 651 652 652 653 def visit_While(self, node): 653 self. newline(node)654 self.track_lineno(node) 654 655 self.write_c('while ') 655 656 self.visit(node.test) … … 662 663 self.unsupported(node) 663 664 664 self. newline(node)665 self.track_lineno(node) 665 666 self.write_python('with ') 666 667 self.visit(node.context_expr) … … 672 673 673 674 def visit_Pass(self, node): 674 self.newline(node)675 #self.track_lineno(node) 675 676 #self.write_python('pass') 677 pass 676 678 677 679 def visit_Print(self, node): … … 679 681 680 682 # CRUFT: python 2.6 only 681 self. newline(node)683 self.track_lineno(node) 682 684 self.write_c('print ') 683 685 want_comma = False … … 697 699 self.unsupported(node) 698 700 699 self. newline(node)701 self.track_lineno(node) 700 702 self.write_python('del ') 701 703 for idx, target in enumerate(node): … … 707 709 self.unsupported(node) 708 710 709 self. newline(node)711 self.track_linno(node) 710 712 self.write_python('try:') 711 713 self.body(node.body) … … 716 718 self.unsupported(node) 717 719 718 self. newline(node)720 self.track_lineno(node) 719 721 self.write_python('try:') 720 722 self.body(node.body) 721 self. newline(node)723 self.track_lineno(node) 722 724 self.write_python('finally:') 723 725 self.body(node.finalbody) … … 726 728 self.unsupported(node) 727 729 728 self. newline(node)730 self.track_lineno(node) 729 731 self.write_python('global ' + ', '.join(node.names)) 730 732 731 733 def visit_Nonlocal(self, node): 732 self. newline(node)734 self.track_lineno(node) 733 735 self.write_python('nonlocal ' + ', '.join(node.names)) 734 736 735 737 def visit_Return(self, node): 736 738 self.add_current_line() 739 self.track_lineno(node) 737 740 self.in_expr = True 738 741 if node.value is None: … … 747 750 748 751 def visit_Break(self, node): 749 self. newline(node)752 self.track_lineno(node) 750 753 self.write_c('break') 751 754 752 755 def visit_Continue(self, node): 753 self. newline(node)756 self.track_lineno(node) 754 757 self.write_c('continue') 755 758 … … 758 761 759 762 # CRUFT: Python 2.6 / 3.0 compatibility 760 self. newline(node)763 self.track_lineno(node) 761 764 self.write_python('raise') 762 765 if hasattr(node, 'exc') and node.exc is not None: … … 870 873 def visit_Str(self, node): 871 874 s = node.s 872 s = s.replace('\\', '\\\\').replace('"','\\"').replace('\n','\\n')875 s = s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') 873 876 self.write_c('"') 874 877 self.write_c(s) … … 877 880 def visit_Bytes(self, node): 878 881 s = node.s 879 s = s.replace('\\', '\\\\').replace('"','\\"').replace('\n','\\n')882 s = s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') 880 883 self.write_c('"') 881 884 self.write_c(s) … … 892 895 self.visit(item) 893 896 894 def sequence_visit(left, right): 895 def visit(self, node): 896 self.is_sequence = True 897 s = "" 898 for idx, item in enumerate(node.elts): 899 if idx > 0 and s: 900 s += ', ' 901 if hasattr(item, 'id'): 902 s += item.id 903 elif hasattr(item, 'n'): 904 s += str(item.n) 905 if s: 906 self.c_vectors.append(s) 907 vec_name = "vec" + str(len(self.c_vectors)) 908 self.write_c(vec_name) 909 return visit 910 911 visit_List = sequence_visit('[', ']') 912 visit_Set = sequence_visit('{', '}') 913 del sequence_visit 897 def visit_List(self, node): 898 #self.unsupported(node) 899 #print("visiting", node) 900 #print(astor.to_source(node)) 901 #print(node.elts) 902 exprs = [render_expression(item) for item in node.elts] 903 if exprs: 904 self.c_vectors.append(', '.join(exprs)) 905 vec_name = "vec" + str(len(self.c_vectors)) 906 self.write_c(vec_name) 907 908 def visit_Set(self, node): 909 self.unsupported(node) 914 910 915 911 def visit_Dict(self, node): … … 1127 1123 1128 1124 def visit_comprehension(self, node): 1125 self.unsupported(node) 1126 1129 1127 self.write_c(' for ') 1130 1128 self.visit(node.target) 1131 self.write_ C(' in ')1129 self.write_c(' in ') 1132 1130 #self.write_python(' in ') 1133 1131 self.visit(node.iter) … … 1286 1284 return snippets, warnings 1287 1285 1288 def to_source(tree, constants=None, fname=None, lineno=0):1289 """1290 This function can convert a syntax tree into C sourcecode.1291 """1292 c_code = "".join(generator.c_proc)1293 return c_code1294 1295 1286 1296 1287 C_HEADER = """
Note: See TracChangeset
for help on using the changeset viewer.