mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Implement default parameter
This commit is contained in:
parent
af65a48355
commit
d0456ec1ee
10 changed files with 375 additions and 171 deletions
|
@ -4,6 +4,7 @@
|
|||
use std::fmt;
|
||||
use std::process;
|
||||
|
||||
use crate::ty::codeobj::MakeFunctionFlags;
|
||||
use crate::ty::codeobj::{CodeObj, CodeObjFlags};
|
||||
use erg_common::astr::AtomicStr;
|
||||
use erg_common::cache::CacheSet;
|
||||
|
@ -21,7 +22,7 @@ use erg_parser::ast::DefId;
|
|||
use erg_parser::ast::DefKind;
|
||||
use Opcode::*;
|
||||
|
||||
use erg_parser::ast::{ParamPattern, ParamSignature, Params, VarName};
|
||||
use erg_parser::ast::{NonDefaultParamSignature, ParamPattern, VarName};
|
||||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
use crate::compile::{AccessKind, Name, StoreLoadKind};
|
||||
|
@ -29,7 +30,7 @@ use crate::context::eval::type_from_token_kind;
|
|||
use crate::error::CompileError;
|
||||
use crate::hir::{
|
||||
Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, Def, DefBody, Expr,
|
||||
Identifier, Lambda, Literal, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
||||
Identifier, Lambda, Literal, Params, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
||||
VarSignature, HIR,
|
||||
};
|
||||
use crate::ty::free::fresh_varname;
|
||||
|
@ -858,6 +859,18 @@ impl CodeGenerator {
|
|||
log!(info "entered {} ({lambda})", fn_name!());
|
||||
let mut make_function_flag = 0u8;
|
||||
let params = self.gen_param_names(&lambda.params);
|
||||
if !lambda.params.defaults.is_empty() {
|
||||
let defaults_len = lambda.params.defaults.len();
|
||||
lambda
|
||||
.params
|
||||
.defaults
|
||||
.into_iter()
|
||||
.for_each(|default| self.emit_expr(default.default_val));
|
||||
self.write_instr(BUILD_TUPLE);
|
||||
self.write_arg(defaults_len as u8);
|
||||
self.stack_dec_n(defaults_len - 1);
|
||||
make_function_flag += MakeFunctionFlags::Defaults as u8;
|
||||
}
|
||||
let code = self.emit_block(lambda.body, Some("<lambda>".into()), params);
|
||||
if !self.cur_block_codeobj().cellvars.is_empty() {
|
||||
let cellvars_len = self.cur_block_codeobj().cellvars.len() as u8;
|
||||
|
@ -867,7 +880,7 @@ impl CodeGenerator {
|
|||
}
|
||||
self.write_instr(BUILD_TUPLE);
|
||||
self.write_arg(cellvars_len);
|
||||
make_function_flag += 8;
|
||||
make_function_flag += MakeFunctionFlags::Closure as u8;
|
||||
}
|
||||
self.emit_load_const(code);
|
||||
self.emit_load_const("<lambda>");
|
||||
|
@ -875,6 +888,9 @@ impl CodeGenerator {
|
|||
self.write_arg(make_function_flag);
|
||||
// stack_dec: <lambda code obj> + <name "<lambda>"> -> <function>
|
||||
self.stack_dec();
|
||||
if make_function_flag & MakeFunctionFlags::Defaults as u8 != 0 {
|
||||
self.stack_dec();
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_unaryop(&mut self, unary: UnaryOp) {
|
||||
|
@ -1671,9 +1687,9 @@ impl CodeGenerator {
|
|||
let ident = Identifier::public_with_line(Token::dummy(), Str::ever("__init__"), line);
|
||||
let param_name = fresh_varname();
|
||||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
||||
let param = ParamSignature::new(ParamPattern::VarName(param), None, None);
|
||||
let param = NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||
let self_param = VarName::from_str_and_line(Str::ever("self"), line);
|
||||
let self_param = ParamSignature::new(ParamPattern::VarName(self_param), None, None);
|
||||
let self_param = NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None);
|
||||
let params = Params::new(vec![self_param, param], None, vec![], None);
|
||||
let subr_sig = SubrSignature::new(ident, params, __new__.clone());
|
||||
let mut attrs = vec![];
|
||||
|
@ -1729,7 +1745,7 @@ impl CodeGenerator {
|
|||
let ident = Identifier::public_with_line(Token::dummy(), Str::ever("new"), line);
|
||||
let param_name = fresh_varname();
|
||||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
||||
let param = ParamSignature::new(ParamPattern::VarName(param), None, None);
|
||||
let param = NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||
let sig = SubrSignature::new(ident, Params::new(vec![param], None, vec![], None), __new__);
|
||||
let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line(
|
||||
Str::from(param_name),
|
||||
|
|
|
@ -512,20 +512,32 @@ impl Context {
|
|||
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
||||
let mut non_default_params = Vec::with_capacity(lambda.sig.params.non_defaults.len());
|
||||
for sig in lambda.sig.params.non_defaults.iter() {
|
||||
let pt =
|
||||
self.instantiate_param_ty(sig, None, Some(&tv_ctx), RegistrationMode::Normal)?;
|
||||
let pt = self.instantiate_param_ty(
|
||||
sig,
|
||||
None,
|
||||
None,
|
||||
Some(&tv_ctx),
|
||||
RegistrationMode::Normal,
|
||||
)?;
|
||||
non_default_params.push(pt);
|
||||
}
|
||||
let var_params = if let Some(p) = lambda.sig.params.var_args.as_ref() {
|
||||
let pt = self.instantiate_param_ty(p, None, Some(&tv_ctx), RegistrationMode::Normal)?;
|
||||
let pt =
|
||||
self.instantiate_param_ty(p, None, None, Some(&tv_ctx), RegistrationMode::Normal)?;
|
||||
Some(pt)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut default_params = Vec::with_capacity(lambda.sig.params.defaults.len());
|
||||
for sig in lambda.sig.params.defaults.iter() {
|
||||
let pt =
|
||||
self.instantiate_param_ty(sig, None, Some(&tv_ctx), RegistrationMode::Normal)?;
|
||||
let expr = self.eval_const_expr(&sig.default_val)?;
|
||||
let pt = self.instantiate_param_ty(
|
||||
&sig.sig,
|
||||
Some(expr.t()),
|
||||
None,
|
||||
Some(&tv_ctx),
|
||||
RegistrationMode::Normal,
|
||||
)?;
|
||||
default_params.push(pt);
|
||||
}
|
||||
// HACK: should avoid cloning
|
||||
|
|
|
@ -13,8 +13,8 @@ use erg_common::Str;
|
|||
use erg_common::{assume_unreachable, enum_unwrap, set, try_map_mut};
|
||||
|
||||
use ast::{
|
||||
ParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec, TypeBoundSpecs,
|
||||
TypeSpec,
|
||||
NonDefaultParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec,
|
||||
TypeBoundSpecs, TypeSpec,
|
||||
};
|
||||
use erg_parser::ast;
|
||||
use erg_parser::token::TokenKind;
|
||||
|
@ -507,6 +507,7 @@ impl Context {
|
|||
pub(crate) fn instantiate_sub_sig_t(
|
||||
&self,
|
||||
sig: &ast::SubrSignature,
|
||||
default_ts: Vec<Type>,
|
||||
mode: RegistrationMode,
|
||||
) -> TyCheckResult<Type> {
|
||||
// -> Result<Type, (Type, TyCheckErrors)> {
|
||||
|
@ -521,22 +522,34 @@ impl Context {
|
|||
let opt_decl_t = opt_decl_sig_t
|
||||
.as_ref()
|
||||
.and_then(|subr| subr.non_default_params.get(n));
|
||||
non_defaults.push(self.instantiate_param_ty(p, opt_decl_t, Some(&tv_ctx), mode)?);
|
||||
non_defaults.push(self.instantiate_param_ty(
|
||||
p,
|
||||
None,
|
||||
opt_decl_t,
|
||||
Some(&tv_ctx),
|
||||
mode,
|
||||
)?);
|
||||
}
|
||||
let var_args = if let Some(var_args) = sig.params.var_args.as_ref() {
|
||||
let opt_decl_t = opt_decl_sig_t
|
||||
.as_ref()
|
||||
.and_then(|subr| subr.var_params.as_ref().map(|v| v.as_ref()));
|
||||
Some(self.instantiate_param_ty(var_args, opt_decl_t, Some(&tv_ctx), mode)?)
|
||||
Some(self.instantiate_param_ty(var_args, None, opt_decl_t, Some(&tv_ctx), mode)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut defaults = vec![];
|
||||
for (n, p) in sig.params.defaults.iter().enumerate() {
|
||||
for ((n, p), default_t) in sig.params.defaults.iter().enumerate().zip(default_ts) {
|
||||
let opt_decl_t = opt_decl_sig_t
|
||||
.as_ref()
|
||||
.and_then(|subr| subr.default_params.get(n));
|
||||
defaults.push(self.instantiate_param_ty(p, opt_decl_t, Some(&tv_ctx), mode)?);
|
||||
defaults.push(self.instantiate_param_ty(
|
||||
&p.sig,
|
||||
Some(default_t),
|
||||
opt_decl_t,
|
||||
Some(&tv_ctx),
|
||||
mode,
|
||||
)?);
|
||||
}
|
||||
let spec_return_t = if let Some(s) = sig.return_t_spec.as_ref() {
|
||||
let opt_decl_t = opt_decl_sig_t
|
||||
|
@ -562,7 +575,7 @@ impl Context {
|
|||
/// spec_t == Noneかつリテラル推論が不可能なら型変数を発行する
|
||||
pub(crate) fn instantiate_param_sig_t(
|
||||
&self,
|
||||
sig: &ParamSignature,
|
||||
sig: &NonDefaultParamSignature,
|
||||
opt_decl_t: Option<&ParamTy>,
|
||||
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||
mode: RegistrationMode,
|
||||
|
@ -599,21 +612,15 @@ impl Context {
|
|||
|
||||
pub(crate) fn instantiate_param_ty(
|
||||
&self,
|
||||
sig: &ParamSignature,
|
||||
sig: &NonDefaultParamSignature,
|
||||
opt_default_t: Option<Type>,
|
||||
opt_decl_t: Option<&ParamTy>,
|
||||
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||
mode: RegistrationMode,
|
||||
) -> TyCheckResult<ParamTy> {
|
||||
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_ctx, mode)?;
|
||||
match (sig.inspect(), &sig.opt_default_val) {
|
||||
(Some(name), Some(default)) => {
|
||||
let default = self.instantiate_const_expr(default)?;
|
||||
Ok(ParamTy::kw_default(
|
||||
name.clone(),
|
||||
t,
|
||||
self.get_tp_t(&default)?,
|
||||
))
|
||||
}
|
||||
match (sig.inspect(), opt_default_t) {
|
||||
(Some(name), Some(default_t)) => Ok(ParamTy::kw_default(name.clone(), t, default_t)),
|
||||
(Some(name), None) => Ok(ParamTy::kw(name.clone(), t)),
|
||||
(None, None) => Ok(ParamTy::anonymous(t)),
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -13,9 +13,9 @@ use erg_common::Str;
|
|||
use erg_common::{enum_unwrap, get_hash, log, option_enum_unwrap, set};
|
||||
|
||||
use ast::{DefId, Identifier, VarName};
|
||||
use erg_parser::ast;
|
||||
use erg_parser::ast::{self, Decorator};
|
||||
|
||||
use crate::ty::constructors::{func, func1, proc, ref_, ref_mut, v_enum};
|
||||
use crate::ty::constructors::{free_var, func, func1, proc, ref_, ref_mut, v_enum};
|
||||
use crate::ty::free::{Constraint, Cyclicity, FreeKind};
|
||||
use crate::ty::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
||||
use crate::ty::{HasType, ParamTy, SubrType, Type};
|
||||
|
@ -115,19 +115,23 @@ impl Context {
|
|||
_ => None,
|
||||
})
|
||||
.collect::<Set<_>>();
|
||||
let t = self.instantiate_sub_sig_t(sig, PreRegister).map_err(|e| {
|
||||
let vi = VarInfo::new(
|
||||
Type::Failure,
|
||||
muty,
|
||||
vis,
|
||||
kind.clone(),
|
||||
Some(comptime_decos.clone()),
|
||||
self.impl_of(),
|
||||
None,
|
||||
);
|
||||
self.decls.insert(sig.ident.name.clone(), vi);
|
||||
e
|
||||
})?;
|
||||
let default_ts =
|
||||
vec![free_var(self.level, Constraint::new_type_of(Type::Type)); sig.params.len()];
|
||||
let t = self
|
||||
.instantiate_sub_sig_t(sig, default_ts, PreRegister)
|
||||
.map_err(|e| {
|
||||
let vi = VarInfo::new(
|
||||
Type::Failure,
|
||||
muty,
|
||||
vis,
|
||||
kind.clone(),
|
||||
Some(comptime_decos.clone()),
|
||||
self.impl_of(),
|
||||
None,
|
||||
);
|
||||
self.decls.insert(sig.ident.name.clone(), vi);
|
||||
e
|
||||
})?;
|
||||
let vi = VarInfo::new(
|
||||
t,
|
||||
muty,
|
||||
|
@ -190,7 +194,8 @@ impl Context {
|
|||
/// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
|
||||
fn assign_param(
|
||||
&mut self,
|
||||
sig: &ast::ParamSignature,
|
||||
sig: &ast::NonDefaultParamSignature,
|
||||
default_val_exists: bool,
|
||||
outer: Option<ParamIdx>,
|
||||
nth: usize,
|
||||
opt_decl_t: Option<&ParamTy>,
|
||||
|
@ -222,7 +227,7 @@ impl Context {
|
|||
} else {
|
||||
ParamIdx::Nth(nth)
|
||||
};
|
||||
let default = if sig.opt_default_val.is_some() {
|
||||
let default = if default_val_exists {
|
||||
DefaultInfo::WithDefault
|
||||
} else {
|
||||
DefaultInfo::NonDefault
|
||||
|
@ -262,7 +267,7 @@ impl Context {
|
|||
} else {
|
||||
ParamIdx::Nth(nth)
|
||||
};
|
||||
let default = if sig.opt_default_val.is_some() {
|
||||
let default = if default_val_exists {
|
||||
DefaultInfo::WithDefault
|
||||
} else {
|
||||
DefaultInfo::NonDefault
|
||||
|
@ -301,7 +306,7 @@ impl Context {
|
|||
} else {
|
||||
ParamIdx::Nth(nth)
|
||||
};
|
||||
let default = if sig.opt_default_val.is_some() {
|
||||
let default = if default_val_exists {
|
||||
DefaultInfo::WithDefault
|
||||
} else {
|
||||
DefaultInfo::NonDefault
|
||||
|
@ -324,7 +329,7 @@ impl Context {
|
|||
|
||||
pub(crate) fn assign_params(
|
||||
&mut self,
|
||||
params: &ast::Params,
|
||||
params: &hir::Params,
|
||||
opt_decl_subr_t: Option<SubrType>,
|
||||
) -> TyCheckResult<()> {
|
||||
if let Some(decl_subr_t) = opt_decl_subr_t {
|
||||
|
@ -339,7 +344,7 @@ impl Context {
|
|||
.zip(decl_subr_t.non_default_params.iter())
|
||||
.enumerate()
|
||||
{
|
||||
self.assign_param(sig, None, nth, Some(pt))?;
|
||||
self.assign_param(sig, false, None, nth, Some(pt))?;
|
||||
}
|
||||
for (nth, (sig, pt)) in params
|
||||
.defaults
|
||||
|
@ -347,17 +352,14 @@ impl Context {
|
|||
.zip(decl_subr_t.default_params.iter())
|
||||
.enumerate()
|
||||
{
|
||||
// TODO: .clone()
|
||||
self.assign_param(sig, None, nth, Some(pt))?;
|
||||
self.assign_param(&sig.sig, true, None, nth, Some(pt))?;
|
||||
}
|
||||
} else {
|
||||
for (nth, sig) in params
|
||||
.non_defaults
|
||||
.iter()
|
||||
.chain(params.defaults.iter())
|
||||
.enumerate()
|
||||
{
|
||||
self.assign_param(sig, None, nth, None)?;
|
||||
for (nth, sig) in params.non_defaults.iter().enumerate() {
|
||||
self.assign_param(sig, false, None, nth, None)?;
|
||||
}
|
||||
for (nth, sig) in params.defaults.iter().enumerate() {
|
||||
self.assign_param(&sig.sig, true, None, nth, None)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -368,23 +370,24 @@ impl Context {
|
|||
/// * AssignError: if `name` has already been registered
|
||||
pub(crate) fn assign_subr(
|
||||
&mut self,
|
||||
sig: &ast::SubrSignature,
|
||||
ident: &Identifier,
|
||||
decorators: &Set<Decorator>,
|
||||
id: DefId,
|
||||
body_t: &Type,
|
||||
) -> TyCheckResult<Type> {
|
||||
// already defined as const
|
||||
if sig.is_const() {
|
||||
let vi = self.decls.remove(sig.ident.inspect()).unwrap();
|
||||
if ident.is_const() {
|
||||
let vi = self.decls.remove(ident.inspect()).unwrap();
|
||||
let t = vi.t.clone();
|
||||
self.locals.insert(sig.ident.name.clone(), vi);
|
||||
self.locals.insert(ident.name.clone(), vi);
|
||||
return Ok(t);
|
||||
}
|
||||
let muty = if sig.ident.is_const() {
|
||||
let muty = if ident.is_const() {
|
||||
Mutability::Const
|
||||
} else {
|
||||
Mutability::Immutable
|
||||
};
|
||||
let name = &sig.ident.name;
|
||||
let name = &ident.name;
|
||||
// FIXME: constでない関数
|
||||
let t = self
|
||||
.get_current_scope_var(name.inspect())
|
||||
|
@ -394,7 +397,7 @@ impl Context {
|
|||
let var_args = t.var_args();
|
||||
let default_params = t.default_params().unwrap();
|
||||
if let Some(spec_ret_t) = t.return_t() {
|
||||
self.sub_unify(body_t, spec_ret_t, sig.loc(), None)
|
||||
self.sub_unify(body_t, spec_ret_t, ident.loc(), None)
|
||||
.map_err(|errs| {
|
||||
TyCheckErrors::new(
|
||||
errs.into_iter()
|
||||
|
@ -413,7 +416,7 @@ impl Context {
|
|||
)
|
||||
})?;
|
||||
}
|
||||
let sub_t = if sig.ident.is_procedural() {
|
||||
let sub_t = if ident.is_procedural() {
|
||||
proc(
|
||||
non_default_params.clone(),
|
||||
var_args.cloned(),
|
||||
|
@ -448,7 +451,7 @@ impl Context {
|
|||
return Err(TyCheckErrors::from(TyCheckError::violate_decl_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
sig.loc(),
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
name.inspect(),
|
||||
&vi.t,
|
||||
|
@ -456,8 +459,7 @@ impl Context {
|
|||
)));
|
||||
}
|
||||
}
|
||||
let comptime_decos = sig
|
||||
.decorators
|
||||
let comptime_decos = decorators
|
||||
.iter()
|
||||
.filter_map(|deco| match &deco.0 {
|
||||
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
|
||||
|
@ -469,7 +471,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
found_t,
|
||||
muty,
|
||||
sig.ident.vis(),
|
||||
ident.vis(),
|
||||
VarKind::Defined(id),
|
||||
Some(comptime_decos),
|
||||
self.impl_of(),
|
||||
|
@ -481,21 +483,25 @@ impl Context {
|
|||
Ok(t)
|
||||
}
|
||||
|
||||
pub(crate) fn fake_subr_assign(&mut self, sig: &ast::SubrSignature, failure_t: Type) {
|
||||
pub(crate) fn fake_subr_assign(
|
||||
&mut self,
|
||||
ident: &Identifier,
|
||||
decorators: &Set<Decorator>,
|
||||
failure_t: Type,
|
||||
) {
|
||||
// already defined as const
|
||||
if sig.is_const() {
|
||||
let vi = self.decls.remove(sig.ident.inspect()).unwrap();
|
||||
self.locals.insert(sig.ident.name.clone(), vi);
|
||||
if ident.is_const() {
|
||||
let vi = self.decls.remove(ident.inspect()).unwrap();
|
||||
self.locals.insert(ident.name.clone(), vi);
|
||||
}
|
||||
let muty = if sig.ident.is_const() {
|
||||
let muty = if ident.is_const() {
|
||||
Mutability::Const
|
||||
} else {
|
||||
Mutability::Immutable
|
||||
};
|
||||
let name = &sig.ident.name;
|
||||
let name = &ident.name;
|
||||
self.decls.remove(name);
|
||||
let comptime_decos = sig
|
||||
.decorators
|
||||
let comptime_decos = decorators
|
||||
.iter()
|
||||
.filter_map(|deco| match &deco.0 {
|
||||
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
|
||||
|
@ -507,7 +513,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
failure_t,
|
||||
muty,
|
||||
sig.ident.vis(),
|
||||
ident.vis(),
|
||||
VarKind::DoesNotExist,
|
||||
Some(comptime_decos),
|
||||
self.impl_of(),
|
||||
|
|
|
@ -12,7 +12,7 @@ use erg_common::{
|
|||
impl_nested_display_for_enum, impl_stream_for_wrapper,
|
||||
};
|
||||
|
||||
use erg_parser::ast::{fmt_lines, DefId, DefKind, Params, TypeSpec, VarName};
|
||||
use erg_parser::ast::{fmt_lines, DefId, DefKind, NonDefaultParamSignature, TypeSpec, VarName};
|
||||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t};
|
||||
|
@ -1216,6 +1216,115 @@ impl VarSignature {
|
|||
}
|
||||
}
|
||||
|
||||
/// Once the default_value is set to Some, all subsequent values must be Some
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DefaultParamSignature {
|
||||
pub sig: NonDefaultParamSignature,
|
||||
pub default_val: Expr,
|
||||
}
|
||||
|
||||
impl NestedDisplay for DefaultParamSignature {
|
||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result {
|
||||
write!(f, "{} := {}", self.sig, self.default_val,)
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(DefaultParamSignature);
|
||||
|
||||
impl Locational for DefaultParamSignature {
|
||||
fn loc(&self) -> Location {
|
||||
Location::concat(&self.sig, &self.default_val)
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultParamSignature {
|
||||
pub const fn new(sig: NonDefaultParamSignature, default_val: Expr) -> Self {
|
||||
Self { sig, default_val }
|
||||
}
|
||||
|
||||
pub const fn inspect(&self) -> Option<&Str> {
|
||||
self.sig.pat.inspect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Params {
|
||||
pub non_defaults: Vec<NonDefaultParamSignature>,
|
||||
pub var_args: Option<Box<NonDefaultParamSignature>>,
|
||||
pub defaults: Vec<DefaultParamSignature>,
|
||||
pub parens: Option<(Token, Token)>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Params {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"({}, {}, {})",
|
||||
fmt_vec(&self.non_defaults),
|
||||
fmt_option!(pre "...", &self.var_args),
|
||||
fmt_vec(&self.defaults)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Locational for Params {
|
||||
fn loc(&self) -> Location {
|
||||
// FIXME: varargs
|
||||
if let Some((l, r)) = &self.parens {
|
||||
Location::concat(l, r)
|
||||
} else if !self.non_defaults.is_empty() {
|
||||
Location::concat(&self.non_defaults[0], self.non_defaults.last().unwrap())
|
||||
} else if let Some(var_args) = &self.var_args {
|
||||
if !self.defaults.is_empty() {
|
||||
Location::concat(var_args.as_ref(), self.defaults.last().unwrap())
|
||||
} else {
|
||||
var_args.loc()
|
||||
}
|
||||
} else if !self.defaults.is_empty() {
|
||||
Location::concat(&self.defaults[0], self.defaults.last().unwrap())
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type RawParams = (
|
||||
Vec<NonDefaultParamSignature>,
|
||||
Option<Box<NonDefaultParamSignature>>,
|
||||
Vec<DefaultParamSignature>,
|
||||
Option<(Token, Token)>,
|
||||
);
|
||||
|
||||
impl Params {
|
||||
pub const fn new(
|
||||
non_defaults: Vec<NonDefaultParamSignature>,
|
||||
var_args: Option<Box<NonDefaultParamSignature>>,
|
||||
defaults: Vec<DefaultParamSignature>,
|
||||
parens: Option<(Token, Token)>,
|
||||
) -> Self {
|
||||
Self {
|
||||
non_defaults,
|
||||
var_args,
|
||||
defaults,
|
||||
parens,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deconstruct(self) -> RawParams {
|
||||
(self.non_defaults, self.var_args, self.defaults, self.parens)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.non_defaults.len() + self.defaults.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct SubrSignature {
|
||||
pub ident: Identifier,
|
||||
|
|
|
@ -759,6 +759,22 @@ impl ASTLowerer {
|
|||
Ok(hir::Call::new(class, Some(attr_name), args))
|
||||
}
|
||||
|
||||
fn lower_params(&mut self, params: ast::Params) -> LowerResult<hir::Params> {
|
||||
log!(info "entered {}({})", fn_name!(), params);
|
||||
let mut hir_defaults = vec![];
|
||||
for default in params.defaults.into_iter() {
|
||||
let default_val = self.lower_expr(default.default_val)?;
|
||||
hir_defaults.push(hir::DefaultParamSignature::new(default.sig, default_val));
|
||||
}
|
||||
let hir_params = hir::Params::new(
|
||||
params.non_defaults,
|
||||
params.var_args,
|
||||
hir_defaults,
|
||||
params.parens,
|
||||
);
|
||||
Ok(hir_params)
|
||||
}
|
||||
|
||||
/// TODO: varargs
|
||||
fn lower_lambda(&mut self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> {
|
||||
log!(info "entered {}({lambda})", fn_name!());
|
||||
|
@ -775,7 +791,8 @@ impl ASTLowerer {
|
|||
.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
|
||||
let tv_ctx = TyVarInstContext::new(self.ctx.level, bounds, &self.ctx);
|
||||
self.ctx.grow(&name, kind, Private, Some(tv_ctx));
|
||||
if let Err(errs) = self.ctx.assign_params(&lambda.sig.params, None) {
|
||||
let params = self.lower_params(lambda.sig.params)?;
|
||||
if let Err(errs) = self.ctx.assign_params(¶ms, None) {
|
||||
self.errs.extend(errs.into_iter());
|
||||
}
|
||||
if let Err(errs) = self.ctx.preregister(&lambda.body) {
|
||||
|
@ -818,7 +835,7 @@ impl ASTLowerer {
|
|||
} else {
|
||||
quant(t, bounds)
|
||||
};
|
||||
Ok(hir::Lambda::new(id, lambda.sig.params, lambda.op, body, t))
|
||||
Ok(hir::Lambda::new(id, params, lambda.op, body, t))
|
||||
}
|
||||
|
||||
fn lower_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
|
||||
|
@ -951,7 +968,8 @@ impl ASTLowerer {
|
|||
.unwrap_or(Type::Failure);
|
||||
match t {
|
||||
Type::Subr(t) => {
|
||||
if let Err(errs) = self.ctx.assign_params(&sig.params, Some(t.clone())) {
|
||||
let params = self.lower_params(sig.params)?;
|
||||
if let Err(errs) = self.ctx.assign_params(¶ms, Some(t.clone())) {
|
||||
self.errs.extend(errs.into_iter());
|
||||
}
|
||||
if let Err(errs) = self.ctx.preregister(&body.block) {
|
||||
|
@ -961,9 +979,9 @@ impl ASTLowerer {
|
|||
Ok(block) => {
|
||||
let found_body_t = block.ref_t();
|
||||
let expect_body_t = t.return_t.as_ref();
|
||||
if !sig.is_const() {
|
||||
if !sig.ident.is_const() {
|
||||
if let Err(e) = self.return_t_check(
|
||||
sig.loc(),
|
||||
sig.ident.loc(),
|
||||
sig.ident.inspect(),
|
||||
expect_body_t,
|
||||
found_body_t,
|
||||
|
@ -972,20 +990,21 @@ impl ASTLowerer {
|
|||
}
|
||||
}
|
||||
let id = body.id;
|
||||
let t =
|
||||
self.ctx
|
||||
.outer
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.assign_subr(&sig, id, found_body_t)?;
|
||||
let t = self.ctx.outer.as_mut().unwrap().assign_subr(
|
||||
&sig.ident,
|
||||
&sig.decorators,
|
||||
id,
|
||||
found_body_t,
|
||||
)?;
|
||||
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name);
|
||||
let sig = hir::SubrSignature::new(ident, sig.params, t);
|
||||
let sig = hir::SubrSignature::new(ident, params, t);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
|
||||
}
|
||||
Err(errs) => {
|
||||
self.ctx.outer.as_mut().unwrap().assign_subr(
|
||||
&sig,
|
||||
&sig.ident,
|
||||
&sig.decorators,
|
||||
ast::DefId(0),
|
||||
&Type::Failure,
|
||||
)?;
|
||||
|
@ -994,20 +1013,21 @@ impl ASTLowerer {
|
|||
}
|
||||
}
|
||||
Type::Failure => {
|
||||
if let Err(errs) = self.ctx.assign_params(&sig.params, None) {
|
||||
let params = self.lower_params(sig.params)?;
|
||||
if let Err(errs) = self.ctx.assign_params(¶ms, None) {
|
||||
self.errs.extend(errs.into_iter());
|
||||
}
|
||||
if let Err(errs) = self.ctx.preregister(&body.block) {
|
||||
self.errs.extend(errs.into_iter());
|
||||
}
|
||||
self.ctx
|
||||
.outer
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.fake_subr_assign(&sig, Type::Failure);
|
||||
self.ctx.outer.as_mut().unwrap().fake_subr_assign(
|
||||
&sig.ident,
|
||||
&sig.decorators,
|
||||
Type::Failure,
|
||||
);
|
||||
let block = self.lower_block(body.block)?;
|
||||
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name);
|
||||
let sig = hir::SubrSignature::new(ident, sig.params, Type::Failure);
|
||||
let sig = hir::SubrSignature::new(ident, params, Type::Failure);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
|
||||
}
|
||||
|
|
|
@ -94,6 +94,29 @@ impl CodeObjFlags {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum MakeFunctionFlags {
|
||||
None = 0,
|
||||
Defaults = 1,
|
||||
KwDefaults = 2,
|
||||
Annotations = 4,
|
||||
Closure = 8,
|
||||
}
|
||||
|
||||
impl From<u8> for MakeFunctionFlags {
|
||||
fn from(flags: u8) -> Self {
|
||||
match flags {
|
||||
0 => Self::None,
|
||||
1 => Self::Defaults,
|
||||
2 => Self::KwDefaults,
|
||||
4 => Self::Annotations,
|
||||
8 => Self::Closure,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of `PyCodeObject`, see Include/cpython/code.h in CPython for details.
|
||||
///
|
||||
/// 各属性をErg側のObjに変換すると遅くなりそうなので、アクサスされたときのみ変換して提供する
|
||||
|
|
|
@ -2422,7 +2422,7 @@ impl ParamTuplePattern {
|
|||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ParamRecordAttr {
|
||||
pub lhs: Identifier,
|
||||
pub rhs: ParamSignature,
|
||||
pub rhs: NonDefaultParamSignature,
|
||||
}
|
||||
|
||||
impl NestedDisplay for ParamRecordAttr {
|
||||
|
@ -2435,7 +2435,7 @@ impl_display_from_nested!(ParamRecordAttr);
|
|||
impl_locational!(ParamRecordAttr, lhs, rhs);
|
||||
|
||||
impl ParamRecordAttr {
|
||||
pub const fn new(lhs: Identifier, rhs: ParamSignature) -> Self {
|
||||
pub const fn new(lhs: Identifier, rhs: NonDefaultParamSignature) -> Self {
|
||||
Self { lhs, rhs }
|
||||
}
|
||||
}
|
||||
|
@ -2554,35 +2554,22 @@ impl ParamPattern {
|
|||
|
||||
/// Once the default_value is set to Some, all subsequent values must be Some
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ParamSignature {
|
||||
pub struct NonDefaultParamSignature {
|
||||
pub pat: ParamPattern,
|
||||
pub t_spec: Option<TypeSpecWithOp>,
|
||||
pub opt_default_val: Option<ConstExpr>,
|
||||
}
|
||||
|
||||
impl NestedDisplay for ParamSignature {
|
||||
impl NestedDisplay for NonDefaultParamSignature {
|
||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result {
|
||||
if let Some(default_val) = &self.opt_default_val {
|
||||
write!(
|
||||
f,
|
||||
"{}{} := {}",
|
||||
self.pat,
|
||||
fmt_option!(self.t_spec),
|
||||
default_val,
|
||||
)
|
||||
} else {
|
||||
write!(f, "{}{}", self.pat, fmt_option!(self.t_spec),)
|
||||
}
|
||||
write!(f, "{}{}", self.pat, fmt_option!(self.t_spec),)
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(ParamSignature);
|
||||
impl_display_from_nested!(NonDefaultParamSignature);
|
||||
|
||||
impl Locational for ParamSignature {
|
||||
impl Locational for NonDefaultParamSignature {
|
||||
fn loc(&self) -> Location {
|
||||
if let Some(default) = &self.opt_default_val {
|
||||
Location::concat(&self.pat, default)
|
||||
} else if let Some(t_spec) = &self.t_spec {
|
||||
if let Some(t_spec) = &self.t_spec {
|
||||
Location::concat(&self.pat, t_spec)
|
||||
} else {
|
||||
self.pat.loc()
|
||||
|
@ -2590,33 +2577,52 @@ impl Locational for ParamSignature {
|
|||
}
|
||||
}
|
||||
|
||||
impl ParamSignature {
|
||||
pub const fn new(
|
||||
pat: ParamPattern,
|
||||
t_spec: Option<TypeSpecWithOp>,
|
||||
opt_default_val: Option<ConstExpr>,
|
||||
) -> Self {
|
||||
Self {
|
||||
pat,
|
||||
t_spec,
|
||||
opt_default_val,
|
||||
}
|
||||
impl NonDefaultParamSignature {
|
||||
pub const fn new(pat: ParamPattern, t_spec: Option<TypeSpecWithOp>) -> Self {
|
||||
Self { pat, t_spec }
|
||||
}
|
||||
|
||||
pub const fn inspect(&self) -> Option<&Str> {
|
||||
self.pat.inspect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_default(&self) -> bool {
|
||||
self.opt_default_val.is_some()
|
||||
/// Once the default_value is set to Some, all subsequent values must be Some
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DefaultParamSignature {
|
||||
pub sig: NonDefaultParamSignature,
|
||||
pub default_val: Expr,
|
||||
}
|
||||
|
||||
impl NestedDisplay for DefaultParamSignature {
|
||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result {
|
||||
write!(f, "{} := {}", self.sig, self.default_val,)
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(DefaultParamSignature);
|
||||
|
||||
impl Locational for DefaultParamSignature {
|
||||
fn loc(&self) -> Location {
|
||||
Location::concat(&self.sig, &self.default_val)
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultParamSignature {
|
||||
pub const fn new(sig: NonDefaultParamSignature, default_val: Expr) -> Self {
|
||||
Self { sig, default_val }
|
||||
}
|
||||
|
||||
pub const fn inspect(&self) -> Option<&Str> {
|
||||
self.sig.pat.inspect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Params {
|
||||
pub non_defaults: Vec<ParamSignature>,
|
||||
pub var_args: Option<Box<ParamSignature>>,
|
||||
pub defaults: Vec<ParamSignature>,
|
||||
pub non_defaults: Vec<NonDefaultParamSignature>,
|
||||
pub var_args: Option<Box<NonDefaultParamSignature>>,
|
||||
pub defaults: Vec<DefaultParamSignature>,
|
||||
pub parens: Option<(Token, Token)>,
|
||||
}
|
||||
|
||||
|
@ -2654,17 +2660,17 @@ impl Locational for Params {
|
|||
}
|
||||
|
||||
type RawParams = (
|
||||
Vec<ParamSignature>,
|
||||
Option<Box<ParamSignature>>,
|
||||
Vec<ParamSignature>,
|
||||
Vec<NonDefaultParamSignature>,
|
||||
Option<Box<NonDefaultParamSignature>>,
|
||||
Vec<DefaultParamSignature>,
|
||||
Option<(Token, Token)>,
|
||||
);
|
||||
|
||||
impl Params {
|
||||
pub fn new(
|
||||
non_defaults: Vec<ParamSignature>,
|
||||
var_args: Option<ParamSignature>,
|
||||
defaults: Vec<ParamSignature>,
|
||||
non_defaults: Vec<NonDefaultParamSignature>,
|
||||
var_args: Option<NonDefaultParamSignature>,
|
||||
defaults: Vec<DefaultParamSignature>,
|
||||
parens: Option<(Token, Token)>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
|
|
@ -13,8 +13,8 @@ use erg_common::{enum_unwrap, get_hash, log, set};
|
|||
use crate::ast::{
|
||||
Accessor, Args, Array, ArrayComprehension, ArrayWithLength, BinOp, Block, Call, DataPack, Def,
|
||||
DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal,
|
||||
Methods, Module, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple, ParamPattern,
|
||||
ParamSignature, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
|
||||
Methods, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet,
|
||||
NormalTuple, ParamPattern, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
|
||||
ShortenedRecord, Signature, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec,
|
||||
UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature,
|
||||
};
|
||||
|
@ -255,7 +255,7 @@ impl Desugarer {
|
|||
name.col_end().unwrap() + 1, // HACK: `(name) %x = ...`という形を想定
|
||||
));
|
||||
let param =
|
||||
ParamSignature::new(ParamPattern::VarName(param), None, None);
|
||||
NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||
let params = Params::new(vec![param], None, vec![], None);
|
||||
let sig = Signature::Subr(SubrSignature::new(
|
||||
set! {},
|
||||
|
|
|
@ -1985,12 +1985,9 @@ impl Parser {
|
|||
return Err(());
|
||||
}
|
||||
// e.g. (x, y:=1) -> ...
|
||||
// Syntax error will occur when trying to use it as a tuple
|
||||
PosOrKwArg::Kw(arg) => {
|
||||
args.push_kw(arg);
|
||||
/*self.level -= 1;
|
||||
let err = ParseError::simple_syntax_error(line!() as usize, arg.loc());
|
||||
self.errs.push(err);
|
||||
return Err(());*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2369,7 +2366,7 @@ impl Parser {
|
|||
&mut self,
|
||||
arg: PosArg,
|
||||
allow_self: bool,
|
||||
) -> ParseResult<ParamSignature> {
|
||||
) -> ParseResult<NonDefaultParamSignature> {
|
||||
debug_call_info!(self);
|
||||
let param = self
|
||||
.convert_rhs_to_param(arg.expr, allow_self)
|
||||
|
@ -2382,7 +2379,7 @@ impl Parser {
|
|||
&mut self,
|
||||
expr: Expr,
|
||||
allow_self: bool,
|
||||
) -> ParseResult<ParamSignature> {
|
||||
) -> ParseResult<NonDefaultParamSignature> {
|
||||
debug_call_info!(self);
|
||||
match expr {
|
||||
Expr::Accessor(Accessor::Ident(ident)) => {
|
||||
|
@ -2394,13 +2391,13 @@ impl Parser {
|
|||
}
|
||||
// FIXME deny: public
|
||||
let pat = ParamPattern::VarName(ident.name);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
Expr::Lit(lit) => {
|
||||
let pat = ParamPattern::Lit(lit);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2409,7 +2406,7 @@ impl Parser {
|
|||
.convert_array_to_param_array_pat(array)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let pat = ParamPattern::Array(array_pat);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2418,7 +2415,7 @@ impl Parser {
|
|||
.convert_record_to_param_record_pat(record)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let pat = ParamPattern::Record(record_pat);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2427,7 +2424,7 @@ impl Parser {
|
|||
.convert_tuple_to_param_tuple_pat(tuple)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let pat = ParamPattern::Tuple(tuple_pat);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2444,7 +2441,7 @@ impl Parser {
|
|||
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::Ref(var.name);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2453,7 +2450,7 @@ impl Parser {
|
|||
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::RefMut(var.name);
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
let param = NonDefaultParamSignature::new(pat, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2474,11 +2471,14 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_kw_arg_to_default_param(&mut self, arg: KwArg) -> ParseResult<ParamSignature> {
|
||||
fn convert_kw_arg_to_default_param(
|
||||
&mut self,
|
||||
arg: KwArg,
|
||||
) -> ParseResult<DefaultParamSignature> {
|
||||
debug_call_info!(self);
|
||||
let pat = ParamPattern::VarName(VarName::new(arg.keyword));
|
||||
let expr = Self::validate_const_expr(arg.expr).map_err(|e| self.errs.push(e))?;
|
||||
let param = ParamSignature::new(pat, arg.t_spec, Some(expr));
|
||||
let sig = NonDefaultParamSignature::new(pat, arg.t_spec);
|
||||
let param = DefaultParamSignature::new(sig, arg.expr);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2532,8 +2532,10 @@ impl Parser {
|
|||
Record::Shortened(rec) => {
|
||||
let mut pats = vec![];
|
||||
for ident in rec.idents.into_iter() {
|
||||
let rhs =
|
||||
ParamSignature::new(ParamPattern::VarName(ident.name.clone()), None, None);
|
||||
let rhs = NonDefaultParamSignature::new(
|
||||
ParamPattern::VarName(ident.name.clone()),
|
||||
None,
|
||||
);
|
||||
pats.push(ParamRecordAttr::new(ident.clone(), rhs));
|
||||
}
|
||||
let attrs = ParamRecordAttrs::new(pats);
|
||||
|
@ -2563,13 +2565,13 @@ impl Parser {
|
|||
&mut self,
|
||||
tasc: TypeAscription,
|
||||
allow_self: bool,
|
||||
) -> ParseResult<ParamSignature> {
|
||||
) -> ParseResult<NonDefaultParamSignature> {
|
||||
debug_call_info!(self);
|
||||
let param = self
|
||||
.convert_rhs_to_param(*tasc.expr, allow_self)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let t_spec = TypeSpecWithOp::new(tasc.op, tasc.t_spec);
|
||||
let param = ParamSignature::new(param.pat, Some(t_spec), None);
|
||||
let param = NonDefaultParamSignature::new(param.pat, Some(t_spec));
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
|
@ -2596,7 +2598,7 @@ impl Parser {
|
|||
let arr = self
|
||||
.convert_array_to_param_array_pat(array)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let param = ParamSignature::new(ParamPattern::Array(arr), None, None);
|
||||
let param = NonDefaultParamSignature::new(ParamPattern::Array(arr), None);
|
||||
let params = Params::new(vec![param], None, vec![], None);
|
||||
self.level -= 1;
|
||||
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty()))
|
||||
|
@ -2605,7 +2607,7 @@ impl Parser {
|
|||
let rec = self
|
||||
.convert_record_to_param_record_pat(record)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
let param = ParamSignature::new(ParamPattern::Record(rec), None, None);
|
||||
let param = NonDefaultParamSignature::new(ParamPattern::Record(rec), None);
|
||||
let params = Params::new(vec![param], None, vec![], None);
|
||||
self.level -= 1;
|
||||
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty()))
|
||||
|
@ -2626,7 +2628,10 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_accessor_to_param_sig(&mut self, accessor: Accessor) -> ParseResult<ParamSignature> {
|
||||
fn convert_accessor_to_param_sig(
|
||||
&mut self,
|
||||
accessor: Accessor,
|
||||
) -> ParseResult<NonDefaultParamSignature> {
|
||||
debug_call_info!(self);
|
||||
match accessor {
|
||||
Accessor::Ident(ident) => {
|
||||
|
@ -2636,7 +2641,7 @@ impl Parser {
|
|||
ParamPattern::VarName(ident.name)
|
||||
};
|
||||
self.level -= 1;
|
||||
Ok(ParamSignature::new(pat, None, None))
|
||||
Ok(NonDefaultParamSignature::new(pat, None))
|
||||
}
|
||||
other => {
|
||||
self.level -= 1;
|
||||
|
@ -2806,7 +2811,7 @@ impl Parser {
|
|||
});
|
||||
let mut defaults = vec![];
|
||||
for param in lambda.sig.params.defaults.into_iter() {
|
||||
let param = match (param.pat, param.t_spec) {
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue