diff --git a/crates/oxide_emit/src/emit.rs b/crates/oxide_emit/src/emit.rs index 8952973..a4c5432 100644 --- a/crates/oxide_emit/src/emit.rs +++ b/crates/oxide_emit/src/emit.rs @@ -13,6 +13,18 @@ use oxide_ir::inst::Inst; use oxide_ir::operand::{LabelId, Operand}; use oxide_ir::IRFunction; +/// 是否为匿名函数定义(剥括号):函数/箭头/class 表达式。 +pub fn is_anonymous_function_definition(expr: &oxide_parser::Expression) -> bool { + match expr { + oxide_parser::Expression::ArrowFunctionExpression(_) + | oxide_parser::Expression::FunctionExpression(_) + | oxide_parser::Expression::ClassExpression(_) => true, + oxide_parser::Expression::ParenthesizedExpression(p) => is_anonymous_function_definition(&p.expression), + _ => false, + } +} + + use crate::emit_ctx::{LabelCtx, ScopeCtx}; use crate::symbol_table::{Binding, ScopeKind, SymbolTable}; diff --git a/crates/oxide_emit/src/expr/assignment.rs b/crates/oxide_emit/src/expr/assignment.rs index 4435f16..424cf87 100644 --- a/crates/oxide_emit/src/expr/assignment.rs +++ b/crates/oxide_emit/src/expr/assignment.rs @@ -194,12 +194,7 @@ impl Emitter { let val_reg = self.emit_expression(&assign.right, ctx)?; let name = id_ref.name.as_str(); // 赋值函数/箭头/class 表达式 → 推断 name。 - if matches!( - &assign.right, - oxide_parser::Expression::ArrowFunctionExpression(_) - | oxide_parser::Expression::FunctionExpression(_) - | oxide_parser::Expression::ClassExpression(_) - ) { + if crate::is_anonymous_function_definition(&assign.right) { if let Some(sub_mod) = ctx.nested.last_mut() { if sub_mod.function_name.is_none() { sub_mod.function_name = Some(name.to_string()); diff --git a/crates/oxide_emit/src/expr/object/object_literal.rs b/crates/oxide_emit/src/expr/object/object_literal.rs index 677162a..16f691a 100644 --- a/crates/oxide_emit/src/expr/object/object_literal.rs +++ b/crates/oxide_emit/src/expr/object/object_literal.rs @@ -5,7 +5,7 @@ use oxide_bytecode::module::Constant; use oxide_bytecode::opcode::OpCode; use oxide_ir::inst::Inst; use oxide_ir::operand::Operand; -use oxide_parser::{Expression, ObjectPropertyKind, PropertyKind}; +use oxide_parser::{ObjectPropertyKind, PropertyKind}; impl Emitter { pub(crate) fn emit_object_expression( @@ -56,12 +56,7 @@ impl Emitter { reg }; let val_reg = self.emit_expression(&p.value, ctx)?; - if matches!( - &p.value, - Expression::ArrowFunctionExpression(_) - | Expression::FunctionExpression(_) - | Expression::ClassExpression(_) - ) { + if crate::is_anonymous_function_definition(&p.value) { if let Some(sub_mod) = ctx.nested.last_mut() { sub_mod.function_name = Some(prop_name.to_string()); } @@ -84,3 +79,4 @@ impl Emitter { Ok(obj_reg) } } + diff --git a/crates/oxide_emit/src/lib.rs b/crates/oxide_emit/src/lib.rs index 5006c24..7ca5fb2 100644 --- a/crates/oxide_emit/src/lib.rs +++ b/crates/oxide_emit/src/lib.rs @@ -15,7 +15,7 @@ pub mod shared; pub mod stmt; pub mod symbol_table; -pub use emit::{is_int_literal, is_side_effect_free}; +pub use emit::{is_anonymous_function_definition, is_int_literal, is_side_effect_free}; pub use emit::{CompileCtx, Emitter, FunctionBodyContext, LabelScope, ParamSpec}; pub use oxide_bytecode::module::Constant; pub use oxide_parser::{AssignmentOperator, BinaryOperator, UnaryOperator}; diff --git a/crates/oxide_emit/src/shared/binding.rs b/crates/oxide_emit/src/shared/binding.rs index 2c62cc9..45d967e 100644 --- a/crates/oxide_emit/src/shared/binding.rs +++ b/crates/oxide_emit/src/shared/binding.rs @@ -30,12 +30,7 @@ impl Emitter { let default_reg = self.emit_expression(default_expr, ctx)?; // 默认值表达式是匿名函数/箭头/class 时按绑定名推断 name(SetFunctionName)。 if let Some(name) = name { - if matches!( - default_expr, - Expression::ArrowFunctionExpression(_) - | Expression::FunctionExpression(_) - | Expression::ClassExpression(_) - ) { + if crate::is_anonymous_function_definition(default_expr) { if let Some(sub_mod) = ctx.nested.last_mut() { if sub_mod.function_name.is_none() { sub_mod.function_name = Some(name.to_string()); diff --git a/crates/oxide_emit/src/stmt/declaration/var.rs b/crates/oxide_emit/src/stmt/declaration/var.rs index 272b22a..94427c0 100644 --- a/crates/oxide_emit/src/stmt/declaration/var.rs +++ b/crates/oxide_emit/src/stmt/declaration/var.rs @@ -5,7 +5,7 @@ use oxide_bytecode::module::Constant; use oxide_bytecode::opcode::OpCode; use oxide_ir::inst::Inst; use oxide_ir::operand::Operand; -use oxide_parser::{BindingPattern, Expression, Statement, VariableDeclarationKind}; +use oxide_parser::{BindingPattern, Statement, VariableDeclarationKind}; impl Emitter { pub(crate) fn emit_variable_declaration_statement( @@ -24,12 +24,7 @@ impl Emitter { let val_reg = self.emit_expression(init, ctx)?; self.emit_binding_pattern(&d.id, val_reg, decl.kind, is_const, ctx)?; if let BindingPattern::BindingIdentifier(bi) = &d.id { - if matches!( - *init, - Expression::ArrowFunctionExpression(_) - | Expression::FunctionExpression(_) - | Expression::ClassExpression(_) - ) { + if crate::is_anonymous_function_definition(init) { if let Some(sub_mod) = ctx.nested.last_mut() { if sub_mod.function_name.is_none() { sub_mod.function_name = Some(bi.name.to_string()); @@ -72,3 +67,4 @@ impl Emitter { Ok(r) } } +