Implement default parameter

This commit is contained in:
Shunsuke Shibayama 2022-10-18 10:27:57 +09:00
parent af65a48355
commit d0456ec1ee
10 changed files with 375 additions and 171 deletions

View file

@ -4,6 +4,7 @@
use std::fmt; use std::fmt;
use std::process; use std::process;
use crate::ty::codeobj::MakeFunctionFlags;
use crate::ty::codeobj::{CodeObj, CodeObjFlags}; use crate::ty::codeobj::{CodeObj, CodeObjFlags};
use erg_common::astr::AtomicStr; use erg_common::astr::AtomicStr;
use erg_common::cache::CacheSet; use erg_common::cache::CacheSet;
@ -21,7 +22,7 @@ use erg_parser::ast::DefId;
use erg_parser::ast::DefKind; use erg_parser::ast::DefKind;
use Opcode::*; use Opcode::*;
use erg_parser::ast::{ParamPattern, ParamSignature, Params, VarName}; use erg_parser::ast::{NonDefaultParamSignature, ParamPattern, VarName};
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
use crate::compile::{AccessKind, Name, StoreLoadKind}; use crate::compile::{AccessKind, Name, StoreLoadKind};
@ -29,7 +30,7 @@ use crate::context::eval::type_from_token_kind;
use crate::error::CompileError; use crate::error::CompileError;
use crate::hir::{ use crate::hir::{
Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, 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, VarSignature, HIR,
}; };
use crate::ty::free::fresh_varname; use crate::ty::free::fresh_varname;
@ -858,6 +859,18 @@ impl CodeGenerator {
log!(info "entered {} ({lambda})", fn_name!()); log!(info "entered {} ({lambda})", fn_name!());
let mut make_function_flag = 0u8; let mut make_function_flag = 0u8;
let params = self.gen_param_names(&lambda.params); 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); let code = self.emit_block(lambda.body, Some("<lambda>".into()), params);
if !self.cur_block_codeobj().cellvars.is_empty() { if !self.cur_block_codeobj().cellvars.is_empty() {
let cellvars_len = self.cur_block_codeobj().cellvars.len() as u8; let cellvars_len = self.cur_block_codeobj().cellvars.len() as u8;
@ -867,7 +880,7 @@ impl CodeGenerator {
} }
self.write_instr(BUILD_TUPLE); self.write_instr(BUILD_TUPLE);
self.write_arg(cellvars_len); 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(code);
self.emit_load_const("<lambda>"); self.emit_load_const("<lambda>");
@ -875,6 +888,9 @@ impl CodeGenerator {
self.write_arg(make_function_flag); self.write_arg(make_function_flag);
// stack_dec: <lambda code obj> + <name "<lambda>"> -> <function> // stack_dec: <lambda code obj> + <name "<lambda>"> -> <function>
self.stack_dec(); self.stack_dec();
if make_function_flag & MakeFunctionFlags::Defaults as u8 != 0 {
self.stack_dec();
}
} }
fn emit_unaryop(&mut self, unary: UnaryOp) { 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 ident = Identifier::public_with_line(Token::dummy(), Str::ever("__init__"), line);
let param_name = fresh_varname(); let param_name = fresh_varname();
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); 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 = 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 params = Params::new(vec![self_param, param], None, vec![], None);
let subr_sig = SubrSignature::new(ident, params, __new__.clone()); let subr_sig = SubrSignature::new(ident, params, __new__.clone());
let mut attrs = vec![]; let mut attrs = vec![];
@ -1729,7 +1745,7 @@ impl CodeGenerator {
let ident = Identifier::public_with_line(Token::dummy(), Str::ever("new"), line); let ident = Identifier::public_with_line(Token::dummy(), Str::ever("new"), line);
let param_name = fresh_varname(); let param_name = fresh_varname();
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); 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 sig = SubrSignature::new(ident, Params::new(vec![param], None, vec![], None), __new__);
let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line( let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line(
Str::from(param_name), Str::from(param_name),

View file

@ -512,20 +512,32 @@ impl Context {
let tv_ctx = TyVarInstContext::new(self.level, bounds, self); let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
let mut non_default_params = Vec::with_capacity(lambda.sig.params.non_defaults.len()); let mut non_default_params = Vec::with_capacity(lambda.sig.params.non_defaults.len());
for sig in lambda.sig.params.non_defaults.iter() { for sig in lambda.sig.params.non_defaults.iter() {
let pt = let pt = self.instantiate_param_ty(
self.instantiate_param_ty(sig, None, Some(&tv_ctx), RegistrationMode::Normal)?; sig,
None,
None,
Some(&tv_ctx),
RegistrationMode::Normal,
)?;
non_default_params.push(pt); non_default_params.push(pt);
} }
let var_params = if let Some(p) = lambda.sig.params.var_args.as_ref() { 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) Some(pt)
} else { } else {
None None
}; };
let mut default_params = Vec::with_capacity(lambda.sig.params.defaults.len()); let mut default_params = Vec::with_capacity(lambda.sig.params.defaults.len());
for sig in lambda.sig.params.defaults.iter() { for sig in lambda.sig.params.defaults.iter() {
let pt = let expr = self.eval_const_expr(&sig.default_val)?;
self.instantiate_param_ty(sig, None, Some(&tv_ctx), RegistrationMode::Normal)?; let pt = self.instantiate_param_ty(
&sig.sig,
Some(expr.t()),
None,
Some(&tv_ctx),
RegistrationMode::Normal,
)?;
default_params.push(pt); default_params.push(pt);
} }
// HACK: should avoid cloning // HACK: should avoid cloning

View file

@ -13,8 +13,8 @@ use erg_common::Str;
use erg_common::{assume_unreachable, enum_unwrap, set, try_map_mut}; use erg_common::{assume_unreachable, enum_unwrap, set, try_map_mut};
use ast::{ use ast::{
ParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec, TypeBoundSpecs, NonDefaultParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec,
TypeSpec, TypeBoundSpecs, TypeSpec,
}; };
use erg_parser::ast; use erg_parser::ast;
use erg_parser::token::TokenKind; use erg_parser::token::TokenKind;
@ -507,6 +507,7 @@ impl Context {
pub(crate) fn instantiate_sub_sig_t( pub(crate) fn instantiate_sub_sig_t(
&self, &self,
sig: &ast::SubrSignature, sig: &ast::SubrSignature,
default_ts: Vec<Type>,
mode: RegistrationMode, mode: RegistrationMode,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
// -> Result<Type, (Type, TyCheckErrors)> { // -> Result<Type, (Type, TyCheckErrors)> {
@ -521,22 +522,34 @@ impl Context {
let opt_decl_t = opt_decl_sig_t let opt_decl_t = opt_decl_sig_t
.as_ref() .as_ref()
.and_then(|subr| subr.non_default_params.get(n)); .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 var_args = if let Some(var_args) = sig.params.var_args.as_ref() {
let opt_decl_t = opt_decl_sig_t let opt_decl_t = opt_decl_sig_t
.as_ref() .as_ref()
.and_then(|subr| subr.var_params.as_ref().map(|v| v.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 { } else {
None None
}; };
let mut defaults = vec![]; 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 let opt_decl_t = opt_decl_sig_t
.as_ref() .as_ref()
.and_then(|subr| subr.default_params.get(n)); .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 spec_return_t = if let Some(s) = sig.return_t_spec.as_ref() {
let opt_decl_t = opt_decl_sig_t let opt_decl_t = opt_decl_sig_t
@ -562,7 +575,7 @@ impl Context {
/// spec_t == Noneかつリテラル推論が不可能なら型変数を発行する /// spec_t == Noneかつリテラル推論が不可能なら型変数を発行する
pub(crate) fn instantiate_param_sig_t( pub(crate) fn instantiate_param_sig_t(
&self, &self,
sig: &ParamSignature, sig: &NonDefaultParamSignature,
opt_decl_t: Option<&ParamTy>, opt_decl_t: Option<&ParamTy>,
tmp_tv_ctx: Option<&TyVarInstContext>, tmp_tv_ctx: Option<&TyVarInstContext>,
mode: RegistrationMode, mode: RegistrationMode,
@ -599,21 +612,15 @@ impl Context {
pub(crate) fn instantiate_param_ty( pub(crate) fn instantiate_param_ty(
&self, &self,
sig: &ParamSignature, sig: &NonDefaultParamSignature,
opt_default_t: Option<Type>,
opt_decl_t: Option<&ParamTy>, opt_decl_t: Option<&ParamTy>,
tmp_tv_ctx: Option<&TyVarInstContext>, tmp_tv_ctx: Option<&TyVarInstContext>,
mode: RegistrationMode, mode: RegistrationMode,
) -> TyCheckResult<ParamTy> { ) -> TyCheckResult<ParamTy> {
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_ctx, mode)?; let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_ctx, mode)?;
match (sig.inspect(), &sig.opt_default_val) { match (sig.inspect(), opt_default_t) {
(Some(name), Some(default)) => { (Some(name), Some(default_t)) => Ok(ParamTy::kw_default(name.clone(), t, default_t)),
let default = self.instantiate_const_expr(default)?;
Ok(ParamTy::kw_default(
name.clone(),
t,
self.get_tp_t(&default)?,
))
}
(Some(name), None) => Ok(ParamTy::kw(name.clone(), t)), (Some(name), None) => Ok(ParamTy::kw(name.clone(), t)),
(None, None) => Ok(ParamTy::anonymous(t)), (None, None) => Ok(ParamTy::anonymous(t)),
_ => unreachable!(), _ => unreachable!(),

View file

@ -13,9 +13,9 @@ use erg_common::Str;
use erg_common::{enum_unwrap, get_hash, log, option_enum_unwrap, set}; use erg_common::{enum_unwrap, get_hash, log, option_enum_unwrap, set};
use ast::{DefId, Identifier, VarName}; 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::free::{Constraint, Cyclicity, FreeKind};
use crate::ty::value::{GenTypeObj, TypeKind, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
use crate::ty::{HasType, ParamTy, SubrType, Type}; use crate::ty::{HasType, ParamTy, SubrType, Type};
@ -115,19 +115,23 @@ impl Context {
_ => None, _ => None,
}) })
.collect::<Set<_>>(); .collect::<Set<_>>();
let t = self.instantiate_sub_sig_t(sig, PreRegister).map_err(|e| { let default_ts =
let vi = VarInfo::new( vec![free_var(self.level, Constraint::new_type_of(Type::Type)); sig.params.len()];
Type::Failure, let t = self
muty, .instantiate_sub_sig_t(sig, default_ts, PreRegister)
vis, .map_err(|e| {
kind.clone(), let vi = VarInfo::new(
Some(comptime_decos.clone()), Type::Failure,
self.impl_of(), muty,
None, vis,
); kind.clone(),
self.decls.insert(sig.ident.name.clone(), vi); Some(comptime_decos.clone()),
e self.impl_of(),
})?; None,
);
self.decls.insert(sig.ident.name.clone(), vi);
e
})?;
let vi = VarInfo::new( let vi = VarInfo::new(
t, t,
muty, muty,
@ -190,7 +194,8 @@ impl Context {
/// 宣言が既にある場合、opt_decl_tに宣言の型を渡す /// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
fn assign_param( fn assign_param(
&mut self, &mut self,
sig: &ast::ParamSignature, sig: &ast::NonDefaultParamSignature,
default_val_exists: bool,
outer: Option<ParamIdx>, outer: Option<ParamIdx>,
nth: usize, nth: usize,
opt_decl_t: Option<&ParamTy>, opt_decl_t: Option<&ParamTy>,
@ -222,7 +227,7 @@ impl Context {
} else { } else {
ParamIdx::Nth(nth) ParamIdx::Nth(nth)
}; };
let default = if sig.opt_default_val.is_some() { let default = if default_val_exists {
DefaultInfo::WithDefault DefaultInfo::WithDefault
} else { } else {
DefaultInfo::NonDefault DefaultInfo::NonDefault
@ -262,7 +267,7 @@ impl Context {
} else { } else {
ParamIdx::Nth(nth) ParamIdx::Nth(nth)
}; };
let default = if sig.opt_default_val.is_some() { let default = if default_val_exists {
DefaultInfo::WithDefault DefaultInfo::WithDefault
} else { } else {
DefaultInfo::NonDefault DefaultInfo::NonDefault
@ -301,7 +306,7 @@ impl Context {
} else { } else {
ParamIdx::Nth(nth) ParamIdx::Nth(nth)
}; };
let default = if sig.opt_default_val.is_some() { let default = if default_val_exists {
DefaultInfo::WithDefault DefaultInfo::WithDefault
} else { } else {
DefaultInfo::NonDefault DefaultInfo::NonDefault
@ -324,7 +329,7 @@ impl Context {
pub(crate) fn assign_params( pub(crate) fn assign_params(
&mut self, &mut self,
params: &ast::Params, params: &hir::Params,
opt_decl_subr_t: Option<SubrType>, opt_decl_subr_t: Option<SubrType>,
) -> TyCheckResult<()> { ) -> TyCheckResult<()> {
if let Some(decl_subr_t) = opt_decl_subr_t { if let Some(decl_subr_t) = opt_decl_subr_t {
@ -339,7 +344,7 @@ impl Context {
.zip(decl_subr_t.non_default_params.iter()) .zip(decl_subr_t.non_default_params.iter())
.enumerate() .enumerate()
{ {
self.assign_param(sig, None, nth, Some(pt))?; self.assign_param(sig, false, None, nth, Some(pt))?;
} }
for (nth, (sig, pt)) in params for (nth, (sig, pt)) in params
.defaults .defaults
@ -347,17 +352,14 @@ impl Context {
.zip(decl_subr_t.default_params.iter()) .zip(decl_subr_t.default_params.iter())
.enumerate() .enumerate()
{ {
// TODO: .clone() self.assign_param(&sig.sig, true, None, nth, Some(pt))?;
self.assign_param(sig, None, nth, Some(pt))?;
} }
} else { } else {
for (nth, sig) in params for (nth, sig) in params.non_defaults.iter().enumerate() {
.non_defaults self.assign_param(sig, false, None, nth, None)?;
.iter() }
.chain(params.defaults.iter()) for (nth, sig) in params.defaults.iter().enumerate() {
.enumerate() self.assign_param(&sig.sig, true, None, nth, None)?;
{
self.assign_param(sig, None, nth, None)?;
} }
} }
Ok(()) Ok(())
@ -368,23 +370,24 @@ impl Context {
/// * AssignError: if `name` has already been registered /// * AssignError: if `name` has already been registered
pub(crate) fn assign_subr( pub(crate) fn assign_subr(
&mut self, &mut self,
sig: &ast::SubrSignature, ident: &Identifier,
decorators: &Set<Decorator>,
id: DefId, id: DefId,
body_t: &Type, body_t: &Type,
) -> TyCheckResult<Type> { ) -> TyCheckResult<Type> {
// already defined as const // already defined as const
if sig.is_const() { if ident.is_const() {
let vi = self.decls.remove(sig.ident.inspect()).unwrap(); let vi = self.decls.remove(ident.inspect()).unwrap();
let t = vi.t.clone(); let t = vi.t.clone();
self.locals.insert(sig.ident.name.clone(), vi); self.locals.insert(ident.name.clone(), vi);
return Ok(t); return Ok(t);
} }
let muty = if sig.ident.is_const() { let muty = if ident.is_const() {
Mutability::Const Mutability::Const
} else { } else {
Mutability::Immutable Mutability::Immutable
}; };
let name = &sig.ident.name; let name = &ident.name;
// FIXME: constでない関数 // FIXME: constでない関数
let t = self let t = self
.get_current_scope_var(name.inspect()) .get_current_scope_var(name.inspect())
@ -394,7 +397,7 @@ impl Context {
let var_args = t.var_args(); let var_args = t.var_args();
let default_params = t.default_params().unwrap(); let default_params = t.default_params().unwrap();
if let Some(spec_ret_t) = t.return_t() { 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| { .map_err(|errs| {
TyCheckErrors::new( TyCheckErrors::new(
errs.into_iter() 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( proc(
non_default_params.clone(), non_default_params.clone(),
var_args.cloned(), var_args.cloned(),
@ -448,7 +451,7 @@ impl Context {
return Err(TyCheckErrors::from(TyCheckError::violate_decl_error( return Err(TyCheckErrors::from(TyCheckError::violate_decl_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
sig.loc(), ident.loc(),
self.caused_by(), self.caused_by(),
name.inspect(), name.inspect(),
&vi.t, &vi.t,
@ -456,8 +459,7 @@ impl Context {
))); )));
} }
} }
let comptime_decos = sig let comptime_decos = decorators
.decorators
.iter() .iter()
.filter_map(|deco| match &deco.0 { .filter_map(|deco| match &deco.0 {
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => { ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
@ -469,7 +471,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
found_t, found_t,
muty, muty,
sig.ident.vis(), ident.vis(),
VarKind::Defined(id), VarKind::Defined(id),
Some(comptime_decos), Some(comptime_decos),
self.impl_of(), self.impl_of(),
@ -481,21 +483,25 @@ impl Context {
Ok(t) 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 // already defined as const
if sig.is_const() { if ident.is_const() {
let vi = self.decls.remove(sig.ident.inspect()).unwrap(); let vi = self.decls.remove(ident.inspect()).unwrap();
self.locals.insert(sig.ident.name.clone(), vi); self.locals.insert(ident.name.clone(), vi);
} }
let muty = if sig.ident.is_const() { let muty = if ident.is_const() {
Mutability::Const Mutability::Const
} else { } else {
Mutability::Immutable Mutability::Immutable
}; };
let name = &sig.ident.name; let name = &ident.name;
self.decls.remove(name); self.decls.remove(name);
let comptime_decos = sig let comptime_decos = decorators
.decorators
.iter() .iter()
.filter_map(|deco| match &deco.0 { .filter_map(|deco| match &deco.0 {
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => { ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
@ -507,7 +513,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
failure_t, failure_t,
muty, muty,
sig.ident.vis(), ident.vis(),
VarKind::DoesNotExist, VarKind::DoesNotExist,
Some(comptime_decos), Some(comptime_decos),
self.impl_of(), self.impl_of(),

View file

@ -12,7 +12,7 @@ use erg_common::{
impl_nested_display_for_enum, impl_stream_for_wrapper, 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 erg_parser::token::{Token, TokenKind};
use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t}; 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)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SubrSignature { pub struct SubrSignature {
pub ident: Identifier, pub ident: Identifier,

View file

@ -759,6 +759,22 @@ impl ASTLowerer {
Ok(hir::Call::new(class, Some(attr_name), args)) 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 /// TODO: varargs
fn lower_lambda(&mut self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> { fn lower_lambda(&mut self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> {
log!(info "entered {}({lambda})", fn_name!()); log!(info "entered {}({lambda})", fn_name!());
@ -775,7 +791,8 @@ impl ASTLowerer {
.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?; .instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
let tv_ctx = TyVarInstContext::new(self.ctx.level, bounds, &self.ctx); let tv_ctx = TyVarInstContext::new(self.ctx.level, bounds, &self.ctx);
self.ctx.grow(&name, kind, Private, Some(tv_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(&params, None) {
self.errs.extend(errs.into_iter()); self.errs.extend(errs.into_iter());
} }
if let Err(errs) = self.ctx.preregister(&lambda.body) { if let Err(errs) = self.ctx.preregister(&lambda.body) {
@ -818,7 +835,7 @@ impl ASTLowerer {
} else { } else {
quant(t, bounds) 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> { fn lower_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
@ -951,7 +968,8 @@ impl ASTLowerer {
.unwrap_or(Type::Failure); .unwrap_or(Type::Failure);
match t { match t {
Type::Subr(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(&params, Some(t.clone())) {
self.errs.extend(errs.into_iter()); self.errs.extend(errs.into_iter());
} }
if let Err(errs) = self.ctx.preregister(&body.block) { if let Err(errs) = self.ctx.preregister(&body.block) {
@ -961,9 +979,9 @@ impl ASTLowerer {
Ok(block) => { Ok(block) => {
let found_body_t = block.ref_t(); let found_body_t = block.ref_t();
let expect_body_t = t.return_t.as_ref(); 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( if let Err(e) = self.return_t_check(
sig.loc(), sig.ident.loc(),
sig.ident.inspect(), sig.ident.inspect(),
expect_body_t, expect_body_t,
found_body_t, found_body_t,
@ -972,20 +990,21 @@ impl ASTLowerer {
} }
} }
let id = body.id; let id = body.id;
let t = let t = self.ctx.outer.as_mut().unwrap().assign_subr(
self.ctx &sig.ident,
.outer &sig.decorators,
.as_mut() id,
.unwrap() found_body_t,
.assign_subr(&sig, id, found_body_t)?; )?;
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name); 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); let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Subr(sig), body)) Ok(hir::Def::new(hir::Signature::Subr(sig), body))
} }
Err(errs) => { Err(errs) => {
self.ctx.outer.as_mut().unwrap().assign_subr( self.ctx.outer.as_mut().unwrap().assign_subr(
&sig, &sig.ident,
&sig.decorators,
ast::DefId(0), ast::DefId(0),
&Type::Failure, &Type::Failure,
)?; )?;
@ -994,20 +1013,21 @@ impl ASTLowerer {
} }
} }
Type::Failure => { 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(&params, None) {
self.errs.extend(errs.into_iter()); self.errs.extend(errs.into_iter());
} }
if let Err(errs) = self.ctx.preregister(&body.block) { if let Err(errs) = self.ctx.preregister(&body.block) {
self.errs.extend(errs.into_iter()); self.errs.extend(errs.into_iter());
} }
self.ctx self.ctx.outer.as_mut().unwrap().fake_subr_assign(
.outer &sig.ident,
.as_mut() &sig.decorators,
.unwrap() Type::Failure,
.fake_subr_assign(&sig, Type::Failure); );
let block = self.lower_block(body.block)?; let block = self.lower_block(body.block)?;
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name); 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); let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Subr(sig), body)) Ok(hir::Def::new(hir::Signature::Subr(sig), body))
} }

View file

@ -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. /// Implementation of `PyCodeObject`, see Include/cpython/code.h in CPython for details.
/// ///
/// 各属性をErg側のObjに変換すると遅くなりそうなので、アクサスされたときのみ変換して提供する /// 各属性をErg側のObjに変換すると遅くなりそうなので、アクサスされたときのみ変換して提供する

View file

@ -2422,7 +2422,7 @@ impl ParamTuplePattern {
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamRecordAttr { pub struct ParamRecordAttr {
pub lhs: Identifier, pub lhs: Identifier,
pub rhs: ParamSignature, pub rhs: NonDefaultParamSignature,
} }
impl NestedDisplay for ParamRecordAttr { impl NestedDisplay for ParamRecordAttr {
@ -2435,7 +2435,7 @@ impl_display_from_nested!(ParamRecordAttr);
impl_locational!(ParamRecordAttr, lhs, rhs); impl_locational!(ParamRecordAttr, lhs, rhs);
impl ParamRecordAttr { impl ParamRecordAttr {
pub const fn new(lhs: Identifier, rhs: ParamSignature) -> Self { pub const fn new(lhs: Identifier, rhs: NonDefaultParamSignature) -> Self {
Self { lhs, rhs } Self { lhs, rhs }
} }
} }
@ -2554,35 +2554,22 @@ impl ParamPattern {
/// Once the default_value is set to Some, all subsequent values must be Some /// Once the default_value is set to Some, all subsequent values must be Some
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamSignature { pub struct NonDefaultParamSignature {
pub pat: ParamPattern, pub pat: ParamPattern,
pub t_spec: Option<TypeSpecWithOp>, 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 { 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),)
write!(
f,
"{}{} := {}",
self.pat,
fmt_option!(self.t_spec),
default_val,
)
} else {
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 { fn loc(&self) -> Location {
if let Some(default) = &self.opt_default_val { if let Some(t_spec) = &self.t_spec {
Location::concat(&self.pat, default)
} else if let Some(t_spec) = &self.t_spec {
Location::concat(&self.pat, t_spec) Location::concat(&self.pat, t_spec)
} else { } else {
self.pat.loc() self.pat.loc()
@ -2590,33 +2577,52 @@ impl Locational for ParamSignature {
} }
} }
impl ParamSignature { impl NonDefaultParamSignature {
pub const fn new( pub const fn new(pat: ParamPattern, t_spec: Option<TypeSpecWithOp>) -> Self {
pat: ParamPattern, Self { pat, t_spec }
t_spec: Option<TypeSpecWithOp>,
opt_default_val: Option<ConstExpr>,
) -> Self {
Self {
pat,
t_spec,
opt_default_val,
}
} }
pub const fn inspect(&self) -> Option<&Str> { pub const fn inspect(&self) -> Option<&Str> {
self.pat.inspect() self.pat.inspect()
} }
}
pub fn has_default(&self) -> bool { /// Once the default_value is set to Some, all subsequent values must be Some
self.opt_default_val.is_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)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Params { pub struct Params {
pub non_defaults: Vec<ParamSignature>, pub non_defaults: Vec<NonDefaultParamSignature>,
pub var_args: Option<Box<ParamSignature>>, pub var_args: Option<Box<NonDefaultParamSignature>>,
pub defaults: Vec<ParamSignature>, pub defaults: Vec<DefaultParamSignature>,
pub parens: Option<(Token, Token)>, pub parens: Option<(Token, Token)>,
} }
@ -2654,17 +2660,17 @@ impl Locational for Params {
} }
type RawParams = ( type RawParams = (
Vec<ParamSignature>, Vec<NonDefaultParamSignature>,
Option<Box<ParamSignature>>, Option<Box<NonDefaultParamSignature>>,
Vec<ParamSignature>, Vec<DefaultParamSignature>,
Option<(Token, Token)>, Option<(Token, Token)>,
); );
impl Params { impl Params {
pub fn new( pub fn new(
non_defaults: Vec<ParamSignature>, non_defaults: Vec<NonDefaultParamSignature>,
var_args: Option<ParamSignature>, var_args: Option<NonDefaultParamSignature>,
defaults: Vec<ParamSignature>, defaults: Vec<DefaultParamSignature>,
parens: Option<(Token, Token)>, parens: Option<(Token, Token)>,
) -> Self { ) -> Self {
Self { Self {

View file

@ -13,8 +13,8 @@ use erg_common::{enum_unwrap, get_hash, log, set};
use crate::ast::{ use crate::ast::{
Accessor, Args, Array, ArrayComprehension, ArrayWithLength, BinOp, Block, Call, DataPack, Def, Accessor, Args, Array, ArrayComprehension, ArrayWithLength, BinOp, Block, Call, DataPack, Def,
DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal,
Methods, Module, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple, ParamPattern, Methods, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet,
ParamSignature, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength, NormalTuple, ParamPattern, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
ShortenedRecord, Signature, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec, ShortenedRecord, Signature, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec,
UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature, UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature,
}; };
@ -255,7 +255,7 @@ impl Desugarer {
name.col_end().unwrap() + 1, // HACK: `(name) %x = ...`という形を想定 name.col_end().unwrap() + 1, // HACK: `(name) %x = ...`という形を想定
)); ));
let param = 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 params = Params::new(vec![param], None, vec![], None);
let sig = Signature::Subr(SubrSignature::new( let sig = Signature::Subr(SubrSignature::new(
set! {}, set! {},

View file

@ -1985,12 +1985,9 @@ impl Parser {
return Err(()); return Err(());
} }
// e.g. (x, y:=1) -> ... // e.g. (x, y:=1) -> ...
// Syntax error will occur when trying to use it as a tuple
PosOrKwArg::Kw(arg) => { PosOrKwArg::Kw(arg) => {
args.push_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, &mut self,
arg: PosArg, arg: PosArg,
allow_self: bool, allow_self: bool,
) -> ParseResult<ParamSignature> { ) -> ParseResult<NonDefaultParamSignature> {
debug_call_info!(self); debug_call_info!(self);
let param = self let param = self
.convert_rhs_to_param(arg.expr, allow_self) .convert_rhs_to_param(arg.expr, allow_self)
@ -2382,7 +2379,7 @@ impl Parser {
&mut self, &mut self,
expr: Expr, expr: Expr,
allow_self: bool, allow_self: bool,
) -> ParseResult<ParamSignature> { ) -> ParseResult<NonDefaultParamSignature> {
debug_call_info!(self); debug_call_info!(self);
match expr { match expr {
Expr::Accessor(Accessor::Ident(ident)) => { Expr::Accessor(Accessor::Ident(ident)) => {
@ -2394,13 +2391,13 @@ impl Parser {
} }
// FIXME deny: public // FIXME deny: public
let pat = ParamPattern::VarName(ident.name); let pat = ParamPattern::VarName(ident.name);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
Expr::Lit(lit) => { Expr::Lit(lit) => {
let pat = ParamPattern::Lit(lit); let pat = ParamPattern::Lit(lit);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2409,7 +2406,7 @@ impl Parser {
.convert_array_to_param_array_pat(array) .convert_array_to_param_array_pat(array)
.map_err(|_| self.stack_dec())?; .map_err(|_| self.stack_dec())?;
let pat = ParamPattern::Array(array_pat); let pat = ParamPattern::Array(array_pat);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2418,7 +2415,7 @@ impl Parser {
.convert_record_to_param_record_pat(record) .convert_record_to_param_record_pat(record)
.map_err(|_| self.stack_dec())?; .map_err(|_| self.stack_dec())?;
let pat = ParamPattern::Record(record_pat); let pat = ParamPattern::Record(record_pat);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2427,7 +2424,7 @@ impl Parser {
.convert_tuple_to_param_tuple_pat(tuple) .convert_tuple_to_param_tuple_pat(tuple)
.map_err(|_| self.stack_dec())?; .map_err(|_| self.stack_dec())?;
let pat = ParamPattern::Tuple(tuple_pat); let pat = ParamPattern::Tuple(tuple_pat);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2444,7 +2441,7 @@ impl Parser {
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_))) let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_)))
.unwrap_or_else(|| todo!()); .unwrap_or_else(|| todo!());
let pat = ParamPattern::Ref(var.name); let pat = ParamPattern::Ref(var.name);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2453,7 +2450,7 @@ impl Parser {
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_))) let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Ident:(_)))
.unwrap_or_else(|| todo!()); .unwrap_or_else(|| todo!());
let pat = ParamPattern::RefMut(var.name); let pat = ParamPattern::RefMut(var.name);
let param = ParamSignature::new(pat, None, None); let param = NonDefaultParamSignature::new(pat, None);
self.level -= 1; self.level -= 1;
Ok(param) 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); debug_call_info!(self);
let pat = ParamPattern::VarName(VarName::new(arg.keyword)); let pat = ParamPattern::VarName(VarName::new(arg.keyword));
let expr = Self::validate_const_expr(arg.expr).map_err(|e| self.errs.push(e))?; let sig = NonDefaultParamSignature::new(pat, arg.t_spec);
let param = ParamSignature::new(pat, arg.t_spec, Some(expr)); let param = DefaultParamSignature::new(sig, arg.expr);
self.level -= 1; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2532,8 +2532,10 @@ impl Parser {
Record::Shortened(rec) => { Record::Shortened(rec) => {
let mut pats = vec![]; let mut pats = vec![];
for ident in rec.idents.into_iter() { for ident in rec.idents.into_iter() {
let rhs = let rhs = NonDefaultParamSignature::new(
ParamSignature::new(ParamPattern::VarName(ident.name.clone()), None, None); ParamPattern::VarName(ident.name.clone()),
None,
);
pats.push(ParamRecordAttr::new(ident.clone(), rhs)); pats.push(ParamRecordAttr::new(ident.clone(), rhs));
} }
let attrs = ParamRecordAttrs::new(pats); let attrs = ParamRecordAttrs::new(pats);
@ -2563,13 +2565,13 @@ impl Parser {
&mut self, &mut self,
tasc: TypeAscription, tasc: TypeAscription,
allow_self: bool, allow_self: bool,
) -> ParseResult<ParamSignature> { ) -> ParseResult<NonDefaultParamSignature> {
debug_call_info!(self); debug_call_info!(self);
let param = self let param = self
.convert_rhs_to_param(*tasc.expr, allow_self) .convert_rhs_to_param(*tasc.expr, allow_self)
.map_err(|_| self.stack_dec())?; .map_err(|_| self.stack_dec())?;
let t_spec = TypeSpecWithOp::new(tasc.op, tasc.t_spec); 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; self.level -= 1;
Ok(param) Ok(param)
} }
@ -2596,7 +2598,7 @@ impl Parser {
let arr = self let arr = self
.convert_array_to_param_array_pat(array) .convert_array_to_param_array_pat(array)
.map_err(|_| self.stack_dec())?; .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); let params = Params::new(vec![param], None, vec![], None);
self.level -= 1; self.level -= 1;
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty())) Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty()))
@ -2605,7 +2607,7 @@ impl Parser {
let rec = self let rec = self
.convert_record_to_param_record_pat(record) .convert_record_to_param_record_pat(record)
.map_err(|_| self.stack_dec())?; .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); let params = Params::new(vec![param], None, vec![], None);
self.level -= 1; self.level -= 1;
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty())) 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); debug_call_info!(self);
match accessor { match accessor {
Accessor::Ident(ident) => { Accessor::Ident(ident) => {
@ -2636,7 +2641,7 @@ impl Parser {
ParamPattern::VarName(ident.name) ParamPattern::VarName(ident.name)
}; };
self.level -= 1; self.level -= 1;
Ok(ParamSignature::new(pat, None, None)) Ok(NonDefaultParamSignature::new(pat, None))
} }
other => { other => {
self.level -= 1; self.level -= 1;
@ -2806,7 +2811,7 @@ impl Parser {
}); });
let mut defaults = vec![]; let mut defaults = vec![];
for param in lambda.sig.params.defaults.into_iter() { 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)) => { (ParamPattern::VarName(name), Some(t_spec_with_op)) => {
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
} }