refactor(compiler): 拆分 oxide_emit 为独立 emit pass crate(依赖倒置)
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
use crate::{CompileCtx, Emitter, ParamSpec};
|
||||
use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
use oxide_parser::{Class, Expression, Statement};
|
||||
|
||||
impl Emitter {
|
||||
fn emit_arrow_function_expression(
|
||||
&self, arrow: &oxide_parser::ArrowFunctionExpression, ctx: &mut CompileCtx,
|
||||
) -> Result<u8, String> {
|
||||
// Rest params not yet supported
|
||||
if let Some(_rest) = &arrow.params.rest {
|
||||
return Err("rest params in arrow functions not yet supported".into());
|
||||
}
|
||||
|
||||
// Extract param names (same pattern as FunctionExpression)
|
||||
let mut param_names = Vec::new();
|
||||
for (idx, param) in arrow.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
||||
}
|
||||
pattern => {
|
||||
param_names.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expression body: pass body statements directly with is_expression_body=true.
|
||||
// Statement body: pass body statements with is_expression_body=false.
|
||||
let body_stmts = &arrow.body.statements;
|
||||
let is_expr_body = arrow.expression;
|
||||
|
||||
let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, is_expr_body, true)?;
|
||||
sub_module.is_arrow = true;
|
||||
|
||||
ctx.nested.push(sub_module);
|
||||
// 1-indexed: 0 = no sub_module (sentinel)
|
||||
let sub_idx = ctx.nested.len() as u16;
|
||||
|
||||
let r = ctx.alloc_reg();
|
||||
ctx.inst(Inst::create_closure(Operand::Reg(r as u32), sub_idx));
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn emit_function_expression(&self, fe: &oxide_parser::Function, ctx: &mut CompileCtx) -> Result<u8, String> {
|
||||
// FunctionExpression: compile body, emit LOAD_CONST(BytecodeFunc)
|
||||
let mut param_names = Vec::new();
|
||||
for (idx, param) in fe.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
||||
}
|
||||
pattern => {
|
||||
param_names.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
|
||||
|
||||
let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, false, false)?;
|
||||
if let Some(id) = &fe.id {
|
||||
sub_module.function_name = Some(id.name.to_string());
|
||||
}
|
||||
ctx.nested.push(sub_module);
|
||||
// 1-indexed: 0 = no sub_module (sentinel)
|
||||
let sub_idx = ctx.nested.len() as u16;
|
||||
|
||||
let r = ctx.alloc_reg();
|
||||
ctx.inst(Inst::create_closure(Operand::Reg(r as u32), sub_idx));
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn emit_class_expression(&self, class: &Class, ctx: &mut CompileCtx) -> Result<u8, String> {
|
||||
self.emit_class(class, ctx)
|
||||
}
|
||||
|
||||
fn emit_new_expression(&self, ne: &oxide_parser::NewExpression, ctx: &mut CompileCtx) -> Result<u8, String> {
|
||||
let constructor_reg = self.emit_expression(&ne.callee, ctx)?;
|
||||
let mut arg_regs = Vec::new();
|
||||
for arg in &ne.arguments {
|
||||
if let Some(expr) = arg.as_expression() {
|
||||
arg_regs.push(self.emit_expression(expr, ctx)?);
|
||||
}
|
||||
}
|
||||
let first_arg_reg = if arg_regs.is_empty() { 0u8 } else { arg_regs[0] };
|
||||
let r = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new_expression(
|
||||
Operand::Reg(r as u32),
|
||||
Operand::Reg(constructor_reg as u32),
|
||||
Operand::Reg(first_arg_reg as u32),
|
||||
arg_regs.len() as u8,
|
||||
));
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
pub(crate) fn emit_function_domain(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result<u8, String> {
|
||||
match expr {
|
||||
Expression::ArrowFunctionExpression(arrow) => self.emit_arrow_function_expression(arrow, ctx),
|
||||
Expression::FunctionExpression(fe) => self.emit_function_expression(fe, ctx),
|
||||
Expression::ClassExpression(class) => self.emit_class_expression(class, ctx),
|
||||
Expression::NewExpression(ne) => self.emit_new_expression(ne, ctx),
|
||||
_ => self.emit_unsupported_expression(expr, ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user