mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Impl subroutine type with default parameters
This commit is contained in:
parent
eadfe9794a
commit
4bb367f258
3 changed files with 55 additions and 14 deletions
|
@ -767,15 +767,24 @@ impl Context {
|
|||
&self,
|
||||
p: &ParamTySpec,
|
||||
opt_decl_t: Option<&ParamTy>,
|
||||
default_t: Option<&TypeSpec>,
|
||||
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||
mode: RegistrationMode,
|
||||
) -> TyCheckResult<ParamTy> {
|
||||
let t = self.instantiate_typespec(&p.ty, opt_decl_t, tmp_tv_ctx, mode)?;
|
||||
if let Some(default_t) = default_t {
|
||||
Ok(ParamTy::kw_default(
|
||||
p.name.as_ref().unwrap().inspect().to_owned(),
|
||||
t,
|
||||
self.instantiate_typespec(default_t, opt_decl_t, tmp_tv_ctx, mode)?,
|
||||
))
|
||||
} else {
|
||||
Ok(ParamTy::pos(
|
||||
p.name.as_ref().map(|t| t.inspect().to_owned()),
|
||||
t,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn instantiate_typespec(
|
||||
&self,
|
||||
|
@ -854,15 +863,23 @@ impl Context {
|
|||
}
|
||||
TypeSpec::Subr(subr) => {
|
||||
let non_defaults = try_map_mut(subr.non_defaults.iter(), |p| {
|
||||
self.instantiate_func_param_spec(p, opt_decl_t, tmp_tv_ctx, mode)
|
||||
self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode)
|
||||
})?;
|
||||
let var_args = subr
|
||||
.var_args
|
||||
.as_ref()
|
||||
.map(|p| self.instantiate_func_param_spec(p, opt_decl_t, tmp_tv_ctx, mode))
|
||||
.map(|p| {
|
||||
self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode)
|
||||
})
|
||||
.transpose()?;
|
||||
let defaults = try_map_mut(subr.defaults.iter(), |p| {
|
||||
self.instantiate_func_param_spec(p, opt_decl_t, tmp_tv_ctx, mode)
|
||||
self.instantiate_func_param_spec(
|
||||
&p.param,
|
||||
opt_decl_t,
|
||||
Some(&p.default),
|
||||
tmp_tv_ctx,
|
||||
mode,
|
||||
)
|
||||
})?
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
|
|
@ -1591,13 +1591,31 @@ impl ParamTySpec {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct DefaultParamTySpec {
|
||||
pub param: ParamTySpec,
|
||||
pub default: TypeSpec,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefaultParamTySpec {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{} := {}", self.param, self.default)
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultParamTySpec {
|
||||
pub const fn new(param: ParamTySpec, default: TypeSpec) -> Self {
|
||||
Self { param, default }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct SubrTypeSpec {
|
||||
pub bounds: TypeBoundSpecs,
|
||||
pub lparen: Option<Token>,
|
||||
pub non_defaults: Vec<ParamTySpec>,
|
||||
pub var_args: Option<Box<ParamTySpec>>,
|
||||
pub defaults: Vec<ParamTySpec>,
|
||||
pub defaults: Vec<DefaultParamTySpec>,
|
||||
pub arrow: Token,
|
||||
pub return_t: Box<TypeSpec>,
|
||||
}
|
||||
|
@ -1638,7 +1656,7 @@ impl SubrTypeSpec {
|
|||
lparen: Option<Token>,
|
||||
non_defaults: Vec<ParamTySpec>,
|
||||
var_args: Option<ParamTySpec>,
|
||||
defaults: Vec<ParamTySpec>,
|
||||
defaults: Vec<DefaultParamTySpec>,
|
||||
arrow: Token,
|
||||
return_t: TypeSpec,
|
||||
) -> Self {
|
||||
|
|
|
@ -2813,12 +2813,18 @@ impl Parser {
|
|||
for param in lambda.sig.params.defaults.into_iter() {
|
||||
let param = match (param.sig.pat, param.sig.t_spec) {
|
||||
(ParamPattern::VarName(name), Some(t_spec_with_op)) => {
|
||||
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
|
||||
let param_spec =
|
||||
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec);
|
||||
let default_spec = Self::expr_to_type_spec(param.default_val)?;
|
||||
DefaultParamTySpec::new(param_spec, default_spec)
|
||||
}
|
||||
(ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy(
|
||||
PreDeclTypeSpec::Simple(SimpleTypeSpec::new(name, ConstArgs::empty())),
|
||||
)),
|
||||
_ => todo!(),
|
||||
(ParamPattern::VarName(name), None) => {
|
||||
let default_spec = Self::expr_to_type_spec(param.default_val)?;
|
||||
let param_spec =
|
||||
ParamTySpec::new(Some(name.into_token()), default_spec.clone());
|
||||
DefaultParamTySpec::new(param_spec, default_spec)
|
||||
}
|
||||
(l, r) => todo!("{:?} {:?}", l, r),
|
||||
};
|
||||
defaults.push(param);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue