@@ -198,7 +198,7 @@ def parse(self) -> None:
198
198
199
199
print (
200
200
f"Read { len (self .instrs )} instructions, "
201
- f"{ len (self .supers )} supers, "
201
+ f"{ len (self .supers )} supers/macros , "
202
202
f"and { len (self .families )} families from { self .filename } " ,
203
203
file = sys .stderr ,
204
204
)
@@ -289,9 +289,11 @@ def write_instructions(self, filename: str) -> None:
289
289
f .write (f"// Do not edit!\n " )
290
290
291
291
# Write regular instructions
292
+ n_instrs = 0
292
293
for name , instr in self .instrs .items ():
293
294
if instr .kind != "inst" :
294
295
continue # ops are not real instructions
296
+ n_instrs += 1
295
297
f .write (f"\n { indent } TARGET({ name } ) {{\n " )
296
298
if instr .predicted :
297
299
f .write (f"{ indent } PREDICTED({ name } );\n " )
@@ -301,49 +303,60 @@ def write_instructions(self, filename: str) -> None:
301
303
f .write (f"{ indent } }}\n " )
302
304
303
305
# Write super-instructions and macros
304
- # TODO: Cleanup the hacks
305
- for name , sup in self .supers .items ():
306
- f .write (f"\n { indent } TARGET({ sup .name } ) {{\n " )
307
- components = [self .instrs [name ] for name in sup .ops ]
308
- lowest , highest = self .super_macro_analysis (name , components )
309
- current = 0
310
- for i in range (lowest , current ):
311
- f .write (f"{ indent } PyObject *_tmp_{ i - lowest + 1 } = PEEK({ - i } );\n " )
312
- for i in range (current , highest ):
313
- f .write (f"{ indent } PyObject *_tmp_{ i - lowest + 1 } ;\n " )
314
- for i , instr in enumerate (components ):
315
- if i > 0 and sup .kind == "super" :
316
- f .write (f"{ indent } NEXTOPARG();\n " )
317
- f .write (f"{ indent } next_instr++;\n " )
318
- f .write (f"{ indent } {{\n " )
319
- for seffect in reversed (instr .input_effects ):
320
- if seffect .name != "unused" :
321
- f .write (f"{ indent } PyObject *{ seffect .name } = _tmp_{ current - lowest } ;\n " )
322
- current -= 1
323
- for oeffect in instr .output_effects :
324
- if oeffect .name != "unused" :
325
- f .write (f"{ indent } PyObject *{ oeffect .name } ;\n " )
326
- instr .write_body (f , indent , dedent = - 4 )
327
- for oeffect in instr .output_effects :
328
- if oeffect .name != "unused" :
329
- f .write (f"{ indent } _tmp_{ current - lowest + 1 } = { oeffect .name } ;\n " )
330
- current += 1
331
- f .write (f" { indent } }}\n " )
332
- if current > 0 :
333
- f .write (f"{ indent } STACK_GROW({ current } );\n " )
334
- elif current < 0 :
335
- f .write (f"{ indent } STACK_SHRINK({ - current } );\n " )
336
- for i in range (lowest , current ):
337
- f .write (f"{ indent } POKE({ i - lowest + 1 } , _tmp_{ current - i } );\n " )
338
- f .write (f"{ indent } DISPATCH();\n " )
339
- f .write (f"{ indent } }}\n " )
306
+ n_supers = 0
307
+ n_macros = 0
308
+ for sup in self .supers .values ():
309
+ if sup .kind == "super" :
310
+ n_supers += 1
311
+ elif sup .kind == "macro" :
312
+ n_macros += 1
313
+ self .write_super_macro (f , sup , indent )
340
314
341
315
print (
342
- f"Wrote { len ( self . instrs ) } instructions and "
343
- f"{ len ( self . supers ) } super-instructions to { filename } " ,
316
+ f"Wrote { n_instrs } instructions, { n_supers } supers, "
317
+ f"and { n_macros } macros to { filename } " ,
344
318
file = sys .stderr ,
345
319
)
346
320
321
+ def write_super_macro (
322
+ self , f : typing .TextIO , sup : parser .Super , indent : str = ""
323
+ ) -> None :
324
+ f .write (f"\n { indent } TARGET({ sup .name } ) {{\n " )
325
+ components = [self .instrs [name ] for name in sup .ops ]
326
+ lowest , highest = self .super_macro_analysis (sup .name , components )
327
+ # TODO: Rename tmp variables _tmp_A, _tmp_B, etc.
328
+ current = 0
329
+ for i in range (lowest , current ):
330
+ f .write (f"{ indent } PyObject *_tmp_{ i - lowest + 1 } = PEEK({ - i } );\n " )
331
+ for i in range (current , highest ):
332
+ f .write (f"{ indent } PyObject *_tmp_{ i - lowest + 1 } ;\n " )
333
+ for i , instr in enumerate (components ):
334
+ if i > 0 and sup .kind == "super" :
335
+ f .write (f"{ indent } NEXTOPARG();\n " )
336
+ f .write (f"{ indent } next_instr++;\n " )
337
+ f .write (f"{ indent } {{\n " )
338
+ for seffect in reversed (instr .input_effects ):
339
+ if seffect .name != "unused" :
340
+ f .write (f"{ indent } PyObject *{ seffect .name } = _tmp_{ current - lowest } ;\n " )
341
+ current -= 1
342
+ for oeffect in instr .output_effects :
343
+ if oeffect .name != "unused" :
344
+ f .write (f"{ indent } PyObject *{ oeffect .name } ;\n " )
345
+ instr .write_body (f , indent , dedent = - 4 )
346
+ for oeffect in instr .output_effects :
347
+ if oeffect .name != "unused" :
348
+ f .write (f"{ indent } _tmp_{ current - lowest + 1 } = { oeffect .name } ;\n " )
349
+ current += 1
350
+ f .write (f" { indent } }}\n " )
351
+ if current > 0 :
352
+ f .write (f"{ indent } STACK_GROW({ current } );\n " )
353
+ elif current < 0 :
354
+ f .write (f"{ indent } STACK_SHRINK({ - current } );\n " )
355
+ for i in range (lowest , current ):
356
+ f .write (f"{ indent } POKE({ i - lowest + 1 } , _tmp_{ current - i } );\n " )
357
+ f .write (f"{ indent } DISPATCH();\n " )
358
+ f .write (f"{ indent } }}\n " )
359
+
347
360
# TODO: Move this into analysis phase
348
361
def super_macro_analysis (self , name : str , components : list [Instruction ]) -> tuple [int , int ]:
349
362
"""Analyze a super-instruction or macro."""
0 commit comments