diff --git a/crates/erg_compiler/context/initialize/classes.rs b/crates/erg_compiler/context/initialize/classes.rs index 410371aa9..a8f031ef6 100644 --- a/crates/erg_compiler/context/initialize/classes.rs +++ b/crates/erg_compiler/context/initialize/classes.rs @@ -87,6 +87,13 @@ impl Context { Some(FUNDAMENTAL_FORMAT), 14, ); + obj.register_builtin_py_impl( + FUNDAMENTAL_CALL, + func0(Obj), + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNDAMENTAL_CALL), + ); // Obj does not implement Eq let mut complex = Self::builtin_mono_class(COMPLEX, 2); complex.register_superclass(Obj, &obj); diff --git a/crates/erg_compiler/context/initialize/funcs.rs b/crates/erg_compiler/context/initialize/funcs.rs index 0735d0cb2..a4e705de8 100644 --- a/crates/erg_compiler/context/initialize/funcs.rs +++ b/crates/erg_compiler/context/initialize/funcs.rs @@ -351,8 +351,8 @@ impl Context { ) .quantify(); let t_slice = no_var_func( - vec![kw(KW_START, Int)], - vec![kw(KW_STOP, Int), kw(KW_STEP, Int)], + vec![kw(KW_START, Int | NoneType)], + vec![kw(KW_STOP, Int | NoneType), kw(KW_STEP, Int | NoneType)], mono(SLICE), ); let t_sorted = nd_func( @@ -975,6 +975,40 @@ impl Context { Visibility::BUILTIN_PUBLIC, None, ); + let t_exec = func( + vec![kw(KW_CODE, Str)], + None, + vec![ + kw(KW_GLOBALS, mono(GENERIC_DICT)), + kw(KW_LOCALS, mono(GENERIC_DICT)), + ], + None, + NoneType, + ); + self.register_builtin_py_impl( + FUNC_EXEC, + t_exec, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_EXEC), + ); + let t_eval = func( + vec![kw(KW_CODE, Str)], + None, + vec![ + kw(KW_GLOBALS, mono(GENERIC_DICT)), + kw(KW_LOCALS, mono(GENERIC_DICT)), + ], + None, + NoneType, + ); + self.register_builtin_py_impl( + FUNC_EVAL, + t_eval, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_EVAL), + ); } pub(super) fn init_builtin_operators(&mut self) { diff --git a/crates/erg_compiler/context/initialize/mod.rs b/crates/erg_compiler/context/initialize/mod.rs index 1b8a4c41f..e19912ebd 100644 --- a/crates/erg_compiler/context/initialize/mod.rs +++ b/crates/erg_compiler/context/initialize/mod.rs @@ -547,6 +547,8 @@ const FUNC_HASATTR: &str = "hasattr"; const FUNC_GETATTR: &str = "getattr"; const FUNC_SETATTR: &str = "setattr"; const FUNC_DELATTR: &str = "delattr"; +const FUNC_EXEC: &str = "exec"; +const FUNC_EVAL: &str = "eval"; const FUNC_NEARLY_EQ: &str = "nearly_eq"; const FUNC_RESOLVE_PATH: &str = "ResolvePath"; const FUNC_RESOLVE_DECL_PATH: &str = "ResolveDeclPath"; @@ -732,6 +734,8 @@ const KW_NUMBER: &str = "number"; const KW_ITERABLE1: &str = "iterable1"; const KW_ITERABLE2: &str = "iterable2"; const KW_CODE: &str = "code"; +const KW_GLOBALS: &str = "globals"; +const KW_LOCALS: &str = "locals"; const KW_STOP: &str = "stop"; const KW_STEP: &str = "step"; const KW_REQUIREMENT: &str = "Requirement"; diff --git a/crates/erg_compiler/context/inquire.rs b/crates/erg_compiler/context/inquire.rs index 4233ab335..24dc76eb0 100644 --- a/crates/erg_compiler/context/inquire.rs +++ b/crates/erg_compiler/context/inquire.rs @@ -273,6 +273,11 @@ impl Context { }) } + /// ```erg + /// get_singular_ctxs_by_hir_expr(1) == Err + /// get_singular_ctxs_by_hir_expr(Int) == [, , ...] + /// get_singular_ctxs_by_hir_expr(math) == [] + /// ``` pub fn get_singular_ctxs_by_hir_expr( &self, obj: &hir::Expr, @@ -1342,6 +1347,20 @@ impl Context { } _ => {} } + if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) { + for ctx in singular_ctxs { + if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + for method_ctx in ctx.methods_list.iter() { + if let Some(vi) = method_ctx.get_current_scope_non_param(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + } + } + } for ctx in self .get_nominal_super_type_ctxs(obj.ref_t()) .ok_or_else(|| { @@ -1376,30 +1395,6 @@ impl Context { } } } - if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) { - for ctx in singular_ctxs { - if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - for method_ctx in ctx.methods_list.iter() { - if let Some(vi) = method_ctx.get_current_scope_non_param(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - } - } - return Err(TyCheckError::singular_no_attr_error( - self.cfg.input.clone(), - line!() as usize, - attr_name.loc(), - namespace.name.to_string(), - obj.qual_name().as_deref().unwrap_or("?"), - obj.ref_t(), - attr_name.inspect(), - self.get_similar_attr_from_singular(obj, attr_name.inspect()), - )); - } match self.get_attr_type_by_name(obj, attr_name, namespace) { Triple::Ok(method) => { let def_t = self @@ -1436,17 +1431,18 @@ impl Context { ); return Ok(vi); } - } - for patch in self.find_patches_of(obj.ref_t()) { - if let Some(vi) = patch.get_current_scope_non_param(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - for methods_ctx in patch.methods_list.iter() { - if let Some(vi) = methods_ctx.get_current_scope_non_param(&attr_name.name) { + } else { + for patch in self.find_patches_of(obj.ref_t()) { + if let Some(vi) = patch.get_current_scope_non_param(&attr_name.name) { self.validate_visibility(attr_name, vi, input, namespace)?; return Ok(vi.clone()); } + for methods_ctx in patch.methods_list.iter() { + if let Some(vi) = methods_ctx.get_current_scope_non_param(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + } } } let coerced = self @@ -1487,6 +1483,20 @@ impl Context { } _ => {} } + if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) { + for ctx in singular_ctxs { + if let Some(vi) = ctx.get_current_scope_callable(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + for method_ctx in ctx.methods_list.iter() { + if let Some(vi) = method_ctx.get_current_scope_callable(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + } + } + } for ctx in self .get_nominal_super_type_ctxs(obj.ref_t()) .ok_or_else(|| { @@ -1521,30 +1531,6 @@ impl Context { } } } - if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) { - for ctx in singular_ctxs { - if let Some(vi) = ctx.get_current_scope_callable(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - for method_ctx in ctx.methods_list.iter() { - if let Some(vi) = method_ctx.get_current_scope_callable(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - } - } - return Err(TyCheckError::singular_no_attr_error( - self.cfg.input.clone(), - line!() as usize, - attr_name.loc(), - namespace.name.to_string(), - obj.qual_name().as_deref().unwrap_or("?"), - obj.ref_t(), - attr_name.inspect(), - self.get_similar_attr_from_singular(obj, attr_name.inspect()), - )); - } match self.get_attr_type_by_name(obj, attr_name, namespace) { Triple::Ok(method) => { let def_t = self @@ -1581,17 +1567,18 @@ impl Context { ); return Ok(vi); } - } - for patch in self.find_patches_of(obj.ref_t()) { - if let Some(vi) = patch.get_current_scope_callable(&attr_name.name) { - self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.clone()); - } - for methods_ctx in patch.methods_list.iter() { - if let Some(vi) = methods_ctx.get_current_scope_callable(&attr_name.name) { + } else { + for patch in self.find_patches_of(obj.ref_t()) { + if let Some(vi) = patch.get_current_scope_callable(&attr_name.name) { self.validate_visibility(attr_name, vi, input, namespace)?; return Ok(vi.clone()); } + for methods_ctx in patch.methods_list.iter() { + if let Some(vi) = methods_ctx.get_current_scope_callable(&attr_name.name) { + self.validate_visibility(attr_name, vi, input, namespace)?; + return Ok(vi.clone()); + } + } } } let coerced = self @@ -2824,7 +2811,7 @@ impl Context { ) } - pub(crate) fn get_similar_attr_from_singular<'a>( + pub(crate) fn _get_similar_attr_from_singular<'a>( &'a self, obj: &hir::Expr, name: &str, @@ -3023,6 +3010,10 @@ impl Context { opt_max } + /// ```erg + /// get_nominal_super_type_ctx(Nat) == [, , , ..., , , ...] + /// get_nominal_super_type_ctx({Nat}) == [, , , ...] + /// ``` pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option> { match t { Type::FreeVar(fv) if fv.is_linked() => self.get_nominal_super_type_ctxs(&fv.crack()), diff --git a/crates/erg_compiler/lib/pystd/typing.d.er b/crates/erg_compiler/lib/pystd/typing.d.er index 8662254d2..024fd8a83 100644 --- a/crates/erg_compiler/lib/pystd/typing.d.er +++ b/crates/erg_compiler/lib/pystd/typing.d.er @@ -8,21 +8,21 @@ .TypeAlias: ClassType .Tuple: ClassType .Tuple. - __getitem__: (*Type) -> Type + __getitem__: (HomogenousTuple Type) -> Type .Union: ClassType .Union. - __getitem__: (*Type) -> Type + __getitem__: (HomogenousTuple Type) -> Type .Optional: ClassType .Optional. - __getitem__: (Type) -> Type + __getitem__: (HomogenousTuple Type) -> Type .Callable: ClassType .Callable. - __getitem__: (params: [Type; _], Type) -> Type + __getitem__: (HomogenousTuple Type) -> Type .Concatenate: (*Type) -> Type .Type: (Type) -> Type .Literal: ClassType .Literal. - __getitem__: (*Obj) -> Type + __getitem__: (HomogenousTuple Obj) -> Type .ClassVar: (Type) -> Type .Final: (Type) -> Type .Required: (Type) -> Type @@ -64,24 +64,42 @@ .AnyStr: ClassType .Protocol: (Type := NoneType) -> Type .NamedTuple: ClassType +.NamedTuple. + __call__: (typename: Str, it := global::Iterable(Obj)) -> Type .NewType: ClassType .NewType. __module__: Str __name__: Str __supertype__: Type __call__: (name: Str, tp: Type) -> NewType -.TypedDict: (Str, Type) -> Type +.TypedDict: (typename: Str, it := global::Iterable(Obj)) -> Type .Dict: (Type, Type) -> Type .List: (Type) -> Type .Set: (Type) -> Type -.FrozenSet: (Type) -> Type -.OrderedDict: (Type, Type) -> Type +.FrozenSet: (Type) -> ClassType +.FrozenSet. + __getitem__: Type -> Type +.OrderedDict: (Type, Type) -> ClassType +.OrderedDict. + __getitem__: (kv: (Type, Type)) -> Type .ChainMap: (Type, Type) -> Type .Counter: (Type, Int) -> Type -.Deque: (Type) -> Type -.IO: ClassType +.Deque: (T: Type) -> ClassType +.Deque. + __call__: |T|(iter: global::Iterable(T)) -> Deque T + __getitem__: (Type) -> Type +.IO: Type -> ClassType +.IO. + __call__: () -> IO Obj + __getitem__: (Type) -> Type .TextIO: ClassType +.TextIO <: IO Str +.TextIO. + __call__: () -> TextIO .BinaryIO: ClassType +.BinaryIO <: IO Bytes +.BinaryIO. + __call__: () -> BinaryIO .Pattern: ClassType .Match: ClassType .Text: ClassType @@ -127,20 +145,40 @@ .KeysView: ClassType .Mapping: ClassType .Mapping. - __getitem__: (Type, Type) -> Type + __getitem__: (kv: (Type, Type)) -> Type .MappingView: ClassType +.MappingView. + __getitem__: (Type) -> Type .MutableMapping: ClassType +.MutableMapping. + __getitem__: (kv: (Type, Type)) -> Type .MutableSequence: ClassType +.MutableSequence. + __getitem__: Type -> Type .MutableSet: ClassType +.MutableSet. + __getitem__: Type -> Type .Sized: ClassType .ValuesView: ClassType .Awaitable: ClassType .AsyncIterator: ClassType +.AsyncIterator. + __getitem__: Type -> Type .AsyncIterable: ClassType +.AsyncIterable. + __getitem__: Type -> Type .Coroutine: ClassType +.Coroutine. + __getitem__: (t: (Type, Type, Type)) -> Type .Collection: ClassType +.Collection. + __getitem__: Type -> Type .AsyncGenerator: ClassType +.AsyncGenerator. + __getitem__: (t: (Type, Type)) -> Type .AsyncContextManager: ClassType +.AsyncContextManager. + __getitem__: Type -> Type .SupportsAbs: ClassType .SupportsBytes: ClassType .SupportsComplex: ClassType @@ -149,5 +187,9 @@ .SupportsInt: ClassType .SupportsRound: ClassType -.Genertor: ClassType +.Generator: ClassType +.Generator. + __getitem__: (t: (Type, Type, Type)) -> Type .Reversible: ClassType +.Reversible. + __getitem__: Type -> Type diff --git a/crates/erg_compiler/lib/pystd/urllib.d/parse.d.er b/crates/erg_compiler/lib/pystd/urllib.d/parse.d.er index e69de29bb..ba0edc7ad 100644 --- a/crates/erg_compiler/lib/pystd/urllib.d/parse.d.er +++ b/crates/erg_compiler/lib/pystd/urllib.d/parse.d.er @@ -0,0 +1,21 @@ +.urlparse: (urlstring: Str, scheme := Str, allow_fragments := Bool) -> NamedTuple { + .scheme = Str; + .netloc = Str; + .path = Str; + .params = Str; + .query = Str; + .fragment = Str; + .username = Str or NoneType; + .password = Str or NoneType; + .hostname = Str or NoneType; + .port = Int or NoneType; +} +.parse_qs: ( + qs: Str, + keep_blank_values := Bool, + strict_parsing := Bool, + encoding := Str, + errors := Str, + max_num_fields := Nat or NoneType, + separator := Str, +) -> {Str: [Str; _]}