mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Add Del
This commit is contained in:
parent
64be2da03b
commit
2f33c9b15d
9 changed files with 110 additions and 31 deletions
|
@ -1203,6 +1203,17 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_del_instr(&mut self, mut args: Args) {
|
||||||
|
let ident = enum_unwrap!(args.remove_left_or_key("obj").unwrap(), Expr::Accessor:(Accessor::Ident:(_)));
|
||||||
|
log!(info "entered {} ({ident})", fn_name!());
|
||||||
|
let escaped = escape_name(ident);
|
||||||
|
let name = self
|
||||||
|
.local_search(&escaped, Name)
|
||||||
|
.unwrap_or_else(|| self.register_name(escaped));
|
||||||
|
self.write_instr(DELETE_NAME);
|
||||||
|
self.write_arg(name.idx as u8);
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_discard_instr(&mut self, mut args: Args) {
|
fn emit_discard_instr(&mut self, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
while let Some(arg) = args.try_remove(0) {
|
while let Some(arg) = args.try_remove(0) {
|
||||||
|
@ -1446,6 +1457,7 @@ impl CodeGenerator {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
match &local.inspect()[..] {
|
match &local.inspect()[..] {
|
||||||
"assert" => self.emit_assert_instr(args),
|
"assert" => self.emit_assert_instr(args),
|
||||||
|
"Del" => self.emit_del_instr(args),
|
||||||
"discard" => self.emit_discard_instr(args),
|
"discard" => self.emit_discard_instr(args),
|
||||||
"for" | "for!" => self.emit_for_instr(args),
|
"for" | "for!" => self.emit_for_instr(args),
|
||||||
"if" | "if!" => self.emit_if_instr(args),
|
"if" | "if!" => self.emit_if_instr(args),
|
||||||
|
|
|
@ -1586,7 +1586,7 @@ impl Context {
|
||||||
mono_q("T"),
|
mono_q("T"),
|
||||||
);
|
);
|
||||||
let t_cond = quant(t_cond, set! {static_instance("T", Type)});
|
let t_cond = quant(t_cond, set! {static_instance("T", Type)});
|
||||||
let t_discard = nd_func(vec![param_t("old", Obj)], None, NoneType);
|
let t_discard = nd_func(vec![param_t("obj", Obj)], None, NoneType);
|
||||||
// FIXME: quantify
|
// FIXME: quantify
|
||||||
let t_if = func(
|
let t_if = func(
|
||||||
vec![
|
vec![
|
||||||
|
@ -1694,6 +1694,9 @@ impl Context {
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
self.register_builtin_const("Inheritable", ValueObj::Subr(inheritable));
|
self.register_builtin_const("Inheritable", ValueObj::Subr(inheritable));
|
||||||
|
// TODO: register Del function object
|
||||||
|
let t_del = nd_func(vec![param_t("obj", Obj)], None, NoneType);
|
||||||
|
self.register_builtin_impl("Del", t_del, Immutable, Private);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_builtin_procs(&mut self) {
|
fn init_builtin_procs(&mut self) {
|
||||||
|
|
|
@ -274,15 +274,17 @@ pub enum RegistrationMode {
|
||||||
Normal,
|
Normal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some Erg functions require additional operation by the compiler.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ImportKind {
|
pub enum OperationKind {
|
||||||
ErgImport,
|
Import,
|
||||||
PyImport,
|
PyImport,
|
||||||
|
Del,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportKind {
|
impl OperationKind {
|
||||||
pub const fn is_erg_import(&self) -> bool {
|
pub const fn is_erg_import(&self) -> bool {
|
||||||
matches!(self, Self::ErgImport)
|
matches!(self, Self::Import)
|
||||||
}
|
}
|
||||||
pub const fn is_py_import(&self) -> bool {
|
pub const fn is_py_import(&self) -> bool {
|
||||||
matches!(self, Self::PyImport)
|
matches!(self, Self::PyImport)
|
||||||
|
|
|
@ -15,7 +15,7 @@ use erg_parser::ast;
|
||||||
|
|
||||||
use erg_type::constructors::{func, func1, proc, ref_, ref_mut, v_enum};
|
use erg_type::constructors::{func, func1, proc, ref_, ref_mut, v_enum};
|
||||||
use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
||||||
use erg_type::{ParamTy, SubrType, TyBound, Type};
|
use erg_type::{ParamTy, SubrType, Type};
|
||||||
|
|
||||||
use crate::build_hir::HIRBuilder;
|
use crate::build_hir::HIRBuilder;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
|
@ -25,6 +25,7 @@ use crate::error::readable_name;
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult,
|
CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult,
|
||||||
};
|
};
|
||||||
|
use crate::hir;
|
||||||
use crate::hir::Literal;
|
use crate::hir::Literal;
|
||||||
use crate::mod_cache::SharedModuleCache;
|
use crate::mod_cache::SharedModuleCache;
|
||||||
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
||||||
|
@ -33,7 +34,7 @@ use RegistrationMode::*;
|
||||||
use Visibility::*;
|
use Visibility::*;
|
||||||
|
|
||||||
use super::instantiate::TyVarContext;
|
use super::instantiate::TyVarContext;
|
||||||
use super::ImportKind;
|
use super::OperationKind;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
|
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
|
||||||
|
@ -856,7 +857,7 @@ impl Context {
|
||||||
|
|
||||||
pub(crate) fn import_mod(
|
pub(crate) fn import_mod(
|
||||||
&mut self,
|
&mut self,
|
||||||
kind: ImportKind,
|
kind: OperationKind,
|
||||||
mod_name: &Literal,
|
mod_name: &Literal,
|
||||||
) -> CompileResult<PathBuf> {
|
) -> CompileResult<PathBuf> {
|
||||||
if kind.is_erg_import() {
|
if kind.is_erg_import() {
|
||||||
|
@ -1031,11 +1032,32 @@ impl Context {
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
|
pub fn del(&mut self, ident: &hir::Identifier) -> CompileResult<()> {
|
||||||
self.bounds.push(TyBound::subtype_of(sub, sup));
|
if self.rec_get_const_obj(ident.inspect()).is_some()
|
||||||
}
|
|| self
|
||||||
|
.get_builtins()
|
||||||
pub(crate) fn _push_instance_bound(&mut self, name: Str, t: Type) {
|
.unwrap()
|
||||||
self.bounds.push(TyBound::instance(name, t));
|
.get_local_kv(ident.inspect())
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
Err(TyCheckErrors::from(TyCheckError::del_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
ident,
|
||||||
|
self.caused_by(),
|
||||||
|
)))
|
||||||
|
} else if self.locals.get(ident.inspect()).is_some() {
|
||||||
|
self.locals.remove(ident.inspect());
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(TyCheckErrors::from(TyCheckError::no_var_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
ident.loc(),
|
||||||
|
self.caused_by(),
|
||||||
|
ident.inspect(),
|
||||||
|
self.get_similar_name(ident.inspect()),
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use erg_parser::error::{ParserRunnerError, ParserRunnerErrors};
|
||||||
|
|
||||||
use erg_type::{Predicate, Type};
|
use erg_type::{Predicate, Type};
|
||||||
|
|
||||||
use crate::hir::Expr;
|
use crate::hir::{Expr, Identifier};
|
||||||
|
|
||||||
/// dname is for "double under name"
|
/// dname is for "double under name"
|
||||||
pub fn binop_to_dname(op: &str) -> &str {
|
pub fn binop_to_dname(op: &str) -> &str {
|
||||||
|
@ -1305,6 +1305,26 @@ impl LowerError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: AtomicStr) -> Self {
|
||||||
|
let name = readable_name(ident.inspect());
|
||||||
|
Self::new(
|
||||||
|
ErrorCore::new(
|
||||||
|
errno,
|
||||||
|
NameError,
|
||||||
|
ident.loc(),
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => format!("{YELLOW}{name}{RESET}は削除できません"),
|
||||||
|
"simplified_chinese" => format!("{YELLOW}{name}{RESET}不能删除"),
|
||||||
|
"traditional_chinese" => format!("{YELLOW}{name}{RESET}不能刪除"),
|
||||||
|
"english" => format!("{YELLOW}{name}{RESET} cannot be deleted"),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
input,
|
||||||
|
caused_by,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn visibility_error(
|
pub fn visibility_error(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
|
|
|
@ -20,7 +20,7 @@ use erg_type::value::{TypeKind, ValueObj};
|
||||||
use erg_type::{impl_t, impl_t_for_enum, HasType, Type};
|
use erg_type::{impl_t, impl_t_for_enum, HasType, Type};
|
||||||
|
|
||||||
use crate::context::eval::type_from_token_kind;
|
use crate::context::eval::type_from_token_kind;
|
||||||
use crate::context::ImportKind;
|
use crate::context::OperationKind;
|
||||||
use crate::error::readable_name;
|
use crate::error::readable_name;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -1011,10 +1011,11 @@ impl Call {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_kind(&self) -> Option<ImportKind> {
|
pub fn additional_operation(&self) -> Option<OperationKind> {
|
||||||
self.obj.show_acc().and_then(|s| match &s[..] {
|
self.obj.show_acc().and_then(|s| match &s[..] {
|
||||||
"import" => Some(ImportKind::ErgImport),
|
"import" => Some(OperationKind::Import),
|
||||||
"pyimport" | "py" => Some(ImportKind::PyImport),
|
"pyimport" | "py" => Some(OperationKind::PyImport),
|
||||||
|
"Del" => Some(OperationKind::Del),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use erg_type::typaram::TyParam;
|
||||||
use erg_type::value::ValueObj;
|
use erg_type::value::ValueObj;
|
||||||
use erg_type::{HasType, Type};
|
use erg_type::{HasType, Type};
|
||||||
|
|
||||||
use crate::context::ImportKind;
|
use crate::context::OperationKind;
|
||||||
use crate::hir::*;
|
use crate::hir::*;
|
||||||
use crate::mod_cache::SharedModuleCache;
|
use crate::mod_cache::SharedModuleCache;
|
||||||
|
|
||||||
|
@ -85,14 +85,14 @@ impl<'a> Linker<'a> {
|
||||||
Expr::UnaryOp(unaryop) => {
|
Expr::UnaryOp(unaryop) => {
|
||||||
self.replace_import(&mut unaryop.expr);
|
self.replace_import(&mut unaryop.expr);
|
||||||
}
|
}
|
||||||
Expr::Call(call) => match call.import_kind() {
|
Expr::Call(call) => match call.additional_operation() {
|
||||||
Some(ImportKind::ErgImport) => {
|
Some(OperationKind::Import) => {
|
||||||
self.replace_erg_import(expr);
|
self.replace_erg_import(expr);
|
||||||
}
|
}
|
||||||
Some(ImportKind::PyImport) => {
|
Some(OperationKind::PyImport) => {
|
||||||
self.replace_py_import(expr);
|
self.replace_py_import(expr);
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
for arg in call.args.pos_args.iter_mut() {
|
for arg in call.args.pos_args.iter_mut() {
|
||||||
self.replace_import(&mut arg.expr);
|
self.replace_import(&mut arg.expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ use erg_type::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
||||||
use erg_type::{HasType, ParamTy, Type};
|
use erg_type::{HasType, ParamTy, Type};
|
||||||
|
|
||||||
use crate::context::instantiate::TyVarContext;
|
use crate::context::instantiate::TyVarContext;
|
||||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
use crate::context::{ClassDefType, Context, ContextKind, OperationKind, RegistrationMode};
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
|
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
|
||||||
SingleLowerResult,
|
SingleLowerResult,
|
||||||
|
@ -457,12 +457,31 @@ impl ASTLowerer {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let call = hir::Call::new(obj, method_name, hir_args, sig_t);
|
let call = hir::Call::new(obj, method_name, hir_args, sig_t);
|
||||||
if let Some(kind) = call.import_kind() {
|
match call.additional_operation() {
|
||||||
let mod_name = enum_unwrap!(call.args.get_left_or_key("Path").unwrap(), hir::Expr::Lit);
|
Some(kind @ (OperationKind::Import | OperationKind::PyImport)) => {
|
||||||
|
let mod_name =
|
||||||
|
enum_unwrap!(call.args.get_left_or_key("Path").unwrap(), hir::Expr::Lit);
|
||||||
if let Err(errs) = self.ctx.import_mod(kind, mod_name) {
|
if let Err(errs) = self.ctx.import_mod(kind, mod_name) {
|
||||||
self.errs.extend(errs.into_iter());
|
self.errs.extend(errs.into_iter());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Some(OperationKind::Del) => match call.args.get_left_or_key("obj").unwrap() {
|
||||||
|
hir::Expr::Accessor(hir::Accessor::Ident(ident)) => {
|
||||||
|
self.ctx.del(ident)?;
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
return Err(LowerErrors::from(LowerError::syntax_error(
|
||||||
|
self.input().clone(),
|
||||||
|
line!() as usize,
|
||||||
|
other.loc(),
|
||||||
|
self.ctx.caused_by(),
|
||||||
|
"",
|
||||||
|
None,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
Ok(call)
|
Ok(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
Dictはキーと値のペアを持つコレクションです。
|
Dictはキーと値のペアを持つコレクションです。
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
|
ids = {"Alice" >: 145, "Bob": 214, "Charlie": 301}
|
||||||
assert ids["Alice"] == 145
|
assert ids["Alice"] == 145
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue