Fix lower bugs

This commit is contained in:
Shunsuke Shibayama 2022-09-21 11:22:18 +09:00
parent 201b313cd2
commit c1d92bc0f4
5 changed files with 48 additions and 41 deletions

View file

@ -8,6 +8,7 @@ use crate::error::{CompileError, CompileErrors, TyCheckErrors};
// use crate::hir::HIR;
use crate::check::Checker;
use crate::mod_cache::SharedModuleCache;
use crate::reorder::Reorderer;
#[derive(Debug)]
pub struct HIRBuilder {
@ -33,6 +34,9 @@ impl HIRBuilder {
pub fn build_and_cache(&mut self, var_name: VarName) -> Result<(), CompileErrors> {
let mut ast_builder = ASTBuilder::new(self.checker.cfg.copy());
let ast = ast_builder.build()?;
let ast = Reorderer::new()
.reorder(ast)
.map_err(|errs| self.convert(errs))?;
let (hir, ctx) = self
.checker
.check(ast, "exec")
@ -46,6 +50,9 @@ impl HIRBuilder {
cfg.input = Input::Str(src);
let mut ast_builder = ASTBuilder::new(cfg);
let ast = ast_builder.build()?;
let ast = Reorderer::new()
.reorder(ast)
.map_err(|errs| self.convert(errs))?;
let (hir, ctx) = self
.checker
.check(ast, mode)

View file

@ -128,20 +128,20 @@ impl Context {
body_t: &Type,
id: DefId,
) -> TyCheckResult<()> {
// already defined as const
if sig.is_const() {
return Ok(());
}
let ident = match &sig.pat {
ast::VarPattern::Ident(ident) => ident,
_ => todo!(),
};
// already defined as const
if sig.is_const() {
let vi = self.decls.remove(ident.inspect()).unwrap();
self.locals.insert(ident.name.clone(), vi);
return Ok(());
}
self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?;
let muty = Mutability::from(&ident.inspect()[..]);
let generalized = self.generalize_t(body_t.clone());
if self.decls.remove(ident.inspect()).is_some() {
// something to do?
}
self.decls.remove(ident.inspect());
let vis = ident.vis();
let vi = VarInfo::new(generalized, muty, vis, VarKind::Defined(id), None);
self.locals.insert(ident.name.clone(), vi);
@ -352,6 +352,8 @@ impl Context {
) -> TyCheckResult<()> {
// 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);
return Ok(());
}
let muty = if sig.ident.is_const() {

View file

@ -18,4 +18,5 @@ pub mod mod_cache;
// pub mod name_resolve;
pub mod optimize;
pub mod ownercheck;
pub mod reorder;
pub mod varinfo;

View file

@ -536,34 +536,28 @@ impl ASTLowerer {
fn lower_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
log!(info "entered {}({})", fn_name!(), def.sig);
if def.body.block.len() >= 1 {
let name = if let Some(name) = def.sig.name_as_str() {
name
} else {
"<lambda>"
};
if self.ctx.registered_info(name, def.sig.is_const()).is_some() {
return Err(LowerError::reassign_error(
line!() as usize,
def.sig.loc(),
self.ctx.caused_by(),
name,
));
}
let kind = ContextKind::from(def.def_kind());
self.ctx.grow(name, kind, def.sig.vis())?;
let res = match def.sig {
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
ast::Signature::Var(sig) => self.lower_var_def(sig, def.body),
};
// TODO: Context上の関数に型境界情報を追加
self.pop_append_errs();
return res;
let name = if let Some(name) = def.sig.name_as_str() {
name
} else {
"<lambda>"
};
if self.ctx.registered_info(name, def.sig.is_const()).is_some() {
return Err(LowerError::reassign_error(
line!() as usize,
def.sig.loc(),
self.ctx.caused_by(),
name,
));
}
match def.sig {
let kind = ContextKind::from(def.def_kind());
self.ctx.grow(name, kind, def.sig.vis())?;
let res = match def.sig {
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
ast::Signature::Var(sig) => self.lower_var_def(sig, def.body),
}
};
// TODO: Context上の関数に型境界情報を追加
self.pop_append_errs();
res
}
fn lower_var_def(

View file

@ -3,8 +3,9 @@ use erg_common::log;
use erg_common::traits::{Locational, Stream};
use erg_common::Str;
use crate::ast::{ClassDef, Expr, Methods, Module, PreDeclTypeSpec, TypeSpec, AST};
use crate::error::{ParseError, ParseErrors};
use erg_parser::ast::{ClassDef, Expr, Methods, Module, PreDeclTypeSpec, TypeSpec, AST};
use crate::error::{TyCheckError, TyCheckErrors};
/// Combine method definitions across multiple modules, specialized class contexts, etc.
#[derive(Debug, Default)]
@ -12,7 +13,7 @@ pub struct Reorderer {
// TODO: inner scope types
pub def_root_pos_map: Dict<Str, usize>,
pub deps: Dict<Str, Vec<Str>>,
pub errs: ParseErrors,
pub errs: TyCheckErrors,
}
impl Reorderer {
@ -20,11 +21,11 @@ impl Reorderer {
Self {
def_root_pos_map: Dict::new(),
deps: Dict::new(),
errs: ParseErrors::empty(),
errs: TyCheckErrors::empty(),
}
}
pub fn reorder(mut self, mut ast: AST) -> Result<AST, ParseErrors> {
pub fn reorder(mut self, mut ast: AST) -> Result<AST, TyCheckErrors> {
log!(info "the reordering process has started.");
let mut new = vec![];
while let Some(chunk) = ast.module.lpop() {
@ -65,11 +66,12 @@ impl Reorderer {
.def_root_pos_map
.keys()
.fold("".to_string(), |acc, key| acc + &key[..] + ",");
self.errs.push(ParseError::no_var_error(
self.errs.push(TyCheckError::no_var_error(
line!() as usize,
methods.class.loc(),
"".into(),
&methods.class.to_string(),
Some(similar_name),
Some(&Str::from(similar_name)),
));
}
}
@ -102,11 +104,12 @@ impl Reorderer {
.def_root_pos_map
.keys()
.fold("".to_string(), |acc, key| acc + &key[..] + ",");
self.errs.push(ParseError::no_var_error(
self.errs.push(TyCheckError::no_var_error(
line!() as usize,
methods.class.loc(),
"".into(),
&name,
Some(similar_name),
Some(&Str::from(similar_name)),
));
}
}