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) {
|
||||
log!(info "entered {}", fn_name!());
|
||||
while let Some(arg) = args.try_remove(0) {
|
||||
|
@ -1446,6 +1457,7 @@ impl CodeGenerator {
|
|||
log!(info "entered {}", fn_name!());
|
||||
match &local.inspect()[..] {
|
||||
"assert" => self.emit_assert_instr(args),
|
||||
"Del" => self.emit_del_instr(args),
|
||||
"discard" => self.emit_discard_instr(args),
|
||||
"for" | "for!" => self.emit_for_instr(args),
|
||||
"if" | "if!" => self.emit_if_instr(args),
|
||||
|
|
|
@ -1586,7 +1586,7 @@ impl Context {
|
|||
mono_q("T"),
|
||||
);
|
||||
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
|
||||
let t_if = func(
|
||||
vec![
|
||||
|
@ -1694,6 +1694,9 @@ impl Context {
|
|||
None,
|
||||
));
|
||||
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) {
|
||||
|
|
|
@ -274,15 +274,17 @@ pub enum RegistrationMode {
|
|||
Normal,
|
||||
}
|
||||
|
||||
/// Some Erg functions require additional operation by the compiler.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ImportKind {
|
||||
ErgImport,
|
||||
pub enum OperationKind {
|
||||
Import,
|
||||
PyImport,
|
||||
Del,
|
||||
}
|
||||
|
||||
impl ImportKind {
|
||||
impl OperationKind {
|
||||
pub const fn is_erg_import(&self) -> bool {
|
||||
matches!(self, Self::ErgImport)
|
||||
matches!(self, Self::Import)
|
||||
}
|
||||
pub const fn is_py_import(&self) -> bool {
|
||||
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::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::context::{
|
||||
|
@ -25,6 +25,7 @@ use crate::error::readable_name;
|
|||
use crate::error::{
|
||||
CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult,
|
||||
};
|
||||
use crate::hir;
|
||||
use crate::hir::Literal;
|
||||
use crate::mod_cache::SharedModuleCache;
|
||||
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
||||
|
@ -33,7 +34,7 @@ use RegistrationMode::*;
|
|||
use Visibility::*;
|
||||
|
||||
use super::instantiate::TyVarContext;
|
||||
use super::ImportKind;
|
||||
use super::OperationKind;
|
||||
|
||||
impl Context {
|
||||
/// 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(
|
||||
&mut self,
|
||||
kind: ImportKind,
|
||||
kind: OperationKind,
|
||||
mod_name: &Literal,
|
||||
) -> CompileResult<PathBuf> {
|
||||
if kind.is_erg_import() {
|
||||
|
@ -1031,11 +1032,32 @@ impl Context {
|
|||
Ok(path)
|
||||
}
|
||||
|
||||
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
|
||||
self.bounds.push(TyBound::subtype_of(sub, sup));
|
||||
}
|
||||
|
||||
pub(crate) fn _push_instance_bound(&mut self, name: Str, t: Type) {
|
||||
self.bounds.push(TyBound::instance(name, t));
|
||||
pub fn del(&mut self, ident: &hir::Identifier) -> CompileResult<()> {
|
||||
if self.rec_get_const_obj(ident.inspect()).is_some()
|
||||
|| self
|
||||
.get_builtins()
|
||||
.unwrap()
|
||||
.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 crate::hir::Expr;
|
||||
use crate::hir::{Expr, Identifier};
|
||||
|
||||
/// dname is for "double under name"
|
||||
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(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
|
|
|
@ -20,7 +20,7 @@ use erg_type::value::{TypeKind, ValueObj};
|
|||
use erg_type::{impl_t, impl_t_for_enum, HasType, Type};
|
||||
|
||||
use crate::context::eval::type_from_token_kind;
|
||||
use crate::context::ImportKind;
|
||||
use crate::context::OperationKind;
|
||||
use crate::error::readable_name;
|
||||
|
||||
#[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[..] {
|
||||
"import" => Some(ImportKind::ErgImport),
|
||||
"pyimport" | "py" => Some(ImportKind::PyImport),
|
||||
"import" => Some(OperationKind::Import),
|
||||
"pyimport" | "py" => Some(OperationKind::PyImport),
|
||||
"Del" => Some(OperationKind::Del),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use erg_type::typaram::TyParam;
|
|||
use erg_type::value::ValueObj;
|
||||
use erg_type::{HasType, Type};
|
||||
|
||||
use crate::context::ImportKind;
|
||||
use crate::context::OperationKind;
|
||||
use crate::hir::*;
|
||||
use crate::mod_cache::SharedModuleCache;
|
||||
|
||||
|
@ -85,14 +85,14 @@ impl<'a> Linker<'a> {
|
|||
Expr::UnaryOp(unaryop) => {
|
||||
self.replace_import(&mut unaryop.expr);
|
||||
}
|
||||
Expr::Call(call) => match call.import_kind() {
|
||||
Some(ImportKind::ErgImport) => {
|
||||
Expr::Call(call) => match call.additional_operation() {
|
||||
Some(OperationKind::Import) => {
|
||||
self.replace_erg_import(expr);
|
||||
}
|
||||
Some(ImportKind::PyImport) => {
|
||||
Some(OperationKind::PyImport) => {
|
||||
self.replace_py_import(expr);
|
||||
}
|
||||
None => {
|
||||
_ => {
|
||||
for arg in call.args.pos_args.iter_mut() {
|
||||
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 crate::context::instantiate::TyVarContext;
|
||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
||||
use crate::context::{ClassDefType, Context, ContextKind, OperationKind, RegistrationMode};
|
||||
use crate::error::{
|
||||
CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings,
|
||||
SingleLowerResult,
|
||||
|
@ -457,12 +457,31 @@ impl ASTLowerer {
|
|||
None
|
||||
};
|
||||
let call = hir::Call::new(obj, method_name, hir_args, sig_t);
|
||||
if let Some(kind) = call.import_kind() {
|
||||
let mod_name = enum_unwrap!(call.args.get_left_or_key("Path").unwrap(), hir::Expr::Lit);
|
||||
match call.additional_operation() {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
Dictはキーと値のペアを持つコレクションです。
|
||||
|
||||
```python
|
||||
ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
|
||||
ids = {"Alice" >: 145, "Bob": 214, "Charlie": 301}
|
||||
assert ids["Alice"] == 145
|
||||
```
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue