From 46b87e1ca3a54cf174daff8dc8ef8aea477b944b Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Tue, 18 Oct 2022 00:25:47 +0900 Subject: [PATCH] Fix: variable to have `VarInfo` instead of `Type` --- compiler/erg_common/env.rs | 4 + compiler/erg_common/python_util.rs | 6 +- compiler/erg_compiler/codegen.rs | 360 ++----------- .../erg_compiler/context/initialize/mod.rs | 472 +++++++++++++----- .../context/initialize/py_mods/glob.rs | 3 +- .../context/initialize/py_mods/importlib.rs | 3 +- .../context/initialize/py_mods/io.rs | 11 +- .../context/initialize/py_mods/os.rs | 37 +- .../context/initialize/py_mods/random.rs | 8 +- .../context/initialize/py_mods/socket.rs | 8 +- .../context/initialize/py_mods/time.rs | 10 +- .../context/initialize/py_mods/urllib.rs | 10 +- compiler/erg_compiler/context/inquire.rs | 152 +++--- compiler/erg_compiler/context/instantiate.rs | 4 +- compiler/erg_compiler/context/mod.rs | 20 +- compiler/erg_compiler/context/register.rs | 106 ++-- compiler/erg_compiler/context/tyvar.rs | 22 +- compiler/erg_compiler/desugar_hir.rs | 10 +- compiler/erg_compiler/effectcheck.rs | 4 +- compiler/erg_compiler/hir.rs | 247 +++++---- .../erg_compiler/lib/pystd/subprocess.d.er | 1 + .../erg_compiler/lib/std/_erg_std_prelude.py | 3 + compiler/erg_compiler/lib/std/subprocess.d.er | 1 - compiler/erg_compiler/link.rs | 22 +- compiler/erg_compiler/lower.rs | 108 ++-- compiler/erg_compiler/ownercheck.rs | 7 +- compiler/erg_compiler/ty/mod.rs | 12 +- compiler/erg_compiler/varinfo.rs | 30 +- compiler/erg_parser/parse.rs | 23 +- 29 files changed, 888 insertions(+), 816 deletions(-) create mode 100644 compiler/erg_compiler/lib/pystd/subprocess.d.er delete mode 100644 compiler/erg_compiler/lib/std/subprocess.d.er diff --git a/compiler/erg_common/env.rs b/compiler/erg_common/env.rs index 308f94f9..59028079 100644 --- a/compiler/erg_common/env.rs +++ b/compiler/erg_common/env.rs @@ -9,6 +9,10 @@ pub fn erg_std_path() -> PathBuf { erg_path().join("lib").join("std") } +pub fn erg_pystd_path() -> PathBuf { + erg_path().join("lib").join("pystd") +} + pub fn erg_external_lib_path() -> PathBuf { erg_path().join("lib").join("external") } diff --git a/compiler/erg_common/python_util.rs b/compiler/erg_common/python_util.rs index 5a21f98d..47850b4e 100644 --- a/compiler/erg_common/python_util.rs +++ b/compiler/erg_common/python_util.rs @@ -5,14 +5,16 @@ use std::process::Command; use crate::serialize::get_magic_num_from_bytes; -pub const BUILTIN_PYTHON_MODS: [&str; 10] = [ +pub const BUILTIN_PYTHON_MODS: [&str; 12] = [ "glob", "importlib", "io", "math", - "re", + "os", "random", + "re", "socket", + "subprocess", "sys", "time", "urllib", diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 186a6138..781554fe 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -38,283 +38,29 @@ use crate::ty::value::ValueObj; use crate::ty::{HasType, Type, TypeCode, TypePair}; use AccessKind::*; -fn is_python_special(name: &str) -> bool { - matches!(name, "__call__" | "__init__") -} - -fn is_python_global(name: &str) -> bool { - matches!( - name, - "ArithmeticError" - | "AssertionError" - | "AttributeError" - | "BaseException" - | "BlockingIOError" - | "BrokenPipeError" - | "BufferError" - | "BytesWarning" - | "ChildProcessError" - | "ConnectionAbortedError" - | "ConnectionError" - | "ConnectionRefusedError" - | "ConnectionResetError" - | "DeprecationWarning" - | "EOFError" - | "Ellipsis" - | "EncodingWarning" - | "EnvironmentError" - | "Exception" - | "False" - | "FileExistsError" - | "FileNotFoundError" - | "FloatingPointError" - | "FutureWarning" - | "GeneratorExit" - | "IOError" - | "ImportError" - | "ImportWarning" - | "IndentationError" - | "IndexError" - | "InterruptedError" - | "IsADirectoryError" - | "KeyError" - | "KeyboardInterrupt" - | "LookupError" - | "MemoryError" - | "ModuleNotFoundError" - | "NameError" - | "None" - | "NotADirectoryError" - | "NotImplemented" - | "NotImplementedError" - | "OSError" - | "OverflowError" - | "PendingDeprecationWarning" - | "PermissionError" - | "ProcessLookupError" - | "RecursionError" - | "ReferenceError" - | "ResourceWarning" - | "RuntimeError" - | "RuntimeWarning" - | "StopAsyncIteration" - | "StopIteration" - | "SyntaxError" - | "SyntaxWarning" - | "SystemError" - | "SystemExit" - | "TabError" - | "TimeoutError" - | "True" - | "TypeError" - | "UnboundLocalError" - | "UnicodeDecodeError" - | "UnicodeEncodeError" - | "UnicodeError" - | "UnicodeTranslateError" - | "UnicodeWarning" - | "UserWarning" - | "ValueError" - | "Warning" - | "WindowsError" - | "ZeroDivisionError" - | "__build__class__" - | "__debug__" - | "__doc__" - | "__import__" - | "__loader__" - | "__name__" - | "__package__" - | "__spec__" - | "__annotations__" - | "__builtins__" - | "abs" - | "aiter" - | "all" - | "any" - | "anext" - | "ascii" - | "bin" - | "bool" - | "breakpoint" - | "bytearray" - | "bytes" - | "callable" - | "chr" - | "classmethod" - | "compile" - | "complex" - | "delattr" - | "dict" - | "dir" - | "divmod" - | "enumerate" - | "eval" - | "exec" - | "exit" - | "filter" - | "float" - | "format" - | "frozenset" - | "getattr" - | "globals" - | "hasattr" - | "hash" - | "help" - | "hex" - | "id" - | "input" - | "int" - | "isinstance" - | "issubclass" - | "iter" - | "len" - | "list" - | "locals" - | "map" - | "max" - | "memoryview" - | "min" - | "next" - | "object" - | "oct" - | "open" - | "ord" - | "pow" - | "print" - | "property" - | "quit" - | "range" - | "repr" - | "reversed" - | "round" - | "set" - | "setattr" - | "slice" - | "sorted" - | "staticmethod" - | "str" - | "sum" - | "super" - | "tuple" - | "type" - | "vars" - | "zip" - | "license" - | "copyright" - | "credits" - ) -} - -fn is_erg_global(name: &str) -> bool { - matches!(name, "Nat",) -} - -fn is_fake_method(class: &str, name: &str) -> bool { - matches!( - (class, name), - ( - _, // "Complex" | "Float" | "Ratio" | "Int" | "Nat" | "Bool", - "abs" - ) | (_, "iter") - | (_, "map") - ) -} - -fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str { - match (class, uniq_obj_name, &name[..]) { - ("Array!", _, "push!") => Str::ever("append"), - ("Array!" | "Array", _, "concat") => Str::ever("__add__"), - ("Set!", _, "add!") => Str::ever("add"), - ("Complex" | "Float" | "Ratio" | "Int" | "Nat" | "Bool", _, "Real") => Str::ever("real"), - ("Complex" | "Float" | "Ratio" | "Int" | "Nat" | "Bool", _, "Imag") => Str::ever("imag"), - (_, _, "read!") => Str::ever("read"), - (_, _, "write!") => Str::ever("write"), - (_, _, "__new__") => Str::ever("__call__"), - (_, _, "to_str") => Str::ever("__str__"), - (_, _, "__Tuple_getitem__") => Str::ever("__getitem__"), - ("StringIO!", _, "getvalue!") => Str::ever("getvalue"), - ("Module", Some("importlib"), "reload!") => Str::ever("reload"), - ("Module", Some("random"), "randint!") => Str::ever("randint"), - ("Module", Some("random"), "choice!") => Str::ever("choice"), - ("Module", Some("sys"), "setrecurtionlimit!") => Str::ever("setrecurtionlimit"), - ("Module", Some("time"), "sleep!") => Str::ever("sleep"), - ("Module", Some("time"), "time!") => Str::ever("time"), - ("Module", Some("glob"), "glob!") => Str::ever("glob"), - ("Module", Some("os"), name) if name != "name" && name != "path" => { - Str::from(name.replace('!', "")) - } - ("Nat", _, "times!") => Str::ever("times"), - _ => name, - } -} - -fn escape_attr(class: &str, uniq_obj_name: Option<&str>, ident: Identifier) -> Str { - let vis = ident.vis(); - let mut name = - convert_to_python_attr(class, uniq_obj_name, ident.name.into_token().content).to_string(); - name = name.replace('!', "__erg_proc__"); - name = name.replace('$', "__erg_shared__"); - if vis.is_public() - || is_python_global(&name) - || is_erg_global(&name) - || is_python_special(&name) - { - Str::from(name) - } else { - Str::from("::".to_string() + &name) - } -} - -fn convert_to_python_name(name: Str) -> Str { - match &name[..] { - "abs" => Str::ever("abs"), - // assert is implemented in bytecode - "classof" => Str::ever("type"), - "compile" => Str::ever("compile"), - "dir!" => Str::ever("dir"), - "globals!" => Str::ever("globals"), - // discard is implemented in bytecode - // for is implemented in bytecode - "id!" => Str::ever("id"), - // if is implemented in bytecode - "import" => Str::ever("__import__"), - "input!" => Str::ever("input"), - "log" => Str::ever("print"), // TODO: log != print (prints after executing) - "locals!" => Str::ever("locals"), - "open!" => Str::ever("open"), - "panic" => Str::ever("exit"), - "print!" => Str::ever("print"), - "py" | "pyimport" => Str::ever("__import__"), - "quit" | "exit" => Str::ever("quit"), - "Nat" | "Nat!" => Str::ever("Nat"), - "Int" | "Int!" => Str::ever("int"), - "Float" | "Float!" => Str::ever("float"), - "Ratio" | "Ratio!" => Str::ever("float"), - "Complex" => Str::ever("complex"), - "Str" | "Str!" => Str::ever("str"), - "Bool" | "Bool!" => Str::ever("bool"), - "Array" | "Array!" => Str::ever("list"), - "Set" | "Set!" => Str::ever("set"), - "Dict" | "Dict!" => Str::ever("dict"), - _ => name, +fn fake_method_to_func(class: &str, name: &str) -> Option<&'static str> { + match (class, name) { + (_, "abs") => Some("abs"), + (_, "iter") => Some("iter"), + (_, "map") => Some("map"), + _ => None, } } /// This method obviously does not scale, so in the future all Python APIs will be replaced by declarations in d.er, and renaming will be done in `HIRDesugarer`. fn escape_name(ident: Identifier) -> Str { let vis = ident.vis(); - let mut name = convert_to_python_name(ident.name.into_token().content).to_string(); - name = name.replace('!', "__erg_proc__"); - name = name.replace('$', "__erg_shared__"); - if vis.is_public() - || is_python_global(&name) - || is_erg_global(&name) - || is_python_special(&name) - { - Str::from(name) + if let Some(py_name) = ident.vi.py_name { + py_name } else { - Str::from("::".to_string() + &name) + let name = ident.name.into_token().content.to_string(); + let name = name.replace('!', "__erg_proc__"); + let name = name.replace('$', "__erg_shared__"); + if vis.is_private() { + Str::from("::".to_string() + &name) + } else { + Str::from(name) + } } } @@ -699,14 +445,9 @@ impl CodeGenerator { self.emit_pop_top(); // discard IMPORT_FROM object } - fn emit_load_attr_instr( - &mut self, - class: &str, - uniq_obj_name: Option<&str>, - ident: Identifier, - ) { - log!(info "entered {} ({class}{ident})", fn_name!()); - let escaped = escape_attr(class, uniq_obj_name, ident); + fn emit_load_attr_instr(&mut self, ident: Identifier) { + log!(info "entered {} ({ident})", fn_name!()); + let escaped = escape_name(ident); let name = self .local_search(&escaped, Attr) .unwrap_or_else(|| self.register_attr(escaped)); @@ -720,14 +461,12 @@ impl CodeGenerator { self.write_arg(name.idx as u8); } - fn emit_load_method_instr( - &mut self, - class: &str, - uniq_obj_name: Option<&str>, - ident: Identifier, - ) { - log!(info "entered {} ({class}{ident})", fn_name!()); - let escaped = escape_attr(class, uniq_obj_name, ident); + fn emit_load_method_instr(&mut self, ident: Identifier) { + log!(info "entered {} ({ident})", fn_name!()); + if &ident.inspect()[..] == "__new__" { + log!("{:?}", ident.vi); + } + let escaped = escape_name(ident); let name = self .local_search(&escaped, Method) .unwrap_or_else(|| self.register_method(escaped)); @@ -801,7 +540,6 @@ impl CodeGenerator { self.emit_expr(*attr.obj); self.emit_store_instr(attr.ident, Attr); } - acc => todo!("store: {acc}"), } } @@ -859,24 +597,8 @@ impl CodeGenerator { self.emit_load_name_instr(ident); } Accessor::Attr(a) => { - let class = a.obj.ref_t().qual_name(); - let uniq_obj_name = a.obj.local_name().map(Str::rc); self.emit_expr(*a.obj); - self.emit_load_attr_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), a.ident); - } - Accessor::TupleAttr(t_attr) => { - self.emit_expr(*t_attr.obj); - self.emit_load_const(t_attr.index.value); - self.write_instr(BINARY_SUBSCR); - self.write_arg(0); - self.stack_dec(); - } - Accessor::Subscr(subscr) => { - self.emit_expr(*subscr.obj); - self.emit_expr(*subscr.index); - self.write_instr(BINARY_SUBSCR); - self.write_arg(0); - self.stack_dec(); + self.emit_load_attr_instr(a.ident); } } } @@ -1541,14 +1263,13 @@ impl CodeGenerator { fn emit_call_method(&mut self, obj: Expr, method_name: Identifier, args: Args) { log!(info "entered {}", fn_name!()); let class = obj.ref_t().qual_name(); // これは必ずmethodのあるクラスになっている - let uniq_obj_name = obj.qual_name().map(Str::rc); if &method_name.inspect()[..] == "update!" { return self.emit_call_update(obj, args); - } else if is_fake_method(&class, method_name.inspect()) { - return self.emit_call_fake_method(obj, method_name, args); + } else if let Some(func_name) = fake_method_to_func(&class, method_name.inspect()) { + return self.emit_call_fake_method(obj, func_name, method_name, args); } self.emit_expr(obj); - self.emit_load_method_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), method_name); + self.emit_load_method_instr(method_name); self.emit_args(args, Method); } @@ -1621,9 +1342,16 @@ impl CodeGenerator { } /// 1.abs() => abs(1) - fn emit_call_fake_method(&mut self, obj: Expr, mut method_name: Identifier, mut args: Args) { + fn emit_call_fake_method( + &mut self, + obj: Expr, + func_name: &'static str, + mut method_name: Identifier, + mut args: Args, + ) { log!(info "entered {}", fn_name!()); method_name.dot = None; + method_name.vi.py_name = Some(Str::ever(func_name)); self.emit_load_name_instr(method_name); args.insert_pos(0, PosArg::new(obj)); self.emit_args(args, Name); @@ -1965,7 +1693,6 @@ impl CodeGenerator { Some(Token::dummy()), VarName::from_str(field.symbol.clone()), ), - Type::Failure, ))); let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line)); let dot = if field.vis.is_private() { @@ -1976,7 +1703,6 @@ impl CodeGenerator { let attr = Accessor::Attr(Attribute::new( obj, Identifier::bare(dot, VarName::from_str(field.symbol.clone())), - Type::Failure, )); let attr_def = AttrDef::new(attr, Block::new(vec![expr])); attrs.push(Expr::AttrDef(attr_def)); @@ -2010,16 +1736,14 @@ impl CodeGenerator { line, ))); let class = Expr::Accessor(Accessor::Ident(class_ident.clone())); - let class_new = Expr::Accessor(Accessor::attr( - class, - Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line)), - Type::Failure, - )); + let mut new_ident = + Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line)); + new_ident.vi.py_name = Some(Str::ever("__call__")); + let class_new = Expr::Accessor(Accessor::attr(class, new_ident)); let call = Expr::Call(Call::new( class_new, None, Args::new(vec![arg], None, vec![], None), - Type::Failure, )); let block = Block::new(vec![call]); let body = DefBody::new(Token::dummy(), block, DefId(0)); @@ -2108,7 +1832,7 @@ impl CodeGenerator { )], ); self.emit_load_name_instr(Identifier::private("#path")); - self.emit_load_method_instr("Array!", None, Identifier::public("push!")); + self.emit_load_method_instr(Identifier::public("append")); self.emit_load_const(erg_std_path().to_str().unwrap()); self.write_instr(CALL_METHOD); self.write_arg(1u8); diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index 4d8442f3..591d694b 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -26,7 +26,7 @@ use erg_parser::ast::VarName; use crate::context::initialize::const_func::*; use crate::context::instantiate::ConstTemplate; use crate::context::{ - ClassDefType, Context, ContextKind, DefaultInfo, MethodType, ParamSpec, TraitInstance, + ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, ParamSpec, TraitInstance, }; use crate::mod_cache::SharedModuleCache; use crate::varinfo::{Mutability, VarInfo, VarKind}; @@ -48,7 +48,38 @@ impl Context { } else { self.decls.insert( name, - VarInfo::new(t, Immutable, vis, Builtin, None, impl_of), + VarInfo::new(t, Immutable, vis, Builtin, None, impl_of, None), + ); + } + } + + fn register_builtin_py_decl( + &mut self, + name: &'static str, + t: Type, + vis: Visibility, + py_name: Option<&'static str>, + ) { + let impl_of = if let ContextKind::MethodDefs(Some(tr)) = &self.kind { + Some(tr.clone()) + } else { + None + }; + let name = VarName::from_static(name); + if self.decls.get(&name).is_some() { + panic!("already registered: {name}"); + } else { + self.decls.insert( + name, + VarInfo::new( + t, + Immutable, + vis, + Builtin, + None, + impl_of, + py_name.map(Str::ever), + ), ); } } @@ -69,13 +100,39 @@ impl Context { if self.locals.get(&name).is_some() { panic!("already registered: {name}"); } else { - self.locals - .insert(name, VarInfo::new(t, muty, vis, Builtin, None, impl_of)); + self.locals.insert( + name, + VarInfo::new(t, muty, vis, Builtin, None, impl_of, None), + ); + } + } + + fn register_builtin_py_impl( + &mut self, + name: &'static str, + t: Type, + muty: Mutability, + vis: Visibility, + py_name: Option<&'static str>, + ) { + let impl_of = if let ContextKind::MethodDefs(Some(tr)) = &self.kind { + Some(tr.clone()) + } else { + None + }; + let name = VarName::from_static(name); + if self.locals.get(&name).is_some() { + panic!("already registered: {name}"); + } else { + self.locals.insert( + name, + VarInfo::new(t, muty, vis, Builtin, None, impl_of, py_name.map(Str::ever)), + ); } } fn register_builtin_immutable_private_var(&mut self, name: &'static str, t: Type) { - self.register_builtin_impl(name, t, Immutable, Private) + self.register_builtin_impl(name, t, Immutable, Private); } fn register_builtin_const(&mut self, name: &str, vis: Visibility, obj: ValueObj) { @@ -95,6 +152,7 @@ impl Context { Builtin, None, impl_of, + None, ); self.consts.insert(VarName::from_str(Str::rc(name)), obj); self.locals.insert(VarName::from_str(Str::rc(name)), vi); @@ -124,15 +182,29 @@ impl Context { unique_in_place(&mut self.super_traits); } - fn register_builtin_type(&mut self, t: Type, ctx: Self, vis: Visibility, muty: Mutability) { + fn register_builtin_type( + &mut self, + t: Type, + ctx: Self, + vis: Visibility, + muty: Mutability, + py_name: Option<&'static str>, + ) { if t.typarams_len().is_none() { - self.register_mono_type(t, ctx, vis, muty); + self.register_mono_type(t, ctx, vis, muty, py_name); } else { - self.register_poly_type(t, ctx, vis, muty); + self.register_poly_type(t, ctx, vis, muty, py_name); } } - fn register_mono_type(&mut self, t: Type, ctx: Self, vis: Visibility, muty: Mutability) { + fn register_mono_type( + &mut self, + t: Type, + ctx: Self, + vis: Visibility, + muty: Mutability, + py_name: Option<&'static str>, + ) { if self.rec_get_mono_type(&t.local_name()).is_some() { panic!("{} has already been registered", t.local_name()); } else if self.rec_get_const_obj(&t.local_name()).is_some() { @@ -146,7 +218,15 @@ impl Context { }; self.locals.insert( name.clone(), - VarInfo::new(meta_t, muty, vis, Builtin, None, None), + VarInfo::new( + meta_t, + muty, + vis, + Builtin, + None, + None, + py_name.map(Str::ever), + ), ); self.consts .insert(name.clone(), ValueObj::builtin_t(t.clone())); @@ -162,21 +242,21 @@ impl Context { } for (trait_method, vi) in ctx.decls.iter() { if let Some(types) = self.method_to_traits.get_mut(trait_method.inspect()) { - types.push(MethodType::new(t.clone(), vi.t.clone())); + types.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_traits.insert( trait_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } for (class_method, vi) in ctx.locals.iter() { if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) { - types.push(MethodType::new(t.clone(), vi.t.clone())); + types.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_classes.insert( class_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } @@ -185,7 +265,14 @@ impl Context { } // FIXME: MethodDefsと再代入は違う - fn register_poly_type(&mut self, t: Type, ctx: Self, vis: Visibility, muty: Mutability) { + fn register_poly_type( + &mut self, + t: Type, + ctx: Self, + vis: Visibility, + muty: Mutability, + py_name: Option<&'static str>, + ) { // FIXME: panic if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.local_name()) { root_ctx.methods_list.push((ClassDefType::Simple(t), ctx)); @@ -198,7 +285,15 @@ impl Context { }; self.locals.insert( name.clone(), - VarInfo::new(meta_t, muty, vis, Builtin, None, None), + VarInfo::new( + meta_t, + muty, + vis, + Builtin, + None, + None, + py_name.map(Str::ever), + ), ); self.consts .insert(name.clone(), ValueObj::builtin_t(t.clone())); @@ -214,21 +309,21 @@ impl Context { } for (trait_method, vi) in ctx.decls.iter() { if let Some(traits) = self.method_to_traits.get_mut(trait_method.inspect()) { - traits.push(MethodType::new(t.clone(), vi.t.clone())); + traits.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_traits.insert( trait_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } for (class_method, vi) in ctx.locals.iter() { if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) { - types.push(MethodType::new(t.clone(), vi.t.clone())); + types.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_classes.insert( class_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } @@ -249,7 +344,7 @@ impl Context { let name = VarName::from_static(name); self.locals.insert( name.clone(), - VarInfo::new(Patch, muty, vis, Builtin, None, None), + VarInfo::new(Patch, muty, vis, Builtin, None, None, None), ); for method_name in ctx.locals.keys() { if let Some(patches) = self.method_impl_patches.get_mut(method_name) { @@ -307,7 +402,7 @@ impl Context { t_read, set! { subtypeof(mono_q("Self"), mono("Readable!")) }, ); - readable.register_builtin_decl("read!", t_read, Public); + readable.register_builtin_py_decl("read!", t_read, Public, Some("read")); /* Writable */ let mut writable = Self::builtin_mono_trait("Writable!", 2); let t_write = pr1_kw_met(ref_mut(mono_q("Self"), None), kw("s", Str), Nat); @@ -315,12 +410,12 @@ impl Context { t_write, set! { subtypeof(mono_q("Self"), mono("Writable!")) }, ); - writable.register_builtin_decl("write!", t_write, Public); + writable.register_builtin_py_decl("write!", t_write, Public, Some("write")); /* Show */ let mut show = Self::builtin_mono_trait("Show", 2); let t_show = fn0_met(ref_(mono_q("Self")), Str); let t_show = quant(t_show, set! { subtypeof(mono_q("Self"), mono("Show")) }); - show.register_builtin_decl("to_str", t_show, Public); + show.register_builtin_py_decl("to_str", t_show, Public, Some("__str__")); /* In */ let mut in_ = Self::builtin_poly_trait("In", vec![PS::t("T", NonDefault)], 2); let params = vec![PS::t("T", NonDefault)]; @@ -447,50 +542,90 @@ impl Context { let op_t = quant(op_t, set! {r_bound, self_bound}); floor_div.register_builtin_decl("__floordiv__", op_t, Public); floor_div.register_builtin_decl("Output", Type, Public); - self.register_builtin_type(mono("Unpack"), unpack, Private, Const); - self.register_builtin_type(mono("InheritableType"), inheritable_type, Private, Const); - self.register_builtin_type(mono("Named"), named, Private, Const); - self.register_builtin_type(mono("Mutable"), mutable, Private, Const); - self.register_builtin_type(mono("Immutizable"), immutizable, Private, Const); - self.register_builtin_type(mono("Mutizable"), mutizable, Private, Const); - self.register_builtin_type(mono("PathLike"), pathlike, Private, Const); - self.register_builtin_type(mono("Readable!"), readable, Private, Const); - self.register_builtin_type(mono("Writable!"), writable, Private, Const); - self.register_builtin_type(mono("Show"), show, Private, Const); + self.register_builtin_type(mono("Unpack"), unpack, Private, Const, None); + self.register_builtin_type( + mono("InheritableType"), + inheritable_type, + Private, + Const, + None, + ); + self.register_builtin_type(mono("Named"), named, Private, Const, None); + self.register_builtin_type(mono("Mutable"), mutable, Private, Const, None); + self.register_builtin_type(mono("Immutizable"), immutizable, Private, Const, None); + self.register_builtin_type(mono("Mutizable"), mutizable, Private, Const, None); + self.register_builtin_type(mono("PathLike"), pathlike, Private, Const, None); + self.register_builtin_type( + mono("Readable!"), + readable, + Private, + Const, + Some("Readable"), + ); + self.register_builtin_type( + mono("Writable!"), + writable, + Private, + Const, + Some("Writable"), + ); + self.register_builtin_type(mono("Show"), show, Private, Const, None); self.register_builtin_type( poly("Input", vec![ty_tp(mono_q("T"))]), input, Private, Const, + None, ); self.register_builtin_type( poly("Output", vec![ty_tp(mono_q("T"))]), output, Private, Const, + None, + ); + self.register_builtin_type( + poly("In", vec![ty_tp(mono_q("T"))]), + in_, + Private, + Const, + None, + ); + self.register_builtin_type( + poly("Eq", vec![ty_tp(mono_q("R"))]), + eq, + Private, + Const, + None, ); - self.register_builtin_type(poly("In", vec![ty_tp(mono_q("T"))]), in_, Private, Const); - self.register_builtin_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Private, Const); self.register_builtin_type( poly("PartialOrd", vec![ty_tp(mono_q("R"))]), partial_ord, Private, Const, + None, + ); + self.register_builtin_type(mono("Ord"), ord, Private, Const, None); + self.register_builtin_type(mono("Num"), num, Private, Const, None); + self.register_builtin_type( + poly("Seq", vec![ty_tp(mono_q("T"))]), + seq, + Private, + Const, + None, ); - self.register_builtin_type(mono("Ord"), ord, Private, Const); - self.register_builtin_type(mono("Num"), num, Private, Const); - self.register_builtin_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Private, Const); self.register_builtin_type( poly("Iterable", vec![ty_tp(mono_q("T"))]), iterable, Private, Const, + None, ); - self.register_builtin_type(poly("Add", ty_params.clone()), add, Private, Const); - self.register_builtin_type(poly("Sub", ty_params.clone()), sub, Private, Const); - self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Private, Const); - self.register_builtin_type(poly("Div", ty_params.clone()), div, Private, Const); - self.register_builtin_type(poly("FloorDiv", ty_params), floor_div, Private, Const); + self.register_builtin_type(poly("Add", ty_params.clone()), add, Private, Const, None); + self.register_builtin_type(poly("Sub", ty_params.clone()), sub, Private, Const, None); + self.register_builtin_type(poly("Mul", ty_params.clone()), mul, Private, Const, None); + self.register_builtin_type(poly("Div", ty_params.clone()), div, Private, Const, None); + self.register_builtin_type(poly("FloorDiv", ty_params), floor_div, Private, Const, None); self.register_const_param_defaults( "Eq", vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))], @@ -551,8 +686,8 @@ impl Context { float.register_superclass(Obj, &obj); // TODO: support multi platform float.register_builtin_const("EPSILON", Public, ValueObj::Float(2.220446049250313e-16)); - float.register_builtin_impl("Real", Float, Const, Public); - float.register_builtin_impl("Imag", Float, Const, Public); + float.register_builtin_py_impl("Real", Float, Const, Public, Some("real")); + float.register_builtin_py_impl("Imag", Float, Const, Public, Some("imag")); float.register_marker_trait(mono("Num")); float.register_marker_trait(mono("Ord")); let mut float_partial_ord = @@ -598,15 +733,15 @@ impl Context { float.register_trait(Float, float_mutizable); let mut float_show = Self::builtin_methods(Some(mono("Show")), 1); let t = fn0_met(Float, Str); - float_show.register_builtin_impl("to_str", t, Immutable, Public); + float_show.register_builtin_py_impl("to_str", t, Immutable, Public, Some("__str__")); float.register_trait(Float, float_show); /* Ratio */ // TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat) let mut ratio = Self::builtin_mono_class("Ratio", 2); ratio.register_superclass(Obj, &obj); - ratio.register_builtin_impl("Real", Ratio, Const, Public); - ratio.register_builtin_impl("Imag", Ratio, Const, Public); + ratio.register_builtin_py_impl("Real", Ratio, Const, Public, Some("real")); + ratio.register_builtin_py_impl("Imag", Ratio, Const, Public, Some("imag")); ratio.register_marker_trait(mono("Num")); ratio.register_marker_trait(mono("Ord")); let mut ratio_partial_ord = @@ -702,17 +837,17 @@ impl Context { int.register_trait(Int, int_mutizable); let mut int_show = Self::builtin_methods(Some(mono("Show")), 1); let t = fn0_met(Int, Str); - int_show.register_builtin_impl("to_str", t, Immutable, Public); + int_show.register_builtin_py_impl("to_str", t, Immutable, Public, Some("__str__")); int.register_trait(Int, int_show); - int.register_builtin_impl("Real", Int, Const, Public); - int.register_builtin_impl("Imag", Int, Const, Public); + int.register_builtin_py_impl("Real", Int, Const, Public, Some("real")); + int.register_builtin_py_impl("Imag", Int, Const, Public, Some("imag")); /* Nat */ let mut nat = Self::builtin_mono_class("Nat", 10); nat.register_superclass(Int, &int); // class("Rational"), // class("Integral"), - nat.register_builtin_impl( + nat.register_builtin_py_impl( "times!", pr_met( Nat, @@ -723,6 +858,7 @@ impl Context { ), Immutable, Public, + Some("times"), ); nat.register_marker_trait(mono("Num")); nat.register_marker_trait(mono("Ord")); @@ -932,7 +1068,7 @@ impl Context { t, set! {static_instance("T", Type), static_instance("N", Nat), static_instance("M", Nat)}, ); - array_.register_builtin_impl("concat", t, Immutable, Public); + array_.register_builtin_py_impl("concat", t, Immutable, Public, Some("__add__")); // Array(T, N)|<: Add(Array(T, M))|. // Output = Array(T, N + M) // __add__: (self: Array(T, N), other: Array(T, M)) -> Array(T, N + M) = Array.concat @@ -983,7 +1119,13 @@ impl Context { array_.register_marker_trait(mono("Mutizable")); array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); let mut array_show = Self::builtin_methods(Some(mono("Show")), 1); - array_show.register_builtin_impl("to_str", fn0_met(arr_t.clone(), Str), Immutable, Public); + array_show.register_builtin_py_impl( + "to_str", + fn0_met(arr_t.clone(), Str), + Immutable, + Public, + Some("__str__"), + ); array_.register_trait(arr_t.clone(), array_show); let mut array_iterable = Self::builtin_methods(Some(poly("Iterable", vec![ty_tp(mono_q("T"))])), 2); @@ -1102,7 +1244,13 @@ impl Context { tuple_getitem_t, set! {static_instance("Ts", array_t(Type, mono_q_tp("N"))), static_instance("N", Nat)}, ); - tuple_.register_builtin_impl("__Tuple_getitem__", tuple_getitem_t, Const, Public); + tuple_.register_builtin_py_impl( + "__Tuple_getitem__", + tuple_getitem_t, + Const, + Public, + Some("__getitem__"), + ); /* record */ let mut record = Self::builtin_mono_class("Record", 2); record.register_superclass(Obj, &obj); @@ -1211,7 +1359,7 @@ impl Context { /* File_mut */ let mut file_mut = Self::builtin_mono_class("File!", 2); let mut file_mut_readable = Self::builtin_methods(Some(mono("Readable!")), 1); - file_mut_readable.register_builtin_impl( + file_mut_readable.register_builtin_py_impl( "read!", pr_met( ref_mut(mono("File!"), None), @@ -1222,14 +1370,16 @@ impl Context { ), Immutable, Public, + Some("read"), ); file_mut.register_trait(mono("File!"), file_mut_readable); let mut file_mut_writable = Self::builtin_methods(Some(mono("Writable!")), 1); - file_mut_writable.register_builtin_impl( + file_mut_writable.register_builtin_py_impl( "write!", pr1_kw_met(ref_mut(mono("File!"), None), kw("s", Str), Nat), Immutable, Public, + Some("write"), ); file_mut.register_trait(mono("File!"), file_mut_writable); /* Array_mut */ @@ -1257,7 +1407,7 @@ impl Context { t, set! {static_instance("T", Type), static_instance("N", mono("Nat!"))}, ); - array_mut_.register_builtin_impl("push!", t, Immutable, Public); + array_mut_.register_builtin_py_impl("push!", t, Immutable, Public, Some("append")); let t = pr_met( array_mut_t.clone(), vec![kw("f", nd_func(vec![anon(mono_q("T"))], None, mono_q("T")))], @@ -1310,7 +1460,7 @@ impl Context { t, set! {static_instance("T", Type), static_instance("N", mono("Nat!"))}, ); - set_mut_.register_builtin_impl("add!", t, Immutable, Public); + set_mut_.register_builtin_py_impl("add!", t, Immutable, Public, Some("add")); let t = pr_met( set_mut_t.clone(), vec![kw("f", nd_func(vec![anon(mono_q("T"))], None, mono_q("T")))], @@ -1363,53 +1513,99 @@ impl Context { let mut named_func = Self::builtin_mono_class("NamedFunc", 2); named_func.register_superclass(mono("Func"), &func); named_func.register_marker_trait(mono("Named")); + let mut quant = Self::builtin_mono_class("Quantified", 2); + quant.register_superclass(mono("Proc"), &proc); let mut qfunc = Self::builtin_mono_class("QuantifiedFunc", 2); qfunc.register_superclass(mono("Func"), &func); - self.register_builtin_type(Obj, obj, Private, Const); + self.register_builtin_type(Obj, obj, Private, Const, Some("object")); // self.register_type(mono("Record"), vec![], record, Private, Const); - self.register_builtin_type(Int, int, Private, Const); - self.register_builtin_type(Nat, nat, Private, Const); - self.register_builtin_type(Float, float, Private, Const); - self.register_builtin_type(Ratio, ratio, Private, Const); - self.register_builtin_type(Bool, bool_, Private, Const); - self.register_builtin_type(Str, str_, Private, Const); - self.register_builtin_type(NoneType, nonetype, Private, Const); - self.register_builtin_type(Type, type_, Private, Const); - self.register_builtin_type(ClassType, class_type, Private, Const); - self.register_builtin_type(TraitType, trait_type, Private, Const); - self.register_builtin_type(g_module_t, generic_module, Private, Const); - self.register_builtin_type(module_t, module, Private, Const); - self.register_builtin_type(arr_t, array_, Private, Const); - self.register_builtin_type(set_t, set_, Private, Const); - self.register_builtin_type(g_dict_t, generic_dict, Private, Const); - self.register_builtin_type(dict_t, dict_, Private, Const); - self.register_builtin_type(mono("Bytes"), bytes, Private, Const); - self.register_builtin_type(mono("GenericTuple"), generic_tuple, Private, Const); - self.register_builtin_type(tuple_t, tuple_, Private, Const); - self.register_builtin_type(mono("Record"), record, Private, Const); - self.register_builtin_type(or_t, or, Private, Const); - self.register_builtin_type(mono("StrIterator"), str_iterator, Private, Const); + self.register_builtin_type(Int, int, Private, Const, Some("int")); + self.register_builtin_type(Nat, nat, Private, Const, Some("Nat")); + self.register_builtin_type(Float, float, Private, Const, Some("float")); + self.register_builtin_type(Ratio, ratio, Private, Const, Some("Ratio")); + self.register_builtin_type(Bool, bool_, Private, Const, Some("Bool")); + self.register_builtin_type(Str, str_, Private, Const, Some("Str")); + self.register_builtin_type(NoneType, nonetype, Private, Const, Some("NoneType")); + self.register_builtin_type(Type, type_, Private, Const, Some("type")); + self.register_builtin_type(ClassType, class_type, Private, Const, Some("ClassType")); + self.register_builtin_type(TraitType, trait_type, Private, Const, Some("TraitType")); + self.register_builtin_type( + g_module_t, + generic_module, + Private, + Const, + Some("ModuleType"), + ); + self.register_builtin_type(module_t, module, Private, Const, Some("Module")); + self.register_builtin_type(arr_t, array_, Private, Const, Some("list")); + self.register_builtin_type(set_t, set_, Private, Const, Some("set")); + self.register_builtin_type(g_dict_t, generic_dict, Private, Const, Some("dict")); + self.register_builtin_type(dict_t, dict_, Private, Const, Some("dict")); + self.register_builtin_type(mono("Bytes"), bytes, Private, Const, Some("bytes")); + self.register_builtin_type( + mono("GenericTuple"), + generic_tuple, + Private, + Const, + Some("tuple"), + ); + self.register_builtin_type(tuple_t, tuple_, Private, Const, Some("tuple")); + self.register_builtin_type(mono("Record"), record, Private, Const, Some("Record")); + self.register_builtin_type(or_t, or, Private, Const, Some("Union")); + self.register_builtin_type( + mono("StrIterator"), + str_iterator, + Private, + Const, + Some("str_iterator"), + ); self.register_builtin_type( poly("ArrayIterator", vec![ty_tp(mono_q("T"))]), array_iterator, Private, Const, + Some("array_iterator"), + ); + self.register_builtin_type(mono("Int!"), int_mut, Private, Const, Some("int")); + self.register_builtin_type(mono("Nat!"), nat_mut, Private, Const, Some("Nat")); + self.register_builtin_type(mono("Float!"), float_mut, Private, Const, Some("float")); + self.register_builtin_type(mono("Ratio!"), ratio_mut, Private, Const, Some("Ratio")); + self.register_builtin_type(mono("Bool!"), bool_mut, Private, Const, Some("Bool")); + self.register_builtin_type(mono("Str!"), str_mut, Private, Const, Some("Str")); + self.register_builtin_type(mono("File!"), file_mut, Private, Const, Some("File")); + self.register_builtin_type(array_mut_t, array_mut_, Private, Const, Some("list")); + self.register_builtin_type(set_mut_t, set_mut_, Private, Const, Some("set")); + self.register_builtin_type(range_t, range, Private, Const, Some("Range")); + self.register_builtin_type(mono("Proc"), proc, Private, Const, Some("Proc")); + self.register_builtin_type( + mono("NamedProc"), + named_proc, + Private, + Const, + Some("NamedProc"), + ); + self.register_builtin_type(mono("Func"), func, Private, Const, Some("Func")); + self.register_builtin_type( + mono("NamedFunc"), + named_func, + Private, + Const, + Some("NamedFunc"), + ); + self.register_builtin_type( + mono("Quantified"), + quant, + Private, + Const, + Some("Quantified"), + ); + self.register_builtin_type( + mono("QuantifiedFunc"), + qfunc, + Private, + Const, + Some("QuantifiedFunc"), ); - self.register_builtin_type(mono("Int!"), int_mut, Private, Const); - self.register_builtin_type(mono("Nat!"), nat_mut, Private, Const); - self.register_builtin_type(mono("Float!"), float_mut, Private, Const); - self.register_builtin_type(mono("Ratio!"), ratio_mut, Private, Const); - self.register_builtin_type(mono("Bool!"), bool_mut, Private, Const); - self.register_builtin_type(mono("Str!"), str_mut, Private, Const); - self.register_builtin_type(mono("File!"), file_mut, Private, Const); - self.register_builtin_type(array_mut_t, array_mut_, Private, Const); - self.register_builtin_type(set_mut_t, set_mut_, Private, Const); - self.register_builtin_type(range_t, range, Private, Const); - self.register_builtin_type(mono("Proc"), proc, Private, Const); - self.register_builtin_type(mono("NamedProc"), named_proc, Private, Const); - self.register_builtin_type(mono("Func"), func, Private, Const); - self.register_builtin_type(mono("NamedFunc"), named_func, Private, Const); - self.register_builtin_type(mono("QuantifiedFunc"), qfunc, Private, Const); } fn init_builtin_funcs(&mut self) { @@ -1519,33 +1715,57 @@ impl Context { let t_exit = t_quit.clone(); let t_repr = nd_func(vec![kw("object", Obj)], None, Str); let t_round = nd_func(vec![kw("number", Float)], None, Int); - self.register_builtin_impl("abs", t_abs, Immutable, Private); - self.register_builtin_impl("ascii", t_ascii, Immutable, Private); + self.register_builtin_py_impl("abs", t_abs, Immutable, Private, Some("abs")); + self.register_builtin_py_impl("ascii", t_ascii, Immutable, Private, Some("ascii")); self.register_builtin_impl("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく - self.register_builtin_impl("bin", t_bin, Immutable, Private); - self.register_builtin_impl("chr", t_chr, Immutable, Private); - self.register_builtin_impl("classof", t_classof, Immutable, Private); - self.register_builtin_impl("compile", t_compile, Immutable, Private); + self.register_builtin_py_impl("bin", t_bin, Immutable, Private, Some("bin")); + self.register_builtin_py_impl("chr", t_chr, Immutable, Private, Some("chr")); + self.register_builtin_py_impl("classof", t_classof, Immutable, Private, Some("type")); + self.register_builtin_py_impl("compile", t_compile, Immutable, Private, Some("compile")); self.register_builtin_impl("cond", t_cond, Immutable, Private); self.register_builtin_impl("discard", t_discard, Immutable, Private); - self.register_builtin_impl("exit", t_exit, Immutable, Private); + self.register_builtin_py_impl("exit", t_exit, Immutable, Private, Some("exit")); self.register_builtin_impl("if", t_if, Immutable, Private); - self.register_builtin_impl("import", t_import, Immutable, Private); - self.register_builtin_impl("isinstance", t_isinstance, Immutable, Private); - self.register_builtin_impl("issubclass", t_issubclass, Immutable, Private); - self.register_builtin_impl("len", t_len, Immutable, Private); - self.register_builtin_impl("log", t_log, Immutable, Private); - self.register_builtin_impl("oct", t_oct, Immutable, Private); - self.register_builtin_impl("ord", t_ord, Immutable, Private); - self.register_builtin_impl("panic", t_panic, Immutable, Private); - self.register_builtin_impl("pow", t_pow, Immutable, Private); + self.register_builtin_py_impl("import", t_import, Immutable, Private, Some("__import__")); + self.register_builtin_py_impl( + "isinstance", + t_isinstance, + Immutable, + Private, + Some("isinstance"), + ); + self.register_builtin_py_impl( + "issubclass", + t_issubclass, + Immutable, + Private, + Some("issubclass"), + ); + self.register_builtin_py_impl("len", t_len, Immutable, Private, Some("len")); + self.register_builtin_py_impl("log", t_log, Immutable, Private, Some("print")); + self.register_builtin_py_impl("oct", t_oct, Immutable, Private, Some("oct")); + self.register_builtin_py_impl("ord", t_ord, Immutable, Private, Some("ord")); + self.register_builtin_py_impl("panic", t_panic, Immutable, Private, Some("quit")); + self.register_builtin_py_impl("pow", t_pow, Immutable, Private, Some("pow")); if cfg!(feature = "debug") { - self.register_builtin_impl("py", t_pyimport.clone(), Immutable, Private); + self.register_builtin_py_impl( + "py", + t_pyimport.clone(), + Immutable, + Private, + Some("__import__"), + ); } - self.register_builtin_impl("pyimport", t_pyimport, Immutable, Private); - self.register_builtin_impl("quit", t_quit, Immutable, Private); - self.register_builtin_impl("repr", t_repr, Immutable, Private); - self.register_builtin_impl("round", t_round, Immutable, Private); + self.register_builtin_py_impl( + "pyimport", + t_pyimport, + Immutable, + Private, + Some("__import__"), + ); + self.register_builtin_py_impl("quit", t_quit, Immutable, Private, Some("quit")); + self.register_builtin_py_impl("repr", t_repr, Immutable, Private, Some("repr")); + self.register_builtin_py_impl("round", t_round, Immutable, Private, Some("round")); } fn init_builtin_const_funcs(&mut self) { @@ -1682,16 +1902,16 @@ impl Context { t_with, set! {static_instance("T", Type), static_instance("U", Type)}, ); - self.register_builtin_impl("dir!", t_dir, Immutable, Private); - self.register_builtin_impl("print!", t_print, Immutable, Private); - self.register_builtin_impl("id!", t_id, Immutable, Private); - self.register_builtin_impl("input!", t_input, Immutable, Private); + self.register_builtin_py_impl("dir!", t_dir, Immutable, Private, Some("dir")); + self.register_builtin_py_impl("print!", t_print, Immutable, Private, Some("print")); + self.register_builtin_py_impl("id!", t_id, Immutable, Private, Some("id")); + self.register_builtin_py_impl("input!", t_input, Immutable, Private, Some("input")); self.register_builtin_impl("if!", t_if, Immutable, Private); self.register_builtin_impl("for!", t_for, Immutable, Private); - self.register_builtin_impl("globals!", t_globals, Immutable, Private); - self.register_builtin_impl("locals!", t_locals, Immutable, Private); + self.register_builtin_py_impl("globals!", t_globals, Immutable, Private, Some("globals")); + self.register_builtin_py_impl("locals!", t_locals, Immutable, Private, Some("locals")); self.register_builtin_impl("while!", t_while, Immutable, Private); - self.register_builtin_impl("open!", t_open, Immutable, Private); + self.register_builtin_py_impl("open!", t_open, Immutable, Private, Some("open")); self.register_builtin_impl("with!", t_with, Immutable, Private); } diff --git a/compiler/erg_compiler/context/initialize/py_mods/glob.rs b/compiler/erg_compiler/context/initialize/py_mods/glob.rs index ca49c97f..ef7d2da9 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/glob.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/glob.rs @@ -13,7 +13,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_glob_mod() -> Self { let mut glob = Context::builtin_module("glob", 10); - glob.register_builtin_impl( + glob.register_builtin_py_impl( "glob!", proc( vec![kw("pathname", Str)], @@ -23,6 +23,7 @@ impl Context { ), Immutable, Public, + Some("glob"), ); glob } diff --git a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs index 46515839..0f93e40f 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs @@ -12,11 +12,12 @@ use Visibility::*; impl Context { pub(crate) fn init_py_importlib_mod() -> Self { let mut importlib = Context::builtin_module("importlib", 15); - importlib.register_builtin_impl( + importlib.register_builtin_py_impl( "reload!", proc1(mono("GenericModule"), NoneType), Immutable, Public, + Some("reload"), ); importlib } diff --git a/compiler/erg_compiler/context/initialize/py_mods/io.rs b/compiler/erg_compiler/context/initialize/py_mods/io.rs index 2d434b2a..51476320 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/io.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/io.rs @@ -15,13 +15,20 @@ impl Context { let mut string_io = Context::builtin_mono_class("StringIO!", 0); // FIXME: include Obj (pass main_ctx as a param) // string_io.register_superclass(Obj, obj); - string_io.register_builtin_impl( + string_io.register_builtin_py_impl( "getvalue!", pr0_met(ref_(mono("io.StringIO!")), Str), Immutable, Public, + Some("getvalue"), + ); + io.register_builtin_type( + mono("io.StringIO!"), + string_io, + Public, + Const, + Some("io.StringIO"), ); - io.register_builtin_type(mono("io.StringIO!"), string_io, Public, Const); io } } diff --git a/compiler/erg_compiler/context/initialize/py_mods/os.rs b/compiler/erg_compiler/context/initialize/py_mods/os.rs index 0cdea29f..3eb8c996 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/os.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/os.rs @@ -13,15 +13,22 @@ use Visibility::*; impl Context { pub(crate) fn init_py_os_mod() -> Self { let mut os = Context::builtin_module("os", 15); - os.register_builtin_impl( + os.register_builtin_py_impl( "chdir!", nd_proc1(kw("path", mono("PathLike")), NoneType), Immutable, Public, + Some("chdir"), ); - os.register_builtin_impl("getcwd!", proc0(Str), Immutable, Public); - os.register_builtin_impl("getenv!", nd_proc1(kw("key", Str), Str), Immutable, Public); - os.register_builtin_impl( + os.register_builtin_py_impl("getcwd!", proc0(Str), Immutable, Public, Some("getcwd")); + os.register_builtin_py_impl( + "getenv!", + nd_proc1(kw("key", Str), Str), + Immutable, + Public, + Some("getenv"), + ); + os.register_builtin_py_impl( "listdir!", proc( vec![], @@ -31,15 +38,17 @@ impl Context { ), Immutable, Public, + Some("listdir"), ); - os.register_builtin_impl( + os.register_builtin_py_impl( "mkdir!", nd_proc1(kw("path", mono("PathLike")), NoneType), Immutable, Public, + Some("mkdir"), ); os.register_builtin_impl("name", Str, Immutable, Public); - os.register_builtin_impl( + os.register_builtin_py_impl( "putenv!", proc( vec![kw("key", Str), kw("value", Str)], @@ -49,20 +58,23 @@ impl Context { ), Immutable, Public, + Some("putenv"), ); - os.register_builtin_impl( + os.register_builtin_py_impl( "remove!", nd_proc1(kw("path", mono("PathLike")), NoneType), Immutable, Public, + Some("remove"), ); - os.register_builtin_impl( + os.register_builtin_py_impl( "removedirs!", nd_proc1(kw("name", mono("PathLike")), NoneType), Immutable, Public, + Some("removedirs"), ); - os.register_builtin_impl( + os.register_builtin_py_impl( "rename!", proc( vec![kw("src", mono("PathLike")), kw("dst", mono("PathLike"))], @@ -72,19 +84,22 @@ impl Context { ), Immutable, Public, + Some("rename"), ); - os.register_builtin_impl( + os.register_builtin_py_impl( "rmdir!", nd_proc1(kw("path", mono("PathLike")), NoneType), Immutable, Public, + Some("rmdir"), ); if cfg!(unix) { - os.register_builtin_impl( + os.register_builtin_py_impl( "uname!", proc0(mono("posix.UnameResult")), Immutable, Public, + Some("uname"), ); } // TODO diff --git a/compiler/erg_compiler/context/initialize/py_mods/random.rs b/compiler/erg_compiler/context/initialize/py_mods/random.rs index 26ec4767..69761724 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/random.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/random.rs @@ -15,7 +15,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_random_mod() -> Self { let mut random = Context::builtin_module("random", 10); - random.register_builtin_impl( + random.register_builtin_py_impl( "seed!", proc( vec![], @@ -28,12 +28,14 @@ impl Context { ), Immutable, Public, + Some("seed"), ); - random.register_builtin_impl( + random.register_builtin_py_impl( "randint!", nd_proc(vec![kw("a", Int), kw("b", Int)], None, Int), Immutable, Public, + Some("randint"), ); let t = nd_proc( vec![kw("seq", poly("Seq", vec![ty_tp(mono_q("T"))]))], @@ -41,7 +43,7 @@ impl Context { mono_q("T"), ); let t = quant(t, set! {static_instance("T", Type)}); - random.register_builtin_impl("choice!", t, Immutable, Public); + random.register_builtin_py_impl("choice!", t, Immutable, Public, Some("choice")); random } } diff --git a/compiler/erg_compiler/context/initialize/py_mods/socket.rs b/compiler/erg_compiler/context/initialize/py_mods/socket.rs index 3648a7cb..dab0442d 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/socket.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/socket.rs @@ -31,7 +31,13 @@ impl Context { Immutable, Public, ); - socket.register_builtin_type(mono("socket.Socket!"), sock, Public, Const); + socket.register_builtin_type( + mono("socket.Socket!"), + sock, + Public, + Const, + Some("socket.Socket"), + ); socket } } diff --git a/compiler/erg_compiler/context/initialize/py_mods/time.rs b/compiler/erg_compiler/context/initialize/py_mods/time.rs index 18580a0b..72d6aa63 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/time.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/time.rs @@ -12,8 +12,14 @@ use Visibility::*; impl Context { pub(crate) fn init_py_time_mod() -> Self { let mut time = Context::builtin_module("time", 15); - time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public); - time.register_builtin_impl("time!", proc0(Float), Immutable, Public); + time.register_builtin_py_impl( + "sleep!", + proc1(Float, NoneType), + Immutable, + Public, + Some("sleep"), + ); + time.register_builtin_py_impl("time!", proc0(Float), Immutable, Public, Some("time")); time } } diff --git a/compiler/erg_compiler/context/initialize/py_mods/urllib.rs b/compiler/erg_compiler/context/initialize/py_mods/urllib.rs index b8b842cc..b4fd1f4d 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/urllib.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/urllib.rs @@ -18,7 +18,13 @@ impl Context { urllib.py_mod_cache = Some(SharedModuleCache::new()); let mut request_class = Context::builtin_mono_class("Request", 5); request_class.register_builtin_impl("data", mono("Bytes"), Immutable, Public); - urllib.register_builtin_type(mono("urllib.request.Request"), request_class, Public, Const); + urllib.register_builtin_type( + mono("urllib.request.Request"), + request_class, + Public, + Const, + Some("urllib.request.Request"), + ); urllib.register_builtin_impl("request", module_from_path("request"), Immutable, Public); let mut request = Context::builtin_module("urllib.request", 15); let t = proc( @@ -30,7 +36,7 @@ impl Context { ], mono("http.client.HTTPResponse"), ); - request.register_builtin_impl("urlopen", t, Immutable, Public); + request.register_builtin_py_impl("urlopen!", t, Immutable, Public, Some("urlopen")); urllib.register_builtin_impl("parse", module_from_path("parse"), Immutable, Public); let parse = Context::builtin_module("urllib.parse", 15); urllib diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index 11c46c34..ffc5173e 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -3,6 +3,7 @@ use std::option::Option; // conflicting to Type::Option use std::path::{Path, PathBuf}; use erg_common::config::Input; +use erg_common::env::erg_pystd_path; use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::levenshtein::get_similar_name; use erg_common::set::Set; @@ -29,12 +30,12 @@ use crate::error::{ TyCheckErrors, TyCheckResult, }; use crate::hir; -use crate::varinfo::VarInfo; +use crate::varinfo::{Mutability, VarInfo, VarKind}; use crate::AccessKind; use RegistrationMode::*; use Visibility::*; -use super::MethodType; +use super::MethodInfo; impl Context { pub(crate) fn validate_var_sig_t( @@ -209,7 +210,7 @@ impl Context { &self, pos_args: &[hir::PosArg], kw_args: &[hir::KwArg], - ) -> TyCheckResult { + ) -> TyCheckResult { if !kw_args.is_empty() { todo!() } @@ -284,14 +285,17 @@ impl Context { let param_ty = ParamTy::anonymous(match_target_expr_t.clone()); let param_ts = [vec![param_ty], branch_ts.to_vec()].concat(); let t = func(param_ts, None, vec![], return_t); - Ok(t) + Ok(VarInfo { + t, + ..VarInfo::default() + }) } fn get_import_call_t( &self, pos_args: &[hir::PosArg], kw_args: &[hir::KwArg], - ) -> TyCheckResult { + ) -> TyCheckResult { let mod_name = pos_args .get(0) .map(|a| &a.expr) @@ -337,20 +341,24 @@ impl Context { vec![], module(TyParam::Value(s)), ); - Ok(import_t) + Ok(VarInfo { + t: import_t, + py_name: Some(Str::ever("__import__")), + ..VarInfo::default() + }) } - pub(crate) fn rec_get_var_t( + pub(crate) fn rec_get_var_info( &self, ident: &Identifier, acc_kind: AccessKind, input: &Input, namespace: &Str, - ) -> SingleTyCheckResult { + ) -> SingleTyCheckResult { if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) { match self.validate_visibility(ident, vi, input, namespace) { Ok(()) => { - return Ok(vi.t()); + return Ok(vi.clone()); } Err(err) => { if !acc_kind.is_local() { @@ -360,7 +368,7 @@ impl Context { } } if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - return parent.rec_get_var_t(ident, acc_kind, input, namespace); + return parent.rec_get_var_info(ident, acc_kind, input, namespace); } Err(TyCheckError::no_var_error( input.clone(), @@ -372,17 +380,17 @@ impl Context { )) } - pub(crate) fn rec_get_decl_t( + pub(crate) fn rec_get_decl_info( &self, ident: &Identifier, acc_kind: AccessKind, input: &Input, namespace: &Str, - ) -> SingleTyCheckResult { + ) -> SingleTyCheckResult { if let Some(vi) = self.decls.get(&ident.inspect()[..]) { match self.validate_visibility(ident, vi, input, namespace) { Ok(()) => { - return Ok(vi.t()); + return Ok(vi.clone()); } Err(err) => { if !acc_kind.is_local() { @@ -392,7 +400,7 @@ impl Context { } } if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - return parent.rec_get_decl_t(ident, acc_kind, input, namespace); + return parent.rec_get_decl_info(ident, acc_kind, input, namespace); } Err(TyCheckError::no_var_error( input.clone(), @@ -404,16 +412,16 @@ impl Context { )) } - pub(crate) fn rec_get_attr_t( + pub(crate) fn rec_get_attr_info( &self, obj: &hir::Expr, ident: &Identifier, input: &Input, namespace: &Str, - ) -> SingleTyCheckResult { + ) -> SingleTyCheckResult { let self_t = obj.t(); let name = ident.name.token(); - match self.get_attr_t_from_attributive(obj, &self_t, ident, namespace) { + match self.get_attr_info_from_attributive(obj, &self_t, ident, namespace) { Ok(t) => { return Ok(t); } @@ -423,9 +431,9 @@ impl Context { } } if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) { - match singular_ctx.rec_get_var_t(ident, AccessKind::Attr, input, namespace) { - Ok(t) => { - return Ok(t); + match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { + Ok(vi) => { + return Ok(vi); } Err(e) if e.core.kind == ErrorKind::NameError => {} Err(e) => { @@ -443,7 +451,7 @@ impl Context { None, // TODO: ) })? { - match ctx.rec_get_var_t(ident, AccessKind::Attr, input, namespace) { + match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { Ok(t) => { return Ok(t); } @@ -455,7 +463,7 @@ impl Context { } // TODO: dependent type widening if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - parent.rec_get_attr_t(obj, ident, input, namespace) + parent.rec_get_attr_info(obj, ident, input, namespace) } else { Err(TyCheckError::no_attr_error( input.clone(), @@ -471,32 +479,42 @@ impl Context { /// get type from given attributive type (Record). /// not ModuleType or ClassType etc. - fn get_attr_t_from_attributive( + fn get_attr_info_from_attributive( &self, obj: &hir::Expr, t: &Type, ident: &Identifier, namespace: &Str, - ) -> SingleTyCheckResult { + ) -> SingleTyCheckResult { match t { Type::FreeVar(fv) if fv.is_linked() => { - self.get_attr_t_from_attributive(obj, &fv.crack(), ident, namespace) + self.get_attr_info_from_attributive(obj, &fv.crack(), ident, namespace) } Type::FreeVar(fv) => { let sup = fv.get_sup().unwrap(); - self.get_attr_t_from_attributive(obj, &sup, ident, namespace) + self.get_attr_info_from_attributive(obj, &sup, ident, namespace) } - Type::Ref(t) => self.get_attr_t_from_attributive(obj, t, ident, namespace), + Type::Ref(t) => self.get_attr_info_from_attributive(obj, t, ident, namespace), Type::RefMut { before, .. } => { - self.get_attr_t_from_attributive(obj, before, ident, namespace) + self.get_attr_info_from_attributive(obj, before, ident, namespace) } Type::Refinement(refine) => { - self.get_attr_t_from_attributive(obj, &refine.t, ident, namespace) + self.get_attr_info_from_attributive(obj, &refine.t, ident, namespace) } Type::Record(record) => { // REVIEW: `rec.get(name.inspect())` returns None (Borrow is implemented for Field). Why? - if let Some(attr) = record.get(&Field::new(Public, ident.inspect().clone())) { - Ok(attr.clone()) + if let Some(attr_t) = record.get(&Field::new(Public, ident.inspect().clone())) { + let muty = Mutability::from(&ident.inspect()[..]); + let vi = VarInfo::new( + attr_t.clone(), + muty, + Public, + VarKind::Builtin, + None, + None, + None, + ); + Ok(vi) } else { let t = Type::Record(record.clone()); Err(TyCheckError::no_attr_error( @@ -515,7 +533,18 @@ impl Context { match v { ValueObj::Type(TypeObj::Generated(gen)) => self .get_gen_t_require_attr_t(gen, &ident.inspect()[..]) - .cloned() + .map(|attr_t| { + let muty = Mutability::from(&ident.inspect()[..]); + VarInfo::new( + attr_t.clone(), + muty, + Public, + VarKind::Builtin, + None, + None, + None, + ) + }) .ok_or_else(|| { TyCheckError::dummy(self.cfg.input.clone(), line!() as usize) }), @@ -539,13 +568,13 @@ impl Context { } // returns callee's type, not the return type - fn search_callee_t( + fn search_callee_info( &self, obj: &hir::Expr, attr_name: &Option, input: &Input, namespace: &Str, - ) -> SingleTyCheckResult { + ) -> SingleTyCheckResult { if let Some(attr_name) = attr_name.as_ref() { for ctx in self .get_nominal_super_type_ctxs(obj.ref_t()) @@ -566,7 +595,7 @@ impl Context { .or_else(|| ctx.decls.get(attr_name.inspect())) { self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.t()); + return Ok(vi.clone()); } for (_, methods_ctx) in ctx.methods_list.iter() { if let Some(vi) = methods_ctx @@ -575,7 +604,7 @@ impl Context { .or_else(|| methods_ctx.decls.get(attr_name.inspect())) { self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.t()); + return Ok(vi.clone()); } } } @@ -586,7 +615,7 @@ impl Context { .or_else(|| singular_ctx.decls.get(attr_name.inspect())) { self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.t()); + return Ok(vi.clone()); } for (_, method_ctx) in singular_ctx.methods_list.iter() { if let Some(vi) = method_ctx @@ -595,7 +624,7 @@ impl Context { .or_else(|| method_ctx.decls.get(attr_name.inspect())) { self.validate_visibility(attr_name, vi, input, namespace)?; - return Ok(vi.t()); + return Ok(vi.clone()); } } return Err(TyCheckError::singular_no_attr_error( @@ -610,11 +639,11 @@ impl Context { )); } match self.get_method_type_by_name(attr_name) { - Ok(t) => { - self.sub_unify(obj.ref_t(), &t.definition_type, obj.loc(), None) + Ok(method) => { + self.sub_unify(obj.ref_t(), &method.definition_type, obj.loc(), None) // HACK: change this func's return type to TyCheckResult .map_err(|mut errs| errs.remove(0))?; - return Ok(t.method_type.clone()); + return Ok(method.method_type.clone()); } Err(err) if err.core.kind == ErrorKind::TypeError => { return Err(err); @@ -632,7 +661,10 @@ impl Context { self.get_similar_attr(obj.ref_t(), attr_name.inspect()), )) } else { - Ok(obj.t()) + Ok(VarInfo { + t: obj.t(), + ..VarInfo::default() + }) } } @@ -677,11 +709,11 @@ impl Context { args: &[hir::PosArg], input: &Input, namespace: &Str, - ) -> TyCheckResult { + ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 2); let cont = binop_to_dname(op.inspect()); let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); - let t = self.rec_get_var_t( + let t = self.rec_get_var_info( &Identifier::new(None, VarName::new(symbol.clone())), AccessKind::Name, input, @@ -690,10 +722,11 @@ impl Context { let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|errs| { - let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); + let op_ident = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); + let vi = op_ident.vi.clone(); let lhs = args[0].expr.clone(); let rhs = args[1].expr.clone(); - let bin = hir::BinOp::new(op.name.into_token(), lhs, rhs, op.t); + let bin = hir::BinOp::new(op_ident.name.into_token(), lhs, rhs, vi); TyCheckErrors::new( errs.into_iter() .map(|e| { @@ -718,22 +751,23 @@ impl Context { args: &[hir::PosArg], input: &Input, namespace: &Str, - ) -> TyCheckResult { + ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 1); let cont = unaryop_to_dname(op.inspect()); let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin); - let t = self.rec_get_var_t( + let vi = self.rec_get_var_info( &Identifier::new(None, VarName::new(symbol.clone())), AccessKind::Name, input, namespace, )?; - let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); + let op = hir::Expr::Accessor(hir::Accessor::private(symbol, vi)); self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|errs| { - let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); + let op_ident = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); + let vi = op_ident.vi.clone(); let expr = args[0].expr.clone(); - let unary = hir::UnaryOp::new(op.name.into_token(), expr, op.t); + let unary = hir::UnaryOp::new(op_ident.name.into_token(), expr, vi); TyCheckErrors::new( errs.into_iter() .map(|e| { @@ -819,7 +853,6 @@ impl Context { let attr = hir::Attribute::new( obj.clone(), hir::Identifier::bare(ident.dot.clone(), ident.name.clone()), - Type::Uninited, ); hir::Expr::Accessor(hir::Accessor::Attr(attr)) } @@ -1097,7 +1130,7 @@ impl Context { kw_args: &[hir::KwArg], input: &Input, namespace: &Str, - ) -> TyCheckResult { + ) -> TyCheckResult { if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj { if local.vis().is_private() { match &local.inspect()[..] { @@ -1122,12 +1155,12 @@ impl Context { } } } - let found = self.search_callee_t(obj, attr_name, input, namespace)?; + let found = self.search_callee_info(obj, attr_name, input, namespace)?; log!( "Found:\ncallee: {obj}{}\nfound: {found}", fmt_option!(pre ".", attr_name.as_ref().map(|ident| &ident.name)) ); - let instance = self.instantiate(found, obj)?; + let instance = self.instantiate(found.t, obj)?; log!( "Instantiated:\ninstance: {instance}\npos_args: ({})\nkw_args: ({})", fmt_slice(pos_args), @@ -1139,6 +1172,7 @@ impl Context { log!(info "Params evaluated:\nres: {res}\n"); self.propagate(&res, obj)?; log!(info "Propagated:\nres: {res}\n"); + let res = VarInfo { t: res, ..found }; Ok(res) } @@ -1679,8 +1713,14 @@ impl Context { let path = option_enum_unwrap!(params.remove(0), TyParam::Value:(ValueObj::Str:(_)))?; let path = Path::new(&path[..]); + // TODO: erg std let path = if let Ok(path) = self.cfg.input.resolve(path) { path + } else if let Ok(path) = erg_pystd_path() + .join(format!("{}.d.er", path.display())) + .canonicalize() + { + path } else { PathBuf::from(format!(".{}", path.display())) }; @@ -1805,7 +1845,7 @@ impl Context { } } - fn get_method_type_by_name(&self, name: &Identifier) -> SingleTyCheckResult<&MethodType> { + fn get_method_type_by_name(&self, name: &Identifier) -> SingleTyCheckResult<&MethodInfo> { // TODO: min_by if let Some(candidates) = self.method_to_traits.get(name.inspect()) { let first_method_type = &candidates.first().unwrap().method_type; diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 474c431b..eaa961b0 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -511,9 +511,9 @@ impl Context { ) -> TyCheckResult { // -> Result { let opt_decl_sig_t = self - .rec_get_decl_t(&sig.ident, AccessKind::Name, &self.cfg.input, &self.name) + .rec_get_decl_info(&sig.ident, AccessKind::Name, &self.cfg.input, &self.name) .ok() - .map(|t| enum_unwrap!(t, Type::Subr)); + .map(|vi| enum_unwrap!(vi.t, Type::Subr)); let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; let tv_ctx = TyVarInstContext::new(self.level, bounds, self); let mut non_defaults = vec![]; diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 80547feb..2fbce08d 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -299,23 +299,23 @@ pub struct ContextInfo { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct MethodType { +pub struct MethodInfo { definition_type: Type, - method_type: Type, + method_type: VarInfo, } -impl fmt::Display for MethodType { +impl fmt::Display for MethodInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "{{ def: {} t: {} }}", + "{{ def: {} info: {} }}", self.definition_type, self.method_type ) } } -impl MethodType { - pub const fn new(definition_type: Type, method_type: Type) -> Self { +impl MethodInfo { + pub const fn new(definition_type: Type, method_type: VarInfo) -> Self { Self { definition_type, method_type, @@ -345,8 +345,8 @@ pub struct Context { pub(crate) methods_list: Vec<(ClassDefType, Context)>, // K: method name, V: types defines the method // If it is declared in a trait, it takes precedence over the class. - pub(crate) method_to_traits: Dict>, - pub(crate) method_to_classes: Dict>, + pub(crate) method_to_traits: Dict>, + pub(crate) method_to_classes: Dict>, /// K: method name, V: impl patch /// Provided methods can switch implementations on a scope-by-scope basis /// K: メソッド名, V: それを実装するパッチたち @@ -462,13 +462,13 @@ impl Context { let idx = ParamIdx::Nth(idx); let kind = VarKind::parameter(id, idx, param.default_info); let muty = Mutability::from(name); - let vi = VarInfo::new(param.t, muty, Private, kind, None, None); + let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None); params_.push((Some(VarName::new(Token::static_symbol(name))), vi)); } else { let idx = ParamIdx::Nth(idx); let kind = VarKind::parameter(id, idx, param.default_info); let muty = Mutability::Immutable; - let vi = VarInfo::new(param.t, muty, Private, kind, None, None); + let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None); params_.push((None, vi)); } } diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 5f74cbbf..8b2b82b0 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use crate::ty::free::HasLevel; use erg_common::config::{ErgConfig, Input}; +use erg_common::env::erg_pystd_path; use erg_common::levenshtein::get_similar_name; use erg_common::python_util::BUILTIN_PYTHON_MODS; use erg_common::set::Set; @@ -21,7 +22,7 @@ use crate::ty::{HasType, ParamTy, SubrType, Type}; use crate::build_hir::HIRBuilder; use crate::context::{ - ClassDefType, Context, ContextKind, DefaultInfo, MethodType, RegistrationMode, TraitInstance, + ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, RegistrationMode, TraitInstance, }; use crate::error::readable_name; use crate::error::{ @@ -86,7 +87,7 @@ impl Context { } else { self.decls.insert( ident.name.clone(), - VarInfo::new(sig_t, muty, vis, kind, None, self.impl_of()), + VarInfo::new(sig_t, muty, vis, kind, None, self.impl_of(), None), ); Ok(()) } @@ -122,11 +123,20 @@ impl Context { kind.clone(), Some(comptime_decos.clone()), self.impl_of(), + None, ); self.decls.insert(sig.ident.name.clone(), vi); e })?; - let vi = VarInfo::new(t, muty, vis, kind, Some(comptime_decos), self.impl_of()); + let vi = VarInfo::new( + t, + muty, + vis, + kind, + Some(comptime_decos), + self.impl_of(), + None, + ); if let Some(_decl) = self.decls.remove(name) { Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error( self.cfg.input.clone(), @@ -146,6 +156,7 @@ impl Context { sig: &ast::VarSignature, body_t: &Type, id: DefId, + py_name: Option, ) -> TyCheckResult<()> { let ident = match &sig.pat { ast::VarPattern::Ident(ident) => ident, @@ -169,6 +180,7 @@ impl Context { VarKind::Defined(id), None, self.impl_of(), + py_name, ); log!(info "Registered {}::{}: {} {:?}", self.name, ident.name, vi.t, vi.impl_of); self.locals.insert(ident.name.clone(), vi); @@ -220,7 +232,7 @@ impl Context { let muty = Mutability::from(&name.inspect()[..]); self.params.push(( Some(name.clone()), - VarInfo::new(spec_t, muty, Private, kind, None, None), + VarInfo::new(spec_t, muty, Private, kind, None, None, None), )); Ok(()) } @@ -259,7 +271,7 @@ impl Context { VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default); self.params.push(( Some(name.clone()), - VarInfo::new(spec_t, Immutable, Private, kind, None, None), + VarInfo::new(spec_t, Immutable, Private, kind, None, None, None), )); Ok(()) } @@ -298,7 +310,7 @@ impl Context { VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default); self.params.push(( Some(name.clone()), - VarInfo::new(spec_t, Immutable, Private, kind, None, None), + VarInfo::new(spec_t, Immutable, Private, kind, None, None, None), )); Ok(()) } @@ -461,6 +473,7 @@ impl Context { VarKind::Defined(id), Some(comptime_decos), self.impl_of(), + None, ); let t = vi.t.clone(); log!(info "Registered {}::{name}: {t}", self.name); @@ -498,6 +511,7 @@ impl Context { VarKind::DoesNotExist, Some(comptime_decos), self.impl_of(), + None, ); log!(info "Registered {}::{name}: {}", self.name, &vi.t); self.locals.insert(name.clone(), vi); @@ -582,6 +596,7 @@ impl Context { t: Type, muty: Mutability, vis: Visibility, + py_name: Option, ) { let name = VarName::from_static(name); if self.locals.get(&name).is_some() { @@ -589,7 +604,7 @@ impl Context { } else { self.locals.insert( name, - VarInfo::new(t, muty, vis, VarKind::Auto, None, self.impl_of()), + VarInfo::new(t, muty, vis, VarKind::Auto, None, self.impl_of(), py_name), ); } } @@ -601,6 +616,7 @@ impl Context { t: Type, muty: Mutability, vis: Visibility, + py_name: Option, ) { let name = VarName::from_static(name); if self.locals.get(&name).is_some() { @@ -608,7 +624,15 @@ impl Context { } else { self.locals.insert( name, - VarInfo::new(t, muty, vis, VarKind::FixedAuto, None, self.impl_of()), + VarInfo::new( + t, + muty, + vis, + VarKind::FixedAuto, + None, + self.impl_of(), + py_name, + ), ); } } @@ -619,13 +643,14 @@ impl Context { t: Type, vis: Visibility, impl_of: Option, + py_name: Option, ) { if self.decls.get(&name).is_some() { panic!("already registered: {name}"); } else { self.decls.insert( name, - VarInfo::new(t, Immutable, vis, VarKind::Declared, None, impl_of), + VarInfo::new(t, Immutable, vis, VarKind::Declared, None, impl_of, py_name), ); } } @@ -637,6 +662,7 @@ impl Context { muty: Mutability, vis: Visibility, impl_of: Option, + py_name: Option, ) { if self.locals.get(&name).is_some() { panic!("already registered: {name}"); @@ -644,7 +670,7 @@ impl Context { let id = DefId(get_hash(&(&self.name, &name))); self.locals.insert( name, - VarInfo::new(t, muty, vis, VarKind::Defined(id), None, impl_of), + VarInfo::new(t, muty, vis, VarKind::Defined(id), None, impl_of, py_name), ); } } @@ -697,6 +723,7 @@ impl Context { VarKind::Defined(id), None, self.impl_of(), + None, ); self.decls.insert(ident.name.clone(), vi); self.consts.insert(ident.name.clone(), other); @@ -729,9 +756,15 @@ impl Context { ); let require = gen.require_or_sup.typ().clone(); let new_t = func1(require, gen.t.clone()); - methods.register_fixed_auto_impl("__new__", new_t.clone(), Immutable, Private); + methods.register_fixed_auto_impl( + "__new__", + new_t.clone(), + Immutable, + Private, + Some("__call__".into()), + ); // 必要なら、ユーザーが独自に上書きする - methods.register_auto_impl("new", new_t, Immutable, Public); + methods.register_auto_impl("new", new_t, Immutable, Public, None); ctx.methods_list .push((ClassDefType::Simple(gen.t.clone()), methods)); self.register_gen_mono_type(ident, gen, ctx, Const); @@ -786,9 +819,10 @@ impl Context { new_t.clone(), Immutable, Private, + Some("__call__".into()), ); // 必要なら、ユーザーが独自に上書きする - methods.register_auto_impl("new", new_t, Immutable, Public); + methods.register_auto_impl("new", new_t, Immutable, Public, None); ctx.methods_list .push((ClassDefType::Simple(gen.t.clone()), methods)); self.register_gen_mono_type(ident, gen, ctx, Const); @@ -823,6 +857,7 @@ impl Context { VarKind::Declared, None, self.impl_of(), + None, ); ctx.decls .insert(VarName::from_str(field.symbol.clone()), vi); @@ -859,6 +894,7 @@ impl Context { VarKind::Declared, None, self.impl_of(), + None, ); ctx.decls .insert(VarName::from_str(field.symbol.clone()), vi); @@ -895,6 +931,7 @@ impl Context { VarKind::Defined(id), None, self.impl_of(), + None, ), ); self.consts @@ -929,6 +966,7 @@ impl Context { VarKind::Defined(id), None, self.impl_of(), + None, ), ); self.consts @@ -945,21 +983,21 @@ impl Context { } for (trait_method, vi) in ctx.decls.iter() { if let Some(types) = self.method_to_traits.get_mut(trait_method.inspect()) { - types.push(MethodType::new(t.clone(), vi.t.clone())); + types.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_traits.insert( trait_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } for (class_method, vi) in ctx.locals.iter() { if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) { - types.push(MethodType::new(t.clone(), vi.t.clone())); + types.push(MethodInfo::new(t.clone(), vi.clone())); } else { self.method_to_classes.insert( class_method.inspect().clone(), - vec![MethodType::new(t.clone(), vi.t.clone())], + vec![MethodInfo::new(t.clone(), vi.clone())], ); } } @@ -973,24 +1011,24 @@ impl Context { mod_name: &Literal, ) -> CompileResult { if kind.is_erg_import() { - self.import_erg_mod(mod_name) + self.import_erg_mod_using_cache(mod_name) } else { - self.import_py_mod(mod_name) + self.import_py_mod_using_cache(mod_name) } } - fn import_erg_mod(&mut self, mod_name: &Literal) -> CompileResult { + fn import_erg_mod_using_cache(&mut self, mod_name: &Literal) -> CompileResult { let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str); let mod_cache = self.mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); #[allow(clippy::match_single_binding)] match &__name__[..] { // TODO: erg builtin modules - _ => self.import_user_erg_mod(__name__, mod_name, mod_cache, py_mod_cache), + _ => self.import_erg_mod(__name__, mod_name, mod_cache, py_mod_cache), } } - fn import_user_erg_mod( + fn import_erg_mod( &self, __name__: Str, mod_name: &Literal, @@ -1045,13 +1083,14 @@ impl Context { Ok(path) } - fn import_py_mod(&mut self, mod_name: &Literal) -> CompileResult { + fn import_py_mod_using_cache(&mut self, mod_name: &Literal) -> CompileResult { let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str); let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); let builtin_path = PathBuf::from(&format!(".{__name__}")); if py_mod_cache.get(&builtin_path).is_some() { return Ok(builtin_path); } + // TODO: rewrite all as `d.er` match &__name__[..] { "glob" => { py_mod_cache.register(builtin_path.clone(), None, Self::init_py_glob_mod()); @@ -1097,7 +1136,7 @@ impl Context { py_mod_cache.register(builtin_path.clone(), None, Self::init_py_urllib_mod()); Ok(builtin_path) } - _ => self.import_user_py_mod(mod_name), + _ => self.import_py_mod(mod_name), } } @@ -1105,8 +1144,15 @@ impl Context { get_similar_name(BUILTIN_PYTHON_MODS.into_iter(), name).map(Str::rc) } - fn import_user_py_mod(&self, mod_name: &Literal) -> CompileResult { + fn find_decl_in_pystd(__name__: &str) -> std::io::Result { + let mut as_std_path = erg_pystd_path().join(__name__); + as_std_path.set_extension("d.er"); + as_std_path.canonicalize() + } + + fn import_py_mod(&self, mod_name: &Literal) -> CompileResult { let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str); + let mod_cache = self.mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { path.pop(); @@ -1115,7 +1161,10 @@ impl Context { PathBuf::new() }; dir.push(format!("{__name__}.d.er")); - let path = match dir.canonicalize() { + let path = match dir + .canonicalize() + .or_else(|_| Self::find_decl_in_pystd(&__name__)) + { Ok(path) => path, Err(err) => { let err = TyCheckError::import_error( @@ -1137,10 +1186,11 @@ impl Context { let cfg = ErgConfig::with_module_path(path.clone()); let src = cfg.input.read(); let mut builder = - HIRBuilder::new_with_cache(cfg, __name__, py_mod_cache.clone(), py_mod_cache.clone()); + HIRBuilder::new_with_cache(cfg, __name__, mod_cache.clone(), py_mod_cache.clone()); match builder.build(src, "declare") { Ok(hir) => { - py_mod_cache.register(path.clone(), Some(hir), builder.pop_mod_ctx()); + let ctx = builder.pop_mod_ctx(); + py_mod_cache.register(path.clone(), Some(hir), ctx); } Err((maybe_hir, errs)) => { if let Some(hir) = maybe_hir { diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 2ccfbdea..2cc80a51 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -731,21 +731,8 @@ impl Context { let loc = acc.loc(); let t = acc.ref_mut_t(); *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; - match acc { - hir::Accessor::Attr(attr) => { - self.resolve_expr_t(&mut attr.obj)?; - } - hir::Accessor::TupleAttr(attr) => { - self.resolve_expr_t(&mut attr.obj)?; - } - hir::Accessor::Subscr(subscr) => { - self.resolve_expr_t(&mut subscr.obj)?; - self.resolve_expr_t(&mut subscr.index)?; - } - hir::Accessor::Ident(ident) => { - ident.t = - self.deref_tyvar(mem::take(&mut ident.t), Covariant, ident.loc())?; - } + if let hir::Accessor::Attr(attr) = acc { + self.resolve_expr_t(&mut attr.obj)?; } Ok(()) } @@ -839,8 +826,9 @@ impl Context { } hir::Expr::Call(call) => { let loc = call.loc(); - let t = call.signature_mut_t().unwrap(); - *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; + if let Some(t) = call.signature_mut_t() { + *t = self.deref_tyvar(mem::take(t), Covariant, loc)?; + } self.resolve_expr_t(&mut call.obj)?; for arg in call.args.pos_args.iter_mut() { self.resolve_expr_t(&mut arg.expr)?; diff --git a/compiler/erg_compiler/desugar_hir.rs b/compiler/erg_compiler/desugar_hir.rs index 575920bb..1c3bb47b 100644 --- a/compiler/erg_compiler/desugar_hir.rs +++ b/compiler/erg_compiler/desugar_hir.rs @@ -2,7 +2,6 @@ use erg_common::log; use erg_common::traits::Stream; use crate::hir::{Accessor, AttrDef, Block, Expr, HIR}; -use crate::ty::Type; pub struct HIRDesugarer {} @@ -19,9 +18,10 @@ impl HIRDesugarer { // _Self = C // a = C.x // x = 1 + // m(self) = ... // ↓ // class C: - // pass + // def m(self): ... // C._Self = C // C.a = C.x // C.x = 1 @@ -39,11 +39,7 @@ impl HIRDesugarer { .into_iter() .map(|expr| match expr { Expr::Def(def) => { - let acc = Accessor::attr( - class.clone(), - def.sig.into_ident(), - Type::Untyped, - ); + let acc = Accessor::attr(class.clone(), def.sig.into_ident()); let attr_def = AttrDef::new(acc, def.body.block); Expr::AttrDef(attr_def) } diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index c8aa948a..3634e7a2 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -226,7 +226,7 @@ impl SideEffectChecker { if i == last_idx && self.block_stack.last().unwrap() == &Instant && !def.sig.is_procedural() - && chunk.t().is_procedural() + && chunk.t().is_procedure() { self.errs.push(EffectError::proc_assign_error( self.cfg.input.clone(), @@ -324,7 +324,7 @@ impl SideEffectChecker { }, // 引数がproceduralでも関数呼び出しなら副作用なし Expr::Call(call) => { - if (call.obj.t().is_procedural() + if (call.obj.t().is_procedure() || call .attr_name .as_ref() diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 9eae5ddd..085eb319 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -23,6 +23,7 @@ use crate::ty::{HasType, Type}; use crate::context::eval::type_from_token_kind; use crate::context::OperationKind; use crate::error::readable_name; +use crate::varinfo::VarInfo; use crate::{impl_t, impl_t_for_enum}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -310,7 +311,7 @@ pub struct Identifier { pub dot: Option, pub name: VarName, pub qual_name: Option, - pub t: Type, + pub vi: VarInfo, } impl NestedDisplay for Identifier { @@ -326,15 +327,33 @@ impl NestedDisplay for Identifier { if let Some(qn) = &self.qual_name { write!(f, "(qual_name: {})", qn)?; } - if self.t != Type::Uninited { - write!(f, "(: {})", self.t)?; + if self.vi.t != Type::Uninited { + write!(f, "(: {})", self.vi.t)?; } Ok(()) } } impl_display_from_nested!(Identifier); -impl_t!(Identifier); + +impl HasType for Identifier { + #[inline] + fn ref_t(&self) -> &Type { + &self.vi.t + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + &mut self.vi.t + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + None + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + None + } +} impl Locational for Identifier { fn loc(&self) -> Location { @@ -353,12 +372,17 @@ impl From<&Identifier> for Field { } impl Identifier { - pub const fn new(dot: Option, name: VarName, qual_name: Option, t: Type) -> Self { + pub const fn new( + dot: Option, + name: VarName, + qual_name: Option, + vi: VarInfo, + ) -> Self { Self { dot, name, qual_name, - t, + vi, } } @@ -382,7 +406,7 @@ impl Identifier { } pub const fn bare(dot: Option, name: VarName) -> Self { - Self::new(dot, name, None, Type::Uninited) + Self::new(dot, name, None, VarInfo::const_default()) } pub fn is_const(&self) -> bool { @@ -413,84 +437,41 @@ impl Identifier { pub struct Attribute { pub obj: Box, pub ident: Identifier, - t: Type, } impl NestedDisplay for Attribute { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - if self.t != Type::Uninited { - write!(f, "({}){}(: {})", self.obj, self.ident, self.t) - } else { - write!(f, "({}){}", self.obj, self.ident) - } + write!(f, "({}){}", self.obj, self.ident) } } impl_display_from_nested!(Attribute); impl_locational!(Attribute, obj, ident); -impl_t!(Attribute); + +impl HasType for Attribute { + #[inline] + fn ref_t(&self) -> &Type { + self.ident.ref_t() + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + self.ident.ref_mut_t() + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + self.ident.signature_t() + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + self.ident.signature_mut_t() + } +} impl Attribute { - pub fn new(obj: Expr, ident: Identifier, t: Type) -> Self { + pub fn new(obj: Expr, ident: Identifier) -> Self { Self { obj: Box::new(obj), ident, - t, - } - } -} - -/// e.g. obj.0, obj.1 -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct TupleAttribute { - pub obj: Box, - pub index: Literal, - t: Type, -} - -impl NestedDisplay for TupleAttribute { - fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result { - write!(f, "({}).{}", self.obj, self.index) - } -} - -impl_display_from_nested!(TupleAttribute); -impl_locational!(TupleAttribute, obj, index); -impl_t!(TupleAttribute); - -impl TupleAttribute { - pub fn new(obj: Expr, index: Literal, t: Type) -> Self { - Self { - obj: Box::new(obj), - index, - t, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Subscript { - pub(crate) obj: Box, - pub(crate) index: Box, - t: Type, -} - -impl NestedDisplay for Subscript { - fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - write!(f, "({})[{}](: {})", self.obj, self.index, self.t) - } -} - -impl_display_from_nested!(Subscript); -impl_locational!(Subscript, obj, index); -impl_t!(Subscript); - -impl Subscript { - pub fn new(obj: Expr, index: Expr, t: Type) -> Self { - Self { - obj: Box::new(obj), - index: Box::new(index), - t, } } } @@ -499,14 +480,12 @@ impl Subscript { pub enum Accessor { Ident(Identifier), Attr(Attribute), - TupleAttr(TupleAttribute), - Subscr(Subscript), } -impl_nested_display_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr); +impl_nested_display_for_enum!(Accessor; Ident, Attr); impl_display_from_nested!(Accessor); -impl_locational_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr); -impl_t_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr); +impl_locational_for_enum!(Accessor; Ident, Attr); +impl_t_for_enum!(Accessor; Ident, Attr); impl Accessor { pub fn private_with_line(name: Str, line: usize) -> Self { @@ -517,25 +496,21 @@ impl Accessor { Self::Ident(Identifier::public_with_line(Token::dummy(), name, line)) } - pub const fn private(name: Token, t: Type) -> Self { - Self::Ident(Identifier::new(None, VarName::new(name), None, t)) + pub const fn private(name: Token, vi: VarInfo) -> Self { + Self::Ident(Identifier::new(None, VarName::new(name), None, vi)) } - pub fn public(name: Token, t: Type) -> Self { + pub fn public(name: Token, vi: VarInfo) -> Self { Self::Ident(Identifier::new( Some(Token::dummy()), VarName::new(name), None, - t, + vi, )) } - pub fn attr(obj: Expr, ident: Identifier, t: Type) -> Self { - Self::Attr(Attribute::new(obj, ident, t)) - } - - pub fn subscr(obj: Expr, index: Expr, t: Type) -> Self { - Self::Subscr(Subscript::new(obj, index, t)) + pub fn attr(obj: Expr, ident: Identifier) -> Self { + Self::Attr(Attribute::new(obj, ident)) } pub fn show(&self) -> String { @@ -548,15 +523,6 @@ impl Accessor { + "." // TODO: visibility + readable_name(attr.ident.inspect()) } - Self::TupleAttr(t_attr) => { - t_attr - .obj - .show_acc() - .unwrap_or_else(|| t_attr.obj.ref_t().to_string()) - + "." - + t_attr.index.token.inspect() - } - Self::Subscr(_) => todo!(), } } @@ -976,12 +942,12 @@ pub struct BinOp { pub op: Token, pub lhs: Box, pub rhs: Box, - pub sig_t: Type, // e.g. (Int, Int) -> Int + pub info: VarInfo, // e.g. (Int, Int) -> Int } impl NestedDisplay for BinOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - writeln!(f, "`{}`(: {}):", self.op.content, self.sig_t)?; + writeln!(f, "`{}`(: {}):", self.op.content, self.info.t)?; self.lhs.fmt_nest(f, level + 1)?; writeln!(f)?; self.rhs.fmt_nest(f, level + 1) @@ -991,26 +957,26 @@ impl NestedDisplay for BinOp { impl HasType for BinOp { #[inline] fn ref_t(&self) -> &Type { - self.sig_t.return_t().unwrap() + self.info.t.return_t().unwrap() } fn ref_mut_t(&mut self) -> &mut Type { - self.sig_t.mut_return_t().unwrap() + self.info.t.mut_return_t().unwrap() } #[inline] fn lhs_t(&self) -> &Type { - self.sig_t.lhs_t() + self.info.t.lhs_t() } #[inline] fn rhs_t(&self) -> &Type { - self.sig_t.rhs_t() + self.info.t.rhs_t() } #[inline] fn signature_t(&self) -> Option<&Type> { - Some(&self.sig_t) + Some(&self.info.t) } #[inline] fn signature_mut_t(&mut self) -> Option<&mut Type> { - Some(&mut self.sig_t) + Some(&mut self.info.t) } } @@ -1018,12 +984,12 @@ impl_display_from_nested!(BinOp); impl_locational!(BinOp, lhs, rhs); impl BinOp { - pub fn new(op: Token, lhs: Expr, rhs: Expr, sig_t: Type) -> Self { + pub fn new(op: Token, lhs: Expr, rhs: Expr, info: VarInfo) -> Self { Self { op, lhs: Box::new(lhs), rhs: Box::new(rhs), - sig_t, + info, } } } @@ -1032,16 +998,16 @@ impl BinOp { pub struct UnaryOp { pub op: Token, pub expr: Box, - pub sig_t: Type, // e.g. Neg -> Nat + pub info: VarInfo, // e.g. Neg -> Nat } impl HasType for UnaryOp { #[inline] fn ref_t(&self) -> &Type { - self.sig_t.return_t().unwrap() + self.info.t.return_t().unwrap() } fn ref_mut_t(&mut self) -> &mut Type { - self.sig_t.mut_return_t().unwrap() + self.info.t.mut_return_t().unwrap() } #[inline] fn lhs_t(&self) -> &Type { @@ -1053,17 +1019,17 @@ impl HasType for UnaryOp { } #[inline] fn signature_t(&self) -> Option<&Type> { - Some(&self.sig_t) + Some(&self.info.t) } #[inline] fn signature_mut_t(&mut self) -> Option<&mut Type> { - Some(&mut self.sig_t) + Some(&mut self.info.t) } } impl NestedDisplay for UnaryOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - writeln!(f, "`{}`(: {}):", self.op, self.sig_t)?; + writeln!(f, "`{}`(: {}):", self.op, self.info.t)?; self.expr.fmt_nest(f, level + 1) } } @@ -1072,11 +1038,11 @@ impl_display_from_nested!(UnaryOp); impl_locational!(UnaryOp, op, expr); impl UnaryOp { - pub fn new(op: Token, expr: Expr, sig_t: Type) -> Self { + pub fn new(op: Token, expr: Expr, info: VarInfo) -> Self { Self { op, expr: Box::new(expr), - sig_t, + info, } } } @@ -1086,19 +1052,11 @@ pub struct Call { pub obj: Box, pub attr_name: Option, pub args: Args, - /// 全体の型(引数自体の型は関係ない)、e.g. `abs(-1)` -> `(self: Neg) -> Nat` - pub sig_t: Type, } impl NestedDisplay for Call { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result { - writeln!( - f, - "({}){} (: {}):", - self.obj, - fmt_option!(self.attr_name), - self.sig_t - )?; + writeln!(f, "({}){}:", self.obj, fmt_option!(self.attr_name),)?; self.args.fmt_nest(f, level + 1) } } @@ -1108,27 +1066,51 @@ impl_display_from_nested!(Call); impl HasType for Call { #[inline] fn ref_t(&self) -> &Type { - self.sig_t.return_t().unwrap() + if let Some(attr) = self.attr_name.as_ref() { + attr.ref_t().return_t().unwrap() + } else { + self.obj.ref_t().return_t().unwrap() + } } #[inline] fn ref_mut_t(&mut self) -> &mut Type { - self.sig_t.mut_return_t().unwrap() + if let Some(attr) = self.attr_name.as_mut() { + attr.ref_mut_t().mut_return_t().unwrap() + } else { + self.obj.ref_mut_t().mut_return_t().unwrap() + } } #[inline] fn lhs_t(&self) -> &Type { - self.sig_t.lhs_t() + if let Some(attr) = self.attr_name.as_ref() { + attr.ref_t().lhs_t() + } else { + self.obj.lhs_t() + } } #[inline] fn rhs_t(&self) -> &Type { - self.sig_t.rhs_t() + if let Some(attr) = self.attr_name.as_ref() { + attr.ref_t().rhs_t() + } else { + self.obj.rhs_t() + } } #[inline] fn signature_t(&self) -> Option<&Type> { - Some(&self.sig_t) + if let Some(attr) = self.attr_name.as_ref() { + Some(attr.ref_t()) + } else { + Some(self.obj.ref_t()) + } } #[inline] fn signature_mut_t(&mut self) -> Option<&mut Type> { - Some(&mut self.sig_t) + if let Some(attr) = self.attr_name.as_mut() { + Some(attr.ref_mut_t()) + } else { + Some(self.obj.ref_mut_t()) + } } } @@ -1139,17 +1121,18 @@ impl Locational for Call { } impl Call { - pub fn new(obj: Expr, attr_name: Option, args: Args, sig_t: Type) -> Self { + pub fn new(obj: Expr, attr_name: Option, args: Args) -> Self { Self { obj: Box::new(obj), attr_name, args, - sig_t, } } - pub fn is_method(&self) -> bool { - self.sig_t.self_t().is_some() + pub fn is_method_call(&self) -> bool { + self.signature_t() + .map(|t| t.self_t().is_some()) + .unwrap_or(false) } pub fn additional_operation(&self) -> Option { diff --git a/compiler/erg_compiler/lib/pystd/subprocess.d.er b/compiler/erg_compiler/lib/pystd/subprocess.d.er new file mode 100644 index 00000000..fc758920 --- /dev/null +++ b/compiler/erg_compiler/lib/pystd/subprocess.d.er @@ -0,0 +1 @@ +.run!: (args: Str or [Str; _], shell := Bool) => NoneType diff --git a/compiler/erg_compiler/lib/std/_erg_std_prelude.py b/compiler/erg_compiler/lib/std/_erg_std_prelude.py index d72e5ec7..1b5dbea0 100644 --- a/compiler/erg_compiler/lib/std/_erg_std_prelude.py +++ b/compiler/erg_compiler/lib/std/_erg_std_prelude.py @@ -62,6 +62,9 @@ class Bool(Nat): def __repr__(self) -> str: return self.__str__() +class Str(str): + pass + class Range: def __init__(self, start, end): self.start = start diff --git a/compiler/erg_compiler/lib/std/subprocess.d.er b/compiler/erg_compiler/lib/std/subprocess.d.er deleted file mode 100644 index 0e9d9ae1..00000000 --- a/compiler/erg_compiler/lib/std/subprocess.d.er +++ /dev/null @@ -1 +0,0 @@ -.run!: (args: Str,) => NoneType diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index f6600203..bbe763b6 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -45,13 +45,6 @@ impl<'a> Linker<'a> { Accessor::Attr(attr) => { self.replace_import(&mut attr.obj); } - Accessor::TupleAttr(attr) => { - self.replace_import(&mut attr.obj); - } - Accessor::Subscr(subscr) => { - self.replace_import(&mut subscr.obj); - self.replace_import(&mut subscr.index); - } Accessor::Ident(_) => {} }, Expr::Array(array) => match array { @@ -192,12 +185,7 @@ impl<'a> Linker<'a> { let module_type = Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line)); let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None); - let block = Block::new(vec![Expr::Call(Call::new( - module_type, - None, - args, - Type::Uninited, - ))]); + let block = Block::new(vec![Expr::Call(Call::new(module_type, None, args))]); let tmp = Identifier::private_with_line(Str::from(fresh_varname()), expr.ln_begin().unwrap()); let mod_def = Expr::Def(Def::new( @@ -206,15 +194,14 @@ impl<'a> Linker<'a> { )); let module = Expr::Accessor(Accessor::Ident(tmp)); let __dict__ = Identifier::public("__dict__"); - let m_dict = Expr::Accessor(Accessor::attr(module.clone(), __dict__, Type::Uninited)); + let m_dict = Expr::Accessor(Accessor::attr(module.clone(), __dict__)); let locals = Expr::Accessor(Accessor::public_with_line(Str::ever("locals"), line)); - let locals_call = Expr::Call(Call::new(locals, None, Args::empty(), Type::Uninited)); + let locals_call = Expr::Call(Call::new(locals, None, Args::empty())); let args = Args::new(vec![PosArg::new(locals_call)], None, vec![], None); let mod_update = Expr::Call(Call::new( m_dict.clone(), Some(Identifier::public("update")), args, - Type::Uninited, )); let exec = Expr::Accessor(Accessor::public_with_line(Str::ever("exec"), line)); let args = Args::new( @@ -223,7 +210,7 @@ impl<'a> Linker<'a> { vec![], None, ); - let exec_code = Expr::Call(Call::new(exec, None, args, Type::Uninited)); + let exec_code = Expr::Call(Call::new(exec, None, args)); let compound = Block::new(vec![mod_def, mod_update, exec_code, module]); *expr = Expr::Compound(compound); } @@ -277,7 +264,6 @@ impl<'a> Linker<'a> { Str::rc(attr.as_os_str().to_str().unwrap()), line, ), - Type::Uninited, )); } } diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index e0a98822..2e619569 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -571,49 +571,32 @@ impl ASTLowerer { } ast::Accessor::Attr(attr) => { let obj = self.lower_expr(*attr.obj)?; - let t = - self.ctx - .rec_get_attr_t(&obj, &attr.ident, &self.cfg.input, &self.ctx.name)?; - let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); - let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t)); - Ok(acc) - } - ast::Accessor::TupleAttr(t_attr) => { - let obj = self.lower_expr(*t_attr.obj)?; - let index = self.lower_literal(t_attr.index)?; - let n = enum_unwrap!(index.value, ValueObj::Nat); - let t = enum_unwrap!( - obj.ref_t().typarams().get(n as usize).unwrap().clone(), - TyParam::Type - ); - let acc = hir::Accessor::TupleAttr(hir::TupleAttribute::new(obj, index, *t)); - Ok(acc) - } - ast::Accessor::Subscr(subscr) => { - let obj = self.lower_expr(*subscr.obj)?; - let index = self.lower_expr(*subscr.index)?; - // FIXME: 配列とは限らない! - let t = enum_unwrap!( - obj.ref_t().typarams().get(0).unwrap().clone(), - TyParam::Type - ); - let acc = hir::Accessor::Subscr(hir::Subscript::new(obj, index, *t)); + let vi = self.ctx.rec_get_attr_info( + &obj, + &attr.ident, + &self.cfg.input, + &self.ctx.name, + )?; + let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); + let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident)); Ok(acc) } ast::Accessor::TypeApp(_t_app) => { todo!() } + // TupleAttr, Subscr are desugared + _ => unreachable!(), } } fn lower_ident(&self, ident: ast::Identifier) -> LowerResult { // `match` is an untypable special form // `match`は型付け不可能な特殊形式 - let (t, __name__) = if ident.vis().is_private() && &ident.inspect()[..] == "match" { - (Type::Untyped, None) + let (vi, __name__) = if ident.vis().is_private() && &ident.inspect()[..] == "match" { + (VarInfo::default(), None) } else { ( - self.ctx.rec_get_var_t( + self.ctx.rec_get_var_info( &ident, AccessKind::Name, &self.cfg.input, @@ -625,7 +608,7 @@ impl ASTLowerer { .map(|ctx| ctx.name.clone()), ) }; - let ident = hir::Identifier::new(ident.dot, ident.name, __name__, t); + let ident = hir::Identifier::new(ident.dot, ident.name, __name__, vi); Ok(ident) } @@ -691,8 +674,8 @@ impl ASTLowerer { for arg in kw_args.into_iter() { hir_args.push_kw(hir::KwArg::new(arg.keyword, self.lower_expr(arg.expr)?)); } - let obj = self.lower_expr(*call.obj)?; - let sig_t = self.ctx.get_call_t( + let mut obj = self.lower_expr(*call.obj)?; + let vi = self.ctx.get_call_t( &obj, &call.attr_name, &hir_args.pos_args, @@ -705,12 +688,13 @@ impl ASTLowerer { attr_name.dot, attr_name.name, None, - Type::Uninited, + vi, )) } else { + *obj.ref_mut_t() = vi.t; None }; - let mut call = hir::Call::new(obj, attr_name, hir_args, sig_t); + let mut call = hir::Call::new(obj, attr_name, hir_args); match call.additional_operation() { Some(kind @ (OperationKind::Import | OperationKind::PyImport)) => { let mod_name = @@ -762,7 +746,7 @@ impl ASTLowerer { pack.connector.col_begin, )), ); - let sig_t = self.ctx.get_call_t( + let vi = self.ctx.get_call_t( &class, &Some(attr_name.clone()), &args, @@ -771,8 +755,8 @@ impl ASTLowerer { &self.ctx.name, )?; let args = hir::Args::new(args, None, vec![], None); - let attr_name = hir::Identifier::bare(attr_name.dot, attr_name.name); - Ok(hir::Call::new(class, Some(attr_name), args, sig_t)) + let attr_name = hir::Identifier::new(attr_name.dot, attr_name.name, None, vi); + Ok(hir::Call::new(class, Some(attr_name), args)) } /// TODO: varargs @@ -927,11 +911,12 @@ impl ASTLowerer { } } } - self.ctx - .outer - .as_mut() - .unwrap() - .assign_var_sig(&sig, found_body_t, body.id)?; + self.ctx.outer.as_mut().unwrap().assign_var_sig( + &sig, + found_body_t, + body.id, + None, + )?; let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); let sig = hir::VarSignature::new(ident, found_body_t.clone()); let body = hir::DefBody::new(body.op, block, body.id); @@ -942,6 +927,7 @@ impl ASTLowerer { &sig, &Type::Failure, ast::DefId(0), + None, )?; Err(errs) } @@ -1463,14 +1449,20 @@ impl ASTLowerer { self.ctx.caused_by(), ))); } - let block = hir::Block::new(vec![self.declare_chunk(body.block.remove(0))?]); + let chunk = self.declare_chunk(body.block.remove(0))?; + let acc = enum_unwrap!( + enum_unwrap!(&chunk, hir::Expr::TypeAsc).expr.as_ref(), + hir::Expr::Accessor + ); + let py_name = acc.local_name().map(Str::rc); + let block = hir::Block::new(vec![chunk]); let found_body_t = block.ref_t(); let ident = match &sig.pat { ast::VarPattern::Ident(ident) => ident, _ => unreachable!(), }; let id = body.id; - self.ctx.assign_var_sig(&sig, found_body_t, id)?; + self.ctx.assign_var_sig(&sig, found_body_t, id, py_name)?; let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); let sig = hir::VarSignature::new(ident, found_body_t.clone()); let body = hir::DefBody::new(body.op, block, body.id); @@ -1515,7 +1507,7 @@ impl ASTLowerer { ast::Expr::Accessor(ast::Accessor::Attr(attr)) => { let obj = self.fake_lower_obj(*attr.obj)?; let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); - let acc = hir::Accessor::attr(obj, ident, Type::Uninited); + let acc = hir::Accessor::attr(obj, ident); Ok(hir::Expr::Accessor(acc)) } other => Err(LowerErrors::from(LowerError::declare_error( @@ -1527,10 +1519,11 @@ impl ASTLowerer { } } - fn declare_type(&mut self, tasc: ast::TypeAscription) -> LowerResult { + fn declare_ident(&mut self, tasc: ast::TypeAscription) -> LowerResult { log!(info "entered {}({})", fn_name!(), tasc); match *tasc.expr { ast::Expr::Accessor(ast::Accessor::Ident(ident)) => { + let py_name = Str::rc(ident.inspect().trim_end_matches('!')); let t = self.ctx.instantiate_typespec( &tasc.t_spec, None, @@ -1545,6 +1538,7 @@ impl ASTLowerer { VarKind::Declared, None, None, + Some(py_name.clone()), ); self.ctx.decls.insert(ident.name.clone(), vi); } @@ -1552,6 +1546,7 @@ impl ASTLowerer { &ast::VarSignature::new(ast::VarPattern::Ident(ident.clone()), None), &t, ast::DefId(0), + Some(py_name), )?; match t { Type::ClassType => { @@ -1576,13 +1571,18 @@ impl ASTLowerer { } _ => {} } - let ident = hir::Identifier::new(ident.dot, ident.name, None, t); + let muty = Mutability::from(&ident.inspect()[..]); + let vis = ident.vis(); + let py_name = Str::rc(ident.inspect().trim_end_matches('!')); + let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name)); + let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); Ok(hir::TypeAscription::new( hir::Expr::Accessor(hir::Accessor::Ident(ident)), tasc.t_spec, )) } ast::Expr::Accessor(ast::Accessor::Attr(attr)) => { + let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!')); let t = self.ctx.instantiate_typespec( &tasc.t_spec, None, @@ -1597,11 +1597,15 @@ impl ASTLowerer { &ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None), &t, ast::DefId(0), + Some(py_name), )?; let obj = self.fake_lower_obj(*attr.obj)?; - let ident = - hir::Identifier::new(attr.ident.dot, attr.ident.name, None, Type::Uninited); - let attr = hir::Accessor::attr(obj, ident, t); + let muty = Mutability::from(&attr.ident.inspect()[..]); + let vis = attr.ident.vis(); + let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!')); + let vi = VarInfo::new(t, muty, vis, VarKind::Declared, None, None, Some(py_name)); + let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); + let attr = hir::Accessor::attr(obj, ident); Ok(hir::TypeAscription::new( hir::Expr::Accessor(attr), tasc.t_spec, @@ -1626,7 +1630,7 @@ impl ASTLowerer { "class declaration", self.ctx.caused_by(), ))), - ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.declare_type(tasc)?)), + ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.declare_ident(tasc)?)), other => Err(LowerErrors::from(LowerError::declare_error( self.cfg.input.clone(), line!() as usize, diff --git a/compiler/erg_compiler/ownercheck.rs b/compiler/erg_compiler/ownercheck.rs index 00991008..c9da99b9 100644 --- a/compiler/erg_compiler/ownercheck.rs +++ b/compiler/erg_compiler/ownercheck.rs @@ -109,7 +109,7 @@ impl OwnershipChecker { // TODO: referenced Expr::Call(call) => { let args_owns = call.signature_t().unwrap().args_ownership(); - let non_defaults_len = if call.is_method() { + let non_defaults_len = if call.is_method_call() { args_owns.non_defaults.len() - 1 } else { args_owns.non_defaults.len() @@ -227,11 +227,6 @@ impl OwnershipChecker { // REVIEW: is ownership the same? self.check_expr(&attr.obj, ownership, false) } - Accessor::TupleAttr(t_attr) => self.check_expr(&t_attr.obj, ownership, false), - Accessor::Subscr(subscr) => { - self.check_expr(&subscr.obj, ownership, false); - self.check_expr(&subscr.index, ownership, false); - } } } diff --git a/compiler/erg_compiler/ty/mod.rs b/compiler/erg_compiler/ty/mod.rs index f2f9e7f9..d0fb67a1 100644 --- a/compiler/erg_compiler/ty/mod.rs +++ b/compiler/erg_compiler/ty/mod.rs @@ -1734,14 +1734,14 @@ impl Type { } } - /// Procedure or MutType? - pub fn is_procedural(&self) -> bool { + /// Procedure + pub fn is_procedure(&self) -> bool { match self { - Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_procedural(), + Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_procedure(), Self::Callable { .. } => true, Self::Subr(subr) if subr.kind == SubrKind::Proc => true, Self::Refinement(refine) => - refine.t.is_procedural() || refine.preds.iter().any(|pred| + refine.t.is_procedure() || refine.preds.iter().any(|pred| matches!(pred, Predicate::Equal{ rhs, .. } if pred.mentions(&refine.var) && rhs.qual_name().map(|n| n.ends_with('!')).unwrap_or(false)) ), _ => false, @@ -2229,6 +2229,9 @@ impl Type { Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => { Some(return_t) } + // NOTE: Quantified could return a quantified type variable. + // At least in situations where this function is needed, self cannot be Quantified. + // Self::Quantified(quant) => quant.unbound_callable.return_t(), _ => None, } } @@ -2243,6 +2246,7 @@ impl Type { Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => { Some(return_t) } + // Self::Quantified(quant) => quant.unbound_callable.mut_return_t(), _ => None, } } diff --git a/compiler/erg_compiler/varinfo.rs b/compiler/erg_compiler/varinfo.rs index 51e15c60..33acdb38 100644 --- a/compiler/erg_compiler/varinfo.rs +++ b/compiler/erg_compiler/varinfo.rs @@ -123,6 +123,7 @@ pub struct VarInfo { pub kind: VarKind, pub comptime_decos: Option>, pub impl_of: Option, + pub py_name: Option, } impl fmt::Display for VarInfo { @@ -154,15 +155,26 @@ impl HasType for VarInfo { } } +impl Default for VarInfo { + fn default() -> Self { + Self::const_default() + } +} + impl VarInfo { - pub const ILLEGAL: &'static Self = &VarInfo::new( - Type::Failure, - Immutable, - Private, - VarKind::DoesNotExist, - None, - None, - ); + pub const ILLEGAL: &'static Self = &Self::const_default(); + + pub const fn const_default() -> Self { + Self::new( + Type::Untyped, + Immutable, + Private, + VarKind::DoesNotExist, + None, + None, + None, + ) + } pub const fn new( t: Type, @@ -171,6 +183,7 @@ impl VarInfo { kind: VarKind, comptime_decos: Option>, impl_of: Option, + py_name: Option, ) -> Self { Self { t, @@ -179,6 +192,7 @@ impl VarInfo { kind, comptime_decos, impl_of, + py_name, } } diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 0dc2dff3..a5003aff 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -1963,7 +1963,7 @@ impl Parser { break; } match self.try_reduce_arg(false).map_err(|_| self.stack_dec())? { - PosOrKwArg::Pos(arg) => match arg.expr { + PosOrKwArg::Pos(arg) if args.kw_is_empty() => match arg.expr { Expr::Tuple(Tuple::Normal(tup)) if tup.elems.paren.is_none() => { args.extend_pos(tup.elems.into_iters().0); } @@ -1971,12 +1971,27 @@ impl Parser { args.push_pos(PosArg::new(other)); } }, - PosOrKwArg::Kw(arg) => { - self.level -= 1; - let err = ParseError::simple_syntax_error(line!() as usize, arg.loc()); + PosOrKwArg::Pos(arg) => { + let err = ParseError::syntax_error( + line!() as usize, + arg.loc(), + switch_lang!( + "japanese" => "非デフォルト引数はデフォルト引数の後に指定できません", + "english" => "non-default argument follows default argument", + ), + None, + ); self.errs.push(err); return Err(()); } + // e.g. (x, y:=1) -> ... + PosOrKwArg::Kw(arg) => { + args.push_kw(arg); + /*self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, arg.loc()); + self.errs.push(err); + return Err(());*/ + } } } _ => {