mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Fix: variable to have VarInfo
instead of Type
This commit is contained in:
parent
119a326ebb
commit
46b87e1ca3
29 changed files with 888 additions and 816 deletions
|
@ -9,6 +9,10 @@ pub fn erg_std_path() -> PathBuf {
|
||||||
erg_path().join("lib").join("std")
|
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 {
|
pub fn erg_external_lib_path() -> PathBuf {
|
||||||
erg_path().join("lib").join("external")
|
erg_path().join("lib").join("external")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,16 @@ use std::process::Command;
|
||||||
|
|
||||||
use crate::serialize::get_magic_num_from_bytes;
|
use crate::serialize::get_magic_num_from_bytes;
|
||||||
|
|
||||||
pub const BUILTIN_PYTHON_MODS: [&str; 10] = [
|
pub const BUILTIN_PYTHON_MODS: [&str; 12] = [
|
||||||
"glob",
|
"glob",
|
||||||
"importlib",
|
"importlib",
|
||||||
"io",
|
"io",
|
||||||
"math",
|
"math",
|
||||||
"re",
|
"os",
|
||||||
"random",
|
"random",
|
||||||
|
"re",
|
||||||
"socket",
|
"socket",
|
||||||
|
"subprocess",
|
||||||
"sys",
|
"sys",
|
||||||
"time",
|
"time",
|
||||||
"urllib",
|
"urllib",
|
||||||
|
|
|
@ -38,283 +38,29 @@ use crate::ty::value::ValueObj;
|
||||||
use crate::ty::{HasType, Type, TypeCode, TypePair};
|
use crate::ty::{HasType, Type, TypeCode, TypePair};
|
||||||
use AccessKind::*;
|
use AccessKind::*;
|
||||||
|
|
||||||
fn is_python_special(name: &str) -> bool {
|
fn fake_method_to_func(class: &str, name: &str) -> Option<&'static str> {
|
||||||
matches!(name, "__call__" | "__init__")
|
match (class, name) {
|
||||||
}
|
(_, "abs") => Some("abs"),
|
||||||
|
(_, "iter") => Some("iter"),
|
||||||
fn is_python_global(name: &str) -> bool {
|
(_, "map") => Some("map"),
|
||||||
matches!(
|
_ => None,
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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`.
|
/// 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 {
|
fn escape_name(ident: Identifier) -> Str {
|
||||||
let vis = ident.vis();
|
let vis = ident.vis();
|
||||||
let mut name = convert_to_python_name(ident.name.into_token().content).to_string();
|
if let Some(py_name) = ident.vi.py_name {
|
||||||
name = name.replace('!', "__erg_proc__");
|
py_name
|
||||||
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 {
|
} else {
|
||||||
|
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)
|
Str::from("::".to_string() + &name)
|
||||||
|
} else {
|
||||||
|
Str::from(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,14 +445,9 @@ impl CodeGenerator {
|
||||||
self.emit_pop_top(); // discard IMPORT_FROM object
|
self.emit_pop_top(); // discard IMPORT_FROM object
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_load_attr_instr(
|
fn emit_load_attr_instr(&mut self, ident: Identifier) {
|
||||||
&mut self,
|
log!(info "entered {} ({ident})", fn_name!());
|
||||||
class: &str,
|
let escaped = escape_name(ident);
|
||||||
uniq_obj_name: Option<&str>,
|
|
||||||
ident: Identifier,
|
|
||||||
) {
|
|
||||||
log!(info "entered {} ({class}{ident})", fn_name!());
|
|
||||||
let escaped = escape_attr(class, uniq_obj_name, ident);
|
|
||||||
let name = self
|
let name = self
|
||||||
.local_search(&escaped, Attr)
|
.local_search(&escaped, Attr)
|
||||||
.unwrap_or_else(|| self.register_attr(escaped));
|
.unwrap_or_else(|| self.register_attr(escaped));
|
||||||
|
@ -720,14 +461,12 @@ impl CodeGenerator {
|
||||||
self.write_arg(name.idx as u8);
|
self.write_arg(name.idx as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_load_method_instr(
|
fn emit_load_method_instr(&mut self, ident: Identifier) {
|
||||||
&mut self,
|
log!(info "entered {} ({ident})", fn_name!());
|
||||||
class: &str,
|
if &ident.inspect()[..] == "__new__" {
|
||||||
uniq_obj_name: Option<&str>,
|
log!("{:?}", ident.vi);
|
||||||
ident: Identifier,
|
}
|
||||||
) {
|
let escaped = escape_name(ident);
|
||||||
log!(info "entered {} ({class}{ident})", fn_name!());
|
|
||||||
let escaped = escape_attr(class, uniq_obj_name, ident);
|
|
||||||
let name = self
|
let name = self
|
||||||
.local_search(&escaped, Method)
|
.local_search(&escaped, Method)
|
||||||
.unwrap_or_else(|| self.register_method(escaped));
|
.unwrap_or_else(|| self.register_method(escaped));
|
||||||
|
@ -801,7 +540,6 @@ impl CodeGenerator {
|
||||||
self.emit_expr(*attr.obj);
|
self.emit_expr(*attr.obj);
|
||||||
self.emit_store_instr(attr.ident, Attr);
|
self.emit_store_instr(attr.ident, Attr);
|
||||||
}
|
}
|
||||||
acc => todo!("store: {acc}"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,24 +597,8 @@ impl CodeGenerator {
|
||||||
self.emit_load_name_instr(ident);
|
self.emit_load_name_instr(ident);
|
||||||
}
|
}
|
||||||
Accessor::Attr(a) => {
|
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_expr(*a.obj);
|
||||||
self.emit_load_attr_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), a.ident);
|
self.emit_load_attr_instr(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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1541,14 +1263,13 @@ impl CodeGenerator {
|
||||||
fn emit_call_method(&mut self, obj: Expr, method_name: Identifier, args: Args) {
|
fn emit_call_method(&mut self, obj: Expr, method_name: Identifier, args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let class = obj.ref_t().qual_name(); // これは必ずmethodのあるクラスになっている
|
let class = obj.ref_t().qual_name(); // これは必ずmethodのあるクラスになっている
|
||||||
let uniq_obj_name = obj.qual_name().map(Str::rc);
|
|
||||||
if &method_name.inspect()[..] == "update!" {
|
if &method_name.inspect()[..] == "update!" {
|
||||||
return self.emit_call_update(obj, args);
|
return self.emit_call_update(obj, args);
|
||||||
} else if is_fake_method(&class, method_name.inspect()) {
|
} else if let Some(func_name) = fake_method_to_func(&class, method_name.inspect()) {
|
||||||
return self.emit_call_fake_method(obj, method_name, args);
|
return self.emit_call_fake_method(obj, func_name, method_name, args);
|
||||||
}
|
}
|
||||||
self.emit_expr(obj);
|
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);
|
self.emit_args(args, Method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1621,9 +1342,16 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 1.abs() => abs(1)
|
/// 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!());
|
log!(info "entered {}", fn_name!());
|
||||||
method_name.dot = None;
|
method_name.dot = None;
|
||||||
|
method_name.vi.py_name = Some(Str::ever(func_name));
|
||||||
self.emit_load_name_instr(method_name);
|
self.emit_load_name_instr(method_name);
|
||||||
args.insert_pos(0, PosArg::new(obj));
|
args.insert_pos(0, PosArg::new(obj));
|
||||||
self.emit_args(args, Name);
|
self.emit_args(args, Name);
|
||||||
|
@ -1965,7 +1693,6 @@ impl CodeGenerator {
|
||||||
Some(Token::dummy()),
|
Some(Token::dummy()),
|
||||||
VarName::from_str(field.symbol.clone()),
|
VarName::from_str(field.symbol.clone()),
|
||||||
),
|
),
|
||||||
Type::Failure,
|
|
||||||
)));
|
)));
|
||||||
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
|
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
|
||||||
let dot = if field.vis.is_private() {
|
let dot = if field.vis.is_private() {
|
||||||
|
@ -1976,7 +1703,6 @@ impl CodeGenerator {
|
||||||
let attr = Accessor::Attr(Attribute::new(
|
let attr = Accessor::Attr(Attribute::new(
|
||||||
obj,
|
obj,
|
||||||
Identifier::bare(dot, VarName::from_str(field.symbol.clone())),
|
Identifier::bare(dot, VarName::from_str(field.symbol.clone())),
|
||||||
Type::Failure,
|
|
||||||
));
|
));
|
||||||
let attr_def = AttrDef::new(attr, Block::new(vec![expr]));
|
let attr_def = AttrDef::new(attr, Block::new(vec![expr]));
|
||||||
attrs.push(Expr::AttrDef(attr_def));
|
attrs.push(Expr::AttrDef(attr_def));
|
||||||
|
@ -2010,16 +1736,14 @@ impl CodeGenerator {
|
||||||
line,
|
line,
|
||||||
)));
|
)));
|
||||||
let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
|
let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
|
||||||
let class_new = Expr::Accessor(Accessor::attr(
|
let mut new_ident =
|
||||||
class,
|
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line));
|
||||||
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line)),
|
new_ident.vi.py_name = Some(Str::ever("__call__"));
|
||||||
Type::Failure,
|
let class_new = Expr::Accessor(Accessor::attr(class, new_ident));
|
||||||
));
|
|
||||||
let call = Expr::Call(Call::new(
|
let call = Expr::Call(Call::new(
|
||||||
class_new,
|
class_new,
|
||||||
None,
|
None,
|
||||||
Args::new(vec![arg], None, vec![], None),
|
Args::new(vec![arg], None, vec![], None),
|
||||||
Type::Failure,
|
|
||||||
));
|
));
|
||||||
let block = Block::new(vec![call]);
|
let block = Block::new(vec![call]);
|
||||||
let body = DefBody::new(Token::dummy(), block, DefId(0));
|
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_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.emit_load_const(erg_std_path().to_str().unwrap());
|
||||||
self.write_instr(CALL_METHOD);
|
self.write_instr(CALL_METHOD);
|
||||||
self.write_arg(1u8);
|
self.write_arg(1u8);
|
||||||
|
|
|
@ -26,7 +26,7 @@ use erg_parser::ast::VarName;
|
||||||
use crate::context::initialize::const_func::*;
|
use crate::context::initialize::const_func::*;
|
||||||
use crate::context::instantiate::ConstTemplate;
|
use crate::context::instantiate::ConstTemplate;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
ClassDefType, Context, ContextKind, DefaultInfo, MethodType, ParamSpec, TraitInstance,
|
ClassDefType, Context, ContextKind, DefaultInfo, MethodInfo, ParamSpec, TraitInstance,
|
||||||
};
|
};
|
||||||
use crate::mod_cache::SharedModuleCache;
|
use crate::mod_cache::SharedModuleCache;
|
||||||
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
||||||
|
@ -48,7 +48,38 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
self.decls.insert(
|
self.decls.insert(
|
||||||
name,
|
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() {
|
if self.locals.get(&name).is_some() {
|
||||||
panic!("already registered: {name}");
|
panic!("already registered: {name}");
|
||||||
} else {
|
} else {
|
||||||
self.locals
|
self.locals.insert(
|
||||||
.insert(name, VarInfo::new(t, muty, vis, Builtin, None, impl_of));
|
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) {
|
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) {
|
fn register_builtin_const(&mut self, name: &str, vis: Visibility, obj: ValueObj) {
|
||||||
|
@ -95,6 +152,7 @@ impl Context {
|
||||||
Builtin,
|
Builtin,
|
||||||
None,
|
None,
|
||||||
impl_of,
|
impl_of,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
self.consts.insert(VarName::from_str(Str::rc(name)), obj);
|
self.consts.insert(VarName::from_str(Str::rc(name)), obj);
|
||||||
self.locals.insert(VarName::from_str(Str::rc(name)), vi);
|
self.locals.insert(VarName::from_str(Str::rc(name)), vi);
|
||||||
|
@ -124,15 +182,29 @@ impl Context {
|
||||||
unique_in_place(&mut self.super_traits);
|
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() {
|
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 {
|
} 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() {
|
if self.rec_get_mono_type(&t.local_name()).is_some() {
|
||||||
panic!("{} has already been registered", t.local_name());
|
panic!("{} has already been registered", t.local_name());
|
||||||
} else if self.rec_get_const_obj(&t.local_name()).is_some() {
|
} else if self.rec_get_const_obj(&t.local_name()).is_some() {
|
||||||
|
@ -146,7 +218,15 @@ impl Context {
|
||||||
};
|
};
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name.clone(),
|
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
|
self.consts
|
||||||
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
||||||
|
@ -162,21 +242,21 @@ impl Context {
|
||||||
}
|
}
|
||||||
for (trait_method, vi) in ctx.decls.iter() {
|
for (trait_method, vi) in ctx.decls.iter() {
|
||||||
if let Some(types) = self.method_to_traits.get_mut(trait_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_traits.insert(
|
self.method_to_traits.insert(
|
||||||
trait_method.inspect().clone(),
|
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() {
|
for (class_method, vi) in ctx.locals.iter() {
|
||||||
if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_classes.insert(
|
self.method_to_classes.insert(
|
||||||
class_method.inspect().clone(),
|
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と再代入は違う
|
// 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
|
// FIXME: panic
|
||||||
if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.local_name()) {
|
if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.local_name()) {
|
||||||
root_ctx.methods_list.push((ClassDefType::Simple(t), ctx));
|
root_ctx.methods_list.push((ClassDefType::Simple(t), ctx));
|
||||||
|
@ -198,7 +285,15 @@ impl Context {
|
||||||
};
|
};
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name.clone(),
|
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
|
self.consts
|
||||||
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
.insert(name.clone(), ValueObj::builtin_t(t.clone()));
|
||||||
|
@ -214,21 +309,21 @@ impl Context {
|
||||||
}
|
}
|
||||||
for (trait_method, vi) in ctx.decls.iter() {
|
for (trait_method, vi) in ctx.decls.iter() {
|
||||||
if let Some(traits) = self.method_to_traits.get_mut(trait_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_traits.insert(
|
self.method_to_traits.insert(
|
||||||
trait_method.inspect().clone(),
|
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() {
|
for (class_method, vi) in ctx.locals.iter() {
|
||||||
if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_classes.insert(
|
self.method_to_classes.insert(
|
||||||
class_method.inspect().clone(),
|
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);
|
let name = VarName::from_static(name);
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name.clone(),
|
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() {
|
for method_name in ctx.locals.keys() {
|
||||||
if let Some(patches) = self.method_impl_patches.get_mut(method_name) {
|
if let Some(patches) = self.method_impl_patches.get_mut(method_name) {
|
||||||
|
@ -307,7 +402,7 @@ impl Context {
|
||||||
t_read,
|
t_read,
|
||||||
set! { subtypeof(mono_q("Self"), mono("Readable!")) },
|
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 */
|
/* Writable */
|
||||||
let mut writable = Self::builtin_mono_trait("Writable!", 2);
|
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);
|
let t_write = pr1_kw_met(ref_mut(mono_q("Self"), None), kw("s", Str), Nat);
|
||||||
|
@ -315,12 +410,12 @@ impl Context {
|
||||||
t_write,
|
t_write,
|
||||||
set! { subtypeof(mono_q("Self"), mono("Writable!")) },
|
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 */
|
/* Show */
|
||||||
let mut show = Self::builtin_mono_trait("Show", 2);
|
let mut show = Self::builtin_mono_trait("Show", 2);
|
||||||
let t_show = fn0_met(ref_(mono_q("Self")), Str);
|
let t_show = fn0_met(ref_(mono_q("Self")), Str);
|
||||||
let t_show = quant(t_show, set! { subtypeof(mono_q("Self"), mono("Show")) });
|
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 */
|
/* In */
|
||||||
let mut in_ = Self::builtin_poly_trait("In", vec![PS::t("T", NonDefault)], 2);
|
let mut in_ = Self::builtin_poly_trait("In", vec![PS::t("T", NonDefault)], 2);
|
||||||
let params = vec![PS::t("T", NonDefault)];
|
let params = vec![PS::t("T", NonDefault)];
|
||||||
|
@ -447,50 +542,90 @@ impl Context {
|
||||||
let op_t = quant(op_t, set! {r_bound, self_bound});
|
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("__floordiv__", op_t, Public);
|
||||||
floor_div.register_builtin_decl("Output", Type, Public);
|
floor_div.register_builtin_decl("Output", Type, Public);
|
||||||
self.register_builtin_type(mono("Unpack"), unpack, Private, Const);
|
self.register_builtin_type(mono("Unpack"), unpack, Private, Const, None);
|
||||||
self.register_builtin_type(mono("InheritableType"), inheritable_type, Private, Const);
|
self.register_builtin_type(
|
||||||
self.register_builtin_type(mono("Named"), named, Private, Const);
|
mono("InheritableType"),
|
||||||
self.register_builtin_type(mono("Mutable"), mutable, Private, Const);
|
inheritable_type,
|
||||||
self.register_builtin_type(mono("Immutizable"), immutizable, Private, Const);
|
Private,
|
||||||
self.register_builtin_type(mono("Mutizable"), mutizable, Private, Const);
|
Const,
|
||||||
self.register_builtin_type(mono("PathLike"), pathlike, Private, Const);
|
None,
|
||||||
self.register_builtin_type(mono("Readable!"), readable, Private, Const);
|
);
|
||||||
self.register_builtin_type(mono("Writable!"), writable, Private, Const);
|
self.register_builtin_type(mono("Named"), named, Private, Const, None);
|
||||||
self.register_builtin_type(mono("Show"), show, Private, Const);
|
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(
|
self.register_builtin_type(
|
||||||
poly("Input", vec![ty_tp(mono_q("T"))]),
|
poly("Input", vec![ty_tp(mono_q("T"))]),
|
||||||
input,
|
input,
|
||||||
Private,
|
Private,
|
||||||
Const,
|
Const,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
self.register_builtin_type(
|
self.register_builtin_type(
|
||||||
poly("Output", vec![ty_tp(mono_q("T"))]),
|
poly("Output", vec![ty_tp(mono_q("T"))]),
|
||||||
output,
|
output,
|
||||||
Private,
|
Private,
|
||||||
Const,
|
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(
|
self.register_builtin_type(
|
||||||
poly("PartialOrd", vec![ty_tp(mono_q("R"))]),
|
poly("PartialOrd", vec![ty_tp(mono_q("R"))]),
|
||||||
partial_ord,
|
partial_ord,
|
||||||
Private,
|
Private,
|
||||||
Const,
|
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(
|
self.register_builtin_type(
|
||||||
poly("Iterable", vec![ty_tp(mono_q("T"))]),
|
poly("Iterable", vec![ty_tp(mono_q("T"))]),
|
||||||
iterable,
|
iterable,
|
||||||
Private,
|
Private,
|
||||||
Const,
|
Const,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
self.register_builtin_type(poly("Add", ty_params.clone()), add, 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);
|
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);
|
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);
|
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);
|
self.register_builtin_type(poly("FloorDiv", ty_params), floor_div, Private, Const, None);
|
||||||
self.register_const_param_defaults(
|
self.register_const_param_defaults(
|
||||||
"Eq",
|
"Eq",
|
||||||
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
vec![ConstTemplate::Obj(ValueObj::builtin_t(mono_q("Self")))],
|
||||||
|
@ -551,8 +686,8 @@ impl Context {
|
||||||
float.register_superclass(Obj, &obj);
|
float.register_superclass(Obj, &obj);
|
||||||
// TODO: support multi platform
|
// TODO: support multi platform
|
||||||
float.register_builtin_const("EPSILON", Public, ValueObj::Float(2.220446049250313e-16));
|
float.register_builtin_const("EPSILON", Public, ValueObj::Float(2.220446049250313e-16));
|
||||||
float.register_builtin_impl("Real", Float, Const, Public);
|
float.register_builtin_py_impl("Real", Float, Const, Public, Some("real"));
|
||||||
float.register_builtin_impl("Imag", Float, Const, Public);
|
float.register_builtin_py_impl("Imag", Float, Const, Public, Some("imag"));
|
||||||
float.register_marker_trait(mono("Num"));
|
float.register_marker_trait(mono("Num"));
|
||||||
float.register_marker_trait(mono("Ord"));
|
float.register_marker_trait(mono("Ord"));
|
||||||
let mut float_partial_ord =
|
let mut float_partial_ord =
|
||||||
|
@ -598,15 +733,15 @@ impl Context {
|
||||||
float.register_trait(Float, float_mutizable);
|
float.register_trait(Float, float_mutizable);
|
||||||
let mut float_show = Self::builtin_methods(Some(mono("Show")), 1);
|
let mut float_show = Self::builtin_methods(Some(mono("Show")), 1);
|
||||||
let t = fn0_met(Float, Str);
|
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);
|
float.register_trait(Float, float_show);
|
||||||
|
|
||||||
/* Ratio */
|
/* Ratio */
|
||||||
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
|
// TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat)
|
||||||
let mut ratio = Self::builtin_mono_class("Ratio", 2);
|
let mut ratio = Self::builtin_mono_class("Ratio", 2);
|
||||||
ratio.register_superclass(Obj, &obj);
|
ratio.register_superclass(Obj, &obj);
|
||||||
ratio.register_builtin_impl("Real", Ratio, Const, Public);
|
ratio.register_builtin_py_impl("Real", Ratio, Const, Public, Some("real"));
|
||||||
ratio.register_builtin_impl("Imag", Ratio, Const, Public);
|
ratio.register_builtin_py_impl("Imag", Ratio, Const, Public, Some("imag"));
|
||||||
ratio.register_marker_trait(mono("Num"));
|
ratio.register_marker_trait(mono("Num"));
|
||||||
ratio.register_marker_trait(mono("Ord"));
|
ratio.register_marker_trait(mono("Ord"));
|
||||||
let mut ratio_partial_ord =
|
let mut ratio_partial_ord =
|
||||||
|
@ -702,17 +837,17 @@ impl Context {
|
||||||
int.register_trait(Int, int_mutizable);
|
int.register_trait(Int, int_mutizable);
|
||||||
let mut int_show = Self::builtin_methods(Some(mono("Show")), 1);
|
let mut int_show = Self::builtin_methods(Some(mono("Show")), 1);
|
||||||
let t = fn0_met(Int, Str);
|
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_trait(Int, int_show);
|
||||||
int.register_builtin_impl("Real", Int, Const, Public);
|
int.register_builtin_py_impl("Real", Int, Const, Public, Some("real"));
|
||||||
int.register_builtin_impl("Imag", Int, Const, Public);
|
int.register_builtin_py_impl("Imag", Int, Const, Public, Some("imag"));
|
||||||
|
|
||||||
/* Nat */
|
/* Nat */
|
||||||
let mut nat = Self::builtin_mono_class("Nat", 10);
|
let mut nat = Self::builtin_mono_class("Nat", 10);
|
||||||
nat.register_superclass(Int, &int);
|
nat.register_superclass(Int, &int);
|
||||||
// class("Rational"),
|
// class("Rational"),
|
||||||
// class("Integral"),
|
// class("Integral"),
|
||||||
nat.register_builtin_impl(
|
nat.register_builtin_py_impl(
|
||||||
"times!",
|
"times!",
|
||||||
pr_met(
|
pr_met(
|
||||||
Nat,
|
Nat,
|
||||||
|
@ -723,6 +858,7 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("times"),
|
||||||
);
|
);
|
||||||
nat.register_marker_trait(mono("Num"));
|
nat.register_marker_trait(mono("Num"));
|
||||||
nat.register_marker_trait(mono("Ord"));
|
nat.register_marker_trait(mono("Ord"));
|
||||||
|
@ -932,7 +1068,7 @@ impl Context {
|
||||||
t,
|
t,
|
||||||
set! {static_instance("T", Type), static_instance("N", Nat), static_instance("M", Nat)},
|
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))|.
|
// Array(T, N)|<: Add(Array(T, M))|.
|
||||||
// Output = Array(T, N + M)
|
// Output = Array(T, N + M)
|
||||||
// __add__: (self: Array(T, N), other: Array(T, M)) -> Array(T, N + M) = Array.concat
|
// __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(mono("Mutizable"));
|
||||||
array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
|
array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
|
||||||
let mut array_show = Self::builtin_methods(Some(mono("Show")), 1);
|
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);
|
array_.register_trait(arr_t.clone(), array_show);
|
||||||
let mut array_iterable =
|
let mut array_iterable =
|
||||||
Self::builtin_methods(Some(poly("Iterable", vec![ty_tp(mono_q("T"))])), 2);
|
Self::builtin_methods(Some(poly("Iterable", vec![ty_tp(mono_q("T"))])), 2);
|
||||||
|
@ -1102,7 +1244,13 @@ impl Context {
|
||||||
tuple_getitem_t,
|
tuple_getitem_t,
|
||||||
set! {static_instance("Ts", array_t(Type, mono_q_tp("N"))), static_instance("N", Nat)},
|
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 */
|
/* record */
|
||||||
let mut record = Self::builtin_mono_class("Record", 2);
|
let mut record = Self::builtin_mono_class("Record", 2);
|
||||||
record.register_superclass(Obj, &obj);
|
record.register_superclass(Obj, &obj);
|
||||||
|
@ -1211,7 +1359,7 @@ impl Context {
|
||||||
/* File_mut */
|
/* File_mut */
|
||||||
let mut file_mut = Self::builtin_mono_class("File!", 2);
|
let mut file_mut = Self::builtin_mono_class("File!", 2);
|
||||||
let mut file_mut_readable = Self::builtin_methods(Some(mono("Readable!")), 1);
|
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!",
|
"read!",
|
||||||
pr_met(
|
pr_met(
|
||||||
ref_mut(mono("File!"), None),
|
ref_mut(mono("File!"), None),
|
||||||
|
@ -1222,14 +1370,16 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("read"),
|
||||||
);
|
);
|
||||||
file_mut.register_trait(mono("File!"), file_mut_readable);
|
file_mut.register_trait(mono("File!"), file_mut_readable);
|
||||||
let mut file_mut_writable = Self::builtin_methods(Some(mono("Writable!")), 1);
|
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!",
|
"write!",
|
||||||
pr1_kw_met(ref_mut(mono("File!"), None), kw("s", Str), Nat),
|
pr1_kw_met(ref_mut(mono("File!"), None), kw("s", Str), Nat),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("write"),
|
||||||
);
|
);
|
||||||
file_mut.register_trait(mono("File!"), file_mut_writable);
|
file_mut.register_trait(mono("File!"), file_mut_writable);
|
||||||
/* Array_mut */
|
/* Array_mut */
|
||||||
|
@ -1257,7 +1407,7 @@ impl Context {
|
||||||
t,
|
t,
|
||||||
set! {static_instance("T", Type), static_instance("N", mono("Nat!"))},
|
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(
|
let t = pr_met(
|
||||||
array_mut_t.clone(),
|
array_mut_t.clone(),
|
||||||
vec![kw("f", nd_func(vec![anon(mono_q("T"))], None, mono_q("T")))],
|
vec![kw("f", nd_func(vec![anon(mono_q("T"))], None, mono_q("T")))],
|
||||||
|
@ -1310,7 +1460,7 @@ impl Context {
|
||||||
t,
|
t,
|
||||||
set! {static_instance("T", Type), static_instance("N", mono("Nat!"))},
|
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(
|
let t = pr_met(
|
||||||
set_mut_t.clone(),
|
set_mut_t.clone(),
|
||||||
vec![kw("f", nd_func(vec![anon(mono_q("T"))], None, mono_q("T")))],
|
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);
|
let mut named_func = Self::builtin_mono_class("NamedFunc", 2);
|
||||||
named_func.register_superclass(mono("Func"), &func);
|
named_func.register_superclass(mono("Func"), &func);
|
||||||
named_func.register_marker_trait(mono("Named"));
|
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);
|
let mut qfunc = Self::builtin_mono_class("QuantifiedFunc", 2);
|
||||||
qfunc.register_superclass(mono("Func"), &func);
|
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_type(mono("Record"), vec![], record, Private, Const);
|
||||||
self.register_builtin_type(Int, int, Private, Const);
|
self.register_builtin_type(Int, int, Private, Const, Some("int"));
|
||||||
self.register_builtin_type(Nat, nat, Private, Const);
|
self.register_builtin_type(Nat, nat, Private, Const, Some("Nat"));
|
||||||
self.register_builtin_type(Float, float, Private, Const);
|
self.register_builtin_type(Float, float, Private, Const, Some("float"));
|
||||||
self.register_builtin_type(Ratio, ratio, Private, Const);
|
self.register_builtin_type(Ratio, ratio, Private, Const, Some("Ratio"));
|
||||||
self.register_builtin_type(Bool, bool_, Private, Const);
|
self.register_builtin_type(Bool, bool_, Private, Const, Some("Bool"));
|
||||||
self.register_builtin_type(Str, str_, Private, Const);
|
self.register_builtin_type(Str, str_, Private, Const, Some("Str"));
|
||||||
self.register_builtin_type(NoneType, nonetype, Private, Const);
|
self.register_builtin_type(NoneType, nonetype, Private, Const, Some("NoneType"));
|
||||||
self.register_builtin_type(Type, type_, Private, Const);
|
self.register_builtin_type(Type, type_, Private, Const, Some("type"));
|
||||||
self.register_builtin_type(ClassType, class_type, Private, Const);
|
self.register_builtin_type(ClassType, class_type, Private, Const, Some("ClassType"));
|
||||||
self.register_builtin_type(TraitType, trait_type, Private, Const);
|
self.register_builtin_type(TraitType, trait_type, Private, Const, Some("TraitType"));
|
||||||
self.register_builtin_type(g_module_t, generic_module, Private, Const);
|
self.register_builtin_type(
|
||||||
self.register_builtin_type(module_t, module, Private, Const);
|
g_module_t,
|
||||||
self.register_builtin_type(arr_t, array_, Private, Const);
|
generic_module,
|
||||||
self.register_builtin_type(set_t, set_, Private, Const);
|
Private,
|
||||||
self.register_builtin_type(g_dict_t, generic_dict, Private, Const);
|
Const,
|
||||||
self.register_builtin_type(dict_t, dict_, Private, Const);
|
Some("ModuleType"),
|
||||||
self.register_builtin_type(mono("Bytes"), bytes, Private, Const);
|
);
|
||||||
self.register_builtin_type(mono("GenericTuple"), generic_tuple, Private, Const);
|
self.register_builtin_type(module_t, module, Private, Const, Some("Module"));
|
||||||
self.register_builtin_type(tuple_t, tuple_, Private, Const);
|
self.register_builtin_type(arr_t, array_, Private, Const, Some("list"));
|
||||||
self.register_builtin_type(mono("Record"), record, Private, Const);
|
self.register_builtin_type(set_t, set_, Private, Const, Some("set"));
|
||||||
self.register_builtin_type(or_t, or, Private, Const);
|
self.register_builtin_type(g_dict_t, generic_dict, Private, Const, Some("dict"));
|
||||||
self.register_builtin_type(mono("StrIterator"), str_iterator, Private, Const);
|
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(
|
self.register_builtin_type(
|
||||||
poly("ArrayIterator", vec![ty_tp(mono_q("T"))]),
|
poly("ArrayIterator", vec![ty_tp(mono_q("T"))]),
|
||||||
array_iterator,
|
array_iterator,
|
||||||
Private,
|
Private,
|
||||||
Const,
|
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) {
|
fn init_builtin_funcs(&mut self) {
|
||||||
|
@ -1519,33 +1715,57 @@ impl Context {
|
||||||
let t_exit = t_quit.clone();
|
let t_exit = t_quit.clone();
|
||||||
let t_repr = nd_func(vec![kw("object", Obj)], None, Str);
|
let t_repr = nd_func(vec![kw("object", Obj)], None, Str);
|
||||||
let t_round = nd_func(vec![kw("number", Float)], None, Int);
|
let t_round = nd_func(vec![kw("number", Float)], None, Int);
|
||||||
self.register_builtin_impl("abs", t_abs, Immutable, Private);
|
self.register_builtin_py_impl("abs", t_abs, Immutable, Private, Some("abs"));
|
||||||
self.register_builtin_impl("ascii", t_ascii, Immutable, Private);
|
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("assert", t_assert, Const, Private); // assert casting に悪影響が出る可能性があるため、Constとしておく
|
||||||
self.register_builtin_impl("bin", t_bin, Immutable, Private);
|
self.register_builtin_py_impl("bin", t_bin, Immutable, Private, Some("bin"));
|
||||||
self.register_builtin_impl("chr", t_chr, Immutable, Private);
|
self.register_builtin_py_impl("chr", t_chr, Immutable, Private, Some("chr"));
|
||||||
self.register_builtin_impl("classof", t_classof, Immutable, Private);
|
self.register_builtin_py_impl("classof", t_classof, Immutable, Private, Some("type"));
|
||||||
self.register_builtin_impl("compile", t_compile, Immutable, Private);
|
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("cond", t_cond, Immutable, Private);
|
||||||
self.register_builtin_impl("discard", t_discard, 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("if", t_if, Immutable, Private);
|
||||||
self.register_builtin_impl("import", t_import, Immutable, Private);
|
self.register_builtin_py_impl("import", t_import, Immutable, Private, Some("__import__"));
|
||||||
self.register_builtin_impl("isinstance", t_isinstance, Immutable, Private);
|
self.register_builtin_py_impl(
|
||||||
self.register_builtin_impl("issubclass", t_issubclass, Immutable, Private);
|
"isinstance",
|
||||||
self.register_builtin_impl("len", t_len, Immutable, Private);
|
t_isinstance,
|
||||||
self.register_builtin_impl("log", t_log, Immutable, Private);
|
Immutable,
|
||||||
self.register_builtin_impl("oct", t_oct, Immutable, Private);
|
Private,
|
||||||
self.register_builtin_impl("ord", t_ord, Immutable, Private);
|
Some("isinstance"),
|
||||||
self.register_builtin_impl("panic", t_panic, Immutable, Private);
|
);
|
||||||
self.register_builtin_impl("pow", t_pow, Immutable, Private);
|
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") {
|
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_py_impl(
|
||||||
self.register_builtin_impl("quit", t_quit, Immutable, Private);
|
"pyimport",
|
||||||
self.register_builtin_impl("repr", t_repr, Immutable, Private);
|
t_pyimport,
|
||||||
self.register_builtin_impl("round", t_round, Immutable, Private);
|
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) {
|
fn init_builtin_const_funcs(&mut self) {
|
||||||
|
@ -1682,16 +1902,16 @@ impl Context {
|
||||||
t_with,
|
t_with,
|
||||||
set! {static_instance("T", Type), static_instance("U", Type)},
|
set! {static_instance("T", Type), static_instance("U", Type)},
|
||||||
);
|
);
|
||||||
self.register_builtin_impl("dir!", t_dir, Immutable, Private);
|
self.register_builtin_py_impl("dir!", t_dir, Immutable, Private, Some("dir"));
|
||||||
self.register_builtin_impl("print!", t_print, Immutable, Private);
|
self.register_builtin_py_impl("print!", t_print, Immutable, Private, Some("print"));
|
||||||
self.register_builtin_impl("id!", t_id, Immutable, Private);
|
self.register_builtin_py_impl("id!", t_id, Immutable, Private, Some("id"));
|
||||||
self.register_builtin_impl("input!", t_input, Immutable, Private);
|
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("if!", t_if, Immutable, Private);
|
||||||
self.register_builtin_impl("for!", t_for, Immutable, Private);
|
self.register_builtin_impl("for!", t_for, Immutable, Private);
|
||||||
self.register_builtin_impl("globals!", t_globals, Immutable, Private);
|
self.register_builtin_py_impl("globals!", t_globals, Immutable, Private, Some("globals"));
|
||||||
self.register_builtin_impl("locals!", t_locals, Immutable, Private);
|
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("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);
|
self.register_builtin_impl("with!", t_with, Immutable, Private);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use Visibility::*;
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn init_py_glob_mod() -> Self {
|
pub(crate) fn init_py_glob_mod() -> Self {
|
||||||
let mut glob = Context::builtin_module("glob", 10);
|
let mut glob = Context::builtin_module("glob", 10);
|
||||||
glob.register_builtin_impl(
|
glob.register_builtin_py_impl(
|
||||||
"glob!",
|
"glob!",
|
||||||
proc(
|
proc(
|
||||||
vec![kw("pathname", Str)],
|
vec![kw("pathname", Str)],
|
||||||
|
@ -23,6 +23,7 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("glob"),
|
||||||
);
|
);
|
||||||
glob
|
glob
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ use Visibility::*;
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn init_py_importlib_mod() -> Self {
|
pub(crate) fn init_py_importlib_mod() -> Self {
|
||||||
let mut importlib = Context::builtin_module("importlib", 15);
|
let mut importlib = Context::builtin_module("importlib", 15);
|
||||||
importlib.register_builtin_impl(
|
importlib.register_builtin_py_impl(
|
||||||
"reload!",
|
"reload!",
|
||||||
proc1(mono("GenericModule"), NoneType),
|
proc1(mono("GenericModule"), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("reload"),
|
||||||
);
|
);
|
||||||
importlib
|
importlib
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,20 @@ impl Context {
|
||||||
let mut string_io = Context::builtin_mono_class("StringIO!", 0);
|
let mut string_io = Context::builtin_mono_class("StringIO!", 0);
|
||||||
// FIXME: include Obj (pass main_ctx as a param)
|
// FIXME: include Obj (pass main_ctx as a param)
|
||||||
// string_io.register_superclass(Obj, obj);
|
// string_io.register_superclass(Obj, obj);
|
||||||
string_io.register_builtin_impl(
|
string_io.register_builtin_py_impl(
|
||||||
"getvalue!",
|
"getvalue!",
|
||||||
pr0_met(ref_(mono("io.StringIO!")), Str),
|
pr0_met(ref_(mono("io.StringIO!")), Str),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
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
|
io
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,22 @@ use Visibility::*;
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn init_py_os_mod() -> Self {
|
pub(crate) fn init_py_os_mod() -> Self {
|
||||||
let mut os = Context::builtin_module("os", 15);
|
let mut os = Context::builtin_module("os", 15);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"chdir!",
|
"chdir!",
|
||||||
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("chdir"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl("getcwd!", proc0(Str), Immutable, Public);
|
os.register_builtin_py_impl("getcwd!", proc0(Str), Immutable, Public, Some("getcwd"));
|
||||||
os.register_builtin_impl("getenv!", nd_proc1(kw("key", Str), Str), Immutable, Public);
|
os.register_builtin_py_impl(
|
||||||
os.register_builtin_impl(
|
"getenv!",
|
||||||
|
nd_proc1(kw("key", Str), Str),
|
||||||
|
Immutable,
|
||||||
|
Public,
|
||||||
|
Some("getenv"),
|
||||||
|
);
|
||||||
|
os.register_builtin_py_impl(
|
||||||
"listdir!",
|
"listdir!",
|
||||||
proc(
|
proc(
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -31,15 +38,17 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("listdir"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"mkdir!",
|
"mkdir!",
|
||||||
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("mkdir"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl("name", Str, Immutable, Public);
|
os.register_builtin_impl("name", Str, Immutable, Public);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"putenv!",
|
"putenv!",
|
||||||
proc(
|
proc(
|
||||||
vec![kw("key", Str), kw("value", Str)],
|
vec![kw("key", Str), kw("value", Str)],
|
||||||
|
@ -49,20 +58,23 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("putenv"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"remove!",
|
"remove!",
|
||||||
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("remove"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"removedirs!",
|
"removedirs!",
|
||||||
nd_proc1(kw("name", mono("PathLike")), NoneType),
|
nd_proc1(kw("name", mono("PathLike")), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("removedirs"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"rename!",
|
"rename!",
|
||||||
proc(
|
proc(
|
||||||
vec![kw("src", mono("PathLike")), kw("dst", mono("PathLike"))],
|
vec![kw("src", mono("PathLike")), kw("dst", mono("PathLike"))],
|
||||||
|
@ -72,19 +84,22 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("rename"),
|
||||||
);
|
);
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"rmdir!",
|
"rmdir!",
|
||||||
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
nd_proc1(kw("path", mono("PathLike")), NoneType),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("rmdir"),
|
||||||
);
|
);
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
os.register_builtin_impl(
|
os.register_builtin_py_impl(
|
||||||
"uname!",
|
"uname!",
|
||||||
proc0(mono("posix.UnameResult")),
|
proc0(mono("posix.UnameResult")),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("uname"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
@ -15,7 +15,7 @@ use Visibility::*;
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn init_py_random_mod() -> Self {
|
pub(crate) fn init_py_random_mod() -> Self {
|
||||||
let mut random = Context::builtin_module("random", 10);
|
let mut random = Context::builtin_module("random", 10);
|
||||||
random.register_builtin_impl(
|
random.register_builtin_py_impl(
|
||||||
"seed!",
|
"seed!",
|
||||||
proc(
|
proc(
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -28,12 +28,14 @@ impl Context {
|
||||||
),
|
),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("seed"),
|
||||||
);
|
);
|
||||||
random.register_builtin_impl(
|
random.register_builtin_py_impl(
|
||||||
"randint!",
|
"randint!",
|
||||||
nd_proc(vec![kw("a", Int), kw("b", Int)], None, Int),
|
nd_proc(vec![kw("a", Int), kw("b", Int)], None, Int),
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
|
Some("randint"),
|
||||||
);
|
);
|
||||||
let t = nd_proc(
|
let t = nd_proc(
|
||||||
vec![kw("seq", poly("Seq", vec![ty_tp(mono_q("T"))]))],
|
vec![kw("seq", poly("Seq", vec![ty_tp(mono_q("T"))]))],
|
||||||
|
@ -41,7 +43,7 @@ impl Context {
|
||||||
mono_q("T"),
|
mono_q("T"),
|
||||||
);
|
);
|
||||||
let t = quant(t, set! {static_instance("T", Type)});
|
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
|
random
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,13 @@ impl Context {
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
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
|
socket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,14 @@ use Visibility::*;
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn init_py_time_mod() -> Self {
|
pub(crate) fn init_py_time_mod() -> Self {
|
||||||
let mut time = Context::builtin_module("time", 15);
|
let mut time = Context::builtin_module("time", 15);
|
||||||
time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public);
|
time.register_builtin_py_impl(
|
||||||
time.register_builtin_impl("time!", proc0(Float), Immutable, Public);
|
"sleep!",
|
||||||
|
proc1(Float, NoneType),
|
||||||
|
Immutable,
|
||||||
|
Public,
|
||||||
|
Some("sleep"),
|
||||||
|
);
|
||||||
|
time.register_builtin_py_impl("time!", proc0(Float), Immutable, Public, Some("time"));
|
||||||
time
|
time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,13 @@ impl Context {
|
||||||
urllib.py_mod_cache = Some(SharedModuleCache::new());
|
urllib.py_mod_cache = Some(SharedModuleCache::new());
|
||||||
let mut request_class = Context::builtin_mono_class("Request", 5);
|
let mut request_class = Context::builtin_mono_class("Request", 5);
|
||||||
request_class.register_builtin_impl("data", mono("Bytes"), Immutable, Public);
|
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);
|
urllib.register_builtin_impl("request", module_from_path("request"), Immutable, Public);
|
||||||
let mut request = Context::builtin_module("urllib.request", 15);
|
let mut request = Context::builtin_module("urllib.request", 15);
|
||||||
let t = proc(
|
let t = proc(
|
||||||
|
@ -30,7 +36,7 @@ impl Context {
|
||||||
],
|
],
|
||||||
mono("http.client.HTTPResponse"),
|
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);
|
urllib.register_builtin_impl("parse", module_from_path("parse"), Immutable, Public);
|
||||||
let parse = Context::builtin_module("urllib.parse", 15);
|
let parse = Context::builtin_module("urllib.parse", 15);
|
||||||
urllib
|
urllib
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::option::Option; // conflicting to Type::Option
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
|
use erg_common::env::erg_pystd_path;
|
||||||
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||||
use erg_common::levenshtein::get_similar_name;
|
use erg_common::levenshtein::get_similar_name;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
|
@ -29,12 +30,12 @@ use crate::error::{
|
||||||
TyCheckErrors, TyCheckResult,
|
TyCheckErrors, TyCheckResult,
|
||||||
};
|
};
|
||||||
use crate::hir;
|
use crate::hir;
|
||||||
use crate::varinfo::VarInfo;
|
use crate::varinfo::{Mutability, VarInfo, VarKind};
|
||||||
use crate::AccessKind;
|
use crate::AccessKind;
|
||||||
use RegistrationMode::*;
|
use RegistrationMode::*;
|
||||||
use Visibility::*;
|
use Visibility::*;
|
||||||
|
|
||||||
use super::MethodType;
|
use super::MethodInfo;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub(crate) fn validate_var_sig_t(
|
pub(crate) fn validate_var_sig_t(
|
||||||
|
@ -209,7 +210,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
pos_args: &[hir::PosArg],
|
pos_args: &[hir::PosArg],
|
||||||
kw_args: &[hir::KwArg],
|
kw_args: &[hir::KwArg],
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
if !kw_args.is_empty() {
|
if !kw_args.is_empty() {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -284,14 +285,17 @@ impl Context {
|
||||||
let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
|
let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
|
||||||
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
|
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
|
||||||
let t = func(param_ts, None, vec![], return_t);
|
let t = func(param_ts, None, vec![], return_t);
|
||||||
Ok(t)
|
Ok(VarInfo {
|
||||||
|
t,
|
||||||
|
..VarInfo::default()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_import_call_t(
|
fn get_import_call_t(
|
||||||
&self,
|
&self,
|
||||||
pos_args: &[hir::PosArg],
|
pos_args: &[hir::PosArg],
|
||||||
kw_args: &[hir::KwArg],
|
kw_args: &[hir::KwArg],
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
let mod_name = pos_args
|
let mod_name = pos_args
|
||||||
.get(0)
|
.get(0)
|
||||||
.map(|a| &a.expr)
|
.map(|a| &a.expr)
|
||||||
|
@ -337,20 +341,24 @@ impl Context {
|
||||||
vec![],
|
vec![],
|
||||||
module(TyParam::Value(s)),
|
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,
|
&self,
|
||||||
ident: &Identifier,
|
ident: &Identifier,
|
||||||
acc_kind: AccessKind,
|
acc_kind: AccessKind,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> SingleTyCheckResult<Type> {
|
) -> SingleTyCheckResult<VarInfo> {
|
||||||
if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) {
|
if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) {
|
||||||
match self.validate_visibility(ident, vi, input, namespace) {
|
match self.validate_visibility(ident, vi, input, namespace) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
return Ok(vi.t());
|
return Ok(vi.clone());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if !acc_kind.is_local() {
|
if !acc_kind.is_local() {
|
||||||
|
@ -360,7 +368,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
return 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(
|
Err(TyCheckError::no_var_error(
|
||||||
input.clone(),
|
input.clone(),
|
||||||
|
@ -372,17 +380,17 @@ impl Context {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rec_get_decl_t(
|
pub(crate) fn rec_get_decl_info(
|
||||||
&self,
|
&self,
|
||||||
ident: &Identifier,
|
ident: &Identifier,
|
||||||
acc_kind: AccessKind,
|
acc_kind: AccessKind,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> SingleTyCheckResult<Type> {
|
) -> SingleTyCheckResult<VarInfo> {
|
||||||
if let Some(vi) = self.decls.get(&ident.inspect()[..]) {
|
if let Some(vi) = self.decls.get(&ident.inspect()[..]) {
|
||||||
match self.validate_visibility(ident, vi, input, namespace) {
|
match self.validate_visibility(ident, vi, input, namespace) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
return Ok(vi.t());
|
return Ok(vi.clone());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if !acc_kind.is_local() {
|
if !acc_kind.is_local() {
|
||||||
|
@ -392,7 +400,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
return 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(
|
Err(TyCheckError::no_var_error(
|
||||||
input.clone(),
|
input.clone(),
|
||||||
|
@ -404,16 +412,16 @@ impl Context {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rec_get_attr_t(
|
pub(crate) fn rec_get_attr_info(
|
||||||
&self,
|
&self,
|
||||||
obj: &hir::Expr,
|
obj: &hir::Expr,
|
||||||
ident: &Identifier,
|
ident: &Identifier,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> SingleTyCheckResult<Type> {
|
) -> SingleTyCheckResult<VarInfo> {
|
||||||
let self_t = obj.t();
|
let self_t = obj.t();
|
||||||
let name = ident.name.token();
|
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) => {
|
Ok(t) => {
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
}
|
}
|
||||||
|
@ -423,9 +431,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) {
|
if let Ok(singular_ctx) = self.get_singular_ctx(obj, namespace) {
|
||||||
match singular_ctx.rec_get_var_t(ident, AccessKind::Attr, input, namespace) {
|
match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
|
||||||
Ok(t) => {
|
Ok(vi) => {
|
||||||
return Ok(t);
|
return Ok(vi);
|
||||||
}
|
}
|
||||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -443,7 +451,7 @@ impl Context {
|
||||||
None, // TODO:
|
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) => {
|
Ok(t) => {
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +463,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
// TODO: dependent type widening
|
// TODO: dependent type widening
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
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 {
|
} else {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
input.clone(),
|
input.clone(),
|
||||||
|
@ -471,32 +479,42 @@ impl Context {
|
||||||
|
|
||||||
/// get type from given attributive type (Record).
|
/// get type from given attributive type (Record).
|
||||||
/// not ModuleType or ClassType etc.
|
/// not ModuleType or ClassType etc.
|
||||||
fn get_attr_t_from_attributive(
|
fn get_attr_info_from_attributive(
|
||||||
&self,
|
&self,
|
||||||
obj: &hir::Expr,
|
obj: &hir::Expr,
|
||||||
t: &Type,
|
t: &Type,
|
||||||
ident: &Identifier,
|
ident: &Identifier,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> SingleTyCheckResult<Type> {
|
) -> SingleTyCheckResult<VarInfo> {
|
||||||
match t {
|
match t {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => {
|
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) => {
|
Type::FreeVar(fv) => {
|
||||||
let sup = fv.get_sup().unwrap();
|
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, .. } => {
|
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) => {
|
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) => {
|
Type::Record(record) => {
|
||||||
// REVIEW: `rec.get(name.inspect())` returns None (Borrow<Str> is implemented for Field). Why?
|
// REVIEW: `rec.get(name.inspect())` returns None (Borrow<Str> is implemented for Field). Why?
|
||||||
if let Some(attr) = record.get(&Field::new(Public, ident.inspect().clone())) {
|
if let Some(attr_t) = record.get(&Field::new(Public, ident.inspect().clone())) {
|
||||||
Ok(attr.clone())
|
let muty = Mutability::from(&ident.inspect()[..]);
|
||||||
|
let vi = VarInfo::new(
|
||||||
|
attr_t.clone(),
|
||||||
|
muty,
|
||||||
|
Public,
|
||||||
|
VarKind::Builtin,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
Ok(vi)
|
||||||
} else {
|
} else {
|
||||||
let t = Type::Record(record.clone());
|
let t = Type::Record(record.clone());
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
|
@ -515,7 +533,18 @@ impl Context {
|
||||||
match v {
|
match v {
|
||||||
ValueObj::Type(TypeObj::Generated(gen)) => self
|
ValueObj::Type(TypeObj::Generated(gen)) => self
|
||||||
.get_gen_t_require_attr_t(gen, &ident.inspect()[..])
|
.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(|| {
|
.ok_or_else(|| {
|
||||||
TyCheckError::dummy(self.cfg.input.clone(), line!() as usize)
|
TyCheckError::dummy(self.cfg.input.clone(), line!() as usize)
|
||||||
}),
|
}),
|
||||||
|
@ -539,13 +568,13 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns callee's type, not the return type
|
// returns callee's type, not the return type
|
||||||
fn search_callee_t(
|
fn search_callee_info(
|
||||||
&self,
|
&self,
|
||||||
obj: &hir::Expr,
|
obj: &hir::Expr,
|
||||||
attr_name: &Option<Identifier>,
|
attr_name: &Option<Identifier>,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> SingleTyCheckResult<Type> {
|
) -> SingleTyCheckResult<VarInfo> {
|
||||||
if let Some(attr_name) = attr_name.as_ref() {
|
if let Some(attr_name) = attr_name.as_ref() {
|
||||||
for ctx in self
|
for ctx in self
|
||||||
.get_nominal_super_type_ctxs(obj.ref_t())
|
.get_nominal_super_type_ctxs(obj.ref_t())
|
||||||
|
@ -566,7 +595,7 @@ impl Context {
|
||||||
.or_else(|| ctx.decls.get(attr_name.inspect()))
|
.or_else(|| ctx.decls.get(attr_name.inspect()))
|
||||||
{
|
{
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
return Ok(vi.t());
|
return Ok(vi.clone());
|
||||||
}
|
}
|
||||||
for (_, methods_ctx) in ctx.methods_list.iter() {
|
for (_, methods_ctx) in ctx.methods_list.iter() {
|
||||||
if let Some(vi) = methods_ctx
|
if let Some(vi) = methods_ctx
|
||||||
|
@ -575,7 +604,7 @@ impl Context {
|
||||||
.or_else(|| methods_ctx.decls.get(attr_name.inspect()))
|
.or_else(|| methods_ctx.decls.get(attr_name.inspect()))
|
||||||
{
|
{
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
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()))
|
.or_else(|| singular_ctx.decls.get(attr_name.inspect()))
|
||||||
{
|
{
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
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() {
|
for (_, method_ctx) in singular_ctx.methods_list.iter() {
|
||||||
if let Some(vi) = method_ctx
|
if let Some(vi) = method_ctx
|
||||||
|
@ -595,7 +624,7 @@ impl Context {
|
||||||
.or_else(|| method_ctx.decls.get(attr_name.inspect()))
|
.or_else(|| method_ctx.decls.get(attr_name.inspect()))
|
||||||
{
|
{
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
return Ok(vi.t());
|
return Ok(vi.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(TyCheckError::singular_no_attr_error(
|
return Err(TyCheckError::singular_no_attr_error(
|
||||||
|
@ -610,11 +639,11 @@ impl Context {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
match self.get_method_type_by_name(attr_name) {
|
match self.get_method_type_by_name(attr_name) {
|
||||||
Ok(t) => {
|
Ok(method) => {
|
||||||
self.sub_unify(obj.ref_t(), &t.definition_type, obj.loc(), None)
|
self.sub_unify(obj.ref_t(), &method.definition_type, obj.loc(), None)
|
||||||
// HACK: change this func's return type to TyCheckResult<Type>
|
// HACK: change this func's return type to TyCheckResult<Type>
|
||||||
.map_err(|mut errs| errs.remove(0))?;
|
.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 => {
|
Err(err) if err.core.kind == ErrorKind::TypeError => {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
@ -632,7 +661,10 @@ impl Context {
|
||||||
self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
|
self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(obj.t())
|
Ok(VarInfo {
|
||||||
|
t: obj.t(),
|
||||||
|
..VarInfo::default()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,11 +709,11 @@ impl Context {
|
||||||
args: &[hir::PosArg],
|
args: &[hir::PosArg],
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
erg_common::debug_power_assert!(args.len() == 2);
|
erg_common::debug_power_assert!(args.len() == 2);
|
||||||
let cont = binop_to_dname(op.inspect());
|
let cont = binop_to_dname(op.inspect());
|
||||||
let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin);
|
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())),
|
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||||
AccessKind::Name,
|
AccessKind::Name,
|
||||||
input,
|
input,
|
||||||
|
@ -690,10 +722,11 @@ impl Context {
|
||||||
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
|
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
|
||||||
self.get_call_t(&op, &None, args, &[], input, namespace)
|
self.get_call_t(&op, &None, args, &[], input, namespace)
|
||||||
.map_err(|errs| {
|
.map_err(|errs| {
|
||||||
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 lhs = args[0].expr.clone();
|
||||||
let rhs = args[1].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(
|
TyCheckErrors::new(
|
||||||
errs.into_iter()
|
errs.into_iter()
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
|
@ -718,22 +751,23 @@ impl Context {
|
||||||
args: &[hir::PosArg],
|
args: &[hir::PosArg],
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
erg_common::debug_power_assert!(args.len() == 1);
|
erg_common::debug_power_assert!(args.len() == 1);
|
||||||
let cont = unaryop_to_dname(op.inspect());
|
let cont = unaryop_to_dname(op.inspect());
|
||||||
let symbol = Token::new(op.kind, Str::rc(cont), op.lineno, op.col_begin);
|
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())),
|
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||||
AccessKind::Name,
|
AccessKind::Name,
|
||||||
input,
|
input,
|
||||||
namespace,
|
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)
|
self.get_call_t(&op, &None, args, &[], input, namespace)
|
||||||
.map_err(|errs| {
|
.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 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(
|
TyCheckErrors::new(
|
||||||
errs.into_iter()
|
errs.into_iter()
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
|
@ -819,7 +853,6 @@ impl Context {
|
||||||
let attr = hir::Attribute::new(
|
let attr = hir::Attribute::new(
|
||||||
obj.clone(),
|
obj.clone(),
|
||||||
hir::Identifier::bare(ident.dot.clone(), ident.name.clone()),
|
hir::Identifier::bare(ident.dot.clone(), ident.name.clone()),
|
||||||
Type::Uninited,
|
|
||||||
);
|
);
|
||||||
hir::Expr::Accessor(hir::Accessor::Attr(attr))
|
hir::Expr::Accessor(hir::Accessor::Attr(attr))
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1130,7 @@ impl Context {
|
||||||
kw_args: &[hir::KwArg],
|
kw_args: &[hir::KwArg],
|
||||||
input: &Input,
|
input: &Input,
|
||||||
namespace: &Str,
|
namespace: &Str,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
||||||
if local.vis().is_private() {
|
if local.vis().is_private() {
|
||||||
match &local.inspect()[..] {
|
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!(
|
log!(
|
||||||
"Found:\ncallee: {obj}{}\nfound: {found}",
|
"Found:\ncallee: {obj}{}\nfound: {found}",
|
||||||
fmt_option!(pre ".", attr_name.as_ref().map(|ident| &ident.name))
|
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!(
|
log!(
|
||||||
"Instantiated:\ninstance: {instance}\npos_args: ({})\nkw_args: ({})",
|
"Instantiated:\ninstance: {instance}\npos_args: ({})\nkw_args: ({})",
|
||||||
fmt_slice(pos_args),
|
fmt_slice(pos_args),
|
||||||
|
@ -1139,6 +1172,7 @@ impl Context {
|
||||||
log!(info "Params evaluated:\nres: {res}\n");
|
log!(info "Params evaluated:\nres: {res}\n");
|
||||||
self.propagate(&res, obj)?;
|
self.propagate(&res, obj)?;
|
||||||
log!(info "Propagated:\nres: {res}\n");
|
log!(info "Propagated:\nres: {res}\n");
|
||||||
|
let res = VarInfo { t: res, ..found };
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1679,8 +1713,14 @@ impl Context {
|
||||||
let path =
|
let path =
|
||||||
option_enum_unwrap!(params.remove(0), TyParam::Value:(ValueObj::Str:(_)))?;
|
option_enum_unwrap!(params.remove(0), TyParam::Value:(ValueObj::Str:(_)))?;
|
||||||
let path = Path::new(&path[..]);
|
let path = Path::new(&path[..]);
|
||||||
|
// TODO: erg std
|
||||||
let path = if let Ok(path) = self.cfg.input.resolve(path) {
|
let path = if let Ok(path) = self.cfg.input.resolve(path) {
|
||||||
path
|
path
|
||||||
|
} else if let Ok(path) = erg_pystd_path()
|
||||||
|
.join(format!("{}.d.er", path.display()))
|
||||||
|
.canonicalize()
|
||||||
|
{
|
||||||
|
path
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from(format!("<builtins>.{}", path.display()))
|
PathBuf::from(format!("<builtins>.{}", 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
|
// TODO: min_by
|
||||||
if let Some(candidates) = self.method_to_traits.get(name.inspect()) {
|
if let Some(candidates) = self.method_to_traits.get(name.inspect()) {
|
||||||
let first_method_type = &candidates.first().unwrap().method_type;
|
let first_method_type = &candidates.first().unwrap().method_type;
|
||||||
|
|
|
@ -511,9 +511,9 @@ impl Context {
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
// -> Result<Type, (Type, TyCheckErrors)> {
|
// -> Result<Type, (Type, TyCheckErrors)> {
|
||||||
let opt_decl_sig_t = self
|
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()
|
.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 bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
||||||
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
||||||
let mut non_defaults = vec![];
|
let mut non_defaults = vec![];
|
||||||
|
|
|
@ -299,23 +299,23 @@ pub struct ContextInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct MethodType {
|
pub struct MethodInfo {
|
||||||
definition_type: Type,
|
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 {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{{ def: {} t: {} }}",
|
"{{ def: {} info: {} }}",
|
||||||
self.definition_type, self.method_type
|
self.definition_type, self.method_type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodType {
|
impl MethodInfo {
|
||||||
pub const fn new(definition_type: Type, method_type: Type) -> Self {
|
pub const fn new(definition_type: Type, method_type: VarInfo) -> Self {
|
||||||
Self {
|
Self {
|
||||||
definition_type,
|
definition_type,
|
||||||
method_type,
|
method_type,
|
||||||
|
@ -345,8 +345,8 @@ pub struct Context {
|
||||||
pub(crate) methods_list: Vec<(ClassDefType, Context)>,
|
pub(crate) methods_list: Vec<(ClassDefType, Context)>,
|
||||||
// K: method name, V: types defines the method
|
// K: method name, V: types defines the method
|
||||||
// If it is declared in a trait, it takes precedence over the class.
|
// If it is declared in a trait, it takes precedence over the class.
|
||||||
pub(crate) method_to_traits: Dict<Str, Vec<MethodType>>,
|
pub(crate) method_to_traits: Dict<Str, Vec<MethodInfo>>,
|
||||||
pub(crate) method_to_classes: Dict<Str, Vec<MethodType>>,
|
pub(crate) method_to_classes: Dict<Str, Vec<MethodInfo>>,
|
||||||
/// K: method name, V: impl patch
|
/// K: method name, V: impl patch
|
||||||
/// Provided methods can switch implementations on a scope-by-scope basis
|
/// Provided methods can switch implementations on a scope-by-scope basis
|
||||||
/// K: メソッド名, V: それを実装するパッチたち
|
/// K: メソッド名, V: それを実装するパッチたち
|
||||||
|
@ -462,13 +462,13 @@ impl Context {
|
||||||
let idx = ParamIdx::Nth(idx);
|
let idx = ParamIdx::Nth(idx);
|
||||||
let kind = VarKind::parameter(id, idx, param.default_info);
|
let kind = VarKind::parameter(id, idx, param.default_info);
|
||||||
let muty = Mutability::from(name);
|
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));
|
params_.push((Some(VarName::new(Token::static_symbol(name))), vi));
|
||||||
} else {
|
} else {
|
||||||
let idx = ParamIdx::Nth(idx);
|
let idx = ParamIdx::Nth(idx);
|
||||||
let kind = VarKind::parameter(id, idx, param.default_info);
|
let kind = VarKind::parameter(id, idx, param.default_info);
|
||||||
let muty = Mutability::Immutable;
|
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));
|
params_.push((None, vi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::ty::free::HasLevel;
|
use crate::ty::free::HasLevel;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
|
use erg_common::env::erg_pystd_path;
|
||||||
use erg_common::levenshtein::get_similar_name;
|
use erg_common::levenshtein::get_similar_name;
|
||||||
use erg_common::python_util::BUILTIN_PYTHON_MODS;
|
use erg_common::python_util::BUILTIN_PYTHON_MODS;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
|
@ -21,7 +22,7 @@ use crate::ty::{HasType, ParamTy, SubrType, Type};
|
||||||
|
|
||||||
use crate::build_hir::HIRBuilder;
|
use crate::build_hir::HIRBuilder;
|
||||||
use crate::context::{
|
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::readable_name;
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
|
@ -86,7 +87,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
self.decls.insert(
|
self.decls.insert(
|
||||||
ident.name.clone(),
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -122,11 +123,20 @@ impl Context {
|
||||||
kind.clone(),
|
kind.clone(),
|
||||||
Some(comptime_decos.clone()),
|
Some(comptime_decos.clone()),
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
self.decls.insert(sig.ident.name.clone(), vi);
|
self.decls.insert(sig.ident.name.clone(), vi);
|
||||||
e
|
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) {
|
if let Some(_decl) = self.decls.remove(name) {
|
||||||
Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error(
|
Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
@ -146,6 +156,7 @@ impl Context {
|
||||||
sig: &ast::VarSignature,
|
sig: &ast::VarSignature,
|
||||||
body_t: &Type,
|
body_t: &Type,
|
||||||
id: DefId,
|
id: DefId,
|
||||||
|
py_name: Option<Str>,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
let ident = match &sig.pat {
|
let ident = match &sig.pat {
|
||||||
ast::VarPattern::Ident(ident) => ident,
|
ast::VarPattern::Ident(ident) => ident,
|
||||||
|
@ -169,6 +180,7 @@ impl Context {
|
||||||
VarKind::Defined(id),
|
VarKind::Defined(id),
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
py_name,
|
||||||
);
|
);
|
||||||
log!(info "Registered {}::{}: {} {:?}", self.name, ident.name, vi.t, vi.impl_of);
|
log!(info "Registered {}::{}: {} {:?}", self.name, ident.name, vi.t, vi.impl_of);
|
||||||
self.locals.insert(ident.name.clone(), vi);
|
self.locals.insert(ident.name.clone(), vi);
|
||||||
|
@ -220,7 +232,7 @@ impl Context {
|
||||||
let muty = Mutability::from(&name.inspect()[..]);
|
let muty = Mutability::from(&name.inspect()[..]);
|
||||||
self.params.push((
|
self.params.push((
|
||||||
Some(name.clone()),
|
Some(name.clone()),
|
||||||
VarInfo::new(spec_t, muty, Private, kind, None, None),
|
VarInfo::new(spec_t, muty, Private, kind, None, None, None),
|
||||||
));
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -259,7 +271,7 @@ impl Context {
|
||||||
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
|
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
|
||||||
self.params.push((
|
self.params.push((
|
||||||
Some(name.clone()),
|
Some(name.clone()),
|
||||||
VarInfo::new(spec_t, Immutable, Private, kind, None, None),
|
VarInfo::new(spec_t, Immutable, Private, kind, None, None, None),
|
||||||
));
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -298,7 +310,7 @@ impl Context {
|
||||||
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
|
VarKind::parameter(DefId(get_hash(&(&self.name, name))), idx, default);
|
||||||
self.params.push((
|
self.params.push((
|
||||||
Some(name.clone()),
|
Some(name.clone()),
|
||||||
VarInfo::new(spec_t, Immutable, Private, kind, None, None),
|
VarInfo::new(spec_t, Immutable, Private, kind, None, None, None),
|
||||||
));
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -461,6 +473,7 @@ impl Context {
|
||||||
VarKind::Defined(id),
|
VarKind::Defined(id),
|
||||||
Some(comptime_decos),
|
Some(comptime_decos),
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let t = vi.t.clone();
|
let t = vi.t.clone();
|
||||||
log!(info "Registered {}::{name}: {t}", self.name);
|
log!(info "Registered {}::{name}: {t}", self.name);
|
||||||
|
@ -498,6 +511,7 @@ impl Context {
|
||||||
VarKind::DoesNotExist,
|
VarKind::DoesNotExist,
|
||||||
Some(comptime_decos),
|
Some(comptime_decos),
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
|
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
|
||||||
self.locals.insert(name.clone(), vi);
|
self.locals.insert(name.clone(), vi);
|
||||||
|
@ -582,6 +596,7 @@ impl Context {
|
||||||
t: Type,
|
t: Type,
|
||||||
muty: Mutability,
|
muty: Mutability,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
|
py_name: Option<Str>,
|
||||||
) {
|
) {
|
||||||
let name = VarName::from_static(name);
|
let name = VarName::from_static(name);
|
||||||
if self.locals.get(&name).is_some() {
|
if self.locals.get(&name).is_some() {
|
||||||
|
@ -589,7 +604,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name,
|
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,
|
t: Type,
|
||||||
muty: Mutability,
|
muty: Mutability,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
|
py_name: Option<Str>,
|
||||||
) {
|
) {
|
||||||
let name = VarName::from_static(name);
|
let name = VarName::from_static(name);
|
||||||
if self.locals.get(&name).is_some() {
|
if self.locals.get(&name).is_some() {
|
||||||
|
@ -608,7 +624,15 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name,
|
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,
|
t: Type,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
impl_of: Option<Type>,
|
impl_of: Option<Type>,
|
||||||
|
py_name: Option<Str>,
|
||||||
) {
|
) {
|
||||||
if self.decls.get(&name).is_some() {
|
if self.decls.get(&name).is_some() {
|
||||||
panic!("already registered: {name}");
|
panic!("already registered: {name}");
|
||||||
} else {
|
} else {
|
||||||
self.decls.insert(
|
self.decls.insert(
|
||||||
name,
|
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,
|
muty: Mutability,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
impl_of: Option<Type>,
|
impl_of: Option<Type>,
|
||||||
|
py_name: Option<Str>,
|
||||||
) {
|
) {
|
||||||
if self.locals.get(&name).is_some() {
|
if self.locals.get(&name).is_some() {
|
||||||
panic!("already registered: {name}");
|
panic!("already registered: {name}");
|
||||||
|
@ -644,7 +670,7 @@ impl Context {
|
||||||
let id = DefId(get_hash(&(&self.name, &name)));
|
let id = DefId(get_hash(&(&self.name, &name)));
|
||||||
self.locals.insert(
|
self.locals.insert(
|
||||||
name,
|
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),
|
VarKind::Defined(id),
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
self.decls.insert(ident.name.clone(), vi);
|
self.decls.insert(ident.name.clone(), vi);
|
||||||
self.consts.insert(ident.name.clone(), other);
|
self.consts.insert(ident.name.clone(), other);
|
||||||
|
@ -729,9 +756,15 @@ impl Context {
|
||||||
);
|
);
|
||||||
let require = gen.require_or_sup.typ().clone();
|
let require = gen.require_or_sup.typ().clone();
|
||||||
let new_t = func1(require, gen.t.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
|
ctx.methods_list
|
||||||
.push((ClassDefType::Simple(gen.t.clone()), methods));
|
.push((ClassDefType::Simple(gen.t.clone()), methods));
|
||||||
self.register_gen_mono_type(ident, gen, ctx, Const);
|
self.register_gen_mono_type(ident, gen, ctx, Const);
|
||||||
|
@ -786,9 +819,10 @@ impl Context {
|
||||||
new_t.clone(),
|
new_t.clone(),
|
||||||
Immutable,
|
Immutable,
|
||||||
Private,
|
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
|
ctx.methods_list
|
||||||
.push((ClassDefType::Simple(gen.t.clone()), methods));
|
.push((ClassDefType::Simple(gen.t.clone()), methods));
|
||||||
self.register_gen_mono_type(ident, gen, ctx, Const);
|
self.register_gen_mono_type(ident, gen, ctx, Const);
|
||||||
|
@ -823,6 +857,7 @@ impl Context {
|
||||||
VarKind::Declared,
|
VarKind::Declared,
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
ctx.decls
|
ctx.decls
|
||||||
.insert(VarName::from_str(field.symbol.clone()), vi);
|
.insert(VarName::from_str(field.symbol.clone()), vi);
|
||||||
|
@ -859,6 +894,7 @@ impl Context {
|
||||||
VarKind::Declared,
|
VarKind::Declared,
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
ctx.decls
|
ctx.decls
|
||||||
.insert(VarName::from_str(field.symbol.clone()), vi);
|
.insert(VarName::from_str(field.symbol.clone()), vi);
|
||||||
|
@ -895,6 +931,7 @@ impl Context {
|
||||||
VarKind::Defined(id),
|
VarKind::Defined(id),
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
self.consts
|
self.consts
|
||||||
|
@ -929,6 +966,7 @@ impl Context {
|
||||||
VarKind::Defined(id),
|
VarKind::Defined(id),
|
||||||
None,
|
None,
|
||||||
self.impl_of(),
|
self.impl_of(),
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
self.consts
|
self.consts
|
||||||
|
@ -945,21 +983,21 @@ impl Context {
|
||||||
}
|
}
|
||||||
for (trait_method, vi) in ctx.decls.iter() {
|
for (trait_method, vi) in ctx.decls.iter() {
|
||||||
if let Some(types) = self.method_to_traits.get_mut(trait_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_traits.insert(
|
self.method_to_traits.insert(
|
||||||
trait_method.inspect().clone(),
|
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() {
|
for (class_method, vi) in ctx.locals.iter() {
|
||||||
if let Some(types) = self.method_to_classes.get_mut(class_method.inspect()) {
|
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 {
|
} else {
|
||||||
self.method_to_classes.insert(
|
self.method_to_classes.insert(
|
||||||
class_method.inspect().clone(),
|
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,
|
mod_name: &Literal,
|
||||||
) -> CompileResult<PathBuf> {
|
) -> CompileResult<PathBuf> {
|
||||||
if kind.is_erg_import() {
|
if kind.is_erg_import() {
|
||||||
self.import_erg_mod(mod_name)
|
self.import_erg_mod_using_cache(mod_name)
|
||||||
} else {
|
} 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<PathBuf> {
|
fn import_erg_mod_using_cache(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
||||||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||||
let mod_cache = self.mod_cache.as_ref().unwrap();
|
let mod_cache = self.mod_cache.as_ref().unwrap();
|
||||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||||
#[allow(clippy::match_single_binding)]
|
#[allow(clippy::match_single_binding)]
|
||||||
match &__name__[..] {
|
match &__name__[..] {
|
||||||
// TODO: erg builtin modules
|
// 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,
|
&self,
|
||||||
__name__: Str,
|
__name__: Str,
|
||||||
mod_name: &Literal,
|
mod_name: &Literal,
|
||||||
|
@ -1045,13 +1083,14 @@ impl Context {
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_py_mod(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
fn import_py_mod_using_cache(&mut self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
||||||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||||
let builtin_path = PathBuf::from(&format!("<builtins>.{__name__}"));
|
let builtin_path = PathBuf::from(&format!("<builtins>.{__name__}"));
|
||||||
if py_mod_cache.get(&builtin_path).is_some() {
|
if py_mod_cache.get(&builtin_path).is_some() {
|
||||||
return Ok(builtin_path);
|
return Ok(builtin_path);
|
||||||
}
|
}
|
||||||
|
// TODO: rewrite all as `d.er`
|
||||||
match &__name__[..] {
|
match &__name__[..] {
|
||||||
"glob" => {
|
"glob" => {
|
||||||
py_mod_cache.register(builtin_path.clone(), None, Self::init_py_glob_mod());
|
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());
|
py_mod_cache.register(builtin_path.clone(), None, Self::init_py_urllib_mod());
|
||||||
Ok(builtin_path)
|
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)
|
get_similar_name(BUILTIN_PYTHON_MODS.into_iter(), name).map(Str::rc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_user_py_mod(&self, mod_name: &Literal) -> CompileResult<PathBuf> {
|
fn find_decl_in_pystd(__name__: &str) -> std::io::Result<PathBuf> {
|
||||||
|
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<PathBuf> {
|
||||||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
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 py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||||
let mut dir = if let Input::File(mut path) = self.cfg.input.clone() {
|
let mut dir = if let Input::File(mut path) = self.cfg.input.clone() {
|
||||||
path.pop();
|
path.pop();
|
||||||
|
@ -1115,7 +1161,10 @@ impl Context {
|
||||||
PathBuf::new()
|
PathBuf::new()
|
||||||
};
|
};
|
||||||
dir.push(format!("{__name__}.d.er"));
|
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,
|
Ok(path) => path,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err = TyCheckError::import_error(
|
let err = TyCheckError::import_error(
|
||||||
|
@ -1137,10 +1186,11 @@ impl Context {
|
||||||
let cfg = ErgConfig::with_module_path(path.clone());
|
let cfg = ErgConfig::with_module_path(path.clone());
|
||||||
let src = cfg.input.read();
|
let src = cfg.input.read();
|
||||||
let mut builder =
|
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") {
|
match builder.build(src, "declare") {
|
||||||
Ok(hir) => {
|
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)) => {
|
Err((maybe_hir, errs)) => {
|
||||||
if let Some(hir) = maybe_hir {
|
if let Some(hir) = maybe_hir {
|
||||||
|
|
|
@ -731,22 +731,9 @@ impl Context {
|
||||||
let loc = acc.loc();
|
let loc = acc.loc();
|
||||||
let t = acc.ref_mut_t();
|
let t = acc.ref_mut_t();
|
||||||
*t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
|
*t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
|
||||||
match acc {
|
if let hir::Accessor::Attr(attr) = acc {
|
||||||
hir::Accessor::Attr(attr) => {
|
|
||||||
self.resolve_expr_t(&mut attr.obj)?;
|
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())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
hir::Expr::Array(array) => match array {
|
hir::Expr::Array(array) => match array {
|
||||||
|
@ -839,8 +826,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
hir::Expr::Call(call) => {
|
hir::Expr::Call(call) => {
|
||||||
let loc = call.loc();
|
let loc = call.loc();
|
||||||
let t = call.signature_mut_t().unwrap();
|
if let Some(t) = call.signature_mut_t() {
|
||||||
*t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
|
*t = self.deref_tyvar(mem::take(t), Covariant, loc)?;
|
||||||
|
}
|
||||||
self.resolve_expr_t(&mut call.obj)?;
|
self.resolve_expr_t(&mut call.obj)?;
|
||||||
for arg in call.args.pos_args.iter_mut() {
|
for arg in call.args.pos_args.iter_mut() {
|
||||||
self.resolve_expr_t(&mut arg.expr)?;
|
self.resolve_expr_t(&mut arg.expr)?;
|
||||||
|
|
|
@ -2,7 +2,6 @@ use erg_common::log;
|
||||||
use erg_common::traits::Stream;
|
use erg_common::traits::Stream;
|
||||||
|
|
||||||
use crate::hir::{Accessor, AttrDef, Block, Expr, HIR};
|
use crate::hir::{Accessor, AttrDef, Block, Expr, HIR};
|
||||||
use crate::ty::Type;
|
|
||||||
|
|
||||||
pub struct HIRDesugarer {}
|
pub struct HIRDesugarer {}
|
||||||
|
|
||||||
|
@ -19,9 +18,10 @@ impl HIRDesugarer {
|
||||||
// _Self = C
|
// _Self = C
|
||||||
// a = C.x
|
// a = C.x
|
||||||
// x = 1
|
// x = 1
|
||||||
|
// m(self) = ...
|
||||||
// ↓
|
// ↓
|
||||||
// class C:
|
// class C:
|
||||||
// pass
|
// def m(self): ...
|
||||||
// C._Self = C
|
// C._Self = C
|
||||||
// C.a = C.x
|
// C.a = C.x
|
||||||
// C.x = 1
|
// C.x = 1
|
||||||
|
@ -39,11 +39,7 @@ impl HIRDesugarer {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|expr| match expr {
|
.map(|expr| match expr {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
let acc = Accessor::attr(
|
let acc = Accessor::attr(class.clone(), def.sig.into_ident());
|
||||||
class.clone(),
|
|
||||||
def.sig.into_ident(),
|
|
||||||
Type::Untyped,
|
|
||||||
);
|
|
||||||
let attr_def = AttrDef::new(acc, def.body.block);
|
let attr_def = AttrDef::new(acc, def.body.block);
|
||||||
Expr::AttrDef(attr_def)
|
Expr::AttrDef(attr_def)
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ impl SideEffectChecker {
|
||||||
if i == last_idx
|
if i == last_idx
|
||||||
&& self.block_stack.last().unwrap() == &Instant
|
&& self.block_stack.last().unwrap() == &Instant
|
||||||
&& !def.sig.is_procedural()
|
&& !def.sig.is_procedural()
|
||||||
&& chunk.t().is_procedural()
|
&& chunk.t().is_procedure()
|
||||||
{
|
{
|
||||||
self.errs.push(EffectError::proc_assign_error(
|
self.errs.push(EffectError::proc_assign_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
@ -324,7 +324,7 @@ impl SideEffectChecker {
|
||||||
},
|
},
|
||||||
// 引数がproceduralでも関数呼び出しなら副作用なし
|
// 引数がproceduralでも関数呼び出しなら副作用なし
|
||||||
Expr::Call(call) => {
|
Expr::Call(call) => {
|
||||||
if (call.obj.t().is_procedural()
|
if (call.obj.t().is_procedure()
|
||||||
|| call
|
|| call
|
||||||
.attr_name
|
.attr_name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -23,6 +23,7 @@ use crate::ty::{HasType, Type};
|
||||||
use crate::context::eval::type_from_token_kind;
|
use crate::context::eval::type_from_token_kind;
|
||||||
use crate::context::OperationKind;
|
use crate::context::OperationKind;
|
||||||
use crate::error::readable_name;
|
use crate::error::readable_name;
|
||||||
|
use crate::varinfo::VarInfo;
|
||||||
use crate::{impl_t, impl_t_for_enum};
|
use crate::{impl_t, impl_t_for_enum};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -310,7 +311,7 @@ pub struct Identifier {
|
||||||
pub dot: Option<Token>,
|
pub dot: Option<Token>,
|
||||||
pub name: VarName,
|
pub name: VarName,
|
||||||
pub qual_name: Option<Str>,
|
pub qual_name: Option<Str>,
|
||||||
pub t: Type,
|
pub vi: VarInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for Identifier {
|
impl NestedDisplay for Identifier {
|
||||||
|
@ -326,15 +327,33 @@ impl NestedDisplay for Identifier {
|
||||||
if let Some(qn) = &self.qual_name {
|
if let Some(qn) = &self.qual_name {
|
||||||
write!(f, "(qual_name: {})", qn)?;
|
write!(f, "(qual_name: {})", qn)?;
|
||||||
}
|
}
|
||||||
if self.t != Type::Uninited {
|
if self.vi.t != Type::Uninited {
|
||||||
write!(f, "(: {})", self.t)?;
|
write!(f, "(: {})", self.vi.t)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_display_from_nested!(Identifier);
|
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 {
|
impl Locational for Identifier {
|
||||||
fn loc(&self) -> Location {
|
fn loc(&self) -> Location {
|
||||||
|
@ -353,12 +372,17 @@ impl From<&Identifier> for Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
pub const fn new(dot: Option<Token>, name: VarName, qual_name: Option<Str>, t: Type) -> Self {
|
pub const fn new(
|
||||||
|
dot: Option<Token>,
|
||||||
|
name: VarName,
|
||||||
|
qual_name: Option<Str>,
|
||||||
|
vi: VarInfo,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
dot,
|
dot,
|
||||||
name,
|
name,
|
||||||
qual_name,
|
qual_name,
|
||||||
t,
|
vi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +406,7 @@ impl Identifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn bare(dot: Option<Token>, name: VarName) -> Self {
|
pub const fn bare(dot: Option<Token>, name: VarName) -> Self {
|
||||||
Self::new(dot, name, None, Type::Uninited)
|
Self::new(dot, name, None, VarInfo::const_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_const(&self) -> bool {
|
pub fn is_const(&self) -> bool {
|
||||||
|
@ -413,84 +437,41 @@ impl Identifier {
|
||||||
pub struct Attribute {
|
pub struct Attribute {
|
||||||
pub obj: Box<Expr>,
|
pub obj: Box<Expr>,
|
||||||
pub ident: Identifier,
|
pub ident: Identifier,
|
||||||
t: Type,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for Attribute {
|
impl NestedDisplay for Attribute {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
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_display_from_nested!(Attribute);
|
||||||
impl_locational!(Attribute, obj, ident);
|
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 {
|
impl Attribute {
|
||||||
pub fn new(obj: Expr, ident: Identifier, t: Type) -> Self {
|
pub fn new(obj: Expr, ident: Identifier) -> Self {
|
||||||
Self {
|
Self {
|
||||||
obj: Box::new(obj),
|
obj: Box::new(obj),
|
||||||
ident,
|
ident,
|
||||||
t,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// e.g. obj.0, obj.1
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct TupleAttribute {
|
|
||||||
pub obj: Box<Expr>,
|
|
||||||
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<Expr>,
|
|
||||||
pub(crate) index: Box<Expr>,
|
|
||||||
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 {
|
pub enum Accessor {
|
||||||
Ident(Identifier),
|
Ident(Identifier),
|
||||||
Attr(Attribute),
|
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_display_from_nested!(Accessor);
|
||||||
impl_locational_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr);
|
impl_locational_for_enum!(Accessor; Ident, Attr);
|
||||||
impl_t_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr);
|
impl_t_for_enum!(Accessor; Ident, Attr);
|
||||||
|
|
||||||
impl Accessor {
|
impl Accessor {
|
||||||
pub fn private_with_line(name: Str, line: usize) -> Self {
|
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))
|
Self::Ident(Identifier::public_with_line(Token::dummy(), name, line))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn private(name: Token, t: Type) -> Self {
|
pub const fn private(name: Token, vi: VarInfo) -> Self {
|
||||||
Self::Ident(Identifier::new(None, VarName::new(name), None, t))
|
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(
|
Self::Ident(Identifier::new(
|
||||||
Some(Token::dummy()),
|
Some(Token::dummy()),
|
||||||
VarName::new(name),
|
VarName::new(name),
|
||||||
None,
|
None,
|
||||||
t,
|
vi,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attr(obj: Expr, ident: Identifier, t: Type) -> Self {
|
pub fn attr(obj: Expr, ident: Identifier) -> Self {
|
||||||
Self::Attr(Attribute::new(obj, ident, t))
|
Self::Attr(Attribute::new(obj, ident))
|
||||||
}
|
|
||||||
|
|
||||||
pub fn subscr(obj: Expr, index: Expr, t: Type) -> Self {
|
|
||||||
Self::Subscr(Subscript::new(obj, index, t))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&self) -> String {
|
pub fn show(&self) -> String {
|
||||||
|
@ -548,15 +523,6 @@ impl Accessor {
|
||||||
+ "." // TODO: visibility
|
+ "." // TODO: visibility
|
||||||
+ readable_name(attr.ident.inspect())
|
+ 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 op: Token,
|
||||||
pub lhs: Box<Expr>,
|
pub lhs: Box<Expr>,
|
||||||
pub rhs: Box<Expr>,
|
pub rhs: Box<Expr>,
|
||||||
pub sig_t: Type, // e.g. (Int, Int) -> Int
|
pub info: VarInfo, // e.g. (Int, Int) -> Int
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for BinOp {
|
impl NestedDisplay for BinOp {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||||
writeln!(f, "`{}`(: {}):", self.op.content, self.sig_t)?;
|
writeln!(f, "`{}`(: {}):", self.op.content, self.info.t)?;
|
||||||
self.lhs.fmt_nest(f, level + 1)?;
|
self.lhs.fmt_nest(f, level + 1)?;
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
self.rhs.fmt_nest(f, level + 1)
|
self.rhs.fmt_nest(f, level + 1)
|
||||||
|
@ -991,26 +957,26 @@ impl NestedDisplay for BinOp {
|
||||||
impl HasType for BinOp {
|
impl HasType for BinOp {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_t(&self) -> &Type {
|
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 {
|
fn ref_mut_t(&mut self) -> &mut Type {
|
||||||
self.sig_t.mut_return_t().unwrap()
|
self.info.t.mut_return_t().unwrap()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lhs_t(&self) -> &Type {
|
fn lhs_t(&self) -> &Type {
|
||||||
self.sig_t.lhs_t()
|
self.info.t.lhs_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rhs_t(&self) -> &Type {
|
fn rhs_t(&self) -> &Type {
|
||||||
self.sig_t.rhs_t()
|
self.info.t.rhs_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
Some(&self.sig_t)
|
Some(&self.info.t)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
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_locational!(BinOp, lhs, rhs);
|
||||||
|
|
||||||
impl BinOp {
|
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 {
|
Self {
|
||||||
op,
|
op,
|
||||||
lhs: Box::new(lhs),
|
lhs: Box::new(lhs),
|
||||||
rhs: Box::new(rhs),
|
rhs: Box::new(rhs),
|
||||||
sig_t,
|
info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,16 +998,16 @@ impl BinOp {
|
||||||
pub struct UnaryOp {
|
pub struct UnaryOp {
|
||||||
pub op: Token,
|
pub op: Token,
|
||||||
pub expr: Box<Expr>,
|
pub expr: Box<Expr>,
|
||||||
pub sig_t: Type, // e.g. Neg -> Nat
|
pub info: VarInfo, // e.g. Neg -> Nat
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasType for UnaryOp {
|
impl HasType for UnaryOp {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_t(&self) -> &Type {
|
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 {
|
fn ref_mut_t(&mut self) -> &mut Type {
|
||||||
self.sig_t.mut_return_t().unwrap()
|
self.info.t.mut_return_t().unwrap()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lhs_t(&self) -> &Type {
|
fn lhs_t(&self) -> &Type {
|
||||||
|
@ -1053,17 +1019,17 @@ impl HasType for UnaryOp {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
Some(&self.sig_t)
|
Some(&self.info.t)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
Some(&mut self.sig_t)
|
Some(&mut self.info.t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for UnaryOp {
|
impl NestedDisplay for UnaryOp {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||||
writeln!(f, "`{}`(: {}):", self.op, self.sig_t)?;
|
writeln!(f, "`{}`(: {}):", self.op, self.info.t)?;
|
||||||
self.expr.fmt_nest(f, level + 1)
|
self.expr.fmt_nest(f, level + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1072,11 +1038,11 @@ impl_display_from_nested!(UnaryOp);
|
||||||
impl_locational!(UnaryOp, op, expr);
|
impl_locational!(UnaryOp, op, expr);
|
||||||
|
|
||||||
impl UnaryOp {
|
impl UnaryOp {
|
||||||
pub fn new(op: Token, expr: Expr, sig_t: Type) -> Self {
|
pub fn new(op: Token, expr: Expr, info: VarInfo) -> Self {
|
||||||
Self {
|
Self {
|
||||||
op,
|
op,
|
||||||
expr: Box::new(expr),
|
expr: Box::new(expr),
|
||||||
sig_t,
|
info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1086,19 +1052,11 @@ pub struct Call {
|
||||||
pub obj: Box<Expr>,
|
pub obj: Box<Expr>,
|
||||||
pub attr_name: Option<Identifier>,
|
pub attr_name: Option<Identifier>,
|
||||||
pub args: Args,
|
pub args: Args,
|
||||||
/// 全体の型(引数自体の型は関係ない)、e.g. `abs(-1)` -> `(self: Neg) -> Nat`
|
|
||||||
pub sig_t: Type,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for Call {
|
impl NestedDisplay for Call {
|
||||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
|
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
|
||||||
writeln!(
|
writeln!(f, "({}){}:", self.obj, fmt_option!(self.attr_name),)?;
|
||||||
f,
|
|
||||||
"({}){} (: {}):",
|
|
||||||
self.obj,
|
|
||||||
fmt_option!(self.attr_name),
|
|
||||||
self.sig_t
|
|
||||||
)?;
|
|
||||||
self.args.fmt_nest(f, level + 1)
|
self.args.fmt_nest(f, level + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1108,27 +1066,51 @@ impl_display_from_nested!(Call);
|
||||||
impl HasType for Call {
|
impl HasType for Call {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_t(&self) -> &Type {
|
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]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
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]
|
#[inline]
|
||||||
fn lhs_t(&self) -> &Type {
|
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]
|
#[inline]
|
||||||
fn rhs_t(&self) -> &Type {
|
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]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
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]
|
#[inline]
|
||||||
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
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 {
|
impl Call {
|
||||||
pub fn new(obj: Expr, attr_name: Option<Identifier>, args: Args, sig_t: Type) -> Self {
|
pub fn new(obj: Expr, attr_name: Option<Identifier>, args: Args) -> Self {
|
||||||
Self {
|
Self {
|
||||||
obj: Box::new(obj),
|
obj: Box::new(obj),
|
||||||
attr_name,
|
attr_name,
|
||||||
args,
|
args,
|
||||||
sig_t,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_method(&self) -> bool {
|
pub fn is_method_call(&self) -> bool {
|
||||||
self.sig_t.self_t().is_some()
|
self.signature_t()
|
||||||
|
.map(|t| t.self_t().is_some())
|
||||||
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn additional_operation(&self) -> Option<OperationKind> {
|
pub fn additional_operation(&self) -> Option<OperationKind> {
|
||||||
|
|
1
compiler/erg_compiler/lib/pystd/subprocess.d.er
Normal file
1
compiler/erg_compiler/lib/pystd/subprocess.d.er
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.run!: (args: Str or [Str; _], shell := Bool) => NoneType
|
|
@ -62,6 +62,9 @@ class Bool(Nat):
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
|
class Str(str):
|
||||||
|
pass
|
||||||
|
|
||||||
class Range:
|
class Range:
|
||||||
def __init__(self, start, end):
|
def __init__(self, start, end):
|
||||||
self.start = start
|
self.start = start
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
.run!: (args: Str,) => NoneType
|
|
|
@ -45,13 +45,6 @@ impl<'a> Linker<'a> {
|
||||||
Accessor::Attr(attr) => {
|
Accessor::Attr(attr) => {
|
||||||
self.replace_import(&mut attr.obj);
|
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(_) => {}
|
Accessor::Ident(_) => {}
|
||||||
},
|
},
|
||||||
Expr::Array(array) => match array {
|
Expr::Array(array) => match array {
|
||||||
|
@ -192,12 +185,7 @@ impl<'a> Linker<'a> {
|
||||||
let module_type =
|
let module_type =
|
||||||
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
||||||
let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None);
|
let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None);
|
||||||
let block = Block::new(vec![Expr::Call(Call::new(
|
let block = Block::new(vec![Expr::Call(Call::new(module_type, None, args))]);
|
||||||
module_type,
|
|
||||||
None,
|
|
||||||
args,
|
|
||||||
Type::Uninited,
|
|
||||||
))]);
|
|
||||||
let tmp =
|
let tmp =
|
||||||
Identifier::private_with_line(Str::from(fresh_varname()), expr.ln_begin().unwrap());
|
Identifier::private_with_line(Str::from(fresh_varname()), expr.ln_begin().unwrap());
|
||||||
let mod_def = Expr::Def(Def::new(
|
let mod_def = Expr::Def(Def::new(
|
||||||
|
@ -206,15 +194,14 @@ impl<'a> Linker<'a> {
|
||||||
));
|
));
|
||||||
let module = Expr::Accessor(Accessor::Ident(tmp));
|
let module = Expr::Accessor(Accessor::Ident(tmp));
|
||||||
let __dict__ = Identifier::public("__dict__");
|
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 = 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 args = Args::new(vec![PosArg::new(locals_call)], None, vec![], None);
|
||||||
let mod_update = Expr::Call(Call::new(
|
let mod_update = Expr::Call(Call::new(
|
||||||
m_dict.clone(),
|
m_dict.clone(),
|
||||||
Some(Identifier::public("update")),
|
Some(Identifier::public("update")),
|
||||||
args,
|
args,
|
||||||
Type::Uninited,
|
|
||||||
));
|
));
|
||||||
let exec = Expr::Accessor(Accessor::public_with_line(Str::ever("exec"), line));
|
let exec = Expr::Accessor(Accessor::public_with_line(Str::ever("exec"), line));
|
||||||
let args = Args::new(
|
let args = Args::new(
|
||||||
|
@ -223,7 +210,7 @@ impl<'a> Linker<'a> {
|
||||||
vec![],
|
vec![],
|
||||||
None,
|
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]);
|
let compound = Block::new(vec![mod_def, mod_update, exec_code, module]);
|
||||||
*expr = Expr::Compound(compound);
|
*expr = Expr::Compound(compound);
|
||||||
}
|
}
|
||||||
|
@ -277,7 +264,6 @@ impl<'a> Linker<'a> {
|
||||||
Str::rc(attr.as_os_str().to_str().unwrap()),
|
Str::rc(attr.as_os_str().to_str().unwrap()),
|
||||||
line,
|
line,
|
||||||
),
|
),
|
||||||
Type::Uninited,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,49 +571,32 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
ast::Accessor::Attr(attr) => {
|
ast::Accessor::Attr(attr) => {
|
||||||
let obj = self.lower_expr(*attr.obj)?;
|
let obj = self.lower_expr(*attr.obj)?;
|
||||||
let t =
|
let vi = self.ctx.rec_get_attr_info(
|
||||||
self.ctx
|
&obj,
|
||||||
.rec_get_attr_t(&obj, &attr.ident, &self.cfg.input, &self.ctx.name)?;
|
&attr.ident,
|
||||||
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
|
&self.cfg.input,
|
||||||
let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident, t));
|
&self.ctx.name,
|
||||||
Ok(acc)
|
)?;
|
||||||
}
|
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi);
|
||||||
ast::Accessor::TupleAttr(t_attr) => {
|
let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident));
|
||||||
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));
|
|
||||||
Ok(acc)
|
Ok(acc)
|
||||||
}
|
}
|
||||||
ast::Accessor::TypeApp(_t_app) => {
|
ast::Accessor::TypeApp(_t_app) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
// TupleAttr, Subscr are desugared
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_ident(&self, ident: ast::Identifier) -> LowerResult<hir::Identifier> {
|
fn lower_ident(&self, ident: ast::Identifier) -> LowerResult<hir::Identifier> {
|
||||||
// `match` is an untypable special form
|
// `match` is an untypable special form
|
||||||
// `match`は型付け不可能な特殊形式
|
// `match`は型付け不可能な特殊形式
|
||||||
let (t, __name__) = if ident.vis().is_private() && &ident.inspect()[..] == "match" {
|
let (vi, __name__) = if ident.vis().is_private() && &ident.inspect()[..] == "match" {
|
||||||
(Type::Untyped, None)
|
(VarInfo::default(), None)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
self.ctx.rec_get_var_t(
|
self.ctx.rec_get_var_info(
|
||||||
&ident,
|
&ident,
|
||||||
AccessKind::Name,
|
AccessKind::Name,
|
||||||
&self.cfg.input,
|
&self.cfg.input,
|
||||||
|
@ -625,7 +608,7 @@ impl ASTLowerer {
|
||||||
.map(|ctx| ctx.name.clone()),
|
.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)
|
Ok(ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,8 +674,8 @@ impl ASTLowerer {
|
||||||
for arg in kw_args.into_iter() {
|
for arg in kw_args.into_iter() {
|
||||||
hir_args.push_kw(hir::KwArg::new(arg.keyword, self.lower_expr(arg.expr)?));
|
hir_args.push_kw(hir::KwArg::new(arg.keyword, self.lower_expr(arg.expr)?));
|
||||||
}
|
}
|
||||||
let obj = self.lower_expr(*call.obj)?;
|
let mut obj = self.lower_expr(*call.obj)?;
|
||||||
let sig_t = self.ctx.get_call_t(
|
let vi = self.ctx.get_call_t(
|
||||||
&obj,
|
&obj,
|
||||||
&call.attr_name,
|
&call.attr_name,
|
||||||
&hir_args.pos_args,
|
&hir_args.pos_args,
|
||||||
|
@ -705,12 +688,13 @@ impl ASTLowerer {
|
||||||
attr_name.dot,
|
attr_name.dot,
|
||||||
attr_name.name,
|
attr_name.name,
|
||||||
None,
|
None,
|
||||||
Type::Uninited,
|
vi,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
*obj.ref_mut_t() = vi.t;
|
||||||
None
|
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() {
|
match call.additional_operation() {
|
||||||
Some(kind @ (OperationKind::Import | OperationKind::PyImport)) => {
|
Some(kind @ (OperationKind::Import | OperationKind::PyImport)) => {
|
||||||
let mod_name =
|
let mod_name =
|
||||||
|
@ -762,7 +746,7 @@ impl ASTLowerer {
|
||||||
pack.connector.col_begin,
|
pack.connector.col_begin,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
let sig_t = self.ctx.get_call_t(
|
let vi = self.ctx.get_call_t(
|
||||||
&class,
|
&class,
|
||||||
&Some(attr_name.clone()),
|
&Some(attr_name.clone()),
|
||||||
&args,
|
&args,
|
||||||
|
@ -771,8 +755,8 @@ impl ASTLowerer {
|
||||||
&self.ctx.name,
|
&self.ctx.name,
|
||||||
)?;
|
)?;
|
||||||
let args = hir::Args::new(args, None, vec![], None);
|
let args = hir::Args::new(args, None, vec![], None);
|
||||||
let attr_name = hir::Identifier::bare(attr_name.dot, attr_name.name);
|
let attr_name = hir::Identifier::new(attr_name.dot, attr_name.name, None, vi);
|
||||||
Ok(hir::Call::new(class, Some(attr_name), args, sig_t))
|
Ok(hir::Call::new(class, Some(attr_name), args))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: varargs
|
/// TODO: varargs
|
||||||
|
@ -927,11 +911,12 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.ctx
|
self.ctx.outer.as_mut().unwrap().assign_var_sig(
|
||||||
.outer
|
&sig,
|
||||||
.as_mut()
|
found_body_t,
|
||||||
.unwrap()
|
body.id,
|
||||||
.assign_var_sig(&sig, found_body_t, body.id)?;
|
None,
|
||||||
|
)?;
|
||||||
let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
|
let ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
|
||||||
let sig = hir::VarSignature::new(ident, found_body_t.clone());
|
let sig = hir::VarSignature::new(ident, found_body_t.clone());
|
||||||
let body = hir::DefBody::new(body.op, block, body.id);
|
let body = hir::DefBody::new(body.op, block, body.id);
|
||||||
|
@ -942,6 +927,7 @@ impl ASTLowerer {
|
||||||
&sig,
|
&sig,
|
||||||
&Type::Failure,
|
&Type::Failure,
|
||||||
ast::DefId(0),
|
ast::DefId(0),
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
Err(errs)
|
Err(errs)
|
||||||
}
|
}
|
||||||
|
@ -1463,14 +1449,20 @@ impl ASTLowerer {
|
||||||
self.ctx.caused_by(),
|
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 found_body_t = block.ref_t();
|
||||||
let ident = match &sig.pat {
|
let ident = match &sig.pat {
|
||||||
ast::VarPattern::Ident(ident) => ident,
|
ast::VarPattern::Ident(ident) => ident,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let id = body.id;
|
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 ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
|
||||||
let sig = hir::VarSignature::new(ident, found_body_t.clone());
|
let sig = hir::VarSignature::new(ident, found_body_t.clone());
|
||||||
let body = hir::DefBody::new(body.op, block, body.id);
|
let body = hir::DefBody::new(body.op, block, body.id);
|
||||||
|
@ -1515,7 +1507,7 @@ impl ASTLowerer {
|
||||||
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
||||||
let obj = self.fake_lower_obj(*attr.obj)?;
|
let obj = self.fake_lower_obj(*attr.obj)?;
|
||||||
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
|
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))
|
Ok(hir::Expr::Accessor(acc))
|
||||||
}
|
}
|
||||||
other => Err(LowerErrors::from(LowerError::declare_error(
|
other => Err(LowerErrors::from(LowerError::declare_error(
|
||||||
|
@ -1527,10 +1519,11 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_type(&mut self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
|
fn declare_ident(&mut self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
|
||||||
log!(info "entered {}({})", fn_name!(), tasc);
|
log!(info "entered {}({})", fn_name!(), tasc);
|
||||||
match *tasc.expr {
|
match *tasc.expr {
|
||||||
ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
|
ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
|
||||||
|
let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
|
||||||
let t = self.ctx.instantiate_typespec(
|
let t = self.ctx.instantiate_typespec(
|
||||||
&tasc.t_spec,
|
&tasc.t_spec,
|
||||||
None,
|
None,
|
||||||
|
@ -1545,6 +1538,7 @@ impl ASTLowerer {
|
||||||
VarKind::Declared,
|
VarKind::Declared,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
Some(py_name.clone()),
|
||||||
);
|
);
|
||||||
self.ctx.decls.insert(ident.name.clone(), vi);
|
self.ctx.decls.insert(ident.name.clone(), vi);
|
||||||
}
|
}
|
||||||
|
@ -1552,6 +1546,7 @@ impl ASTLowerer {
|
||||||
&ast::VarSignature::new(ast::VarPattern::Ident(ident.clone()), None),
|
&ast::VarSignature::new(ast::VarPattern::Ident(ident.clone()), None),
|
||||||
&t,
|
&t,
|
||||||
ast::DefId(0),
|
ast::DefId(0),
|
||||||
|
Some(py_name),
|
||||||
)?;
|
)?;
|
||||||
match t {
|
match t {
|
||||||
Type::ClassType => {
|
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(
|
Ok(hir::TypeAscription::new(
|
||||||
hir::Expr::Accessor(hir::Accessor::Ident(ident)),
|
hir::Expr::Accessor(hir::Accessor::Ident(ident)),
|
||||||
tasc.t_spec,
|
tasc.t_spec,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
|
||||||
|
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
||||||
let t = self.ctx.instantiate_typespec(
|
let t = self.ctx.instantiate_typespec(
|
||||||
&tasc.t_spec,
|
&tasc.t_spec,
|
||||||
None,
|
None,
|
||||||
|
@ -1597,11 +1597,15 @@ impl ASTLowerer {
|
||||||
&ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None),
|
&ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None),
|
||||||
&t,
|
&t,
|
||||||
ast::DefId(0),
|
ast::DefId(0),
|
||||||
|
Some(py_name),
|
||||||
)?;
|
)?;
|
||||||
let obj = self.fake_lower_obj(*attr.obj)?;
|
let obj = self.fake_lower_obj(*attr.obj)?;
|
||||||
let ident =
|
let muty = Mutability::from(&attr.ident.inspect()[..]);
|
||||||
hir::Identifier::new(attr.ident.dot, attr.ident.name, None, Type::Uninited);
|
let vis = attr.ident.vis();
|
||||||
let attr = hir::Accessor::attr(obj, ident, t);
|
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(
|
Ok(hir::TypeAscription::new(
|
||||||
hir::Expr::Accessor(attr),
|
hir::Expr::Accessor(attr),
|
||||||
tasc.t_spec,
|
tasc.t_spec,
|
||||||
|
@ -1626,7 +1630,7 @@ impl ASTLowerer {
|
||||||
"class declaration",
|
"class declaration",
|
||||||
self.ctx.caused_by(),
|
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(
|
other => Err(LowerErrors::from(LowerError::declare_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl OwnershipChecker {
|
||||||
// TODO: referenced
|
// TODO: referenced
|
||||||
Expr::Call(call) => {
|
Expr::Call(call) => {
|
||||||
let args_owns = call.signature_t().unwrap().args_ownership();
|
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
|
args_owns.non_defaults.len() - 1
|
||||||
} else {
|
} else {
|
||||||
args_owns.non_defaults.len()
|
args_owns.non_defaults.len()
|
||||||
|
@ -227,11 +227,6 @@ impl OwnershipChecker {
|
||||||
// REVIEW: is ownership the same?
|
// REVIEW: is ownership the same?
|
||||||
self.check_expr(&attr.obj, ownership, false)
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1734,14 +1734,14 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Procedure or MutType?
|
/// Procedure
|
||||||
pub fn is_procedural(&self) -> bool {
|
pub fn is_procedure(&self) -> bool {
|
||||||
match self {
|
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::Callable { .. } => true,
|
||||||
Self::Subr(subr) if subr.kind == SubrKind::Proc => true,
|
Self::Subr(subr) if subr.kind == SubrKind::Proc => true,
|
||||||
Self::Refinement(refine) =>
|
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))
|
matches!(pred, Predicate::Equal{ rhs, .. } if pred.mentions(&refine.var) && rhs.qual_name().map(|n| n.ends_with('!')).unwrap_or(false))
|
||||||
),
|
),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -2229,6 +2229,9 @@ impl Type {
|
||||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||||
Some(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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2243,6 +2246,7 @@ impl Type {
|
||||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||||
Some(return_t)
|
Some(return_t)
|
||||||
}
|
}
|
||||||
|
// Self::Quantified(quant) => quant.unbound_callable.mut_return_t(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ pub struct VarInfo {
|
||||||
pub kind: VarKind,
|
pub kind: VarKind,
|
||||||
pub comptime_decos: Option<Set<Str>>,
|
pub comptime_decos: Option<Set<Str>>,
|
||||||
pub impl_of: Option<Type>,
|
pub impl_of: Option<Type>,
|
||||||
|
pub py_name: Option<Str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for VarInfo {
|
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 {
|
impl VarInfo {
|
||||||
pub const ILLEGAL: &'static Self = &VarInfo::new(
|
pub const ILLEGAL: &'static Self = &Self::const_default();
|
||||||
Type::Failure,
|
|
||||||
|
pub const fn const_default() -> Self {
|
||||||
|
Self::new(
|
||||||
|
Type::Untyped,
|
||||||
Immutable,
|
Immutable,
|
||||||
Private,
|
Private,
|
||||||
VarKind::DoesNotExist,
|
VarKind::DoesNotExist,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
t: Type,
|
t: Type,
|
||||||
|
@ -171,6 +183,7 @@ impl VarInfo {
|
||||||
kind: VarKind,
|
kind: VarKind,
|
||||||
comptime_decos: Option<Set<Str>>,
|
comptime_decos: Option<Set<Str>>,
|
||||||
impl_of: Option<Type>,
|
impl_of: Option<Type>,
|
||||||
|
py_name: Option<Str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
t,
|
t,
|
||||||
|
@ -179,6 +192,7 @@ impl VarInfo {
|
||||||
kind,
|
kind,
|
||||||
comptime_decos,
|
comptime_decos,
|
||||||
impl_of,
|
impl_of,
|
||||||
|
py_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1963,7 +1963,7 @@ impl Parser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match self.try_reduce_arg(false).map_err(|_| self.stack_dec())? {
|
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() => {
|
Expr::Tuple(Tuple::Normal(tup)) if tup.elems.paren.is_none() => {
|
||||||
args.extend_pos(tup.elems.into_iters().0);
|
args.extend_pos(tup.elems.into_iters().0);
|
||||||
}
|
}
|
||||||
|
@ -1971,12 +1971,27 @@ impl Parser {
|
||||||
args.push_pos(PosArg::new(other));
|
args.push_pos(PosArg::new(other));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PosOrKwArg::Kw(arg) => {
|
PosOrKwArg::Pos(arg) => {
|
||||||
self.level -= 1;
|
let err = ParseError::syntax_error(
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, arg.loc());
|
line!() as usize,
|
||||||
|
arg.loc(),
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => "非デフォルト引数はデフォルト引数の後に指定できません",
|
||||||
|
"english" => "non-default argument follows default argument",
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
);
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return 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(());*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue