feat: add restricted visibility syntax

This commit is contained in:
Shunsuke Shibayama 2023-03-05 02:19:18 +09:00
parent 309bb06db8
commit d92f5284c8
44 changed files with 3803 additions and 2358 deletions

View file

@ -200,9 +200,9 @@ impl<'a> HIRVisitor<'a> {
token: &Token, token: &Token,
) -> Option<&Expr> { ) -> Option<&Expr> {
match acc { match acc {
Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.name.token(), token), Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.raw.name.token(), token),
Accessor::Attr(attr) => self Accessor::Attr(attr) => self
.return_expr_if_same(expr, attr.ident.name.token(), token) .return_expr_if_same(expr, attr.ident.raw.name.token(), token)
.or_else(|| self.get_expr(&attr.obj, token)), .or_else(|| self.get_expr(&attr.obj, token)),
} }
} }
@ -234,7 +234,7 @@ impl<'a> HIRVisitor<'a> {
.or_else(|| { .or_else(|| {
call.attr_name call.attr_name
.as_ref() .as_ref()
.and_then(|attr| self.return_expr_if_same(expr, attr.name.token(), token)) .and_then(|attr| self.return_expr_if_same(expr, attr.raw.name.token(), token))
}) })
.or_else(|| self.get_expr(&call.obj, token)) .or_else(|| self.get_expr(&call.obj, token))
.or_else(|| self.get_expr_from_args(&call.args, token)) .or_else(|| self.get_expr_from_args(&call.args, token))
@ -266,7 +266,7 @@ impl<'a> HIRVisitor<'a> {
def: &'e Def, def: &'e Def,
token: &Token, token: &Token,
) -> Option<&Expr> { ) -> Option<&Expr> {
self.return_expr_if_same(expr, def.sig.ident().name.token(), token) self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), token)
.or_else(|| self.get_expr_from_block(&def.body.block, token)) .or_else(|| self.get_expr_from_block(&def.body.block, token))
.or_else(|| def.loc().contains(token.loc()).then_some(expr)) .or_else(|| def.loc().contains(token.loc()).then_some(expr))
} }
@ -319,7 +319,7 @@ impl<'a> HIRVisitor<'a> {
patch_def: &'e PatchDef, patch_def: &'e PatchDef,
token: &Token, token: &Token,
) -> Option<&Expr> { ) -> Option<&Expr> {
self.return_expr_if_same(expr, patch_def.sig.ident().name.token(), token) self.return_expr_if_same(expr, patch_def.sig.name().token(), token)
.or_else(|| self.get_expr(&patch_def.base, token)) .or_else(|| self.get_expr(&patch_def.base, token))
.or_else(|| self.get_expr_from_block(&patch_def.methods, token)) .or_else(|| self.get_expr_from_block(&patch_def.methods, token))
.or_else(|| patch_def.loc().contains(token.loc()).then_some(expr)) .or_else(|| patch_def.loc().contains(token.loc()).then_some(expr))
@ -489,10 +489,10 @@ impl<'a> HIRVisitor<'a> {
fn get_acc_info(&self, acc: &Accessor, token: &Token) -> Option<VarInfo> { fn get_acc_info(&self, acc: &Accessor, token: &Token) -> Option<VarInfo> {
match acc { match acc {
Accessor::Ident(ident) => { Accessor::Ident(ident) => {
self.return_var_info_if_same(ident, ident.name.token(), token) self.return_var_info_if_same(ident, ident.raw.name.token(), token)
} }
Accessor::Attr(attr) => self Accessor::Attr(attr) => self
.return_var_info_if_same(&attr.ident, attr.ident.name.token(), token) .return_var_info_if_same(&attr.ident, attr.ident.raw.name.token(), token)
.or_else(|| self.get_expr_info(&attr.obj, token)), .or_else(|| self.get_expr_info(&attr.obj, token)),
} }
} }
@ -504,7 +504,7 @@ impl<'a> HIRVisitor<'a> {
fn get_call_info(&self, call: &Call, token: &Token) -> Option<VarInfo> { fn get_call_info(&self, call: &Call, token: &Token) -> Option<VarInfo> {
if let Some(attr) = &call.attr_name { if let Some(attr) = &call.attr_name {
if let Some(t) = self.return_var_info_if_same(attr, attr.name.token(), token) { if let Some(t) = self.return_var_info_if_same(attr, attr.raw.name.token(), token) {
return Some(t); return Some(t);
} }
} }
@ -534,10 +534,10 @@ impl<'a> HIRVisitor<'a> {
fn get_sig_info(&self, sig: &Signature, token: &Token) -> Option<VarInfo> { fn get_sig_info(&self, sig: &Signature, token: &Token) -> Option<VarInfo> {
match sig { match sig {
Signature::Var(var) => { Signature::Var(var) => {
self.return_var_info_if_same(&var.ident, var.ident.name.token(), token) self.return_var_info_if_same(&var.ident, var.name().token(), token)
} }
Signature::Subr(subr) => self Signature::Subr(subr) => self
.return_var_info_if_same(&subr.ident, subr.ident.name.token(), token) .return_var_info_if_same(&subr.ident, subr.name().token(), token)
.or_else(|| self.get_params_info(&subr.params, token)), .or_else(|| self.get_params_info(&subr.params, token)),
} }
} }

View file

@ -526,7 +526,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
ctxs.extend(type_ctxs); ctxs.extend(type_ctxs);
if let Ok(singular_ctx) = module if let Ok(singular_ctx) = module
.context .context
.get_singular_ctx_by_hir_expr(expr, &"".into()) .get_singular_ctx_by_hir_expr(expr, &module.context)
{ {
ctxs.push(singular_ctx); ctxs.push(singular_ctx);
} }

View file

@ -40,14 +40,17 @@ 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, I: Iterator<Item = &'a str> + Clone>( pub fn get_similar_name<'a, S: ?Sized, I: Iterator<Item = &'a S> + Clone>(
candidates: I, candidates: I,
name: &str, name: &str,
) -> Option<&'a str> { ) -> Option<&'a S>
let limit = (name.len() as f64).sqrt() as usize; where
S: std::borrow::Borrow<str>,
{
let limit = (name.len() as f64).sqrt().round() as usize;
let most_similar_name = let most_similar_name =
candidates.min_by_key(|v| levenshtein(v, name, limit).unwrap_or(usize::MAX))?; candidates.min_by_key(|v| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?;
let dist = levenshtein(most_similar_name, name, limit); let dist = levenshtein(most_similar_name.borrow(), name, limit);
if dist.is_none() || dist.unwrap() >= limit { if dist.is_none() || dist.unwrap() >= limit {
None None
} else { } else {
@ -55,6 +58,24 @@ pub fn get_similar_name<'a, I: Iterator<Item = &'a str> + Clone>(
} }
} }
pub fn get_similar_name_and_some<'a, S: ?Sized, T, I: Iterator<Item = (&'a T, &'a S)> + Clone>(
candidates: I,
name: &str,
) -> Option<(&'a T, &'a S)>
where
S: std::borrow::Borrow<str>,
{
let limit = (name.len() as f64).sqrt().round() as usize;
let most_similar_name_and_some = candidates
.min_by_key(|(_, v)| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?;
let dist = levenshtein(most_similar_name_and_some.1.borrow(), name, limit);
if dist.is_none() || dist.unwrap() >= limit {
None
} else {
Some(most_similar_name_and_some)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::levenshtein::get_similar_name; use crate::levenshtein::get_similar_name;

View file

@ -31,9 +31,9 @@ pub mod stdin;
pub mod str; pub mod str;
pub mod style; pub mod style;
pub mod traits; pub mod traits;
pub mod triple;
pub mod tsort; pub mod tsort;
pub mod tty; pub mod tty;
pub mod vis;
use crate::set::Set; use crate::set::Set;
pub use crate::str::Str; pub use crate::str::Str;

View file

@ -199,6 +199,30 @@ impl Str {
ret ret
} }
/// ```
/// use erg_common::str::Str;
/// let s = Str::rc("a.b.c");
/// assert_eq!(s.rpartition_with(&[".", "/"]), ("a.b", "c"));
/// let s = Str::rc("a::b.c");
/// assert_eq!(s.rpartition_with(&["/", "::"]), ("a", "b.c"));
/// ```
pub fn rpartition_with(&self, seps: &[&str]) -> (&str, &str) {
let mut i = self.len();
while i > 0 {
for sep in seps {
if self[i..].starts_with(sep) {
return (&self[..i], &self[i + sep.len()..]);
}
}
i -= 1;
}
(&self[..], "")
}
pub fn reversed(&self) -> Str {
Str::rc(&self.chars().rev().collect::<String>())
}
pub fn multi_replace(&self, paths: &[(&str, &str)]) -> Self { pub fn multi_replace(&self, paths: &[(&str, &str)]) -> Self {
let mut self_ = self.to_string(); let mut self_ = self.to_string();
for (from, to) in paths { for (from, to) in paths {
@ -237,11 +261,6 @@ impl Str {
mod tests { mod tests {
use super::*; use super::*;
use crate::dict;
// use crate::dict::Dict;
use crate::vis::Field;
#[test] #[test]
fn test_split_with() { fn test_split_with() {
assert_eq!( assert_eq!(
@ -261,17 +280,4 @@ mod tests {
vec!["aa", "bb", "ff"] vec!["aa", "bb", "ff"]
); );
} }
#[test]
fn test_std_key() {
let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2};
assert_eq!(dict.get("a"), Some(&1));
assert_eq!(dict.get("b"), Some(&2));
assert_eq!(dict.get(&Str::ever("b")), Some(&2));
assert_eq!(dict.get(&Str::rc("b")), Some(&2));
let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2};
assert_eq!(dict.get("a"), Some(&1));
assert_eq!(dict.get("b"), Some(&2));
}
} }

View file

@ -0,0 +1,82 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Triple<T, E> {
Ok(T),
Err(E),
None,
}
impl<T, E> Triple<T, E> {
pub fn none_then(self, err: E) -> Result<T, E> {
match self {
Triple::None => Err(err),
Triple::Ok(ok) => Ok(ok),
Triple::Err(err) => Err(err),
}
}
pub fn none_or_result(self, f: impl FnOnce() -> E) -> Result<T, E> {
match self {
Triple::None => Err(f()),
Triple::Ok(ok) => Ok(ok),
Triple::Err(err) => Err(err),
}
}
pub fn none_or_else(self, f: impl FnOnce() -> Triple<T, E>) -> Triple<T, E> {
match self {
Triple::None => f(),
Triple::Ok(ok) => Triple::Ok(ok),
Triple::Err(err) => Triple::Err(err),
}
}
pub fn unwrap_to_result(self) -> Result<T, E> {
match self {
Triple::None => panic!("unwrapping Triple::None"),
Triple::Ok(ok) => Ok(ok),
Triple::Err(err) => Err(err),
}
}
pub fn ok(self) -> Option<T> {
match self {
Triple::None => None,
Triple::Ok(ok) => Some(ok),
Triple::Err(_) => None,
}
}
pub fn or_else(self, f: impl FnOnce() -> Result<T, E>) -> Result<T, E> {
match self {
Triple::None => f(),
Triple::Ok(ok) => Ok(ok),
Triple::Err(err) => Err(err),
}
}
pub fn unwrap_or(self, default: T) -> T {
match self {
Triple::None => default,
Triple::Ok(ok) => ok,
Triple::Err(_) => default,
}
}
pub fn unwrap_err(self) -> E {
match self {
Triple::None => panic!("unwrapping Triple::None"),
Triple::Ok(_) => panic!("unwrapping Triple::Ok"),
Triple::Err(err) => err,
}
}
}
impl<T, E: std::error::Error> Triple<T, E> {
pub fn unwrap(self) -> T {
match self {
Triple::None => panic!("unwrapping Triple::None"),
Triple::Ok(ok) => ok,
Triple::Err(err) => panic!("unwrapping Triple::Err({err})"),
}
}
}

View file

@ -1,81 +0,0 @@
use std::borrow::Borrow;
use std::fmt;
use crate::Str;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum Visibility {
Private,
Public,
}
impl Visibility {
pub const fn is_public(&self) -> bool {
matches!(self, Self::Public)
}
pub const fn is_private(&self) -> bool {
matches!(self, Self::Private)
}
}
/// same structure as `Identifier`, but only for Record fields.
#[derive(Debug, Clone, Eq)]
pub struct Field {
pub vis: Visibility,
pub symbol: Str,
}
impl PartialEq for Field {
fn eq(&self, other: &Self) -> bool {
self.symbol == other.symbol
}
}
impl std::hash::Hash for Field {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.symbol.hash(state);
}
}
impl fmt::Display for Field {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.vis.is_public() {
write!(f, ".{}", self.symbol)
} else {
write!(f, "::{}", self.symbol)
}
}
}
impl Borrow<str> for Field {
#[inline]
fn borrow(&self) -> &str {
&self.symbol[..]
}
}
impl Borrow<Str> for Field {
#[inline]
fn borrow(&self) -> &Str {
&self.symbol
}
}
impl Field {
pub const fn new(vis: Visibility, symbol: Str) -> Self {
Field { vis, symbol }
}
pub const fn private(symbol: Str) -> Self {
Field::new(Visibility::Private, symbol)
}
pub const fn public(symbol: Str) -> Self {
Field::new(Visibility::Public, symbol)
}
pub fn is_const(&self) -> bool {
self.symbol.starts_with(char::is_uppercase)
}
}

View file

@ -17,11 +17,11 @@ use erg_common::opcode311::{BinOpCode, Opcode311};
use erg_common::option_enum_unwrap; use erg_common::option_enum_unwrap;
use erg_common::python_util::{env_python_version, PythonVersion}; use erg_common::python_util::{env_python_version, PythonVersion};
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
use erg_common::{ use erg_common::{
debug_power_assert, enum_unwrap, fn_name, fn_name_full, impl_stream, log, switch_unreachable, debug_power_assert, enum_unwrap, fn_name, fn_name_full, impl_stream, log, switch_unreachable,
}; };
use erg_parser::ast::VisModifierSpec;
use erg_parser::ast::{DefId, DefKind}; use erg_parser::ast::{DefId, DefKind};
use CommonOpcode::*; use CommonOpcode::*;
@ -38,7 +38,7 @@ use crate::hir::{
SubrSignature, Tuple, UnaryOp, VarSignature, HIR, SubrSignature, Tuple, UnaryOp, VarSignature, HIR,
}; };
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::{HasType, Type, TypeCode, TypePair}; use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
use crate::varinfo::VarInfo; use crate::varinfo::VarInfo;
use erg_common::fresh::fresh_varname; use erg_common::fresh::fresh_varname;
use AccessKind::*; use AccessKind::*;
@ -70,7 +70,7 @@ fn debind(ident: &Identifier) -> Option<Str> {
} }
} }
fn escape_name(name: &str, vis: Visibility) -> Str { fn escape_name(name: &str, vis: &VisibilityModifier) -> Str {
let name = name.replace('!', "__erg_proc__"); let name = name.replace('!', "__erg_proc__");
let name = name.replace('$', "__erg_shared__"); let name = name.replace('$', "__erg_shared__");
if vis.is_private() { if vis.is_private() {
@ -908,7 +908,7 @@ impl PyCodeGenerator {
if s == "_" { if s == "_" {
format!("_{i}") format!("_{i}")
} else { } else {
escape_name(s, Visibility::Private).to_string() escape_name(s, &VisibilityModifier::Private).to_string()
} }
}) })
.map(|s| self.get_cached(&s)) .map(|s| self.get_cached(&s))
@ -930,11 +930,11 @@ impl PyCodeGenerator {
// Since Erg does not allow the coexistence of private and public variables with the same name, there is no problem in this trick. // Since Erg does not allow the coexistence of private and public variables with the same name, there is no problem in this trick.
let is_record = a.obj.ref_t().is_record(); let is_record = a.obj.ref_t().is_record();
if is_record { if is_record {
a.ident.dot = Some(DOT); a.ident.raw.vis = VisModifierSpec::Public(DOT);
} }
if let Some(varname) = debind(&a.ident) { if let Some(varname) = debind(&a.ident) {
a.ident.dot = None; a.ident.raw.vis = VisModifierSpec::Private;
a.ident.name = VarName::from_str(varname); a.ident.raw.name = VarName::from_str(varname);
self.emit_load_name_instr(a.ident); self.emit_load_name_instr(a.ident);
} else { } else {
self.emit_expr(*a.obj); self.emit_expr(*a.obj);
@ -1153,9 +1153,9 @@ impl PyCodeGenerator {
self.emit_load_const(code); self.emit_load_const(code);
if self.py_version.minor < Some(11) { if self.py_version.minor < Some(11) {
if let Some(class) = class_name { if let Some(class) = class_name {
self.emit_load_const(Str::from(format!("{class}.{}", ident.name.inspect()))); self.emit_load_const(Str::from(format!("{class}.{}", ident.inspect())));
} else { } else {
self.emit_load_const(ident.name.inspect().clone()); self.emit_load_const(ident.inspect().clone());
} }
} else { } else {
self.stack_inc(); self.stack_inc();
@ -1213,8 +1213,8 @@ impl PyCodeGenerator {
patch_def.sig.ident().to_string_notype(), patch_def.sig.ident().to_string_notype(),
def.sig.ident().to_string_notype() def.sig.ident().to_string_notype()
); );
def.sig.ident_mut().name = VarName::from_str(Str::from(name)); def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
def.sig.ident_mut().dot = None; def.sig.ident_mut().raw.vis = VisModifierSpec::Private;
self.emit_def(def); self.emit_def(def);
} }
} }
@ -1925,7 +1925,8 @@ impl PyCodeGenerator {
} }
match param.raw.pat { match param.raw.pat {
ParamPattern::VarName(name) => { ParamPattern::VarName(name) => {
let ident = Identifier::bare(None, name); let ident = erg_parser::ast::Identifier::private_from_varname(name);
let ident = Identifier::bare(ident);
self.emit_store_instr(ident, AccessKind::Name); self.emit_store_instr(ident, AccessKind::Name);
} }
ParamPattern::Discard(_) => { ParamPattern::Discard(_) => {
@ -2190,7 +2191,7 @@ impl PyCodeGenerator {
let kw = if is_py_api { let kw = if is_py_api {
arg.keyword.content arg.keyword.content
} else { } else {
escape_name(&arg.keyword.content, Visibility::Private) escape_name(&arg.keyword.content, &VisibilityModifier::Private)
}; };
kws.push(ValueObj::Str(kw)); kws.push(ValueObj::Str(kw));
self.emit_expr(arg.expr); self.emit_expr(arg.expr);
@ -2301,7 +2302,7 @@ impl PyCodeGenerator {
mut args: Args, mut args: Args,
) { ) {
log!(info "entered {}", fn_name!()); log!(info "entered {}", fn_name!());
method_name.dot = None; method_name.raw.vis = VisModifierSpec::Private;
method_name.vi.py_name = Some(func_name); method_name.vi.py_name = Some(func_name);
self.emit_push_null(); self.emit_push_null();
self.emit_load_name_instr(method_name); self.emit_load_name_instr(method_name);
@ -2785,6 +2786,7 @@ impl PyCodeGenerator {
let vi = VarInfo::nd_parameter( let vi = VarInfo::nd_parameter(
__new__.return_t().unwrap().clone(), __new__.return_t().unwrap().clone(),
ident.vi.def_loc.clone(), ident.vi.def_loc.clone(),
"?".into(),
); );
let raw = let raw =
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None); erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None);
@ -2797,7 +2799,11 @@ impl PyCodeGenerator {
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
let raw = let raw =
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None); erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone()); let vi = VarInfo::nd_parameter(
new_first_param.typ().clone(),
ident.vi.def_loc.clone(),
"?".into(),
);
let param = NonDefaultParamSignature::new(raw, vi, None); let param = NonDefaultParamSignature::new(raw, vi, None);
let params = Params::new(vec![self_param, param], None, vec![], None); let params = Params::new(vec![self_param, param], None, vec![], None);
(param_name, params) (param_name, params)
@ -2818,20 +2824,19 @@ impl PyCodeGenerator {
for field in rec.keys() { for field in rec.keys() {
let obj = let obj =
Expr::Accessor(Accessor::private_with_line(Str::from(&param_name), line)); Expr::Accessor(Accessor::private_with_line(Str::from(&param_name), line));
let expr = obj.attr_expr(Identifier::bare( let ident = erg_parser::ast::Identifier::public(field.symbol.clone());
Some(DOT), let expr = obj.attr_expr(Identifier::bare(ident));
VarName::from_str(field.symbol.clone()),
));
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line)); let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
let dot = if field.vis.is_private() { let dot = if field.vis.is_private() {
None VisModifierSpec::Private
} else { } else {
Some(DOT) VisModifierSpec::Public(DOT)
}; };
let attr = obj.attr(Identifier::bare( let attr = erg_parser::ast::Identifier::new(
dot, dot,
VarName::from_str(field.symbol.clone()), VarName::from_str(field.symbol.clone()),
)); );
let attr = obj.attr(Identifier::bare(attr));
let redef = ReDef::new(attr, Block::new(vec![expr])); let redef = ReDef::new(attr, Block::new(vec![expr]));
attrs.push(Expr::ReDef(redef)); attrs.push(Expr::ReDef(redef));
} }
@ -2865,8 +2870,7 @@ impl PyCodeGenerator {
let line = sig.ln_begin().unwrap(); let line = sig.ln_begin().unwrap();
let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line); let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line);
let class = Expr::Accessor(Accessor::Ident(class_ident.clone())); let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
let mut new_ident = let mut new_ident = Identifier::private_with_line(Str::ever("__new__"), line);
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line));
new_ident.vi.py_name = Some(Str::ever("__call__")); new_ident.vi.py_name = Some(Str::ever("__call__"));
let class_new = class.attr_expr(new_ident); let class_new = class.attr_expr(new_ident);
ident.vi.t = __new__; ident.vi.t = __new__;
@ -2876,7 +2880,11 @@ impl PyCodeGenerator {
.map(|s| s.to_string()) .map(|s| s.to_string())
.unwrap_or_else(fresh_varname); .unwrap_or_else(fresh_varname);
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone()); let vi = VarInfo::nd_parameter(
new_first_param.typ().clone(),
ident.vi.def_loc.clone(),
"?".into(),
);
let raw = let raw =
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None); erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
let param = NonDefaultParamSignature::new(raw, vi, None); let param = NonDefaultParamSignature::new(raw, vi, None);

View file

@ -1,21 +1,20 @@
//! provides type-comparison //! provides type-comparison
use std::option::Option; // conflicting to Type::Option use std::option::Option; // conflicting to Type::Option
use erg_common::dict::Dict;
use erg_common::error::MultiErrorDisplay; use erg_common::error::MultiErrorDisplay;
use erg_common::style::colors::DEBUG_ERROR; use erg_common::style::colors::DEBUG_ERROR;
use erg_common::traits::StructuralEq; use erg_common::traits::StructuralEq;
use erg_common::{assume_unreachable, log};
use crate::ty::constructors::{and, not, or, poly}; use crate::ty::constructors::{and, not, or, poly};
use crate::ty::free::{Constraint, FreeKind}; use crate::ty::free::{Constraint, FreeKind};
use crate::ty::typaram::{OpKind, TyParam, TyParamOrdering}; use crate::ty::typaram::{OpKind, TyParam, TyParamOrdering};
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::value::ValueObj::Inf; use crate::ty::value::ValueObj::Inf;
use crate::ty::{Predicate, RefinementType, SubrKind, SubrType, Type}; use crate::ty::{Field, Predicate, RefinementType, SubrKind, SubrType, Type};
use Predicate as Pred; use Predicate as Pred;
use erg_common::dict::Dict;
use erg_common::vis::Field;
use erg_common::{assume_unreachable, log};
use TyParamOrdering::*; use TyParamOrdering::*;
use Type::*; use Type::*;
@ -705,7 +704,12 @@ impl Context {
.unwrap_or_else(|| panic!("{other} is not found")); .unwrap_or_else(|| panic!("{other} is not found"));
ctx.type_dir() ctx.type_dir()
.into_iter() .into_iter()
.map(|(name, vi)| (Field::new(vi.vis, name.inspect().clone()), vi.t.clone())) .map(|(name, vi)| {
(
Field::new(vi.vis.modifier.clone(), name.inspect().clone()),
vi.t.clone(),
)
})
.collect() .collect()
} }
} }

View file

@ -7,7 +7,6 @@ use erg_common::log;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::shared::Shared; use erg_common::shared::Shared;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Field;
use erg_common::{dict, fn_name, option_enum_unwrap, set}; use erg_common::{dict, fn_name, option_enum_unwrap, set};
use erg_common::{enum_unwrap, fmt_vec}; use erg_common::{enum_unwrap, fmt_vec};
use erg_common::{RcArray, Str}; use erg_common::{RcArray, Str};
@ -27,7 +26,7 @@ use crate::ty::typaram::{OpKind, TyParam};
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, Type, UserConstSubr, ValueArgs}; use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, Type, UserConstSubr, ValueArgs};
use crate::context::instantiate::ParamKind; use crate::context::instantiate_spec::ParamKind;
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode}; use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult}; use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult};
@ -166,7 +165,10 @@ impl Context {
} }
fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> SingleEvalResult<ValueObj> { fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> SingleEvalResult<ValueObj> {
if let Some(val) = obj.try_get_attr(&Field::from(ident)) { let field = self
.instantiate_field(ident)
.map_err(|mut errs| errs.remove(0))?;
if let Some(val) = obj.try_get_attr(&field) {
return Ok(val); return Ok(val);
} }
if let ValueObj::Type(t) = &obj { if let ValueObj::Type(t) = &obj {
@ -301,7 +303,7 @@ impl Context {
fn eval_const_def(&mut self, def: &Def) -> EvalResult<ValueObj> { fn eval_const_def(&mut self, def: &Def) -> EvalResult<ValueObj> {
if def.is_const() { if def.is_const() {
let __name__ = def.sig.ident().unwrap().inspect(); let __name__ = def.sig.ident().unwrap().inspect();
let vis = def.sig.vis(); let vis = self.instantiate_vis_modifier(def.sig.vis())?;
let tv_cache = match &def.sig { let tv_cache = match &def.sig {
Signature::Subr(subr) => { Signature::Subr(subr) => {
let ty_cache = let ty_cache =
@ -430,7 +432,7 @@ impl Context {
let elem = record_ctx.eval_const_block(&attr.body.block)?; let elem = record_ctx.eval_const_block(&attr.body.block)?;
let ident = match &attr.sig { let ident = match &attr.sig {
Signature::Var(var) => match &var.pat { Signature::Var(var) => match &var.pat {
VarPattern::Ident(ident) => Field::new(ident.vis(), ident.inspect().clone()), VarPattern::Ident(ident) => self.instantiate_field(ident)?,
other => { other => {
return feature_error!(self, other.loc(), &format!("record field: {other}")) return feature_error!(self, other.loc(), &format!("record field: {other}"))
} }

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,23 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::vis::{Field, Visibility};
use crate::ty::constructors::*; use crate::ty::constructors::*;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::Type; use crate::ty::{Field, Type, Visibility};
use Type::*; use Type::*;
use crate::context::initialize::*; use crate::context::initialize::*;
use crate::context::Context; use crate::context::Context;
use crate::varinfo::Mutability; use crate::varinfo::Mutability;
use Mutability::*; use Mutability::*;
use Visibility::*;
impl Context { impl Context {
pub(super) fn init_builtin_funcs(&mut self) { pub(super) fn init_builtin_funcs(&mut self) {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
let T = mono_q(TY_T, instanceof(Type)); let T = mono_q(TY_T, instanceof(Type));
let U = mono_q(TY_U, instanceof(Type)); let U = mono_q(TY_U, instanceof(Type));
@ -222,96 +220,144 @@ impl Context {
self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33); self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33);
self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53); self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53);
// Leave as `Const`, as it may negatively affect assert casting. // Leave as `Const`, as it may negatively affect assert casting.
self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis); self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis.clone());
self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis, Some(FUNC_BIN)); self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis.clone(), Some(FUNC_BIN));
self.register_builtin_py_impl(FUNC_BYTES, t_bytes, Immutable, vis, Some(FUNC_BYTES)); self.register_builtin_py_impl(
self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis, Some(FUNC_CHR)); FUNC_BYTES,
self.register_builtin_py_impl(FUNC_CLASSOF, t_classof, Immutable, vis, Some(FUNC_TYPE)); t_bytes,
self.register_builtin_py_impl(FUNC_COMPILE, t_compile, Immutable, vis, Some(FUNC_COMPILE)); Immutable,
self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis); vis.clone(),
Some(FUNC_BYTES),
);
self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis.clone(), Some(FUNC_CHR));
self.register_builtin_py_impl(
FUNC_CLASSOF,
t_classof,
Immutable,
vis.clone(),
Some(FUNC_TYPE),
);
self.register_builtin_py_impl(
FUNC_COMPILE,
t_compile,
Immutable,
vis.clone(),
Some(FUNC_COMPILE),
);
self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis.clone());
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_ENUMERATE, FUNC_ENUMERATE,
t_enumerate, t_enumerate,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_ENUMERATE), Some(FUNC_ENUMERATE),
); );
self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis, Some(FUNC_EXIT)); self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis.clone(), Some(FUNC_EXIT));
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_ISINSTANCE, FUNC_ISINSTANCE,
t_isinstance, t_isinstance,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_ISINSTANCE), Some(FUNC_ISINSTANCE),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_ISSUBCLASS, FUNC_ISSUBCLASS,
t_issubclass, t_issubclass,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_ISSUBCLASS), Some(FUNC_ISSUBCLASS),
); );
self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis, Some(FUNC_ITER)); self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis.clone(), Some(FUNC_ITER));
self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis, Some(FUNC_LEN)); self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis.clone(), Some(FUNC_LEN));
self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis, Some(FUNC_MAP)); self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis.clone(), Some(FUNC_MAP));
self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis, Some(FUNC_MAX)); self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis.clone(), Some(FUNC_MAX));
self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis, Some(FUNC_MIN)); self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis.clone(), Some(FUNC_MIN));
self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis, None); // `not` is not a function in Python self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis.clone(), None); // `not` is not a function in Python
self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis, Some(FUNC_OCT)); self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis.clone(), Some(FUNC_OCT));
self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis, Some(FUNC_ORD)); self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis.clone(), Some(FUNC_ORD));
self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis, Some(FUNC_POW)); self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis.clone(), Some(FUNC_POW));
self.register_builtin_py_impl( self.register_builtin_py_impl(
PYIMPORT, PYIMPORT,
t_pyimport.clone(), t_pyimport.clone(),
Immutable, Immutable,
vis, vis.clone(),
Some(FUNDAMENTAL_IMPORT), Some(FUNDAMENTAL_IMPORT),
); );
self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis, Some(FUNC_QUIT)); self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis.clone(), Some(FUNC_QUIT));
self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis, Some(FUNC_REPR)); self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis.clone(), Some(FUNC_REPR));
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_REVERSED, FUNC_REVERSED,
t_reversed, t_reversed,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_REVERSED), Some(FUNC_REVERSED),
); );
self.register_builtin_py_impl(FUNC_ROUND, t_round, Immutable, vis, Some(FUNC_ROUND)); self.register_builtin_py_impl(
self.register_builtin_py_impl(FUNC_SORTED, t_sorted, Immutable, vis, Some(FUNC_SORTED)); FUNC_ROUND,
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis, Some(FUNC_STR__)); t_round,
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis, Some(FUNC_SUM)); Immutable,
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis, Some(FUNC_ZIP)); vis.clone(),
Some(FUNC_ROUND),
);
self.register_builtin_py_impl(
FUNC_SORTED,
t_sorted,
Immutable,
vis.clone(),
Some(FUNC_SORTED),
);
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis.clone(), Some(FUNC_STR__));
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis.clone(), Some(FUNC_SUM));
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis.clone(), Some(FUNC_ZIP));
let name = if cfg!(feature = "py_compatible") { let name = if cfg!(feature = "py_compatible") {
FUNC_INT FUNC_INT
} else { } else {
FUNC_INT__ FUNC_INT__
}; };
self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis, Some(name)); self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis.clone(), Some(name));
if !cfg!(feature = "py_compatible") { if !cfg!(feature = "py_compatible") {
self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis, Some(FUNC_IF__)); self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis.clone(), Some(FUNC_IF__));
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_DISCARD, FUNC_DISCARD,
t_discard, t_discard,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_DISCARD__), Some(FUNC_DISCARD__),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNC_IMPORT, FUNC_IMPORT,
t_import, t_import,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNDAMENTAL_IMPORT), Some(FUNDAMENTAL_IMPORT),
); );
self.register_builtin_py_impl(FUNC_LOG, t_log, Immutable, vis, Some(FUNC_PRINT)); self.register_builtin_py_impl(
self.register_builtin_py_impl(FUNC_NAT, t_nat, Immutable, vis, Some(FUNC_NAT__)); FUNC_LOG,
self.register_builtin_py_impl(FUNC_PANIC, t_panic, Immutable, vis, Some(FUNC_QUIT)); t_log,
Immutable,
vis.clone(),
Some(FUNC_PRINT),
);
self.register_builtin_py_impl(
FUNC_NAT,
t_nat,
Immutable,
vis.clone(),
Some(FUNC_NAT__),
);
self.register_builtin_py_impl(
FUNC_PANIC,
t_panic,
Immutable,
vis.clone(),
Some(FUNC_QUIT),
);
if cfg!(feature = "debug") { if cfg!(feature = "debug") {
self.register_builtin_py_impl( self.register_builtin_py_impl(
PY, PY,
t_pyimport, t_pyimport,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNDAMENTAL_IMPORT), Some(FUNDAMENTAL_IMPORT),
); );
} }
@ -319,7 +365,7 @@ impl Context {
PYCOMPILE, PYCOMPILE,
t_pycompile, t_pycompile,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNC_COMPILE), Some(FUNC_COMPILE),
); );
// TODO: original implementation // TODO: original implementation
@ -340,7 +386,13 @@ impl Context {
], ],
poly(RANGE, vec![ty_tp(Int)]), poly(RANGE, vec![ty_tp(Int)]),
); );
self.register_builtin_py_impl(FUNC_RANGE, t_range, Immutable, vis, Some(FUNC_RANGE)); self.register_builtin_py_impl(
FUNC_RANGE,
t_range,
Immutable,
vis.clone(),
Some(FUNC_RANGE),
);
let t_list = func( let t_list = func(
vec![], vec![],
None, None,
@ -348,7 +400,13 @@ impl Context {
poly(ARRAY, vec![ty_tp(T.clone()), TyParam::erased(Nat)]), poly(ARRAY, vec![ty_tp(T.clone()), TyParam::erased(Nat)]),
) )
.quantify(); .quantify();
self.register_builtin_py_impl(FUNC_LIST, t_list, Immutable, vis, Some(FUNC_LIST)); self.register_builtin_py_impl(
FUNC_LIST,
t_list,
Immutable,
vis.clone(),
Some(FUNC_LIST),
);
let t_dict = func( let t_dict = func(
vec![], vec![],
None, None,
@ -365,9 +423,9 @@ impl Context {
pub(super) fn init_builtin_const_funcs(&mut self) { pub(super) fn init_builtin_const_funcs(&mut self) {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
let class_t = func( let class_t = func(
vec![], vec![],
@ -376,7 +434,7 @@ impl Context {
ClassType, ClassType,
); );
let class = ConstSubr::Builtin(BuiltinConstSubr::new(CLASS, class_func, class_t, None)); let class = ConstSubr::Builtin(BuiltinConstSubr::new(CLASS, class_func, class_t, None));
self.register_builtin_const(CLASS, vis, ValueObj::Subr(class)); self.register_builtin_const(CLASS, vis.clone(), ValueObj::Subr(class));
let inherit_t = func( let inherit_t = func(
vec![kw(KW_SUPER, ClassType)], vec![kw(KW_SUPER, ClassType)],
None, None,
@ -389,7 +447,7 @@ impl Context {
inherit_t, inherit_t,
None, None,
)); ));
self.register_builtin_const(INHERIT, vis, ValueObj::Subr(inherit)); self.register_builtin_const(INHERIT, vis.clone(), ValueObj::Subr(inherit));
let trait_t = func( let trait_t = func(
vec![kw(KW_REQUIREMENT, Type)], vec![kw(KW_REQUIREMENT, Type)],
None, None,
@ -397,7 +455,7 @@ impl Context {
TraitType, TraitType,
); );
let trait_ = ConstSubr::Builtin(BuiltinConstSubr::new(TRAIT, trait_func, trait_t, None)); let trait_ = ConstSubr::Builtin(BuiltinConstSubr::new(TRAIT, trait_func, trait_t, None));
self.register_builtin_const(TRAIT, vis, ValueObj::Subr(trait_)); self.register_builtin_const(TRAIT, vis.clone(), ValueObj::Subr(trait_));
let subsume_t = func( let subsume_t = func(
vec![kw(KW_SUPER, TraitType)], vec![kw(KW_SUPER, TraitType)],
None, None,
@ -410,14 +468,14 @@ impl Context {
subsume_t, subsume_t,
None, None,
)); ));
self.register_builtin_const(SUBSUME, vis, ValueObj::Subr(subsume)); self.register_builtin_const(SUBSUME, vis.clone(), ValueObj::Subr(subsume));
let structural = ConstSubr::Builtin(BuiltinConstSubr::new( let structural = ConstSubr::Builtin(BuiltinConstSubr::new(
STRUCTURAL, STRUCTURAL,
structural_func, structural_func,
func1(Type, Type), func1(Type, Type),
None, None,
)); ));
self.register_builtin_const(STRUCTURAL, vis, ValueObj::Subr(structural)); self.register_builtin_const(STRUCTURAL, vis.clone(), ValueObj::Subr(structural));
// decorators // decorators
let inheritable_t = func1(ClassType, ClassType); let inheritable_t = func1(ClassType, ClassType);
let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new( let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new(
@ -426,10 +484,10 @@ impl Context {
inheritable_t, inheritable_t,
None, None,
)); ));
self.register_builtin_const(INHERITABLE, vis, ValueObj::Subr(inheritable)); self.register_builtin_const(INHERITABLE, vis.clone(), ValueObj::Subr(inheritable));
// TODO: register Del function object // TODO: register Del function object
let t_del = nd_func(vec![kw(KW_OBJ, Obj)], None, NoneType); let t_del = nd_func(vec![kw(KW_OBJ, Obj)], None, NoneType);
self.register_builtin_erg_impl(DEL, t_del, Immutable, vis); self.register_builtin_erg_impl(DEL, t_del, Immutable, vis.clone());
let patch_t = func( let patch_t = func(
vec![kw(KW_REQUIREMENT, Type)], vec![kw(KW_REQUIREMENT, Type)],
None, None,
@ -451,65 +509,65 @@ impl Context {
proj(L, OUTPUT), proj(L, OUTPUT),
) )
.quantify(); .quantify();
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private); self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE);
let L = mono_q(TY_L, subtypeof(poly(SUB, params.clone()))); let L = mono_q(TY_L, subtypeof(poly(SUB, params.clone())));
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private); self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE);
let L = mono_q(TY_L, subtypeof(poly(MUL, params.clone()))); let L = mono_q(TY_L, subtypeof(poly(MUL, params.clone())));
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private); self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE);
let L = mono_q(TY_L, subtypeof(poly(DIV, params.clone()))); let L = mono_q(TY_L, subtypeof(poly(DIV, params.clone())));
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private); self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
let L = mono_q(TY_L, subtypeof(poly(FLOOR_DIV, params))); let L = mono_q(TY_L, subtypeof(poly(FLOOR_DIV, params)));
let op_t = bin_op(L.clone(), R, proj(L, OUTPUT)).quantify(); let op_t = bin_op(L.clone(), R, proj(L, OUTPUT)).quantify();
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private); self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
let P = mono_q(TY_P, Constraint::Uninited); let P = mono_q(TY_P, Constraint::Uninited);
let P = mono_q(TY_P, subtypeof(poly(MUL, vec![ty_tp(P)]))); let P = mono_q(TY_P, subtypeof(poly(MUL, vec![ty_tp(P)])));
let op_t = bin_op(P.clone(), P.clone(), proj(P, POW_OUTPUT)).quantify(); let op_t = bin_op(P.clone(), P.clone(), proj(P, POW_OUTPUT)).quantify();
// TODO: add bound: M == M.Output // TODO: add bound: M == M.Output
self.register_builtin_erg_impl(OP_POW, op_t, Const, Private); self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE);
let M = mono_q(TY_M, Constraint::Uninited); let M = mono_q(TY_M, Constraint::Uninited);
let M = mono_q(TY_M, subtypeof(poly(DIV, vec![ty_tp(M)]))); let M = mono_q(TY_M, subtypeof(poly(DIV, vec![ty_tp(M)])));
let op_t = bin_op(M.clone(), M.clone(), proj(M, MOD_OUTPUT)).quantify(); let op_t = bin_op(M.clone(), M.clone(), proj(M, MOD_OUTPUT)).quantify();
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private); self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool); let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool);
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private); self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE);
let E = mono_q(TY_E, subtypeof(mono(EQ))); let E = mono_q(TY_E, subtypeof(mono(EQ)));
let op_t = bin_op(E.clone(), E, Bool).quantify(); let op_t = bin_op(E.clone(), E, Bool).quantify();
self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_NE, op_t, Const, Private); self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let O = mono_q(TY_O, subtypeof(mono(ORD))); let O = mono_q(TY_O, subtypeof(mono(ORD)));
let op_t = bin_op(O.clone(), O.clone(), Bool).quantify(); let op_t = bin_op(O.clone(), O.clone(), Bool).quantify();
self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_GE, op_t, Const, Private); self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let BT = mono_q(TY_BT, subtypeof(or(Bool, Type))); let BT = mono_q(TY_BT, subtypeof(or(Bool, Type)));
let op_t = bin_op(BT.clone(), BT.clone(), BT).quantify(); let op_t = bin_op(BT.clone(), BT.clone(), BT).quantify();
self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_OR, op_t, Const, Private); self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = bin_op(O.clone(), O.clone(), range(O)).quantify(); let op_t = bin_op(O.clone(), O.clone(), range(O)).quantify();
self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Private); self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Private); self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Private); self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_decl(OP_ORNG, op_t, Private); self.register_builtin_erg_decl(OP_ORNG, op_t, Visibility::BUILTIN_PRIVATE);
// TODO: use existential type: |T: Type| (T, In(T)) -> Bool // TODO: use existential type: |T: Type| (T, In(T)) -> Bool
let T = mono_q(TY_T, instanceof(Type)); let T = mono_q(TY_T, instanceof(Type));
let I = mono_q(KW_I, subtypeof(poly(IN, vec![ty_tp(T.clone())]))); let I = mono_q(KW_I, subtypeof(poly(IN, vec![ty_tp(T.clone())])));
let op_t = bin_op(I, T, Bool).quantify(); let op_t = bin_op(I, T, Bool).quantify();
self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Private); self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Visibility::BUILTIN_PRIVATE);
/* unary */ /* unary */
// TODO: +/- Bool would like to be warned // TODO: +/- Bool would like to be warned
let M = mono_q(TY_M, subtypeof(mono(MUTIZABLE))); let M = mono_q(TY_M, subtypeof(mono(MUTIZABLE)));
let op_t = func1(M.clone(), proj(M, MUTABLE_MUT_TYPE)).quantify(); let op_t = func1(M.clone(), proj(M, MUTABLE_MUT_TYPE)).quantify();
self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Private); self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let N = mono_q(TY_N, subtypeof(mono(NUM))); let N = mono_q(TY_N, subtypeof(mono(NUM)));
let op_t = func1(N.clone(), N).quantify(); let op_t = func1(N.clone(), N).quantify();
self.register_builtin_erg_decl(OP_POS, op_t.clone(), Private); self.register_builtin_erg_decl(OP_POS, op_t.clone(), Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_decl(OP_NEG, op_t, Private); self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE);
} }
pub(super) fn init_py_builtin_operators(&mut self) { pub(super) fn init_py_builtin_operators(&mut self) {
@ -525,7 +583,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private); self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__sub__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__sub__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -533,7 +591,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private); self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__mul__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__mul__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -541,7 +599,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private); self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__div__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__div__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -549,7 +607,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private); self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__floordiv__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__floordiv__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -557,7 +615,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private); self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__pow__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__pow__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -565,7 +623,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_POW, op_t, Const, Private); self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__mod__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__mod__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -573,10 +631,10 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private); self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool); let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool);
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private); self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private); self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__eq__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__eq__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -584,7 +642,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_EQ, op_t, Const, Private); self.register_builtin_erg_impl(OP_EQ, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__ne__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__ne__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -592,7 +650,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_NE, op_t, Const, Private); self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__lt__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__lt__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -600,7 +658,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_LT, op_t, Const, Private); self.register_builtin_erg_impl(OP_LT, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__le__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__le__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -608,7 +666,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_LE, op_t, Const, Private); self.register_builtin_erg_impl(OP_LE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__gt__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__gt__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -616,7 +674,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_GT, op_t, Const, Private); self.register_builtin_erg_impl(OP_GT, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__ge__".into()) => fn1_met(Never, R.clone(), Bool) }, dict! { Field::public("__ge__".into()) => fn1_met(Never, R.clone(), Bool) },
@ -624,7 +682,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), Bool).quantify() bin_op(S, R.clone(), Bool).quantify()
}; };
self.register_builtin_erg_impl(OP_GE, op_t, Const, Private); self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__and__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__and__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -632,7 +690,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O.clone()).quantify() bin_op(S, R.clone(), O.clone()).quantify()
}; };
self.register_builtin_erg_impl(OP_AND, op_t, Const, Private); self.register_builtin_erg_impl(OP_AND, op_t, Const, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = Type::from( let S = Type::from(
dict! { Field::public("__or__".into()) => fn1_met(Never, R.clone(), O.clone()) }, dict! { Field::public("__or__".into()) => fn1_met(Never, R.clone(), O.clone()) },
@ -640,7 +698,7 @@ impl Context {
.structuralize(); .structuralize();
bin_op(S, R.clone(), O).quantify() bin_op(S, R.clone(), O).quantify()
}; };
self.register_builtin_erg_impl(OP_OR, op_t, Const, Private); self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE);
/* unary */ /* unary */
let op_t = { let op_t = {
let S = let S =
@ -648,13 +706,13 @@ impl Context {
.structuralize(); .structuralize();
func1(S, R.clone()).quantify() func1(S, R.clone()).quantify()
}; };
self.register_builtin_erg_decl(OP_POS, op_t, Private); self.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PRIVATE);
let op_t = { let op_t = {
let S = let S =
Type::from(dict! { Field::public("__neg__".into()) => fn0_met(Never, R.clone()) }) Type::from(dict! { Field::public("__neg__".into()) => fn0_met(Never, R.clone()) })
.structuralize(); .structuralize();
func1(S, R).quantify() func1(S, R).quantify()
}; };
self.register_builtin_erg_decl(OP_NEG, op_t, Private); self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE);
} }
} }

View file

@ -18,28 +18,26 @@ use erg_common::error::Location;
use erg_common::fresh::fresh_varname; use erg_common::fresh::fresh_varname;
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
use erg_common::{set, unique_in_place}; use erg_common::{set, unique_in_place};
use erg_parser::ast::VarName; use erg_parser::ast::VarName;
use crate::context::initialize::const_func::*; use crate::context::initialize::const_func::*;
use crate::context::instantiate::ConstTemplate; use crate::context::instantiate_spec::ConstTemplate;
use crate::context::{ use crate::context::{
ClassDefType, Context, ContextKind, MethodInfo, ModuleContext, ParamSpec, TraitImpl, ClassDefType, Context, ContextKind, MethodInfo, ModuleContext, ParamSpec, TraitImpl,
}; };
use crate::module::SharedCompilerResource; use crate::module::SharedCompilerResource;
use crate::ty::free::Constraint; use crate::ty::free::Constraint;
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::Type;
use crate::ty::{constructors::*, BuiltinConstSubr, ConstSubr, Predicate}; use crate::ty::{constructors::*, BuiltinConstSubr, ConstSubr, Predicate};
use crate::ty::{Type, Visibility};
use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
use Mutability::*; use Mutability::*;
use ParamSpec as PS; use ParamSpec as PS;
use Type::*; use Type::*;
use VarKind::*; use VarKind::*;
use Visibility::*;
const NUM: &str = "Num"; const NUM: &str = "Num";
@ -543,7 +541,7 @@ impl Context {
); );
if let Some(_vi) = self.locals.get(&name) { if let Some(_vi) = self.locals.get(&name) {
if _vi != &vi { if _vi != &vi {
panic!("already registered: {} {name}", self.name); unreachable!("already registered: {} {name}", self.name);
} }
} else { } else {
self.locals.insert(name, vi); self.locals.insert(name, vi);
@ -599,9 +597,9 @@ impl Context {
VarName::from_static(name) VarName::from_static(name)
}; };
let vis = if cfg!(feature = "py_compatible") || &self.name[..] != "<builtins>" { let vis = if cfg!(feature = "py_compatible") || &self.name[..] != "<builtins>" {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
let muty = Immutable; let muty = Immutable;
let loc = Location::range(lineno, 0, lineno, name.inspect().len() as u32); let loc = Location::range(lineno, 0, lineno, name.inspect().len() as u32);
@ -859,50 +857,56 @@ impl Context {
fn init_builtin_consts(&mut self) { fn init_builtin_consts(&mut self) {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
// TODO: this is not a const, but a special property // TODO: this is not a const, but a special property
self.register_builtin_py_impl( self.register_builtin_py_impl(
FUNDAMENTAL_NAME, FUNDAMENTAL_NAME,
Str, Str,
Immutable, Immutable,
vis, vis.clone(),
Some(FUNDAMENTAL_NAME), Some(FUNDAMENTAL_NAME),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
LICENSE, LICENSE,
mono(SITEBUILTINS_PRINTER), mono(SITEBUILTINS_PRINTER),
Immutable, Immutable,
vis, vis.clone(),
Some(LICENSE), Some(LICENSE),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
CREDITS, CREDITS,
mono(SITEBUILTINS_PRINTER), mono(SITEBUILTINS_PRINTER),
Immutable, Immutable,
vis, vis.clone(),
Some(CREDITS), Some(CREDITS),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
COPYRIGHT, COPYRIGHT,
mono(SITEBUILTINS_PRINTER), mono(SITEBUILTINS_PRINTER),
Immutable, Immutable,
vis, vis.clone(),
Some(COPYRIGHT), Some(COPYRIGHT),
); );
self.register_builtin_py_impl( self.register_builtin_py_impl(
NOT_IMPLEMENTED, NOT_IMPLEMENTED,
NotImplementedType, NotImplementedType,
Const, Const,
vis, vis.clone(),
Some(NOT_IMPLEMENTED), Some(NOT_IMPLEMENTED),
); );
self.register_builtin_py_impl(ELLIPSIS, Ellipsis, Const, vis, Some(ELLIPSIS)); self.register_builtin_py_impl(ELLIPSIS, Ellipsis, Const, vis, Some(ELLIPSIS));
self.register_builtin_py_impl(TRUE, Bool, Const, Private, Some(TRUE)); self.register_builtin_py_impl(TRUE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(TRUE));
self.register_builtin_py_impl(FALSE, Bool, Const, Private, Some(FALSE)); self.register_builtin_py_impl(FALSE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(FALSE));
self.register_builtin_py_impl(NONE, NoneType, Const, Private, Some(NONE)); self.register_builtin_py_impl(
NONE,
NoneType,
Const,
Visibility::BUILTIN_PRIVATE,
Some(NONE),
);
} }
pub(crate) fn init_builtins(cfg: ErgConfig, shared: SharedCompilerResource) { pub(crate) fn init_builtins(cfg: ErgConfig, shared: SharedCompilerResource) {

View file

@ -1,18 +1,16 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::vis::Visibility;
use crate::ty::constructors::*; use crate::ty::constructors::*;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::Type; use crate::ty::{Type, Visibility};
use Type::*; use Type::*;
use crate::context::initialize::*; use crate::context::initialize::*;
use crate::context::Context; use crate::context::Context;
use crate::varinfo::Mutability; use crate::varinfo::Mutability;
use Mutability::*; use Mutability::*;
use Visibility::*;
impl Context { impl Context {
pub(super) fn init_builtin_patches(&mut self) { pub(super) fn init_builtin_patches(&mut self) {
@ -38,10 +36,10 @@ impl Context {
) )
.quantify(); .quantify();
let mut interval_add = Self::builtin_methods(Some(impls), 2); let mut interval_add = Self::builtin_methods(Some(impls), 2);
interval_add.register_builtin_erg_impl("__add__", op_t, Const, Public); interval_add.register_builtin_erg_impl("__add__", op_t, Const, Visibility::BUILTIN_PUBLIC);
interval_add.register_builtin_const( interval_add.register_builtin_const(
"Output", "Output",
Public, Visibility::BUILTIN_PUBLIC,
ValueObj::builtin_t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())), ValueObj::builtin_t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())),
); );
interval.register_trait(class.clone(), interval_add); interval.register_trait(class.clone(), interval_add);
@ -53,18 +51,18 @@ impl Context {
Type::from(m.clone() - p.clone()..=n.clone() - o.clone()), Type::from(m.clone() - p.clone()..=n.clone() - o.clone()),
) )
.quantify(); .quantify();
interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Public); interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Visibility::BUILTIN_PUBLIC);
interval_sub.register_builtin_const( interval_sub.register_builtin_const(
"Output", "Output",
Public, Visibility::BUILTIN_PUBLIC,
ValueObj::builtin_t(Type::from(m - p..=n - o)), ValueObj::builtin_t(Type::from(m - p..=n - o)),
); );
interval.register_trait(class, interval_sub); interval.register_trait(class, interval_sub);
self.register_builtin_patch("Interval", interval, Private, Const); self.register_builtin_patch("Interval", interval, Visibility::BUILTIN_PRIVATE, Const);
// eq.register_impl("__ne__", op_t, Const, Public); // eq.register_impl("__ne__", op_t, Const, Visibility::BUILTIN_PUBLIC);
// ord.register_impl("__le__", op_t.clone(), Const, Public); // ord.register_impl("__le__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC);
// ord.register_impl("__gt__", op_t.clone(), Const, Public); // ord.register_impl("__gt__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC);
// ord.register_impl("__ge__", op_t, Const, Public); // ord.register_impl("__ge__", op_t, Const, Visibility::BUILTIN_PUBLIC);
let E = mono_q("E", subtypeof(mono("Eq"))); let E = mono_q("E", subtypeof(mono("Eq")));
let base = or(E, NoneType); let base = or(E, NoneType);
let impls = mono("Eq"); let impls = mono("Eq");
@ -73,8 +71,8 @@ impl Context {
Self::builtin_poly_glue_patch("OptionEq", base.clone(), impls.clone(), params, 1); Self::builtin_poly_glue_patch("OptionEq", base.clone(), impls.clone(), params, 1);
let mut option_eq_impl = Self::builtin_methods(Some(impls), 1); let mut option_eq_impl = Self::builtin_methods(Some(impls), 1);
let op_t = fn1_met(base.clone(), base.clone(), Bool).quantify(); let op_t = fn1_met(base.clone(), base.clone(), Bool).quantify();
option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Public); option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Visibility::BUILTIN_PUBLIC);
option_eq.register_trait(base, option_eq_impl); option_eq.register_trait(base, option_eq_impl);
self.register_builtin_patch("OptionEq", option_eq, Private, Const); self.register_builtin_patch("OptionEq", option_eq, Visibility::BUILTIN_PRIVATE, Const);
} }
} }

View file

@ -1,24 +1,22 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::vis::Visibility;
use crate::ty::constructors::*; use crate::ty::constructors::*;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::Type; use crate::ty::{Type, Visibility};
use Type::*; use Type::*;
use crate::context::initialize::*; use crate::context::initialize::*;
use crate::context::Context; use crate::context::Context;
use crate::varinfo::Mutability; use crate::varinfo::Mutability;
use Mutability::*; use Mutability::*;
use Visibility::*;
impl Context { impl Context {
pub(super) fn init_builtin_procs(&mut self) { pub(super) fn init_builtin_procs(&mut self) {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
let T = mono_q("T", instanceof(Type)); let T = mono_q("T", instanceof(Type));
let U = mono_q("U", instanceof(Type)); let U = mono_q("U", instanceof(Type));
@ -119,32 +117,38 @@ impl Context {
U, U,
) )
.quantify(); .quantify();
self.register_builtin_py_impl("dir!", t_dir, Immutable, vis, Some("dir")); self.register_builtin_py_impl("dir!", t_dir, Immutable, vis.clone(), Some("dir"));
self.register_py_builtin("print!", t_print, Some("print"), 81); self.register_py_builtin("print!", t_print, Some("print"), 81);
self.register_builtin_py_impl("id!", t_id, Immutable, vis, Some("id")); self.register_builtin_py_impl("id!", t_id, Immutable, vis.clone(), Some("id"));
self.register_builtin_py_impl("input!", t_input, Immutable, vis, Some("input")); self.register_builtin_py_impl("input!", t_input, Immutable, vis.clone(), Some("input"));
self.register_builtin_py_impl("globals!", t_globals, Immutable, vis, Some("globals")); self.register_builtin_py_impl(
self.register_builtin_py_impl("locals!", t_locals, Immutable, vis, Some("locals")); "globals!",
self.register_builtin_py_impl("next!", t_next, Immutable, vis, Some("next")); t_globals,
Immutable,
vis.clone(),
Some("globals"),
);
self.register_builtin_py_impl("locals!", t_locals, Immutable, vis.clone(), Some("locals"));
self.register_builtin_py_impl("next!", t_next, Immutable, vis.clone(), Some("next"));
self.register_py_builtin("open!", t_open, Some("open"), 198); self.register_py_builtin("open!", t_open, Some("open"), 198);
let name = if cfg!(feature = "py_compatible") { let name = if cfg!(feature = "py_compatible") {
"if" "if"
} else { } else {
"if__" "if__"
}; };
self.register_builtin_py_impl("if!", t_if, Immutable, vis, Some(name)); self.register_builtin_py_impl("if!", t_if, Immutable, vis.clone(), Some(name));
let name = if cfg!(feature = "py_compatible") { let name = if cfg!(feature = "py_compatible") {
"for" "for"
} else { } else {
"for__" "for__"
}; };
self.register_builtin_py_impl("for!", t_for, Immutable, vis, Some(name)); self.register_builtin_py_impl("for!", t_for, Immutable, vis.clone(), Some(name));
let name = if cfg!(feature = "py_compatible") { let name = if cfg!(feature = "py_compatible") {
"while" "while"
} else { } else {
"while__" "while__"
}; };
self.register_builtin_py_impl("while!", t_while, Immutable, vis, Some(name)); self.register_builtin_py_impl("while!", t_while, Immutable, vis.clone(), Some(name));
let name = if cfg!(feature = "py_compatible") { let name = if cfg!(feature = "py_compatible") {
"with" "with"
} else { } else {

View file

@ -1,11 +1,10 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::vis::Visibility;
use crate::ty::constructors::*; use crate::ty::constructors::*;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::Type; use crate::ty::{Type, Visibility};
use ParamSpec as PS; use ParamSpec as PS;
use Type::*; use Type::*;
@ -14,7 +13,6 @@ use crate::context::{ConstTemplate, Context, DefaultInfo, ParamSpec};
use crate::varinfo::Mutability; use crate::varinfo::Mutability;
use DefaultInfo::*; use DefaultInfo::*;
use Mutability::*; use Mutability::*;
use Visibility::*;
impl Context { impl Context {
/// see std/prelude.er /// see std/prelude.er
@ -24,9 +22,9 @@ impl Context {
// push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する // push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する
pub(super) fn init_builtin_traits(&mut self) { pub(super) fn init_builtin_traits(&mut self) {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::BUILTIN_PRIVATE
}; };
let unpack = Self::builtin_mono_trait(UNPACK, 2); let unpack = Self::builtin_mono_trait(UNPACK, 2);
let inheritable_type = Self::builtin_mono_trait(INHERITABLE_TYPE, 2); let inheritable_type = Self::builtin_mono_trait(INHERITABLE_TYPE, 2);
@ -36,25 +34,35 @@ impl Context {
let immut_t = proj(Slf.clone(), IMMUT_TYPE); let immut_t = proj(Slf.clone(), IMMUT_TYPE);
let f_t = func(vec![kw(KW_OLD, immut_t.clone())], None, vec![], immut_t); let f_t = func(vec![kw(KW_OLD, immut_t.clone())], None, vec![], immut_t);
let t = pr1_met(ref_mut(Slf, None), f_t, NoneType).quantify(); let t = pr1_met(ref_mut(Slf, None), f_t, NoneType).quantify();
mutable.register_builtin_erg_decl(PROC_UPDATE, t, Public); mutable.register_builtin_erg_decl(PROC_UPDATE, t, Visibility::BUILTIN_PUBLIC);
// REVIEW: Immutatable? // REVIEW: Immutatable?
let mut immutizable = Self::builtin_mono_trait(IMMUTIZABLE, 2); let mut immutizable = Self::builtin_mono_trait(IMMUTIZABLE, 2);
immutizable.register_superclass(mono(MUTABLE), &mutable); immutizable.register_superclass(mono(MUTABLE), &mutable);
immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Public); immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Visibility::BUILTIN_PUBLIC);
// REVIEW: Mutatable? // REVIEW: Mutatable?
let mut mutizable = Self::builtin_mono_trait(MUTIZABLE, 2); let mut mutizable = Self::builtin_mono_trait(MUTIZABLE, 2);
mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Public); mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Visibility::BUILTIN_PUBLIC);
let pathlike = Self::builtin_mono_trait(PATH_LIKE, 2); let pathlike = Self::builtin_mono_trait(PATH_LIKE, 2);
/* Readable */ /* Readable */
let mut readable = Self::builtin_mono_trait(MUTABLE_READABLE, 2); let mut readable = Self::builtin_mono_trait(MUTABLE_READABLE, 2);
let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_READABLE))); let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_READABLE)));
let t_read = pr_met(ref_mut(Slf, None), vec![], None, vec![kw(KW_N, Int)], Str).quantify(); let t_read = pr_met(ref_mut(Slf, None), vec![], None, vec![kw(KW_N, Int)], Str).quantify();
readable.register_builtin_py_decl(PROC_READ, t_read, Public, Some(FUNC_READ)); readable.register_builtin_py_decl(
PROC_READ,
t_read,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_READ),
);
/* Writable */ /* Writable */
let mut writable = Self::builtin_mono_trait(MUTABLE_WRITABLE, 2); let mut writable = Self::builtin_mono_trait(MUTABLE_WRITABLE, 2);
let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_WRITABLE))); let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_WRITABLE)));
let t_write = pr1_kw_met(ref_mut(Slf, None), kw("s", Str), Nat).quantify(); let t_write = pr1_kw_met(ref_mut(Slf, None), kw("s", Str), Nat).quantify();
writable.register_builtin_py_decl(PROC_WRITE, t_write, Public, Some(FUNC_WRITE)); writable.register_builtin_py_decl(
PROC_WRITE,
t_write,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_WRITE),
);
// TODO: Add required methods // TODO: Add required methods
let mut filelike = Self::builtin_mono_trait(FILE_LIKE, 2); let mut filelike = Self::builtin_mono_trait(FILE_LIKE, 2);
filelike.register_superclass(mono(READABLE), &readable); filelike.register_superclass(mono(READABLE), &readable);
@ -65,7 +73,12 @@ impl Context {
let mut show = Self::builtin_mono_trait(SHOW, 2); let mut show = Self::builtin_mono_trait(SHOW, 2);
let Slf = mono_q(SELF, subtypeof(mono(SHOW))); let Slf = mono_q(SELF, subtypeof(mono(SHOW)));
let t_show = fn0_met(ref_(Slf), Str).quantify(); let t_show = fn0_met(ref_(Slf), Str).quantify();
show.register_builtin_py_decl(TO_STR, t_show, Public, Some(FUNDAMENTAL_STR)); show.register_builtin_py_decl(
TO_STR,
t_show,
Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_STR),
);
/* In */ /* In */
let mut in_ = Self::builtin_poly_trait(IN, vec![PS::t_nd(TY_T)], 2); let mut in_ = Self::builtin_poly_trait(IN, vec![PS::t_nd(TY_T)], 2);
let params = vec![PS::t_nd(TY_T)]; let params = vec![PS::t_nd(TY_T)];
@ -75,7 +88,7 @@ impl Context {
let I = mono_q(TY_I, subtypeof(poly(IN, vec![ty_tp(T.clone())]))); let I = mono_q(TY_I, subtypeof(poly(IN, vec![ty_tp(T.clone())])));
in_.register_superclass(poly(INPUT, vec![ty_tp(T.clone())]), &input); in_.register_superclass(poly(INPUT, vec![ty_tp(T.clone())]), &input);
let op_t = fn1_met(T.clone(), I, Bool).quantify(); let op_t = fn1_met(T.clone(), I, Bool).quantify();
in_.register_builtin_erg_decl(OP_IN, op_t, Public); in_.register_builtin_erg_decl(OP_IN, op_t, Visibility::BUILTIN_PUBLIC);
/* Eq */ /* Eq */
// Erg does not have a trait equivalent to `PartialEq` in Rust // Erg does not have a trait equivalent to `PartialEq` in Rust
// This means, Erg's `Float` cannot be compared with other `Float` // This means, Erg's `Float` cannot be compared with other `Float`
@ -84,13 +97,13 @@ impl Context {
let Slf = mono_q(SELF, subtypeof(mono(EQ))); let Slf = mono_q(SELF, subtypeof(mono(EQ)));
// __eq__: |Self <: Eq| (self: Self, other: Self) -> Bool // __eq__: |Self <: Eq| (self: Self, other: Self) -> Bool
let op_t = fn1_met(Slf.clone(), Slf, Bool).quantify(); let op_t = fn1_met(Slf.clone(), Slf, Bool).quantify();
eq.register_builtin_erg_decl(OP_EQ, op_t, Public); eq.register_builtin_erg_decl(OP_EQ, op_t, Visibility::BUILTIN_PUBLIC);
/* Ord */ /* Ord */
let mut ord = Self::builtin_mono_trait(ORD, 2); let mut ord = Self::builtin_mono_trait(ORD, 2);
ord.register_superclass(mono(EQ), &eq); ord.register_superclass(mono(EQ), &eq);
let Slf = mono_q(SELF, subtypeof(mono(ORD))); let Slf = mono_q(SELF, subtypeof(mono(ORD)));
let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify(); let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify();
ord.register_builtin_erg_decl(OP_CMP, op_t, Public); ord.register_builtin_erg_decl(OP_CMP, op_t, Visibility::BUILTIN_PUBLIC);
// FIXME: poly trait // FIXME: poly trait
/* Num */ /* Num */
let num = Self::builtin_mono_trait(NUM, 2); let num = Self::builtin_mono_trait(NUM, 2);
@ -104,24 +117,29 @@ impl Context {
seq.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output); seq.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(SEQ, vec![TyParam::erased(Type)]))); let Slf = mono_q(SELF, subtypeof(poly(SEQ, vec![TyParam::erased(Type)])));
let t = fn0_met(Slf.clone(), Nat).quantify(); let t = fn0_met(Slf.clone(), Nat).quantify();
seq.register_builtin_erg_decl(FUNC_LEN, t, Public); seq.register_builtin_erg_decl(FUNC_LEN, t, Visibility::BUILTIN_PUBLIC);
let t = fn1_met(Slf, Nat, T.clone()).quantify(); let t = fn1_met(Slf, Nat, T.clone()).quantify();
// Seq.get: |Self <: Seq(T)| Self.(Nat) -> T // Seq.get: |Self <: Seq(T)| Self.(Nat) -> T
seq.register_builtin_erg_decl(FUNC_GET, t, Public); seq.register_builtin_erg_decl(FUNC_GET, t, Visibility::BUILTIN_PUBLIC);
/* Iterable */ /* Iterable */
let mut iterable = Self::builtin_poly_trait(ITERABLE, vec![PS::t_nd(TY_T)], 2); let mut iterable = Self::builtin_poly_trait(ITERABLE, vec![PS::t_nd(TY_T)], 2);
iterable.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output); iterable.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(ITERABLE, vec![ty_tp(T.clone())]))); let Slf = mono_q(SELF, subtypeof(poly(ITERABLE, vec![ty_tp(T.clone())])));
let t = fn0_met(Slf.clone(), proj(Slf, ITER)).quantify(); let t = fn0_met(Slf.clone(), proj(Slf, ITER)).quantify();
iterable.register_builtin_py_decl(FUNC_ITER, t, Public, Some(FUNDAMENTAL_ITER)); iterable.register_builtin_py_decl(
iterable.register_builtin_erg_decl(ITER, Type, Public); FUNC_ITER,
t,
Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_ITER),
);
iterable.register_builtin_erg_decl(ITER, Type, Visibility::BUILTIN_PUBLIC);
let mut context_manager = Self::builtin_mono_trait(CONTEXT_MANAGER, 2); let mut context_manager = Self::builtin_mono_trait(CONTEXT_MANAGER, 2);
let Slf = mono_q(SELF, subtypeof(mono(CONTEXT_MANAGER))); let Slf = mono_q(SELF, subtypeof(mono(CONTEXT_MANAGER)));
let t = fn0_met(Slf.clone(), NoneType).quantify(); let t = fn0_met(Slf.clone(), NoneType).quantify();
context_manager.register_builtin_py_decl( context_manager.register_builtin_py_decl(
FUNDAMENTAL_ENTER, FUNDAMENTAL_ENTER,
t, t,
Public, Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_ENTER), Some(FUNDAMENTAL_ENTER),
); );
let t = fn_met( let t = fn_met(
@ -139,7 +157,7 @@ impl Context {
context_manager.register_builtin_py_decl( context_manager.register_builtin_py_decl(
FUNDAMENTAL_EXIT, FUNDAMENTAL_EXIT,
t, t,
Public, Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_EXIT), Some(FUNDAMENTAL_EXIT),
); );
let R = mono_q(TY_R, instanceof(Type)); let R = mono_q(TY_R, instanceof(Type));
@ -152,111 +170,141 @@ impl Context {
add.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); add.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(ADD, ty_params.clone()))); let Slf = mono_q(SELF, subtypeof(poly(ADD, ty_params.clone())));
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
add.register_builtin_erg_decl(OP_ADD, op_t, Public); add.register_builtin_erg_decl(OP_ADD, op_t, Visibility::BUILTIN_PUBLIC);
add.register_builtin_erg_decl(OUTPUT, Type, Public); add.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* Sub */ /* Sub */
let mut sub = Self::builtin_poly_trait(SUB, params.clone(), 2); let mut sub = Self::builtin_poly_trait(SUB, params.clone(), 2);
sub.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); sub.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(SUB, ty_params.clone()))); let Slf = mono_q(SELF, subtypeof(poly(SUB, ty_params.clone())));
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
sub.register_builtin_erg_decl(OP_SUB, op_t, Public); sub.register_builtin_erg_decl(OP_SUB, op_t, Visibility::BUILTIN_PUBLIC);
sub.register_builtin_erg_decl(OUTPUT, Type, Public); sub.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* Mul */ /* Mul */
let mut mul = Self::builtin_poly_trait(MUL, params.clone(), 2); let mut mul = Self::builtin_poly_trait(MUL, params.clone(), 2);
mul.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); mul.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(MUL, ty_params.clone()))); let Slf = mono_q(SELF, subtypeof(poly(MUL, ty_params.clone())));
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
mul.register_builtin_erg_decl(OP_MUL, op_t, Public); mul.register_builtin_erg_decl(OP_MUL, op_t, Visibility::BUILTIN_PUBLIC);
mul.register_builtin_erg_decl(OUTPUT, Type, Public); mul.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* Div */ /* Div */
let mut div = Self::builtin_poly_trait(DIV, params.clone(), 2); let mut div = Self::builtin_poly_trait(DIV, params.clone(), 2);
div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(DIV, ty_params.clone()))); let Slf = mono_q(SELF, subtypeof(poly(DIV, ty_params.clone())));
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
div.register_builtin_erg_decl(OP_DIV, op_t, Public); div.register_builtin_erg_decl(OP_DIV, op_t, Visibility::BUILTIN_PUBLIC);
div.register_builtin_erg_decl(OUTPUT, Type, Public); div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* FloorDiv */ /* FloorDiv */
let mut floor_div = Self::builtin_poly_trait(FLOOR_DIV, params, 2); let mut floor_div = Self::builtin_poly_trait(FLOOR_DIV, params, 2);
floor_div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); floor_div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
let Slf = mono_q(SELF, subtypeof(poly(FLOOR_DIV, ty_params.clone()))); let Slf = mono_q(SELF, subtypeof(poly(FLOOR_DIV, ty_params.clone())));
let op_t = fn1_met(Slf.clone(), R, proj(Slf.clone(), OUTPUT)).quantify(); let op_t = fn1_met(Slf.clone(), R, proj(Slf.clone(), OUTPUT)).quantify();
floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Public); floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Visibility::BUILTIN_PUBLIC);
floor_div.register_builtin_erg_decl(OUTPUT, Type, Public); floor_div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* Pos */ /* Pos */
let mut pos = Self::builtin_mono_trait(POS, 2); let mut pos = Self::builtin_mono_trait(POS, 2);
let _Slf = mono_q(SELF, subtypeof(mono(POS))); let _Slf = mono_q(SELF, subtypeof(mono(POS)));
let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify(); let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify();
pos.register_builtin_erg_decl(OP_POS, op_t, Public); pos.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PUBLIC);
pos.register_builtin_erg_decl(OUTPUT, Type, Public); pos.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
/* Neg */ /* Neg */
let mut neg = Self::builtin_mono_trait(NEG, 2); let mut neg = Self::builtin_mono_trait(NEG, 2);
let _Slf = mono_q(SELF, subtypeof(mono(NEG))); let _Slf = mono_q(SELF, subtypeof(mono(NEG)));
let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify(); let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify();
neg.register_builtin_erg_decl(OP_NEG, op_t, Public); neg.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PUBLIC);
neg.register_builtin_erg_decl(OUTPUT, Type, Public); neg.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
self.register_builtin_type(mono(UNPACK), unpack, vis, Const, None); self.register_builtin_type(mono(UNPACK), unpack, vis.clone(), Const, None);
self.register_builtin_type( self.register_builtin_type(
mono(INHERITABLE_TYPE), mono(INHERITABLE_TYPE),
inheritable_type, inheritable_type,
Private, Visibility::BUILTIN_PRIVATE,
Const, Const,
None, None,
); );
self.register_builtin_type(mono(NAMED), named, vis, Const, None); self.register_builtin_type(mono(NAMED), named, vis.clone(), Const, None);
self.register_builtin_type(mono(MUTABLE), mutable, vis, Const, None); self.register_builtin_type(mono(MUTABLE), mutable, vis.clone(), Const, None);
self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis, Const, None); self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis.clone(), Const, None);
self.register_builtin_type(mono(MUTIZABLE), mutizable, vis, Const, None); self.register_builtin_type(mono(MUTIZABLE), mutizable, vis.clone(), Const, None);
self.register_builtin_type(mono(PATH_LIKE), pathlike, vis, Const, None); self.register_builtin_type(mono(PATH_LIKE), pathlike, vis.clone(), Const, None);
self.register_builtin_type( self.register_builtin_type(
mono(MUTABLE_READABLE), mono(MUTABLE_READABLE),
readable, readable,
Private, Visibility::BUILTIN_PRIVATE,
Const, Const,
Some(READABLE), Some(READABLE),
); );
self.register_builtin_type( self.register_builtin_type(
mono(MUTABLE_WRITABLE), mono(MUTABLE_WRITABLE),
writable, writable,
Private, Visibility::BUILTIN_PRIVATE,
Const, Const,
Some(WRITABLE), Some(WRITABLE),
); );
self.register_builtin_type(mono(FILE_LIKE), filelike, vis, Const, None); self.register_builtin_type(mono(FILE_LIKE), filelike, vis.clone(), Const, None);
self.register_builtin_type(mono(MUTABLE_FILE_LIKE), filelike_mut, vis, Const, None); self.register_builtin_type(
self.register_builtin_type(mono(SHOW), show, vis, Const, None); mono(MUTABLE_FILE_LIKE),
filelike_mut,
vis.clone(),
Const,
None,
);
self.register_builtin_type(mono(SHOW), show, vis.clone(), Const, None);
self.register_builtin_type( self.register_builtin_type(
poly(INPUT, vec![ty_tp(T.clone())]), poly(INPUT, vec![ty_tp(T.clone())]),
input, input,
Private, Visibility::BUILTIN_PRIVATE,
Const, Const,
None, None,
); );
self.register_builtin_type( self.register_builtin_type(
poly(OUTPUT, vec![ty_tp(T.clone())]), poly(OUTPUT, vec![ty_tp(T.clone())]),
output, output,
Private, Visibility::BUILTIN_PRIVATE,
Const,
None,
);
self.register_builtin_type(
poly(IN, vec![ty_tp(T.clone())]),
in_,
Visibility::BUILTIN_PRIVATE,
Const,
None,
);
self.register_builtin_type(mono(EQ), eq, vis.clone(), Const, None);
self.register_builtin_type(mono(ORD), ord, vis.clone(), Const, None);
self.register_builtin_type(mono(NUM), num, vis.clone(), Const, None);
self.register_builtin_type(
poly(SEQ, vec![ty_tp(T.clone())]),
seq,
Visibility::BUILTIN_PRIVATE,
Const, Const,
None, None,
); );
self.register_builtin_type(poly(IN, vec![ty_tp(T.clone())]), in_, Private, Const, None);
self.register_builtin_type(mono(EQ), eq, vis, Const, None);
self.register_builtin_type(mono(ORD), ord, vis, Const, None);
self.register_builtin_type(mono(NUM), num, vis, Const, None);
self.register_builtin_type(poly(SEQ, vec![ty_tp(T.clone())]), seq, Private, Const, None);
self.register_builtin_type( self.register_builtin_type(
poly(ITERABLE, vec![ty_tp(T)]), poly(ITERABLE, vec![ty_tp(T)]),
iterable, iterable,
Private, Visibility::BUILTIN_PRIVATE,
Const, Const,
None, None,
); );
self.register_builtin_type(mono(CONTEXT_MANAGER), context_manager, Private, Const, None); self.register_builtin_type(
self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis, Const, None); mono(CONTEXT_MANAGER),
self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis, Const, None); context_manager,
self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis, Const, None); Visibility::BUILTIN_PRIVATE,
self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis, Const, None); Const,
self.register_builtin_type(poly(FLOOR_DIV, ty_params), floor_div, vis, Const, None); None,
self.register_builtin_type(mono(POS), pos, vis, Const, None); );
self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis.clone(), Const, None);
self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis.clone(), Const, None);
self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis.clone(), Const, None);
self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis.clone(), Const, None);
self.register_builtin_type(
poly(FLOOR_DIV, ty_params),
floor_div,
vis.clone(),
Const,
None,
);
self.register_builtin_type(mono(POS), pos, vis.clone(), Const, None);
self.register_builtin_type(mono(NEG), neg, vis, Const, None); self.register_builtin_type(mono(NEG), neg, vis, Const, None);
self.register_const_param_defaults( self.register_const_param_defaults(
ADD, ADD,

View file

@ -5,28 +5,27 @@ use std::path::{Path, PathBuf};
use erg_common::config::{ErgConfig, Input}; use erg_common::config::{ErgConfig, Input};
use erg_common::env::{erg_py_external_lib_path, erg_pystd_path, erg_std_path}; use erg_common::env::{erg_py_external_lib_path, erg_pystd_path, erg_std_path};
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage}; use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
use erg_common::levenshtein::get_similar_name; use erg_common::levenshtein;
use erg_common::pathutil::add_postfix_foreach; use erg_common::pathutil::add_postfix_foreach;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{Locational, NoTypeDisplay, Stream}; use erg_common::traits::{Locational, NoTypeDisplay, Stream};
use erg_common::vis::Visibility; use erg_common::triple::Triple;
use erg_common::Str; use erg_common::Str;
use erg_common::{ use erg_common::{
fmt_option, fmt_slice, log, normalize_path, option_enum_unwrap, set, switch_lang, fmt_option, fmt_slice, log, normalize_path, option_enum_unwrap, set, switch_lang,
}; };
use Type::*;
use ast::VarName; use erg_parser::ast::{self, Identifier, VarName};
use erg_parser::ast::{self, Identifier};
use erg_parser::token::Token; use erg_parser::token::Token;
use crate::ty::constructors::{anon, free_var, func, mono, poly, proc, proj, ref_, subr_t}; use crate::ty::constructors::{anon, free_var, func, mono, poly, proc, proj, ref_, subr_t};
use crate::ty::free::Constraint; use crate::ty::free::Constraint;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type}; use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type, Visibility};
use Type::*;
use crate::context::instantiate::ConstTemplate; use crate::context::instantiate_spec::ConstTemplate;
use crate::context::{Context, RegistrationMode, TraitImpl, TyVarCache, Variance}; use crate::context::{Context, RegistrationMode, TraitImpl, TyVarCache, Variance};
use crate::error::{ use crate::error::{
binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError, binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError,
@ -36,9 +35,8 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
use crate::{feature_error, hir}; use crate::{feature_error, hir};
use crate::{unreachable_error, AccessKind}; use crate::{unreachable_error, AccessKind};
use RegistrationMode::*; use RegistrationMode::*;
use Visibility::*;
use super::instantiate::ParamKind; use super::instantiate_spec::ParamKind;
use super::{ContextKind, MethodInfo}; use super::{ContextKind, MethodInfo};
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -105,7 +103,7 @@ impl Context {
pub fn get_singular_ctx_by_hir_expr( pub fn get_singular_ctx_by_hir_expr(
&self, &self,
obj: &hir::Expr, obj: &hir::Expr,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<&Context> { ) -> SingleTyCheckResult<&Context> {
match obj { match obj {
hir::Expr::Accessor(hir::Accessor::Ident(ident)) => { hir::Expr::Accessor(hir::Accessor::Ident(ident)) => {
@ -132,19 +130,22 @@ impl Context {
pub(crate) fn get_singular_ctx_by_ident( pub(crate) fn get_singular_ctx_by_ident(
&self, &self,
ident: &ast::Identifier, ident: &ast::Identifier,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<&Context> { ) -> SingleTyCheckResult<&Context> {
self.get_mod(ident.inspect()) self.get_mod(ident.inspect())
.or_else(|| self.rec_local_get_type(ident.inspect()).map(|(_, ctx)| ctx)) .or_else(|| self.rec_local_get_type(ident.inspect()).map(|(_, ctx)| ctx))
.or_else(|| self.rec_get_patch(ident.inspect())) .or_else(|| self.rec_get_patch(ident.inspect()))
.ok_or_else(|| { .ok_or_else(|| {
TyCheckError::no_var_error( let (similar_info, similar_name) =
self.get_similar_name_and_info(ident.inspect()).unzip();
TyCheckError::detailed_no_var_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.name.to_string(),
ident.inspect(), ident.inspect(),
self.get_similar_name(ident.inspect()), similar_name,
similar_info,
) )
}) })
} }
@ -170,7 +171,7 @@ impl Context {
pub(crate) fn get_singular_ctx( pub(crate) fn get_singular_ctx(
&self, &self,
obj: &ast::Expr, obj: &ast::Expr,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<&Context> { ) -> SingleTyCheckResult<&Context> {
match obj { match obj {
ast::Expr::Accessor(ast::Accessor::Ident(ident)) => { ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
@ -342,16 +343,16 @@ impl Context {
ident: &Identifier, ident: &Identifier,
acc_kind: AccessKind, acc_kind: AccessKind,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> Triple<VarInfo, TyCheckError> {
if let Some(vi) = self.get_current_scope_var(&ident.name) { if let Some(vi) = self.get_current_scope_var(&ident.name) {
match self.validate_visibility(ident, vi, input, namespace) { match self.validate_visibility(ident, vi, input, namespace) {
Ok(()) => { Ok(()) => {
return Ok(vi.clone()); return Triple::Ok(vi.clone());
} }
Err(err) => { Err(err) => {
if !acc_kind.is_local() { if !acc_kind.is_local() {
return Err(err); return Triple::Err(err);
} }
} }
} }
@ -359,21 +360,21 @@ impl Context {
.future_defined_locals .future_defined_locals
.get_key_value(&ident.inspect()[..]) .get_key_value(&ident.inspect()[..])
{ {
return Err(TyCheckError::access_before_def_error( return Triple::Err(TyCheckError::access_before_def_error(
input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.name.to_string(),
ident.inspect(), ident.inspect(),
name.ln_begin().unwrap_or(0), name.ln_begin().unwrap_or(0),
self.get_similar_name(ident.inspect()), self.get_similar_name(ident.inspect()),
)); ));
} else if let Some((name, _vi)) = self.deleted_locals.get_key_value(&ident.inspect()[..]) { } else if let Some((name, _vi)) = self.deleted_locals.get_key_value(&ident.inspect()[..]) {
return Err(TyCheckError::access_deleted_var_error( return Triple::Err(TyCheckError::access_deleted_var_error(
input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.name.to_string(),
ident.inspect(), ident.inspect(),
name.ln_begin().unwrap_or(0), name.ln_begin().unwrap_or(0),
self.get_similar_name(ident.inspect()), self.get_similar_name(ident.inspect()),
@ -381,20 +382,22 @@ impl Context {
} }
if acc_kind.is_local() { if acc_kind.is_local() {
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
return match parent.rec_get_var_info(ident, acc_kind, input, namespace) { return parent.rec_get_var_info(ident, acc_kind, input, namespace);
Ok(vi) => Ok(vi),
Err(err) => Err(err),
};
} }
} }
Err(TyCheckError::no_var_error( /*
let (similar_info, similar_name) = self.get_similar_name_and_info(ident.inspect()).unzip();
Err(TyCheckError::detailed_no_var_error(
input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.into(),
ident.inspect(), ident.inspect(),
self.get_similar_name(ident.inspect()), similar_name,
similar_info,
)) ))
*/
Triple::None
} }
pub(crate) fn rec_get_decl_info( pub(crate) fn rec_get_decl_info(
@ -402,8 +405,8 @@ impl Context {
ident: &Identifier, ident: &Identifier,
acc_kind: AccessKind, acc_kind: AccessKind,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> Triple<VarInfo, TyCheckError> {
if let Some(vi) = self if let Some(vi) = self
.decls .decls
.get(&ident.inspect()[..]) .get(&ident.inspect()[..])
@ -411,11 +414,11 @@ impl Context {
{ {
match self.validate_visibility(ident, vi, input, namespace) { match self.validate_visibility(ident, vi, input, namespace) {
Ok(()) => { Ok(()) => {
return Ok(vi.clone()); return Triple::Ok(vi.clone());
} }
Err(err) => { Err(err) => {
if !acc_kind.is_local() { if !acc_kind.is_local() {
return Err(err); return Triple::Err(err);
} }
} }
} }
@ -425,14 +428,15 @@ impl Context {
return parent.rec_get_decl_info(ident, acc_kind, input, namespace); return parent.rec_get_decl_info(ident, acc_kind, input, namespace);
} }
} }
Err(TyCheckError::no_var_error( /*Err(TyCheckError::no_var_error(
input.clone(), input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
namespace.into(), namespace.into(),
ident.inspect(), ident.inspect(),
self.get_similar_name(ident.inspect()), self.get_similar_name(ident.inspect()),
)) ))*/
Triple::None
} }
pub(crate) fn get_attr_info( pub(crate) fn get_attr_info(
@ -440,42 +444,48 @@ impl Context {
obj: &hir::Expr, obj: &hir::Expr,
ident: &Identifier, ident: &Identifier,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> Triple<VarInfo, TyCheckError> {
let self_t = obj.t(); let self_t = obj.t();
let name = ident.name.token(); match self.get_attr_info_from_attributive(&self_t, ident) {
match self.get_attr_info_from_attributive(&self_t, ident, namespace) { Triple::Ok(vi) => {
Ok(vi) => { return Triple::Ok(vi);
return Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::AttributeError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
if let Ok(singular_ctx) = self.get_singular_ctx_by_hir_expr(obj, namespace) { if let Ok(singular_ctx) = self.get_singular_ctx_by_hir_expr(obj, namespace) {
match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
Triple::None => {}
} }
} }
match self.get_attr_from_nominal_t(obj, ident, input, namespace) { match self.get_attr_from_nominal_t(obj, ident, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
if let Some(self_t) = vi.t.self_t() { if let Some(self_t) = vi.t.self_t() {
self.sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into())) match self
.map_err(|mut e| e.remove(0))?; .sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into()))
.map_err(|mut e| e.remove(0))
{
Ok(_) => {}
Err(e) => {
return Triple::Err(e);
}
}
} }
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::AttributeError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
for patch in self.find_patches_of(obj.ref_t()) { for patch in self.find_patches_of(obj.ref_t()) {
if let Some(vi) = patch if let Some(vi) = patch
@ -483,8 +493,10 @@ impl Context {
.get(ident.inspect()) .get(ident.inspect())
.or_else(|| patch.decls.get(ident.inspect())) .or_else(|| patch.decls.get(ident.inspect()))
{ {
self.validate_visibility(ident, vi, input, namespace)?; return match self.validate_visibility(ident, vi, input, namespace) {
return Ok(vi.clone()); Ok(_) => Triple::Ok(vi.clone()),
Err(e) => Triple::Err(e),
};
} }
for (_, methods_ctx) in patch.methods_list.iter() { for (_, methods_ctx) in patch.methods_list.iter() {
if let Some(vi) = methods_ctx if let Some(vi) = methods_ctx
@ -492,12 +504,15 @@ impl Context {
.get(ident.inspect()) .get(ident.inspect())
.or_else(|| methods_ctx.decls.get(ident.inspect())) .or_else(|| methods_ctx.decls.get(ident.inspect()))
{ {
self.validate_visibility(ident, vi, input, namespace)?; return match self.validate_visibility(ident, vi, input, namespace) {
return Ok(vi.clone()); Ok(_) => Triple::Ok(vi.clone()),
Err(e) => Triple::Err(e),
};
} }
} }
} }
Err(TyCheckError::no_attr_error( Triple::None
/*Err(TyCheckError::no_attr_error(
input.clone(), input.clone(),
line!() as usize, line!() as usize,
name.loc(), name.loc(),
@ -505,7 +520,7 @@ impl Context {
&self_t, &self_t,
name.inspect(), name.inspect(),
self.get_similar_attr(&self_t, name.inspect()), self.get_similar_attr(&self_t, name.inspect()),
)) ))*/
} }
fn get_attr_from_nominal_t( fn get_attr_from_nominal_t(
@ -513,39 +528,45 @@ impl Context {
obj: &hir::Expr, obj: &hir::Expr,
ident: &Identifier, ident: &Identifier,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> Triple<VarInfo, TyCheckError> {
let self_t = obj.t(); let self_t = obj.t();
if let Some(sups) = self.get_nominal_super_type_ctxs(&self_t) { if let Some(sups) = self.get_nominal_super_type_ctxs(&self_t) {
for ctx in sups { for ctx in sups {
match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
// if self is a methods context // if self is a methods context
if let Some(ctx) = self.get_same_name_context(&ctx.name) { if let Some(ctx) = self.get_same_name_context(&ctx.name) {
match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) { match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
} }
} }
} }
let coerced = self let coerced = match self
.deref_tyvar(obj.t(), Variance::Covariant, &set! {}, &()) .deref_tyvar(obj.t(), Variance::Covariant, &set! {}, &())
.map_err(|mut es| es.remove(0))?; .map_err(|mut es| es.remove(0))
{
Ok(t) => t,
Err(e) => {
return Triple::Err(e);
}
};
if obj.ref_t() != &coerced { if obj.ref_t() != &coerced {
for ctx in self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| { let ctxs = match self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| {
TyCheckError::type_not_found( TyCheckError::type_not_found(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -553,31 +574,37 @@ impl Context {
self.caused_by(), self.caused_by(),
&coerced, &coerced,
) )
})? { }) {
Ok(ctxs) => ctxs,
Err(e) => {
return Triple::Err(e);
}
};
for ctx in ctxs {
match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
obj.ref_t().coerce(); obj.ref_t().coerce();
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
if let Some(ctx) = self.get_same_name_context(&ctx.name) { if let Some(ctx) = self.get_same_name_context(&ctx.name) {
match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) { match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) {
Ok(vi) => { Triple::Ok(vi) => {
return Ok(vi); return Triple::Ok(vi);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => { return Triple::Err(e);
return Err(e);
} }
_ => {}
} }
} }
} }
} }
Err(TyCheckError::no_attr_error( /*Err(TyCheckError::no_attr_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
@ -585,7 +612,8 @@ impl Context {
&self_t, &self_t,
ident.inspect(), ident.inspect(),
self.get_similar_attr(&self_t, ident.inspect()), self.get_similar_attr(&self_t, ident.inspect()),
)) ))*/
Triple::None
} }
/// get type from given attributive type (Record). /// get type from given attributive type (Record).
@ -594,105 +622,43 @@ impl Context {
&self, &self,
t: &Type, t: &Type,
ident: &Identifier, ident: &Identifier,
namespace: &Str, ) -> Triple<VarInfo, TyCheckError> {
) -> SingleTyCheckResult<VarInfo> {
match t { match t {
// (obj: Never).foo: Never // (obj: Never).foo: Never
Type::Never => Ok(VarInfo::ILLEGAL.clone()), Type::Never => Triple::Ok(VarInfo::ILLEGAL.clone()),
Type::FreeVar(fv) if fv.is_linked() => { Type::FreeVar(fv) if fv.is_linked() => {
self.get_attr_info_from_attributive(&fv.crack(), ident, namespace) self.get_attr_info_from_attributive(&fv.crack(), ident)
} }
Type::FreeVar(fv) /* if fv.is_unbound() */ => { Type::FreeVar(fv) /* if fv.is_unbound() */ => {
let sup = fv.get_super().unwrap(); let sup = fv.get_super().unwrap();
self.get_attr_info_from_attributive(&sup, ident, namespace) self.get_attr_info_from_attributive(&sup, ident)
} }
Type::Ref(t) => self.get_attr_info_from_attributive(t, ident, namespace), Type::Ref(t) => self.get_attr_info_from_attributive(t, ident),
Type::RefMut { before, .. } => { Type::RefMut { before, .. } => {
self.get_attr_info_from_attributive(before, ident, namespace) self.get_attr_info_from_attributive(before, ident)
} }
Type::Refinement(refine) => { Type::Refinement(refine) => {
self.get_attr_info_from_attributive(&refine.t, ident, namespace) self.get_attr_info_from_attributive(&refine.t, ident)
} }
Type::Record(record) => { Type::Record(record) => {
if let Some(attr_t) = record.get(ident.inspect()) { if let Some((field, attr_t)) = record.get_key_value(ident.inspect()) {
let muty = Mutability::from(&ident.inspect()[..]); let muty = Mutability::from(&ident.inspect()[..]);
let vi = VarInfo::new( let vi = VarInfo::new(
attr_t.clone(), attr_t.clone(),
muty, muty,
Public, Visibility::new(field.vis.clone(), Str::ever("<dummy>")),
VarKind::Builtin, VarKind::Builtin,
None, None,
None, None,
None, None,
AbsLocation::unknown(), AbsLocation::unknown(),
); );
Ok(vi) if let Err(err) = self.validate_visibility(ident, &vi, &self.cfg.input, self) {
} else { return Triple::Err(err);
Err(TyCheckError::no_attr_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
namespace.into(),
t,
ident.inspect(),
self.get_similar_attr(t, ident.inspect()),
))
}
}
Type::Structural(t) => self.get_attr_info_from_attributive(t, ident, namespace),
other => {
if let Some(v) = self.rec_get_const_obj(&other.local_name()) {
match v {
ValueObj::Type(TypeObj::Generated(gen)) => self
.get_gen_t_require_attr_t(gen, &ident.inspect()[..])
.map(|attr_t| {
let muty = Mutability::from(&ident.inspect()[..]);
VarInfo::new(
attr_t.clone(),
muty,
Public,
VarKind::Builtin,
None,
None,
None,
AbsLocation::unknown(),
)
})
.ok_or_else(|| {
TyCheckError::no_attr_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
namespace.into(),
t,
ident.inspect(),
self.get_similar_attr(t, ident.inspect()),
)
}),
ValueObj::Type(TypeObj::Builtin(_t)) => {
// FIXME:
Err(TyCheckError::no_attr_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
namespace.into(),
_t,
ident.inspect(),
self.get_similar_attr(_t, ident.inspect()),
))
}
_other => Err(TyCheckError::no_attr_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
namespace.into(),
t,
ident.inspect(),
self.get_similar_attr(t, ident.inspect()),
)),
} }
Triple::Ok(vi)
} else { } else {
Err(TyCheckError::no_attr_error( /*Err(TyCheckError::no_attr_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
ident.loc(), ident.loc(),
@ -700,9 +666,12 @@ impl Context {
t, t,
ident.inspect(), ident.inspect(),
self.get_similar_attr(t, ident.inspect()), self.get_similar_attr(t, ident.inspect()),
)) ))*/
Triple::None
} }
} }
Type::Structural(t) => self.get_attr_info_from_attributive(t, ident),
_other => Triple::None,
} }
} }
@ -712,7 +681,7 @@ impl Context {
obj: &hir::Expr, obj: &hir::Expr,
attr_name: &Option<Identifier>, attr_name: &Option<Identifier>,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> SingleTyCheckResult<VarInfo> {
if obj.ref_t() == Type::FAILURE { if obj.ref_t() == Type::FAILURE {
// (...Obj) -> Failure // (...Obj) -> Failure
@ -750,10 +719,16 @@ impl Context {
obj: &hir::Expr, obj: &hir::Expr,
attr_name: &Identifier, attr_name: &Identifier,
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> SingleTyCheckResult<VarInfo> { ) -> SingleTyCheckResult<VarInfo> {
if let Ok(vi) = self.get_attr_info_from_attributive(obj.ref_t(), attr_name, namespace) { match self.get_attr_info_from_attributive(obj.ref_t(), attr_name) {
return Ok(vi); Triple::Ok(vi) => {
return Ok(vi);
}
Triple::Err(e) => {
return Err(e);
}
_ => {}
} }
for ctx in self for ctx in self
.get_nominal_super_type_ctxs(obj.ref_t()) .get_nominal_super_type_ctxs(obj.ref_t())
@ -787,13 +762,13 @@ impl Context {
} }
if let Some(ctx) = self.get_same_name_context(&ctx.name) { if let Some(ctx) = self.get_same_name_context(&ctx.name) {
match ctx.rec_get_var_info(attr_name, AccessKind::Method, input, namespace) { match ctx.rec_get_var_info(attr_name, AccessKind::Method, input, namespace) {
Ok(t) => { Triple::Ok(t) => {
return Ok(t); return Ok(t);
} }
Err(e) if e.core.kind == ErrorKind::NameError => {} Triple::Err(e) => {
Err(e) => {
return Err(e); return Err(e);
} }
Triple::None => {}
} }
} }
} }
@ -820,7 +795,7 @@ impl Context {
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
attr_name.loc(), attr_name.loc(),
namespace.into(), namespace.name.to_string(),
obj.qual_name().unwrap_or("?"), obj.qual_name().unwrap_or("?"),
obj.ref_t(), obj.ref_t(),
attr_name.inspect(), attr_name.inspect(),
@ -863,7 +838,7 @@ impl Context {
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
attr_name.loc(), attr_name.loc(),
namespace.into(), namespace.name.to_string(),
obj.ref_t(), obj.ref_t(),
attr_name.inspect(), attr_name.inspect(),
self.get_similar_attr(obj.ref_t(), attr_name.inspect()), self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
@ -875,34 +850,19 @@ impl Context {
ident: &Identifier, ident: &Identifier,
vi: &VarInfo, vi: &VarInfo,
input: &Input, input: &Input,
namespace: &str, namespace: &Context,
) -> SingleTyCheckResult<()> { ) -> SingleTyCheckResult<()> {
if ident.vis() != vi.vis { if vi.vis.compatible(&ident.acc_kind(), namespace) {
Err(TyCheckError::visibility_error(
input.clone(),
line!() as usize,
ident.loc(),
self.caused_by(),
ident.inspect(),
vi.vis,
))
// check if the private variable is loaded from the other scope
} else if vi.vis.is_private()
&& &self.name[..] != "<builtins>"
&& &self.name[..] != namespace
&& !namespace.contains(&self.name[..])
{
log!(err "{namespace}/{}", self.name);
Err(TyCheckError::visibility_error(
input.clone(),
line!() as usize,
ident.loc(),
self.caused_by(),
ident.inspect(),
Private,
))
} else {
Ok(()) Ok(())
} else {
Err(TyCheckError::visibility_error(
input.clone(),
line!() as usize,
ident.loc(),
self.caused_by(),
ident.inspect(),
vi.vis.clone(),
))
} }
} }
@ -931,18 +891,20 @@ impl Context {
op: &Token, op: &Token,
args: &[hir::PosArg], args: &[hir::PosArg],
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> TyCheckResult<VarInfo> { ) -> TyCheckResult<VarInfo> {
erg_common::debug_power_assert!(args.len() == 2); erg_common::debug_power_assert!(args.len() == 2);
let cont = binop_to_dname(op.inspect()); let cont = binop_to_dname(op.inspect());
// not a `Token::from_str(op.kind, cont)` because ops are defined as symbols // not a `Token::from_str(op.kind, cont)` because ops are defined as symbols
let symbol = Token::symbol(cont); let symbol = Token::symbol(cont);
let t = self.rec_get_var_info( let t = self
&Identifier::new(None, VarName::new(symbol.clone())), .rec_get_var_info(
AccessKind::Name, &Identifier::private_from_token(symbol.clone()),
input, AccessKind::Name,
namespace, input,
)?; namespace,
)
.unwrap_to_result()?;
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
self.get_call_t(&op, &None, args, &[], input, namespace) self.get_call_t(&op, &None, args, &[], input, namespace)
.map_err(|(_, errs)| { .map_err(|(_, errs)| {
@ -952,7 +914,7 @@ impl Context {
let vi = op_ident.vi.clone(); let vi = op_ident.vi.clone();
let lhs = args[0].expr.clone(); let lhs = args[0].expr.clone();
let rhs = args[1].expr.clone(); let rhs = args[1].expr.clone();
let bin = hir::BinOp::new(op_ident.name.into_token(), lhs, rhs, vi); let bin = hir::BinOp::new(op_ident.raw.name.into_token(), lhs, rhs, vi);
let errs = errs let errs = errs
.into_iter() .into_iter()
.map(|e| self.append_loc_info(e, bin.loc())) .map(|e| self.append_loc_info(e, bin.loc()))
@ -966,17 +928,19 @@ impl Context {
op: &Token, op: &Token,
args: &[hir::PosArg], args: &[hir::PosArg],
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> TyCheckResult<VarInfo> { ) -> TyCheckResult<VarInfo> {
erg_common::debug_power_assert!(args.len() == 1); erg_common::debug_power_assert!(args.len() == 1);
let cont = unaryop_to_dname(op.inspect()); let cont = unaryop_to_dname(op.inspect());
let symbol = Token::symbol(cont); let symbol = Token::symbol(cont);
let vi = self.rec_get_var_info( let vi = self
&Identifier::new(None, VarName::new(symbol.clone())), .rec_get_var_info(
AccessKind::Name, &Identifier::private_from_token(symbol.clone()),
input, AccessKind::Name,
namespace, input,
)?; namespace,
)
.unwrap_to_result()?;
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, vi)); let op = hir::Expr::Accessor(hir::Accessor::private(symbol, vi));
self.get_call_t(&op, &None, args, &[], input, namespace) self.get_call_t(&op, &None, args, &[], input, namespace)
.map_err(|(_, errs)| { .map_err(|(_, errs)| {
@ -985,7 +949,7 @@ impl Context {
}; };
let vi = op_ident.vi.clone(); let vi = op_ident.vi.clone();
let expr = args[0].expr.clone(); let expr = args[0].expr.clone();
let unary = hir::UnaryOp::new(op_ident.name.into_token(), expr, vi); let unary = hir::UnaryOp::new(op_ident.raw.name.into_token(), expr, vi);
let errs = errs let errs = errs
.into_iter() .into_iter()
.map(|e| self.append_loc_info(e, unary.loc())) .map(|e| self.append_loc_info(e, unary.loc()))
@ -1118,10 +1082,8 @@ impl Context {
if is_method { if is_method {
obj.clone() obj.clone()
} else { } else {
let attr = hir::Attribute::new( let attr =
obj.clone(), hir::Attribute::new(obj.clone(), hir::Identifier::bare(ident.clone()));
hir::Identifier::bare(ident.dot.clone(), ident.name.clone()),
);
hir::Expr::Accessor(hir::Accessor::Attr(attr)) hir::Expr::Accessor(hir::Accessor::Attr(attr))
} }
} else { } else {
@ -1272,10 +1234,10 @@ impl Context {
} }
} }
other => { other => {
let one = self.get_singular_ctx_by_hir_expr(obj, &self.name).ok(); let one = self.get_singular_ctx_by_hir_expr(obj, self).ok();
let one = one let one = one
.zip(attr_name.as_ref()) .zip(attr_name.as_ref())
.and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, &self.name).ok()) .and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, self).ok())
.or(one); .or(one);
let two = obj let two = obj
.qual_name() .qual_name()
@ -1354,7 +1316,8 @@ impl Context {
)) ))
} else { } else {
let unknown_arg_errors = unknown_args.into_iter().map(|arg| { let unknown_arg_errors = unknown_args.into_iter().map(|arg| {
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); let similar =
levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
TyCheckError::unexpected_kw_arg_error( TyCheckError::unexpected_kw_arg_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1550,7 +1513,8 @@ impl Context {
) )
})?; })?;
} else { } else {
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); let similar =
levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error( return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1571,7 +1535,7 @@ impl Context {
pos_args: &[hir::PosArg], pos_args: &[hir::PosArg],
kw_args: &[hir::KwArg], kw_args: &[hir::KwArg],
input: &Input, input: &Input,
namespace: &Str, namespace: &Context,
) -> Result<VarInfo, (Option<VarInfo>, TyCheckErrors)> { ) -> Result<VarInfo, (Option<VarInfo>, TyCheckErrors)> {
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj { if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
if local.vis().is_private() { if local.vis().is_private() {
@ -1692,18 +1656,27 @@ impl Context {
} }
pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> { pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> {
get_similar_name( levenshtein::get_similar_name(
self.dir().into_iter().map(|(vn, _)| &vn.inspect()[..]), self.dir().into_iter().map(|(vn, _)| &vn.inspect()[..]),
name, name,
) )
} }
pub(crate) fn get_similar_name_and_info(&self, name: &str) -> Option<(&VarInfo, &str)> {
levenshtein::get_similar_name_and_some(
self.dir()
.into_iter()
.map(|(vn, vi)| (vi, &vn.inspect()[..])),
name,
)
}
pub(crate) fn get_similar_attr_from_singular<'a>( pub(crate) fn get_similar_attr_from_singular<'a>(
&'a self, &'a self,
obj: &hir::Expr, obj: &hir::Expr,
name: &str, name: &str,
) -> Option<&'a str> { ) -> Option<&'a str> {
if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, &self.name) { if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, self) {
if let Some(name) = ctx.get_similar_name(name) { if let Some(name) = ctx.get_similar_name(name) {
return Some(name); return Some(name);
} }
@ -1720,6 +1693,19 @@ impl Context {
None None
} }
pub(crate) fn get_similar_attr_and_info<'a>(
&'a self,
self_t: &'a Type,
name: &str,
) -> Option<(&'a VarInfo, &'a str)> {
for ctx in self.get_nominal_super_type_ctxs(self_t)? {
if let Some((vi, name)) = ctx.get_similar_name_and_info(name) {
return Some((vi, name));
}
}
None
}
// Returns what kind of variance the type has for each parameter Type. // Returns what kind of variance the type has for each parameter Type.
// Invariant for types not specified // Invariant for types not specified
// selfが示す型が、各パラメータTypeに対してどのような変性Varianceを持つかを返す // selfが示す型が、各パラメータTypeに対してどのような変性Varianceを持つかを返す
@ -2166,7 +2152,7 @@ impl Context {
{ {
normalize_path(path) normalize_path(path)
} else { } else {
todo!("{} {}", path.display(), add.display()) todo!("{} // {}", path.display(), add.display())
} }
} }
@ -2423,7 +2409,11 @@ impl Context {
} }
} }
fn get_gen_t_require_attr_t<'a>(&'a self, gen: &'a GenTypeObj, attr: &str) -> Option<&'a Type> { fn _get_gen_t_require_attr_t<'a>(
&'a self,
gen: &'a GenTypeObj,
attr: &str,
) -> Option<&'a Type> {
match gen.base_or_sup().map(|req_sup| req_sup.typ()) { match gen.base_or_sup().map(|req_sup| req_sup.typ()) {
Some(Type::Record(rec)) => { Some(Type::Record(rec)) => {
if let Some(t) = rec.get(attr) { if let Some(t) = rec.get(attr) {
@ -2433,7 +2423,7 @@ impl Context {
Some(other) => { Some(other) => {
let obj = self.rec_get_const_obj(&other.local_name()); let obj = self.rec_get_const_obj(&other.local_name());
let obj = option_enum_unwrap!(obj, Some:(ValueObj::Type:(TypeObj::Generated:(_))))?; let obj = option_enum_unwrap!(obj, Some:(ValueObj::Type:(TypeObj::Generated:(_))))?;
if let Some(t) = self.get_gen_t_require_attr_t(obj, attr) { if let Some(t) = self._get_gen_t_require_attr_t(obj, attr) {
return Some(t); return Some(t);
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,7 @@ pub mod hint;
pub mod initialize; pub mod initialize;
pub mod inquire; pub mod inquire;
pub mod instantiate; pub mod instantiate;
pub mod instantiate_spec;
pub mod register; pub mod register;
pub mod test; pub mod test;
pub mod unify; pub mod unify;
@ -25,7 +26,6 @@ use erg_common::dict::Dict;
use erg_common::error::Location; use erg_common::error::Location;
use erg_common::impl_display_from_debug; use erg_common::impl_display_from_debug;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
use erg_common::{fmt_option, fn_name, get_hash, log}; use erg_common::{fmt_option, fn_name, get_hash, log};
@ -33,14 +33,14 @@ use ast::{DefId, DefKind, VarName};
use erg_parser::ast; use erg_parser::ast;
use erg_parser::token::Token; use erg_parser::token::Token;
use crate::context::instantiate::{ConstTemplate, TyVarCache}; use crate::context::instantiate::TyVarCache;
use crate::context::instantiate_spec::ConstTemplate;
use crate::error::{TyCheckError, TyCheckErrors}; use crate::error::{TyCheckError, TyCheckErrors};
use crate::module::{SharedCompilerResource, SharedModuleCache}; use crate::module::{SharedCompilerResource, SharedModuleCache};
use crate::ty::value::ValueObj; use crate::ty::value::ValueObj;
use crate::ty::{Predicate, Type}; use crate::ty::{Predicate, Type, Visibility, VisibilityModifier};
use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
use Type::*; use Type::*;
use Visibility::*;
/// For implementing LSP or other IDE features /// For implementing LSP or other IDE features
pub trait ContextProvider { pub trait ContextProvider {
@ -511,12 +511,30 @@ impl Context {
if let Some(name) = param.name { if let Some(name) = param.name {
let kind = VarKind::parameter(id, param.is_var_params, param.default_info); let kind = VarKind::parameter(id, param.is_var_params, param.default_info);
let muty = Mutability::from(name); let muty = Mutability::from(name);
let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc); let vi = VarInfo::new(
param.t,
muty,
Visibility::private(name),
kind,
None,
None,
None,
param.loc,
);
params_.push((Some(VarName::new(Token::static_symbol(name))), vi)); params_.push((Some(VarName::new(Token::static_symbol(name))), vi));
} else { } else {
let kind = VarKind::parameter(id, param.is_var_params, param.default_info); let kind = VarKind::parameter(id, param.is_var_params, param.default_info);
let muty = Mutability::Immutable; let muty = Mutability::Immutable;
let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc); let vi = VarInfo::new(
param.t,
muty,
Visibility::private(name.clone()),
kind,
None,
None,
None,
param.loc,
);
params_.push((None, vi)); params_.push((None, vi));
} }
} }
@ -925,7 +943,7 @@ impl Context {
&mut self, &mut self,
name: &str, name: &str,
kind: ContextKind, kind: ContextKind,
vis: Visibility, vis: VisibilityModifier,
tv_cache: Option<TyVarCache>, tv_cache: Option<TyVarCache>,
) { ) {
let name = if vis.is_public() { let name = if vis.is_public() {
@ -999,6 +1017,7 @@ impl Context {
} }
} }
/// enumerates all the variables/methods in the current context & super contexts.
fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> { fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> {
let mut vars: Vec<_> = self let mut vars: Vec<_> = self
.locals .locals

View file

@ -11,7 +11,7 @@ use erg_common::levenshtein::get_similar_name;
use erg_common::python_util::BUILTIN_PYTHON_MODS; use erg_common::python_util::BUILTIN_PYTHON_MODS;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility; use erg_common::triple::Triple;
use erg_common::Str; use erg_common::Str;
use erg_common::{enum_unwrap, get_hash, log, set}; use erg_common::{enum_unwrap, get_hash, log, set};
@ -23,7 +23,7 @@ use crate::ty::constructors::{
}; };
use crate::ty::free::{Constraint, FreeKind, HasLevel}; use crate::ty::free::{Constraint, FreeKind, HasLevel};
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{HasType, ParamTy, SubrType, Type}; use crate::ty::{HasType, ParamTy, SubrType, Type, Visibility};
use crate::build_hir::HIRBuilder; use crate::build_hir::HIRBuilder;
use crate::context::{ use crate::context::{
@ -38,9 +38,9 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
use crate::{feature_error, hir}; use crate::{feature_error, hir};
use Mutability::*; use Mutability::*;
use RegistrationMode::*; use RegistrationMode::*;
use Visibility::*;
use super::instantiate::{ParamKind, TyVarCache}; use super::instantiate::TyVarCache;
use super::instantiate_spec::ParamKind;
/// format: /// format:
/// ```python /// ```python
@ -133,7 +133,7 @@ impl Context {
} }
other => unreachable!("{other}"), other => unreachable!("{other}"),
}; };
let vis = ident.vis(); let vis = self.instantiate_vis_modifier(&ident.vis)?;
let kind = id.map_or(VarKind::Declared, VarKind::Defined); let kind = id.map_or(VarKind::Declared, VarKind::Defined);
let sig_t = self.instantiate_var_sig_t(sig.t_spec.as_ref(), PreRegister)?; let sig_t = self.instantiate_var_sig_t(sig.t_spec.as_ref(), PreRegister)?;
let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind { let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind {
@ -153,7 +153,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
sig_t, sig_t,
muty, muty,
vis, Visibility::new(vis, self.name.clone()),
kind, kind,
None, None,
self.impl_of(), self.impl_of(),
@ -172,7 +172,7 @@ impl Context {
id: Option<DefId>, id: Option<DefId>,
) -> TyCheckResult<()> { ) -> TyCheckResult<()> {
let name = sig.ident.inspect(); let name = sig.ident.inspect();
let vis = sig.ident.vis(); let vis = self.instantiate_vis_modifier(&sig.ident.vis)?;
let muty = Mutability::from(&name[..]); let muty = Mutability::from(&name[..]);
let kind = id.map_or(VarKind::Declared, VarKind::Defined); let kind = id.map_or(VarKind::Declared, VarKind::Defined);
let comptime_decos = sig let comptime_decos = sig
@ -199,7 +199,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
t, t,
muty, muty,
vis, Visibility::new(vis, self.name.clone()),
kind, kind,
Some(comptime_decos), Some(comptime_decos),
self.impl_of(), self.impl_of(),
@ -238,18 +238,19 @@ impl Context {
ast::VarPattern::Discard(_) => { ast::VarPattern::Discard(_) => {
return Ok(VarInfo { return Ok(VarInfo {
t: body_t.clone(), t: body_t.clone(),
..VarInfo::const_default() ..VarInfo::const_default_private()
}); });
} }
_ => todo!(), _ => unreachable!(),
}; };
let vis = self.instantiate_vis_modifier(&ident.vis)?;
// already defined as const // already defined as const
if sig.is_const() { if sig.is_const() {
let vi = self.decls.remove(ident.inspect()).unwrap_or_else(|| { let vi = self.decls.remove(ident.inspect()).unwrap_or_else(|| {
VarInfo::new( VarInfo::new(
body_t.clone(), body_t.clone(),
Mutability::Const, Mutability::Const,
sig.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Declared, VarKind::Declared,
None, None,
self.impl_of(), self.impl_of(),
@ -270,7 +271,6 @@ impl Context {
} else { } else {
py_name py_name
}; };
let vis = ident.vis();
let kind = if id.0 == 0 { let kind = if id.0 == 0 {
VarKind::Declared VarKind::Declared
} else { } else {
@ -279,14 +279,14 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
body_t.clone(), body_t.clone(),
muty, muty,
vis, Visibility::new(vis, self.name.clone()),
kind, kind,
None, None,
self.impl_of(), self.impl_of(),
py_name, py_name,
self.absolutize(ident.name.loc()), self.absolutize(ident.name.loc()),
); );
log!(info "Registered {}::{}: {}", self.name, ident.name, vi); log!(info "Registered {}{}: {}", self.name, ident, vi);
self.locals.insert(ident.name.clone(), vi.clone()); self.locals.insert(ident.name.clone(), vi.clone());
Ok(vi) Ok(vi)
} }
@ -300,9 +300,9 @@ impl Context {
kind: ParamKind, kind: ParamKind,
) -> TyCheckResult<()> { ) -> TyCheckResult<()> {
let vis = if cfg!(feature = "py_compatible") { let vis = if cfg!(feature = "py_compatible") {
Public Visibility::BUILTIN_PUBLIC
} else { } else {
Private Visibility::private(self.name.clone())
}; };
let default = kind.default_info(); let default = kind.default_info();
let is_var_params = kind.is_var_params(); let is_var_params = kind.is_var_params();
@ -622,6 +622,7 @@ impl Context {
self.locals.insert(sig.ident.name.clone(), vi.clone()); self.locals.insert(sig.ident.name.clone(), vi.clone());
return Ok(vi); return Ok(vi);
} }
let vis = self.instantiate_vis_modifier(&sig.ident.vis)?;
let muty = if sig.ident.is_const() { let muty = if sig.ident.is_const() {
Mutability::Const Mutability::Const
} else { } else {
@ -717,7 +718,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
found_t, found_t,
muty, muty,
sig.ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Defined(id), VarKind::Defined(id),
Some(comptime_decos), Some(comptime_decos),
self.impl_of(), self.impl_of(),
@ -746,6 +747,7 @@ impl Context {
return Ok(()); return Ok(());
} }
} }
let vis = self.instantiate_vis_modifier(&ident.vis)?;
let muty = if ident.is_const() { let muty = if ident.is_const() {
Mutability::Const Mutability::Const
} else { } else {
@ -765,7 +767,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
failure_t, failure_t,
muty, muty,
ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::DoesNotExist, VarKind::DoesNotExist,
Some(comptime_decos), Some(comptime_decos),
self.impl_of(), self.impl_of(),
@ -814,7 +816,7 @@ impl Context {
ast::Signature::Subr(sig) => { ast::Signature::Subr(sig) => {
if sig.is_const() { if sig.is_const() {
let tv_cache = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let tv_cache = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
let vis = def.sig.vis(); let vis = self.instantiate_vis_modifier(sig.vis())?;
self.grow(__name__, ContextKind::Proc, vis, Some(tv_cache)); self.grow(__name__, ContextKind::Proc, vis, Some(tv_cache));
let (obj, const_t) = match self.eval_const_block(&def.body.block) { let (obj, const_t) = match self.eval_const_block(&def.body.block) {
Ok(obj) => (obj.clone(), v_enum(set! {obj})), Ok(obj) => (obj.clone(), v_enum(set! {obj})),
@ -852,7 +854,8 @@ impl Context {
ast::Signature::Var(sig) => { ast::Signature::Var(sig) => {
if sig.is_const() { if sig.is_const() {
let kind = ContextKind::from(def.def_kind()); let kind = ContextKind::from(def.def_kind());
self.grow(__name__, kind, sig.vis(), None); let vis = self.instantiate_vis_modifier(sig.vis())?;
self.grow(__name__, kind, vis, None);
let (obj, const_t) = match self.eval_const_block(&def.body.block) { let (obj, const_t) = match self.eval_const_block(&def.body.block) {
Ok(obj) => (obj.clone(), v_enum(set! {obj})), Ok(obj) => (obj.clone(), v_enum(set! {obj})),
Err(errs) => { Err(errs) => {
@ -1048,7 +1051,8 @@ impl Context {
ident: &Identifier, ident: &Identifier,
obj: ValueObj, obj: ValueObj,
) -> CompileResult<()> { ) -> CompileResult<()> {
if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { let vis = self.instantiate_vis_modifier(&ident.vis)?;
if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1068,7 +1072,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
v_enum(set! {other.clone()}), v_enum(set! {other.clone()}),
Const, Const,
ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Defined(id), VarKind::Defined(id),
None, None,
self.impl_of(), self.impl_of(),
@ -1111,6 +1115,7 @@ impl Context {
field.clone(), field.clone(),
t.clone(), t.clone(),
self.impl_of(), self.impl_of(),
ctx.name.clone(),
); );
ctx.decls.insert(varname, vi); ctx.decls.insert(varname, vi);
} }
@ -1120,7 +1125,7 @@ impl Context {
"base", "base",
other.typ().clone(), other.typ().clone(),
Immutable, Immutable,
Private, Visibility::BUILTIN_PRIVATE,
None, None,
)?; )?;
} }
@ -1133,12 +1138,18 @@ impl Context {
"__new__", "__new__",
new_t.clone(), new_t.clone(),
Immutable, Immutable,
Private, Visibility::BUILTIN_PRIVATE,
Some("__call__".into()), Some("__call__".into()),
)?; )?;
// 必要なら、ユーザーが独自に上書きする // 必要なら、ユーザーが独自に上書きする
// users can override this if necessary // users can override this if necessary
methods.register_auto_impl("new", new_t, Immutable, Public, None)?; methods.register_auto_impl(
"new",
new_t,
Immutable,
Visibility::BUILTIN_PUBLIC,
None,
)?;
ctx.methods_list ctx.methods_list
.push((ClassDefType::Simple(gen.typ().clone()), methods)); .push((ClassDefType::Simple(gen.typ().clone()), methods));
self.register_gen_mono_type(ident, gen, ctx, Const) self.register_gen_mono_type(ident, gen, ctx, Const)
@ -1189,6 +1200,7 @@ impl Context {
field.clone(), field.clone(),
t.clone(), t.clone(),
self.impl_of(), self.impl_of(),
ctx.name.clone(),
); );
ctx.decls.insert(varname, vi); ctx.decls.insert(varname, vi);
} }
@ -1202,11 +1214,17 @@ impl Context {
"__new__", "__new__",
new_t.clone(), new_t.clone(),
Immutable, Immutable,
Private, Visibility::BUILTIN_PRIVATE,
Some("__call__".into()), Some("__call__".into()),
)?; )?;
// 必要なら、ユーザーが独自に上書きする // 必要なら、ユーザーが独自に上書きする
methods.register_auto_impl("new", new_t, Immutable, Public, None)?; methods.register_auto_impl(
"new",
new_t,
Immutable,
Visibility::BUILTIN_PUBLIC,
None,
)?;
ctx.methods_list ctx.methods_list
.push((ClassDefType::Simple(gen.typ().clone()), methods)); .push((ClassDefType::Simple(gen.typ().clone()), methods));
self.register_gen_mono_type(ident, gen, ctx, Const) self.register_gen_mono_type(ident, gen, ctx, Const)
@ -1242,7 +1260,12 @@ impl Context {
); );
let Some(TypeObj::Builtin(Type::Record(req))) = gen.base_or_sup() else { todo!("{gen}") }; let Some(TypeObj::Builtin(Type::Record(req))) = gen.base_or_sup() else { todo!("{gen}") };
for (field, t) in req.iter() { for (field, t) in req.iter() {
let vi = VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of()); let vi = VarInfo::instance_attr(
field.clone(),
t.clone(),
self.impl_of(),
ctx.name.clone(),
);
ctx.decls ctx.decls
.insert(VarName::from_str(field.symbol.clone()), vi); .insert(VarName::from_str(field.symbol.clone()), vi);
} }
@ -1273,8 +1296,12 @@ impl Context {
); );
if let Some(additional) = additional { if let Some(additional) = additional {
for (field, t) in additional.iter() { for (field, t) in additional.iter() {
let vi = let vi = VarInfo::instance_attr(
VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of()); field.clone(),
t.clone(),
self.impl_of(),
ctx.name.clone(),
);
ctx.decls ctx.decls
.insert(VarName::from_str(field.symbol.clone()), vi); .insert(VarName::from_str(field.symbol.clone()), vi);
} }
@ -1330,6 +1357,7 @@ impl Context {
} }
pub(crate) fn register_type_alias(&mut self, ident: &Identifier, t: Type) -> CompileResult<()> { pub(crate) fn register_type_alias(&mut self, ident: &Identifier, t: Type) -> CompileResult<()> {
let vis = self.instantiate_vis_modifier(&ident.vis)?;
if self.mono_types.contains_key(ident.inspect()) { if self.mono_types.contains_key(ident.inspect()) {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
self.cfg.input.clone(), self.cfg.input.clone(),
@ -1338,7 +1366,7 @@ impl Context {
self.caused_by(), self.caused_by(),
ident.inspect(), ident.inspect(),
))) )))
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
// TODO: display where defined // TODO: display where defined
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
self.cfg.input.clone(), self.cfg.input.clone(),
@ -1354,7 +1382,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
Type::Type, Type::Type,
muty, muty,
ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Defined(id), VarKind::Defined(id),
None, None,
self.impl_of(), self.impl_of(),
@ -1376,6 +1404,7 @@ impl Context {
ctx: Self, ctx: Self,
muty: Mutability, muty: Mutability,
) -> CompileResult<()> { ) -> CompileResult<()> {
let vis = self.instantiate_vis_modifier(&ident.vis)?;
// FIXME: recursive search // FIXME: recursive search
if self.mono_types.contains_key(ident.inspect()) { if self.mono_types.contains_key(ident.inspect()) {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
@ -1385,7 +1414,7 @@ impl Context {
self.caused_by(), self.caused_by(),
ident.inspect(), ident.inspect(),
))) )))
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1401,7 +1430,7 @@ impl Context {
let vi = VarInfo::new( let vi = VarInfo::new(
meta_t, meta_t,
muty, muty,
ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Defined(id), VarKind::Defined(id),
None, None,
self.impl_of(), self.impl_of(),
@ -1454,6 +1483,7 @@ impl Context {
ctx: Self, ctx: Self,
muty: Mutability, muty: Mutability,
) -> CompileResult<()> { ) -> CompileResult<()> {
let vis = self.instantiate_vis_modifier(&ident.vis)?;
// FIXME: recursive search // FIXME: recursive search
if self.patches.contains_key(ident.inspect()) { if self.patches.contains_key(ident.inspect()) {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
@ -1463,7 +1493,7 @@ impl Context {
self.caused_by(), self.caused_by(),
ident.inspect(), ident.inspect(),
))) )))
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
Err(CompileErrors::from(CompileError::reassign_error( Err(CompileErrors::from(CompileError::reassign_error(
self.cfg.input.clone(), self.cfg.input.clone(),
line!() as usize, line!() as usize,
@ -1481,7 +1511,7 @@ impl Context {
VarInfo::new( VarInfo::new(
meta_t, meta_t,
muty, muty,
ident.vis(), Visibility::new(vis, self.name.clone()),
VarKind::Defined(id), VarKind::Defined(id),
None, None,
self.impl_of(), self.impl_of(),
@ -1758,7 +1788,7 @@ impl Context {
))) )))
} else if self.locals.get(ident.inspect()).is_some() { } else if self.locals.get(ident.inspect()).is_some() {
let vi = self.locals.remove(ident.inspect()).unwrap(); let vi = self.locals.remove(ident.inspect()).unwrap();
self.deleted_locals.insert(ident.name.clone(), vi); self.deleted_locals.insert(ident.raw.name.clone(), vi);
Ok(()) Ok(())
} else { } else {
Err(TyCheckErrors::from(TyCheckError::no_var_error( Err(TyCheckErrors::from(TyCheckError::no_var_error(
@ -1831,7 +1861,7 @@ impl Context {
#[allow(clippy::single_match)] #[allow(clippy::single_match)]
match acc { match acc {
hir::Accessor::Ident(ident) => { hir::Accessor::Ident(ident) => {
if let Some(vi) = self.get_mut_current_scope_var(&ident.name) { if let Some(vi) = self.get_mut_current_scope_var(&ident.raw.name) {
vi.t = t; vi.t = t;
} else { } else {
return Err(TyCheckErrors::from(TyCheckError::feature_error( return Err(TyCheckErrors::from(TyCheckError::feature_error(
@ -1850,22 +1880,22 @@ impl Context {
} }
pub(crate) fn inc_ref_simple_typespec(&self, simple: &SimpleTypeSpec) { pub(crate) fn inc_ref_simple_typespec(&self, simple: &SimpleTypeSpec) {
if let Ok(vi) = self.rec_get_var_info( if let Triple::Ok(vi) = self.rec_get_var_info(
&simple.ident, &simple.ident,
crate::compile::AccessKind::Name, crate::compile::AccessKind::Name,
&self.cfg.input, &self.cfg.input,
&self.name, self,
) { ) {
self.inc_ref(&vi, &simple.ident.name); self.inc_ref(&vi, &simple.ident.name);
} }
} }
pub(crate) fn inc_ref_const_local(&self, local: &ConstIdentifier) { pub(crate) fn inc_ref_const_local(&self, local: &ConstIdentifier) {
if let Ok(vi) = self.rec_get_var_info( if let Triple::Ok(vi) = self.rec_get_var_info(
local, local,
crate::compile::AccessKind::Name, crate::compile::AccessKind::Name,
&self.cfg.input, &self.cfg.input,
&self.name, self,
) { ) {
self.inc_ref(&vi, &local.name); self.inc_ref(&vi, &local.name);
} }

View file

@ -9,7 +9,7 @@ use crate::lower::ASTLowerer;
use crate::ty::constructors::mono; use crate::ty::constructors::mono;
use crate::ty::free::HasLevel; use crate::ty::free::HasLevel;
use crate::ty::value::{GenTypeObj, TypeObj}; use crate::ty::value::{GenTypeObj, TypeObj};
use crate::ty::{HasType, Type}; use crate::ty::{HasType, Type, Visibility};
use crate::compile::AccessKind; use crate::compile::AccessKind;
use crate::context::RegistrationMode; use crate::context::RegistrationMode;
@ -73,7 +73,7 @@ impl ASTLowerer {
.assign_var_sig(&sig, found_body_t, id, py_name.clone())?; .assign_var_sig(&sig, found_body_t, id, py_name.clone())?;
} }
// FIXME: Identifier::new should be used // FIXME: Identifier::new should be used
let mut ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); let mut ident = hir::Identifier::bare(ident.clone());
ident.vi.t = found_body_t.clone(); ident.vi.t = found_body_t.clone();
ident.vi.py_name = py_name; ident.vi.py_name = py_name;
let sig = hir::VarSignature::new(ident, sig.t_spec); let sig = hir::VarSignature::new(ident, sig.t_spec);
@ -127,20 +127,15 @@ impl ASTLowerer {
let vi = self let vi = self
.module .module
.context .context
.rec_get_var_info( .rec_get_var_info(&ident, AccessKind::Name, self.input(), &self.module.context)
&ident,
AccessKind::Name,
self.input(),
&self.module.context.name,
)
.unwrap_or(VarInfo::default()); .unwrap_or(VarInfo::default());
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); let ident = hir::Identifier::new(ident, None, vi);
let acc = hir::Accessor::Ident(ident); let acc = hir::Accessor::Ident(ident);
Ok(acc) Ok(acc)
} }
ast::Accessor::Attr(attr) => { ast::Accessor::Attr(attr) => {
let obj = self.fake_lower_expr(*attr.obj)?; let obj = self.fake_lower_expr(*attr.obj)?;
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); let ident = hir::Identifier::bare(attr.ident);
Ok(obj.attr(ident)) Ok(obj.attr(ident))
} }
other => Err(LowerErrors::from(LowerError::declare_error( other => Err(LowerErrors::from(LowerError::declare_error(
@ -177,9 +172,7 @@ impl ASTLowerer {
fn fake_lower_call(&self, call: ast::Call) -> LowerResult<hir::Call> { fn fake_lower_call(&self, call: ast::Call) -> LowerResult<hir::Call> {
let obj = self.fake_lower_expr(*call.obj)?; let obj = self.fake_lower_expr(*call.obj)?;
let attr_name = call let attr_name = call.attr_name.map(hir::Identifier::bare);
.attr_name
.map(|ident| hir::Identifier::bare(ident.dot, ident.name));
let args = self.fake_lower_args(call.args)?; let args = self.fake_lower_args(call.args)?;
Ok(hir::Call::new(obj, attr_name, args)) Ok(hir::Call::new(obj, attr_name, args))
} }
@ -247,12 +240,12 @@ impl ASTLowerer {
match sig { match sig {
ast::Signature::Var(var) => { ast::Signature::Var(var) => {
let ident = var.ident().unwrap().clone(); let ident = var.ident().unwrap().clone();
let ident = hir::Identifier::bare(ident.dot, ident.name); let ident = hir::Identifier::bare(ident);
let sig = hir::VarSignature::new(ident, var.t_spec); let sig = hir::VarSignature::new(ident, var.t_spec);
Ok(hir::Signature::Var(sig)) Ok(hir::Signature::Var(sig))
} }
ast::Signature::Subr(subr) => { ast::Signature::Subr(subr) => {
let ident = hir::Identifier::bare(subr.ident.dot, subr.ident.name); let ident = hir::Identifier::bare(subr.ident);
let params = self.fake_lower_params(subr.params)?; let params = self.fake_lower_params(subr.params)?;
let sig = hir::SubrSignature::new(ident, subr.bounds, params, subr.return_t_spec); let sig = hir::SubrSignature::new(ident, subr.bounds, params, subr.return_t_spec);
Ok(hir::Signature::Subr(sig)) Ok(hir::Signature::Subr(sig))
@ -454,19 +447,19 @@ impl ASTLowerer {
self.declare_subtype(&ident, &t)?; self.declare_subtype(&ident, &t)?;
} }
let muty = Mutability::from(&ident.inspect()[..]); let muty = Mutability::from(&ident.inspect()[..]);
let vis = ident.vis(); let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?;
let py_name = Str::rc(ident.inspect().trim_end_matches('!')); let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
let vi = VarInfo::new( let vi = VarInfo::new(
t, t,
muty, muty,
vis, Visibility::new(vis, self.module.context.name.clone()),
VarKind::Declared, VarKind::Declared,
None, None,
None, None,
Some(py_name), Some(py_name),
self.module.context.absolutize(ident.loc()), self.module.context.absolutize(ident.loc()),
); );
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); let ident = hir::Identifier::new(ident, None, vi);
let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?; let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?;
let t_spec = hir::TypeSpecWithOp::new( let t_spec = hir::TypeSpecWithOp::new(
tasc.t_spec.op, tasc.t_spec.op,
@ -488,11 +481,10 @@ impl ASTLowerer {
RegistrationMode::Normal, RegistrationMode::Normal,
false, false,
)?; )?;
let namespace = self.module.context.name.clone();
let ctx = self let ctx = self
.module .module
.context .context
.get_mut_singular_ctx(attr.obj.as_ref(), &namespace)?; .get_mut_singular_ctx(attr.obj.as_ref(), &self.module.context.name.clone())?;
ctx.assign_var_sig( ctx.assign_var_sig(
&ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None), &ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None),
&t, &t,
@ -501,19 +493,22 @@ impl ASTLowerer {
)?; )?;
let obj = self.fake_lower_expr(*attr.obj)?; let obj = self.fake_lower_expr(*attr.obj)?;
let muty = Mutability::from(&attr.ident.inspect()[..]); let muty = Mutability::from(&attr.ident.inspect()[..]);
let vis = attr.ident.vis(); let vis = self
.module
.context
.instantiate_vis_modifier(&attr.ident.vis)?;
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!')); let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
let vi = VarInfo::new( let vi = VarInfo::new(
t, t,
muty, muty,
vis, Visibility::new(vis, self.module.context.name.clone()),
VarKind::Declared, VarKind::Declared,
None, None,
None, None,
Some(py_name), Some(py_name),
self.module.context.absolutize(attr.ident.loc()), self.module.context.absolutize(attr.ident.loc()),
); );
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); let ident = hir::Identifier::new(attr.ident, None, vi);
let attr = obj.attr_expr(ident); let attr = obj.attr_expr(ident);
let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?; let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?;
let t_spec = hir::TypeSpecWithOp::new( let t_spec = hir::TypeSpecWithOp::new(
@ -544,10 +539,11 @@ impl ASTLowerer {
return Ok(()); return Ok(());
} }
if ident.is_const() { if ident.is_const() {
let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?;
let vi = VarInfo::new( let vi = VarInfo::new(
t.clone(), t.clone(),
Mutability::Const, Mutability::Const,
ident.vis(), Visibility::new(vis, self.module.context.name.clone()),
VarKind::Declared, VarKind::Declared,
None, None,
None, None,

View file

@ -5,15 +5,12 @@
use erg_common::config::ErgConfig; use erg_common::config::ErgConfig;
use erg_common::log; use erg_common::log;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
use erg_parser::token::TokenKind; use erg_parser::token::TokenKind;
use Visibility::*;
use crate::ty::HasType;
use crate::error::{EffectError, EffectErrors}; use crate::error::{EffectError, EffectErrors};
use crate::hir::{Array, Def, Dict, Expr, Params, Set, Signature, Tuple, HIR}; use crate::hir::{Array, Def, Dict, Expr, Params, Set, Signature, Tuple, HIR};
use crate::ty::{HasType, Visibility};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum BlockKind { enum BlockKind {
@ -36,7 +33,7 @@ use BlockKind::*;
#[derive(Debug)] #[derive(Debug)]
pub struct SideEffectChecker { pub struct SideEffectChecker {
cfg: ErgConfig, cfg: ErgConfig,
path_stack: Vec<(Str, Visibility)>, path_stack: Vec<Visibility>,
block_stack: Vec<BlockKind>, block_stack: Vec<BlockKind>,
errs: EffectErrors, errs: EffectErrors,
} }
@ -52,15 +49,13 @@ impl SideEffectChecker {
} }
fn full_path(&self) -> String { fn full_path(&self) -> String {
self.path_stack self.path_stack.iter().fold(String::new(), |acc, vis| {
.iter() if vis.is_public() {
.fold(String::new(), |acc, (path, vis)| { acc + "." + &vis.def_namespace[..]
if vis.is_public() { } else {
acc + "." + &path[..] acc + "::" + &vis.def_namespace[..]
} else { }
acc + "::" + &path[..] })
}
})
} }
/// It is permitted to define a procedure in a function, /// It is permitted to define a procedure in a function,
@ -85,7 +80,7 @@ impl SideEffectChecker {
} }
pub fn check(mut self, hir: HIR) -> Result<HIR, (HIR, EffectErrors)> { pub fn check(mut self, hir: HIR) -> Result<HIR, (HIR, EffectErrors)> {
self.path_stack.push((hir.name.clone(), Private)); self.path_stack.push(Visibility::private(hir.name.clone()));
self.block_stack.push(Module); self.block_stack.push(Module);
log!(info "the side-effects checking process has started.{RESET}"); log!(info "the side-effects checking process has started.{RESET}");
// At the top level, there is no problem with side effects, only check for purity violations. // At the top level, there is no problem with side effects, only check for purity violations.
@ -150,7 +145,8 @@ impl SideEffectChecker {
} }
}, },
Expr::Record(rec) => { Expr::Record(rec) => {
self.path_stack.push((Str::ever("<record>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<record>")));
self.block_stack.push(Instant); self.block_stack.push(Instant);
for attr in rec.attrs.iter() { for attr in rec.attrs.iter() {
self.check_def(attr); self.check_def(attr);
@ -184,10 +180,12 @@ impl SideEffectChecker {
Expr::Lambda(lambda) => { Expr::Lambda(lambda) => {
let is_proc = lambda.is_procedural(); let is_proc = lambda.is_procedural();
if is_proc { if is_proc {
self.path_stack.push((Str::ever("<lambda!>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<lambda!>")));
self.block_stack.push(Proc); self.block_stack.push(Proc);
} else { } else {
self.path_stack.push((Str::ever("<lambda>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<lambda>")));
self.block_stack.push(Func); self.block_stack.push(Func);
} }
lambda.body.iter().for_each(|chunk| self.check_expr(chunk)); lambda.body.iter().for_each(|chunk| self.check_expr(chunk));
@ -244,10 +242,7 @@ impl SideEffectChecker {
} }
fn check_def(&mut self, def: &Def) { fn check_def(&mut self, def: &Def) {
let name_and_vis = match &def.sig { let name_and_vis = Visibility::new(def.sig.vis().clone(), def.sig.inspect().clone());
Signature::Var(var) => (var.inspect().clone(), var.vis()),
Signature::Subr(subr) => (subr.ident.inspect().clone(), subr.ident.vis()),
};
self.path_stack.push(name_and_vis); self.path_stack.push(name_and_vis);
let is_procedural = def.sig.is_procedural(); let is_procedural = def.sig.is_procedural();
let is_subr = def.sig.is_subr(); let is_subr = def.sig.is_subr();
@ -360,7 +355,8 @@ impl SideEffectChecker {
} }
}, },
Expr::Record(record) => { Expr::Record(record) => {
self.path_stack.push((Str::ever("<record>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<record>")));
self.block_stack.push(Instant); self.block_stack.push(Instant);
for attr in record.attrs.iter() { for attr in record.attrs.iter() {
self.check_def(attr); self.check_def(attr);
@ -433,10 +429,12 @@ impl SideEffectChecker {
Expr::Lambda(lambda) => { Expr::Lambda(lambda) => {
let is_proc = lambda.is_procedural(); let is_proc = lambda.is_procedural();
if is_proc { if is_proc {
self.path_stack.push((Str::ever("<lambda!>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<lambda!>")));
self.block_stack.push(Proc); self.block_stack.push(Proc);
} else { } else {
self.path_stack.push((Str::ever("<lambda>"), Private)); self.path_stack
.push(Visibility::private(Str::ever("<lambda>")));
self.block_stack.push(Func); self.block_stack.push(Func);
} }
self.check_params(&lambda.params); self.check_params(&lambda.params);

View file

@ -2,12 +2,12 @@ use erg_common::config::Input;
use erg_common::error::{ErrorCore, ErrorKind::*, Location, SubMessage}; use erg_common::error::{ErrorCore, ErrorKind::*, Location, SubMessage};
use erg_common::style::{StyledStr, StyledString, StyledStrings, Stylize}; use erg_common::style::{StyledStr, StyledString, StyledStrings, Stylize};
use erg_common::traits::Locational; use erg_common::traits::Locational;
use erg_common::vis::Visibility;
use erg_common::{switch_lang, Str}; use erg_common::{switch_lang, Str};
use crate::error::*; use crate::error::*;
use crate::hir::{Expr, Identifier}; use crate::hir::{Expr, Identifier};
use crate::ty::{HasType, Type}; use crate::ty::{HasType, Type, Visibility};
use crate::varinfo::VarInfo;
pub type LowerError = CompileError; pub type LowerError = CompileError;
pub type LowerWarning = LowerError; pub type LowerWarning = LowerError;
@ -196,7 +196,47 @@ impl LowerError {
"english" => format!("exists a similar name variable: {n}"), "english" => format!("exists a similar name variable: {n}"),
) )
}); });
let found = StyledString::new(name, Some(ERR), Some(ATTR)); let found = name.with_color_and_attr(ERR, ATTR);
Self::new(
ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
switch_lang!(
"japanese" => format!("{found}という変数は定義されていません"),
"simplified_chinese" => format!("{found}未定义"),
"traditional_chinese" => format!("{found}未定義"),
"english" => format!("{found} is not defined"),
),
errno,
NameError,
loc,
),
input,
caused_by,
)
}
/// TODO: replace `no_var_error` with this function
pub fn detailed_no_var_error(
input: Input,
errno: usize,
loc: Location,
caused_by: String,
name: &str,
similar_name: Option<&str>,
similar_info: Option<&VarInfo>,
) -> Self {
let name = readable_name(name);
let hint = similar_name.map(|n| {
let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display());
let n = n.with_color_and_attr(HINT, ATTR);
switch_lang!(
"japanese" => format!("似た名前の{vis}変数があります: {n}"),
"simplified_chinese" => format!("存在相同名称{vis}变量: {n}"),
"traditional_chinese" => format!("存在相同名稱{vis}變量: {n}"),
"english" => format!("exists a similar name {vis} variable: {n}"),
)
});
let found = name.with_color_and_attr(ERR, ATTR);
Self::new( Self::new(
ErrorCore::new( ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], hint)], vec![SubMessage::ambiguous_new(loc, vec![], hint)],
@ -226,7 +266,7 @@ impl LowerError {
) -> Self { ) -> Self {
let name = readable_name(name); let name = readable_name(name);
let hint = similar_name.map(|n| { let hint = similar_name.map(|n| {
let n = StyledStr::new(n, Some(HINT), Some(ATTR)); let n = n.with_color_and_attr(HINT, ATTR);
switch_lang!( switch_lang!(
"japanese" => format!("似た名前の変数があります: {n}"), "japanese" => format!("似た名前の変数があります: {n}"),
"simplified_chinese" => format!("存在相同名称变量: {n}"), "simplified_chinese" => format!("存在相同名称变量: {n}"),
@ -234,7 +274,7 @@ impl LowerError {
"english" => format!("exists a similar name variable: {n}"), "english" => format!("exists a similar name variable: {n}"),
) )
}); });
let found = StyledString::new(name, Some(ERR), Some(ATTR)); let found = name.with_color_and_attr(ERR, ATTR);
Self::new( Self::new(
ErrorCore::new( ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], hint)], vec![SubMessage::ambiguous_new(loc, vec![], hint)],
@ -264,7 +304,7 @@ impl LowerError {
) -> Self { ) -> Self {
let name = readable_name(name); let name = readable_name(name);
let hint = similar_name.map(|n| { let hint = similar_name.map(|n| {
let n = StyledStr::new(n, Some(HINT), Some(ATTR)); let n = n.with_color_and_attr(HINT, ATTR);
switch_lang!( switch_lang!(
"japanese" => format!("似た名前の変数があります: {n}"), "japanese" => format!("似た名前の変数があります: {n}"),
"simplified_chinese" => format!("存在相同名称变量: {n}"), "simplified_chinese" => format!("存在相同名称变量: {n}"),
@ -272,7 +312,7 @@ impl LowerError {
"english" => format!("exists a similar name variable: {n}"), "english" => format!("exists a similar name variable: {n}"),
) )
}); });
let found = StyledString::new(name, Some(ERR), Some(ATTR)); let found = name.with_color_and_attr(ERR, ATTR);
Self::new( Self::new(
ErrorCore::new( ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], hint)], vec![SubMessage::ambiguous_new(loc, vec![], hint)],
@ -396,6 +436,45 @@ impl LowerError {
) )
} }
#[allow(clippy::too_many_arguments)]
pub fn detailed_no_attr_error(
input: Input,
errno: usize,
loc: Location,
caused_by: String,
obj_t: &Type,
name: &str,
similar_name: Option<&str>,
similar_info: Option<&VarInfo>,
) -> Self {
let hint = similar_name.map(|n| {
let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display());
switch_lang!(
"japanese" => format!("似た名前の{vis}属性があります: {n}"),
"simplified_chinese" => format!("具有相同名称的{vis}属性: {n}"),
"traditional_chinese" => format!("具有相同名稱的{vis}屬性: {n}"),
"english" => format!("has a similar name {vis} attribute: {n}"),
)
});
let found = StyledString::new(name, Some(ERR), Some(ATTR));
Self::new(
ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
switch_lang!(
"japanese" => format!("{obj_t}型オブジェクトに{found}という属性はありません"),
"simplified_chinese" => format!("{obj_t}对象没有属性{found}"),
"traditional_chinese" => format!("{obj_t}對像沒有屬性{found}"),
"english" => format!("{obj_t} object has no attribute {found}"),
),
errno,
AttributeError,
loc,
),
input,
caused_by,
)
}
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn singular_no_attr_error( pub fn singular_no_attr_error(
input: Input, input: Input,
@ -510,21 +589,7 @@ impl LowerError {
name: &str, name: &str,
vis: Visibility, vis: Visibility,
) -> Self { ) -> Self {
let visibility = if vis.is_private() { let visibility = vis.modifier.display();
switch_lang!(
"japanese" => "非公開",
"simplified_chinese" => "私有",
"traditional_chinese" => "私有",
"english" => "private",
)
} else {
switch_lang!(
"japanese" => "公開",
"simplified_chinese" => "公有",
"traditional_chinese" => "公有",
"english" => "public",
)
};
let found = StyledString::new(readable_name(name), Some(ERR), Some(ATTR)); let found = StyledString::new(readable_name(name), Some(ERR), Some(ATTR));
Self::new( Self::new(
ErrorCore::new( ErrorCore::new(

View file

@ -520,7 +520,7 @@ mod test {
varinfo::{AbsLocation, VarInfo}, varinfo::{AbsLocation, VarInfo},
}; };
use erg_common::{config::Input, error::Location}; use erg_common::{config::Input, error::Location};
use erg_parser::ast::VarName; use erg_parser::ast::{VarName, VisModifierSpec};
// These Erg codes are not correct grammar. // These Erg codes are not correct grammar.
// This test make sure sub_msg and hint are displayed correctly. // This test make sure sub_msg and hint are displayed correctly.
@ -704,19 +704,17 @@ mod test {
errors.push(err); errors.push(err);
let input = Input::pipe("ambiguous type error".to_string()); let input = Input::pipe("ambiguous type error".to_string());
let expr = Identifier::new( let raw = erg_parser::ast::Identifier::new(
Some(erg_parser::token::Token { VisModifierSpec::Private,
kind: erg_parser::token::TokenKind::EOF,
content: "expr_content".into(),
lineno: 1,
col_begin: 1,
}),
VarName::from_str("variable_name".into()), VarName::from_str("variable_name".into()),
);
let expr = Identifier::new(
raw,
None, None,
VarInfo::new( VarInfo::new(
Type::Nat, Type::Nat,
crate::varinfo::Mutability::Const, crate::varinfo::Mutability::Const,
erg_common::vis::Visibility::Private, crate::ty::Visibility::DUMMY_PRIVATE,
crate::varinfo::VarKind::Builtin, crate::varinfo::VarKind::Builtin,
None, None,
None, None,
@ -759,7 +757,7 @@ mod test {
let input = Input::pipe("visibility error".to_string()); let input = Input::pipe("visibility error".to_string());
let loc = Location::Line(1); let loc = Location::Line(1);
let vis = erg_common::vis::Visibility::Private; let vis = crate::ty::Visibility::DUMMY_PRIVATE;
let err = let err =
TyCheckError::visibility_error(input, errno, loc, caused_by.to_string(), name, vis); TyCheckError::visibility_error(input, errno, loc, caused_by.to_string(), name, vis);
errors.push(err); errors.push(err);

View file

@ -6,7 +6,6 @@ use erg_common::error::Location;
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
use erg_common::traits::{Locational, NestedDisplay, NoTypeDisplay, Stream}; use erg_common::traits::{Locational, NestedDisplay, NoTypeDisplay, Stream};
use erg_common::vis::{Field, Visibility};
use erg_common::Str; use erg_common::Str;
use erg_common::{ use erg_common::{
enum_unwrap, fmt_option, fmt_vec, impl_display_for_enum, impl_display_from_nested, enum_unwrap, fmt_option, fmt_vec, impl_display_for_enum, impl_display_from_nested,
@ -23,7 +22,7 @@ use erg_parser::token::{Token, TokenKind, DOT};
use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t}; use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t};
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::{GenTypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, ValueObj};
use crate::ty::{HasType, Type}; use crate::ty::{Field, HasType, Type, VisibilityModifier};
use crate::context::eval::type_from_token_kind; use crate::context::eval::type_from_token_kind;
use crate::error::readable_name; use crate::error::readable_name;
@ -381,22 +380,14 @@ impl Args {
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Identifier { pub struct Identifier {
pub dot: Option<Token>, pub raw: ast::Identifier,
pub name: VarName,
pub qual_name: Option<Str>, pub qual_name: Option<Str>,
pub vi: VarInfo, pub vi: VarInfo,
} }
impl NestedDisplay for Identifier { impl NestedDisplay for Identifier {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
match &self.dot { write!(f, "{}", self.raw)?;
Some(_dot) => {
write!(f, ".{}", self.name)?;
}
None => {
write!(f, "::{}", self.name)?;
}
}
if let Some(qn) = &self.qual_name { if let Some(qn) = &self.qual_name {
write!(f, "(qual_name: {qn})")?; write!(f, "(qual_name: {qn})")?;
} }
@ -409,10 +400,7 @@ impl NestedDisplay for Identifier {
impl NoTypeDisplay for Identifier { impl NoTypeDisplay for Identifier {
fn to_string_notype(&self) -> String { fn to_string_notype(&self) -> String {
match &self.dot { self.raw.to_string()
Some(_dot) => format!(".{}", self.name),
None => format!("::{}", self.name),
}
} }
} }
@ -439,56 +427,50 @@ impl HasType for Identifier {
impl Locational for Identifier { impl Locational for Identifier {
fn loc(&self) -> Location { fn loc(&self) -> Location {
if let Some(dot) = &self.dot { self.raw.loc()
Location::concat(dot, &self.name)
} else {
self.name.loc()
}
} }
} }
impl From<&Identifier> for Field { impl From<&Identifier> for Field {
fn from(ident: &Identifier) -> Self { fn from(ident: &Identifier) -> Self {
Self::new(ident.vis(), ident.inspect().clone()) Self::new(ident.vis().clone(), ident.inspect().clone())
} }
} }
impl Identifier { impl Identifier {
pub const fn new( pub const fn new(raw: ast::Identifier, qual_name: Option<Str>, vi: VarInfo) -> Self {
dot: Option<Token>, Self { raw, qual_name, vi }
name: VarName,
qual_name: Option<Str>,
vi: VarInfo,
) -> Self {
Self {
dot,
name,
qual_name,
vi,
}
} }
pub fn public(name: &'static str) -> Self { pub fn public(name: &'static str) -> Self {
Self::bare( let ident = ast::Identifier::public_from_token(
Some(Token::from_str(TokenKind::Dot, ".")), Token::from_str(TokenKind::Dot, "."),
VarName::from_static(name), Token::static_symbol(name),
) );
Self::bare(ident)
} }
pub fn private(name: &'static str) -> Self { pub fn private(name: &'static str) -> Self {
Self::bare(None, VarName::from_static(name)) let ident = ast::Identifier::private_from_token(Token::static_symbol(name));
Self::bare(ident)
} }
pub fn private_with_line(name: Str, line: u32) -> Self { pub fn private_with_line(name: Str, line: u32) -> Self {
Self::bare(None, VarName::from_str_and_line(name, line)) let ident = ast::Identifier::private_from_token(Token::symbol_with_line(&name, line));
Self::bare(ident)
} }
pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self { pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self {
Self::bare(Some(dot), VarName::from_str_and_line(name, line)) let ident = ast::Identifier::public_from_token(dot, Token::symbol_with_line(&name, line));
Self::bare(ident)
} }
pub const fn bare(dot: Option<Token>, name: VarName) -> Self { pub const fn bare(ident: ast::Identifier) -> Self {
Self::new(dot, name, None, VarInfo::const_default()) if ident.vis.is_public() {
Self::new(ident, None, VarInfo::const_default_public())
} else {
Self::new(ident, None, VarInfo::const_default_private())
}
} }
pub fn is_py_api(&self) -> bool { pub fn is_py_api(&self) -> bool {
@ -496,18 +478,15 @@ impl Identifier {
} }
pub fn is_const(&self) -> bool { pub fn is_const(&self) -> bool {
self.name.is_const() self.raw.is_const()
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisibilityModifier {
match &self.dot { &self.vi.vis.modifier
Some(_) => Visibility::Public,
None => Visibility::Private,
}
} }
pub const fn inspect(&self) -> &Str { pub const fn inspect(&self) -> &Str {
self.name.inspect() self.raw.inspect()
} }
/// show dot + name (no qual_name & type) /// show dot + name (no qual_name & type)
@ -516,11 +495,11 @@ impl Identifier {
} }
pub fn is_procedural(&self) -> bool { pub fn is_procedural(&self) -> bool {
self.name.is_procedural() self.raw.is_procedural()
} }
pub fn downcast(self) -> erg_parser::ast::Identifier { pub fn downcast(self) -> ast::Identifier {
erg_parser::ast::Identifier::new(self.dot, self.name) self.raw
} }
} }
@ -598,12 +577,20 @@ impl Accessor {
Self::Ident(Identifier::public_with_line(DOT, name, line)) Self::Ident(Identifier::public_with_line(DOT, name, line))
} }
pub const fn private(name: Token, vi: VarInfo) -> Self { pub fn private(name: Token, vi: VarInfo) -> Self {
Self::Ident(Identifier::new(None, VarName::new(name), None, vi)) Self::Ident(Identifier::new(
ast::Identifier::private_from_token(name),
None,
vi,
))
} }
pub fn public(name: Token, vi: VarInfo) -> Self { pub fn public(name: Token, vi: VarInfo) -> Self {
Self::Ident(Identifier::new(Some(DOT), VarName::new(name), None, vi)) Self::Ident(Identifier::new(
ast::Identifier::public_from_token(DOT, name),
None,
vi,
))
} }
pub fn attr(obj: Expr, ident: Identifier) -> Self { pub fn attr(obj: Expr, ident: Identifier) -> Self {
@ -655,12 +642,12 @@ impl Accessor {
seps.remove(seps.len() - 1) seps.remove(seps.len() - 1)
}) })
.or_else(|| { .or_else(|| {
let mut raw_parts = ident.name.inspect().split_with(&["'"]); let mut raw_parts = ident.inspect().split_with(&["'"]);
// "'aaa'".split_with(&["'"]) == ["", "aaa", ""] // "'aaa'".split_with(&["'"]) == ["", "aaa", ""]
if raw_parts.len() == 3 || raw_parts.len() == 4 { if raw_parts.len() == 3 || raw_parts.len() == 4 {
Some(raw_parts.remove(1)) Some(raw_parts.remove(1))
} else { } else {
Some(ident.name.inspect()) Some(ident.inspect())
} }
}), }),
_ => None, _ => None,
@ -1580,9 +1567,13 @@ impl VarSignature {
self.ident.inspect() self.ident.inspect()
} }
pub fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisibilityModifier {
self.ident.vis() self.ident.vis()
} }
pub const fn name(&self) -> &VarName {
&self.ident.raw.name
}
} }
/// Once the default_value is set to Some, all subsequent values must be Some /// Once the default_value is set to Some, all subsequent values must be Some
@ -1864,6 +1855,10 @@ impl SubrSignature {
pub fn is_procedural(&self) -> bool { pub fn is_procedural(&self) -> bool {
self.ident.is_procedural() self.ident.is_procedural()
} }
pub const fn name(&self) -> &VarName {
&self.ident.raw.name
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -1947,13 +1942,20 @@ impl Signature {
} }
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisibilityModifier {
match self { match self {
Self::Var(v) => v.ident.vis(), Self::Var(v) => v.ident.vis(),
Self::Subr(s) => s.ident.vis(), Self::Subr(s) => s.ident.vis(),
} }
} }
pub const fn inspect(&self) -> &Str {
match self {
Self::Var(v) => v.ident.inspect(),
Self::Subr(s) => s.ident.inspect(),
}
}
pub const fn ident(&self) -> &Identifier { pub const fn ident(&self) -> &Identifier {
match self { match self {
Self::Var(v) => &v.ident, Self::Var(v) => &v.ident,
@ -1975,6 +1977,13 @@ impl Signature {
} }
} }
pub const fn name(&self) -> &VarName {
match self {
Self::Var(v) => v.name(),
Self::Subr(s) => s.name(),
}
}
pub fn t_spec(&self) -> Option<&TypeSpec> { pub fn t_spec(&self) -> Option<&TypeSpec> {
match self { match self {
Self::Var(v) => v.t_spec.as_ref(), Self::Var(v) => v.t_spec.as_ref(),

View file

@ -9,10 +9,10 @@ use erg_common::error::{Location, MultiErrorDisplay};
use erg_common::set; use erg_common::set;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{Locational, NoTypeDisplay, Runnable, Stream}; use erg_common::traits::{Locational, NoTypeDisplay, Runnable, Stream};
use erg_common::vis::Visibility; use erg_common::triple::Triple;
use erg_common::{fmt_option, fn_name, log, option_enum_unwrap, switch_lang, Str}; use erg_common::{fmt_option, fn_name, log, option_enum_unwrap, switch_lang, Str};
use erg_parser::ast; use erg_parser::ast::{self, VisModifierSpec};
use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST}; use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST};
use erg_parser::build_ast::ASTBuilder; use erg_parser::build_ast::ASTBuilder;
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
@ -27,7 +27,7 @@ use crate::ty::constructors::{
use crate::ty::free::Constraint; use crate::ty::free::Constraint;
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{HasType, ParamTy, Type}; use crate::ty::{HasType, ParamTy, Type, VisibilityModifier};
use crate::context::{ use crate::context::{
ClassDefType, Context, ContextKind, ContextProvider, ModuleContext, RegistrationMode, ClassDefType, Context, ContextKind, ContextProvider, ModuleContext, RegistrationMode,
@ -43,7 +43,8 @@ use crate::reorder::Reorderer;
use crate::varinfo::{VarInfo, VarKind}; use crate::varinfo::{VarInfo, VarKind};
use crate::AccessKind; use crate::AccessKind;
use crate::{feature_error, unreachable_error}; use crate::{feature_error, unreachable_error};
use Visibility::*;
use VisibilityModifier::*;
/// Checks & infers types of an AST, and convert (lower) it into a HIR /// Checks & infers types of an AST, and convert (lower) it into a HIR
#[derive(Debug)] #[derive(Debug)]
@ -624,14 +625,40 @@ impl ASTLowerer {
} }
ast::Accessor::Attr(attr) => { ast::Accessor::Attr(attr) => {
let obj = self.lower_expr(*attr.obj)?; let obj = self.lower_expr(*attr.obj)?;
let vi = self.module.context.get_attr_info( let vi = match self.module.context.get_attr_info(
&obj, &obj,
&attr.ident, &attr.ident,
&self.cfg.input, &self.cfg.input,
&self.module.context.name, &self.module.context,
)?; ) {
Triple::Ok(vi) => vi,
Triple::Err(errs) => {
self.errs.push(errs);
VarInfo::ILLEGAL.clone()
}
Triple::None => {
let self_t = obj.t();
let (similar_info, similar_name) = self
.module
.context
.get_similar_attr_and_info(&self_t, attr.ident.inspect())
.unzip();
let err = LowerError::detailed_no_attr_error(
self.cfg.input.clone(),
line!() as usize,
attr.ident.loc(),
self.module.context.caused_by(),
&self_t,
attr.ident.inspect(),
similar_name,
similar_info,
);
self.errs.push(err);
VarInfo::ILLEGAL.clone()
}
};
self.inc_ref(&vi, &attr.ident.name); self.inc_ref(&vi, &attr.ident.name);
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); let ident = hir::Identifier::new(attr.ident, None, vi);
let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident)); let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident));
Ok(acc) Ok(acc)
} }
@ -649,7 +676,7 @@ impl ASTLowerer {
fn lower_ident(&mut self, ident: ast::Identifier) -> LowerResult<hir::Identifier> { fn lower_ident(&mut self, ident: ast::Identifier) -> LowerResult<hir::Identifier> {
// `match` is a special form, typing is magic // `match` is a special form, typing is magic
let (vi, __name__) = if ident.vis().is_private() let (vi, __name__) = if ident.vis.is_private()
&& (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!") && (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!")
{ {
( (
@ -660,22 +687,47 @@ impl ASTLowerer {
None, None,
) )
} else { } else {
let res = match self.module.context.rec_get_var_info(
&ident,
AccessKind::Name,
&self.cfg.input,
&self.module.context,
) {
Triple::Ok(vi) => vi,
Triple::Err(err) => {
self.errs.push(err);
VarInfo::ILLEGAL.clone()
}
Triple::None => {
let (similar_info, similar_name) = self
.module
.context
.get_similar_name_and_info(ident.inspect())
.unzip();
let err = LowerError::detailed_no_var_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
self.module.context.caused_by(),
ident.inspect(),
similar_name,
similar_info,
);
self.errs.push(err);
VarInfo::ILLEGAL.clone()
}
};
( (
self.module.context.rec_get_var_info( res,
&ident,
AccessKind::Name,
&self.cfg.input,
&self.module.context.name,
)?,
self.module self.module
.context .context
.get_singular_ctx_by_ident(&ident, &self.module.context.name) .get_singular_ctx_by_ident(&ident, &self.module.context)
.ok() .ok()
.map(|ctx| ctx.name.clone()), .map(|ctx| ctx.name.clone()),
) )
}; };
self.inc_ref(&vi, &ident.name); self.inc_ref(&vi, &ident.name);
let ident = hir::Identifier::new(ident.dot, ident.name, __name__, vi); let ident = hir::Identifier::new(ident, __name__, vi);
Ok(ident) Ok(ident)
} }
@ -700,7 +752,7 @@ impl ASTLowerer {
let t = self let t = self
.module .module
.context .context
.get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context.name) .get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context)
.unwrap_or_else(|errs| { .unwrap_or_else(|errs| {
self.errs.extend(errs); self.errs.extend(errs);
VarInfo::ILLEGAL.clone() VarInfo::ILLEGAL.clone()
@ -724,7 +776,7 @@ impl ASTLowerer {
let t = self let t = self
.module .module
.context .context
.get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context.name) .get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context)
.unwrap_or_else(|errs| { .unwrap_or_else(|errs| {
self.errs.extend(errs); self.errs.extend(errs);
VarInfo::ILLEGAL.clone() VarInfo::ILLEGAL.clone()
@ -824,7 +876,7 @@ impl ASTLowerer {
&hir_args.pos_args, &hir_args.pos_args,
&hir_args.kw_args, &hir_args.kw_args,
&self.cfg.input, &self.cfg.input,
&self.module.context.name, &self.module.context,
) { ) {
Ok(vi) => vi, Ok(vi) => vi,
Err((vi, es)) => { Err((vi, es)) => {
@ -835,12 +887,7 @@ impl ASTLowerer {
}; };
let attr_name = if let Some(attr_name) = call.attr_name { let attr_name = if let Some(attr_name) = call.attr_name {
self.inc_ref(&vi, &attr_name.name); self.inc_ref(&vi, &attr_name.name);
Some(hir::Identifier::new( Some(hir::Identifier::new(attr_name, None, vi))
attr_name.dot,
attr_name.name,
None,
vi,
))
} else { } else {
*obj.ref_mut_t() = vi.t; *obj.ref_mut_t() = vi.t;
None None
@ -904,17 +951,17 @@ impl ASTLowerer {
let args = self.lower_record(pack.args)?; let args = self.lower_record(pack.args)?;
let args = vec![hir::PosArg::new(hir::Expr::Record(args))]; let args = vec![hir::PosArg::new(hir::Expr::Record(args))];
let attr_name = ast::Identifier::new( let attr_name = ast::Identifier::new(
Some(Token::new( VisModifierSpec::Public(Token::new(
TokenKind::Dot, TokenKind::Dot,
Str::ever("."), Str::ever("."),
pack.connector.lineno, pack.connector.ln_begin().unwrap(),
pack.connector.col_begin, pack.connector.col_begin().unwrap(),
)), )),
ast::VarName::new(Token::new( ast::VarName::new(Token::new(
TokenKind::Symbol, TokenKind::Symbol,
Str::ever("new"), Str::ever("new"),
pack.connector.lineno, pack.connector.ln_begin().unwrap(),
pack.connector.col_begin, pack.connector.col_begin().unwrap(),
)), )),
); );
let vi = match self.module.context.get_call_t( let vi = match self.module.context.get_call_t(
@ -923,7 +970,7 @@ impl ASTLowerer {
&args, &args,
&[], &[],
&self.cfg.input, &self.cfg.input,
&self.module.context.name, &self.module.context,
) { ) {
Ok(vi) => vi, Ok(vi) => vi,
Err((vi, errs)) => { Err((vi, errs)) => {
@ -932,7 +979,7 @@ impl ASTLowerer {
} }
}; };
let args = hir::Args::pos_only(args, None); let args = hir::Args::pos_only(args, None);
let attr_name = hir::Identifier::new(attr_name.dot, attr_name.name, None, vi); let attr_name = hir::Identifier::new(attr_name, None, vi);
Ok(hir::Call::new(class, Some(attr_name), args)) Ok(hir::Call::new(class, Some(attr_name), args))
} }
@ -1209,7 +1256,10 @@ impl ASTLowerer {
)); ));
} }
let kind = ContextKind::from(def.def_kind()); let kind = ContextKind::from(def.def_kind());
let vis = def.sig.vis(); let vis = self
.module
.context
.instantiate_vis_modifier(def.sig.vis())?;
let res = match def.sig { let res = match def.sig {
ast::Signature::Subr(sig) => { ast::Signature::Subr(sig) => {
let tv_cache = self let tv_cache = self
@ -1263,7 +1313,7 @@ impl ASTLowerer {
let ident = match &sig.pat { let ident = match &sig.pat {
ast::VarPattern::Ident(ident) => ident.clone(), ast::VarPattern::Ident(ident) => ident.clone(),
ast::VarPattern::Discard(token) => { ast::VarPattern::Discard(token) => {
ast::Identifier::new(None, VarName::new(token.clone())) ast::Identifier::private_from_token(token.clone())
} }
_ => unreachable!(), _ => unreachable!(),
}; };
@ -1287,7 +1337,7 @@ impl ASTLowerer {
body.id, body.id,
None, None,
)?; )?;
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); let ident = hir::Identifier::new(ident, None, vi);
let sig = hir::VarSignature::new(ident, sig.t_spec); let sig = hir::VarSignature::new(ident, sig.t_spec);
let body = hir::DefBody::new(body.op, block, body.id); let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Var(sig), body)) Ok(hir::Def::new(hir::Signature::Var(sig), body))
@ -1358,7 +1408,7 @@ impl ASTLowerer {
); );
self.warns.push(warn); self.warns.push(warn);
} }
let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi); let ident = hir::Identifier::new(sig.ident, None, vi);
let sig = let sig =
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let body = hir::DefBody::new(body.op, block, body.id); let body = hir::DefBody::new(body.op, block, body.id);
@ -1371,7 +1421,7 @@ impl ASTLowerer {
&Type::Failure, &Type::Failure,
)?; )?;
self.errs.extend(errs); self.errs.extend(errs);
let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi); let ident = hir::Identifier::new(sig.ident, None, vi);
let sig = let sig =
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let block = let block =
@ -1396,7 +1446,7 @@ impl ASTLowerer {
.unwrap() .unwrap()
.fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?; .fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?;
let block = self.lower_block(body.block)?; let block = self.lower_block(body.block)?;
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name); let ident = hir::Identifier::bare(sig.ident);
let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let body = hir::DefBody::new(body.op, block, body.id); let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Subr(sig), body)) Ok(hir::Def::new(hir::Signature::Subr(sig), body))
@ -1439,12 +1489,12 @@ impl ASTLowerer {
let kind = ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone())); let kind = ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone()));
self.module self.module
.context .context
.grow(&class.local_name(), kind, hir_def.sig.vis(), None); .grow(&class.local_name(), kind, hir_def.sig.vis().clone(), None);
for attr in methods.attrs.iter_mut() { for attr in methods.attrs.iter_mut() {
match attr { match attr {
ast::ClassAttr::Def(def) => { ast::ClassAttr::Def(def) => {
if methods.vis.is(TokenKind::Dot) { if methods.vis.is_public() {
def.sig.ident_mut().unwrap().dot = Some(Token::new( def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new(
TokenKind::Dot, TokenKind::Dot,
".", ".",
def.sig.ln_begin().unwrap_or(0), def.sig.ln_begin().unwrap_or(0),
@ -1641,14 +1691,17 @@ impl ASTLowerer {
let mut hir_methods = hir::Block::empty(); let mut hir_methods = hir::Block::empty();
for mut methods in class_def.methods_list.into_iter() { for mut methods in class_def.methods_list.into_iter() {
let kind = ContextKind::PatchMethodDefs(base_t.clone()); let kind = ContextKind::PatchMethodDefs(base_t.clone());
self.module self.module.context.grow(
.context hir_def.sig.ident().inspect(),
.grow(hir_def.sig.ident().inspect(), kind, hir_def.sig.vis(), None); kind,
hir_def.sig.vis().clone(),
None,
);
for attr in methods.attrs.iter_mut() { for attr in methods.attrs.iter_mut() {
match attr { match attr {
ast::ClassAttr::Def(def) => { ast::ClassAttr::Def(def) => {
if methods.vis.is(TokenKind::Dot) { if methods.vis.is_public() {
def.sig.ident_mut().unwrap().dot = Some(Token::new( def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new(
TokenKind::Dot, TokenKind::Dot,
".", ".",
def.sig.ln_begin().unwrap(), def.sig.ln_begin().unwrap(),
@ -2037,7 +2090,7 @@ impl ASTLowerer {
let ctx = self let ctx = self
.module .module
.context .context
.get_singular_ctx_by_hir_expr(&expr, &self.module.context.name)?; .get_singular_ctx_by_hir_expr(&expr, &self.module.context)?;
// REVIEW: need to use subtype_of? // REVIEW: need to use subtype_of?
if ctx.super_traits.iter().all(|trait_| trait_ != &spec_t) if ctx.super_traits.iter().all(|trait_| trait_ != &spec_t)
&& ctx.super_classes.iter().all(|class| class != &spec_t) && ctx.super_classes.iter().all(|class| class != &spec_t)
@ -2089,14 +2142,30 @@ impl ASTLowerer {
&ident, &ident,
AccessKind::Name, AccessKind::Name,
&self.cfg.input, &self.cfg.input,
&self.module.context.name, &self.module.context,
) )
.or_else(|_e| { .none_or_else(|| {
self.module.context.rec_get_var_info( self.module.context.rec_get_var_info(
&ident, &ident,
AccessKind::Name, AccessKind::Name,
&self.cfg.input, &self.cfg.input,
&self.module.context.name, &self.module.context,
)
})
.none_or_result(|| {
let (similar_info, similar_name) = self
.module
.context
.get_similar_name_and_info(ident.inspect())
.unzip();
LowerError::detailed_no_var_error(
self.cfg.input.clone(),
line!() as usize,
ident.loc(),
self.module.context.caused_by(),
ident.inspect(),
similar_name,
similar_info,
) )
})?; })?;
if is_instance_ascription { if is_instance_ascription {
@ -2119,10 +2188,10 @@ impl ASTLowerer {
let qual_name = self let qual_name = self
.module .module
.context .context
.get_singular_ctx_by_ident(&ident, &self.module.context.name) .get_singular_ctx_by_ident(&ident, &self.module.context)
.ok() .ok()
.map(|ctx| ctx.name.clone()); .map(|ctx| ctx.name.clone());
let ident = hir::Identifier::new(ident.dot, ident.name, qual_name, ident_vi); let ident = hir::Identifier::new(ident, qual_name, ident_vi);
let expr = hir::Expr::Accessor(hir::Accessor::Ident(ident)); let expr = hir::Expr::Accessor(hir::Accessor::Ident(ident));
let t_spec = self.lower_type_spec_with_op(tasc.t_spec, spec_t)?; let t_spec = self.lower_type_spec_with_op(tasc.t_spec, spec_t)?;
Ok(expr.type_asc(t_spec)) Ok(expr.type_asc(t_spec))

View file

@ -6,13 +6,11 @@ use erg_common::error::Location;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::style::colors::DEBUG_MAIN; use erg_common::style::colors::DEBUG_MAIN;
use erg_common::traits::{Locational, Stream}; use erg_common::traits::{Locational, Stream};
use erg_common::vis::Visibility;
use erg_common::Str; use erg_common::Str;
use erg_common::{impl_display_from_debug, log}; use erg_common::{impl_display_from_debug, log};
use erg_parser::ast::{ParamPattern, VarName}; use erg_parser::ast::{ParamPattern, VarName};
use Visibility::*;
use crate::ty::{HasType, Ownership}; use crate::ty::{HasType, Ownership, Visibility};
use crate::error::{OwnershipError, OwnershipErrors}; use crate::error::{OwnershipError, OwnershipErrors};
use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR}; use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR};
@ -39,7 +37,7 @@ impl_display_from_debug!(LocalVars);
#[derive(Debug)] #[derive(Debug)]
pub struct OwnershipChecker { pub struct OwnershipChecker {
cfg: ErgConfig, cfg: ErgConfig,
path_stack: Vec<(Str, Visibility)>, path_stack: Vec<Visibility>,
dict: Dict<Str, LocalVars>, dict: Dict<Str, LocalVars>,
errs: OwnershipErrors, errs: OwnershipErrors,
} }
@ -55,15 +53,13 @@ impl OwnershipChecker {
} }
fn full_path(&self) -> String { fn full_path(&self) -> String {
self.path_stack self.path_stack.iter().fold(String::new(), |acc, vis| {
.iter() if vis.is_public() {
.fold(String::new(), |acc, (path, vis)| { acc + "." + &vis.def_namespace[..]
if vis.is_public() { } else {
acc + "." + &path[..] acc + "::" + &vis.def_namespace[..]
} else { }
acc + "::" + &path[..] })
}
})
} }
// moveされた後の変数が使用されていないかチェックする // moveされた後の変数が使用されていないかチェックする
@ -71,7 +67,7 @@ impl OwnershipChecker {
pub fn check(&mut self, hir: HIR) -> Result<HIR, (HIR, OwnershipErrors)> { pub fn check(&mut self, hir: HIR) -> Result<HIR, (HIR, OwnershipErrors)> {
log!(info "the ownership checking process has started.{RESET}"); log!(info "the ownership checking process has started.{RESET}");
if self.full_path() != ("::".to_string() + &hir.name[..]) { if self.full_path() != ("::".to_string() + &hir.name[..]) {
self.path_stack.push((hir.name.clone(), Private)); self.path_stack.push(Visibility::private(hir.name.clone()));
self.dict self.dict
.insert(Str::from(self.full_path()), LocalVars::default()); .insert(Str::from(self.full_path()), LocalVars::default());
} }
@ -106,7 +102,8 @@ impl OwnershipChecker {
Signature::Var(var) => var.inspect().clone(), Signature::Var(var) => var.inspect().clone(),
Signature::Subr(subr) => subr.ident.inspect().clone(), Signature::Subr(subr) => subr.ident.inspect().clone(),
}; };
self.path_stack.push((name, def.sig.vis())); self.path_stack
.push(Visibility::new(def.sig.vis().clone(), name));
self.dict self.dict
.insert(Str::from(self.full_path()), LocalVars::default()); .insert(Str::from(self.full_path()), LocalVars::default());
if let Signature::Subr(subr) = &def.sig { if let Signature::Subr(subr) = &def.sig {
@ -247,7 +244,8 @@ impl OwnershipChecker {
}, },
// TODO: capturing // TODO: capturing
Expr::Lambda(lambda) => { Expr::Lambda(lambda) => {
let name_and_vis = (Str::from(format!("<lambda_{}>", lambda.id)), Private); let name_and_vis =
Visibility::private(Str::from(format!("<lambda_{}>", lambda.id)));
self.path_stack.push(name_and_vis); self.path_stack.push(name_and_vis);
self.dict self.dict
.insert(Str::from(self.full_path()), LocalVars::default()); .insert(Str::from(self.full_path()), LocalVars::default());
@ -289,11 +287,11 @@ impl OwnershipChecker {
fn nth_outer_scope(&mut self, n: usize) -> &mut LocalVars { fn nth_outer_scope(&mut self, n: usize) -> &mut LocalVars {
let path = self.path_stack.iter().take(self.path_stack.len() - n).fold( let path = self.path_stack.iter().take(self.path_stack.len() - n).fold(
String::new(), String::new(),
|acc, (path, vis)| { |acc, vis| {
if vis.is_public() { if vis.is_public() {
acc + "." + &path[..] acc + "." + &vis.def_namespace[..]
} else { } else {
acc + "::" + &path[..] acc + "::" + &vis.def_namespace[..]
} }
}, },
); );

View file

@ -123,7 +123,6 @@ impl Reorderer {
/// ``` /// ```
fn flatten_method_decls(&mut self, new: &mut Vec<Expr>, methods: Methods) { fn flatten_method_decls(&mut self, new: &mut Vec<Expr>, methods: Methods) {
let class = methods.class_as_expr.as_ref(); let class = methods.class_as_expr.as_ref();
let vis = methods.vis();
for method in methods.attrs.into_iter() { for method in methods.attrs.into_iter() {
match method { match method {
ClassAttr::Decl(decl) => { ClassAttr::Decl(decl) => {
@ -138,11 +137,7 @@ impl Reorderer {
)); ));
continue; continue;
}; };
let attr = if vis.is_public() { let attr = Identifier::new(methods.vis.clone(), ident.name);
Identifier::new(Some(methods.vis.clone()), ident.name)
} else {
Identifier::new(None, ident.name)
};
let expr = class.clone().attr_expr(attr); let expr = class.clone().attr_expr(attr);
let decl = TypeAscription::new(expr, decl.t_spec); let decl = TypeAscription::new(expr, decl.t_spec);
new.push(Expr::TypeAscription(decl)); new.push(Expr::TypeAscription(decl));

View file

@ -787,9 +787,9 @@ impl ScriptGenerator {
if let Some(py_name) = ident.vi.py_name { if let Some(py_name) = ident.vi.py_name {
return demangle(&py_name); return demangle(&py_name);
} }
let name = ident.name.into_token().content.to_string(); let name = ident.inspect().to_string();
let name = replace_non_symbolic(name); let name = replace_non_symbolic(name);
if ident.dot.is_some() { if ident.vis().is_public() {
name name
} else { } else {
format!("{name}__") format!("{name}__")
@ -941,7 +941,7 @@ impl ScriptGenerator {
demangle(&patch_def.sig.ident().to_string_notype()), demangle(&patch_def.sig.ident().to_string_notype()),
demangle(&def.sig.ident().to_string_notype()), demangle(&def.sig.ident().to_string_notype()),
); );
def.sig.ident_mut().name = VarName::from_str(Str::from(name)); def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
code += &" ".repeat(self.level); code += &" ".repeat(self.level);
code += &self.transpile_def(def); code += &self.transpile_def(def);
code.push('\n'); code.push('\n');

View file

@ -11,6 +11,7 @@ pub mod free;
pub mod predicate; pub mod predicate;
pub mod typaram; pub mod typaram;
pub mod value; pub mod value;
pub mod vis;
use std::fmt; use std::fmt;
use std::ops::{BitAnd, BitOr, Deref, Not, Range, RangeInclusive}; use std::ops::{BitAnd, BitOr, Deref, Not, Range, RangeInclusive};
@ -22,7 +23,6 @@ use erg_common::fresh::fresh_varname;
use erg_common::log; use erg_common::log;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{LimitedDisplay, StructuralEq}; use erg_common::traits::{LimitedDisplay, StructuralEq};
use erg_common::vis::Field;
use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str}; use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str};
use erg_parser::token::TokenKind; use erg_parser::token::TokenKind;
@ -35,6 +35,7 @@ use typaram::{IntervalOp, TyParam};
use value::value_set::*; use value::value_set::*;
use value::ValueObj; use value::ValueObj;
use value::ValueObj::{Inf, NegInf}; use value::ValueObj::{Inf, NegInf};
pub use vis::*;
/// cloneのコストがあるためなるべく.ref_tを使うようにすること /// cloneのコストがあるためなるべく.ref_tを使うようにすること
/// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う /// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う
@ -534,9 +535,6 @@ impl LimitedDisplay for RefinementType {
write!(f, "{rhs}, ")?; write!(f, "{rhs}, ")?;
} }
write!(f, "}}")?; write!(f, "}}")?;
if cfg!(feature = "debug") {
write!(f, "(<: {})", self.t)?;
}
Ok(()) Ok(())
} else { } else {
write!(f, "{{{}: ", self.var)?; write!(f, "{{{}: ", self.var)?;

View file

@ -7,7 +7,6 @@ use erg_common::dict::Dict;
use erg_common::set; use erg_common::set;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::traits::{LimitedDisplay, StructuralEq}; use erg_common::traits::{LimitedDisplay, StructuralEq};
use erg_common::vis::Field;
use erg_common::Str; use erg_common::Str;
use erg_common::{dict, log}; use erg_common::{dict, log};
@ -19,7 +18,7 @@ use super::free::{
}; };
use super::value::ValueObj; use super::value::ValueObj;
use super::Type; use super::Type;
use super::{ConstSubr, ParamTy, UserConstSubr}; use super::{ConstSubr, Field, ParamTy, UserConstSubr};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]

View file

@ -16,7 +16,6 @@ use erg_common::python_util::PythonVersion;
use erg_common::serialize::*; use erg_common::serialize::*;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::shared::Shared; use erg_common::shared::Shared;
use erg_common::vis::Field;
use erg_common::{dict, fmt_iter, impl_display_from_debug, log, switch_lang}; use erg_common::{dict, fmt_iter, impl_display_from_debug, log, switch_lang};
use erg_common::{RcArray, Str}; use erg_common::{RcArray, Str};
use erg_parser::ast::{ConstArgs, ConstExpr}; use erg_parser::ast::{ConstArgs, ConstExpr};
@ -28,7 +27,7 @@ use self::value_set::inner_class;
use super::codeobj::CodeObj; use super::codeobj::CodeObj;
use super::constructors::{array_t, dict_t, mono, poly, refinement, set_t, tuple_t}; use super::constructors::{array_t, dict_t, mono, poly, refinement, set_t, tuple_t};
use super::typaram::TyParam; use super::typaram::TyParam;
use super::{ConstSubr, HasType, Predicate, Type}; use super::{ConstSubr, Field, HasType, Predicate, Type};
pub struct EvalValueError(pub Box<ErrorCore>); pub struct EvalValueError(pub Box<ErrorCore>);
@ -1311,11 +1310,11 @@ impl ValueObj {
} }
Self::Subr(subr) => subr.as_type().map(TypeObj::Builtin), Self::Subr(subr) => subr.as_type().map(TypeObj::Builtin),
Self::Array(elems) | Self::Tuple(elems) => { Self::Array(elems) | Self::Tuple(elems) => {
erg_common::log!(err "as_type({})", erg_common::fmt_vec(elems)); log!(err "as_type({})", erg_common::fmt_vec(elems));
None None
} }
Self::Dict(elems) => { Self::Dict(elems) => {
erg_common::log!(err "as_type({elems})"); log!(err "as_type({elems})");
None None
} }
_other => None, _other => None,

View file

@ -0,0 +1,233 @@
use std::borrow::Borrow;
use std::fmt;
#[allow(unused_imports)]
use erg_common::log;
use erg_common::set::Set;
use erg_common::{switch_lang, Str};
use erg_parser::ast::AccessModifier;
use crate::context::Context;
use crate::ty::Type;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisibilityModifier {
Public,
Private,
Restricted(Set<Str>),
SubtypeRestricted(Type),
}
impl fmt::Display for VisibilityModifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Private => write!(f, "::"),
Self::Public => write!(f, "."),
Self::Restricted(namespaces) => write!(f, "::[{namespaces}]"),
Self::SubtypeRestricted(typ) => write!(f, "::[<: {typ}]"),
}
}
}
impl VisibilityModifier {
pub const fn is_public(&self) -> bool {
matches!(self, Self::Public)
}
pub const fn is_private(&self) -> bool {
matches!(self, Self::Private)
}
pub const fn display_as_accessor(&self) -> &'static str {
match self {
Self::Public => ".",
Self::Private | Self::Restricted(_) | Self::SubtypeRestricted(_) => "::",
}
}
pub fn display(&self) -> String {
match self {
Self::Private => switch_lang!(
"japanese" => "非公開",
"simplified_chinese" => "私有",
"traditional_chinese" => "私有",
"english" => "private",
)
.into(),
Self::Public => switch_lang!(
"japanese" => "公開",
"simplified_chinese" => "公开",
"traditional_chinese" => "公開",
"english" => "public",
)
.into(),
Self::Restricted(namespaces) => switch_lang!(
"japanese" => format!("制限付き公開({namespaces}でのみ公開)"),
"simplified_chinese" => format!("受限公开({namespaces}中可见)"),
"traditional_chinese" => format!("受限公開({namespaces}中可見)"),
"english" => format!("restricted public ({namespaces} only)"),
),
Self::SubtypeRestricted(typ) => switch_lang!(
"japanese" => format!("制限付き公開({typ}の部分型でのみ公開)"),
"simplified_chinese" => format!("受限公开({typ}的子类型中可见)"),
"traditional_chinese" => format!("受限公開({typ}的子類型中可見)"),
"english" => format!("restricted public (subtypes of {typ} only)"),
),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Visibility {
pub modifier: VisibilityModifier,
pub def_namespace: Str,
}
impl Visibility {
pub const DUMMY_PRIVATE: Self = Self {
modifier: VisibilityModifier::Private,
def_namespace: Str::ever("<dummy>"),
};
pub const DUMMY_PUBLIC: Self = Self {
modifier: VisibilityModifier::Public,
def_namespace: Str::ever("<dummy>"),
};
pub const BUILTIN_PRIVATE: Self = Self {
modifier: VisibilityModifier::Private,
def_namespace: Str::ever("<builtins>"),
};
pub const BUILTIN_PUBLIC: Self = Self {
modifier: VisibilityModifier::Public,
def_namespace: Str::ever("<builtins>"),
};
pub const fn new(modifier: VisibilityModifier, def_namespace: Str) -> Self {
Self {
modifier,
def_namespace,
}
}
pub fn private<S: Into<Str>>(namespace: S) -> Self {
Self {
modifier: VisibilityModifier::Private,
def_namespace: namespace.into(),
}
}
pub const fn is_public(&self) -> bool {
self.modifier.is_public()
}
pub const fn is_private(&self) -> bool {
self.modifier.is_private()
}
pub fn compatible(&self, access: &AccessModifier, namespace: &Context) -> bool {
match (&self.modifier, access) {
(_, AccessModifier::Force) => true,
(VisibilityModifier::Public, AccessModifier::Auto | AccessModifier::Public) => true,
// compatible example:
// def_namespace: <module>::C
// namespace: <module>::C::f
(VisibilityModifier::Private, AccessModifier::Auto | AccessModifier::Private) => {
&self.def_namespace[..] == "<builtins>"
|| namespace.name.starts_with(&self.def_namespace[..])
}
(
VisibilityModifier::Restricted(namespaces),
AccessModifier::Auto | AccessModifier::Private,
) => {
namespace.name.starts_with(&self.def_namespace[..])
|| namespaces.contains(&namespace.name)
}
(
VisibilityModifier::SubtypeRestricted(typ),
AccessModifier::Auto | AccessModifier::Private,
) => {
namespace.name.starts_with(&self.def_namespace[..]) || {
let Some(space_t) = namespace.rec_get_self_t() else {
return false;
};
namespace.subtype_of(&space_t, typ)
}
}
_ => false,
}
}
}
/// same structure as `Identifier`, but only for Record fields.
#[derive(Debug, Clone, Eq)]
pub struct Field {
pub vis: VisibilityModifier,
pub symbol: Str,
}
impl PartialEq for Field {
fn eq(&self, other: &Self) -> bool {
self.symbol == other.symbol
}
}
impl std::hash::Hash for Field {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.symbol.hash(state);
}
}
impl fmt::Display for Field {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.vis, self.symbol)
}
}
impl Borrow<str> for Field {
#[inline]
fn borrow(&self) -> &str {
&self.symbol[..]
}
}
impl Borrow<Str> for Field {
#[inline]
fn borrow(&self) -> &Str {
&self.symbol
}
}
impl Field {
pub const fn new(vis: VisibilityModifier, symbol: Str) -> Self {
Field { vis, symbol }
}
pub fn private(symbol: Str) -> Self {
Field::new(VisibilityModifier::Private, symbol)
}
pub fn public(symbol: Str) -> Self {
Field::new(VisibilityModifier::Public, symbol)
}
pub fn is_const(&self) -> bool {
self.symbol.starts_with(char::is_uppercase)
}
}
#[cfg(test)]
mod tests {
use super::*;
use erg_common::dict;
#[test]
fn test_std_key() {
let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2};
assert_eq!(dict.get("a"), Some(&1));
assert_eq!(dict.get("b"), Some(&2));
assert_eq!(dict.get(&Str::ever("b")), Some(&2));
assert_eq!(dict.get(&Str::rc("b")), Some(&2));
let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2};
assert_eq!(dict.get("a"), Some(&1));
assert_eq!(dict.get("b"), Some(&2));
}
}

View file

@ -3,14 +3,12 @@ use std::path::PathBuf;
use erg_common::error::Location; use erg_common::error::Location;
use erg_common::set::Set; use erg_common::set::Set;
use erg_common::vis::{Field, Visibility};
use erg_common::Str; use erg_common::Str;
use Visibility::*;
use erg_parser::ast::DefId; use erg_parser::ast::DefId;
use crate::context::DefaultInfo; use crate::context::DefaultInfo;
use crate::ty::{HasType, Type}; use crate::ty::{Field, HasType, Type, Visibility};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]
@ -200,18 +198,31 @@ impl HasType for VarInfo {
impl Default for VarInfo { impl Default for VarInfo {
fn default() -> Self { fn default() -> Self {
Self::const_default() Self::const_default_private()
} }
} }
impl VarInfo { impl VarInfo {
pub const ILLEGAL: &'static Self = &Self::const_default(); pub const ILLEGAL: &'static Self = &Self::const_default_private();
pub const fn const_default() -> Self { pub const fn const_default_private() -> Self {
Self::new( Self::new(
Type::Failure, Type::Failure,
Immutable, Immutable,
Private, Visibility::DUMMY_PRIVATE,
VarKind::DoesNotExist,
None,
None,
None,
AbsLocation::unknown(),
)
}
pub const fn const_default_public() -> Self {
Self::new(
Type::Failure,
Immutable,
Visibility::DUMMY_PUBLIC,
VarKind::DoesNotExist, VarKind::DoesNotExist,
None, None,
None, None,
@ -250,16 +261,25 @@ impl VarInfo {
} }
} }
pub fn nd_parameter(t: Type, def_loc: AbsLocation) -> Self { pub fn nd_parameter(t: Type, def_loc: AbsLocation, namespace: Str) -> Self {
let kind = VarKind::Parameter { let kind = VarKind::Parameter {
def_id: DefId(0), def_id: DefId(0),
var: false, var: false,
default: DefaultInfo::NonDefault, default: DefaultInfo::NonDefault,
}; };
Self::new(t, Immutable, Private, kind, None, None, None, def_loc) Self::new(
t,
Immutable,
Visibility::private(namespace),
kind,
None,
None,
None,
def_loc,
)
} }
pub fn instance_attr(field: Field, t: Type, impl_of: Option<Type>) -> Self { pub fn instance_attr(field: Field, t: Type, impl_of: Option<Type>, namespace: Str) -> Self {
let muty = if field.is_const() { let muty = if field.is_const() {
Mutability::Const Mutability::Const
} else { } else {
@ -269,7 +289,7 @@ impl VarInfo {
Self::new( Self::new(
t, t,
muty, muty,
field.vis, Visibility::new(field.vis, namespace),
kind, kind,
None, None,
impl_of, impl_of,

View file

@ -7,7 +7,6 @@ use erg_common::error::Location;
use erg_common::set::Set as HashSet; use erg_common::set::Set as HashSet;
// use erg_common::dict::Dict as HashMap; // use erg_common::dict::Dict as HashMap;
use erg_common::traits::{Locational, NestedDisplay, Stream}; use erg_common::traits::{Locational, NestedDisplay, Stream};
use erg_common::vis::{Field, Visibility};
use erg_common::{ use erg_common::{
fmt_option, fmt_vec, impl_display_for_enum, impl_display_for_single_struct, fmt_option, fmt_vec, impl_display_for_enum, impl_display_for_single_struct,
impl_display_from_nested, impl_displayable_stream_for_wrapper, impl_from_trait_for_enum, impl_display_from_nested, impl_displayable_stream_for_wrapper, impl_from_trait_for_enum,
@ -493,11 +492,31 @@ impl_locational_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr, TypeApp);
impl Accessor { impl Accessor {
pub const fn local(symbol: Token) -> Self { pub const fn local(symbol: Token) -> Self {
Self::Ident(Identifier::new(None, VarName::new(symbol))) Self::Ident(Identifier::new(
VisModifierSpec::Private,
VarName::new(symbol),
))
} }
pub const fn public(dot: Token, symbol: Token) -> Self { pub const fn public(dot: Token, symbol: Token) -> Self {
Self::Ident(Identifier::new(Some(dot), VarName::new(symbol))) Self::Ident(Identifier::new(
VisModifierSpec::Public(dot),
VarName::new(symbol),
))
}
pub const fn explicit_local(dcolon: Token, symbol: Token) -> Self {
Self::Ident(Identifier::new(
VisModifierSpec::ExplicitPrivate(dcolon),
VarName::new(symbol),
))
}
pub const fn restricted(rest: VisRestriction, symbol: Token) -> Self {
Self::Ident(Identifier::new(
VisModifierSpec::Restricted(rest),
VarName::new(symbol),
))
} }
pub fn attr(obj: Expr, ident: Identifier) -> Self { pub fn attr(obj: Expr, ident: Identifier) -> Self {
@ -1201,7 +1220,7 @@ impl Call {
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct DataPack { pub struct DataPack {
pub class: Box<Expr>, pub class: Box<Expr>,
pub connector: Token, pub connector: VisModifierSpec,
pub args: Record, pub args: Record,
} }
@ -1220,7 +1239,7 @@ impl Locational for DataPack {
} }
impl DataPack { impl DataPack {
pub fn new(class: Expr, connector: Token, args: Record) -> Self { pub fn new(class: Expr, connector: VisModifierSpec, args: Record) -> Self {
Self { Self {
class: Box::new(class), class: Box::new(class),
connector, connector,
@ -1392,7 +1411,10 @@ impl_locational_for_enum!(ConstAccessor; Local, SelfDot, Attr, TupleAttr, Subscr
impl ConstAccessor { impl ConstAccessor {
pub const fn local(symbol: Token) -> Self { pub const fn local(symbol: Token) -> Self {
Self::Local(ConstIdentifier::new(None, VarName::new(symbol))) Self::Local(ConstIdentifier::new(
VisModifierSpec::Private,
VarName::new(symbol),
))
} }
pub fn attr(obj: ConstExpr, name: ConstIdentifier) -> Self { pub fn attr(obj: ConstExpr, name: ConstIdentifier) -> Self {
@ -2655,18 +2677,108 @@ impl VarName {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Namespaces(Vec<Accessor>);
impl_displayable_stream_for_wrapper!(Namespaces, Accessor);
impl NestedDisplay for Namespaces {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
for (i, ns) in self.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{ns}")?;
}
Ok(())
}
}
impl Locational for Namespaces {
fn loc(&self) -> Location {
Location::concat(self.first().unwrap(), self.last().unwrap())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisRestriction {
Namespaces(Namespaces),
SubtypeOf(Box<TypeSpec>),
}
impl_locational_for_enum!(VisRestriction; Namespaces, SubtypeOf);
impl_display_from_nested!(VisRestriction);
impl NestedDisplay for VisRestriction {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
match self {
Self::Namespaces(ns) => write!(f, "{ns}"),
Self::SubtypeOf(ty) => write!(f, "<: {ty}"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum VisModifierSpec {
Private,
Auto,
Public(Token),
ExplicitPrivate(Token),
Restricted(VisRestriction),
}
impl NestedDisplay for VisModifierSpec {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
match self {
Self::Private => Ok(()),
Self::Auto => write!(f, ":auto:"),
Self::Public(_token) => write!(f, "."),
Self::ExplicitPrivate(_token) => write!(f, "::"),
Self::Restricted(rest) => write!(f, "::[{rest}]"),
}
}
}
impl_display_from_nested!(VisModifierSpec);
impl Locational for VisModifierSpec {
fn loc(&self) -> Location {
match self {
Self::Private | Self::Auto => Location::Unknown,
Self::Public(token) => token.loc(),
Self::ExplicitPrivate(token) => token.loc(),
Self::Restricted(rest) => rest.loc(),
}
}
}
impl VisModifierSpec {
pub const fn is_public(&self) -> bool {
matches!(self, Self::Public(_))
}
pub const fn is_private(&self) -> bool {
matches!(self, Self::Private | Self::ExplicitPrivate(_))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AccessModifier {
Private, // `::`
Public, // `.`
Auto, // record unpacking
Force, // can access any identifiers
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Identifier { pub struct Identifier {
pub dot: Option<Token>, pub vis: VisModifierSpec,
pub name: VarName, pub name: VarName,
} }
impl NestedDisplay for Identifier { impl NestedDisplay for Identifier {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
match &self.dot { write!(f, "{}{}", self.vis, self.name)
Some(_dot) => write!(f, ".{}", self.name),
None => write!(f, "::{}", self.name),
}
} }
} }
@ -2674,24 +2786,16 @@ impl_display_from_nested!(Identifier);
impl Locational for Identifier { impl Locational for Identifier {
fn loc(&self) -> Location { fn loc(&self) -> Location {
if let Some(dot) = &self.dot { match &self.vis {
if dot.loc().is_unknown() { VisModifierSpec::Private | VisModifierSpec::Auto => self.name.loc(),
self.name.loc() VisModifierSpec::ExplicitPrivate(token) | VisModifierSpec::Public(token) => {
} else { Location::concat(token, &self.name)
Location::concat(dot, &self.name)
} }
} else { VisModifierSpec::Restricted(args) => Location::concat(args, &self.name),
self.name.loc()
} }
} }
} }
impl From<&Identifier> for Field {
fn from(ident: &Identifier) -> Self {
Self::new(ident.vis(), ident.inspect().clone())
}
}
impl From<Identifier> for Expr { impl From<Identifier> for Expr {
fn from(ident: Identifier) -> Self { fn from(ident: Identifier) -> Self {
Self::Accessor(Accessor::Ident(ident)) Self::Accessor(Accessor::Ident(ident))
@ -2699,34 +2803,52 @@ impl From<Identifier> for Expr {
} }
impl Identifier { impl Identifier {
pub const fn new(dot: Option<Token>, name: VarName) -> Self { pub const fn new(vis: VisModifierSpec, name: VarName) -> Self {
Self { dot, name } Self { vis, name }
} }
pub fn static_public(name: &'static str) -> Self { pub fn static_public(name: &'static str) -> Self {
Self::new( Self::new(
Some(Token::from_str(TokenKind::Dot, ".")), VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")),
VarName::from_static(name), VarName::from_static(name),
) )
} }
pub fn public(name: Str) -> Self { pub fn public(name: Str) -> Self {
Self::new( Self::new(
Some(Token::from_str(TokenKind::Dot, ".")), VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")),
VarName::from_str(name), VarName::from_str(name),
) )
} }
pub fn private(name: Str) -> Self { pub fn private(name: Str) -> Self {
Self::new(None, VarName::from_str(name)) Self::new(VisModifierSpec::Private, VarName::from_str(name))
}
pub fn private_from_token(symbol: Token) -> Self {
Self::new(VisModifierSpec::Private, VarName::new(symbol))
}
pub fn private_from_varname(name: VarName) -> Self {
Self::new(VisModifierSpec::Private, name)
} }
pub fn private_with_line(name: Str, line: u32) -> Self { pub fn private_with_line(name: Str, line: u32) -> Self {
Self::new(None, VarName::from_str_and_line(name, line)) Self::new(
VisModifierSpec::Private,
VarName::from_str_and_line(name, line),
)
} }
pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self { pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self {
Self::new(Some(dot), VarName::from_str_and_line(name, line)) Self::new(
VisModifierSpec::Public(dot),
VarName::from_str_and_line(name, line),
)
}
pub fn public_from_token(dot: Token, symbol: Token) -> Self {
Self::new(VisModifierSpec::Public(dot), VarName::new(symbol))
} }
pub fn is_const(&self) -> bool { pub fn is_const(&self) -> bool {
@ -2737,10 +2859,13 @@ impl Identifier {
self.name.is_raw() self.name.is_raw()
} }
pub const fn vis(&self) -> Visibility { pub fn acc_kind(&self) -> AccessModifier {
match &self.dot { match &self.vis {
Some(_) => Visibility::Public, VisModifierSpec::Auto => AccessModifier::Auto,
None => Visibility::Private, VisModifierSpec::Public(_) => AccessModifier::Public,
VisModifierSpec::ExplicitPrivate(_)
| VisModifierSpec::Restricted(_)
| VisModifierSpec::Private => AccessModifier::Private,
} }
} }
@ -2983,11 +3108,11 @@ impl VarPattern {
} }
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisModifierSpec {
match self { match self {
Self::Ident(ident) => ident.vis(), Self::Ident(ident) => &ident.vis,
// TODO: `[.x, .y]`? // TODO: `[.x, .y]`?
_ => Visibility::Private, _ => &VisModifierSpec::Private,
} }
} }
@ -3036,7 +3161,7 @@ impl VarSignature {
self.pat.is_const() self.pat.is_const()
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisModifierSpec {
self.pat.vis() self.pat.vis()
} }
@ -3493,8 +3618,8 @@ impl SubrSignature {
self.ident.is_const() self.ident.is_const()
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisModifierSpec {
self.ident.vis() &self.ident.vis
} }
} }
@ -3693,7 +3818,7 @@ impl Signature {
matches!(self, Self::Subr(_)) matches!(self, Self::Subr(_))
} }
pub const fn vis(&self) -> Visibility { pub fn vis(&self) -> &VisModifierSpec {
match self { match self {
Self::Var(var) => var.vis(), Self::Var(var) => var.vis(),
Self::Subr(subr) => subr.vis(), Self::Subr(subr) => subr.vis(),
@ -3893,13 +4018,13 @@ impl ReDef {
pub struct Methods { pub struct Methods {
pub class: TypeSpec, pub class: TypeSpec,
pub class_as_expr: Box<Expr>, pub class_as_expr: Box<Expr>,
pub vis: Token, // `.` or `::` pub vis: VisModifierSpec, // `.` or `::`
pub attrs: ClassAttrs, pub attrs: ClassAttrs,
} }
impl NestedDisplay for Methods { impl NestedDisplay for Methods {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
writeln!(f, "{}{}", self.class, self.vis.content)?; writeln!(f, "{}{}", self.class, self.vis)?;
self.attrs.fmt_nest(f, level + 1) self.attrs.fmt_nest(f, level + 1)
} }
} }
@ -3908,7 +4033,12 @@ impl_display_from_nested!(Methods);
impl_locational!(Methods, class, attrs); impl_locational!(Methods, class, attrs);
impl Methods { impl Methods {
pub fn new(class: TypeSpec, class_as_expr: Expr, vis: Token, attrs: ClassAttrs) -> Self { pub fn new(
class: TypeSpec,
class_as_expr: Expr,
vis: VisModifierSpec,
attrs: ClassAttrs,
) -> Self {
Self { Self {
class, class,
class_as_expr: Box::new(class_as_expr), class_as_expr: Box::new(class_as_expr),
@ -3916,14 +4046,6 @@ impl Methods {
attrs, attrs,
} }
} }
pub fn vis(&self) -> Visibility {
if self.vis.is(TokenKind::Dot) {
Visibility::Public
} else {
Visibility::Private
}
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]

View file

@ -16,7 +16,7 @@ use crate::ast::{
ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent,
RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec,
TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName,
VarPattern, VarRecordAttr, VarSignature, VarPattern, VarRecordAttr, VarSignature, VisModifierSpec,
}; };
use crate::token::{Token, TokenKind, COLON, DOT}; use crate::token::{Token, TokenKind, COLON, DOT};
@ -636,7 +636,10 @@ impl Desugarer {
r_brace, r_brace,
) )
} }
BufIndex::Record(attr) => obj.attr(attr.clone()), BufIndex::Record(attr) => {
let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone());
obj.attr(attr)
}
}; };
let id = DefId(get_hash(&(&acc, buf_name))); let id = DefId(get_hash(&(&acc, buf_name)));
let block = Block::new(vec![Expr::Accessor(acc)]); let block = Block::new(vec![Expr::Accessor(acc)]);
@ -1001,7 +1004,10 @@ impl Desugarer {
r_brace, r_brace,
) )
} }
BufIndex::Record(attr) => obj.attr(attr.clone()), BufIndex::Record(attr) => {
let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone());
obj.attr(attr)
}
}; };
let id = DefId(get_hash(&(&acc, buf_name))); let id = DefId(get_hash(&(&acc, buf_name)));
let block = Block::new(vec![Expr::Accessor(acc)]); let block = Block::new(vec![Expr::Accessor(acc)]);
@ -1166,7 +1172,7 @@ impl Desugarer {
} }
*/ */
ParamPattern::VarName(name) => { ParamPattern::VarName(name) => {
let ident = Identifier::new(None, name.clone()); let ident = Identifier::new(VisModifierSpec::Private, name.clone());
let v = VarSignature::new( let v = VarSignature::new(
VarPattern::Ident(ident), VarPattern::Ident(ident),
sig.t_spec.as_ref().map(|ts| ts.t_spec.clone()), sig.t_spec.as_ref().map(|ts| ts.t_spec.clone()),

View file

@ -560,6 +560,37 @@ impl Parser {
Ok(TypeAppArgs::new(l_vbar, args, r_vbar)) Ok(TypeAppArgs::new(l_vbar, args, r_vbar))
} }
fn try_reduce_restriction(&mut self) -> ParseResult<VisRestriction> {
debug_call_info!(self);
expect_pop!(self, LSqBr);
let rest = match self.peek_kind() {
Some(SubtypeOf) => {
self.lpop();
let t_spec_as_expr = self
.try_reduce_expr(false, true, false, false)
.map_err(|_| self.stack_dec(fn_name!()))?;
match Parser::expr_to_type_spec(t_spec_as_expr) {
Ok(t_spec) => VisRestriction::SubtypeOf(Box::new(t_spec)),
Err(err) => {
self.errs.push(err);
debug_exit_info!(self);
return Err(());
}
}
}
_ => {
// FIXME: reduce namespaces
let acc = self
.try_reduce_acc_lhs()
.map_err(|_| self.stack_dec(fn_name!()))?;
VisRestriction::Namespaces(Namespaces::new(vec![acc]))
}
};
expect_pop!(self, RSqBr);
debug_exit_info!(self);
Ok(rest)
}
fn try_reduce_acc_lhs(&mut self) -> ParseResult<Accessor> { fn try_reduce_acc_lhs(&mut self) -> ParseResult<Accessor> {
debug_call_info!(self); debug_call_info!(self);
let acc = match self.peek_kind() { let acc = match self.peek_kind() {
@ -576,6 +607,19 @@ impl Parser {
return Err(()); return Err(());
} }
} }
Some(DblColon) => {
let dbl_colon = self.lpop();
if let Some(LSqBr) = self.peek_kind() {
let rest = self
.try_reduce_restriction()
.map_err(|_| self.stack_dec(fn_name!()))?;
let symbol = expect_pop!(self, Symbol);
Accessor::restricted(rest, symbol)
} else {
let symbol = expect_pop!(self, Symbol);
Accessor::explicit_local(dbl_colon, symbol)
}
}
_ => { _ => {
let err = self.skip_and_throw_syntax_err(caused_by!()); let err = self.skip_and_throw_syntax_err(caused_by!());
self.errs.push(err); self.errs.push(err);
@ -1000,7 +1044,11 @@ impl Parser {
} }
} }
fn try_reduce_method_defs(&mut self, class: Expr, vis: Token) -> ParseResult<Methods> { fn try_reduce_method_defs(
&mut self,
class: Expr,
vis: VisModifierSpec,
) -> ParseResult<Methods> {
debug_call_info!(self); debug_call_info!(self);
expect_pop!(self, fail_next Indent); expect_pop!(self, fail_next Indent);
while self.cur_is(Newline) { while self.cur_is(Newline) {
@ -1205,7 +1253,7 @@ impl Parser {
)); ));
} }
Some(t) if t.is(DblColon) => { Some(t) if t.is(DblColon) => {
let vis = self.lpop(); let vis = VisModifierSpec::ExplicitPrivate(self.lpop());
match self.lpop() { match self.lpop() {
symbol if symbol.is(Symbol) => { symbol if symbol.is(Symbol) => {
let Some(ExprOrOp::Expr(obj)) = stack.pop() else { let Some(ExprOrOp::Expr(obj)) = stack.pop() else {
@ -1219,11 +1267,13 @@ impl Parser {
.transpose() .transpose()
.map_err(|_| self.stack_dec(fn_name!()))? .map_err(|_| self.stack_dec(fn_name!()))?
{ {
let ident = Identifier::new(None, VarName::new(symbol)); let ident =
Identifier::new(VisModifierSpec::Private, VarName::new(symbol));
let call = Call::new(obj, Some(ident), args); let call = Call::new(obj, Some(ident), args);
stack.push(ExprOrOp::Expr(Expr::Call(call))); stack.push(ExprOrOp::Expr(Expr::Call(call)));
} else { } else {
let ident = Identifier::new(None, VarName::new(symbol)); let ident =
Identifier::new(VisModifierSpec::Private, VarName::new(symbol));
stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
} }
} }
@ -1267,7 +1317,7 @@ impl Parser {
} }
} }
Some(t) if t.is(Dot) => { Some(t) if t.is(Dot) => {
let vis = self.lpop(); let dot = self.lpop();
match self.lpop() { match self.lpop() {
symbol if symbol.is(Symbol) => { symbol if symbol.is(Symbol) => {
let Some(ExprOrOp::Expr(obj)) = stack.pop() else { let Some(ExprOrOp::Expr(obj)) = stack.pop() else {
@ -1281,15 +1331,16 @@ impl Parser {
.transpose() .transpose()
.map_err(|_| self.stack_dec(fn_name!()))? .map_err(|_| self.stack_dec(fn_name!()))?
{ {
let ident = Identifier::new(Some(vis), VarName::new(symbol)); let ident = Identifier::public_from_token(dot, symbol);
let call = Expr::Call(Call::new(obj, Some(ident), args)); let call = Expr::Call(Call::new(obj, Some(ident), args));
stack.push(ExprOrOp::Expr(call)); stack.push(ExprOrOp::Expr(call));
} else { } else {
let ident = Identifier::new(Some(vis), VarName::new(symbol)); let ident = Identifier::public_from_token(dot, symbol);
stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
} }
} }
line_break if line_break.is(Newline) => { line_break if line_break.is(Newline) => {
let vis = VisModifierSpec::Public(dot);
let maybe_class = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_))); let maybe_class = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
let defs = self let defs = self
.try_reduce_method_defs(maybe_class, vis) .try_reduce_method_defs(maybe_class, vis)
@ -1488,11 +1539,17 @@ impl Parser {
.transpose() .transpose()
.map_err(|_| self.stack_dec(fn_name!()))? .map_err(|_| self.stack_dec(fn_name!()))?
{ {
let ident = Identifier::new(Some(vis), VarName::new(symbol)); let ident = Identifier::new(
VisModifierSpec::Public(vis),
VarName::new(symbol),
);
let call = Call::new(obj, Some(ident), args); let call = Call::new(obj, Some(ident), args);
stack.push(ExprOrOp::Expr(Expr::Call(call))); stack.push(ExprOrOp::Expr(Expr::Call(call)));
} else { } else {
let ident = Identifier::new(Some(vis), VarName::new(symbol)); let ident = Identifier::new(
VisModifierSpec::Public(vis),
VarName::new(symbol),
);
stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
} }
} }
@ -1696,7 +1753,7 @@ impl Parser {
} }
} }
} }
Some(t) if t.is(Symbol) || t.is(Dot) || t.is(UBar) => { Some(t) if t.is(Symbol) || t.is(Dot) || t.is(DblColon) || t.is(UBar) => {
let call_or_acc = self let call_or_acc = self
.try_reduce_call_or_acc(in_type_args) .try_reduce_call_or_acc(in_type_args)
.map_err(|_| self.stack_dec(fn_name!()))?; .map_err(|_| self.stack_dec(fn_name!()))?;
@ -1861,7 +1918,8 @@ impl Parser {
let token = self.lpop(); let token = self.lpop();
match token.kind { match token.kind {
Symbol => { Symbol => {
let ident = Identifier::new(Some(vis), VarName::new(token)); let ident =
Identifier::new(VisModifierSpec::Public(vis), VarName::new(token));
obj = obj.attr_expr(ident); obj = obj.attr_expr(ident);
} }
NatLit => { NatLit => {
@ -1895,7 +1953,10 @@ impl Parser {
let token = self.lpop(); let token = self.lpop();
match token.kind { match token.kind {
Symbol => { Symbol => {
let ident = Identifier::new(None, VarName::new(token)); let ident = Identifier::new(
VisModifierSpec::ExplicitPrivate(vis),
VarName::new(token),
);
obj = obj.attr_expr(ident); obj = obj.attr_expr(ident);
} }
LBrace => { LBrace => {
@ -1905,6 +1966,7 @@ impl Parser {
.map_err(|_| self.stack_dec(fn_name!()))?; .map_err(|_| self.stack_dec(fn_name!()))?;
match args { match args {
BraceContainer::Record(args) => { BraceContainer::Record(args) => {
let vis = VisModifierSpec::ExplicitPrivate(vis);
obj = Expr::DataPack(DataPack::new(obj, vis, args)); obj = Expr::DataPack(DataPack::new(obj, vis, args));
} }
other => { other => {
@ -2023,15 +2085,15 @@ impl Parser {
} }
// Empty brace literals // Empty brace literals
if let Some(first) = self.peek() { match self.peek_kind() {
if first.is(RBrace) { Some(RBrace) => {
let r_brace = self.lpop(); let r_brace = self.lpop();
let arg = Args::empty(); let arg = Args::empty();
let set = NormalSet::new(l_brace, r_brace, arg); let set = NormalSet::new(l_brace, r_brace, arg);
debug_exit_info!(self); debug_exit_info!(self);
return Ok(BraceContainer::Set(Set::Normal(set))); return Ok(BraceContainer::Set(Set::Normal(set)));
} }
if first.is(Equal) { Some(Equal) => {
let _eq = self.lpop(); let _eq = self.lpop();
if let Some(t) = self.peek() { if let Some(t) = self.peek() {
if t.is(RBrace) { if t.is(RBrace) {
@ -2045,7 +2107,7 @@ impl Parser {
debug_exit_info!(self); debug_exit_info!(self);
return Err(()); return Err(());
} }
if first.is(Colon) { Some(Colon) => {
let _colon = self.lpop(); let _colon = self.lpop();
if let Some(t) = self.peek() { if let Some(t) = self.peek() {
if t.is(RBrace) { if t.is(RBrace) {
@ -2060,6 +2122,7 @@ impl Parser {
debug_exit_info!(self); debug_exit_info!(self);
return Err(()); return Err(());
} }
_ => {}
} }
let first = self let first = self
@ -2541,7 +2604,8 @@ impl Parser {
.transpose() .transpose()
.map_err(|_| self.stack_dec(fn_name!()))? .map_err(|_| self.stack_dec(fn_name!()))?
{ {
let ident = Identifier::new(Some(vis), VarName::new(symbol)); let ident =
Identifier::new(VisModifierSpec::Public(vis), VarName::new(symbol));
let mut call = Expr::Call(Call::new(obj, Some(ident), args)); let mut call = Expr::Call(Call::new(obj, Some(ident), args));
while let Some(res) = self.opt_reduce_args(false) { while let Some(res) = self.opt_reduce_args(false) {
let args = res.map_err(|_| self.stack_dec(fn_name!()))?; let args = res.map_err(|_| self.stack_dec(fn_name!()))?;

View file

@ -229,11 +229,12 @@ impl Parser {
(ParamPattern::VarName(name), Some(t_spec_with_op)) => { (ParamPattern::VarName(name), Some(t_spec_with_op)) => {
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
} }
(ParamPattern::VarName(name), None) => { (ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy(
ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple( PreDeclTypeSpec::Simple(SimpleTypeSpec::new(
SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()), Identifier::new(VisModifierSpec::Private, name),
))) ConstArgs::empty(),
} )),
)),
_ => todo!(), _ => todo!(),
}; };
non_defaults.push(param); non_defaults.push(param);
@ -247,11 +248,12 @@ impl Parser {
(ParamPattern::VarName(name), Some(t_spec_with_op)) => { (ParamPattern::VarName(name), Some(t_spec_with_op)) => {
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
} }
(ParamPattern::VarName(name), None) => { (ParamPattern::VarName(name), None) => ParamTySpec::anonymous(
ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple( TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new(
SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()), Identifier::new(VisModifierSpec::Private, name),
))) ConstArgs::empty(),
} ))),
),
_ => todo!(), _ => todo!(),
}); });
let mut defaults = vec![]; let mut defaults = vec![];

View file

@ -4,7 +4,7 @@ print! empty
# Inheritance is prohibited by default. Remove this decorator and check for errors. # Inheritance is prohibited by default. Remove this decorator and check for errors.
@Inheritable @Inheritable
Point2D = Class {x = Int; y = Int} Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int}
Point2D:: Point2D::
one = 1 one = 1
Point2D. Point2D.

View file

@ -1,5 +1,5 @@
UnpackPoint2D = Class {x = Int; y = Int}, Impl := Unpack UnpackPoint2D = Class {.x = Int; .y = Int}, Impl := Unpack
q = UnpackPoint2D::{x = 1; y = 2} q = UnpackPoint2D::{.x = 1; .y = 2}
UnpackPoint2D::{x; y} = q UnpackPoint2D::{x; y} = q
print! x, y print! x, y

View file

@ -0,0 +1,25 @@
@Inheritable
Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int}
Point2D.
norm self = self::x**2 + self::y**2 #OK
Point3D = Inherit Point2D, Additional := {z = Int}
Point3D.
@Override
norm self = self::x**2 + self::y**2 + self::z**2 #OK
C = Class()
C.
method point: Point2D = point::x # ERR
p = Point3D.new {x = 1; y = 2; z = 3}
p::x # ERR
p.x # ERR
p::z # ERR
rec = {
::[f] x = 1
}
f x = rec::x + x # OK
g x = rec::x + x # ERR

View file

@ -1,6 +1,6 @@
f {x; y}, [_], (_, _) = x + y f {.x; .y}, [_], (_, _) = x + y
x = f {x = 1; y = 2}, [3], (4, 5) x = f {.x = 1; .y = 2}, [3], (4, 5)
assert x == 3 assert x == 3
#[ #[

View file

@ -306,6 +306,11 @@ fn exec_var_args_err() -> Result<(), ()> {
expect_failure("tests/should_err/var_args.er", 3) expect_failure("tests/should_err/var_args.er", 3)
} }
#[test]
fn exec_visibility() -> Result<(), ()> {
expect_failure("tests/should_err/visibility.er", 5)
}
#[test] #[test]
fn exec_move() -> Result<(), ()> { fn exec_move() -> Result<(), ()> {
expect_failure("tests/should_err/move.er", 1) expect_failure("tests/should_err/move.er", 1)