erg_compiler/
codegen.rs

1//! generates `CodeObj` (equivalent to PyCodeObject of CPython) from `AST`.
2//!
3//! ASTからPythonバイトコード(コードオブジェクト)を生成する
4use std::fmt;
5use std::process;
6
7use erg_common::cache::CacheSet;
8use erg_common::config::ErgConfig;
9use erg_common::env::erg_core_path;
10use erg_common::error::{ErrorDisplay, Location};
11use erg_common::fresh::SharedFreshNameGenerator;
12use erg_common::io::Input;
13use erg_common::opcode::{CommonOpcode, CompareOp};
14use erg_common::opcode308::Opcode308;
15use erg_common::opcode309::Opcode309;
16use erg_common::opcode310::Opcode310;
17use erg_common::opcode311::{BinOpCode, Opcode311};
18use erg_common::option_enum_unwrap;
19use erg_common::python_util::{env_python_version, PythonVersion};
20use erg_common::traits::{Locational, Stream};
21use erg_common::Str;
22use erg_common::{
23    debug_power_assert, fmt_option, fn_name, fn_name_full, impl_stream, log, set,
24    switch_unreachable,
25};
26use erg_parser::ast::VisModifierSpec;
27use erg_parser::ast::{DefId, DefKind};
28use CommonOpcode::*;
29
30use erg_parser::ast::{ParamPattern, TypeBoundSpecs, VarName};
31use erg_parser::token::DOT;
32use erg_parser::token::EQUAL;
33use erg_parser::token::{Token, TokenKind};
34
35use crate::compile::{AccessKind, Name, StoreLoadKind};
36use crate::context::ControlKind;
37use crate::error::CompileError;
38use crate::hir::DefaultParamSignature;
39use crate::hir::GlobSignature;
40use crate::hir::ListWithLength;
41use crate::hir::{
42    Accessor, Args, BinOp, Block, Call, ClassDef, Def, DefBody, Dict, Expr, GuardClause,
43    Identifier, Lambda, List, Literal, NonDefaultParamSignature, Params, PatchDef, PosArg, ReDef,
44    Record, Set, Signature, SubrSignature, Tuple, UnaryOp, VarSignature, HIR,
45};
46use crate::ty::codeobj::{CodeObj, CodeObjFlags, MakeFunctionFlags};
47use crate::ty::value::{GenTypeObj, ValueObj};
48use crate::ty::SubrType;
49use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
50use crate::varinfo::VarInfo;
51use AccessKind::*;
52use Type::*;
53
54#[derive(Debug)]
55pub enum RegisterNameKind {
56    Import,
57    Fast,
58    NonFast,
59}
60
61use RegisterNameKind::*;
62
63impl RegisterNameKind {
64    pub const fn is_fast(&self) -> bool {
65        matches!(self, Fast)
66    }
67
68    pub fn from_ident(ident: &Identifier) -> Self {
69        if ident.vi.is_fast_value() {
70            Fast
71        } else {
72            NonFast
73        }
74    }
75}
76
77/// patch method -> function
78/// patch attr -> variable
79fn debind(ident: &Identifier) -> Option<Str> {
80    match ident.vi.py_name.as_ref().map(|s| &s[..]) {
81        Some(name) if name.starts_with("Function::") => {
82            Some(Str::from(name.replace("Function::", "")))
83        }
84        Some(patch_method) if patch_method.contains("::") || patch_method.contains('.') => {
85            Some(Str::rc(patch_method))
86        }
87        _ => None,
88    }
89}
90
91fn escape_name(
92    name: &str,
93    vis: &VisibilityModifier,
94    def_line: u32,
95    def_col: u32,
96    is_attr: bool,
97) -> Str {
98    let name = name.replace('!', "__erg_proc__");
99    let name = name.replace('$', "__erg_shared__");
100    // For public APIs, mangling is not performed because `hasattr`, etc. cannot be used.
101    // For automatically generated variables, there is no possibility of conflict.
102    if vis.is_private() && !name.starts_with('%') {
103        if is_attr {
104            return Str::from(format!("::{name}"));
105        }
106        let line_mangling = match (def_line, def_col) {
107            (0, 0) => "".to_string(),
108            (0, _) => format!("_C{def_col}"),
109            (_, 0) => format!("_L{def_line}"),
110            (_, _) => format!("_L{def_line}_C{def_col}"),
111        };
112        Str::from(format!("::{name}{line_mangling}"))
113    } else {
114        Str::from(name)
115    }
116}
117
118fn escape_ident(ident: Identifier) -> Str {
119    let vis = ident.vis();
120    if &ident.inspect()[..] == "Self" {
121        // reference the self type or the self type constructor
122        let ty = ident
123            .vi
124            .t
125            .singleton_value()
126            .and_then(|tp| <&Type>::try_from(tp).ok())
127            .or_else(|| ident.vi.t.return_t())
128            .unwrap();
129        escape_name(
130            &ty.local_name(),
131            &ident.vi.vis.modifier,
132            ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
133            ident.vi.def_loc.loc.col_begin().unwrap_or(0),
134            ident.vi.kind.is_instance_attr(),
135        )
136    } else if let Some(py_name) = ident.vi.py_name {
137        py_name
138    } else if ident.vi.is_parameter() || ident.inspect() == "self" {
139        ident.inspect().clone()
140    } else {
141        escape_name(
142            ident.inspect(),
143            vis,
144            ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
145            ident.vi.def_loc.loc.col_begin().unwrap_or(0),
146            ident.vi.kind.is_instance_attr(),
147        )
148    }
149}
150
151#[derive(Debug, Clone)]
152pub struct PyCodeGenUnit {
153    pub(crate) id: usize,
154    pub(crate) py_version: PythonVersion,
155    pub(crate) codeobj: CodeObj,
156    pub(crate) captured_vars: Vec<Str>,
157    pub(crate) stack_len: u32, // the maximum stack size
158    pub(crate) prev_lineno: u32,
159    pub(crate) lasti: usize,
160    pub(crate) prev_lasti: usize,
161    pub(crate) _refs: Vec<ValueObj>, // ref-counted objects
162}
163
164impl PartialEq for PyCodeGenUnit {
165    #[inline]
166    fn eq(&self, other: &Self) -> bool {
167        self.id == other.id
168    }
169}
170
171impl fmt::Display for PyCodeGenUnit {
172    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173        write!(
174            f,
175            "CompilerUnit{{\nid: {}\ncode:\n{}\n}}",
176            self.id,
177            self.codeobj.code_info(Some(self.py_version))
178        )
179    }
180}
181
182impl PyCodeGenUnit {
183    #[allow(clippy::too_many_arguments)]
184    pub fn new<S: Into<Str>, T: Into<Str>>(
185        id: usize,
186        py_version: PythonVersion,
187        params: Vec<Str>,
188        kwonlyargcount: u32,
189        filename: S,
190        name: T,
191        firstlineno: u32,
192        flags: u32,
193    ) -> Self {
194        Self {
195            id,
196            py_version,
197            codeobj: CodeObj::empty(params, kwonlyargcount, filename, name, firstlineno, flags),
198            captured_vars: vec![],
199            stack_len: 0,
200            prev_lineno: firstlineno,
201            lasti: 0,
202            prev_lasti: 0,
203            _refs: vec![],
204        }
205    }
206}
207
208#[derive(Debug, Clone)]
209pub struct PyCodeGenStack(Vec<PyCodeGenUnit>);
210
211impl_stream!(PyCodeGenStack, PyCodeGenUnit);
212
213#[derive(Debug, Default)]
214pub struct PyCodeGenerator {
215    pub(crate) cfg: ErgConfig,
216    pub(crate) py_version: PythonVersion,
217    str_cache: CacheSet<str>,
218    prelude_loaded: bool,
219    mutate_op_loaded: bool,
220    contains_op_loaded: bool,
221    record_type_loaded: bool,
222    module_type_loaded: bool,
223    control_loaded: bool,
224    convertors_loaded: bool,
225    traits_loaded: bool,
226    operators_loaded: bool,
227    union_loaded: bool,
228    fake_generic_loaded: bool,
229    abc_loaded: bool,
230    builtins_loaded: bool,
231    unit_size: usize,
232    units: PyCodeGenStack,
233    fresh_gen: SharedFreshNameGenerator,
234}
235
236impl PyCodeGenerator {
237    pub fn new(cfg: ErgConfig) -> Self {
238        Self {
239            py_version: cfg.target_version.unwrap_or_else(|| {
240                let Some(version) = env_python_version() else {
241                    panic!("Failed to get python version");
242                };
243                version
244            }),
245            cfg,
246            str_cache: CacheSet::new(),
247            prelude_loaded: false,
248            mutate_op_loaded: false,
249            contains_op_loaded: false,
250            record_type_loaded: false,
251            module_type_loaded: false,
252            control_loaded: false,
253            convertors_loaded: false,
254            traits_loaded: false,
255            operators_loaded: false,
256            union_loaded: false,
257            fake_generic_loaded: false,
258            abc_loaded: false,
259            builtins_loaded: false,
260            unit_size: 0,
261            units: PyCodeGenStack::empty(),
262            fresh_gen: SharedFreshNameGenerator::new("codegen"),
263        }
264    }
265
266    pub fn inherit(&self) -> Self {
267        Self {
268            cfg: self.cfg.clone(),
269            py_version: self.py_version,
270            str_cache: self.str_cache.clone(),
271            prelude_loaded: false,
272            mutate_op_loaded: false,
273            contains_op_loaded: false,
274            record_type_loaded: false,
275            module_type_loaded: false,
276            control_loaded: false,
277            convertors_loaded: false,
278            traits_loaded: false,
279            operators_loaded: false,
280            union_loaded: false,
281            fake_generic_loaded: false,
282            abc_loaded: false,
283            builtins_loaded: false,
284            unit_size: 0,
285            units: PyCodeGenStack::empty(),
286            fresh_gen: self.fresh_gen.clone(),
287        }
288    }
289
290    pub fn clear(&mut self) {
291        self.units.clear();
292    }
293
294    pub fn set_input(&mut self, input: Input) {
295        self.cfg.input = input;
296    }
297
298    pub fn initialize(&mut self) {
299        self.prelude_loaded = false;
300        self.mutate_op_loaded = false;
301        self.contains_op_loaded = false;
302        self.record_type_loaded = false;
303        self.module_type_loaded = false;
304        self.control_loaded = false;
305        self.convertors_loaded = false;
306        self.traits_loaded = false;
307        self.operators_loaded = false;
308        self.union_loaded = false;
309        self.fake_generic_loaded = false;
310        self.abc_loaded = false;
311        self.builtins_loaded = false;
312    }
313
314    #[inline]
315    fn input(&self) -> &Input {
316        &self.cfg.input
317    }
318
319    fn get_cached(&self, s: &str) -> Str {
320        self.str_cache.get(s)
321    }
322
323    #[inline]
324    fn toplevel_block(&self) -> &PyCodeGenUnit {
325        self.units.first().unwrap()
326    }
327
328    #[inline]
329    fn cur_block(&self) -> &PyCodeGenUnit {
330        self.units.last().unwrap()
331    }
332
333    fn is_toplevel(&self) -> bool {
334        self.cur_block() == self.toplevel_block()
335    }
336
337    fn captured_vars(&self) -> Vec<&str> {
338        let mut caps = vec![];
339        for unit in self.units.iter() {
340            caps.extend(unit.captured_vars.iter().map(|s| &**s));
341        }
342        caps
343    }
344
345    #[inline]
346    fn mut_cur_block(&mut self) -> &mut PyCodeGenUnit {
347        self.units.last_mut().unwrap()
348    }
349
350    #[inline]
351    fn cur_block_codeobj(&self) -> &CodeObj {
352        &self.cur_block().codeobj
353    }
354
355    #[inline]
356    fn mut_cur_block_codeobj(&mut self) -> &mut CodeObj {
357        &mut self.mut_cur_block().codeobj
358    }
359
360    #[inline]
361    fn toplevel_block_codeobj(&self) -> &CodeObj {
362        &self.toplevel_block().codeobj
363    }
364
365    #[inline]
366    fn stack_len(&self) -> u32 {
367        self.cur_block().stack_len
368    }
369
370    #[inline]
371    fn lasti(&self) -> usize {
372        self.cur_block().lasti
373    }
374
375    #[inline]
376    #[allow(dead_code)]
377    fn debug_print(&mut self, value: impl Into<ValueObj>) {
378        self.emit_load_const(value);
379        self.emit_print_expr();
380    }
381
382    #[inline]
383    #[allow(dead_code)]
384    fn emit_print_expr(&mut self) {
385        self.write_instr(Opcode311::PRINT_EXPR);
386        self.write_arg(0);
387        self.stack_dec();
388    }
389
390    fn _emit_compare_op(&mut self, op: CompareOp) {
391        self.write_instr(Opcode311::COMPARE_OP);
392        self.write_arg(op as usize);
393        self.stack_dec();
394        if self.py_version.minor >= Some(11) {
395            self.write_bytes(&[0; 4]);
396        }
397    }
398
399    /// shut down the interpreter
400    #[allow(unused)]
401    fn terminate(&mut self) {
402        self.emit_push_null();
403        self.emit_load_name_instr(Identifier::static_public("exit"));
404        self.emit_load_const(1);
405        if self.py_version.minor >= Some(11) {
406            self.emit_precall_and_call(1);
407        } else {
408            self.write_instr(Opcode310::CALL_FUNCTION);
409            self.write_arg(1);
410        }
411        self.stack_dec();
412    }
413
414    /// swap TOS and TOS1
415    #[allow(unused)]
416    fn rot2(&mut self) {
417        if self.py_version.minor >= Some(11) {
418            self.write_instr(Opcode311::SWAP);
419            self.write_arg(2);
420        } else {
421            self.write_instr(Opcode310::ROT_TWO);
422            self.write_arg(0);
423        }
424    }
425
426    #[allow(unused)]
427    fn dup_top(&mut self) {
428        if self.py_version.minor >= Some(11) {
429            self.write_instr(Opcode311::COPY);
430            self.write_arg(1);
431        } else {
432            self.write_instr(Opcode310::DUP_TOP);
433            self.write_arg(0);
434        }
435        self.stack_inc();
436    }
437
438    /// COPY(1) == DUP_TOP
439    fn copy(&mut self, i: usize) {
440        debug_power_assert!(i, >, 0);
441        if self.py_version.minor >= Some(11) {
442            self.write_instr(Opcode311::COPY);
443            self.write_arg(i);
444        } else if i == 1 {
445            self.write_instr(Opcode310::DUP_TOP);
446            self.write_arg(0);
447        } else {
448            todo!()
449        }
450        self.stack_inc();
451    }
452
453    /// 0 origin
454    #[allow(dead_code)]
455    fn peek_stack(&mut self, i: usize) {
456        self.copy(i + 1);
457        self.emit_print_expr();
458    }
459
460    fn fill_jump(&mut self, idx: usize, jump_to: usize) {
461        let arg = if self.py_version.minor >= Some(10) {
462            jump_to / 2
463        } else {
464            jump_to
465        };
466        let bytes = u16::try_from(arg).unwrap().to_be_bytes();
467        *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = bytes[0];
468        *self.mut_cur_block_codeobj().code.get_mut(idx + 2).unwrap() = bytes[1];
469    }
470
471    /// returns: shift bytes
472    fn calc_edit_jump(&mut self, idx: usize, jump_to: usize) -> usize {
473        let arg = if self.py_version.minor >= Some(10) {
474            jump_to / 2
475        } else {
476            jump_to
477        };
478        if idx == 0
479            || !CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.get(idx - 1).unwrap())
480        {
481            self.crash(&format!("calc_edit_jump: not jump op: {idx} {jump_to}"));
482        }
483        self.edit_code(idx, arg)
484    }
485
486    /// returns: shift bytes
487    #[inline]
488    fn edit_code(&mut self, idx: usize, arg: usize) -> usize {
489        log!(err "editing: {idx} {arg}");
490        match u8::try_from(arg) {
491            Ok(u8code) => {
492                *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = u8code;
493                0
494            }
495            Err(_e) => {
496                // TODO: use u16 as long as possible
497                // see write_arg's comment
498                let bytes = u32::try_from(arg).unwrap().to_be_bytes();
499                let before_instr = idx.saturating_sub(1);
500                *self.mut_cur_block_codeobj().code.get_mut(idx).unwrap() = bytes[3];
501                self.extend_arg(before_instr, &bytes)
502            }
503        }
504    }
505
506    // e.g. JUMP_ABSOLUTE 264, lasti: 100
507    // 6 more instructions will be added after this, so 264 + 6 => 270
508    // this is greater than u8::MAX, so we need to extend the arg
509    // first, split `code + delta` into 4 u8s (as __Big__ endian)
510    // 270.to_be_bytes() == [0, 0, 1, 14]
511    // then, write the bytes in reverse order
512    // [..., EXTENDED_ARG 0, EXTENDED_ARG 0, EXTENDED_ARG 1, JUMP_ABSOLUTE 14]
513    /// returns: shift bytes
514    #[inline]
515    fn extend_arg(&mut self, before_instr: usize, bytes: &[u8]) -> usize {
516        let mut shift_bytes = 0;
517        for byte in bytes.iter().rev().skip(1) {
518            self.mut_cur_block_codeobj()
519                .code
520                .insert(before_instr, *byte);
521            self.mut_cur_block_codeobj()
522                .code
523                .insert(before_instr, CommonOpcode::EXTENDED_ARG as u8);
524            self.mut_cur_block().lasti += 2;
525            shift_bytes += 2;
526        }
527        shift_bytes
528    }
529
530    fn write_instr<C: Into<u8>>(&mut self, code: C) {
531        self.mut_cur_block_codeobj().code.push(code.into());
532        self.mut_cur_block().lasti += 1;
533        // log!(info "wrote: {}", code);
534    }
535
536    /// returns: shift bytes
537    fn write_arg(&mut self, code: usize) -> usize {
538        match u8::try_from(code) {
539            Ok(u8code) => {
540                self.mut_cur_block_codeobj().code.push(u8code);
541                self.mut_cur_block().lasti += 1;
542                1
543            }
544            Err(_) => match u16::try_from(code) {
545                Ok(_) => {
546                    let delta =
547                        if CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.last().unwrap())
548                        {
549                            2
550                        } else {
551                            0
552                        };
553                    let arg = code + delta;
554                    let bytes = u16::try_from(arg).unwrap().to_be_bytes(); // [u8; 2]
555                    let before_instr = self.lasti().saturating_sub(1);
556                    self.mut_cur_block_codeobj().code.push(bytes[1]);
557                    self.mut_cur_block().lasti += 1;
558                    self.extend_arg(before_instr, &bytes) + 1
559                }
560                Err(_) => {
561                    let delta = 0;
562                    if CommonOpcode::is_jump_op(*self.cur_block_codeobj().code.last().unwrap()) {
563                        6
564                    } else {
565                        0
566                    };
567                    let arg = code + delta;
568                    let bytes = u32::try_from(arg).unwrap().to_be_bytes(); // [u8; 4]
569                    let before_instr = self.lasti().saturating_sub(1);
570                    self.mut_cur_block_codeobj().code.push(bytes[3]);
571                    self.mut_cur_block().lasti += 1;
572                    self.extend_arg(before_instr, &bytes) + 1
573                }
574            },
575        }
576    }
577
578    fn write_bytes(&mut self, bytes: &[u8]) {
579        self.mut_cur_block_codeobj().code.extend_from_slice(bytes);
580        self.mut_cur_block().lasti += bytes.len();
581    }
582
583    fn stack_inc(&mut self) {
584        self.mut_cur_block().stack_len += 1;
585        if self.stack_len() > self.cur_block_codeobj().stacksize {
586            self.mut_cur_block_codeobj().stacksize = self.stack_len();
587        }
588    }
589
590    fn stack_dec(&mut self) {
591        if self.stack_len() == 0 {
592            let lasti = self.lasti();
593            let last = self.cur_block_codeobj().code.last().unwrap();
594            self.crash(&format!(
595                "the stack size becomes -1\nlasti: {lasti}\nlast code: {last}"
596            ));
597        } else {
598            self.mut_cur_block().stack_len -= 1;
599        }
600    }
601
602    /// NOTE: For example, an operation that increases the stack by 2 and decreases it by 1 should be `stack_inc_n(2); stack_dec();` not `stack_inc(1);`.
603    /// This is because the stack size will not increase correctly.
604    fn stack_inc_n(&mut self, n: usize) {
605        self.mut_cur_block().stack_len += n as u32;
606        if self.stack_len() > self.cur_block_codeobj().stacksize {
607            self.mut_cur_block_codeobj().stacksize = self.stack_len();
608        }
609    }
610
611    fn stack_dec_n(&mut self, n: usize) {
612        if n as u32 > self.stack_len() {
613            let lasti = self.lasti();
614            let last = self.cur_block_codeobj().code.last().unwrap();
615            self.crash(&format!(
616                "the stack size becomes -1\nlasti: {lasti}\nlast code: {last}"
617            ));
618        } else {
619            self.mut_cur_block().stack_len -= n as u32;
620        }
621    }
622
623    fn emit_load_const<C: Into<ValueObj>>(&mut self, cons: C) {
624        let value: ValueObj = cons.into();
625        let idx = self
626            .mut_cur_block_codeobj()
627            .consts
628            .iter()
629            .position(|c| c == &value)
630            .unwrap_or_else(|| {
631                self.mut_cur_block_codeobj().consts.push(value);
632                self.mut_cur_block_codeobj().consts.len() - 1
633            });
634        self.write_instr(LOAD_CONST);
635        self.write_arg(idx);
636        self.stack_inc();
637    }
638
639    fn register_const<C: Into<ValueObj>>(&mut self, cons: C) -> usize {
640        let value = cons.into();
641        self.mut_cur_block_codeobj()
642            .consts
643            .iter()
644            .position(|c| c == &value)
645            .unwrap_or_else(|| {
646                self.mut_cur_block_codeobj().consts.push(value);
647                self.mut_cur_block_codeobj().consts.len() - 1
648            })
649    }
650
651    fn local_search(&self, name: &str, acc_kind: AccessKind) -> Option<Name> {
652        if self.py_version.minor < Some(11) {
653            if let Some(idx) = self
654                .cur_block_codeobj()
655                .cellvars
656                .iter()
657                .position(|v| &**v == name)
658            {
659                return Some(Name::deref(idx));
660            }
661        }
662        match acc_kind {
663            AccessKind::Name => {
664                if let Some(idx) = self
665                    .cur_block_codeobj()
666                    .freevars
667                    .iter()
668                    .position(|f| &**f == name)
669                {
670                    Some(Name::deref(idx))
671                } else if let Some(idx) = self
672                    .cur_block_codeobj()
673                    .varnames
674                    .iter()
675                    .position(|v| &**v == name)
676                {
677                    if self.captured_vars().contains(&name) {
678                        None
679                    } else {
680                        Some(Name::fast(idx))
681                    }
682                } else if let Some(idx) = self
683                    .cur_block_codeobj()
684                    .names
685                    .iter()
686                    .position(|n| &**n == name)
687                {
688                    if !self.is_toplevel() {
689                        None
690                    } else {
691                        Some(Name::local(idx))
692                    }
693                } else {
694                    None
695                }
696            }
697            _ => self
698                .cur_block_codeobj()
699                .names
700                .iter()
701                .position(|n| &**n == name)
702                .map(Name::local),
703        }
704    }
705
706    // local_searchで見つからなかった変数を探索する
707    fn rec_search(&mut self, name: &str) -> Option<StoreLoadKind> {
708        // search_name()を実行した後なのでcur_blockはskipする
709        for (nth_from_toplevel, block) in self.units.iter_mut().enumerate().rev().skip(1) {
710            let block_is_toplevel = nth_from_toplevel == 0;
711            if block.codeobj.cellvars.iter().any(|c| &**c == name) {
712                return Some(StoreLoadKind::Deref);
713            } else if let Some(idx) = block.codeobj.varnames.iter().position(|v| &**v == name) {
714                if block_is_toplevel {
715                    return Some(StoreLoadKind::Global);
716                } else {
717                    // the outer scope variable
718                    let cellvar_name = block.codeobj.varnames.get(idx).unwrap().clone();
719                    block.codeobj.cellvars.push(cellvar_name);
720                    return Some(StoreLoadKind::Deref);
721                }
722            }
723            if block_is_toplevel && block.codeobj.names.iter().any(|n| &**n == name) {
724                return Some(StoreLoadKind::Global);
725            }
726        }
727        // 見つからなかった変数(前方参照変数など)はグローバル
728        Some(StoreLoadKind::Global)
729    }
730
731    fn register_name(&mut self, name: Str, kind: RegisterNameKind) -> Name {
732        let current_is_toplevel = self.is_toplevel();
733        match self.rec_search(&name) {
734            Some(st @ (StoreLoadKind::Local | StoreLoadKind::Global)) => {
735                if kind.is_fast() {
736                    self.mut_cur_block_codeobj().varnames.push(name);
737                    Name::fast(self.cur_block_codeobj().varnames.len() - 1)
738                } else {
739                    let st = if current_is_toplevel {
740                        StoreLoadKind::Local
741                    } else {
742                        st
743                    };
744                    self.mut_cur_block_codeobj().names.push(name);
745                    Name::new(st, self.cur_block_codeobj().names.len() - 1)
746                }
747            }
748            Some(StoreLoadKind::Deref) => {
749                self.mut_cur_block_codeobj().freevars.push(name.clone());
750                if self.py_version.minor >= Some(11) {
751                    // in 3.11 freevars are unified with varnames
752                    self.mut_cur_block_codeobj().varnames.push(name);
753                    Name::deref(self.cur_block_codeobj().varnames.len() - 1)
754                } else {
755                    // cellvarsのpushはrec_search()で行われる
756                    Name::deref(self.cur_block_codeobj().freevars.len() - 1)
757                }
758            }
759            None => {
760                // new variable
761                if current_is_toplevel {
762                    self.mut_cur_block_codeobj().names.push(name);
763                    Name::local(self.cur_block_codeobj().names.len() - 1)
764                } else {
765                    self.mut_cur_block_codeobj().varnames.push(name);
766                    Name::fast(self.cur_block_codeobj().varnames.len() - 1)
767                }
768            }
769            Some(_) => {
770                switch_unreachable!()
771            }
772        }
773    }
774
775    fn register_attr(&mut self, name: Str) -> Name {
776        self.mut_cur_block_codeobj().names.push(name);
777        Name::local(self.cur_block_codeobj().names.len() - 1)
778    }
779
780    fn register_method(&mut self, name: Str) -> Name {
781        self.mut_cur_block_codeobj().names.push(name);
782        Name::local(self.cur_block_codeobj().names.len() - 1)
783    }
784
785    fn select_load_instr(&self, kind: StoreLoadKind, acc_kind: AccessKind) -> u8 {
786        match kind {
787            StoreLoadKind::Fast | StoreLoadKind::FastConst => LOAD_FAST as u8,
788            StoreLoadKind::Global | StoreLoadKind::GlobalConst => LOAD_NAME as u8, //LOAD_GLOBAL as u8,
789            StoreLoadKind::Deref | StoreLoadKind::DerefConst => {
790                if self.py_version.minor >= Some(11) {
791                    Opcode311::LOAD_DEREF as u8
792                } else {
793                    Opcode310::LOAD_DEREF as u8
794                }
795            }
796            StoreLoadKind::Local | StoreLoadKind::LocalConst => match acc_kind {
797                Name => LOAD_NAME as u8,
798                UnboundAttr => LOAD_ATTR as u8,
799                BoundAttr => LOAD_METHOD as u8,
800            },
801        }
802    }
803
804    fn select_store_instr(&self, kind: StoreLoadKind, acc_kind: AccessKind) -> u8 {
805        match kind {
806            StoreLoadKind::Fast => STORE_FAST as u8,
807            StoreLoadKind::FastConst => STORE_FAST as u8, // ERG_STORE_FAST_IMMUT,
808            // NOTE: First-time variables are treated as GLOBAL, but they are always first-time variables when assigned, so they are just NAME
809            // NOTE: 初見の変数はGLOBAL扱いになるが、代入時は必ず初見であるので単なるNAME
810            StoreLoadKind::Global | StoreLoadKind::GlobalConst => STORE_NAME as u8,
811            StoreLoadKind::Deref | StoreLoadKind::DerefConst => {
812                if self.py_version.minor >= Some(11) {
813                    Opcode311::STORE_DEREF as u8
814                } else {
815                    Opcode310::STORE_DEREF as u8
816                }
817            }
818            StoreLoadKind::Local | StoreLoadKind::LocalConst => {
819                match acc_kind {
820                    Name => STORE_NAME as u8,
821                    UnboundAttr => STORE_ATTR as u8,
822                    // cannot overwrite methods directly
823                    BoundAttr => STORE_ATTR as u8,
824                }
825            }
826        }
827    }
828
829    fn emit_load_name_instr(&mut self, ident: Identifier) {
830        log!(info "entered {}({ident})", fn_name!());
831        if &ident.inspect()[..] == "#ModuleType" && !self.module_type_loaded {
832            self.load_module_type();
833            self.module_type_loaded = true;
834        }
835        let kind = RegisterNameKind::from_ident(&ident);
836        let escaped = escape_ident(ident);
837        match &escaped[..] {
838            "if__" | "for__" | "while__" | "with__" | "discard__" | "assert__" => {
839                self.load_control();
840            }
841            "int__" | "nat__" | "str__" | "float__" => {
842                self.load_convertors();
843            }
844            "add" | "sub" | "mul" | "truediv" | "floordiv" | "mod" | "pow" | "eq" | "ne" | "lt"
845            | "le" | "gt" | "ge" | "and_" | "or_" | "xor" | "lshift" | "rshift" | "pos" | "neg"
846            | "invert" | "is_" | "is_not" | "call" => {
847                self.load_operators();
848            }
849            "Eq" | "Ord" | "Hash" | "Add" | "Sub" | "Mul" | "Div" | "Pos" | "Neg" => {
850                self.load_traits();
851            }
852            "CodeType" => {
853                self.emit_global_import_items(
854                    Identifier::static_public("types"),
855                    vec![(Identifier::static_public("CodeType"), None)],
856                );
857            }
858            // NoneType is not defined in the global scope, use `type(None)` instead
859            "NoneType" => {
860                self.emit_push_null();
861                self.emit_load_name_instr(Identifier::static_public("type"));
862                let none = Expr::Literal(Literal::new(ValueObj::None, Token::DUMMY));
863                let args = Args::single(PosArg::new(none));
864                self.emit_args_311(args, AccessKind::Name);
865                return;
866            }
867            "list_iterator" => {
868                let list = Expr::Literal(Literal::new(ValueObj::List(vec![].into()), Token::DUMMY));
869                let iter = Identifier::static_public("iter");
870                let iter_call = iter.call(Args::single(PosArg::new(list)));
871                let typ = Identifier::static_public("type");
872                let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
873                self.emit_call(typ_call);
874                return;
875            }
876            "set_iterator" => {
877                let set = Expr::Set(Set::empty());
878                let iter = Identifier::static_public("iter");
879                let iter_call = iter.call(Args::single(PosArg::new(set)));
880                let typ = Identifier::static_public("type");
881                let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
882                self.emit_call(typ_call);
883                return;
884            }
885            "dict_items" => {
886                let dict = Expr::Dict(Dict::empty());
887                let items = Identifier::static_public("iter");
888                let items_call = items.call(Args::single(PosArg::new(dict)));
889                let typ = Identifier::static_public("type");
890                let typ_call = typ.call(Args::single(PosArg::new(items_call.into())));
891                self.emit_call(typ_call);
892                return;
893            }
894            "dict_keys" => {
895                let dict = Expr::Dict(Dict::empty());
896                let keys = Identifier::static_public("keys");
897                let keys_call = dict.method_call(keys, Args::empty());
898                let typ = Identifier::static_public("type");
899                let typ_call = typ.call(Args::single(PosArg::new(keys_call.into())));
900                self.emit_call(typ_call);
901                return;
902            }
903            "dict_values" => {
904                let dict = Expr::Dict(Dict::empty());
905                let values = Identifier::static_public("values");
906                let values_call = dict.method_call(values, Args::empty());
907                let typ = Identifier::static_public("type");
908                let typ_call = typ.call(Args::single(PosArg::new(values_call.into())));
909                self.emit_call(typ_call);
910                return;
911            }
912            _ => {}
913        }
914        let name = self
915            .local_search(&escaped, Name)
916            .unwrap_or_else(|| self.register_name(escaped, kind));
917        let instr = self.select_load_instr(name.kind, Name);
918        self.write_instr(instr);
919        self.write_arg(name.idx);
920        self.stack_inc();
921        self.mut_cur_block_codeobj().stacksize += 2;
922        if instr == LOAD_GLOBAL as u8 && self.py_version.minor >= Some(11) {
923            self.write_bytes(&[0; 2]);
924            self.write_bytes(&[0; 8]);
925        }
926    }
927
928    fn emit_load_global_instr(&mut self, ident: Identifier) {
929        log!(info "entered {} ({ident})", fn_name!());
930        let escaped = escape_ident(ident);
931        let name = self
932            .local_search(&escaped, Name)
933            .unwrap_or_else(|| self.register_name(escaped, NonFast));
934        let instr = LOAD_GLOBAL;
935        self.write_instr(instr);
936        self.write_arg(name.idx);
937        self.stack_inc();
938    }
939
940    fn emit_import_name_instr(&mut self, ident: Identifier, items_len: usize) {
941        log!(info "entered {}({ident})", fn_name!());
942        let escaped = escape_ident(ident);
943        let name = self
944            .local_search(&escaped, Name)
945            .unwrap_or_else(|| self.register_name(escaped, Import));
946        self.write_instr(IMPORT_NAME);
947        self.write_arg(name.idx);
948        self.stack_inc_n(items_len);
949        self.stack_dec(); // (level + from_list) -> module object
950    }
951
952    fn emit_import_from_instr(&mut self, ident: Identifier) {
953        log!(info "entered {}", fn_name!());
954        let escaped = escape_ident(ident);
955        let name = self
956            .local_search(&escaped, Name)
957            .unwrap_or_else(|| self.register_name(escaped, Import));
958        self.write_instr(IMPORT_FROM);
959        self.write_arg(name.idx);
960        // self.stack_inc(); (module object) -> attribute
961    }
962
963    fn emit_import_all_instr(&mut self, ident: Identifier) {
964        log!(info "entered {}", fn_name!());
965        self.emit_load_const(0i32); // escaping to call access `Nat` before importing `Nat`
966        self.emit_load_const([Str::ever("*")]);
967        let escaped = escape_ident(ident);
968        let name = self
969            .local_search(&escaped, Name)
970            .unwrap_or_else(|| self.register_name(escaped, Import));
971        self.write_instr(IMPORT_NAME);
972        self.write_arg(name.idx);
973        self.stack_inc();
974        self.write_instr(IMPORT_STAR);
975        self.write_arg(0);
976        self.stack_dec_n(3);
977    }
978
979    /// item: (name, renamed)
980    fn emit_global_import_items(
981        &mut self,
982        module: Identifier,
983        items: Vec<(Identifier, Option<Identifier>)>,
984    ) {
985        self.emit_load_const(0);
986        let item_name_tuple = items
987            .iter()
988            .map(|ident| ValueObj::Str(ident.0.inspect().clone()))
989            .collect::<Vec<_>>();
990        let items_len = item_name_tuple.len();
991        self.emit_load_const(item_name_tuple);
992        self.emit_import_name_instr(module, items_len);
993        for (item, renamed) in items.into_iter() {
994            if let Some(renamed) = renamed {
995                self.emit_import_from_instr(item);
996                self.emit_store_global_instr(renamed);
997            } else {
998                self.emit_import_from_instr(item.clone());
999                self.emit_store_global_instr(item);
1000            }
1001        }
1002        self.emit_pop_top(); // discard IMPORT_FROM object
1003    }
1004
1005    fn emit_load_attr_instr(&mut self, ident: Identifier) {
1006        log!(info "entered {} ({ident})", fn_name!());
1007        let escaped = escape_ident(ident);
1008        let name = self
1009            .local_search(&escaped, UnboundAttr)
1010            .unwrap_or_else(|| self.register_attr(escaped));
1011        let instr = self.select_load_instr(name.kind, UnboundAttr);
1012        self.write_instr(instr);
1013        self.write_arg(name.idx);
1014        if self.py_version.minor >= Some(11) {
1015            self.write_bytes(&[0; 8]);
1016        }
1017    }
1018
1019    fn emit_load_method_instr(&mut self, ident: Identifier, acc_kind: AccessKind) {
1020        log!(info "entered {} ({ident})", fn_name!());
1021        let escaped = escape_ident(ident);
1022        let name = self
1023            .local_search(&escaped, acc_kind)
1024            .unwrap_or_else(|| self.register_method(escaped));
1025        let instr = self.select_load_instr(name.kind, acc_kind);
1026        self.write_instr(instr);
1027        self.write_arg(name.idx);
1028        if self.py_version.minor >= Some(11) {
1029            self.stack_inc(); // instead of PUSH_NULL
1030            self.write_bytes(&[0; 20]);
1031        }
1032    }
1033
1034    fn emit_store_instr(&mut self, ident: Identifier, acc_kind: AccessKind) {
1035        log!(info "entered {} ({ident})", fn_name!());
1036        let kind = RegisterNameKind::from_ident(&ident);
1037        let escaped = escape_ident(ident);
1038        let name = self.local_search(&escaped, acc_kind).unwrap_or_else(|| {
1039            if acc_kind.is_local() {
1040                self.register_name(escaped, kind)
1041            } else {
1042                self.register_attr(escaped)
1043            }
1044        });
1045        let instr = self.select_store_instr(name.kind, acc_kind);
1046        self.write_instr(instr);
1047        self.write_arg(name.idx);
1048        self.stack_dec();
1049        if instr == STORE_ATTR as u8 {
1050            if self.py_version.minor >= Some(11) {
1051                self.write_bytes(&[0; 8]);
1052            }
1053            self.stack_dec();
1054        } else if instr == STORE_FAST as u8 {
1055            self.mut_cur_block_codeobj().nlocals += 1;
1056        }
1057    }
1058
1059    /// used for importing Erg builtin objects, etc. normally, this is not used
1060    // Ergの組み込みオブジェクトをimportするときなどに使う、通常は使わない
1061    fn emit_store_global_instr(&mut self, ident: Identifier) {
1062        log!(info "entered {} ({ident})", fn_name!());
1063        let escaped = escape_ident(ident);
1064        let name = self
1065            .local_search(&escaped, Name)
1066            .unwrap_or_else(|| self.register_name(escaped, NonFast));
1067        let instr = STORE_GLOBAL;
1068        self.write_instr(instr);
1069        self.write_arg(name.idx);
1070        self.stack_dec();
1071    }
1072
1073    /// Ergの文法として、属性への代入は存在しない(必ずオブジェクトはすべての属性を初期化しなくてはならないため)
1074    /// この関数はPythonへ落とし込むときに使う
1075    fn store_acc(&mut self, acc: Accessor) {
1076        log!(info "entered {} ({acc})", fn_name!());
1077        match acc {
1078            Accessor::Ident(ident) => {
1079                self.emit_store_instr(ident, Name);
1080            }
1081            Accessor::Attr(attr) => {
1082                self.emit_expr(*attr.obj);
1083                self.emit_store_instr(attr.ident, UnboundAttr);
1084            }
1085        }
1086    }
1087
1088    fn emit_pop_top(&mut self) {
1089        self.write_instr(POP_TOP);
1090        self.write_arg(0);
1091        self.stack_dec();
1092    }
1093
1094    fn cancel_if_pop_top(&mut self) {
1095        if self.cur_block_codeobj().code.len() < 2 {
1096            return;
1097        }
1098        let lasop_t_idx = self.cur_block_codeobj().code.len() - 2;
1099        if self.cur_block_codeobj().code.get(lasop_t_idx) == Some(&(POP_TOP as u8)) {
1100            self.mut_cur_block_codeobj().code.pop();
1101            self.mut_cur_block_codeobj().code.pop();
1102            self.mut_cur_block().lasti -= 2;
1103            self.stack_inc();
1104        }
1105    }
1106
1107    /// Compileが継続不能になった際呼び出す
1108    /// 極力使わないこと
1109    #[track_caller]
1110    fn crash(&mut self, description: &str) -> ! {
1111        if cfg!(debug_assertions) || cfg!(feature = "debug") {
1112            println!("internal error: {description}");
1113            panic!("current block: {}", self.cur_block());
1114        } else {
1115            let err = CompileError::compiler_bug(
1116                0,
1117                self.input().clone(),
1118                Location::Unknown,
1119                fn_name!(),
1120                line!(),
1121            );
1122            err.write_to_stderr();
1123            process::exit(1);
1124        }
1125    }
1126
1127    fn gen_param_names(&self, params: &Params) -> Vec<Str> {
1128        params
1129            .non_defaults
1130            .iter()
1131            .map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.vi))
1132            .chain(
1133                params
1134                    .defaults
1135                    .iter()
1136                    .map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.sig.vi)),
1137            )
1138            .chain(if let Some(var_args) = &params.var_params {
1139                vec![(
1140                    var_args.inspect().map(|s| &s[..]).unwrap_or("_"),
1141                    &var_args.vi,
1142                )]
1143            } else {
1144                vec![]
1145            })
1146            .chain(if let Some(kw_var_args) = &params.kw_var_params {
1147                vec![(
1148                    kw_var_args.inspect().map(|s| &s[..]).unwrap_or("_"),
1149                    &kw_var_args.vi,
1150                )]
1151            } else {
1152                vec![]
1153            })
1154            .enumerate()
1155            .map(|(i, (s, vi))| {
1156                if s == "_" {
1157                    format!("_{i}")
1158                } else {
1159                    escape_name(
1160                        s,
1161                        &VisibilityModifier::Public,
1162                        vi.def_loc.loc.ln_begin().unwrap_or(0),
1163                        vi.def_loc.loc.col_begin().unwrap_or(0),
1164                        false,
1165                    )
1166                    .to_string()
1167                }
1168            })
1169            .map(|s| self.get_cached(&s))
1170            .collect()
1171    }
1172
1173    fn emit_acc(&mut self, acc: Accessor) {
1174        log!(info "entered {} ({acc})", fn_name!());
1175        let init_stack_len = self.stack_len();
1176        match acc {
1177            Accessor::Ident(ident) => {
1178                self.emit_load_name_instr(ident);
1179            }
1180            Accessor::Attr(mut a) => {
1181                // Python's namedtuple, a representation of Record, does not allow attribute names such as `::x`.
1182                // Since Erg does not allow the coexistence of private and public variables with the same name, there is no problem in this trick.
1183                let is_record = a.obj.ref_t().is_record();
1184                if is_record {
1185                    a.ident.raw.vis = VisModifierSpec::Public(Location::Unknown);
1186                }
1187                if let Some(varname) = debind(&a.ident) {
1188                    a.ident.raw.vis = VisModifierSpec::Private;
1189                    a.ident.raw.name = VarName::from_str(varname);
1190                    self.emit_load_name_instr(a.ident);
1191                } else {
1192                    self.emit_expr(*a.obj);
1193                    self.emit_load_attr_instr(a.ident);
1194                }
1195            }
1196        }
1197        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1198    }
1199
1200    fn emit_def(&mut self, def: Def) {
1201        log!(info "entered {} ({})", fn_name!(), def.sig);
1202        if def.def_kind().is_trait() {
1203            return self.emit_trait_def(def);
1204        }
1205        match def.sig {
1206            Signature::Subr(sig) => self.emit_subr_def(None, sig, def.body),
1207            Signature::Var(sig) => self.emit_var_def(sig, def.body),
1208            Signature::Glob(sig) => self.emit_glob_def(sig, def.body),
1209        }
1210    }
1211
1212    fn emit_push_null(&mut self) {
1213        if self.py_version.minor >= Some(11) {
1214            self.write_instr(Opcode311::PUSH_NULL);
1215            self.write_arg(0);
1216            self.stack_inc();
1217        }
1218    }
1219
1220    fn emit_precall_and_call(&mut self, argc: usize) {
1221        self.write_instr(Opcode311::PRECALL);
1222        self.write_arg(argc);
1223        self.write_arg(0);
1224        self.write_arg(0);
1225        self.write_instr(Opcode311::CALL);
1226        self.write_arg(argc);
1227        self.write_bytes(&[0; 8]);
1228        self.stack_dec();
1229    }
1230
1231    fn emit_call_instr(&mut self, argc: usize, kind: AccessKind) {
1232        if self.py_version.minor >= Some(11) {
1233            self.emit_precall_and_call(argc);
1234        } else {
1235            match kind {
1236                AccessKind::BoundAttr => self.write_instr(Opcode310::CALL_METHOD),
1237                _ => self.write_instr(Opcode310::CALL_FUNCTION),
1238            }
1239            self.write_arg(argc);
1240        }
1241    }
1242
1243    fn emit_call_kw_instr(&mut self, argc: usize, kws: Vec<ValueObj>) {
1244        if self.py_version.minor >= Some(11) {
1245            let idx = self.register_const(kws);
1246            self.write_instr(Opcode311::KW_NAMES);
1247            self.write_arg(idx);
1248            self.emit_precall_and_call(argc);
1249        } else {
1250            self.emit_load_const(kws);
1251            self.write_instr(Opcode310::CALL_FUNCTION_KW);
1252            self.write_arg(argc);
1253        }
1254    }
1255
1256    fn emit_trait_def(&mut self, def: Def) {
1257        if !self.abc_loaded {
1258            self.load_abc();
1259            self.abc_loaded = true;
1260        }
1261        self.emit_push_null();
1262        self.write_instr(LOAD_BUILD_CLASS);
1263        self.write_arg(0);
1264        self.stack_inc();
1265        let kind = def.def_kind();
1266        let code = self.emit_trait_block(kind, &def.sig, def.body.block);
1267        self.emit_load_const(code);
1268        if self.py_version.minor < Some(11) {
1269            self.emit_load_const(def.sig.ident().inspect().clone());
1270        } else {
1271            self.stack_inc();
1272        }
1273        self.write_instr(MAKE_FUNCTION);
1274        self.write_arg(0);
1275        self.emit_load_const(def.sig.ident().inspect().clone());
1276        self.emit_load_name_instr(Identifier::private("#ABCMeta"));
1277        let subclasses_len = 1;
1278        self.emit_call_kw_instr(2 + subclasses_len, vec![ValueObj::from("metaclass")]);
1279        let sum = if self.py_version.minor >= Some(11) {
1280            1 + 2 + subclasses_len
1281        } else {
1282            1 + 2 + 1 + subclasses_len
1283        };
1284        self.stack_dec_n(sum - 1);
1285        self.emit_store_instr(def.sig.into_ident(), Name);
1286        self.stack_dec();
1287    }
1288
1289    // trait variables will be removed
1290    // T = Trait {
1291    //     x = Int
1292    //     f = (self: Self) -> Int
1293    // }
1294    // ↓
1295    // class T(metaclass=ABCMeta):
1296    //    def f(): pass
1297    fn emit_trait_block(&mut self, kind: DefKind, sig: &Signature, mut block: Block) -> CodeObj {
1298        debug_assert!(kind.is_trait());
1299        let name = sig.ident().inspect().clone();
1300        let Expr::Call(mut trait_call) = block.remove(0) else {
1301            unreachable!()
1302        };
1303        let req = if let Some(Expr::Record(req)) = trait_call.args.remove_left_or_key("Requirement")
1304        {
1305            req.attrs.into_iter()
1306        } else {
1307            vec![].into_iter()
1308        };
1309        self.unit_size += 1;
1310        let firstlineno = block
1311            .get(0)
1312            .and_then(|def| def.ln_begin())
1313            .unwrap_or_else(|| sig.ln_begin().unwrap());
1314        self.units.push(PyCodeGenUnit::new(
1315            self.unit_size,
1316            self.py_version,
1317            vec![],
1318            0,
1319            Str::rc(self.cfg.input.enclosed_name()),
1320            &name,
1321            firstlineno,
1322            0,
1323        ));
1324        let mod_name = self.toplevel_block_codeobj().name.clone();
1325        self.emit_load_const(mod_name);
1326        self.emit_store_instr(Identifier::static_public("__module__"), Name);
1327        self.emit_load_const(name);
1328        self.emit_store_instr(Identifier::static_public("__qualname__"), Name);
1329        for def in req {
1330            self.emit_empty_func(
1331                Some(sig.ident().inspect()),
1332                def.sig.into_ident(),
1333                Some(Identifier::private("#abstractmethod")),
1334            );
1335        }
1336        self.emit_load_const(ValueObj::None);
1337        self.write_instr(RETURN_VALUE);
1338        self.write_arg(0);
1339        if self.stack_len() > 1 {
1340            let block_id = self.cur_block().id;
1341            let stack_len = self.stack_len();
1342            CompileError::stack_bug(
1343                self.input().clone(),
1344                Location::Unknown,
1345                stack_len,
1346                block_id,
1347                fn_name_full!(),
1348            )
1349            .write_to_stderr();
1350            self.crash("error in emit_trait_block: invalid stack size");
1351        }
1352        // flagging
1353        if !self.cur_block_codeobj().varnames.is_empty() {
1354            self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
1355        }
1356        // end of flagging
1357        let unit = self.units.pop().unwrap();
1358        if !self.units.is_empty() {
1359            let ld = unit.prev_lineno - self.cur_block().prev_lineno;
1360            if ld != 0 {
1361                if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
1362                    *l += u8::try_from(ld).unwrap();
1363                }
1364                self.mut_cur_block().prev_lineno += ld;
1365            }
1366        }
1367        unit.codeobj
1368    }
1369
1370    fn emit_empty_func(
1371        &mut self,
1372        class_name: Option<&str>,
1373        ident: Identifier,
1374        deco: Option<Identifier>,
1375    ) {
1376        log!(info "entered {} ({ident})", fn_name!());
1377        self.emit_push_null();
1378        let deco_is_some = deco.is_some();
1379        if let Some(deco) = deco {
1380            self.emit_load_name_instr(deco);
1381        }
1382        let code = {
1383            self.unit_size += 1;
1384            self.units.push(PyCodeGenUnit::new(
1385                self.unit_size,
1386                self.py_version,
1387                vec![],
1388                0,
1389                Str::rc(self.cfg.input.enclosed_name()),
1390                ident.inspect(),
1391                ident.ln_begin().unwrap_or(0),
1392                0,
1393            ));
1394            self.emit_load_const(ValueObj::None);
1395            self.write_instr(RETURN_VALUE);
1396            self.write_arg(0);
1397            let unit = self.units.pop().unwrap();
1398            if !self.units.is_empty() {
1399                let ld = unit
1400                    .prev_lineno
1401                    .saturating_sub(self.cur_block().prev_lineno);
1402                if ld != 0 {
1403                    if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
1404                        *l += u8::try_from(ld).unwrap();
1405                    }
1406                    self.mut_cur_block().prev_lineno += ld;
1407                }
1408            }
1409            unit.codeobj
1410        };
1411        self.emit_load_const(code);
1412        if self.py_version.minor < Some(11) {
1413            if let Some(class) = class_name {
1414                self.emit_load_const(Str::from(format!("{class}.{}", ident.inspect())));
1415            } else {
1416                self.emit_load_const(ident.inspect().clone());
1417            }
1418        } else {
1419            self.stack_inc();
1420        }
1421        self.write_instr(MAKE_FUNCTION);
1422        self.write_arg(0);
1423        if deco_is_some {
1424            self.emit_call_instr(1, Name);
1425            self.stack_dec();
1426        }
1427        // stack_dec: (<abstractmethod>) + <code obj> + <name> -> <function>
1428        self.stack_dec();
1429        self.emit_store_instr(ident, Name);
1430    }
1431
1432    fn emit_class_def(&mut self, class_def: ClassDef) {
1433        log!(info "entered {} ({})", fn_name!(), class_def.sig);
1434        self.emit_push_null();
1435        let ident = class_def.sig.ident().clone();
1436        let require_or_sup = class_def.require_or_sup.clone().map(|x| *x);
1437        let obj = *class_def.obj.clone();
1438        self.write_instr(LOAD_BUILD_CLASS);
1439        self.write_arg(0);
1440        self.stack_inc();
1441        let code = self.emit_class_block(class_def);
1442        self.emit_load_const(code);
1443        if self.py_version.minor < Some(11) {
1444            self.emit_load_const(ident.inspect().clone());
1445        } else {
1446            self.stack_inc();
1447        }
1448        self.write_instr(MAKE_FUNCTION);
1449        self.write_arg(0);
1450        self.emit_load_const(ident.inspect().clone());
1451        // LOAD subclasses
1452        let subclasses_len = self.emit_require_type(obj, require_or_sup);
1453        self.emit_call_instr(2 + subclasses_len, Name);
1454        self.stack_dec_n((1 + 2 + subclasses_len) - 1);
1455        self.emit_store_instr(ident, Name);
1456        self.stack_dec();
1457    }
1458
1459    fn emit_patch_def(&mut self, patch_def: PatchDef) {
1460        log!(info "entered {} ({})", fn_name!(), patch_def.sig);
1461        for def in patch_def.methods {
1462            // Invert.
1463            //     invert self = ...
1464            // ↓
1465            // def Invert::invert(self): ...
1466            let Expr::Def(mut def) = def else { todo!() };
1467            let namespace = self.cur_block_codeobj().name.trim_start_matches("::");
1468            let name = format!(
1469                "{}{}{}",
1470                namespace,
1471                patch_def.sig.ident().to_string_notype(),
1472                def.sig.ident().to_string_notype()
1473            );
1474            def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
1475            def.sig.ident_mut().raw.vis = VisModifierSpec::Private;
1476            self.emit_def(def);
1477        }
1478    }
1479
1480    // NOTE: use `TypeVar`, `Generic` in `typing` module
1481    // fn emit_poly_type_def(&mut self, sig: SubrSignature, body: DefBody) {}
1482
1483    /// Y = Inherit X => class Y(X): ...
1484    /// N = Inherit 1..10 => class N(Nat): ...
1485    fn emit_require_type(&mut self, obj: GenTypeObj, require_or_sup: Option<Expr>) -> usize {
1486        log!(info "entered {} ({obj}, {})", fn_name!(), fmt_option!(require_or_sup));
1487        match obj {
1488            GenTypeObj::Class(_) => 0,
1489            GenTypeObj::Subclass(typ) => {
1490                let require_or_sup = require_or_sup.unwrap();
1491                let typ = if require_or_sup.is_acc() {
1492                    require_or_sup
1493                } else {
1494                    Expr::try_from_type(typ.sup.typ().derefine()).unwrap_or(require_or_sup)
1495                };
1496                self.emit_expr(typ);
1497                1 // TODO: not always 1
1498            }
1499            _ => todo!(),
1500        }
1501    }
1502
1503    fn emit_redef(&mut self, redef: ReDef) {
1504        log!(info "entered {} ({redef})", fn_name!());
1505        self.emit_simple_block(redef.block);
1506        self.store_acc(redef.attr);
1507    }
1508
1509    fn emit_var_def(&mut self, sig: VarSignature, mut body: DefBody) {
1510        log!(info "entered {} ({sig} = {})", fn_name!(), body.block);
1511        if body.block.len() == 1 {
1512            self.emit_expr(body.block.remove(0));
1513        } else {
1514            self.emit_simple_block(body.block);
1515        }
1516        if sig.global {
1517            self.emit_store_global_instr(sig.ident);
1518        } else {
1519            self.emit_store_instr(sig.ident, Name);
1520        }
1521    }
1522
1523    fn emit_glob_def(&mut self, _sig: GlobSignature, _body: DefBody) {}
1524
1525    /// No parameter mangling is used
1526    /// so that Erg functions can be called from Python with keyword arguments.
1527    fn emit_params(
1528        &mut self,
1529        var_params: Option<&NonDefaultParamSignature>,
1530        defaults: Vec<DefaultParamSignature>,
1531        function_flag: &mut usize,
1532    ) {
1533        if var_params.is_some() && !defaults.is_empty() {
1534            let defaults_len = defaults.len();
1535            let names = defaults
1536                .iter()
1537                .map(|default| {
1538                    escape_name(
1539                        default.sig.inspect().map_or("_", |s| &s[..]),
1540                        &VisibilityModifier::Public,
1541                        0,
1542                        0,
1543                        false,
1544                    )
1545                })
1546                .collect::<Vec<_>>();
1547            defaults
1548                .into_iter()
1549                .for_each(|default| self.emit_expr(default.default_val));
1550            self.emit_load_const(names);
1551            self.stack_dec();
1552            self.write_instr(BUILD_CONST_KEY_MAP);
1553            self.write_arg(defaults_len);
1554            self.stack_dec_n(defaults_len - 1);
1555            *function_flag += MakeFunctionFlags::KwDefaults as usize;
1556        } else if !defaults.is_empty() {
1557            let defaults_len = defaults.len();
1558            defaults
1559                .into_iter()
1560                .for_each(|default| self.emit_expr(default.default_val));
1561            self.write_instr(BUILD_TUPLE);
1562            self.write_arg(defaults_len);
1563            self.stack_dec_n(defaults_len - 1);
1564            *function_flag += MakeFunctionFlags::Defaults as usize;
1565        }
1566    }
1567
1568    fn emit_subr_def(&mut self, class_name: Option<&str>, sig: SubrSignature, body: DefBody) {
1569        log!(info "entered {} ({sig} = {})", fn_name!(), body.block);
1570        let name = sig.ident.inspect().clone();
1571        let mut make_function_flag = 0;
1572        let params = self.gen_param_names(&sig.params);
1573        let kwonlyargcount = if sig.params.var_params.is_some() {
1574            sig.params.defaults.len()
1575        } else {
1576            0
1577        };
1578        self.emit_params(
1579            sig.params.var_params.as_deref(),
1580            sig.params.defaults,
1581            &mut make_function_flag,
1582        );
1583        let mut flags = 0;
1584        if sig.params.var_params.is_some() {
1585            flags += CodeObjFlags::VarArgs as u32;
1586        }
1587        if sig.params.kw_var_params.is_some() {
1588            flags += CodeObjFlags::VarKeywords as u32;
1589        }
1590        let code = self.emit_block(
1591            body.block,
1592            sig.params.guards,
1593            Some(name.clone()),
1594            params,
1595            kwonlyargcount as u32,
1596            sig.captured_names.clone(),
1597            flags,
1598        );
1599        // code.flags += CodeObjFlags::Optimized as u32;
1600        self.enclose_vars(&mut make_function_flag);
1601        let n_decos = sig.decorators.len();
1602        for deco in sig.decorators {
1603            self.emit_expr(deco);
1604        }
1605        self.rewrite_captured_fast(&code);
1606        self.emit_load_const(code);
1607        if self.py_version.minor < Some(11) {
1608            if let Some(class) = class_name {
1609                self.emit_load_const(Str::from(format!("{class}.{name}")));
1610            } else {
1611                self.emit_load_const(name);
1612            }
1613        } else {
1614            self.stack_inc();
1615        }
1616        self.write_instr(MAKE_FUNCTION);
1617        self.write_arg(make_function_flag);
1618        for _ in 0..n_decos {
1619            let argc = if self.py_version.minor >= Some(11) {
1620                0
1621            } else {
1622                self.stack_dec();
1623                1
1624            };
1625            self.emit_call_instr(argc, Name);
1626        }
1627        // stack_dec: <code obj> + <name> -> <function>
1628        self.stack_dec();
1629        if make_function_flag
1630            & (MakeFunctionFlags::Defaults as usize | MakeFunctionFlags::KwDefaults as usize)
1631            != 0
1632        {
1633            self.stack_dec();
1634        }
1635        self.emit_store_instr(sig.ident, Name);
1636    }
1637
1638    fn emit_lambda(&mut self, lambda: Lambda) {
1639        log!(info "entered {} ({lambda})", fn_name!());
1640        let init_stack_len = self.stack_len();
1641        let mut make_function_flag = 0;
1642        let params = self.gen_param_names(&lambda.params);
1643        let kwonlyargcount = if lambda.params.var_params.is_some() {
1644            lambda.params.defaults.len()
1645        } else {
1646            0
1647        };
1648        self.emit_params(
1649            lambda.params.var_params.as_deref(),
1650            lambda.params.defaults,
1651            &mut make_function_flag,
1652        );
1653        let flags = if lambda.params.var_params.is_some() {
1654            CodeObjFlags::VarArgs as u32
1655        } else {
1656            0
1657        };
1658        let code = self.emit_block(
1659            lambda.body,
1660            lambda.params.guards,
1661            Some(format!("<lambda_{}>", lambda.id).into()),
1662            params,
1663            kwonlyargcount as u32,
1664            lambda.captured_names.clone(),
1665            flags,
1666        );
1667        self.enclose_vars(&mut make_function_flag);
1668        self.rewrite_captured_fast(&code);
1669        self.emit_load_const(code);
1670        if self.py_version.minor < Some(11) {
1671            self.emit_load_const(format!("<lambda_{}>", lambda.id));
1672        } else {
1673            self.stack_inc();
1674        }
1675        self.write_instr(MAKE_FUNCTION);
1676        self.write_arg(make_function_flag);
1677        // stack_dec: <lambda code obj> + <name "<lambda>"> -> <function>
1678        self.stack_dec();
1679        if make_function_flag & MakeFunctionFlags::Defaults as usize != 0 {
1680            self.stack_dec();
1681        }
1682        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1683    }
1684
1685    fn enclose_vars(&mut self, flag: &mut usize) {
1686        if !self.cur_block_codeobj().cellvars.is_empty() {
1687            let cellvars_len = self.cur_block_codeobj().cellvars.len();
1688            let cellvars = self.cur_block_codeobj().cellvars.clone();
1689            for (i, name) in cellvars.iter().enumerate() {
1690                // Since 3.11, LOAD_CLOSURE is simply an alias for LOAD_FAST.
1691                if self.py_version.minor >= Some(11) {
1692                    let idx = self
1693                        .cur_block_codeobj()
1694                        .varnames
1695                        .iter()
1696                        .position(|n| n == name)
1697                        .unwrap();
1698                    self.write_instr(Opcode311::LOAD_CLOSURE);
1699                    self.write_arg(idx);
1700                } else {
1701                    self.write_instr(Opcode310::LOAD_CLOSURE);
1702                    self.write_arg(i);
1703                }
1704            }
1705            self.write_instr(BUILD_TUPLE);
1706            self.write_arg(cellvars_len);
1707            *flag += MakeFunctionFlags::Closure as usize;
1708        }
1709    }
1710
1711    /// ```erg
1712    /// f = i ->
1713    ///     log i
1714    ///     do i
1715    /// ```
1716    /// ↓
1717    /// ```pyc
1718    /// Disassembly of <code object f ...>
1719    /// 0 LOAD_NAME                0 (print)
1720    /// 2 LOAD_NAME                1 (Nat)
1721    /// 4 LOAD_DEREF               0 (::i) # not LOAD_FAST!
1722    /// 6 CALL_FUNCTION            1
1723    /// 8 CALL_FUNCTION            1
1724    /// 10 POP_TOP
1725    /// 12 LOAD_CLOSURE             0 (::i)
1726    /// 14 BUILD_TUPLE              1
1727    /// 16 LOAD_CONST               0 (<code object ...>)
1728    /// 18 LOAD_CONST               1 ("<lambda>")
1729    /// 20 MAKE_FUNCTION            8 (closure)
1730    /// 22 RETURN_VALUE
1731    /// ```
1732    fn rewrite_captured_fast(&mut self, code: &CodeObj) {
1733        if self.py_version.minor >= Some(11) {
1734            return;
1735        }
1736        let cellvars = self.cur_block_codeobj().cellvars.clone();
1737        for cellvar in cellvars {
1738            if code.freevars.iter().any(|n| n == &cellvar) {
1739                let old_idx = self
1740                    .cur_block_codeobj()
1741                    .varnames
1742                    .iter()
1743                    .position(|n| n == &cellvar)
1744                    .unwrap();
1745                let new_idx = self
1746                    .cur_block_codeobj()
1747                    .cellvars
1748                    .iter()
1749                    .position(|n| n == &cellvar)
1750                    .unwrap();
1751                self.mut_cur_block().captured_vars.push(cellvar);
1752                let mut op_idx = 0;
1753                while let Some([op, arg]) = self
1754                    .mut_cur_block_codeobj()
1755                    .code
1756                    .get_mut(op_idx..=op_idx + 1)
1757                {
1758                    match Opcode310::try_from(*op) {
1759                        Ok(Opcode310::LOAD_FAST) if *arg == old_idx as u8 => {
1760                            *op = Opcode310::LOAD_DEREF as u8;
1761                            *arg = new_idx as u8;
1762                        }
1763                        Ok(Opcode310::STORE_FAST) if *arg == old_idx as u8 => {
1764                            *op = Opcode310::STORE_DEREF as u8;
1765                            *arg = new_idx as u8;
1766                        }
1767                        _ => {}
1768                    }
1769                    op_idx += 2;
1770                }
1771            }
1772        }
1773    }
1774
1775    fn emit_unaryop(&mut self, unary: UnaryOp) {
1776        log!(info "entered {} ({unary})", fn_name!());
1777        let init_stack_len = self.stack_len();
1778        let val_t = unary
1779            .info
1780            .t
1781            .non_default_params()
1782            .and_then(|tys| tys.first().map(|pt| pt.typ()))
1783            .unwrap_or(Type::FAILURE);
1784        let tycode = TypeCode::from(val_t);
1785        let instr = match &unary.op.kind {
1786            // TODO:
1787            TokenKind::PrePlus => UNARY_POSITIVE,
1788            TokenKind::PreMinus => UNARY_NEGATIVE,
1789            TokenKind::PreBitNot => UNARY_INVERT,
1790            TokenKind::Mutate => {
1791                if !self.mutate_op_loaded {
1792                    self.load_mutate_op();
1793                }
1794                if self.py_version.minor >= Some(11) {
1795                    self.emit_push_null();
1796                }
1797                self.emit_load_name_instr(Identifier::private("#mutate_operator"));
1798                NOP // ERG_MUTATE,
1799            }
1800            _ => {
1801                CompileError::feature_error(
1802                    self.cfg.input.clone(),
1803                    line!() as usize,
1804                    unary.op.loc(),
1805                    &unary.op.inspect().clone(),
1806                    String::from(unary.op.content),
1807                )
1808                .write_to_stderr();
1809                NOT_IMPLEMENTED
1810            }
1811        };
1812        self.emit_expr(*unary.expr);
1813        if instr != NOP {
1814            self.write_instr(instr);
1815            self.write_arg(tycode as usize);
1816        } else {
1817            if self.py_version.minor >= Some(11) {
1818                self.emit_precall_and_call(1);
1819            } else {
1820                self.write_instr(Opcode310::CALL_FUNCTION);
1821                self.write_arg(1);
1822            }
1823            self.stack_dec();
1824        }
1825        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1826    }
1827
1828    fn emit_binop(&mut self, bin: BinOp) {
1829        log!(info "entered {} ({bin})", fn_name!());
1830        let init_stack_len = self.stack_len();
1831        // TODO: and/orのプリミティブ命令の実装
1832        // Range operators are not operators in Python
1833        match &bin.op.kind {
1834            // l..<r == range(l, r)
1835            TokenKind::RightOpen => {
1836                self.emit_push_null();
1837                self.emit_load_name_instr(Identifier::static_public("RightOpenRange"));
1838            }
1839            TokenKind::LeftOpen => {
1840                self.emit_push_null();
1841                self.emit_load_name_instr(Identifier::static_public("LeftOpenRange"));
1842            }
1843            TokenKind::Closed => {
1844                self.emit_push_null();
1845                self.emit_load_name_instr(Identifier::static_public("ClosedRange"));
1846            }
1847            TokenKind::Open => {
1848                self.emit_push_null();
1849                self.emit_load_name_instr(Identifier::static_public("OpenRange"));
1850            }
1851            // From 3.10, `or` can be used for types.
1852            // But Erg supports Python 3.7~, so we should use `typing.Union`.
1853            TokenKind::OrOp if bin.lhs.ref_t().is_type() => {
1854                self.load_union();
1855                let args = Args::pos_only(vec![PosArg::new(*bin.lhs), PosArg::new(*bin.rhs)], None);
1856                self.emit_push_null();
1857                self.emit_load_name_instr(Identifier::private("#UnionType"));
1858                self.emit_args_311(args, Name);
1859                return;
1860            }
1861            // short circuiting
1862            TokenKind::OrOp => {
1863                self.emit_expr(*bin.lhs);
1864                let idx = self.lasti();
1865                self.write_instr(EXTENDED_ARG);
1866                self.write_arg(0);
1867                self.write_instr(Opcode311::JUMP_IF_TRUE_OR_POP);
1868                self.write_arg(0);
1869                self.emit_expr(*bin.rhs);
1870                let arg = match self.py_version.minor {
1871                    Some(11) => self.lasti() - idx - 4,
1872                    _ => self.lasti(),
1873                };
1874                self.fill_jump(idx + 1, arg);
1875                self.stack_dec();
1876                return;
1877            }
1878            TokenKind::AndOp => {
1879                self.emit_expr(*bin.lhs);
1880                let idx = self.lasti();
1881                self.write_instr(EXTENDED_ARG);
1882                self.write_arg(0);
1883                self.write_instr(Opcode311::JUMP_IF_FALSE_OR_POP);
1884                self.write_arg(0);
1885                self.emit_expr(*bin.rhs);
1886                let arg = match self.py_version.minor {
1887                    Some(11) => self.lasti() - idx - 4,
1888                    _ => self.lasti(),
1889                };
1890                self.fill_jump(idx + 1, arg);
1891                self.stack_dec();
1892                return;
1893            }
1894            TokenKind::ContainsOp => {
1895                // if no-std, always `x contains y == True`
1896                if self.cfg.no_std {
1897                    self.emit_load_const(true);
1898                    return;
1899                }
1900                if !self.contains_op_loaded {
1901                    self.load_contains_op();
1902                }
1903                self.emit_push_null();
1904                self.emit_load_name_instr(Identifier::private("#contains_operator"));
1905            }
1906            _ => {}
1907        }
1908        let lhs_t = bin
1909            .info
1910            .t
1911            .non_default_params()
1912            .and_then(|tys| tys.first().map(|pt| pt.typ()))
1913            .unwrap_or(Type::FAILURE);
1914        let rhs_t = bin
1915            .info
1916            .t
1917            .non_default_params()
1918            .and_then(|tys| tys.get(1).map(|pt| pt.typ()))
1919            .unwrap_or(Type::FAILURE);
1920        let type_pair = TypePair::new(lhs_t, rhs_t);
1921        self.emit_expr(*bin.lhs);
1922        self.emit_expr(*bin.rhs);
1923        self.emit_binop_instr(bin.op, type_pair);
1924        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
1925    }
1926
1927    fn emit_binop_instr(&mut self, binop: Token, type_pair: TypePair) {
1928        if self.py_version.minor >= Some(11) {
1929            self.emit_binop_instr_311(binop, type_pair);
1930        } else if self.py_version.minor >= Some(9) {
1931            self.emit_binop_instr_309(binop, type_pair);
1932        } else {
1933            self.emit_binop_instr_307(binop, type_pair);
1934        }
1935    }
1936
1937    fn emit_binop_instr_307(&mut self, binop: Token, type_pair: TypePair) {
1938        let instr = match &binop.kind {
1939            TokenKind::Plus => Opcode308::BINARY_ADD,
1940            TokenKind::Minus => Opcode308::BINARY_SUBTRACT,
1941            TokenKind::Star => Opcode308::BINARY_MULTIPLY,
1942            TokenKind::Slash => Opcode308::BINARY_TRUE_DIVIDE,
1943            TokenKind::FloorDiv => Opcode308::BINARY_FLOOR_DIVIDE,
1944            TokenKind::Pow => Opcode308::BINARY_POWER,
1945            TokenKind::Mod => Opcode308::BINARY_MODULO,
1946            TokenKind::AndOp | TokenKind::BitAnd => Opcode308::BINARY_AND,
1947            TokenKind::OrOp | TokenKind::BitOr => Opcode308::BINARY_OR,
1948            TokenKind::BitXor => Opcode308::BINARY_XOR,
1949            TokenKind::Less
1950            | TokenKind::LessEq
1951            | TokenKind::DblEq
1952            | TokenKind::NotEq
1953            | TokenKind::Gre
1954            | TokenKind::GreEq
1955            | TokenKind::InOp
1956            | TokenKind::NotInOp
1957            | TokenKind::IsOp
1958            | TokenKind::IsNotOp => Opcode308::COMPARE_OP,
1959            TokenKind::LeftOpen
1960            | TokenKind::RightOpen
1961            | TokenKind::Closed
1962            | TokenKind::Open
1963            | TokenKind::ContainsOp => Opcode308::CALL_FUNCTION, // ERG_BINARY_RANGE,
1964            _ => {
1965                CompileError::feature_error(
1966                    self.cfg.input.clone(),
1967                    line!() as usize,
1968                    binop.loc(),
1969                    &binop.inspect().clone(),
1970                    String::from(binop.content),
1971                )
1972                .write_to_stderr();
1973                Opcode308::NOT_IMPLEMENTED
1974            }
1975        };
1976        let arg = match &binop.kind {
1977            TokenKind::Less => 0,
1978            TokenKind::LessEq => 1,
1979            TokenKind::DblEq => 2,
1980            TokenKind::NotEq => 3,
1981            TokenKind::Gre => 4,
1982            TokenKind::GreEq => 5,
1983            TokenKind::InOp => 6,
1984            TokenKind::NotInOp => 7,
1985            TokenKind::IsOp => 8,
1986            TokenKind::IsNotOp => 9,
1987            TokenKind::LeftOpen
1988            | TokenKind::RightOpen
1989            | TokenKind::Closed
1990            | TokenKind::Open
1991            | TokenKind::ContainsOp => 2,
1992            _ => type_pair as usize,
1993        };
1994        self.write_instr(instr);
1995        self.write_arg(arg);
1996        self.stack_dec();
1997        match &binop.kind {
1998            TokenKind::LeftOpen
1999            | TokenKind::RightOpen
2000            | TokenKind::Open
2001            | TokenKind::Closed
2002            | TokenKind::ContainsOp => {
2003                self.stack_dec();
2004            }
2005            _ => {}
2006        }
2007    }
2008
2009    fn emit_binop_instr_309(&mut self, binop: Token, type_pair: TypePair) {
2010        let instr = match &binop.kind {
2011            TokenKind::Plus => Opcode309::BINARY_ADD,
2012            TokenKind::Minus => Opcode309::BINARY_SUBTRACT,
2013            TokenKind::Star => Opcode309::BINARY_MULTIPLY,
2014            TokenKind::Slash => Opcode309::BINARY_TRUE_DIVIDE,
2015            TokenKind::FloorDiv => Opcode309::BINARY_FLOOR_DIVIDE,
2016            TokenKind::Pow => Opcode309::BINARY_POWER,
2017            TokenKind::Mod => Opcode309::BINARY_MODULO,
2018            TokenKind::AndOp | TokenKind::BitAnd => Opcode309::BINARY_AND,
2019            TokenKind::OrOp | TokenKind::BitOr => Opcode309::BINARY_OR,
2020            TokenKind::BitXor => Opcode309::BINARY_XOR,
2021            TokenKind::IsOp | TokenKind::IsNotOp => Opcode309::IS_OP,
2022            TokenKind::Less
2023            | TokenKind::LessEq
2024            | TokenKind::DblEq
2025            | TokenKind::NotEq
2026            | TokenKind::Gre
2027            | TokenKind::GreEq => Opcode309::COMPARE_OP,
2028            TokenKind::LeftOpen
2029            | TokenKind::RightOpen
2030            | TokenKind::Closed
2031            | TokenKind::Open
2032            | TokenKind::ContainsOp => Opcode309::CALL_FUNCTION, // ERG_BINARY_RANGE,
2033            _ => {
2034                CompileError::feature_error(
2035                    self.cfg.input.clone(),
2036                    line!() as usize,
2037                    binop.loc(),
2038                    &binop.inspect().clone(),
2039                    String::from(binop.content),
2040                )
2041                .write_to_stderr();
2042                Opcode309::NOT_IMPLEMENTED
2043            }
2044        };
2045        let arg = match &binop.kind {
2046            TokenKind::Less => 0,
2047            TokenKind::LessEq => 1,
2048            TokenKind::DblEq => 2,
2049            TokenKind::NotEq => 3,
2050            TokenKind::Gre => 4,
2051            TokenKind::GreEq => 5,
2052            TokenKind::IsOp => 0,
2053            TokenKind::IsNotOp => 1,
2054            TokenKind::LeftOpen
2055            | TokenKind::RightOpen
2056            | TokenKind::Closed
2057            | TokenKind::Open
2058            | TokenKind::ContainsOp => 2,
2059            _ => type_pair as usize,
2060        };
2061        self.write_instr(instr);
2062        self.write_arg(arg);
2063        self.stack_dec();
2064        match &binop.kind {
2065            TokenKind::LeftOpen
2066            | TokenKind::RightOpen
2067            | TokenKind::Open
2068            | TokenKind::Closed
2069            | TokenKind::ContainsOp => {
2070                self.stack_dec();
2071            }
2072            _ => {}
2073        }
2074    }
2075
2076    fn emit_binop_instr_311(&mut self, binop: Token, type_pair: TypePair) {
2077        let instr = match &binop.kind {
2078            TokenKind::Plus
2079            | TokenKind::Minus
2080            | TokenKind::Star
2081            | TokenKind::Slash
2082            | TokenKind::FloorDiv
2083            | TokenKind::Pow
2084            | TokenKind::Mod
2085            | TokenKind::AndOp
2086            | TokenKind::OrOp
2087            | TokenKind::BitAnd
2088            | TokenKind::BitOr
2089            | TokenKind::BitXor => Opcode311::BINARY_OP,
2090            TokenKind::IsOp | TokenKind::IsNotOp => Opcode311::IS_OP,
2091            TokenKind::Less
2092            | TokenKind::LessEq
2093            | TokenKind::DblEq
2094            | TokenKind::NotEq
2095            | TokenKind::Gre
2096            | TokenKind::GreEq => Opcode311::COMPARE_OP,
2097            TokenKind::LeftOpen
2098            | TokenKind::RightOpen
2099            | TokenKind::Closed
2100            | TokenKind::Open
2101            | TokenKind::ContainsOp => {
2102                self.write_instr(Opcode311::PRECALL);
2103                self.write_arg(2);
2104                self.write_arg(0);
2105                self.write_arg(0);
2106                Opcode311::CALL
2107            }
2108            _ => {
2109                CompileError::feature_error(
2110                    self.cfg.input.clone(),
2111                    line!() as usize,
2112                    binop.loc(),
2113                    &binop.inspect().clone(),
2114                    String::from(binop.content),
2115                )
2116                .write_to_stderr();
2117                Opcode311::NOT_IMPLEMENTED
2118            }
2119        };
2120        let arg = match &binop.kind {
2121            TokenKind::Plus => BinOpCode::Add as usize,
2122            TokenKind::Minus => BinOpCode::Subtract as usize,
2123            TokenKind::Star => BinOpCode::Multiply as usize,
2124            TokenKind::Slash => BinOpCode::TrueDivide as usize,
2125            TokenKind::FloorDiv => BinOpCode::FloorDiv as usize,
2126            TokenKind::Pow => BinOpCode::Power as usize,
2127            TokenKind::Mod => BinOpCode::Remainder as usize,
2128            TokenKind::AndOp | TokenKind::BitAnd => BinOpCode::And as usize,
2129            TokenKind::OrOp | TokenKind::BitOr => BinOpCode::Or as usize,
2130            TokenKind::BitXor => BinOpCode::Xor as usize,
2131            TokenKind::Less => 0,
2132            TokenKind::LessEq => 1,
2133            TokenKind::DblEq => 2,
2134            TokenKind::NotEq => 3,
2135            TokenKind::Gre => 4,
2136            TokenKind::GreEq => 5,
2137            TokenKind::IsOp => 0,
2138            TokenKind::IsNotOp => 1,
2139            TokenKind::LeftOpen
2140            | TokenKind::RightOpen
2141            | TokenKind::Closed
2142            | TokenKind::Open
2143            | TokenKind::ContainsOp => 2,
2144            _ => type_pair as usize,
2145        };
2146        self.write_instr(instr);
2147        self.write_arg(arg);
2148        match instr {
2149            Opcode311::CALL => {
2150                self.write_bytes(&[0; 8]);
2151            }
2152            Opcode311::BINARY_OP => {
2153                self.write_bytes(&[0; 2]);
2154            }
2155            Opcode311::COMPARE_OP => {
2156                self.write_bytes(&[0; 4]);
2157            }
2158            _ => {}
2159        }
2160        self.stack_dec();
2161        match &binop.kind {
2162            TokenKind::LeftOpen
2163            | TokenKind::RightOpen
2164            | TokenKind::Open
2165            | TokenKind::Closed
2166            | TokenKind::ContainsOp => {
2167                self.stack_dec();
2168                if self.py_version.minor >= Some(11) {
2169                    self.stack_dec();
2170                }
2171            }
2172            _ => {}
2173        }
2174    }
2175
2176    fn emit_del_instr(&mut self, mut args: Args) {
2177        let Some(Expr::Accessor(Accessor::Ident(ident))) = args.remove_left_or_key("obj") else {
2178            log!(err "del instruction requires an identifier");
2179            return;
2180        };
2181        log!(info "entered {} ({ident})", fn_name!());
2182        let escaped = escape_ident(ident);
2183        let name = self
2184            .local_search(&escaped, Name)
2185            .unwrap_or_else(|| self.register_name(escaped, Fast));
2186        self.write_instr(DELETE_NAME);
2187        self.write_arg(name.idx);
2188        self.emit_load_const(ValueObj::None);
2189    }
2190
2191    fn emit_not_instr(&mut self, mut args: Args) {
2192        log!(info "entered {}", fn_name!());
2193        let expr = args.remove_left_or_key("b").unwrap();
2194        self.emit_expr(expr);
2195        self.write_instr(UNARY_NOT);
2196        self.write_arg(0);
2197    }
2198
2199    fn emit_discard_instr(&mut self, mut args: Args) {
2200        log!(info "entered {}", fn_name!());
2201        while let Some(arg) = args.try_remove(0) {
2202            self.emit_expr(arg);
2203            self.emit_pop_top();
2204        }
2205        self.emit_load_const(ValueObj::None);
2206    }
2207
2208    fn deopt_instr(&mut self, kind: ControlKind, args: Args) {
2209        if !self.control_loaded {
2210            self.load_control();
2211        }
2212        let local = match kind {
2213            ControlKind::If => Identifier::static_public("if__"),
2214            ControlKind::For => Identifier::static_public("for__"),
2215            ControlKind::While => Identifier::static_public("while__"),
2216            ControlKind::With => Identifier::static_public("with__"),
2217            ControlKind::Discard => Identifier::static_public("discard__"),
2218            ControlKind::Assert => Identifier::static_public("assert__"),
2219            kind => todo!("{kind:?}"),
2220        };
2221        self.emit_call_local(local, args);
2222    }
2223
2224    fn emit_if_instr(&mut self, mut args: Args) {
2225        log!(info "entered {}", fn_name!());
2226        let init_stack_len = self.stack_len();
2227        let cond = args.remove(0);
2228        self.emit_expr(cond);
2229        let idx_pop_jump_if_false = self.lasti();
2230        self.write_instr(EXTENDED_ARG);
2231        self.write_arg(0);
2232        // Opcode310::POP_JUMP_IF_FALSE == Opcode311::POP_JUMP_FORWARD_IF_FALSE
2233        self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
2234        // cannot detect where to jump to at this moment, so put as 0
2235        self.write_arg(0);
2236        match args.remove(0) {
2237            // then block
2238            Expr::Lambda(lambda) => {
2239                // let params = self.gen_param_names(&lambda.params);
2240                self.emit_simple_block(lambda.body);
2241            }
2242            other => {
2243                self.emit_expr(other);
2244            }
2245        }
2246        if args.get(0).is_some() {
2247            let idx_jump_forward = self.lasti();
2248            self.write_instr(EXTENDED_ARG);
2249            self.write_arg(0);
2250            self.write_instr(Opcode308::JUMP_FORWARD); // jump to end
2251            self.write_arg(0);
2252            // else block
2253            let idx_else_begin = match self.py_version.minor {
2254                Some(11) => self.lasti() - idx_pop_jump_if_false - 4,
2255                Some(7..=10) => self.lasti(),
2256                _ => self.lasti(),
2257            };
2258            self.fill_jump(idx_pop_jump_if_false + 1, idx_else_begin);
2259            match args.remove(0) {
2260                Expr::Lambda(lambda) => {
2261                    // let params = self.gen_param_names(&lambda.params);
2262                    self.emit_simple_block(lambda.body);
2263                }
2264                other => {
2265                    self.emit_expr(other);
2266                }
2267            }
2268            let idx_end = self.lasti();
2269            self.fill_jump(idx_jump_forward + 1, idx_end - idx_jump_forward - 2 - 1);
2270            // FIXME: this is a hack to make sure the stack is balanced
2271            while self.stack_len() != init_stack_len + 1 {
2272                self.stack_dec();
2273            }
2274        } else {
2275            self.write_instr(Opcode311::JUMP_FORWARD);
2276            let jump_to = match self.py_version.minor {
2277                Some(11 | 10) => 1,
2278                _ => 2,
2279            };
2280            self.write_arg(jump_to);
2281            // no else block
2282            let idx_end = if self.py_version.minor >= Some(11) {
2283                self.lasti() - idx_pop_jump_if_false - 3
2284            } else {
2285                self.lasti()
2286            };
2287            self.fill_jump(idx_pop_jump_if_false + 1, idx_end);
2288            self.emit_load_const(ValueObj::None);
2289            while self.stack_len() != init_stack_len + 1 {
2290                self.stack_dec();
2291            }
2292        }
2293        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2294    }
2295
2296    fn emit_for_instr(&mut self, mut args: Args) {
2297        log!(info "entered {} ({})", fn_name!(), args);
2298        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2299            return self.deopt_instr(ControlKind::For, args);
2300        }
2301        let _init_stack_len = self.stack_len();
2302        let iterable = args.remove(0);
2303        self.emit_expr(iterable);
2304        self.write_instr(GET_ITER);
2305        self.write_arg(0);
2306        let idx_for_iter = self.lasti();
2307        self.write_instr(EXTENDED_ARG);
2308        self.write_arg(0);
2309        self.write_instr(FOR_ITER);
2310        self.stack_inc();
2311        // FOR_ITER pushes a value onto the stack, but we can't know how many
2312        // but after executing this instruction, stack_len should be 1
2313        // cannot detect where to jump to at this moment, so put as 0
2314        self.write_arg(0);
2315        let Expr::Lambda(lambda) = args.remove(0) else {
2316            unreachable!()
2317        };
2318        // If there is nothing on the stack at the start, init_stack_len == 2 (an iterator and the first iterator value)
2319        let init_stack_len = self.stack_len();
2320        // store the iterator value, stack_len == 1 or 2 in the end
2321        self.emit_control_block(lambda.body, lambda.params);
2322        if self.stack_len() > init_stack_len - 1 {
2323            self.emit_pop_top();
2324        }
2325        debug_assert_eq!(self.stack_len(), init_stack_len - 1); // the iterator is remained
2326        let idx = self.lasti();
2327        self.write_instr(EXTENDED_ARG);
2328        self.write_arg(0);
2329        match self.py_version.minor {
2330            Some(11) => {
2331                self.write_instr(Opcode311::JUMP_BACKWARD);
2332                self.write_arg(0);
2333                self.fill_jump(idx + 1, self.lasti() - idx_for_iter);
2334            }
2335            Some(7..=10) => {
2336                self.write_instr(Opcode309::JUMP_ABSOLUTE);
2337                self.write_arg(0);
2338                self.fill_jump(idx + 1, idx_for_iter);
2339            }
2340            _ => todo!("not supported Python version"),
2341        }
2342        let idx_end = self.lasti();
2343        self.fill_jump(idx_for_iter + 1, idx_end - idx_for_iter - 2 - 2);
2344        self.stack_dec();
2345        self.emit_load_const(ValueObj::None);
2346        debug_assert_eq!(self.stack_len(), _init_stack_len + 1);
2347    }
2348
2349    fn emit_while_instr(&mut self, mut args: Args) {
2350        log!(info "entered {} ({})", fn_name!(), args);
2351        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2352            return self.deopt_instr(ControlKind::While, args);
2353        }
2354        let _init_stack_len = self.stack_len();
2355        // e.g. is_foo!: () => Bool, do!(is_bar)
2356        let cond_block = args.remove(0);
2357        let cond = match cond_block {
2358            Expr::Lambda(mut lambda) => lambda.body.remove(0),
2359            Expr::Accessor(acc) => Expr::Accessor(acc).call_expr(Args::empty()),
2360            _ => todo!(),
2361        };
2362        // Evaluate again at the end of the loop
2363        self.emit_expr(cond.clone());
2364        let idx_while = self.lasti();
2365        self.write_instr(EXTENDED_ARG);
2366        self.write_arg(0);
2367        self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
2368        self.write_arg(0);
2369        self.stack_dec();
2370        let Expr::Lambda(lambda) = args.remove(0) else {
2371            unreachable!()
2372        };
2373        let init_stack_len = self.stack_len();
2374        self.emit_control_block(lambda.body, lambda.params);
2375        if self.stack_len() > init_stack_len {
2376            self.emit_pop_top();
2377        }
2378        self.emit_expr(cond);
2379        let idx = self.lasti();
2380        self.write_instr(EXTENDED_ARG);
2381        self.write_arg(0);
2382        let arg = if self.py_version.minor >= Some(11) {
2383            let arg = self.lasti() - (idx_while + 2);
2384            self.write_instr(Opcode311::POP_JUMP_BACKWARD_IF_TRUE);
2385            self.write_arg(0);
2386            arg
2387        } else {
2388            self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2389            self.write_arg(0);
2390            idx_while + 4
2391        };
2392        self.fill_jump(idx + 1, arg);
2393        self.stack_dec();
2394        let idx_end = match self.py_version.minor {
2395            Some(11) => self.lasti() - idx_while - 3,
2396            _ => self.lasti(),
2397        };
2398        self.fill_jump(idx_while + 1, idx_end);
2399        self.emit_load_const(ValueObj::None);
2400        debug_assert_eq!(self.stack_len(), _init_stack_len + 1);
2401    }
2402
2403    fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) {
2404        log!(info "entered {}", fn_name!());
2405        let init_stack_len = self.stack_len();
2406        let expr = args.remove(0);
2407        self.emit_expr(expr);
2408        let len = args.len();
2409        let mut jump_forward_points = vec![];
2410        while let Some(expr) = args.try_remove(0) {
2411            if len > 1 && !args.is_empty() {
2412                self.dup_top();
2413            }
2414            // compilerで型チェック済み(可読性が下がるため、matchでNamedは使えない)
2415            let Expr::Lambda(lambda) = expr else {
2416                unreachable!()
2417            };
2418            debug_power_assert!(lambda.params.len(), ==, 1);
2419            if !lambda.params.defaults.is_empty() {
2420                todo!("default values in match expression are not supported yet")
2421            }
2422            let pop_jump_points = self.emit_match_pattern(lambda.params, args.is_empty());
2423            self.emit_simple_block(lambda.body);
2424            // If we move on to the next arm, the stack size will increase
2425            // so `self.stack_dec();` for now (+1 at the end).
2426            self.stack_dec();
2427            for pop_jump_point in pop_jump_points {
2428                let idx = match self.py_version.minor {
2429                    Some(11) => self.lasti() - pop_jump_point,
2430                    Some(10) => self.lasti() + 4,
2431                    _ => self.lasti() + 4,
2432                };
2433                self.fill_jump(pop_jump_point + 1, idx); // jump to POP_TOP
2434            }
2435            jump_forward_points.push(self.lasti());
2436            self.write_instr(EXTENDED_ARG);
2437            self.write_arg(0);
2438            self.write_instr(Opcode308::JUMP_FORWARD); // jump to the end
2439            self.write_arg(0);
2440        }
2441        let lasti = self.lasti();
2442        for jump_point in jump_forward_points.into_iter() {
2443            let jump_to = match self.py_version.minor {
2444                Some(11 | 10) => lasti - jump_point - 2 - 2,
2445                _ => lasti - jump_point - 2 - 2,
2446            };
2447            self.fill_jump(jump_point + 1, jump_to);
2448        }
2449        self.stack_inc();
2450        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2451    }
2452
2453    /// return `None` if the arm is the last one
2454    fn emit_match_pattern(&mut self, mut params: Params, is_last_arm: bool) -> Vec<usize> {
2455        let param = params.non_defaults.remove(0);
2456        log!(info "entered {}({param})", fn_name!());
2457        match &param.raw.pat {
2458            ParamPattern::VarName(name) => {
2459                let ident = erg_parser::ast::Identifier::private_from_varname(name.clone());
2460                let ident = Identifier::new(ident, None, param.vi);
2461                self.emit_store_instr(ident, AccessKind::Name);
2462            }
2463            ParamPattern::Discard(_) => {
2464                self.emit_pop_top();
2465            }
2466            _other => unreachable!(),
2467        }
2468        let mut pop_jump_points = vec![];
2469        let last = params.guards.len().saturating_sub(1);
2470        for (i, mut guard) in params.guards.into_iter().enumerate() {
2471            if let GuardClause::Condition(Expr::BinOp(BinOp {
2472                op:
2473                    Token {
2474                        kind: TokenKind::ContainsOp,
2475                        ..
2476                    },
2477                lhs,
2478                rhs,
2479                ..
2480            })) = &mut guard
2481            {
2482                // Guards have not been checked.
2483                // Therefore, an invalid guard may be generated.
2484                if lhs.var_info().is_some_and(|vi| vi == &VarInfo::ILLEGAL) {
2485                    continue;
2486                }
2487                if rhs.var_info().is_some_and(|vi| vi == &VarInfo::ILLEGAL) {
2488                    continue;
2489                }
2490                // *lhs.ref_mut_t().unwrap() = Type::Obj;
2491                *rhs.ref_mut_t().unwrap() = Type::Obj;
2492            }
2493            match guard {
2494                GuardClause::Bind(def) => {
2495                    self.emit_def(def);
2496                }
2497                GuardClause::Condition(cond) => {
2498                    self.emit_expr(cond);
2499                    if is_last_arm {
2500                        self.emit_pop_top();
2501                    } else {
2502                        pop_jump_points.push(self.lasti());
2503                        // HACK: match branches often jump very far (beyond the u8 range),
2504                        // so the jump destination should be reserved as the u16 range.
2505                        // Other jump instructions may need to be replaced by this way.
2506                        self.write_instr(EXTENDED_ARG);
2507                        self.write_arg(0);
2508                        // in 3.11, POP_JUMP_IF_FALSE is replaced with POP_JUMP_FORWARD_IF_FALSE
2509                        // but the numbers are the same, only the way the jumping points are calculated is different.
2510                        self.write_instr(Opcode310::POP_JUMP_IF_FALSE); // jump to the next case
2511                        self.write_arg(0);
2512                        // if matched, pop original
2513                        if i == last {
2514                            self.emit_pop_top();
2515                        } else {
2516                            self.stack_dec();
2517                        }
2518                    }
2519                }
2520            }
2521        }
2522        pop_jump_points
2523    }
2524
2525    fn emit_with_instr_311(&mut self, mut args: Args) {
2526        log!(info "entered {}", fn_name!());
2527        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2528            return self.deopt_instr(ControlKind::With, args);
2529        }
2530        let expr = args.remove(0);
2531        let Expr::Lambda(lambda) = args.remove(0) else {
2532            unreachable!()
2533        };
2534        let params = self.gen_param_names(&lambda.params);
2535        self.emit_expr(expr);
2536        self.write_instr(Opcode311::BEFORE_WITH);
2537        self.write_arg(0);
2538        // push __exit__, __enter__() to the stack
2539        self.stack_inc_n(2);
2540        let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2541        self.emit_with_block(lambda.body, params);
2542        let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2543        self.emit_store_instr(stash.clone(), Name);
2544        self.emit_load_const(ValueObj::None);
2545        self.emit_load_const(ValueObj::None);
2546        self.emit_load_const(ValueObj::None);
2547        self.emit_precall_and_call(2);
2548        self.emit_pop_top();
2549        let idx_jump_forward = self.lasti();
2550        self.write_instr(Opcode311::JUMP_FORWARD);
2551        self.write_arg(0);
2552        self.write_instr(Opcode311::PUSH_EXC_INFO);
2553        self.write_arg(0);
2554        self.write_instr(Opcode309::WITH_EXCEPT_START);
2555        self.write_arg(0);
2556        self.write_instr(Opcode311::POP_JUMP_FORWARD_IF_TRUE);
2557        self.write_arg(4);
2558        self.write_instr(Opcode311::RERAISE);
2559        self.write_arg(0);
2560        self.write_instr(Opcode311::COPY);
2561        self.write_arg(3);
2562        self.write_instr(Opcode311::POP_EXCEPT);
2563        self.write_arg(0);
2564        self.write_instr(Opcode311::RERAISE);
2565        self.write_arg(1);
2566        self.emit_pop_top();
2567        self.write_instr(Opcode311::POP_EXCEPT);
2568        self.write_arg(0);
2569        self.emit_pop_top();
2570        self.emit_pop_top();
2571        self.calc_edit_jump(idx_jump_forward + 1, self.lasti() - idx_jump_forward - 2);
2572        self.emit_load_name_instr(stash);
2573    }
2574
2575    fn emit_with_instr_310(&mut self, mut args: Args) {
2576        log!(info "entered {}", fn_name!());
2577        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2578            return self.deopt_instr(ControlKind::With, args);
2579        }
2580        let expr = args.remove(0);
2581        let Expr::Lambda(lambda) = args.remove(0) else {
2582            unreachable!()
2583        };
2584        let params = self.gen_param_names(&lambda.params);
2585        self.emit_expr(expr);
2586        let idx_setup_with = self.lasti();
2587        self.write_instr(Opcode310::SETUP_WITH);
2588        self.write_arg(0);
2589        // push __exit__, __enter__() to the stack
2590        self.stack_inc_n(2);
2591        let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2592        self.emit_with_block(lambda.body, params);
2593        let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2594        self.emit_store_instr(stash.clone(), Name);
2595        self.write_instr(POP_BLOCK);
2596        self.write_arg(0);
2597        self.emit_load_const(ValueObj::None);
2598        self.write_instr(Opcode310::DUP_TOP);
2599        self.write_arg(0);
2600        self.stack_inc();
2601        self.write_instr(Opcode310::DUP_TOP);
2602        self.write_arg(0);
2603        self.stack_inc();
2604        self.write_instr(Opcode310::CALL_FUNCTION);
2605        self.write_arg(3);
2606        self.stack_dec_n((1 + 3) - 1);
2607        self.emit_pop_top();
2608        let idx_jump_forward = self.lasti();
2609        self.write_instr(Opcode310::JUMP_FORWARD);
2610        self.write_arg(0);
2611        self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2612        self.write_instr(Opcode310::WITH_EXCEPT_START);
2613        self.write_arg(0);
2614        let idx_pop_jump_if_true = self.lasti();
2615        self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2616        self.write_arg(0);
2617        self.write_instr(Opcode310::RERAISE);
2618        self.write_arg(1);
2619        self.edit_code(idx_pop_jump_if_true + 1, self.lasti() / 2);
2620        // self.emit_pop_top();
2621        // self.emit_pop_top();
2622        self.emit_pop_top();
2623        self.write_instr(Opcode310::POP_EXCEPT);
2624        self.write_arg(0);
2625        let idx_end = self.lasti();
2626        self.edit_code(idx_jump_forward + 1, (idx_end - idx_jump_forward - 2) / 2);
2627        self.emit_load_name_instr(stash);
2628    }
2629
2630    fn emit_with_instr_309(&mut self, mut args: Args) {
2631        log!(info "entered {}", fn_name!());
2632        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2633            return self.deopt_instr(ControlKind::With, args);
2634        }
2635        let expr = args.remove(0);
2636        let Expr::Lambda(lambda) = args.remove(0) else {
2637            unreachable!()
2638        };
2639        let params = self.gen_param_names(&lambda.params);
2640        self.emit_expr(expr);
2641        let idx_setup_with = self.lasti();
2642        self.write_instr(Opcode310::SETUP_WITH);
2643        self.write_arg(0);
2644        // push __exit__, __enter__() to the stack
2645        self.stack_inc_n(2);
2646        let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2647        self.emit_with_block(lambda.body, params);
2648        let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2649        self.emit_store_instr(stash.clone(), Name);
2650        self.write_instr(POP_BLOCK);
2651        self.write_arg(0);
2652        self.emit_load_const(ValueObj::None);
2653        self.write_instr(Opcode310::DUP_TOP);
2654        self.write_arg(0);
2655        self.stack_inc();
2656        self.write_instr(Opcode310::DUP_TOP);
2657        self.write_arg(0);
2658        self.stack_inc();
2659        self.write_instr(Opcode310::CALL_FUNCTION);
2660        self.write_arg(3);
2661        self.stack_dec_n((1 + 3) - 1);
2662        self.emit_pop_top();
2663        let idx_jump_forward = self.lasti();
2664        self.write_instr(Opcode311::JUMP_FORWARD);
2665        self.write_arg(0);
2666        self.edit_code(idx_setup_with + 1, self.lasti() - idx_setup_with - 2);
2667        self.write_instr(Opcode310::WITH_EXCEPT_START);
2668        self.write_arg(0);
2669        let idx_pop_jump_if_true = self.lasti();
2670        self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
2671        self.write_arg(0);
2672        self.write_instr(Opcode309::RERAISE);
2673        self.write_arg(1);
2674        self.edit_code(idx_pop_jump_if_true + 1, self.lasti());
2675        // self.emit_pop_top();
2676        // self.emit_pop_top();
2677        self.emit_pop_top();
2678        self.write_instr(Opcode310::POP_EXCEPT);
2679        self.write_arg(0);
2680        let idx_end = self.lasti();
2681        self.edit_code(idx_jump_forward + 1, idx_end - idx_jump_forward - 2);
2682        self.emit_load_name_instr(stash);
2683    }
2684
2685    fn emit_with_instr_308(&mut self, mut args: Args) {
2686        log!(info "entered {}", fn_name!());
2687        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2688            return self.deopt_instr(ControlKind::With, args);
2689        }
2690        let expr = args.remove(0);
2691        let Expr::Lambda(lambda) = args.remove(0) else {
2692            unreachable!()
2693        };
2694        let params = self.gen_param_names(&lambda.params);
2695        self.emit_expr(expr);
2696        let idx_setup_with = self.lasti();
2697        self.write_instr(Opcode309::SETUP_WITH);
2698        self.write_arg(0);
2699        // push __exit__, __enter__() to the stack
2700        // self.stack_inc_n(2);
2701        let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2702        self.emit_with_block(lambda.body, params);
2703        let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2704        self.emit_store_instr(stash.clone(), Name);
2705        self.write_instr(POP_BLOCK);
2706        self.write_arg(0);
2707        self.write_instr(Opcode308::BEGIN_FINALLY);
2708        self.write_arg(0);
2709        self.write_instr(Opcode308::WITH_CLEANUP_START);
2710        self.write_arg(0);
2711        self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2712        self.write_instr(Opcode308::WITH_CLEANUP_FINISH);
2713        self.write_arg(0);
2714        self.write_instr(Opcode308::END_FINALLY);
2715        self.write_arg(0);
2716        self.emit_load_name_instr(stash);
2717    }
2718
2719    fn emit_with_instr_307(&mut self, mut args: Args) {
2720        log!(info "entered {}", fn_name!());
2721        if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
2722            return self.deopt_instr(ControlKind::With, args);
2723        }
2724        let expr = args.remove(0);
2725        let Expr::Lambda(lambda) = args.remove(0) else {
2726            unreachable!()
2727        };
2728        let params = self.gen_param_names(&lambda.params);
2729        self.emit_expr(expr);
2730        let idx_setup_with = self.lasti();
2731        self.write_instr(Opcode309::SETUP_WITH);
2732        self.write_arg(0);
2733        // push __exit__, __enter__() to the stack
2734        // self.stack_inc_n(2);
2735        let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
2736        self.emit_with_block(lambda.body, params);
2737        let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
2738        self.emit_store_instr(stash.clone(), Name);
2739        self.write_instr(POP_BLOCK);
2740        self.write_arg(0);
2741        self.emit_load_const(ValueObj::None);
2742        self.stack_dec();
2743        self.write_instr(Opcode308::WITH_CLEANUP_START);
2744        self.write_arg(0);
2745        self.edit_code(idx_setup_with + 1, (self.lasti() - idx_setup_with - 2) / 2);
2746        self.write_instr(Opcode308::WITH_CLEANUP_FINISH);
2747        self.write_arg(0);
2748        self.write_instr(Opcode308::END_FINALLY);
2749        self.write_arg(0);
2750        self.emit_load_name_instr(stash);
2751    }
2752
2753    fn emit_call(&mut self, call: Call) {
2754        log!(info "entered {} ({call})", fn_name!());
2755        let init_stack_len = self.stack_len();
2756        // Python cannot distinguish at compile time between a method call and a attribute call
2757        if let Some(attr_name) = call.attr_name {
2758            self.emit_call_method(*call.obj, attr_name, call.args);
2759        } else {
2760            match *call.obj {
2761                Expr::Accessor(Accessor::Ident(ident)) if ident.vis().is_private() => {
2762                    self.emit_call_local(ident, call.args)
2763                }
2764                other if other.ref_t().is_poly_meta_type() => {
2765                    self.emit_expr(other);
2766                    self.emit_index_args(call.args);
2767                }
2768                other => {
2769                    self.emit_push_null();
2770                    self.emit_expr(other);
2771                    self.emit_args_311(call.args, Name);
2772                }
2773            }
2774        }
2775        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
2776    }
2777
2778    fn emit_call_local(&mut self, local: Identifier, args: Args) {
2779        log!(info "entered {}", fn_name!());
2780        match &local.inspect()[..] {
2781            "assert" => self.emit_assert_instr(args),
2782            "Del" => self.emit_del_instr(args),
2783            "not" => self.emit_not_instr(args),
2784            "discard" => self.emit_discard_instr(args),
2785            "for" | "for!" => self.emit_for_instr(args),
2786            "while!" => self.emit_while_instr(args),
2787            "if" | "if!" => self.emit_if_instr(args),
2788            "match" | "match!" => self.emit_match_instr(args, true),
2789            "with!" => match self.py_version.minor {
2790                Some(11) => self.emit_with_instr_311(args),
2791                Some(10) => self.emit_with_instr_310(args),
2792                Some(9) => self.emit_with_instr_309(args),
2793                Some(8) => self.emit_with_instr_308(args),
2794                Some(7) => self.emit_with_instr_307(args),
2795                _ => todo!("not supported Python version"),
2796            },
2797            "sum" if self.py_version.minor <= Some(7) && args.get_kw("start").is_some() => {
2798                self.load_builtins();
2799                self.emit_load_name_instr(Identifier::private("#sum"));
2800                self.emit_args_311(args, Name);
2801            }
2802            "ListIterator" => {
2803                let list = Expr::Literal(Literal::new(ValueObj::List(vec![].into()), Token::DUMMY));
2804                let iter = Identifier::static_public("iter");
2805                let iter_call = iter.call(Args::single(PosArg::new(list)));
2806                let typ = Identifier::static_public("type");
2807                let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
2808                self.emit_call(typ_call);
2809            }
2810            "SetIterator" => {
2811                let set = Expr::Set(Set::empty());
2812                let iter = Identifier::static_public("iter");
2813                let iter_call = iter.call(Args::single(PosArg::new(set)));
2814                let typ = Identifier::static_public("type");
2815                let typ_call = typ.call(Args::single(PosArg::new(iter_call.into())));
2816                self.emit_call(typ_call);
2817            }
2818            "DictItems" => {
2819                let dict = Expr::Dict(Dict::empty());
2820                let iter = Identifier::static_public("iter");
2821                let items_call = iter.call(Args::single(PosArg::new(dict)));
2822                let typ = Identifier::static_public("type");
2823                let typ_call = typ.call(Args::single(PosArg::new(items_call.into())));
2824                self.emit_call(typ_call);
2825            }
2826            "DictKeys" => {
2827                let dict = Expr::Dict(Dict::empty());
2828                let keys = Identifier::static_public("keys");
2829                let keys_call = dict.method_call(keys, Args::empty());
2830                let typ = Identifier::static_public("type");
2831                let typ_call = typ.call(Args::single(PosArg::new(keys_call.into())));
2832                self.emit_call(typ_call);
2833            }
2834            "DictValues" => {
2835                let dict = Expr::Dict(Dict::empty());
2836                let values = Identifier::static_public("values");
2837                let values_call = dict.method_call(values, Args::empty());
2838                let typ = Identifier::static_public("type");
2839                let typ_call = typ.call(Args::single(PosArg::new(values_call.into())));
2840                self.emit_call(typ_call);
2841            }
2842            other if local.ref_t().is_poly_meta_type() && other != "classof" => {
2843                if self.py_version.minor <= Some(9) {
2844                    self.load_fake_generic();
2845                    self.emit_load_name_instr(Identifier::private("#FakeGenericAlias"));
2846                    let mut args = args;
2847                    args.insert_pos(0, PosArg::new(Expr::Accessor(Accessor::Ident(local))));
2848                    self.emit_args_311(args, Name);
2849                } else {
2850                    self.emit_load_name_instr(local);
2851                    self.emit_index_args(args);
2852                }
2853            }
2854            // "pyimport" | "py" are here
2855            _ => {
2856                self.emit_push_null();
2857                self.emit_load_name_instr(local);
2858                self.emit_args_311(args, Name);
2859            }
2860        }
2861    }
2862
2863    fn emit_call_method(&mut self, obj: Expr, method_name: Identifier, args: Args) {
2864        log!(info "entered {}", fn_name!());
2865        match &method_name.inspect()[..] {
2866            "return" if obj.ref_t().is_callable() => {
2867                return self.emit_return_instr(args);
2868            }
2869            // TODO: create `Generator` type
2870            "yield" /* if obj.ref_t().is_callable() */ => {
2871                return self.emit_yield_instr(args);
2872            }
2873            _ => {}
2874        }
2875        if let Some(func_name) = debind(&method_name) {
2876            return self.emit_call_fake_method(obj, func_name, method_name, args);
2877        }
2878        let is_type = method_name.ref_t().is_poly_meta_type();
2879        let kind = if self.py_version.minor >= Some(11)
2880            || (method_name.vi.t.is_method() && args.kw_args.is_empty())
2881        {
2882            BoundAttr
2883        } else {
2884            UnboundAttr
2885        };
2886        self.emit_expr(obj);
2887        self.emit_load_method_instr(method_name, kind);
2888        if is_type {
2889            self.emit_index_args(args);
2890        } else {
2891            self.emit_args_311(args, kind);
2892        }
2893    }
2894
2895    fn emit_var_args_311(&mut self, pos_len: usize, var_args: &PosArg) {
2896        if pos_len > 0 {
2897            self.write_instr(BUILD_LIST);
2898            self.write_arg(pos_len);
2899        }
2900        self.emit_expr(var_args.expr.clone());
2901        if pos_len > 0 {
2902            self.write_instr(Opcode310::LIST_EXTEND);
2903            self.write_arg(1);
2904            self.write_instr(Opcode310::LIST_TO_TUPLE);
2905            self.write_arg(0);
2906        }
2907        self.stack_dec();
2908    }
2909
2910    fn emit_var_args_308(&mut self, pos_len: usize, var_args: &PosArg) {
2911        if pos_len > 0 {
2912            self.write_instr(BUILD_TUPLE);
2913            self.write_arg(pos_len);
2914        }
2915        self.emit_expr(var_args.expr.clone());
2916        if pos_len > 0 {
2917            self.write_instr(Opcode309::BUILD_TUPLE_UNPACK_WITH_CALL);
2918            self.write_arg(2);
2919        }
2920        self.stack_dec();
2921    }
2922
2923    fn emit_kw_var_args_311(&mut self, pos_len: usize, kw_var: &PosArg) {
2924        self.write_instr(BUILD_TUPLE);
2925        self.write_arg(pos_len);
2926        self.stack_dec_n(pos_len.saturating_sub(1));
2927        self.write_instr(BUILD_MAP);
2928        self.write_arg(0);
2929        self.emit_expr(kw_var.expr.clone());
2930        self.write_instr(Opcode311::DICT_MERGE);
2931        self.write_arg(1);
2932    }
2933
2934    fn emit_kw_var_args_308(&mut self, pos_len: usize, kw_var: &PosArg) {
2935        self.write_instr(BUILD_TUPLE);
2936        self.write_arg(pos_len);
2937        self.emit_expr(kw_var.expr.clone());
2938        self.stack_dec_n(pos_len.saturating_sub(1));
2939    }
2940
2941    fn emit_args_311(&mut self, mut args: Args, kind: AccessKind) {
2942        let argc = args.len();
2943        let pos_len = args.pos_args.len();
2944        let mut kws = Vec::with_capacity(args.kw_len());
2945        while let Some(arg) = args.try_remove_pos(0) {
2946            self.emit_expr(arg.expr);
2947        }
2948        if let Some(var_args) = &args.var_args {
2949            if self.py_version.minor >= Some(9) {
2950                self.emit_var_args_311(pos_len, var_args);
2951            } else {
2952                self.emit_var_args_308(pos_len, var_args);
2953            }
2954        }
2955        while let Some(arg) = args.try_remove_kw(0) {
2956            kws.push(ValueObj::Str(arg.keyword.content));
2957            self.emit_expr(arg.expr);
2958        }
2959        // FIXME: tests/should_ok/args_expansion.er
2960        if let Some(kw_var) = &args.kw_var {
2961            if self.py_version.minor >= Some(9) {
2962                self.emit_kw_var_args_311(pos_len, kw_var);
2963            } else {
2964                self.emit_kw_var_args_308(pos_len, kw_var);
2965            }
2966        }
2967        let kwsc = if !kws.is_empty() {
2968            self.emit_call_kw_instr(argc, kws);
2969            #[allow(clippy::bool_to_int_with_if)]
2970            if self.py_version.minor >= Some(11) {
2971                0
2972            } else {
2973                1
2974            }
2975        } else if args.var_args.is_some() || args.kw_var.is_some() {
2976            self.write_instr(CALL_FUNCTION_EX);
2977            if kws.is_empty() && args.kw_var.is_none() {
2978                self.write_arg(0);
2979            } else {
2980                self.write_arg(1);
2981            }
2982            if self.py_version.minor >= Some(11) {
2983                self.stack_dec();
2984            }
2985            if args.kw_var.is_some() {
2986                1
2987            } else {
2988                0
2989            }
2990        } else {
2991            self.emit_call_instr(argc, kind);
2992            0
2993        };
2994        // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
2995        self.stack_dec_n((1 + argc + kwsc) - 1);
2996    }
2997
2998    fn emit_index_args(&mut self, mut args: Args) {
2999        let argc = args.pos_args.len();
3000        while let Some(arg) = args.try_remove_pos(0) {
3001            self.emit_expr(arg.expr);
3002        }
3003        if argc > 1 {
3004            self.write_instr(BUILD_TUPLE);
3005            self.write_arg(argc);
3006        }
3007        self.write_instr(Opcode311::BINARY_SUBSCR);
3008        self.write_arg(0);
3009        if self.py_version.minor >= Some(11) {
3010            self.write_bytes(&[0; 8]);
3011        }
3012        // (1 (subroutine) + argc) input objects -> 1 return object
3013        self.stack_dec_n((1 + argc) - 1);
3014    }
3015
3016    // TODO: use exception
3017    fn emit_return_instr(&mut self, mut args: Args) {
3018        log!(info "entered {}", fn_name!());
3019        if args.is_empty() {
3020            self.emit_load_const(ValueObj::None);
3021        } else {
3022            self.emit_expr(args.remove(0));
3023        }
3024        self.write_instr(RETURN_VALUE);
3025        self.write_arg(0);
3026    }
3027
3028    fn emit_yield_instr(&mut self, mut args: Args) {
3029        log!(info "entered {}", fn_name!());
3030        if args.is_empty() {
3031            self.emit_load_const(ValueObj::None);
3032        } else {
3033            self.emit_expr(args.remove(0));
3034        }
3035        self.write_instr(YIELD_VALUE);
3036        self.write_arg(0);
3037    }
3038
3039    /// 1.abs() => abs(1)
3040    fn emit_call_fake_method(
3041        &mut self,
3042        obj: Expr,
3043        func_name: Str,
3044        mut method_name: Identifier,
3045        mut args: Args,
3046    ) {
3047        log!(info "entered {}", fn_name!());
3048        method_name.raw.vis = VisModifierSpec::Private;
3049        method_name.vi.py_name = Some(func_name);
3050        self.emit_push_null();
3051        self.emit_load_name_instr(method_name);
3052        args.insert_pos(0, PosArg::new(obj));
3053        self.emit_args_311(args, Name);
3054    }
3055
3056    // assert takes 1 or 2 arguments (0: cond, 1: message)
3057    fn emit_assert_instr(&mut self, mut args: Args) {
3058        log!(info "entered {}", fn_name!());
3059        let init_stack_len = self.stack_len();
3060        self.emit_expr(args.remove(0));
3061        let pop_jump_point = self.lasti();
3062        self.write_instr(EXTENDED_ARG);
3063        self.write_arg(0);
3064        self.write_instr(Opcode310::POP_JUMP_IF_TRUE);
3065        self.write_arg(0);
3066        self.stack_dec();
3067        if self.py_version.minor >= Some(10) {
3068            self.write_instr(Opcode310::LOAD_ASSERTION_ERROR);
3069            self.write_arg(0);
3070            self.stack_inc();
3071        } else {
3072            self.emit_load_global_instr(Identifier::static_public("AssertionError"));
3073        }
3074        if let Some(expr) = args.try_remove(0) {
3075            self.emit_expr(expr);
3076            if self.py_version.minor >= Some(11) {
3077                self.emit_precall_and_call(0);
3078            } else {
3079                self.write_instr(Opcode310::CALL_FUNCTION);
3080                self.write_arg(1);
3081                self.stack_dec();
3082            }
3083        }
3084        self.write_instr(RAISE_VARARGS);
3085        self.write_arg(1);
3086        self.stack_dec();
3087        let idx = match self.py_version.minor {
3088            Some(11) => self.lasti() - pop_jump_point - 4,
3089            Some(10) => self.lasti(),
3090            Some(_) => self.lasti(),
3091            _ => todo!(),
3092        };
3093        self.fill_jump(pop_jump_point + 1, idx);
3094        self.emit_load_const(ValueObj::None);
3095        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3096    }
3097
3098    // TODO: list comprehension
3099    fn emit_list(&mut self, list: List) {
3100        let init_stack_len = self.stack_len();
3101        if !self.cfg.no_std {
3102            self.emit_push_null();
3103            if list.is_unsized() {
3104                self.emit_load_name_instr(Identifier::static_public("UnsizedList"));
3105            } else {
3106                self.emit_load_name_instr(Identifier::static_public("List"));
3107            }
3108        }
3109        match list {
3110            List::Normal(mut lis) => {
3111                let len = lis.elems.len();
3112                while let Some(arg) = lis.elems.try_remove_pos(0) {
3113                    self.emit_expr(arg.expr);
3114                }
3115                self.write_instr(BUILD_LIST);
3116                self.write_arg(len);
3117                if len == 0 {
3118                    self.stack_inc();
3119                } else {
3120                    self.stack_dec_n(len - 1);
3121                }
3122            }
3123            List::WithLength(ListWithLength {
3124                elem,
3125                len: Some(len),
3126                ..
3127            }) => {
3128                self.emit_expr(*elem);
3129                self.write_instr(BUILD_LIST);
3130                self.write_arg(1);
3131                self.emit_call_instr(1, Name);
3132                self.stack_dec();
3133                self.emit_expr(*len);
3134                self.emit_binop_instr(Token::dummy(TokenKind::Star, "*"), TypePair::ListNat);
3135                return;
3136            }
3137            List::WithLength(ListWithLength {
3138                elem, len: None, ..
3139            }) => {
3140                self.emit_expr(*elem);
3141            }
3142            other => todo!("{other}"),
3143        }
3144        if !self.cfg.no_std {
3145            self.emit_call_instr(1, Name);
3146            self.stack_dec();
3147        }
3148        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3149    }
3150
3151    // TODO: tuple comprehension
3152    // TODO: tuples can be const
3153    fn emit_tuple(&mut self, tuple: Tuple) {
3154        let init_stack_len = self.stack_len();
3155        match tuple {
3156            Tuple::Normal(mut tup) => {
3157                let len = tup.elems.len();
3158                while let Some(arg) = tup.elems.try_remove_pos(0) {
3159                    self.emit_expr(arg.expr);
3160                }
3161                self.write_instr(BUILD_TUPLE);
3162                self.write_arg(len);
3163                if len == 0 {
3164                    self.stack_inc();
3165                } else {
3166                    self.stack_dec_n(len - 1);
3167                }
3168            }
3169        }
3170        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3171    }
3172
3173    fn emit_set(&mut self, set: crate::hir::Set) {
3174        let init_stack_len = self.stack_len();
3175        match set {
3176            crate::hir::Set::Normal(mut set) => {
3177                let len = set.elems.len();
3178                while let Some(arg) = set.elems.try_remove_pos(0) {
3179                    self.emit_expr(arg.expr);
3180                }
3181                self.write_instr(BUILD_SET);
3182                self.write_arg(len);
3183                if len == 0 {
3184                    self.stack_inc();
3185                } else {
3186                    self.stack_dec_n(len - 1);
3187                }
3188            }
3189            crate::hir::Set::WithLength(st) => {
3190                self.emit_expr(*st.elem);
3191                self.write_instr(BUILD_SET);
3192                self.write_arg(1);
3193            }
3194        }
3195        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3196    }
3197
3198    fn emit_dict(&mut self, dict: crate::hir::Dict) {
3199        let init_stack_len = self.stack_len();
3200        if !self.cfg.no_std {
3201            self.emit_push_null();
3202            self.emit_load_name_instr(Identifier::static_public("Dict"));
3203        }
3204        match dict {
3205            crate::hir::Dict::Normal(dic) => {
3206                let len = dic.kvs.len();
3207                for kv in dic.kvs.into_iter() {
3208                    self.emit_expr(kv.key);
3209                    self.emit_expr(kv.value);
3210                }
3211                self.write_instr(BUILD_MAP);
3212                self.write_arg(len);
3213                if len == 0 {
3214                    self.stack_inc();
3215                } else {
3216                    self.stack_dec_n(2 * len - 1);
3217                }
3218            }
3219            other => todo!("{other}"),
3220        }
3221        if !self.cfg.no_std {
3222            self.emit_call_instr(1, Name);
3223            self.stack_dec();
3224        }
3225        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3226    }
3227
3228    #[allow(clippy::identity_op)]
3229    fn emit_record(&mut self, rec: Record) {
3230        log!(info "entered {} ({rec})", fn_name!());
3231        let init_stack_len = self.stack_len();
3232        let attrs_len = rec.attrs.len();
3233        self.emit_push_null();
3234        // making record type
3235        let ident = Identifier::private("#NamedTuple");
3236        self.emit_load_name_instr(ident);
3237        // record name, let it be anonymous
3238        self.emit_load_const("Record");
3239        for field in rec.attrs.iter() {
3240            self.emit_load_const(ValueObj::Str(field.sig.ident().inspect().clone()));
3241        }
3242        self.write_instr(BUILD_LIST);
3243        self.write_arg(attrs_len);
3244        if attrs_len == 0 {
3245            self.stack_inc();
3246        } else {
3247            self.stack_dec_n(attrs_len - 1);
3248        }
3249        self.emit_call_instr(2, Name);
3250        // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
3251        self.stack_dec_n((1 + 2 + 0) - 1);
3252        let ident = Identifier::private("#rec");
3253        self.emit_store_instr(ident, Name);
3254        // making record instance
3255        let ident = Identifier::private("#rec");
3256        self.emit_push_null();
3257        self.emit_load_name_instr(ident);
3258        for field in rec.attrs.into_iter() {
3259            self.emit_simple_block(field.body.block);
3260        }
3261        self.emit_call_instr(attrs_len, Name);
3262        // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
3263        self.stack_dec_n((1 + attrs_len + 0) - 1);
3264        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3265    }
3266
3267    /// Emits independent code blocks (e.g., linked other modules)
3268    fn emit_code(&mut self, code: Block) {
3269        let mut gen = self.inherit();
3270        let code = gen.emit_block(code, vec![], None, vec![], 0, vec![], 0);
3271        self.emit_load_const(code);
3272    }
3273
3274    pub(crate) fn get_root(acc: &Accessor) -> Identifier {
3275        match acc {
3276            Accessor::Ident(ident) => ident.clone(),
3277            Accessor::Attr(attr) => {
3278                if let Expr::Accessor(acc) = attr.obj.as_ref() {
3279                    Self::get_root(acc)
3280                } else {
3281                    todo!("{:?}", attr.obj)
3282                }
3283            }
3284        }
3285    }
3286
3287    fn emit_import(&mut self, acc: Accessor) {
3288        self.emit_load_const(0i32);
3289        self.emit_load_const(ValueObj::None);
3290        let full_name = Str::from(
3291            acc.qual_name()
3292                .map_or(acc.show(), |s| s.replace(".__init__", "")),
3293        );
3294        let name = self
3295            .local_search(&full_name, Name)
3296            .unwrap_or_else(|| self.register_name(full_name, Import));
3297        self.write_instr(IMPORT_NAME);
3298        self.write_arg(name.idx);
3299        let root = Self::get_root(&acc);
3300        self.emit_store_instr(root, Name);
3301        self.stack_dec();
3302    }
3303
3304    fn emit_compound(&mut self, chunks: Block) {
3305        let is_module_loading_chunks = chunks
3306            .get(2)
3307            .map(|chunk| {
3308                option_enum_unwrap!(chunk, Expr::Call)
3309                    .map(|call| call.obj.show_acc().as_ref().map(|s| &s[..]) == Some("exec"))
3310                    .unwrap_or(false)
3311            })
3312            .unwrap_or(false);
3313        if !self.module_type_loaded && is_module_loading_chunks {
3314            self.load_module_type();
3315            self.module_type_loaded = true;
3316        }
3317        let init_stack_len = self.stack_len();
3318        for chunk in chunks.into_iter() {
3319            self.emit_chunk(chunk);
3320            if self.stack_len() == init_stack_len + 1 {
3321                self.emit_pop_top();
3322            }
3323        }
3324        self.cancel_if_pop_top();
3325    }
3326
3327    /// See `cpython/Object/lnotab_notes.txt` in details
3328    fn push_lnotab(&mut self, expr: &Expr) {
3329        let ln_begin = expr.ln_begin().unwrap_or(0);
3330        if ln_begin > self.cur_block().prev_lineno {
3331            let mut sd = self.lasti() - self.cur_block().prev_lasti;
3332            let mut ld = ln_begin - self.cur_block().prev_lineno;
3333            if ld != 0 {
3334                if sd != 0 {
3335                    while sd > 254 {
3336                        self.mut_cur_block_codeobj().lnotab.push(255);
3337                        self.mut_cur_block_codeobj().lnotab.push(0);
3338                        sd -= 254;
3339                    }
3340                    while ld > 127 {
3341                        self.mut_cur_block_codeobj().lnotab.push(0);
3342                        self.mut_cur_block_codeobj().lnotab.push(127);
3343                        ld -= 127;
3344                    }
3345                    self.mut_cur_block_codeobj().lnotab.push(sd as u8);
3346                    self.mut_cur_block_codeobj().lnotab.push(ld as u8);
3347                } else {
3348                    // empty lines
3349                    if let Some(&last_ld) = self.cur_block_codeobj().lnotab.last() {
3350                        if last_ld as u32 + ld > 127 {
3351                            *self.mut_cur_block_codeobj().lnotab.last_mut().unwrap() = 127;
3352                            self.mut_cur_block_codeobj().lnotab.push(0);
3353                            ld -= 127;
3354                        }
3355                        while last_ld as u32 + ld > 127 {
3356                            self.mut_cur_block_codeobj().lnotab.push(127);
3357                            self.mut_cur_block_codeobj().lnotab.push(0);
3358                            ld -= 127;
3359                        }
3360                        self.mut_cur_block_codeobj().lnotab.push(ld as u8);
3361                    } else {
3362                        // a block starts with an empty line
3363                        self.mut_cur_block_codeobj().lnotab.push(0);
3364                        self.mut_cur_block_codeobj()
3365                            .lnotab
3366                            .push(u8::try_from(ld).unwrap());
3367                    }
3368                }
3369                self.mut_cur_block().prev_lineno += ld;
3370                self.mut_cur_block().prev_lasti = self.lasti();
3371            } else {
3372                CompileError::compiler_bug(
3373                    0,
3374                    self.cfg.input.clone(),
3375                    expr.loc(),
3376                    fn_name_full!(),
3377                    line!(),
3378                )
3379                .write_to_stderr();
3380                self.crash("codegen failed: invalid bytecode format");
3381            }
3382        }
3383    }
3384
3385    fn emit_chunk(&mut self, chunk: Expr) {
3386        log!(info "entered {} ({chunk})", fn_name!());
3387        self.push_lnotab(&chunk);
3388        match chunk {
3389            Expr::Literal(lit) => self.emit_load_const(lit.value),
3390            Expr::Accessor(acc) => self.emit_acc(acc),
3391            Expr::Def(def) => self.emit_def(def),
3392            Expr::ClassDef(class) => self.emit_class_def(class),
3393            Expr::PatchDef(patch) => self.emit_patch_def(patch),
3394            Expr::ReDef(attr) => self.emit_redef(attr),
3395            Expr::Lambda(lambda) => self.emit_lambda(lambda),
3396            Expr::UnaryOp(unary) => self.emit_unaryop(unary),
3397            Expr::BinOp(bin) => self.emit_binop(bin),
3398            Expr::Call(call) => self.emit_call(call),
3399            Expr::List(lis) => self.emit_list(lis),
3400            Expr::Tuple(tup) => self.emit_tuple(tup),
3401            Expr::Set(set) => self.emit_set(set),
3402            Expr::Dict(dict) => self.emit_dict(dict),
3403            Expr::Record(rec) => self.emit_record(rec),
3404            Expr::Code(code) => self.emit_code(code),
3405            Expr::Compound(chunks) => self.emit_compound(chunks),
3406            Expr::Import(acc) => self.emit_import(acc),
3407            Expr::Dummy(_) | Expr::TypeAsc(_) => {}
3408        }
3409    }
3410
3411    fn emit_expr(&mut self, expr: Expr) {
3412        log!(info "entered {} ({expr})", fn_name!());
3413        self.push_lnotab(&expr);
3414        let init_stack_len = self.stack_len();
3415        let mut wrapped = true;
3416        if !self.cfg.no_std && expr.should_wrap() {
3417            match expr.ref_t().derefine() {
3418                v @ (Bool | Nat | Int | Float | Str) => {
3419                    self.emit_push_null();
3420                    self.emit_load_name_instr(Identifier::public(&v.qual_name()));
3421                }
3422                other => match &other.qual_name()[..] {
3423                    t @ ("Bytes" | "List" | "Dict" | "Set") => {
3424                        self.emit_push_null();
3425                        self.emit_load_name_instr(Identifier::public(t));
3426                    }
3427                    _ => {
3428                        wrapped = false;
3429                    }
3430                },
3431            }
3432        } else {
3433            wrapped = false;
3434        }
3435        match expr {
3436            Expr::Literal(lit) => self.emit_load_const(lit.value),
3437            Expr::Accessor(acc) => self.emit_acc(acc),
3438            Expr::Def(def) => self.emit_def(def),
3439            Expr::ClassDef(class) => self.emit_class_def(class),
3440            Expr::PatchDef(patch) => self.emit_patch_def(patch),
3441            Expr::ReDef(attr) => self.emit_redef(attr),
3442            Expr::Lambda(lambda) => self.emit_lambda(lambda),
3443            Expr::UnaryOp(unary) => self.emit_unaryop(unary),
3444            Expr::BinOp(bin) => self.emit_binop(bin),
3445            Expr::Call(call) => self.emit_call(call),
3446            Expr::List(lis) => self.emit_list(lis),
3447            Expr::Tuple(tup) => self.emit_tuple(tup),
3448            Expr::Set(set) => self.emit_set(set),
3449            Expr::Dict(dict) => self.emit_dict(dict),
3450            Expr::Record(rec) => self.emit_record(rec),
3451            Expr::Code(code) => self.emit_code(code),
3452            Expr::Compound(chunks) => self.emit_compound(chunks),
3453            Expr::TypeAsc(tasc) => self.emit_expr(*tasc.expr),
3454            Expr::Import(acc) => self.emit_import(acc),
3455            Expr::Dummy(_) => {}
3456        }
3457        if !self.cfg.no_std && wrapped {
3458            self.emit_call_instr(1, Name);
3459            self.stack_dec();
3460        }
3461        debug_assert_eq!(self.stack_len(), init_stack_len + 1);
3462    }
3463
3464    /// forブロックなどで使う
3465    fn emit_control_block(&mut self, block: Block, params: Params) {
3466        log!(info "entered {}", fn_name!());
3467        let param_names = self.gen_param_names(&params);
3468        let line = block.ln_begin().unwrap_or(0);
3469        for param in param_names {
3470            self.emit_store_instr(Identifier::public_with_line(DOT, param, line), Name);
3471        }
3472        for guard in params.guards {
3473            if let GuardClause::Bind(bind) = guard {
3474                self.emit_def(bind);
3475            }
3476        }
3477        if block.is_empty() {
3478            return;
3479        }
3480        let init_stack_len = self.stack_len();
3481        for chunk in block.into_iter() {
3482            self.emit_chunk(chunk);
3483            if self.stack_len() > init_stack_len {
3484                self.emit_pop_top();
3485            }
3486        }
3487        self.cancel_if_pop_top();
3488    }
3489
3490    fn emit_simple_block(&mut self, block: Block) {
3491        log!(info "entered {}", fn_name!());
3492        if block.is_empty() {
3493            return;
3494        }
3495        let init_stack_len = self.stack_len();
3496        for chunk in block.into_iter() {
3497            self.emit_chunk(chunk);
3498            if self.stack_len() > init_stack_len {
3499                self.emit_pop_top();
3500            }
3501        }
3502        self.cancel_if_pop_top();
3503    }
3504
3505    fn emit_with_block(&mut self, block: Block, params: Vec<Str>) {
3506        log!(info "entered {}", fn_name!());
3507        let line = block.ln_begin().unwrap_or(0);
3508        for param in params {
3509            self.emit_store_instr(Identifier::public_with_line(DOT, param, line), Name);
3510        }
3511        let init_stack_len = self.stack_len();
3512        for chunk in block.into_iter() {
3513            self.emit_chunk(chunk);
3514            // __exit__, __enter__() are on the stack
3515            if self.stack_len() > init_stack_len {
3516                self.emit_pop_top();
3517            }
3518        }
3519        self.cancel_if_pop_top();
3520    }
3521
3522    fn emit_class_block(&mut self, class: ClassDef) -> CodeObj {
3523        log!(info "entered {}", fn_name!());
3524        let name = class.sig.ident().inspect().clone();
3525        self.unit_size += 1;
3526        let firstlineno = match class.methods_list.first().and_then(|def| def.ln_begin()) {
3527            Some(l) => l,
3528            None => class.sig.ln_begin().unwrap_or(0),
3529        };
3530        self.units.push(PyCodeGenUnit::new(
3531            self.unit_size,
3532            self.py_version,
3533            vec![],
3534            0,
3535            Str::rc(self.cfg.input.enclosed_name()),
3536            &name,
3537            firstlineno,
3538            0,
3539        ));
3540        let init_stack_len = self.stack_len();
3541        let mod_name = self.toplevel_block_codeobj().name.clone();
3542        self.emit_load_const(mod_name);
3543        self.emit_store_instr(Identifier::static_public("__module__"), Name);
3544        self.emit_load_const(name);
3545        self.emit_store_instr(Identifier::static_public("__qualname__"), Name);
3546        let mut methods = ClassDef::take_all_methods(class.methods_list);
3547        let __init__ = methods
3548            .get_def("__init__")
3549            .or_else(|| methods.get_def("__init__!"))
3550            .cloned();
3551        self.emit_init_method(&class.sig, __init__, class.constructor.clone());
3552        if class.need_to_gen_new {
3553            self.emit_new_func(&class.sig, class.constructor);
3554        }
3555        let __del__ = methods
3556            .remove_def("__del__")
3557            .or_else(|| methods.remove_def("__del__!"));
3558        if let Some(mut __del__) = __del__ {
3559            __del__.sig.ident_mut().vi.py_name = Some(Str::from("__del__"));
3560            self.emit_def(__del__);
3561        }
3562        if !methods.is_empty() {
3563            self.emit_simple_block(methods);
3564        }
3565        if self.stack_len() == init_stack_len {
3566            self.emit_load_const(ValueObj::None);
3567        }
3568        self.write_instr(RETURN_VALUE);
3569        self.write_arg(0);
3570        if self.stack_len() > 1 {
3571            let block_id = self.cur_block().id;
3572            let stack_len = self.stack_len();
3573            CompileError::stack_bug(
3574                self.input().clone(),
3575                Location::Unknown,
3576                stack_len,
3577                block_id,
3578                fn_name_full!(),
3579            )
3580            .write_to_stderr();
3581            self.crash("error in emit_class_block: invalid stack size");
3582        }
3583        // flagging
3584        if !self.cur_block_codeobj().varnames.is_empty() {
3585            self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
3586        }
3587        // end of flagging
3588        let unit = self.units.pop().unwrap();
3589        if !self.units.is_empty() {
3590            let ld = unit.prev_lineno - self.cur_block().prev_lineno;
3591            if ld != 0 {
3592                if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
3593                    *l += u8::try_from(ld).unwrap();
3594                }
3595                self.mut_cur_block().prev_lineno += ld;
3596            }
3597        }
3598        unit.codeobj
3599    }
3600
3601    fn emit_init_method(&mut self, sig: &Signature, __init__: Option<Def>, constructor: Type) {
3602        log!(info "entered {}", fn_name!());
3603        let new_first_param = constructor.non_default_params().unwrap().first();
3604        let line = sig.ln_begin().unwrap_or(0);
3605        let class_name = sig.ident().inspect();
3606        let mut ident = Identifier::public_with_line(DOT, Str::ever("__init__"), line);
3607        ident.vi.t = constructor.clone();
3608        let self_param = VarName::from_str_and_line(Str::ever("self"), line);
3609        let vi = VarInfo::nd_parameter(
3610            constructor.return_t().unwrap().clone(),
3611            ident.vi.def_loc.clone(),
3612            "?".into(),
3613        );
3614        let raw =
3615            erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None);
3616        let self_param = NonDefaultParamSignature::new(raw, vi, None);
3617        let (param_name, params) = if let Some(new_first_param) = new_first_param {
3618            let param_name = new_first_param
3619                .name()
3620                .cloned()
3621                .unwrap_or_else(|| self.fresh_gen.fresh_varname());
3622            let param = VarName::from_str_and_line(param_name.clone(), line);
3623            let raw =
3624                erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
3625            let vi = VarInfo::nd_parameter(
3626                new_first_param.typ().clone(),
3627                ident.vi.def_loc.clone(),
3628                "?".into(),
3629            );
3630            let param = NonDefaultParamSignature::new(raw, vi, None);
3631            let params = Params::new(vec![self_param, param], None, vec![], None, vec![], None);
3632            (param_name, params)
3633        } else {
3634            ("_".into(), Params::single(self_param))
3635        };
3636        let bounds = TypeBoundSpecs::empty();
3637        let subr_sig = SubrSignature::new(
3638            set! {},
3639            ident,
3640            bounds,
3641            params,
3642            sig.t_spec_with_op().cloned(),
3643            vec![],
3644        );
3645        let mut attrs = vec![];
3646        match new_first_param.map(|pt| pt.typ()) {
3647            // namedtupleは仕様上::xなどの名前を使えない
3648            // {x = Int; y = Int}
3649            //   => self::x = %x.x; self::y = %x.y
3650            // {.x = Int; .y = Int}
3651            //   => self.x = %x.x; self.y = %x.y
3652            // () => pass
3653            Some(Type::Record(rec)) => {
3654                for field in rec.keys() {
3655                    let obj =
3656                        Expr::Accessor(Accessor::private_with_line(Str::from(&param_name), line));
3657                    let ident = erg_parser::ast::Identifier::public(field.symbol.clone());
3658                    let expr = obj.attr_expr(Identifier::bare(ident));
3659                    let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
3660                    let dot = if field.vis.is_private() {
3661                        VisModifierSpec::Private
3662                    } else {
3663                        VisModifierSpec::Public(Location::Unknown)
3664                    };
3665                    let attr = erg_parser::ast::Identifier::new(
3666                        dot,
3667                        VarName::from_str(field.symbol.clone()),
3668                    );
3669                    let attr = obj.attr(Identifier::bare(attr));
3670                    let redef = ReDef::new(attr, Block::new(vec![expr]));
3671                    attrs.push(Expr::ReDef(redef));
3672                }
3673            }
3674            // self::base = %x
3675            Some(_) => {
3676                let expr =
3677                    Expr::Accessor(Accessor::private_with_line(Str::from(&param_name), line));
3678                let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
3679                let attr = obj.attr(Identifier::private_with_line(Str::ever("base"), line));
3680                let redef = ReDef::new(attr, Block::new(vec![expr]));
3681                attrs.push(Expr::ReDef(redef));
3682            }
3683            None => {}
3684        }
3685        if let Some(__init__) = __init__ {
3686            attrs.extend(__init__.body.block.clone());
3687        }
3688        let none = Token::new_fake(TokenKind::NoneLit, "None", line, 0, 0);
3689        attrs.push(Expr::Literal(Literal::new(ValueObj::None, none)));
3690        let block = Block::new(attrs);
3691        let body = DefBody::new(EQUAL, block, DefId(0));
3692        self.emit_subr_def(Some(class_name), subr_sig, body);
3693    }
3694
3695    /// ```python
3696    /// class C:
3697    ///     # constructor => C
3698    ///     def new(x): return C(x)
3699    /// ```
3700    fn emit_new_func(&mut self, sig: &Signature, constructor: Type) {
3701        log!(info "entered {}", fn_name!());
3702        let class_ident = sig.ident();
3703        let line = sig.ln_begin().unwrap_or(0);
3704        let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line);
3705        let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
3706        ident.vi.t = constructor;
3707        if let Ok(subr) = <&SubrType>::try_from(&ident.vi.t) {
3708            let mut params = Params::empty();
3709            let mut args = Args::empty();
3710            for nd_param in subr.non_default_params.iter() {
3711                let param_name = nd_param
3712                    .name()
3713                    .cloned()
3714                    .unwrap_or_else(|| self.fresh_gen.fresh_varname());
3715                let param = VarName::from_str_and_line(param_name.clone(), line);
3716                let vi = VarInfo::nd_parameter(
3717                    nd_param.typ().clone(),
3718                    ident.vi.def_loc.clone(),
3719                    "?".into(),
3720                );
3721                let raw = erg_parser::ast::NonDefaultParamSignature::new(
3722                    ParamPattern::VarName(param),
3723                    None,
3724                );
3725                let param = NonDefaultParamSignature::new(raw, vi, None);
3726                params.push_non_default(param);
3727                let arg = PosArg::new(Expr::Accessor(Accessor::public_with_line(param_name, line)));
3728                args.push_pos(arg);
3729            }
3730            // FIXME: var params, default params, kw var params
3731            let bounds = TypeBoundSpecs::empty();
3732            let sig = SubrSignature::new(
3733                set! {},
3734                ident,
3735                bounds,
3736                params,
3737                sig.t_spec_with_op().cloned(),
3738                vec![],
3739            );
3740            let call = class.call_expr(args);
3741            let block = Block::new(vec![call]);
3742            let body = DefBody::new(EQUAL, block, DefId(0));
3743            self.emit_subr_def(Some(class_ident.inspect()), sig, body);
3744        } else {
3745            let params = Params::empty();
3746            let bounds = TypeBoundSpecs::empty();
3747            let sig = SubrSignature::new(
3748                set! {},
3749                ident,
3750                bounds,
3751                params,
3752                sig.t_spec_with_op().cloned(),
3753                vec![],
3754            );
3755            let call = class.call_expr(Args::empty());
3756            let block = Block::new(vec![call]);
3757            let body = DefBody::new(EQUAL, block, DefId(0));
3758            self.emit_subr_def(Some(class_ident.inspect()), sig, body);
3759        }
3760    }
3761
3762    #[allow(clippy::too_many_arguments)]
3763    fn emit_block(
3764        &mut self,
3765        block: Block,
3766        guards: Vec<GuardClause>,
3767        opt_name: Option<Str>,
3768        params: Vec<Str>,
3769        kwonlyargcount: u32,
3770        captured_names: Vec<Identifier>,
3771        flags: u32,
3772    ) -> CodeObj {
3773        log!(info "entered {}", fn_name!());
3774        self.unit_size += 1;
3775        let name = if let Some(name) = opt_name {
3776            name
3777        } else {
3778            self.fresh_gen.fresh_varname()
3779        };
3780        let firstlineno = block
3781            .first()
3782            .and_then(|first| first.ln_begin())
3783            .unwrap_or(0);
3784        self.units.push(PyCodeGenUnit::new(
3785            self.unit_size,
3786            self.py_version,
3787            params,
3788            kwonlyargcount,
3789            Str::rc(self.cfg.input.enclosed_name()),
3790            name,
3791            firstlineno,
3792            flags,
3793        ));
3794        let idx_copy_free_vars = if self.py_version.minor >= Some(11) {
3795            let idx_copy_free_vars = self.lasti();
3796            self.write_instr(Opcode311::COPY_FREE_VARS);
3797            self.write_arg(0);
3798            self.write_instr(Opcode311::RESUME);
3799            self.write_arg(0);
3800            idx_copy_free_vars
3801        } else {
3802            0
3803        };
3804        let mut cells = vec![];
3805        for captured in captured_names {
3806            self.mut_cur_block()
3807                .captured_vars
3808                .push(captured.inspect().clone());
3809            if self.py_version.minor >= Some(11) {
3810                self.write_instr(Opcode311::MAKE_CELL);
3811                cells.push((captured, self.lasti()));
3812                self.write_arg(0);
3813            }
3814        }
3815        let init_stack_len = self.stack_len();
3816        for guard in guards {
3817            if let GuardClause::Bind(bind) = guard {
3818                self.emit_def(bind);
3819            }
3820        }
3821        for chunk in block.into_iter() {
3822            self.emit_chunk(chunk);
3823            // NOTE: 各行のトップレベルでは0個または1個のオブジェクトが残っている
3824            // Pythonの場合使わなかったオブジェクトはそのまま捨てられるが、Ergではdiscardを使う必要がある
3825            // TODO: discard
3826            if self.stack_len() > init_stack_len {
3827                self.emit_pop_top();
3828            }
3829        }
3830        self.cancel_if_pop_top(); // 最後の値は戻り値として取っておく
3831        if self.stack_len() == init_stack_len {
3832            self.emit_load_const(ValueObj::None);
3833        } else if self.stack_len() > init_stack_len + 1 {
3834            let block_id = self.cur_block().id;
3835            let stack_len = self.stack_len();
3836            CompileError::stack_bug(
3837                self.input().clone(),
3838                Location::Unknown,
3839                stack_len,
3840                block_id,
3841                fn_name_full!(),
3842            )
3843            .write_to_stderr();
3844            self.crash("error in emit_block: invalid stack size");
3845        }
3846        self.write_instr(RETURN_VALUE);
3847        self.write_arg(0);
3848        // flagging
3849        if !self.cur_block_codeobj().varnames.is_empty() {
3850            self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
3851        }
3852        let freevars_len = self.cur_block_codeobj().freevars.len();
3853        if freevars_len > 0 {
3854            self.mut_cur_block_codeobj().flags += CodeObjFlags::Nested as u32;
3855            if self.py_version.minor >= Some(11) {
3856                self.edit_code(idx_copy_free_vars + 1, freevars_len);
3857            }
3858        } else if self.py_version.minor >= Some(11) {
3859            // cancel copying
3860            let code = self.cur_block_codeobj().code.get(idx_copy_free_vars);
3861            debug_assert_eq!(code, Some(&(Opcode311::COPY_FREE_VARS as u8)));
3862            self.edit_code(idx_copy_free_vars, CommonOpcode::NOP as usize);
3863        }
3864        for (cell, placeholder) in cells {
3865            let name = escape_ident(cell);
3866            let Some(idx) = self
3867                .cur_block_codeobj()
3868                .varnames
3869                .iter()
3870                .position(|v| v == &name)
3871            else {
3872                continue;
3873            };
3874            self.edit_code(placeholder, idx);
3875        }
3876        // end of flagging
3877        let unit = self.units.pop().unwrap();
3878        // increase lineno
3879        if !self.units.is_empty() {
3880            let ld = unit
3881                .prev_lineno
3882                .saturating_sub(self.cur_block().prev_lineno);
3883            if ld != 0 {
3884                if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
3885                    *l += u8::try_from(ld).unwrap();
3886                }
3887                self.mut_cur_block().prev_lineno += ld;
3888            }
3889        }
3890        unit.codeobj
3891    }
3892
3893    fn load_prelude(&mut self) {
3894        // NOTE: Integers need to be used in IMPORT_NAME
3895        // but `Int` are called before importing it, so they need to be no_std mode
3896        let no_std = self.cfg.no_std;
3897        self.cfg.no_std = true;
3898        self.load_record_type();
3899        self.load_prelude_py();
3900        self.prelude_loaded = true;
3901        self.record_type_loaded = true;
3902        self.cfg.no_std = no_std;
3903    }
3904
3905    fn load_contains_op(&mut self) {
3906        let mod_name = Identifier::static_public("_erg_std_prelude");
3907        self.emit_global_import_items(
3908            mod_name,
3909            vec![(
3910                Identifier::static_public("contains_operator"),
3911                Some(Identifier::private("#contains_operator")),
3912            )],
3913        );
3914        self.contains_op_loaded = true;
3915    }
3916
3917    fn load_mutate_op(&mut self) {
3918        let mod_name = Identifier::static_public("_erg_std_prelude");
3919        self.emit_global_import_items(
3920            mod_name,
3921            vec![(
3922                Identifier::static_public("mutate_operator"),
3923                Some(Identifier::private("#mutate_operator")),
3924            )],
3925        );
3926        self.mutate_op_loaded = true;
3927    }
3928
3929    fn load_control(&mut self) {
3930        let mod_name = Identifier::static_public("_erg_control");
3931        self.emit_import_all_instr(mod_name);
3932        self.control_loaded = true;
3933    }
3934
3935    fn load_convertors(&mut self) {
3936        let mod_name = Identifier::static_public("_erg_convertors");
3937        self.emit_import_all_instr(mod_name);
3938        self.convertors_loaded = true;
3939    }
3940
3941    fn load_traits(&mut self) {
3942        let mod_name = Identifier::static_public("_erg_traits");
3943        self.emit_import_all_instr(mod_name);
3944        self.traits_loaded = true;
3945    }
3946
3947    fn load_operators(&mut self) {
3948        let mod_name = Identifier::static_public("operator");
3949        self.emit_import_all_instr(mod_name);
3950        self.operators_loaded = true;
3951    }
3952
3953    fn load_prelude_py(&mut self) {
3954        self.emit_global_import_items(
3955            Identifier::static_public("sys"),
3956            vec![(
3957                Identifier::static_public("path"),
3958                Some(Identifier::private("#path")),
3959            )],
3960        );
3961        self.emit_load_name_instr(Identifier::private("#path"));
3962        self.emit_load_method_instr(Identifier::static_public("append"), BoundAttr);
3963        self.emit_load_const(erg_core_path().to_str().unwrap());
3964        self.emit_call_instr(1, BoundAttr);
3965        self.stack_dec();
3966        self.emit_pop_top();
3967        let erg_std_mod = Identifier::static_public("_erg_std_prelude");
3968        // escaping
3969        self.emit_global_import_items(
3970            erg_std_mod.clone(),
3971            vec![(
3972                Identifier::static_public("contains_operator"),
3973                Some(Identifier::private("#contains_operator")),
3974            )],
3975        );
3976        self.emit_import_all_instr(erg_std_mod);
3977    }
3978
3979    fn load_record_type(&mut self) {
3980        self.emit_global_import_items(
3981            Identifier::static_public("collections"),
3982            vec![(
3983                Identifier::static_public("namedtuple"),
3984                Some(Identifier::private("#NamedTuple")),
3985            )],
3986        );
3987    }
3988
3989    fn load_abc(&mut self) {
3990        self.emit_global_import_items(
3991            Identifier::static_public("abc"),
3992            vec![
3993                (
3994                    Identifier::static_public("ABCMeta"),
3995                    Some(Identifier::private("#ABCMeta")),
3996                ),
3997                (
3998                    Identifier::static_public("abstractmethod"),
3999                    Some(Identifier::private("#abstractmethod")),
4000                ),
4001            ],
4002        );
4003    }
4004
4005    fn load_union(&mut self) {
4006        self.emit_global_import_items(
4007            Identifier::static_public("_erg_type"),
4008            vec![(
4009                Identifier::static_public("UnionType"),
4010                Some(Identifier::private("#UnionType")),
4011            )],
4012        );
4013    }
4014
4015    fn load_fake_generic(&mut self) {
4016        self.emit_global_import_items(
4017            Identifier::static_public("_erg_type"),
4018            vec![(
4019                Identifier::static_public("FakeGenericAlias"),
4020                Some(Identifier::private("#FakeGenericAlias")),
4021            )],
4022        );
4023    }
4024
4025    fn load_module_type(&mut self) {
4026        self.emit_global_import_items(
4027            Identifier::static_public("types"),
4028            vec![(
4029                Identifier::static_public("ModuleType"),
4030                Some(Identifier::private("#ModuleType")),
4031            )],
4032        );
4033    }
4034
4035    fn load_builtins(&mut self) {
4036        self.emit_global_import_items(
4037            Identifier::static_public("_erg_builtins"),
4038            vec![(
4039                Identifier::static_public("sum"),
4040                Some(Identifier::private("#sum")),
4041            )],
4042        );
4043    }
4044
4045    pub fn emit(&mut self, hir: HIR) -> CodeObj {
4046        log!(info "the code-generating process has started.{RESET}");
4047        self.unit_size += 1;
4048        self.units.push(PyCodeGenUnit::new(
4049            self.unit_size,
4050            self.py_version,
4051            vec![],
4052            0,
4053            Str::rc(self.cfg.input.enclosed_name()),
4054            "<module>",
4055            1,
4056            0,
4057        ));
4058        if self.py_version.minor >= Some(11) {
4059            self.write_instr(Opcode311::RESUME);
4060            self.write_arg(0);
4061        }
4062        if !self.cfg.no_std && !self.prelude_loaded {
4063            self.load_prelude();
4064        }
4065        for chunk in hir.module.into_iter() {
4066            self.emit_chunk(chunk);
4067            // TODO: discard
4068            if self.stack_len() == 1 {
4069                self.emit_pop_top();
4070            }
4071        }
4072        self.cancel_if_pop_top(); // 最後の値は戻り値として取っておく
4073        if self.input().is_repl() {
4074            if self.stack_len() == 1 {
4075                self.emit_print_expr();
4076            }
4077            self.stack_dec_n(self.stack_len() as usize);
4078        }
4079        if self.stack_len() == 0 {
4080            self.emit_load_const(ValueObj::None);
4081        } else if self.stack_len() > 1 {
4082            let block_id = self.cur_block().id;
4083            let stack_len = self.stack_len();
4084            CompileError::stack_bug(
4085                self.input().clone(),
4086                Location::Unknown,
4087                stack_len,
4088                block_id,
4089                fn_name_full!(),
4090            )
4091            .write_to_stderr();
4092            self.crash("error in emit: invalid stack size");
4093        }
4094        self.write_instr(RETURN_VALUE);
4095        self.write_arg(0);
4096        // flagging
4097        if !self.cur_block_codeobj().varnames.is_empty() {
4098            self.mut_cur_block_codeobj().flags += CodeObjFlags::NewLocals as u32;
4099        }
4100        // end of flagging
4101        let unit = self.units.pop().unwrap();
4102        if !self.units.is_empty() {
4103            let ld = unit.prev_lineno - self.cur_block().prev_lineno;
4104            if ld != 0 {
4105                if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() {
4106                    *l += u8::try_from(ld).unwrap();
4107                }
4108                self.mut_cur_block().prev_lineno += ld;
4109            }
4110        }
4111        log!(info "the code-generating process has completed.{RESET}");
4112        unit.codeobj
4113    }
4114}