Changes in / [d5014e4:5ab99b7] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/py2c.py
r0bd0877 rd7f33e5 112 112 # Update Notes 113 113 # ============ 114 # 2017-11-22, OE:Each 'visit_*' method is to build a C statement string. It115 # shold insert 4 blanks per indentation level. The 'body'116 # method will combine all the strings, by adding the117 # 'current_statement' to the c_proc string list118 # 2017-11-22, OE: variables, argument definition implemented. Note: An119 # 120 # 121 # 2017-11-27, OE: 'pow' basicly working122 # 2017-12-07, OE: Multiple assignment: a1,a2,...,an=b1,b2,...bn implemented123 # 2017-12-07, OE: Power function, including special cases of114 # 11/22/2017, O.E. Each 'visit_*' method is to build a C statement string. It 115 # shold insert 4 blanks per indentation level. 116 # The 'body' method will combine all the strings, by adding 117 # the 'current_statement' to the c_proc string list 118 # 11/2017, OE: variables, argument definition implemented. 119 # Note: An argument is considered an array if it is the target of an 120 # assignment. In that case it is translated to <var>[0] 121 # 11/27/2017, OE: 'pow' basicly working 122 # /12/2017, OE: Multiple assignment: a1,a2,...,an=b1,b2,...bn implemented 123 # /12/2017, 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 # 2017-12-07, OE: Translation of integer division, '\\' in python, implemented126 # 12/07/2017, OE: Translation of integer division, '\\' in python, implemented 127 127 # in translate_integer_divide, called from visit_BinOp 128 # 2017-12-07, OE: C variable definition handled in 'define_c_vars'128 # 12/07/2017, OE: C variable definition handled in 'define_c_vars' 129 129 # : Python integer division, '//', translated to C in 130 130 # 'translate_integer_divide' 131 # 2017-12-15, OE: Precedence maintained by writing opening and closing131 # 12/15/2017, OE: Precedence maintained by writing opening and closing 132 132 # parenthesesm '(',')', in procedure 'visit_BinOp'. 133 # 2017-12-18, OE: Added call to 'add_current_line()' at the beginning133 # 12/18/2017, 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.143 142 144 143 from __future__ import print_function … … 185 184 186 185 187 # TODO: should not allow eval of arbitrary python 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 188 195 def isevaluable(s): 189 196 try: … … 322 329 except AttributeError: 323 330 arg_name = arg.id 324 w_str = (" C does not support default parameters: %s=%s"331 w_str = ("Default Parameters are unknown to C: '%s = %s" 325 332 % (arg_name, str(default.n))) 326 333 self.warnings.append(w_str) … … 501 508 self.current_function = node.name 502 509 503 # remember the location of the next warning that will be inserted504 # so that we can stuff the function name ahead of the warning list505 # if any warnings are generated by the function.506 warning_index = len(self.warnings)507 508 510 self.newline(extra=1) 509 511 self.decorators(node) … … 521 523 del self.c_pointers[:] 522 524 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( else_)588 self.body(node.body) 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 621 617 def visit_For(self, node): 622 618 # node: for iterator is stored in node.target. … … 631 627 iterator = self.current_statement 632 628 self.current_statement = '' 633 self.add_c_int_var(iterator) 629 if iterator not in self.c_int_vars: 630 self.c_int_vars.append(iterator) 634 631 start, stop, step = self.get_for_range(node) 635 632 self.write_c("for (" + iterator + "=" + str(start) + … … 739 736 self.write_c('return') 740 737 else: 741 self.write_c('return 738 self.write_c('return(') 742 739 self.visit(node.value) 740 self.write_c(')') 743 741 self.add_semi_colon() 744 742 self.in_expr = False … … 857 855 name not in self.c_constants and not name.isdigit()): 858 856 if self.in_subscript: 859 self. add_c_int_var(node.id)857 self.c_int_vars.append(node.id) 860 858 else: 861 859 self.c_vars.append(node.id) … … 1254 1252 Convert a list of functions to a list of C code strings. 1255 1253 1256 Returns list of corresponding code snippets (with trailing lines in1257 each block) and a list of warnings generated by the translator.1258 1259 1254 A function is given by the tuple (source, filename, line number). 1260 1255 … … 1271 1266 """ 1272 1267 snippets = [] 1273 warnings = [] 1268 #snippets.append("#include <math.h>") 1269 #snippets.append("") 1274 1270 for source, fname, lineno in functions: 1275 1271 line_directive = '#line %d "%s"\n'%(lineno, fname.replace('\\', '\\\\')) … … 1279 1275 source = PRINT_STR.sub(SUBST_STR, source) 1280 1276 tree = ast.parse(source) 1281 generator = SourceGenerator(constants=constants, fname=fname, lineno=lineno) 1282 generator.visit(tree) 1283 c_code = "".join(generator.c_proc) 1277 c_code = to_source(tree, constants=constants, fname=fname, lineno=lineno) 1284 1278 snippets.append(c_code) 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 = """ 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(""" 1297 1315 #include <stdio.h> 1298 1316 #include <stdbool.h> … … 1312 1330 return ans; 1313 1331 } 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) 1332 1333 """) 1352 1334 file_out.write(c_code) 1353 1354 if warnings:1355 print("\n".join(warnings))1356 1335 #print("...Done") 1357 1336
Note: See TracChangeset
for help on using the changeset viewer.