Generate IR based on the body of a generator function. Add "__next__", "__iter__" and other generator methods to the generator class that implements the function (each function gets a separate class). Return the symbol table for the body.
(builder: IRBuilder, fn_info: FuncInfo, func_reg: Value | None)
| 85 | |
| 86 | |
| 87 | def gen_generator_func_body(builder: IRBuilder, fn_info: FuncInfo, func_reg: Value | None) -> None: |
| 88 | """Generate IR based on the body of a generator function. |
| 89 | |
| 90 | Add "__next__", "__iter__" and other generator methods to the generator |
| 91 | class that implements the function (each function gets a separate class). |
| 92 | |
| 93 | Return the symbol table for the body. |
| 94 | """ |
| 95 | builder.enter(fn_info, ret_type=object_rprimitive) |
| 96 | setup_env_for_generator_class(builder) |
| 97 | |
| 98 | load_outer_envs(builder, builder.fn_info.generator_class) |
| 99 | top_level = builder.top_level_fn_info() |
| 100 | fitem = fn_info.fitem |
| 101 | if ( |
| 102 | builder.fn_info.is_nested |
| 103 | and isinstance(fitem, FuncDef) |
| 104 | and top_level |
| 105 | and top_level.add_nested_funcs_to_env |
| 106 | ): |
| 107 | setup_func_for_recursive_call( |
| 108 | builder, fitem, builder.fn_info.generator_class, prefix=GENERATOR_ATTRIBUTE_PREFIX |
| 109 | ) |
| 110 | create_switch_for_generator_class(builder) |
| 111 | add_raise_exception_blocks_to_generator_class(builder, fitem.line) |
| 112 | |
| 113 | add_vars_to_env(builder, prefix=GENERATOR_ATTRIBUTE_PREFIX) |
| 114 | |
| 115 | builder.accept(fitem.body) |
| 116 | builder.maybe_add_implicit_return() |
| 117 | |
| 118 | populate_switch_for_generator_class(builder) |
| 119 | |
| 120 | # Hang on to the local symbol table, since the caller will use it |
| 121 | # to calculate argument defaults. |
| 122 | symtable = builder.symtables[-1] |
| 123 | |
| 124 | args, _, blocks, ret_type, fn_info = builder.leave() |
| 125 | |
| 126 | add_methods_to_generator_class(builder, fn_info, args, blocks, fitem.is_coroutine) |
| 127 | |
| 128 | # Evaluate argument defaults in the surrounding scope, since we |
| 129 | # calculate them *once* when the function definition is evaluated. |
| 130 | calculate_arg_defaults(builder, fn_info, func_reg, symtable) |
| 131 | |
| 132 | |
| 133 | def instantiate_generator_class(builder: IRBuilder) -> Value: |
no test coverage detected
searching dependent graphs…