mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
feat: 实现默认参数(形参 initializer 与解构默认值)
This commit is contained in:
@@ -174,19 +174,23 @@ pub enum FunctionBodyContext {
|
|||||||
ClassElement,
|
ClassElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 参数规格:普通形参为标识符,解构形参用合成名 + 原始 pattern。
|
/// 参数规格:普通形参为标识符(可带默认值 initializer),解构形参用合成名 + 原始 pattern。
|
||||||
pub enum ParamSpec<'a> {
|
pub enum ParamSpec<'a> {
|
||||||
Identifier(String),
|
Identifier {
|
||||||
|
name: String,
|
||||||
|
initializer: Option<&'a Expression<'a>>,
|
||||||
|
},
|
||||||
Pattern {
|
Pattern {
|
||||||
synthetic_name: String,
|
synthetic_name: String,
|
||||||
pattern: &'a oxide_parser::BindingPattern<'a>,
|
pattern: &'a oxide_parser::BindingPattern<'a>,
|
||||||
|
initializer: Option<&'a Expression<'a>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParamSpec<'_> {
|
impl ParamSpec<'_> {
|
||||||
pub(crate) fn register_name(&self) -> &str {
|
pub(crate) fn register_name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Self::Identifier(name) => name,
|
Self::Identifier { name, .. } => name,
|
||||||
Self::Pattern { synthetic_name, .. } => synthetic_name,
|
Self::Pattern { synthetic_name, .. } => synthetic_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,12 +533,16 @@ impl Emitter {
|
|||||||
for (idx, param) in function.params.items.iter().enumerate() {
|
for (idx, param) in function.params.items.iter().enumerate() {
|
||||||
match ¶m.pattern {
|
match ¶m.pattern {
|
||||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||||
param_specs.push(ParamSpec::Identifier(bi.name.to_string()));
|
param_specs.push(ParamSpec::Identifier {
|
||||||
|
name: bi.name.to_string(),
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pattern => {
|
pattern => {
|
||||||
param_specs.push(ParamSpec::Pattern {
|
param_specs.push(ParamSpec::Pattern {
|
||||||
synthetic_name: format!("@@param_{idx}"),
|
synthetic_name: format!("@@param_{idx}"),
|
||||||
pattern,
|
pattern,
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -729,9 +737,23 @@ impl Emitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for spec in param_specs {
|
for spec in param_specs {
|
||||||
if let ParamSpec::Pattern { synthetic_name, pattern } = spec {
|
match spec {
|
||||||
let src_reg = ctx.lookup(synthetic_name)?;
|
ParamSpec::Pattern { synthetic_name, pattern, initializer } => {
|
||||||
self.emit_binding_pattern(pattern, src_reg, VariableDeclarationKind::Var, false, ctx)?;
|
let src_reg = ctx.lookup(synthetic_name)?;
|
||||||
|
let src_reg = if let Some(init) = initializer {
|
||||||
|
self.emit_default_if_undefined(src_reg, init, ctx)?
|
||||||
|
} else {
|
||||||
|
src_reg
|
||||||
|
};
|
||||||
|
self.emit_binding_pattern(pattern, src_reg, VariableDeclarationKind::Var, false, ctx)?;
|
||||||
|
}
|
||||||
|
ParamSpec::Identifier { name, initializer } => {
|
||||||
|
if let Some(init) = initializer {
|
||||||
|
// 默认参数:实参为 undefined 时用默认值。
|
||||||
|
let reg = ctx.lookup(name)?;
|
||||||
|
self.emit_default_if_undefined(reg, init, ctx)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,3 +932,4 @@ impl Default for Emitter {
|
|||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,16 @@ impl Emitter {
|
|||||||
for (idx, param) in arrow.params.items.iter().enumerate() {
|
for (idx, param) in arrow.params.items.iter().enumerate() {
|
||||||
match ¶m.pattern {
|
match ¶m.pattern {
|
||||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
param_names.push(ParamSpec::Identifier {
|
||||||
|
name: bi.name.to_string(),
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pattern => {
|
pattern => {
|
||||||
param_names.push(ParamSpec::Pattern {
|
param_names.push(ParamSpec::Pattern {
|
||||||
synthetic_name: format!("@@param_{idx}"),
|
synthetic_name: format!("@@param_{idx}"),
|
||||||
pattern,
|
pattern,
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,12 +58,16 @@ impl Emitter {
|
|||||||
for (idx, param) in fe.params.items.iter().enumerate() {
|
for (idx, param) in fe.params.items.iter().enumerate() {
|
||||||
match ¶m.pattern {
|
match ¶m.pattern {
|
||||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
param_names.push(ParamSpec::Identifier {
|
||||||
|
name: bi.name.to_string(),
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
pattern => {
|
pattern => {
|
||||||
param_names.push(ParamSpec::Pattern {
|
param_names.push(ParamSpec::Pattern {
|
||||||
synthetic_name: format!("@@param_{idx}"),
|
synthetic_name: format!("@@param_{idx}"),
|
||||||
pattern,
|
pattern,
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,3 +121,4 @@ impl Emitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use oxide_parser::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl Emitter {
|
impl Emitter {
|
||||||
fn emit_default_if_undefined(
|
pub(crate) fn emit_default_if_undefined(
|
||||||
&self, val_reg: u32, default_expr: &Expression, ctx: &mut CompileCtx,
|
&self, val_reg: u32, default_expr: &Expression, ctx: &mut CompileCtx,
|
||||||
) -> Result<u32, String> {
|
) -> Result<u32, String> {
|
||||||
let undef_reg = self.emit_undefined(ctx);
|
let undef_reg = self.emit_undefined(ctx);
|
||||||
|
|||||||
@@ -22,12 +22,16 @@ impl Emitter {
|
|||||||
for (idx, param) in fd.params.items.iter().enumerate() {
|
for (idx, param) in fd.params.items.iter().enumerate() {
|
||||||
match ¶m.pattern {
|
match ¶m.pattern {
|
||||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()))
|
param_names.push(ParamSpec::Identifier {
|
||||||
|
name: bi.name.to_string(),
|
||||||
|
initializer: param.initializer.as_deref(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
pattern => param_names.push(ParamSpec::Pattern {
|
pattern => param_names.push(ParamSpec::Pattern {
|
||||||
synthetic_name: format!("@@param_{idx}"),
|
synthetic_name: format!("@@param_{idx}"),
|
||||||
pattern,
|
pattern,
|
||||||
}),
|
initializer: param.initializer.as_deref(),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
|
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
|
||||||
@@ -50,3 +54,4 @@ impl Emitter {
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user