Changes in / [5ab99b7:d5014e4] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/py2c.py
rd7f33e5 r0bd0877 112 112 # Update Notes 113 113 # ============ 114 # 11/22/2017, O.E.Each 'visit_*' method is to build a C statement string. It115 # shold insert 4 blanks per indentation level.116 # The 'body' method will combine all the strings, by adding117 # the'current_statement' to the c_proc string list118 # 11/2017, OE: variables, argument definition implemented.119 # Note: Anargument is considered an array if it is the target of an120 # assignment. In that case it is translated to <var>[0]121 # 11/27/2017, OE: 'pow' basicly working122 # /12/2017, OE: Multiple assignment: a1,a2,...,an=b1,b2,...bn implemented123 # /12/2017, OE: Power function, including special cases of114 # 2017-11-22, OE: Each 'visit_*' method is to build a C statement string. It 115 # shold insert 4 blanks per indentation level. The 'body' 116 # method will combine all the strings, by adding the 117 # 'current_statement' to the c_proc string list 118 # 2017-11-22, OE: variables, argument definition implemented. Note: An 119 # argument is considered an array if it is the target of an 120 # assignment. In that case it is translated to <var>[0] 121 # 2017-11-27, OE: 'pow' basicly working 122 # 2017-12-07, OE: Multiple assignment: a1,a2,...,an=b1,b2,...bn implemented 123 # 2017-12-07, OE: Power function, including special cases of 124 124 # square(x)(pow(x,2)) and cube(x)(pow(x,3)), implemented in 125 125 # translate_power, called from visit_BinOp 126 # 12/07/2017, OE: Translation of integer division, '\\' in python, implemented126 # 2017-12-07, OE: Translation of integer division, '\\' in python, implemented 127 127 # in translate_integer_divide, called from visit_BinOp 128 # 12/07/2017, OE: C variable definition handled in 'define_c_vars'128 # 2017-12-07, OE: C variable definition handled in 'define_c_vars' 129 129 # : Python integer division, '//', translated to C in 130 130 # 'translate_integer_divide' 131 # 12/15/2017, OE: Precedence maintained by writing opening and closing131 # 2017-12-15, OE: Precedence maintained by writing opening and closing 132 132 # parenthesesm '(',')', in procedure 'visit_BinOp'. 133 # 12/18/2017, OE: Added call to 'add_current_line()' at the beginning133 # 2017-12-18, OE: Added call to 'add_current_line()' at the beginning 134 134 # of visit_Return 135 135 # 2018-01-03, PK: Update interface for use in sasmodels … … 140 140 # 2018-01-03, PK: simplistic print function, for debugging 141 141 # 2018-01-03, PK: while expr: ... => while (expr) { ... } 142 # 2018-01-04, OE: Fixed bug in 'visit_If': visiting node.orelse in case else exists. 142 143 143 144 from __future__ import print_function … … 184 185 185 186 186 def to_source(tree, constants=None, fname=None, lineno=0): 187 """ 188 This function can convert a syntax tree into C sourcecode. 189 """ 190 generator = SourceGenerator(constants=constants, fname=fname, lineno=lineno) 191 generator.visit(tree) 192 c_code = "".join(generator.c_proc) 193 return c_code 194 187 # TODO: should not allow eval of arbitrary python 195 188 def isevaluable(s): 196 189 try: … … 329 322 except AttributeError: 330 323 arg_name = arg.id 331 w_str = (" Default Parameters are unknown to C: '%s =%s"324 w_str = ("C does not support default parameters: %s=%s" 332 325 % (arg_name, str(default.n))) 333 326 self.warnings.append(w_str) … … 508 501 self.current_function = node.name 509 502 503 # remember the location of the next warning that will be inserted 504 # so that we can stuff the function name ahead of the warning list 505 # if any warnings are generated by the function. 506 warning_index = len(self.warnings) 507 510 508 self.newline(extra=1) 511 509 self.decorators(node) … … 523 521 del self.c_pointers[:] 524 522 self.current_function = "" 523 if warning_index != len(self.warnings): 524 self.warnings.insert(warning_index, "Warning in function '" + node.name + "':") 525 525 526 526 def visit_ClassDef(self, node): … … 586 586 self.newline() 587 587 self.write_c('else {') 588 self.body( node.body)588 self.body(else_) 589 589 self.add_c_line('}') 590 590 break … … 615 615 return start, stop, step 616 616 617 def add_c_int_var(self, name): 618 if name not in self.c_int_vars: 619 self.c_int_vars.append(name) 620 617 621 def visit_For(self, node): 618 622 # node: for iterator is stored in node.target. … … 627 631 iterator = self.current_statement 628 632 self.current_statement = '' 629 if iterator not in self.c_int_vars: 630 self.c_int_vars.append(iterator) 633 self.add_c_int_var(iterator) 631 634 start, stop, step = self.get_for_range(node) 632 635 self.write_c("for (" + iterator + "=" + str(start) + … … 736 739 self.write_c('return') 737 740 else: 738 self.write_c('return (')741 self.write_c('return ') 739 742 self.visit(node.value) 740 self.write_c(')')741 743 self.add_semi_colon() 742 744 self.in_expr = False … … 855 857 name not in self.c_constants and not name.isdigit()): 856 858 if self.in_subscript: 857 self. c_int_vars.append(node.id)859 self.add_c_int_var(node.id) 858 860 else: 859 861 self.c_vars.append(node.id) … … 1252 1254 Convert a list of functions to a list of C code strings. 1253 1255 1256 Returns list of corresponding code snippets (with trailing lines in 1257 each block) and a list of warnings generated by the translator. 1258 1254 1259 A function is given by the tuple (source, filename, line number). 1255 1260 … … 1266 1271 """ 1267 1272 snippets = [] 1268 #snippets.append("#include <math.h>") 1269 #snippets.append("") 1273 warnings = [] 1270 1274 for source, fname, lineno in functions: 1271 1275 line_directive = '#line %d "%s"\n'%(lineno, fname.replace('\\', '\\\\')) … … 1275 1279 source = PRINT_STR.sub(SUBST_STR, source) 1276 1280 tree = ast.parse(source) 1277 c_code = to_source(tree, constants=constants, fname=fname, lineno=lineno) 1281 generator = SourceGenerator(constants=constants, fname=fname, lineno=lineno) 1282 generator.visit(tree) 1283 c_code = "".join(generator.c_proc) 1278 1284 snippets.append(c_code) 1279 return snippets 1280 1281 def main(): 1282 import os 1283 #print("Parsing...using Python" + sys.version) 1284 if len(sys.argv) == 1: 1285 print("""\ 1286 Usage: python py2c.py <infile> [<outfile>] 1287 1288 if outfile is omitted, output file is '<infile>.c' 1289 """) 1290 return 1291 1292 fname_in = sys.argv[1] 1293 if len(sys.argv) == 2: 1294 fname_base = os.path.splitext(fname_in)[0] 1295 fname_out = str(fname_base) + '.c' 1296 else: 1297 fname_out = sys.argv[2] 1298 1299 with open(fname_in, "r") as python_file: 1300 code = python_file.read() 1301 name = "gauss" 1302 code = (code 1303 .replace(name+'.n', 'GAUSS_N') 1304 .replace(name+'.z', 'GAUSS_Z') 1305 .replace(name+'.w', 'GAUSS_W') 1306 .replace('if __name__ == "__main__"', "def main()") 1307 ) 1308 1309 1310 c_code = "".join(translate([(code, fname_in, 1)])) 1311 c_code = c_code.replace("double main()", "int main(int argc, char *argv[])") 1312 1313 with open(fname_out, "w") as file_out: 1314 file_out.write(""" 1285 warnings.extend(generator.warnings) 1286 return snippets, warnings 1287 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_code 1294 1295 1296 C_HEADER = """ 1315 1297 #include <stdio.h> 1316 1298 #include <stdbool.h> … … 1330 1312 return ans; 1331 1313 } 1332 1333 """) 1314 """ 1315 1316 USAGE = """\ 1317 Usage: python py2c.py <infile> [<outfile>] 1318 1319 if outfile is omitted, output file is '<infile>.c' 1320 """ 1321 1322 def main(): 1323 import os 1324 #print("Parsing...using Python" + sys.version) 1325 if len(sys.argv) == 1: 1326 print(USAGE) 1327 return 1328 1329 fname_in = sys.argv[1] 1330 if len(sys.argv) == 2: 1331 fname_base = os.path.splitext(fname_in)[0] 1332 fname_out = str(fname_base) + '.c' 1333 else: 1334 fname_out = sys.argv[2] 1335 1336 with open(fname_in, "r") as python_file: 1337 code = python_file.read() 1338 name = "gauss" 1339 code = (code 1340 .replace(name+'.n', 'GAUSS_N') 1341 .replace(name+'.z', 'GAUSS_Z') 1342 .replace(name+'.w', 'GAUSS_W') 1343 .replace('if __name__ == "__main__"', "def main()") 1344 ) 1345 1346 translation, warnings = translate([(code, fname_in, 1)]) 1347 c_code = "".join(translation) 1348 c_code = c_code.replace("double main()", "int main(int argc, char *argv[])") 1349 1350 with open(fname_out, "w") as file_out: 1351 file_out.write(C_HEADER) 1334 1352 file_out.write(c_code) 1353 1354 if warnings: 1355 print("\n".join(warnings)) 1335 1356 #print("...Done") 1336 1357
Note: See TracChangeset
for help on using the changeset viewer.