o
    2g0                     @  s  d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZmZmZmZ ddlmZ ddlmZmZ er@ddlmZ G d	d
 d
ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdS )zHelpers for dealing with nonlocal control such as 'break' and 'return'.

Model how these behave differently in different contexts.
    )annotations)abstractmethod)TYPE_CHECKING)	NO_TRACEBACK_LINE_NO
BasicBlockBranchGotoIntegerRegisterReturnUnreachableValue)AssignmentTarget)restore_exc_info_opset_stop_iteration_value)	IRBuilderc                   @  s:   e Zd ZdZeddd	Zedd
dZedddZdS )NonlocalControla  ABC representing a stack frame of constructs that modify nonlocal control flow.

    The nonlocal control flow constructs are break, continue, and
    return, and their behavior is modified by a number of other
    constructs.  The most obvious is loop, which override where break
    and continue jump to, but also `except` (which needs to clear
    exc_info when left) and (eventually) finally blocks (which need to
    ensure that the finally block is always executed when leaving the
    try/except blocks).
    builderr   lineintreturnNonec                 C     d S N selfr   r   r   r   U/home/garg/my-data/venv/lib/python3.10/site-packages/mypyc/irbuild/nonlocalcontrol.py	gen_break)      zNonlocalControl.gen_breakc                 C  r   r   r   r   r   r   r   gen_continue-   r   zNonlocalControl.gen_continuevaluer   c                 C  r   r   r   r   r   r!   r   r   r   r   
gen_return1   r   zNonlocalControl.gen_returnNr   r   r   r   r   r   r   r   r!   r   r   r   r   r   )__name__
__module____qualname____doc__r   r   r    r#   r   r   r   r   r      s    r   c                   @  s.   e Zd ZdZddd	Zdd
dZdddZdS )BaseNonlocalControlz?Default nonlocal control outside any statements that affect it.r   r   r   r   r   r   c                 C     J d)NFzbreak outside of loopr   r   r   r   r   r   9      zBaseNonlocalControl.gen_breakc                 C  r+   )NFzcontinue outside of loopr   r   r   r   r   r    <   r,   z BaseNonlocalControl.gen_continuer!   r   c                 C  s   | t| d S r   )addr   r"   r   r   r   r#   ?   s   zBaseNonlocalControl.gen_returnNr$   r%   )r&   r'   r(   r)   r   r    r#   r   r   r   r   r*   6   s
    

r*   c                   @  s8   e Zd ZdZdd	d
ZdddZdddZdddZdS )LoopNonlocalControlzNonlocal control within a loop.outerr   continue_blockr   break_blockr   r   c                 C  s   || _ || _|| _d S r   )r/   r0   r1   )r   r/   r0   r1   r   r   r   __init__F   s   
zLoopNonlocalControl.__init__r   r   r   r   c                 C     | t| j d S r   )r-   r   r1   r   r   r   r   r   M      zLoopNonlocalControl.gen_breakc                 C  r3   r   )r-   r   r0   r   r   r   r   r    P   r4   z LoopNonlocalControl.gen_continuer!   r   c                 C  s   | j ||| d S r   )r/   r#   r"   r   r   r   r#   S   r4   zLoopNonlocalControl.gen_returnN)r/   r   r0   r   r1   r   r   r   r$   r%   r&   r'   r(   r)   r2   r   r    r#   r   r   r   r   r.   C   s    


r.   c                   @  s   e Zd ZdZdd
dZdS )GeneratorNonlocalControlzDDefault nonlocal control in a generator function outside statements.r   r   r!   r   r   r   r   r   c                 C  sZ   | |jjjtd| |jd  |t  |	t
|gt |t  |j  d S N)assignfn_infogenerator_classnext_label_targetr	   r   push_error_handlergoto_and_activater   call_cr   r   r-   r   pop_error_handlerr"   r   r   r   r#   Z   s   	z#GeneratorNonlocalControl.gen_returnNr%   )r&   r'   r(   r)   r#   r   r   r   r   r6   W   s    r6   c                   @  sF   e Zd ZdZdddZedddZdddZdddZdddZ	dS )CleanupNonlocalControlz6Abstract nonlocal control that runs some cleanup code.r/   r   r   r   c                 C  s
   || _ d S r   )r/   )r   r/   r   r   r   r2   w   s   
zCleanupNonlocalControl.__init__r   r   r   r   c                 C  r   r   r   r   r   r   r   gen_cleanupz   s   z"CleanupNonlocalControl.gen_cleanupc                 C     |  || | j|| d S r   )rB   r/   r   r   r   r   r   r   }      z CleanupNonlocalControl.gen_breakc                 C  rC   r   )rB   r/   r    r   r   r   r   r       rD   z#CleanupNonlocalControl.gen_continuer!   r   c                 C  s    |  || | j||| d S r   )rB   r/   r#   r"   r   r   r   r#      s   z!CleanupNonlocalControl.gen_returnN)r/   r   r   r   r$   r%   )
r&   r'   r(   r)   r2   r   rB   r   r    r#   r   r   r   r   rA   t   s    


rA   c                   @  s8   e Zd ZdZdddZdddZdddZdddZdS )TryFinallyNonlocalControlz$Nonlocal control within try/finally.targetr   r   r   c                 C  s   || _ d | _d S r   )rF   ret_reg)r   rF   r   r   r   r2      s   
z"TryFinallyNonlocalControl.__init__r   r   r   r   c                 C     | d| d S )Nz/break inside try/finally block is unimplementederrorr   r   r   r   r         z#TryFinallyNonlocalControl.gen_breakc                 C  rH   )Nz2continue inside try/finally block is unimplementedrI   r   r   r   r   r       rK   z&TryFinallyNonlocalControl.gen_continuer!   r   c                 C  sn   | j d u r|jjr||jd | _ nt|jd | _ t| j ttfs%J || j || |	t
| j d S r7   )rG   r:   is_generatormake_spill_target	ret_typesr
   
isinstancer   r9   r-   r   rF   r"   r   r   r   r#      s   
z$TryFinallyNonlocalControl.gen_returnN)rF   r   r   r   r$   r%   r5   r   r   r   r   rE      s    


rE   c                      ,   e Zd ZdZd fdd	ZdddZ  ZS )ExceptNonlocalControlzNonlocal control for except blocks.

    Just makes sure that sys.exc_info always gets restored when we leave.
    This is super annoying.
    r/   r   savedValue | AssignmentTargetr   r   c                      t  | || _d S r   superr2   rR   r   r/   rR   	__class__r   r   r2         
zExceptNonlocalControl.__init__r   r   r   r   c                 C  s   | t|| jg| d S r   )r?   r   readrR   r   r   r   r   rB      s   z!ExceptNonlocalControl.gen_cleanup)r/   r   rR   rS   r   r   r$   r&   r'   r(   r)   r2   rB   __classcell__r   r   rX   r   rQ          rQ   c                      rP   )FinallyNonlocalControlzNonlocal control for finally blocks.

    Just makes sure that sys.exc_info always gets restored when we
    leave and the return register is decrefed if it isn't null.
    r/   r   rR   r   r   r   c                   rT   r   rU   rW   rX   r   r   r2      rZ   zFinallyNonlocalControl.__init__r   r   r   r   c                 C  sP   t  t  }}|t| j||tj || |t| jg| || d S r   )	r   r-   r   rR   IS_ERRORactivate_blockr?   r   r>   )r   r   r   rF   cleanupr   r   r   rB      s
   
z"FinallyNonlocalControl.gen_cleanup)r/   r   rR   r   r   r   r$   r\   r   r   rX   r   r_      r^   r_   N) r)   
__future__r   abcr   typingr   mypyc.ir.opsr   r   r   r   r	   r
   r   r   r   mypyc.irbuild.targetsr   mypyc.primitives.exc_opsr   r   mypyc.irbuild.builderr   r   r*   r.   r6   rA   rE   rQ   r_   r   r   r   r   <module>   s"    ,