mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 10:41:11 +08:00
33 lines
1.3 KiB
Rust
33 lines
1.3 KiB
Rust
//! 类声明语句 emit:`emit_class_declaration_statement` 声明类名并初始化类对象。
|
||
|
||
use crate::{CompileCtx, Emitter};
|
||
use oxide_ir::inst::Inst;
|
||
use oxide_ir::operand::Operand;
|
||
use oxide_bytecode::opcode::OpCode;
|
||
use oxide_parser::{Statement, VariableDeclarationKind};
|
||
|
||
impl Emitter {
|
||
pub(crate) fn emit_class_declaration_statement(
|
||
&self, stmt: &Statement, ctx: &mut CompileCtx,
|
||
) -> Result<Option<u32>, String> {
|
||
let Statement::ClassDeclaration(class) = stmt else {
|
||
return Err("ClassDeclaration without name".into());
|
||
};
|
||
let name = class
|
||
.id
|
||
.as_ref()
|
||
.map(|id| id.name.to_string())
|
||
.ok_or_else(|| "ClassDeclaration without name".to_string())?;
|
||
let var_reg = ctx.alloc_reg();
|
||
ctx.declare(&name, var_reg, VariableDeclarationKind::Let, false)?;
|
||
ctx.init_var(&name);
|
||
let ctor_reg = self.emit_class(class, ctx)?;
|
||
if let Some(&cell_idx) = ctx.captured_bindings.get(&name) {
|
||
ctx.inst(Inst::new(OpCode::MAKE_CELL, Operand::Reg(var_reg), Operand::Imm(cell_idx as u16), Operand::None));
|
||
} else {
|
||
ctx.inst(Inst::new(OpCode::STORE_VAR, Operand::Reg(var_reg), Operand::Reg(ctor_reg), Operand::None));
|
||
}
|
||
Ok(None)
|
||
}
|
||
}
|