mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-26 19:39:07 +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
|
@ -205,11 +205,20 @@ impl<K: Hash + Eq, V> Dict<K, V> {
|
||||||
self.dict.remove(k)
|
self.dict.remove(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NOTE: This method does not consider pairing with values and keys. That is, a value may be paired with a different key (can be considered equal).
|
||||||
|
/// If you need to consider the pairing of the keys and values, use `guaranteed_extend` instead.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
|
pub fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
|
||||||
self.dict.extend(iter);
|
self.dict.extend(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn guaranteed_extend<I: IntoIterator<Item = (K, V)>>(&mut self, other: I) {
|
||||||
|
for (k, v) in other {
|
||||||
|
self.dict.entry(k).or_insert(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn merge(&mut self, other: Self) {
|
pub fn merge(&mut self, other: Self) {
|
||||||
self.dict.extend(other.dict);
|
self.dict.extend(other.dict);
|
||||||
|
@ -222,9 +231,9 @@ impl<K: Hash + Eq, V> Dict<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn diff(mut self, other: Self) -> Self {
|
pub fn diff(mut self, other: &Self) -> Self {
|
||||||
for (k, _) in other.dict {
|
for k in other.dict.keys() {
|
||||||
self.dict.remove(&k);
|
self.dict.remove(k);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn levenshtein(a: &str, b: &str, limit: usize) -> Option<usize> {
|
||||||
(dcol[m] <= limit).then_some(dcol[m])
|
(dcol[m] <= limit).then_some(dcol[m])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_similar_name<'a, S: ?Sized, I: Iterator<Item = &'a S> + Clone>(
|
pub fn get_similar_name<'a, S: ?Sized, I: Iterator<Item = &'a S>>(
|
||||||
candidates: I,
|
candidates: I,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Option<&'a S>
|
) -> Option<&'a S>
|
||||||
|
@ -58,7 +58,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_similar_name_and_some<'a, S: ?Sized, T, I: Iterator<Item = (&'a T, &'a S)> + Clone>(
|
pub fn get_similar_name_and_some<'a, S: ?Sized, T, I: Iterator<Item = (&'a T, &'a S)>>(
|
||||||
candidates: I,
|
candidates: I,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Option<(&'a T, &'a S)>
|
) -> Option<(&'a T, &'a S)>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
@ -100,7 +101,7 @@ impl Buildable for HIRBuilder {
|
||||||
impl BuildRunnable for HIRBuilder {}
|
impl BuildRunnable for HIRBuilder {}
|
||||||
|
|
||||||
impl ContextProvider for HIRBuilder {
|
impl ContextProvider for HIRBuilder {
|
||||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
self.lowerer.dir()
|
self.lowerer.dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +158,7 @@ impl HIRBuilder {
|
||||||
self.lowerer.pop_mod_ctx()
|
self.lowerer.pop_mod_ctx()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dir(&mut self) -> Vec<(&VarName, &VarInfo)> {
|
pub fn dir(&mut self) -> Dict<&VarName, &VarInfo> {
|
||||||
ContextProvider::dir(self)
|
ContextProvider::dir(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
use erg_parser::ast::VarName;
|
||||||
|
|
||||||
use crate::artifact::{CompleteArtifact, ErrorArtifact};
|
use crate::artifact::{CompleteArtifact, ErrorArtifact};
|
||||||
use crate::context::ContextProvider;
|
use crate::context::{Context, ContextProvider};
|
||||||
use crate::ty::codeobj::CodeObj;
|
use crate::ty::codeobj::CodeObj;
|
||||||
|
|
||||||
use crate::build_hir::HIRBuilder;
|
use crate::build_hir::HIRBuilder;
|
||||||
|
@ -19,6 +21,7 @@ use crate::error::{CompileError, CompileErrors, CompileWarnings};
|
||||||
use crate::hir::Expr;
|
use crate::hir::Expr;
|
||||||
use crate::link::Linker;
|
use crate::link::Linker;
|
||||||
use crate::module::{SharedCompilerResource, SharedModuleCache};
|
use crate::module::{SharedCompilerResource, SharedModuleCache};
|
||||||
|
use crate::varinfo::VarInfo;
|
||||||
|
|
||||||
/// * registered as global -> Global
|
/// * registered as global -> Global
|
||||||
/// * defined in the toplevel scope (and called in the inner scope) -> 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 {
|
impl ContextProvider for Compiler {
|
||||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
self.builder.dir()
|
self.builder.dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,6 @@ impl Context {
|
||||||
| (Float | Ratio | Int, Int)
|
| (Float | Ratio | Int, Int)
|
||||||
| (Float | Ratio, Ratio) => (Absolutely, true),
|
| (Float | Ratio, Ratio) => (Absolutely, true),
|
||||||
(Type, ClassType | TraitType) => (Absolutely, true),
|
(Type, ClassType | TraitType) => (Absolutely, true),
|
||||||
(Uninited, _) | (_, Uninited) => panic!("used an uninited type variable"),
|
|
||||||
(
|
(
|
||||||
Mono(n),
|
Mono(n),
|
||||||
Subr(SubrType {
|
Subr(SubrType {
|
||||||
|
@ -542,6 +541,7 @@ impl Context {
|
||||||
let nat = Type::Refinement(Nat.into_refinement());
|
let nat = Type::Refinement(Nat.into_refinement());
|
||||||
self.structural_supertype_of(re, &nat)
|
self.structural_supertype_of(re, &nat)
|
||||||
}
|
}
|
||||||
|
(Structural(_), Refinement(refine)) => self.supertype_of(lhs, &refine.t),
|
||||||
// Int :> {I: Int | ...} == true
|
// Int :> {I: Int | ...} == true
|
||||||
// Int :> {I: Str| ...} == false
|
// Int :> {I: Str| ...} == false
|
||||||
// Eq({1, 2}) :> {1, 2} (= {I: Int | I == 1 or I == 2})
|
// 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> {
|
pub fn fields(&self, t: &Type) -> Dict<Field, Type> {
|
||||||
match t {
|
match t {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => self.fields(&fv.crack()),
|
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::Refinement(refine) => self.fields(&refine.t),
|
||||||
Type::Structural(t) => self.fields(t),
|
Type::Structural(t) => self.fields(t),
|
||||||
other => {
|
other => {
|
||||||
let (_, ctx) = self
|
let Some((_, ctx)) = self.get_nominal_type_ctx(other) else {
|
||||||
.get_nominal_type_ctx(other)
|
return Dict::new();
|
||||||
.unwrap_or_else(|| panic!("{other} is not found"));
|
};
|
||||||
ctx.type_dir()
|
ctx.type_dir(self)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, vi)| {
|
.map(|(name, vi)| {
|
||||||
(
|
(
|
||||||
|
@ -993,7 +992,7 @@ impl Context {
|
||||||
// not {i = Int} and {i = Int; j = Int} == {j = Int}
|
// not {i = Int} and {i = Int; j = Int} == {j = Int}
|
||||||
(other @ Record(rec), Not(t)) | (Not(t), other @ Record(rec)) => match t.as_ref() {
|
(other @ Record(rec), Not(t)) | (Not(t), other @ Record(rec)) => match t.as_ref() {
|
||||||
Type::FreeVar(fv) => self.intersection(&fv.crack(), other),
|
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,
|
_ => Type::Never,
|
||||||
},
|
},
|
||||||
(l, r) if self.is_trait(l) && self.is_trait(r) => and(l.clone(), r.clone()),
|
(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,
|
Visibility::BUILTIN_PUBLIC,
|
||||||
ValueObj::Float(2.220446049250313e-16),
|
ValueObj::Float(2.220446049250313e-16),
|
||||||
);
|
);
|
||||||
float.register_builtin_py_impl(
|
float.register_builtin_py_impl(REAL, Float, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||||
REAL,
|
float.register_builtin_py_impl(IMAG, Float, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||||
Float,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_REAL),
|
|
||||||
);
|
|
||||||
float.register_builtin_py_impl(
|
|
||||||
IMAG,
|
|
||||||
Float,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_IMAG),
|
|
||||||
);
|
|
||||||
float.register_py_builtin(
|
float.register_py_builtin(
|
||||||
FUNC_AS_INTEGER_RATIO,
|
FUNC_AS_INTEGER_RATIO,
|
||||||
fn0_met(Float, tuple_t(vec![Int, Int])),
|
fn0_met(Float, tuple_t(vec![Int, Int])),
|
||||||
|
@ -124,6 +112,10 @@ impl Context {
|
||||||
Some(FUNC_FROMHEX),
|
Some(FUNC_FROMHEX),
|
||||||
53,
|
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(NUM));
|
||||||
float.register_marker_trait(mono(ORD));
|
float.register_marker_trait(mono(ORD));
|
||||||
let mut float_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
let mut float_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
||||||
|
@ -250,20 +242,8 @@ impl Context {
|
||||||
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
|
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
|
||||||
let mut ratio = Self::builtin_mono_class(RATIO, 2);
|
let mut ratio = Self::builtin_mono_class(RATIO, 2);
|
||||||
ratio.register_superclass(Obj, &obj);
|
ratio.register_superclass(Obj, &obj);
|
||||||
ratio.register_builtin_py_impl(
|
ratio.register_builtin_py_impl(REAL, Ratio, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||||
REAL,
|
ratio.register_builtin_py_impl(IMAG, Ratio, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||||
Ratio,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_REAL),
|
|
||||||
);
|
|
||||||
ratio.register_builtin_py_impl(
|
|
||||||
IMAG,
|
|
||||||
Ratio,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_IMAG),
|
|
||||||
);
|
|
||||||
ratio.register_marker_trait(mono(NUM));
|
ratio.register_marker_trait(mono(NUM));
|
||||||
ratio.register_marker_trait(mono(ORD));
|
ratio.register_marker_trait(mono(ORD));
|
||||||
let mut ratio_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
let mut ratio_ord = Self::builtin_methods(Some(mono(ORD)), 2);
|
||||||
|
@ -513,20 +493,8 @@ impl Context {
|
||||||
Some(FUNDAMENTAL_STR),
|
Some(FUNDAMENTAL_STR),
|
||||||
);
|
);
|
||||||
int.register_trait(Int, int_show);
|
int.register_trait(Int, int_show);
|
||||||
int.register_builtin_py_impl(
|
int.register_builtin_py_impl(REAL, Int, Const, Visibility::BUILTIN_PUBLIC, Some(REAL));
|
||||||
REAL,
|
int.register_builtin_py_impl(IMAG, Int, Const, Visibility::BUILTIN_PUBLIC, Some(IMAG));
|
||||||
Int,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_REAL),
|
|
||||||
);
|
|
||||||
int.register_builtin_py_impl(
|
|
||||||
IMAG,
|
|
||||||
Int,
|
|
||||||
Const,
|
|
||||||
Visibility::BUILTIN_PUBLIC,
|
|
||||||
Some(FUNC_IMAG),
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Nat */
|
/* Nat */
|
||||||
let mut nat = Self::builtin_mono_class(NAT, 10);
|
let mut nat = Self::builtin_mono_class(NAT, 10);
|
||||||
|
|
|
@ -100,10 +100,8 @@ const BYTES: &str = "Bytes";
|
||||||
const FLOAT: &str = "Float";
|
const FLOAT: &str = "Float";
|
||||||
const MUT_FLOAT: &str = "Float!";
|
const MUT_FLOAT: &str = "Float!";
|
||||||
const EPSILON: &str = "EPSILON";
|
const EPSILON: &str = "EPSILON";
|
||||||
const REAL: &str = "Real";
|
const REAL: &str = "real";
|
||||||
const FUNC_REAL: &str = "real";
|
const IMAG: &str = "imag";
|
||||||
const IMAG: &str = "Imag";
|
|
||||||
const FUNC_IMAG: &str = "imag";
|
|
||||||
const FUNC_AS_INTEGER_RATIO: &str = "as_integer_ratio";
|
const FUNC_AS_INTEGER_RATIO: &str = "as_integer_ratio";
|
||||||
const FUNC_CONJUGATE: &str = "conjugate";
|
const FUNC_CONJUGATE: &str = "conjugate";
|
||||||
const FUNC_IS_INTEGER: &str = "is_integer";
|
const FUNC_IS_INTEGER: &str = "is_integer";
|
||||||
|
|
|
@ -396,6 +396,25 @@ impl Context {
|
||||||
mode: RegistrationMode,
|
mode: RegistrationMode,
|
||||||
kind: ParamKind,
|
kind: ParamKind,
|
||||||
) -> TyCheckResult<ParamTy> {
|
) -> 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())?;
|
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_cache, mode, kind.clone())?;
|
||||||
match (sig.inspect(), kind) {
|
match (sig.inspect(), kind) {
|
||||||
(Some(name), ParamKind::Default(default_t)) => {
|
(Some(name), ParamKind::Default(default_t)) => {
|
||||||
|
|
|
@ -43,7 +43,7 @@ use Type::*;
|
||||||
|
|
||||||
/// For implementing LSP or other IDE features
|
/// For implementing LSP or other IDE features
|
||||||
pub trait ContextProvider {
|
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_receiver_ctx(&self, receiver_name: &str) -> Option<&Context>;
|
||||||
fn get_var_info(&self, name: &str) -> Option<(&VarName, &VarInfo)>;
|
fn get_var_info(&self, name: &str) -> Option<(&VarName, &VarInfo)>;
|
||||||
}
|
}
|
||||||
|
@ -411,12 +411,12 @@ impl fmt::Display for Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextProvider for Context {
|
impl ContextProvider for Context {
|
||||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
let mut vars = self.type_dir();
|
let mut vars = self.type_dir(self);
|
||||||
if let Some(outer) = self.get_outer() {
|
if let Some(outer) = self.get_outer() {
|
||||||
vars.extend(outer.dir());
|
vars.guaranteed_extend(outer.dir());
|
||||||
} else if let Some(builtins) = self.get_builtins() {
|
} else if let Some(builtins) = self.get_builtins() {
|
||||||
vars.extend(builtins.locals.iter());
|
vars.guaranteed_extend(builtins.locals.iter());
|
||||||
}
|
}
|
||||||
vars
|
vars
|
||||||
}
|
}
|
||||||
|
@ -439,7 +439,7 @@ impl ContextProvider for Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
pub fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
ContextProvider::dir(self)
|
ContextProvider::dir(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,24 +1013,25 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// enumerates all the variables/methods in the current context & super contexts.
|
/// enumerates all the variables/methods in the current context & super contexts.
|
||||||
fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn type_dir<'t>(&'t self, namespace: &'t Context) -> Dict<&VarName, &VarInfo> {
|
||||||
let mut vars: Vec<_> = self
|
let mut attrs = self.locals.iter().collect::<Dict<_, _>>();
|
||||||
.locals
|
attrs.guaranteed_extend(
|
||||||
.iter()
|
self.params
|
||||||
.chain(self.decls.iter())
|
.iter()
|
||||||
.chain(
|
.filter_map(|(k, v)| k.as_ref().map(|k| (k, v))),
|
||||||
self.params
|
);
|
||||||
.iter()
|
attrs.guaranteed_extend(self.decls.iter());
|
||||||
.filter_map(|(k, v)| k.as_ref().map(|k| (k, v))),
|
attrs.guaranteed_extend(
|
||||||
)
|
self.methods_list
|
||||||
.chain(self.methods_list.iter().flat_map(|(_, ctx)| ctx.type_dir()))
|
.iter()
|
||||||
.collect();
|
.flat_map(|(_, ctx)| ctx.type_dir(namespace)),
|
||||||
|
);
|
||||||
for sup in self.super_classes.iter() {
|
for sup in self.super_classes.iter() {
|
||||||
if let Some((_, sup_ctx)) = self.get_nominal_type_ctx(sup) {
|
if let Some((_, sup_ctx)) = namespace.get_nominal_type_ctx(sup) {
|
||||||
vars.extend(sup_ctx.type_dir());
|
attrs.guaranteed_extend(sup_ctx.type_dir(namespace));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vars
|
attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mod_cache(&self) -> &SharedModuleCache {
|
pub(crate) fn mod_cache(&self) -> &SharedModuleCache {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::mem;
|
||||||
|
|
||||||
use erg_common::config::{ErgConfig, ErgMode};
|
use erg_common::config::{ErgConfig, ErgMode};
|
||||||
use erg_common::dict;
|
use erg_common::dict;
|
||||||
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
use erg_common::set;
|
use erg_common::set;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
|
@ -124,7 +125,7 @@ impl Runnable for ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextProvider for ASTLowerer {
|
impl ContextProvider for ASTLowerer {
|
||||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
self.module.context.dir()
|
self.module.context.dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ impl ASTLowerer {
|
||||||
&self.module
|
&self.module
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
pub fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
ContextProvider::dir(self)
|
ContextProvider::dir(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::dict::Dict as HashMap;
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
@ -167,7 +168,7 @@ impl Runnable for Transpiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextProvider for Transpiler {
|
impl ContextProvider for Transpiler {
|
||||||
fn dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
fn dir(&self) -> HashMap<&VarName, &VarInfo> {
|
||||||
self.builder.dir()
|
self.builder.dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ impl Transpiler {
|
||||||
self.builder.pop_mod_ctx()
|
self.builder.pop_mod_ctx()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dir(&mut self) -> Vec<(&VarName, &VarInfo)> {
|
pub fn dir(&mut self) -> HashMap<&VarName, &VarInfo> {
|
||||||
ContextProvider::dir(self)
|
ContextProvider::dir(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,13 @@ Option T: Type = T or NoneType
|
||||||
Option: Type -> Type
|
Option: Type -> Type
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Compile-time function parameters must have different names from any constants already defined. If the names are the same, it will be interpreted as a constant pattern.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Int is not a parameter but a constant (type Int)
|
||||||
|
K Int = None
|
||||||
|
```
|
||||||
|
|
||||||
## Appendix: Function Comparison
|
## Appendix: Function Comparison
|
||||||
|
|
||||||
Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general.
|
Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general.
|
||||||
|
|
|
@ -277,6 +277,13 @@ Option T: Type = T or NoneType
|
||||||
Option: Type -> Type
|
Option: Type -> Type
|
||||||
```
|
```
|
||||||
|
|
||||||
|
コンパイル時関数の仮引数は、既に定義されている如何なる定数とも違う名前である必要があります。名前が被った場合、定数パターンとして解釈されます。
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Intは仮引数ではない。型Intのみを引数にとる関数
|
||||||
|
K Int = None
|
||||||
|
```
|
||||||
|
|
||||||
## 付録1: 関数の比較
|
## 付録1: 関数の比較
|
||||||
|
|
||||||
Ergでは、関数に`==`が定義されていません。それは関数の構造的な同値性判定アルゴリズムが一般には存在しないためです。
|
Ergでは、関数に`==`が定義されていません。それは関数の構造的な同値性判定アルゴリズムが一般には存在しないためです。
|
||||||
|
|
|
@ -12,3 +12,6 @@ x = _add 1, 2
|
||||||
y = _add x, 2
|
y = _add x, 2
|
||||||
z = _add y, 2
|
z = _add y, 2
|
||||||
assert z == 7
|
assert z == 7
|
||||||
|
|
||||||
|
w = _add -1, 2
|
||||||
|
assert w == 1
|
|
@ -157,13 +157,13 @@ fn exec_return() -> Result<(), ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_structural() -> Result<(), ()> {
|
fn exec_structural_example() -> Result<(), ()> {
|
||||||
expect_success("examples/structural.er")
|
expect_success("examples/structural.er")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_structural_test() -> Result<(), ()> {
|
fn exec_structural() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/structural_test.er")
|
expect_success("tests/should_ok/structural.er")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue