mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 13:41:10 +00:00
feat: add restricted visibility syntax
This commit is contained in:
parent
309bb06db8
commit
d92f5284c8
44 changed files with 3803 additions and 2358 deletions
|
@ -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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
82
crates/erg_common/triple.rs
Normal file
82
crates/erg_common/triple.rs
Normal 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})"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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(¶m_name), line));
|
Expr::Accessor(Accessor::private_with_line(Str::from(¶m_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);
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
1212
crates/erg_compiler/context/instantiate_spec.rs
Normal file
1212
crates/erg_compiler/context/instantiate_spec.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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[..]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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,
|
||||||
|
|
233
crates/erg_compiler/ty/vis.rs
Normal file
233
crates/erg_compiler/ty/vis.rs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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!()))?;
|
||||||
|
|
|
@ -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![];
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
25
tests/should_err/visibility.er
Normal file
25
tests/should_err/visibility.er
Normal 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
|
|
@ -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
|
||||||
|
|
||||||
#[
|
#[
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue