1515from .check_syntax import check_syntax
1616import re
1717
18+
1819def wrap_loops_for_optimization (code ):
1920 """
2021 Rewrites for/while loops with <OPTIMIZE ...> annotations into runtime functions
@@ -42,7 +43,8 @@ def wrap_loops_for_optimization(code):
4243 if parallel and loop_line .startswith ("for " ):
4344 loop_match = re .match (r'for\s+(.*?)\s+in\s+(.*):?' , loop_line )
4445 loop_vars = loop_match .group (1 ).strip () # type: ignore
45- iter_expr = loop_match .group (2 ).strip ().rstrip (':' ) # type: ignore
46+ iter_expr = loop_match .group (
47+ 2 ).strip ().rstrip (':' ) # type: ignore
4648 is_tuple_unpack = ',' in loop_vars
4749
4850 body_func_name = f"_repy_loop_body_{ loop_counter } "
@@ -69,31 +71,42 @@ def wrap_loops_for_optimization(code):
6971 loop_counter += 1
7072
7173 modified_lines .append (" " * loop_indent + decorator_line )
72- modified_lines .append (" " * loop_indent + f"def { body_func_name } ({ loop_vars } ):" )
74+ modified_lines .append (
75+ " " * loop_indent + f"def { body_func_name } ({ loop_vars } ):" )
7376 modified_lines .extend (loop_body )
7477
7578 # Emit executor function
76- modified_lines .append (" " * loop_indent + f"def { func_name } ():" )
79+ modified_lines .append (
80+ " " * loop_indent + f"def { func_name } ():" )
7781 executor_type = "ThreadPoolExecutor"
78- modified_lines .append (" " * (loop_indent + 4 ) + f"from concurrent.futures import { executor_type } " )
82+ modified_lines .append (
83+ " " * (loop_indent + 4 ) + f"from concurrent.futures import { executor_type } " )
7984
8085 if is_tuple_unpack :
81- modified_lines .append (" " * (loop_indent + 4 ) + "def starmap_pool(fn, iterable):" )
82- modified_lines .append (" " * (loop_indent + 8 ) + f"with { executor_type } () as pool:" )
83- modified_lines .append (" " * (loop_indent + 12 ) + "futures = [pool.submit(fn, *args) for args in iterable]" )
84- modified_lines .append (" " * (loop_indent + 12 ) + "return [f.result() for f in futures]" )
85- modified_lines .append (" " * (loop_indent + 4 ) + f"starmap_pool({ body_func_name } , { iter_expr } )" )
86+ modified_lines .append (
87+ " " * (loop_indent + 4 ) + "def starmap_pool(fn, iterable):" )
88+ modified_lines .append (
89+ " " * (loop_indent + 8 ) + f"with { executor_type } () as pool:" )
90+ modified_lines .append (
91+ " " * (loop_indent + 12 ) + "futures = [pool.submit(fn, *args) for args in iterable]" )
92+ modified_lines .append (
93+ " " * (loop_indent + 12 ) + "return [f.result() for f in futures]" )
94+ modified_lines .append (
95+ " " * (loop_indent + 4 ) + f"starmap_pool({ body_func_name } , { iter_expr } )" )
8696 else :
87- modified_lines .append (" " * (loop_indent + 4 ) + f"with { executor_type } () as pool:" )
88- modified_lines .append (" " * (loop_indent + 8 ) + f"list(pool.map({ body_func_name } , { iter_expr } ))" )
97+ modified_lines .append (
98+ " " * (loop_indent + 4 ) + f"with { executor_type } () as pool:" )
99+ modified_lines .append (
100+ " " * (loop_indent + 8 ) + f"list(pool.map({ body_func_name } , { iter_expr } ))" )
89101
90102 # Call the executor function
91103 modified_lines .append (" " * loop_indent + f"{ func_name } ()" )
92104
93105 else :
94106 # Non-parallel loop: wrap as usual
95107 modified_lines .append (" " * loop_indent + decorator_line )
96- modified_lines .append (" " * loop_indent + f"def { func_name } ():" )
108+ modified_lines .append (
109+ " " * loop_indent + f"def { func_name } ():" )
97110 modified_lines .append (" " * (loop_indent + 4 ) + loop_line )
98111 i += 2
99112 loop_body = []
@@ -111,31 +124,38 @@ def wrap_loops_for_optimization(code):
111124 loop_body .append (" " * new_indent + body_line .lstrip ())
112125 i += 1
113126
114- if unroll_factor > 1 and loop_line .startswith ("for " ) and "range(" in loop_line :
127+ if unroll_factor > 1 and loop_line .startswith (
128+ "for " ) and "range(" in loop_line :
115129 range_match = re .search (r'range\(([^)]+)\)' , loop_line )
116130 if range_match :
117131 range_args = range_match .group (1 ).split (',' )
118132 if len (range_args ) == 1 :
119- start , end , step = "0" , range_args [0 ].strip (), str (unroll_factor )
133+ start , end , step = "0" , range_args [0 ].strip (), str (
134+ unroll_factor )
120135 elif len (range_args ) == 2 :
121- start , end = range_args [0 ].strip (), range_args [1 ].strip ()
136+ start , end = range_args [0 ].strip (
137+ ), range_args [1 ].strip ()
122138 step = str (unroll_factor )
123139 elif len (range_args ) == 3 :
124- start , end , step = [arg .strip () for arg in range_args ]
140+ start , end , step = [arg .strip ()
141+ for arg in range_args ]
125142 step = f"({ step } ) * { unroll_factor } "
126143
127- var_match = re .match (r'for\s+(\w+)\s+in\s+range' , loop_line )
144+ var_match = re .match (
145+ r'for\s+(\w+)\s+in\s+range' , loop_line )
128146 loop_var = var_match .group (1 ) if var_match else "i"
129147
130148 new_loop_line = f"for { loop_var } in range({ start } , { end } , { step } ):"
131- modified_lines [- 1 ] = " " * (loop_indent + 4 ) + new_loop_line
149+ modified_lines [- 1 ] = " " * \
150+ (loop_indent + 4 ) + new_loop_line
132151
133152 for offset in range (unroll_factor ):
134153 for body in loop_body :
135154 if offset == 0 :
136155 unrolled_line = body
137156 else :
138- unrolled_line = re .sub (rf'\b{ loop_var } \b' , f"{ loop_var } +{ offset } " , body )
157+ unrolled_line = re .sub (
158+ rf'\b{ loop_var } \b' , f"{ loop_var } +{ offset } " , body )
139159 modified_lines .append (unrolled_line )
140160 else :
141161 modified_lines .extend (loop_body )
@@ -221,7 +241,8 @@ def nest(parts):
221241 required_imports .add ("optimize_loop" )
222242 pending_optimize = None
223243 elif re .match (r'^\s*def\s+.*\{' , processed_line ):
224- modified_code .append (" " * loop_indent + f"@optimize_function({ pending_optimize } )" )
244+ modified_code .append (
245+ " " * loop_indent + f"@optimize_function({ pending_optimize } )" )
225246 required_imports .add ("optimize_function" )
226247 pending_optimize = None
227248
0 commit comments