mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-27 11:59:05 +00:00
fix: bugs with enumeration of vars
This commit is contained in:
parent
b1a9f7bf40
commit
fa2919e824
15 changed files with 107 additions and 94 deletions
|
@ -1,4 +1,5 @@
|
|||
use erg_common::config::ErgConfig;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::traits::{Runnable, Stream};
|
||||
use erg_common::Str;
|
||||
|
@ -100,7 +101,7 @@ impl Buildable for HIRBuilder {
|
|||
impl BuildRunnable for HIRBuilder {}
|
||||
|
||||
impl ContextProvider for HIRBuilder {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
self.lowerer.dir()
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ impl HIRBuilder {
|
|||
self.lowerer.pop_mod_ctx()
|
||||
}
|
||||
|
||||
pub fn dir(&mut self) -> Vec<(&VarName, &VarInfo)> {
|
||||
pub fn dir(&mut self) -> Dict<&VarName, &VarInfo> {
|
||||
ContextProvider::dir(self)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
use std::path::Path;
|
||||
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::log;
|
||||
use erg_common::traits::{Runnable, Stream};
|
||||
use erg_parser::ast::VarName;
|
||||
|
||||
use crate::artifact::{CompleteArtifact, ErrorArtifact};
|
||||
use crate::context::ContextProvider;
|
||||
use crate::context::{Context, ContextProvider};
|
||||
use crate::ty::codeobj::CodeObj;
|
||||
|
||||
use crate::build_hir::HIRBuilder;
|
||||
|
@ -19,6 +21,7 @@ use crate::error::{CompileError, CompileErrors, CompileWarnings};
|
|||
use crate::hir::Expr;
|
||||
use crate::link::Linker;
|
||||
use crate::module::{SharedCompilerResource, SharedModuleCache};
|
||||
use crate::varinfo::VarInfo;
|
||||
|
||||
/// * registered as global -> Global
|
||||
/// * defined in the toplevel scope (and called in the inner scope) -> Global
|
||||
|
@ -169,12 +172,8 @@ impl Runnable for Compiler {
|
|||
}
|
||||
}
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::varinfo::VarInfo;
|
||||
use erg_parser::ast::VarName;
|
||||
|
||||
impl ContextProvider for Compiler {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
self.builder.dir()
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,6 @@ impl Context {
|
|||
| (Float | Ratio | Int, Int)
|
||||
| (Float | Ratio, Ratio) => (Absolutely, true),
|
||||
(Type, ClassType | TraitType) => (Absolutely, true),
|
||||
(Uninited, _) | (_, Uninited) => panic!("used an uninited type variable"),
|
||||
(
|
||||
Mono(n),
|
||||
Subr(SubrType {
|
||||
|
@ -542,6 +541,7 @@ impl Context {
|
|||
let nat = Type::Refinement(Nat.into_refinement());
|
||||
self.structural_supertype_of(re, &nat)
|
||||
}
|
||||
(Structural(_), Refinement(refine)) => self.supertype_of(lhs, &refine.t),
|
||||
// Int :> {I: Int | ...} == true
|
||||
// Int :> {I: Str| ...} == false
|
||||
// Eq({1, 2}) :> {1, 2} (= {I: Int | I == 1 or I == 2})
|
||||
|
@ -694,7 +694,6 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: we need consider duplicating keys
|
||||
pub fn fields(&self, t: &Type) -> Dict<Field, Type> {
|
||||
match t {
|
||||
Type::FreeVar(fv) if fv.is_linked() => self.fields(&fv.crack()),
|
||||
|
@ -702,10 +701,10 @@ impl Context {
|
|||
Type::Refinement(refine) => self.fields(&refine.t),
|
||||
Type::Structural(t) => self.fields(t),
|
||||
other => {
|
||||
let (_, ctx) = self
|
||||
.get_nominal_type_ctx(other)
|
||||
.unwrap_or_else(|| panic!("{other} is not found"));
|
||||
ctx.type_dir()
|
||||
let Some((_, ctx)) = self.get_nominal_type_ctx(other) else {
|
||||
return Dict::new();
|
||||
};
|
||||
ctx.type_dir(self)
|
||||
.into_iter()
|
||||
.map(|(name, vi)| {
|
||||
(
|
||||
|
@ -993,7 +992,7 @@ impl Context {
|
|||
// not {i = Int} and {i = Int; j = Int} == {j = Int}
|
||||
(other @ Record(rec), Not(t)) | (Not(t), other @ Record(rec)) => match t.as_ref() {
|
||||
Type::FreeVar(fv) => self.intersection(&fv.crack(), other),
|
||||
Type::Record(rec2) => Type::Record(rec.clone().diff(rec2.clone())),
|
||||
Type::Record(rec2) => Type::Record(rec.clone().diff(rec2)),
|
||||
_ => Type::Never,
|
||||
},
|
||||
(l, r) if self.is_trait(l) && self.is_trait(r) => and(l.clone(), r.clone()),
|
||||
|
|
|
@ -85,20 +85,8 @@ impl Context {
|
|||
Visibility::BUILTIN_PUBLIC,
|
||||
ValueObj::Float(2.220446049250313e-16),
|
||||
);
|
||||
float.register_builtin_py_impl(
|
||||
REAL,
|
||||
Float,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_REAL),
|
||||
);
|
||||
float.register_builtin_py_impl(
|
||||
IMAG,
|
||||
Float,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_IMAG),
|
||||
);
|
||||
float.register_builtin_py_impl(REAL, Float, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||
float.register_builtin_py_impl(IMAG, Float, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||
float.register_py_builtin(
|
||||
FUNC_AS_INTEGER_RATIO,
|
||||
fn0_met(Float, tuple_t(vec![Int, Int])),
|
||||
|
@ -124,6 +112,10 @@ impl Context {
|
|||
Some(FUNC_FROMHEX),
|
||||
53,
|
||||
);
|
||||
float.register_py_builtin(OP_GT, fn1_met(Float, Float, Bool), Some(OP_GT), 0);
|
||||
float.register_py_builtin(OP_GE, fn1_met(Float, Float, Bool), Some(OP_GE), 0);
|
||||
float.register_py_builtin(OP_LT, fn1_met(Float, Float, Bool), Some(OP_LT), 0);
|
||||
float.register_py_builtin(OP_LE, fn1_met(Float, Float, Bool), Some(OP_LE), 0);
|
||||
float.register_marker_trait(mono(NUM));
|
||||
float.register_marker_trait(mono(ORD));
|
||||
let mut float_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
||||
|
@ -250,20 +242,8 @@ impl Context {
|
|||
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
|
||||
let mut ratio = Self::builtin_mono_class(RATIO, 2);
|
||||
ratio.register_superclass(Obj, &obj);
|
||||
ratio.register_builtin_py_impl(
|
||||
REAL,
|
||||
Ratio,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_REAL),
|
||||
);
|
||||
ratio.register_builtin_py_impl(
|
||||
IMAG,
|
||||
Ratio,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_IMAG),
|
||||
);
|
||||
ratio.register_builtin_py_impl(REAL, Ratio, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||
ratio.register_builtin_py_impl(IMAG, Ratio, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||
ratio.register_marker_trait(mono(NUM));
|
||||
ratio.register_marker_trait(mono(ORD));
|
||||
let mut ratio_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
||||
|
@ -513,20 +493,8 @@ impl Context {
|
|||
Some(FUNDAMENTAL_STR),
|
||||
);
|
||||
int.register_trait(Int, int_show);
|
||||
int.register_builtin_py_impl(
|
||||
REAL,
|
||||
Int,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_REAL),
|
||||
);
|
||||
int.register_builtin_py_impl(
|
||||
IMAG,
|
||||
Int,
|
||||
Const,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_IMAG),
|
||||
);
|
||||
int.register_builtin_py_impl(REAL, Int, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||
int.register_builtin_py_impl(IMAG, Int, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||
|
||||
/* Nat */
|
||||
let mut nat = Self::builtin_mono_class(NAT, 10);
|
||||
|
|
|
@ -100,10 +100,8 @@ const BYTES: &str = "Bytes";
|
|||
const FLOAT: &str = "Float";
|
||||
const MUT_FLOAT: &str = "Float!";
|
||||
const EPSILON: &str = "EPSILON";
|
||||
const REAL: &str = "Real";
|
||||
const FUNC_REAL: &str = "real";
|
||||
const IMAG: &str = "Imag";
|
||||
const FUNC_IMAG: &str = "imag";
|
||||
const REAL: &str = "real";
|
||||
const IMAG: &str = "imag";
|
||||
const FUNC_AS_INTEGER_RATIO: &str = "as_integer_ratio";
|
||||
const FUNC_CONJUGATE: &str = "conjugate";
|
||||
const FUNC_IS_INTEGER: &str = "is_integer";
|
||||
|
|
|
@ -396,6 +396,25 @@ impl Context {
|
|||
mode: RegistrationMode,
|
||||
kind: ParamKind,
|
||||
) -> TyCheckResult<ParamTy> {
|
||||
if let Some(value) = sig
|
||||
.name()
|
||||
.and_then(|name| self.get_const_local(name.token(), &self.name).ok())
|
||||
{
|
||||
return Ok(ParamTy::pos(None, v_enum(set! { value })));
|
||||
} else if let Some(tp) = sig.name().and_then(|name| {
|
||||
self.instantiate_local(name.inspect(), None, tmp_tv_cache, sig)
|
||||
.ok()
|
||||
}) {
|
||||
match tp {
|
||||
TyParam::Type(t) => return Ok(ParamTy::pos(None, *t)),
|
||||
other => {
|
||||
return Ok(ParamTy::pos(
|
||||
None,
|
||||
tp_enum(self.get_tp_t(&other)?, set! { other }),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_cache, mode, kind.clone())?;
|
||||
match (sig.inspect(), kind) {
|
||||
(Some(name), ParamKind::Default(default_t)) => {
|
||||
|
|
|
@ -43,7 +43,7 @@ use Type::*;
|
|||
|
||||
/// For implementing LSP or other IDE features
|
||||
pub trait ContextProvider {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)>;
|
||||
fn dir(&self) -> Dict<&VarName, &VarInfo>;
|
||||
fn get_receiver_ctx(&self, receiver_name: &str) -> Option<&Context>;
|
||||
fn get_var_info(&self, name: &str) -> Option<(&VarName, &VarInfo)>;
|
||||
}
|
||||
|
@ -411,12 +411,12 @@ impl fmt::Display for Context {
|
|||
}
|
||||
|
||||
impl ContextProvider for Context {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
let mut vars = self.type_dir();
|
||||
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
let mut vars = self.type_dir(self);
|
||||
if let Some(outer) = self.get_outer() {
|
||||
vars.extend(outer.dir());
|
||||
vars.guaranteed_extend(outer.dir());
|
||||
} else if let Some(builtins) = self.get_builtins() {
|
||||
vars.extend(builtins.locals.iter());
|
||||
vars.guaranteed_extend(builtins.locals.iter());
|
||||
}
|
||||
vars
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ impl ContextProvider for Context {
|
|||
}
|
||||
|
||||
impl Context {
|
||||
pub fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
pub fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
ContextProvider::dir(self)
|
||||
}
|
||||
|
||||
|
@ -1013,24 +1013,25 @@ impl Context {
|
|||
}
|
||||
|
||||
/// enumerates all the variables/methods in the current context & super contexts.
|
||||
fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
let mut vars: Vec<_> = self
|
||||
.locals
|
||||
.iter()
|
||||
.chain(self.decls.iter())
|
||||
.chain(
|
||||
self.params
|
||||
.iter()
|
||||
.filter_map(|(k, v)| k.as_ref().map(|k| (k, v))),
|
||||
)
|
||||
.chain(self.methods_list.iter().flat_map(|(_, ctx)| ctx.type_dir()))
|
||||
.collect();
|
||||
fn type_dir<'t>(&'t self, namespace: &'t Context) -> Dict<&VarName, &VarInfo> {
|
||||
let mut attrs = self.locals.iter().collect::<Dict<_, _>>();
|
||||
attrs.guaranteed_extend(
|
||||
self.params
|
||||
.iter()
|
||||
.filter_map(|(k, v)| k.as_ref().map(|k| (k, v))),
|
||||
);
|
||||
attrs.guaranteed_extend(self.decls.iter());
|
||||
attrs.guaranteed_extend(
|
||||
self.methods_list
|
||||
.iter()
|
||||
.flat_map(|(_, ctx)| ctx.type_dir(namespace)),
|
||||
);
|
||||
for sup in self.super_classes.iter() {
|
||||
if let Some((_, sup_ctx)) = self.get_nominal_type_ctx(sup) {
|
||||
vars.extend(sup_ctx.type_dir());
|
||||
if let Some((_, sup_ctx)) = namespace.get_nominal_type_ctx(sup) {
|
||||
attrs.guaranteed_extend(sup_ctx.type_dir(namespace));
|
||||
}
|
||||
}
|
||||
vars
|
||||
attrs
|
||||
}
|
||||
|
||||
pub(crate) fn mod_cache(&self) -> &SharedModuleCache {
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::mem;
|
|||
|
||||
use erg_common::config::{ErgConfig, ErgMode};
|
||||
use erg_common::dict;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::{Location, MultiErrorDisplay};
|
||||
use erg_common::set;
|
||||
use erg_common::set::Set;
|
||||
|
@ -124,7 +125,7 @@ impl Runnable for ASTLowerer {
|
|||
}
|
||||
|
||||
impl ContextProvider for ASTLowerer {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
self.module.context.dir()
|
||||
}
|
||||
|
||||
|
@ -176,7 +177,7 @@ impl ASTLowerer {
|
|||
&self.module
|
||||
}
|
||||
|
||||
pub fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
pub fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||
ContextProvider::dir(self)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::fs::File;
|
|||
use std::io::Write;
|
||||
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::dict::Dict as HashMap;
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::log;
|
||||
use erg_common::traits::{Runnable, Stream};
|
||||
|
@ -167,7 +168,7 @@ impl Runnable for Transpiler {
|
|||
}
|
||||
|
||||
impl ContextProvider for Transpiler {
|
||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
fn dir(&self) -> HashMap<&VarName, &VarInfo> {
|
||||
self.builder.dir()
|
||||
}
|
||||
|
||||
|
@ -238,7 +239,7 @@ impl Transpiler {
|
|||
self.builder.pop_mod_ctx()
|
||||
}
|
||||
|
||||
pub fn dir(&mut self) -> Vec<(&VarName, &VarInfo)> {
|
||||
pub fn dir(&mut self) -> HashMap<&VarName, &VarInfo> {
|
||||
ContextProvider::dir(self)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue