This commit is contained in:
Shunsuke Shibayama 2022-09-11 23:19:48 +09:00
parent fad62f6fa3
commit c0742005ee
3 changed files with 74 additions and 84 deletions

View file

@ -25,11 +25,11 @@ use Visibility::*;
impl Context { impl Context {
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes /// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
fn registered(&self, name: &Str, is_const: bool) -> bool { pub(crate) fn registered(&self, name: &str, is_const: bool) -> bool {
if self.params.iter().any(|(maybe_name, _)| { if self.params.iter().any(|(maybe_name, _)| {
maybe_name maybe_name
.as_ref() .as_ref()
.map(|n| n.inspect() == name) .map(|n| &n.inspect()[..] == name)
.unwrap_or(false) .unwrap_or(false)
}) || self.locals.contains_key(name) }) || self.locals.contains_key(name)
{ {
@ -87,7 +87,7 @@ impl Context {
let muty = Mutability::from(&name[..]); let muty = Mutability::from(&name[..]);
let kind = id.map_or(VarKind::Declared, VarKind::Defined); let kind = id.map_or(VarKind::Declared, VarKind::Defined);
if self.registered(name, sig.is_const()) { if self.registered(name, sig.is_const()) {
return Err(TyCheckError::duplicate_decl_error( return Err(TyCheckError::reassign_error(
line!() as usize, line!() as usize,
sig.loc(), sig.loc(),
self.caused_by(), self.caused_by(),
@ -136,14 +136,6 @@ impl Context {
self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?; self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?;
let muty = Mutability::from(&ident.inspect()[..]); let muty = Mutability::from(&ident.inspect()[..]);
let generalized = self.generalize_t(body_t.clone()); let generalized = self.generalize_t(body_t.clone());
if self.registered(ident.inspect(), ident.is_const()) {
Err(TyCheckError::reassign_error(
line!() as usize,
ident.loc(),
self.caused_by(),
ident.inspect(),
))
} else {
if self.decls.remove(ident.inspect()).is_some() { if self.decls.remove(ident.inspect()).is_some() {
// something to do? // something to do?
} }
@ -152,7 +144,6 @@ impl Context {
self.locals.insert(ident.name.clone(), vi); self.locals.insert(ident.name.clone(), vi);
Ok(()) Ok(())
} }
}
/// 宣言が既にある場合、opt_decl_tに宣言の型を渡す /// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
fn assign_param( fn assign_param(
@ -370,14 +361,6 @@ impl Context {
) )
})?; })?;
} }
if self.registered(name.inspect(), name.is_const()) {
Err(TyCheckError::reassign_error(
line!() as usize,
name.loc(),
self.caused_by(),
name.inspect(),
))
} else {
let sub_t = if sig.ident.is_procedural() { let sub_t = if sig.ident.is_procedural() {
proc( proc(
non_default_params.clone(), non_default_params.clone(),
@ -435,7 +418,6 @@ impl Context {
self.locals.insert(name.clone(), vi); self.locals.insert(name.clone(), vi);
Ok(()) Ok(())
} }
}
// To allow forward references and recursive definitions // To allow forward references and recursive definitions
pub(crate) fn preregister(&mut self, block: &ast::Block) -> TyCheckResult<()> { pub(crate) fn preregister(&mut self, block: &ast::Block) -> TyCheckResult<()> {

View file

@ -685,10 +685,10 @@ impl TyCheckError {
AssignError, AssignError,
loc, loc,
switch_lang!( switch_lang!(
"japanese" => format!("変数{name}に再代入されています"), "japanese" => format!("変数{YELLOW}{name}{RESET}に再代入されています"),
"simplified_chinese" => format!("不能为变量{name}分配两次"), "simplified_chinese" => format!("不能为变量{YELLOW}{name}{RESET}分配两次"),
"traditional_chinese" => format!("不能為變量{name}分配兩次"), "traditional_chinese" => format!("不能為變量{YELLOW}{name}{RESET}分配兩次"),
"english" => format!("cannot assign twice to the variable {name}"), "english" => format!("cannot assign twice to the variable {YELLOW}{name}{RESET}"),
), ),
None, None,
), ),

View file

@ -577,6 +577,14 @@ impl ASTLowerer {
} else { } else {
"<lambda>" "<lambda>"
}; };
if self.ctx.registered(name, def.sig.is_const()) {
return Err(LowerError::reassign_error(
line!() as usize,
def.sig.loc(),
self.ctx.caused_by(),
name,
));
}
self.ctx.grow(name, ContextKind::Instant, def.sig.vis())?; self.ctx.grow(name, ContextKind::Instant, def.sig.vis())?;
let res = match def.sig { let res = match def.sig {
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body), ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),