fix: bugs with enumeration of vars

This commit is contained in:
Shunsuke Shibayama 2023-03-06 19:44:49 +09:00
parent b1a9f7bf40
commit fa2919e824
15 changed files with 107 additions and 94 deletions

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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()),

View file

@ -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);

View file

@ -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";

View file

@ -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)) => {

View file

@ -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 {

View file

@ -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)
}

View file

@ -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)
}