NL iaCdZddlmZddlmZddlmZmZmZddl m Z m Z m Z ddl mZddlmZmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZm Z dd l!m"Z"m#Z#m$Z$m%Z%dd l&m'Z'm(Z(m)Z)dd l*m+Z+m,Z,dd l-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4dd l5m6Z6ddl7m8Z8ddl9m:Z:m;Z;mZ> d!dZ?d"dZ@d#dZAd$dZBd%dZCd%dZDd&dZE d'dZF d(dZGd)dZHd*dZId*dZJd*dZKd)dZLd)dZMd%dZNy )+aGenerate 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)Callable)ARG_OPTFuncDefVar) ENV_ATTR_NAMEGENERATOR_ATTRIBUTE_PREFIXNEXT_LABEL_ATTR_NAME)ClassIR)FuncDeclFuncIR)NO_TRACEBACK_LINE_NO BasicBlockBranchCallGotoInteger MethodCallRaiseStandardErrorRegisterReturnSetAttrTupleSet UnreachableValue) RInstanceint32_rprimitiveobject_pointer_rprimitiveobject_rprimitive) IRBuildercalculate_arg_defaultsgen_arg_defaults)FuncInfoGeneratorClass)add_args_to_envadd_vars_to_envfinalize_env_classload_env_registersload_outer_envload_outer_envssetup_func_for_recursive_call)ExceptNonlocalControl)GENERATOR_HELPER_NAME)error_catch_opexc_matches_opraise_exception_with_tb_opreraise_exception_oprestore_exc_info_opct|t|tt||jj r.t |}||j_t|tnt|tt |}|jt||j\}}}}}||||\}} || fS)zAGenerate IR for generator function that returns generator object.prefix) setup_generator_classr(r r"fn_info#can_merge_generator_and_env_classesinstantiate_generator_class _curr_env_regr'addrleave) builder gen_func_irgenargs_blocksret_typer7func_irfunc_regs ]/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/mypyc/irbuild/generator.pygen_generator_funcrG?s'"w'ABW::<)'2(+%7+EF7+EF)'2 KKs )0&D!VXw#D&':GX H c|j|tt|t||jj |j }|j}|jjrEt|tr5|r3|jr't|||jj tt|t||j t#|t|j%|j&|j)t+||j,d}|j/\}}}} }t1|||||j2t5||||y)aGenerate 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. )rCr4N)enterrsetup_env_for_generator_classr*r7generator_classtop_level_fn_infofitem is_nested isinstanceradd_nested_funcs_to_envr+r !create_switch_for_generator_class-add_raise_exception_blocks_to_generator_classliner&acceptbodymaybe_add_implicit_return#populate_switch_for_generator_class symtablesr<add_methods_to_generator_class is_coroutiner!) r=r7rE top_levelrOsymtabler@rArBrCs rFgen_generator_func_bodyr_Ws MM'$5M6!'*GW__<<=))+I MME!! ug &   - -% UGOO;;D^ &g.1'5::FG$>? NN5:: %%''0  $H)0&D!VXw"7GT65CUCUV7GXx@rHc|jj}|jt|jjj j g|j}|jjr8td}|jt|t||j|S|jjr!|jjj}n|jj}|jt|t||jtd}|jt|t||j|S)Nr)r7rOr;rrMirctorrUr8rrr rPcallable_class curr_env_regr)r=rO generator_regzerords rFr9r9s OO ! !EKKW__%D%D%G%G%L%LbRWR\R\ ]^M::<qz GM+?uzzRS$  ?? $ $"??99FFL"??77L  GM=, STqz GL*>ejjQR rHc|j}t|jjtsJ|jj|j |jj}|jj r||j_n0t|jj|jt<|g|_ |jj|t||j_|SN)mapperrQr7rOrfdef_to_generatorr8 env_classr attributesrmroclassesappendr$rM)r=rigenerator_class_irs rFr6r6s ^^F goo++W 5Lw7L7LL 511'//2G2GH::<$6!7@AZAZ7[%%m401 OO-.&45G&HGOO# rHc|jt|jjjt }|jjj j||j|yrh) r;rr7rM switch_blockrcontinuation_blocksroactivate_block)r=blocks rFrSrSsV KKW__44AABC LE OO##77>>uE 5!rHc|jj}|jjj}|j |j t |jD]Z\}}t}|j|jt|d|}|j||||j |\|jttjd||jt!y)Nz==)r7rMrOrUrtrr enumeratersr binary_opnext_label_regradd_bool_branchr;rSTOP_ITERATIONr)r=clsrUlabel true_block false_block comparisons rFrYrYs // ) )C ?? % %D 3++,&s'>'>?,z l &&s'9'975>4QUV  J D{+ ,  KK"#5#D#DdDQR KK rHc|jj}|jJ|j\}}}t}t}|j ||j d|}|j ||||j||jt|||g||jt|j|y)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. Nzis not) r7rMexc_regsrtranslate_is_op none_objectrzrtcall_cr0r;rgoto_and_activate) r=rUr|exc_typeexc_valexc_tb error_blockok_blockrs rFrTrTs // ) )C << ## # # Hgv,K|H((73F3F3H(TXYJ J X> ;' NN-'6/JDQ KK  h'rHct||||}t|||t|||t||t |||t |||r t ||yyrh)add_helper_to_generator_classadd_next_to_generator_classadd_send_to_generator_classadd_iter_to_generator_classadd_throw_to_generator_classadd_close_to_generator_classadd_await_to_generator_class)r=r7arg_regsrBr\helper_fn_decls rFr[r[s^37HfgVN.A.A1 '>B '2$Wg6rHcj|jjjt}t ||||j j |j j}||jjjt<|jj|||j_ |S)zRGenerates a helper method for a generator class, called by '__next__' and 'throw'.)traceback_name) rMra method_declsr-r rOrUnamemethods functionsrorkenv_user_function)r=rrBr7r helper_fn_irs rFrrs,,//<<=RSN&'--*<**+,,, )AA(c~|j|jjdt|5|j }|j t ||j||||tdtg|jj}|j t|dddy#1swYyxYw)z6Generates the '__next__' method for a generator class.__next__rN) rrMrarrr;rrrrrOrUr)r=r7fn_declnone_regresults rFrrs   g5588*FWY` a$&&( LLNA89  ""     F6N##$$$s A=B33B<c|j|jjdt|5|j dt}|j }|j t||j||||j|tdtg|jj}|j t|dddy#1swYyxYw)z2Generates the 'send' method for a generator class.sendargrN)rrMrar add_argumentrr;rrreadrrrOrUr)r=r7rrrrs rFrrs   g5588&BSU\ ]$""5*;<&&( LLNLL%A89  ""     F6N#%$$$s B"CC!cB|j|jjdt|5|j dt}|j dtt }|j dtt }|j |j|fd|jjj|j|fd|jjj|jt||j|j||j||j|tdt g|jj}|jt#|dddy#1swYyxYw) z3Generates the 'throw' method for a generator class.throwtypevalue tracebackcSrhrsrFz.add_throw_to_generator_class..;sHrHcSrhrrsrFrz.add_throw_to_generator_class..<s8rHrN)rrMrarrrrassign_if_nullr7rOrUr;rrrrrr)r=r7rtypvaltbrrs @rFrr0sI   g5588'CTV] ^$""6+<=""7,=wG  ! !+/@' J &&(s$4goo6K6K6P6PQr#3W__5J5J5O5OP LLNLL%LL%LL$A89  ""     F6N#7$$$s EFFc  |j|jjdt|5t t }}|j j ||jt |jd|jj}|jt|jd||j|jg|j||j j!|j#||j%t&g|jj}|j(j+t-|j(d||jd|jj}|jt/||g|jj}|j%t0|g|jj}t t } } |jt3|| | t2j4|j#| |j%t6|j9|g|jj|jt;|j|j#| |j%t<gt>|jtA|j(jC|j#||jtEtDjFd|jj|jtAdddy#1swYyxYw)z7Generates the '__close__' method for a generator class.closezbuiltins.GeneratorExitrrJzbuiltins.StopIterationzgenerator ignored GeneratorExitN)$rrMrarrr=push_error_handlerrload_module_attr_by_fullnamerOrUr;rrrgotopop_error_handlerrtrr.nonlocal_controlror,rr/rBOOLr2rrr1rrpopr RUNTIME_ERROR) r=r7 except_block else_blockgenerator_exitold_excstop_iteration exceptionsmatches match_blocknon_match_blocks rFrrPs   g5588'CTV] ^1##-<j **<8!!*,/ == $gmm&8&8    !4!4!68K8K8MN    Z ))+|,..W]]5G5GH  '' !'":":2"> H !== $gmm&8&8 [[>>*JGMML^L^!_` ..*w}}?Q?QR'1|Z\_  F7K&++NO{+*W\\'-B,CW]]EWEWX F7..012/+R1EF KM"  $$&z* "001 ""    KM"c1#1#1#s MNN c|j|jjdt|5|j t |j dddy#1swYyxYw)z7Generates the '__await__' method for a generator class. __await__Nrrs rFrrsP   g5588+GXZa b, F7<<>*+,,,rc|jj}|jj}|j|j}|j t dtd}|j t dtd}|j t dtd}|j t dtd}|j t dtd}|||f|_ ||_ ||_ |j||j|_|jjr|j|_n)t#||j|j$d|_|j't t(t*|d d |_t/|d |d t0 |j|j,|j|_y ) z0Populates the environment for a generator class.rT)is_argrrr stop_iter_ptrrJF)reassignalways_defined)localbaserr5N)r7rOrMadd_self_to_envra add_localrrrr send_arg_regstop_iter_value_regrrUself_regr8rdr)rZadd_var_to_env_classr rnext_label_targetr%r ry) r=rOr| self_targetrrrexc_argstop_iter_value_args rFrLrLs OO ! !E // ) )C))#&&1K  V.? MHG .?MG   s;/1B4  PFE ,=dKG"++ O7,gv.CLC1C<< UZZ8CL::<<<)'3<<ARARSUAVW $88 !#3S5Y]9C u3?Y !c&;&;UZZHCrHN)r=r r>zSCallable[[list[Register], list[BasicBlock], FuncInfo], tuple[FuncIR, Value | None]]returnztuple[FuncIR, Value | None])r=r r7r#rEz Value | NonerNone)r=r rr)r=r rr )r=r rr)r=r rUintrr) r=r r7r#rlist[Register]rBlist[BasicBlock]r\boolrr) r=r rrrBrr7r#rr )r=r r7r#rr)r=r r7r#rr rr)O__doc__ __future__rtypingr mypy.nodesrrr mypyc.commonrr r mypyc.ir.class_irr mypyc.ir.func_irr r mypyc.ir.opsrrrrrrrrrrrrrrmypyc.ir.rtypesrrrrmypyc.irbuild.builderr r!r"mypyc.irbuild.contextr#r$mypyc.irbuild.env_classr%r&r'r(r)r*r+mypyc.irbuild.nonlocalcontrolr,mypyc.irbuild.preparer-mypyc.primitives.exc_opsr.r/r0r1r2rGr_r9r6rSrYrTr[rrrrrrrrLrrHrFrsA#,,XX%-  VU:@7  ! 0+A\8 " (.7 7 77  7  7  7"   "0 :J U]   , $,$.$@3#l, +IrH