This commit is contained in:
Shunsuke Shibayama 2022-10-03 21:44:59 +09:00
parent 64be2da03b
commit 2f33c9b15d
9 changed files with 110 additions and 31 deletions

View file

@ -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),

View file

@ -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) {

View file

@ -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)

View file

@ -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()),
)))
}
} }
} }

View file

@ -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,

View file

@ -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,
}) })
} }

View file

@ -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);
} }

View file

@ -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)
} }

View file

@ -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
``` ```