mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
Merge branch 'main' into rwlock
This commit is contained in:
parent
8c983c3714
commit
0d3691f243
143 changed files with 4781 additions and 3289 deletions
|
@ -8,7 +8,7 @@ use erg_common::consts::{ERG_MODE, PYTHON_MODE};
|
|||
use erg_common::dict;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::{Location, MultiErrorDisplay};
|
||||
use erg_common::fresh::fresh_varname;
|
||||
use erg_common::fresh::FreshNameGenerator;
|
||||
use erg_common::set;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{ExitStatus, Locational, NoTypeDisplay, Runnable, Stream};
|
||||
|
@ -37,8 +37,8 @@ use crate::context::{
|
|||
RegistrationMode, TraitImpl,
|
||||
};
|
||||
use crate::error::{
|
||||
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarning, LowerWarnings,
|
||||
SingleLowerResult,
|
||||
CompileError, CompileErrors, CompileWarning, LowerError, LowerErrors, LowerResult,
|
||||
LowerWarning, LowerWarnings, SingleLowerResult,
|
||||
};
|
||||
use crate::hir;
|
||||
use crate::hir::HIR;
|
||||
|
@ -75,6 +75,7 @@ pub struct ASTLowerer {
|
|||
pub(crate) module: ModuleContext,
|
||||
pub(crate) errs: LowerErrors,
|
||||
pub(crate) warns: LowerWarnings,
|
||||
fresh_gen: FreshNameGenerator,
|
||||
}
|
||||
|
||||
impl Default for ASTLowerer {
|
||||
|
@ -125,22 +126,27 @@ impl Runnable for ASTLowerer {
|
|||
|
||||
fn exec(&mut self) -> Result<ExitStatus, Self::Errs> {
|
||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||
let ast = ast_builder.build(self.cfg.input.read())?;
|
||||
let artifact = self
|
||||
.lower(ast, "exec")
|
||||
let artifact = ast_builder
|
||||
.build(self.cfg.input.read())
|
||||
.map_err(|artifact| artifact.errors)?;
|
||||
artifact.warns.fmt_all_stderr();
|
||||
println!("{}", artifact.object);
|
||||
artifact.warns.write_all_to(&mut self.cfg.output);
|
||||
let artifact = self
|
||||
.lower(artifact.ast, "exec")
|
||||
.map_err(|artifact| artifact.errors)?;
|
||||
artifact.warns.write_all_to(&mut self.cfg.output);
|
||||
use std::io::Write;
|
||||
write!(self.cfg.output, "{}", artifact.object).unwrap();
|
||||
Ok(ExitStatus::compile_passed(artifact.warns.len()))
|
||||
}
|
||||
|
||||
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||
let ast = ast_builder.build(src)?;
|
||||
let artifact = ast_builder.build(src).map_err(|artifact| artifact.errors)?;
|
||||
artifact.warns.write_all_stderr();
|
||||
let artifact = self
|
||||
.lower(ast, "eval")
|
||||
.lower(artifact.ast, "eval")
|
||||
.map_err(|artifact| artifact.errors)?;
|
||||
artifact.warns.fmt_all_stderr();
|
||||
artifact.warns.write_all_stderr();
|
||||
Ok(format!("{}", artifact.object))
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +178,7 @@ impl ASTLowerer {
|
|||
cfg,
|
||||
errs: LowerErrors::empty(),
|
||||
warns: LowerWarnings::empty(),
|
||||
fresh_gen: FreshNameGenerator::new("lower"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,17 +188,16 @@ impl ASTLowerer {
|
|||
module,
|
||||
errs: LowerErrors::empty(),
|
||||
warns: LowerWarnings::empty(),
|
||||
fresh_gen: FreshNameGenerator::new("lower"),
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_append_errs(&mut self) {
|
||||
match self.module.context.check_decls_and_pop() {
|
||||
Ok(ctx) if self.cfg.mode == ErgMode::LanguageServer && !ctx.dir().is_empty() => {
|
||||
self.module.scope.insert(ctx.name.clone(), ctx);
|
||||
}
|
||||
Err(errs) => self.errs.extend(errs),
|
||||
_ => {}
|
||||
let (ctx, errs) = self.module.context.check_decls_and_pop();
|
||||
if self.cfg.mode == ErgMode::LanguageServer && !ctx.dir().is_empty() {
|
||||
self.module.scope.insert(ctx.name.clone(), ctx);
|
||||
}
|
||||
self.errs.extend(errs);
|
||||
}
|
||||
|
||||
pub fn pop_mod_ctx(&mut self) -> Option<ModuleContext> {
|
||||
|
@ -751,7 +757,7 @@ impl ASTLowerer {
|
|||
TokenKind::Gre => {
|
||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||
let t = value.class();
|
||||
let varname = Str::from(fresh_varname());
|
||||
let varname = self.fresh_gen.fresh_varname();
|
||||
let pred = Predicate::gt(varname.clone(), TyParam::value(value));
|
||||
let refine = refinement(varname, t, pred);
|
||||
Some(guard(var, refine))
|
||||
|
@ -759,7 +765,7 @@ impl ASTLowerer {
|
|||
TokenKind::GreEq => {
|
||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||
let t = value.class();
|
||||
let varname = Str::from(fresh_varname());
|
||||
let varname = self.fresh_gen.fresh_varname();
|
||||
let pred = Predicate::ge(varname.clone(), TyParam::value(value));
|
||||
let refine = refinement(varname, t, pred);
|
||||
Some(guard(var, refine))
|
||||
|
@ -767,7 +773,7 @@ impl ASTLowerer {
|
|||
TokenKind::Less => {
|
||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||
let t = value.class();
|
||||
let varname = Str::from(fresh_varname());
|
||||
let varname = self.fresh_gen.fresh_varname();
|
||||
let pred = Predicate::lt(varname.clone(), TyParam::value(value));
|
||||
let refine = refinement(varname, t, pred);
|
||||
Some(guard(var, refine))
|
||||
|
@ -775,7 +781,7 @@ impl ASTLowerer {
|
|||
TokenKind::LessEq => {
|
||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||
let t = value.class();
|
||||
let varname = Str::from(fresh_varname());
|
||||
let varname = self.fresh_gen.fresh_varname();
|
||||
let pred = Predicate::le(varname.clone(), TyParam::value(value));
|
||||
let refine = refinement(varname, t, pred);
|
||||
Some(guard(var, refine))
|
||||
|
@ -1549,8 +1555,14 @@ impl ASTLowerer {
|
|||
}
|
||||
};
|
||||
let ident = hir::Identifier::new(sig.ident, None, vi);
|
||||
let sig =
|
||||
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
|
||||
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
|
||||
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
|
||||
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
|
||||
}
|
||||
|
@ -1569,8 +1581,14 @@ impl ASTLowerer {
|
|||
}
|
||||
};
|
||||
let ident = hir::Identifier::new(sig.ident, None, vi);
|
||||
let sig =
|
||||
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
|
||||
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
|
||||
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
|
||||
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
|
||||
let block =
|
||||
hir::Block::new(vec![hir::Expr::Dummy(hir::Dummy::new(vec![]))]);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
|
@ -1594,7 +1612,14 @@ impl ASTLowerer {
|
|||
.fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?;
|
||||
let block = self.lower_block(body.block)?;
|
||||
let ident = hir::Identifier::bare(sig.ident);
|
||||
let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
|
||||
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
|
||||
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
|
||||
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
|
||||
}
|
||||
|
@ -1644,6 +1669,23 @@ impl ASTLowerer {
|
|||
self.pop_append_errs();
|
||||
errs
|
||||
})?;
|
||||
if let Some(ident) = def.sig.ident() {
|
||||
if self
|
||||
.module
|
||||
.context
|
||||
.get_instance_attr(ident.inspect())
|
||||
.is_some()
|
||||
{
|
||||
self.warns
|
||||
.push(CompileWarning::same_name_instance_attr_warning(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.module.context.caused_by(),
|
||||
ident.inspect(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ClassAttr::Decl(_) | ast::ClassAttr::Doc(_) => {}
|
||||
}
|
||||
|
@ -1711,21 +1753,19 @@ impl ASTLowerer {
|
|||
if let Some(sup_type) = call.args.get_left_or_key("Super") {
|
||||
Self::check_inheritable(&self.cfg, &mut self.errs, type_obj, sup_type, &hir_def.sig);
|
||||
}
|
||||
let (__new__, need_to_gen_new) = if let (Some(dunder_new_vi), Some(new_vi)) = (
|
||||
class_ctx.get_current_scope_var(&VarName::from_static("__new__")),
|
||||
class_ctx.get_current_scope_var(&VarName::from_static("new")),
|
||||
) {
|
||||
(dunder_new_vi.t.clone(), new_vi.kind == VarKind::Auto)
|
||||
} else {
|
||||
let Some(__new__) = class_ctx.get_current_scope_var(&VarName::from_static("__new__")).or(class_ctx.get_current_scope_var(&VarName::from_static("__call__"))) else {
|
||||
return unreachable_error!(LowerErrors, LowerError, self);
|
||||
};
|
||||
let need_to_gen_new = class_ctx
|
||||
.get_current_scope_var(&VarName::from_static("new"))
|
||||
.map_or(false, |vi| vi.kind == VarKind::Auto);
|
||||
let require_or_sup = Self::get_require_or_sup_or_base(hir_def.body.block.remove(0));
|
||||
Ok(hir::ClassDef::new(
|
||||
type_obj.clone(),
|
||||
hir_def.sig,
|
||||
require_or_sup,
|
||||
need_to_gen_new,
|
||||
__new__,
|
||||
__new__.t.clone(),
|
||||
hir_methods,
|
||||
))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue