o
    2g5                     @  s  d Z ddlmZ ddlmZmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z# dd	l$m%Z%m&Z& dd
l'm(Z(m)Z) ddl*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5m6Z6 dAddZ7dBddZ8dCddZ9dAddZ:dAddZ;dDd d!Z<dEd,d-Z=dFd/d0Z>dGd1d2Z?dHd4d5Z@dHd6d7ZAdHd8d9ZBdGd:d;ZCdGd<d=ZDdAd>d?ZEd@S )Ia  Generate IR for generator functions.

A generator function is represented by a class that implements the
generator protocol and keeps track of the generator state, including
local variables.

The top-level logic for dealing with generator functions is in
mypyc.irbuild.function.
    )annotations)ARG_OPTVar)ENV_ATTR_NAMENEXT_LABEL_ATTR_NAME	SELF_NAME)ClassIR)FuncDeclFuncIRFuncSignature
RuntimeArg)NO_TRACEBACK_LINE_NO
BasicBlockBranchCallGotoInteger
MethodCallRaiseStandardErrorRegisterReturnSetAttrTupleSetUnreachableValue)	RInstanceint_rprimitiveobject_rprimitive)	IRBuildergen_arg_defaults)FuncInfoGeneratorClass)add_args_to_envfinalize_env_classload_env_registersload_outer_env)ExceptNonlocalControl)error_catch_opexc_matches_opraise_exception_with_tb_opreraise_exception_oprestore_exc_info_opbuilderr   returnNonec                 C  s6   t |  t|  t|  t|  | tt|  d S N)setup_generator_classr$   r   r#   addr   instantiate_generator_class)r,    r3   O/home/garg/my-data/venv/lib/python3.10/site-packages/mypyc/irbuild/generator.pygen_generator_func4   s
   r5   r   c                 C  sx   | j j}| t| j jjjg |j}| j jr| j j	j
}n| j j
}| t|t||j td}| t|t||j |S )Nr   )fn_infofitemr1   r   generator_classirctorline	is_nestedcallable_classcurr_env_regr   r   r   r   )r,   r7   generator_regr>   zeror3   r3   r4   r2   <   s   r2   r   c                 C  sV   | j   d}t|| jdd}t| j j|jt< |g|_| j	
| t|| j _|S )N_genT)is_generated)r6   namespaced_namer   module_namer   	env_class
attributesr   mroclassesappendr!   r8   )r,   namegenerator_class_irr3   r3   r4   r0   S   s   r0   c                 C  s8   |  t| jjj t }| jjj| | | d S r/   )	r1   r   r6   r8   switch_blockr   continuation_blocksrI   activate_block)r,   blockr3   r3   r4   !create_switch_for_generator_class_   s   rP   c                 C  s   | j j}| j jj}| |j t|jD ]\}}t }| 	|j
t|d|}| ||| | | q| ttjd | | t  d S )Nz==)r6   r8   r7   r;   rN   rL   	enumeraterM   r   	binary_opnext_label_regr   add_bool_branchr1   r   STOP_ITERATIONr   )r,   clsr;   label
true_blockfalse_block
comparisonr3   r3   r4   #populate_switch_for_generator_classf   s   
r[   r;   intc           	      C  s   | j j}|jdusJ |j\}}}t }t }| ||  d|}| ||| | | | t	|||g| | 
t  | | dS )zAdd error handling blocks to a generator class.

    Generates blocks to check if error flags are set while calling the
    helper method for generator functions, and raises an exception if
    those flags are set.
    Nzis not)r6   r8   exc_regsr   translate_is_opnone_objectrT   rN   call_cr)   r1   r   goto_and_activate)	r,   r;   rV   exc_typeexc_valexc_tberror_blockok_blockrZ   r3   r3   r4   -add_raise_exception_blocks_to_generator_classu   s   
rg   r6   r    sigr   arg_regslist[Register]blockslist[BasicBlock]is_coroutineboolc                 C  sd   t | ||||}t| ||| t| ||| t| | t| ||| t| | |r0t| | d S d S r/   )add_helper_to_generator_classadd_next_to_generator_classadd_send_to_generator_classadd_iter_to_generator_classadd_throw_to_generator_classadd_close_to_generator_classadd_await_to_generator_class)r,   r6   rh   ri   rk   rm   helper_fn_declr3   r3   r4   add_methods_to_generator_class   s   

rw   r	   c                 C  s   t ttttdttdttdttdtf|j}td|jjj| j	|}t
||||jj|jjd}||jjjd< | j| |S )zRGenerates a helper method for a generator class, called by '__next__' and 'throw'.typevalue	tracebackarg__mypyc_generator_helper__)traceback_name)r   r   r   r   ret_typer	   r8   r9   rJ   rD   r
   r7   r;   methods	functionsrI   )r,   ri   rk   rh   r6   rv   helper_fn_irr3   r3   r4   ro      s$   
ro   c                 C  L   |  |jjdt| | t|   W d   dS 1 sw   Y  dS )z6Generates the '__iter__' method for a generator class.__iter__Nenter_methodr8   r9   r   r1   r   selfr,   r6   r3   r3   r4   rr         "rr   fn_declc              
   C  st   |  |jjdt|& |  }| t||  ||||g|jj	}| t
| W d   dS 1 s3w   Y  dS )z6Generates the '__next__' method for a generator class.__next__N)r   r8   r9   r   r_   r1   r   r   r7   r;   r   )r,   r6   r   rh   none_regresultr3   r3   r4   rp      s   "rp   c                 C  s   |  |jjdt|/ | dt}|  }| t||  |||| 	|g|j
j}| t| W d   dS 1 s<w   Y  dS )z2Generates the 'send' method for a generator class.sendr{   N)r   r8   r9   r   add_argumentr_   r1   r   r   readr7   r;   r   )r,   r6   r   rh   r{   r   r   r3   r3   r4   rq      s   "rq   c                   s   |  |jjdt|_ | dt}| dtt}| dtt}|   | | fdd| jj	j
 | | fdd| jj	j
 | t||  | || || | g|j	j
}| t| W d   dS 1 slw   Y  dS )	z3Generates the 'throw' method for a generator class.throwrx   ry   rz   c                         S r/   r3   r3   r   r3   r4   <lambda>       z.add_throw_to_generator_class.<locals>.<lambda>c                     r   r/   r3   r3   r   r3   r4   r      r   N)r   r8   r9   r   r   r   r_   assign_if_nullr6   r7   r;   r1   r   r   r   r   )r,   r6   r   rh   typvaltbr   r3   r   r4   rs      s    ""rs   c              
   C  s  |  |jjdt| t t }}| j| | t  | d|j	j
}| t|  d||  |  g | | | j  | | | tg |j	j
}| jt| jd | | d|j	j
}| t||g|j	j
}| t|g|j	j
}t t }	}
| t||	|
tj | |	 | t| |g|j	j
 | t|   | |
 | tg t | t   | j!  | | | t"t"j#d|j	j
 | t   W d   dS 1 sw   Y  dS )z7Generates the '__close__' method for a generator class.closezbuiltins.GeneratorExitr   zbuiltins.StopIterationzgenerator ignored GeneratorExitN)$r   r8   r9   r   r   r,   push_error_handlerra   load_module_attr_by_fullnamer7   r;   r1   r   r   r_   gotopop_error_handlerrN   r`   r'   nonlocal_controlrI   r&   r   r(   r   BOOLr+   r   r   r*   r   r   popr   RUNTIME_ERROR)r,   r6   except_block
else_blockgenerator_exitold_excstop_iteration
exceptionsmatchesmatch_blocknon_match_blockr3   r3   r4   rt      sZ   






"rt   c                 C  r   )z7Generates the '__await__' method for a generator class.	__await__Nr   r   r3   r3   r4   ru   5  r   ru   c                 C  s   | j j}| j j}| |j}| jtdtdd}| jtdtdd}| jtdtdd}| jtdtdd}|||f|_||_	| 
||j|_t| |j| jd |_| jttt|dd	|_t| d|dd
 | 
|j|j|_dS )z0Populates the environment for a generator class.rx   T)is_argry   rz   r{   r   F)reassign)localbaser   N)r6   r7   r8   add_self_to_envr9   	add_localr   r   r]   send_arg_regr   r;   self_regr%   	symtablesr>   add_var_to_env_classr   r   next_label_targetr"   rS   )r,   r7   rV   self_targetrb   rc   rd   exc_argr3   r3   r4   setup_env_for_generator_class;  s    r   N)r,   r   r-   r.   )r,   r   r-   r   )r,   r   r-   r   )r,   r   r;   r\   r-   r.   )r,   r   r6   r    rh   r   ri   rj   rk   rl   rm   rn   r-   r.   )r,   r   ri   rj   rk   rl   rh   r   r6   r    r-   r	   )r,   r   r6   r    r-   r.   )
r,   r   r6   r    r   r	   rh   r   r-   r.   )F__doc__
__future__r   
mypy.nodesr   r   mypyc.commonr   r   r   mypyc.ir.class_irr   mypyc.ir.func_irr	   r
   r   r   mypyc.ir.opsr   r   r   r   r   r   r   r   r   r   r   r   r   r   mypyc.ir.rtypesr   r   r   mypyc.irbuild.builderr   r   mypyc.irbuild.contextr    r!   mypyc.irbuild.env_classr"   r#   r$   r%   mypyc.irbuild.nonlocalcontrolr&   mypyc.primitives.exc_opsr'   r(   r)   r*   r+   r5   r2   r0   rP   r[   rg   rw   ro   rr   rp   rq   rs   rt   ru   r   r3   r3   r3   r4   <module>   s8    
@
	












6