mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Implement Dict
This commit is contained in:
parent
56779ab06e
commit
decb0fd077
7 changed files with 83 additions and 25 deletions
|
@ -1752,6 +1752,23 @@ impl CodeGenerator {
|
||||||
self.write_arg(1u8);
|
self.write_arg(1u8);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expr::Dict(dict) => match dict {
|
||||||
|
crate::hir::Dict::Normal(dic) => {
|
||||||
|
let len = dic.kvs.len();
|
||||||
|
for kv in dic.kvs.into_iter() {
|
||||||
|
self.emit_expr(kv.key);
|
||||||
|
self.emit_expr(kv.value);
|
||||||
|
}
|
||||||
|
self.write_instr(BUILD_MAP);
|
||||||
|
self.write_arg(len as u8);
|
||||||
|
if len == 0 {
|
||||||
|
self.stack_inc();
|
||||||
|
} else {
|
||||||
|
self.stack_dec_n(len - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
},
|
||||||
Expr::Record(rec) => self.emit_record(rec),
|
Expr::Record(rec) => self.emit_record(rec),
|
||||||
Expr::Code(code) => {
|
Expr::Code(code) => {
|
||||||
let code = self.emit_block(code, None, vec![]);
|
let code = self.emit_block(code, None, vec![]);
|
||||||
|
@ -1767,9 +1784,8 @@ impl CodeGenerator {
|
||||||
Expr::TypeAsc(tasc) => {
|
Expr::TypeAsc(tasc) => {
|
||||||
self.emit_expr(*tasc.expr);
|
self.emit_expr(*tasc.expr);
|
||||||
}
|
}
|
||||||
// Dict,
|
|
||||||
other => {
|
other => {
|
||||||
CompileError::feature_error(self.cfg.input.clone(), other.loc(), "Dict", "".into())
|
CompileError::feature_error(self.cfg.input.clone(), other.loc(), "??", "".into())
|
||||||
.write_to_stderr();
|
.write_to_stderr();
|
||||||
self.crash("cannot compile this expression at this time");
|
self.crash("cannot compile this expression at this time");
|
||||||
}
|
}
|
||||||
|
|
|
@ -958,6 +958,12 @@ impl Context {
|
||||||
);
|
);
|
||||||
set_type.register_superclass(set_t.clone(), &set_);
|
set_type.register_superclass(set_t.clone(), &set_);
|
||||||
set_type.register_superclass(Type, &type_);
|
set_type.register_superclass(Type, &type_);
|
||||||
|
let dict_t = builtin_poly("Dict", vec![mono_q_tp("D")]);
|
||||||
|
let mut dict_ =
|
||||||
|
// TODO: D <: GenericDict
|
||||||
|
Self::builtin_poly_class("Dict", vec![PS::named_nd("D", builtin_mono("GenericDict"))], 10);
|
||||||
|
dict_.register_superclass(Obj, &obj);
|
||||||
|
dict_.register_marker_trait(builtin_poly("Output", vec![ty_tp(mono_q("D"))]));
|
||||||
/* Bytes */
|
/* Bytes */
|
||||||
let mut bytes = Self::builtin_mono_class("Bytes", 2);
|
let mut bytes = Self::builtin_mono_class("Bytes", 2);
|
||||||
bytes.register_superclass(Obj, &obj);
|
bytes.register_superclass(Obj, &obj);
|
||||||
|
@ -1494,6 +1500,7 @@ impl Context {
|
||||||
self.register_builtin_type(array_type_t, array_type, Const);
|
self.register_builtin_type(array_type_t, array_type, Const);
|
||||||
self.register_builtin_type(set_t, set_, Const);
|
self.register_builtin_type(set_t, set_, Const);
|
||||||
self.register_builtin_type(set_type_t, set_type, Const);
|
self.register_builtin_type(set_type_t, set_type, Const);
|
||||||
|
self.register_builtin_type(dict_t, dict_, Const);
|
||||||
self.register_builtin_type(builtin_mono("Bytes"), bytes, Const);
|
self.register_builtin_type(builtin_mono("Bytes"), bytes, Const);
|
||||||
self.register_builtin_type(tuple(vec![mono_q("A")]), tuple1, Const);
|
self.register_builtin_type(tuple(vec![mono_q("A")]), tuple1, Const);
|
||||||
self.register_builtin_type(tuple(vec![mono_q("A"), mono_q("B")]), tuple2, Const);
|
self.register_builtin_type(tuple(vec![mono_q("A"), mono_q("B")]), tuple2, Const);
|
||||||
|
|
|
@ -705,9 +705,18 @@ impl Context {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hir::Expr::Dict(_dict) => {
|
hir::Expr::Dict(dict) => match dict {
|
||||||
todo!()
|
hir::Dict::Normal(dic) => {
|
||||||
}
|
let loc = dic.loc();
|
||||||
|
dic.t = self.deref_tyvar(mem::take(&mut dic.t), Covariant, loc)?;
|
||||||
|
for kv in dic.kvs.iter_mut() {
|
||||||
|
self.resolve_expr_t(&mut kv.key)?;
|
||||||
|
self.resolve_expr_t(&mut kv.value)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
},
|
||||||
hir::Expr::Record(record) => {
|
hir::Expr::Record(record) => {
|
||||||
for attr in record.attrs.iter_mut() {
|
for attr in record.attrs.iter_mut() {
|
||||||
match &mut attr.sig {
|
match &mut attr.sig {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use Visibility::*;
|
||||||
use erg_type::HasType;
|
use erg_type::HasType;
|
||||||
|
|
||||||
use crate::error::{EffectError, EffectErrors};
|
use crate::error::{EffectError, EffectErrors};
|
||||||
use crate::hir::{Array, Def, Expr, Signature, Tuple, HIR};
|
use crate::hir::{Array, Def, Dict, Expr, Set, Signature, Tuple, HIR};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
enum BlockKind {
|
enum BlockKind {
|
||||||
|
@ -143,16 +143,25 @@ impl SideEffectChecker {
|
||||||
self.block_stack.pop();
|
self.block_stack.pop();
|
||||||
}
|
}
|
||||||
Expr::Set(set) => match set {
|
Expr::Set(set) => match set {
|
||||||
crate::hir::Set::Normal(set) => {
|
Set::Normal(set) => {
|
||||||
for elem in set.elems.pos_args.iter() {
|
for elem in set.elems.pos_args.iter() {
|
||||||
self.check_expr(&elem.expr);
|
self.check_expr(&elem.expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::hir::Set::WithLength(set) => {
|
Set::WithLength(set) => {
|
||||||
self.check_expr(&set.elem);
|
self.check_expr(&set.elem);
|
||||||
self.check_expr(&set.len);
|
self.check_expr(&set.len);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expr::Dict(dict) => match dict {
|
||||||
|
Dict::Normal(dict) => {
|
||||||
|
for kv in dict.kvs.iter() {
|
||||||
|
self.check_expr(&kv.key);
|
||||||
|
self.check_expr(&kv.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
},
|
||||||
Expr::TypeAsc(tasc) => {
|
Expr::TypeAsc(tasc) => {
|
||||||
self.check_expr(&tasc.expr);
|
self.check_expr(&tasc.expr);
|
||||||
}
|
}
|
||||||
|
@ -294,16 +303,25 @@ impl SideEffectChecker {
|
||||||
self.block_stack.pop();
|
self.block_stack.pop();
|
||||||
}
|
}
|
||||||
Expr::Set(set) => match set {
|
Expr::Set(set) => match set {
|
||||||
crate::hir::Set::Normal(set) => {
|
Set::Normal(set) => {
|
||||||
for elem in set.elems.pos_args.iter() {
|
for elem in set.elems.pos_args.iter() {
|
||||||
self.check_expr(&elem.expr);
|
self.check_expr(&elem.expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::hir::Set::WithLength(set) => {
|
Set::WithLength(set) => {
|
||||||
self.check_expr(&set.elem);
|
self.check_expr(&set.elem);
|
||||||
self.check_expr(&set.len);
|
self.check_expr(&set.len);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expr::Dict(dict) => match dict {
|
||||||
|
Dict::Normal(dict) => {
|
||||||
|
for kv in dict.kvs.iter() {
|
||||||
|
self.check_expr(&kv.key);
|
||||||
|
self.check_expr(&kv.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
},
|
||||||
// 引数がproceduralでも関数呼び出しなら副作用なし
|
// 引数がproceduralでも関数呼び出しなら副作用なし
|
||||||
Expr::Call(call) => {
|
Expr::Call(call) => {
|
||||||
if (call.obj.t().is_procedural()
|
if (call.obj.t().is_procedural()
|
||||||
|
|
|
@ -83,9 +83,15 @@ impl<'a> Linker<'a> {
|
||||||
self.replace_import(&mut st.len);
|
self.replace_import(&mut st.len);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expr::Dict(_dict) => {
|
Expr::Dict(dict) => match dict {
|
||||||
todo!()
|
Dict::Normal(dic) => {
|
||||||
}
|
for elem in dic.kvs.iter_mut() {
|
||||||
|
self.replace_import(&mut elem.key);
|
||||||
|
self.replace_import(&mut elem.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
},
|
||||||
Expr::Record(record) => {
|
Expr::Record(record) => {
|
||||||
for attr in record.attrs.iter_mut() {
|
for attr in record.attrs.iter_mut() {
|
||||||
for chunk in attr.body.block.iter_mut() {
|
for chunk in attr.body.block.iter_mut() {
|
||||||
|
|
|
@ -493,17 +493,17 @@ impl ASTLowerer {
|
||||||
let loc = kv.loc();
|
let loc = kv.loc();
|
||||||
let key = self.lower_expr(kv.key)?;
|
let key = self.lower_expr(kv.key)?;
|
||||||
let value = self.lower_expr(kv.value)?;
|
let value = self.lower_expr(kv.value)?;
|
||||||
if union.insert(key.t(), value.t()).is_none() {
|
if union.insert(key.t(), value.t()).is_some() {
|
||||||
return Err(LowerErrors::from(LowerError::syntax_error(
|
return Err(LowerErrors::from(LowerError::syntax_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
loc,
|
loc,
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
AtomicStr::arc(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "集合の要素は全て同じ型である必要があります",
|
"japanese" => "Dictの値は全て同じ型である必要があります",
|
||||||
"simplified_chinese" => "集合元素必须全部是相同类型",
|
"simplified_chinese" => "Dict的值必须是同一类型",
|
||||||
"traditional_chinese" => "集合元素必須全部是相同類型",
|
"traditional_chinese" => "Dict的值必須是同一類型",
|
||||||
"english" => "all elements of a set must be of the same type",
|
"english" => "Values of Dict must be the same type",
|
||||||
),
|
),
|
||||||
Some(
|
Some(
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
|
@ -518,12 +518,14 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
new_kvs.push(hir::KeyValue::new(key, value));
|
new_kvs.push(hir::KeyValue::new(key, value));
|
||||||
}
|
}
|
||||||
/*let sup = builtin_poly("Eq", vec![TyParam::t(elem_t.clone())]);
|
for key_t in union.keys() {
|
||||||
let loc = Location::concat(&dict.l_brace, &dict.r_brace);
|
let sup = builtin_poly("Eq", vec![TyParam::t(key_t.clone())]);
|
||||||
// check if elem_t is Eq
|
let loc = Location::concat(&dict.l_brace, &dict.r_brace);
|
||||||
if let Err(errs) = self.ctx.sub_unify(&elem_t, &sup, loc, None) {
|
// check if key_t is Eq
|
||||||
self.errs.extend(errs.into_iter());
|
if let Err(errs) = self.ctx.sub_unify(key_t, &sup, loc, None) {
|
||||||
}*/
|
self.errs.extend(errs.into_iter());
|
||||||
|
}
|
||||||
|
}
|
||||||
let kv_ts = if union.is_empty() {
|
let kv_ts = if union.is_empty() {
|
||||||
dict! {
|
dict! {
|
||||||
ty_tp(free_var(self.ctx.level, Constraint::new_type_of(Type::Type))) =>
|
ty_tp(free_var(self.ctx.level, Constraint::new_type_of(Type::Type))) =>
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl OwnershipChecker {
|
||||||
self.check_expr(&kv.value, ownership, false);
|
self.check_expr(&kv.value, ownership, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
other => todo!("{other}"),
|
||||||
},
|
},
|
||||||
Expr::Record(rec) => {
|
Expr::Record(rec) => {
|
||||||
for def in rec.attrs.iter() {
|
for def in rec.attrs.iter() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue