mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 13:11:11 +00:00
Add DictTypeSpec
This commit is contained in:
parent
7defa71c86
commit
45e34c6773
4 changed files with 66 additions and 3 deletions
|
@ -3,6 +3,7 @@ use std::mem;
|
|||
use std::option::Option; // conflicting to Type::Option
|
||||
|
||||
use erg_common::astr::AtomicStr;
|
||||
use erg_common::dict;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::Location;
|
||||
#[allow(unused)]
|
||||
|
@ -933,6 +934,28 @@ impl Context {
|
|||
}
|
||||
Ok(tuple_t(inst_tys))
|
||||
}
|
||||
TypeSpec::Dict(dict) => {
|
||||
let mut inst_tys = dict! {};
|
||||
for (k, v) in dict {
|
||||
inst_tys.insert(
|
||||
self.instantiate_typespec(
|
||||
k,
|
||||
opt_decl_t,
|
||||
tmp_tv_ctx,
|
||||
mode,
|
||||
not_found_is_qvar,
|
||||
)?,
|
||||
self.instantiate_typespec(
|
||||
v,
|
||||
opt_decl_t,
|
||||
tmp_tv_ctx,
|
||||
mode,
|
||||
not_found_is_qvar,
|
||||
)?,
|
||||
);
|
||||
}
|
||||
Ok(dict_t(inst_tys.into()))
|
||||
}
|
||||
// TODO: エラー処理(リテラルでない)はパーサーにやらせる
|
||||
TypeSpec::Enum(set) => {
|
||||
let mut new_set = set! {};
|
||||
|
|
|
@ -31,8 +31,11 @@ def in_operator(x, y):
|
|||
type_check = in_operator(x[0], y[0])
|
||||
len_check = len(x) == len(y)
|
||||
return type_check and len_check
|
||||
elif type(y) == dict and type(y[0]) == type:
|
||||
NotImplemented
|
||||
elif type(y) == dict and type(next(iter(y.keys()))) == type:
|
||||
# TODO:
|
||||
type_check = True # in_operator(x[next(iter(x.keys()))], next(iter(y.keys())))
|
||||
len_check = len(x) >= len(y)
|
||||
return type_check and len_check
|
||||
else:
|
||||
return x in y
|
||||
|
||||
|
@ -63,7 +66,15 @@ class Bool(Nat):
|
|||
return self.__str__()
|
||||
|
||||
class Str(str):
|
||||
pass
|
||||
def __instancecheck__(cls, obj):
|
||||
print(cls, obj)
|
||||
return obj == Str or obj == str
|
||||
|
||||
def try_new(s: str): # -> Result[Nat]
|
||||
if isinstance(s, str):
|
||||
return Str(s)
|
||||
else:
|
||||
return Error("Str can't be other than str")
|
||||
|
||||
class Range:
|
||||
def __init__(self, start, end):
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::fmt::Write as _;
|
|||
|
||||
use erg_common::error::Location;
|
||||
use erg_common::set::Set as HashSet;
|
||||
// use erg_common::dict::Dict as HashMap;
|
||||
use erg_common::traits::{Locational, NestedDisplay, Stream};
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
use erg_common::{
|
||||
|
@ -1766,6 +1767,7 @@ pub enum TypeSpec {
|
|||
Array(ArrayTypeSpec),
|
||||
Set(SetTypeSpec),
|
||||
Tuple(Vec<TypeSpec>),
|
||||
Dict(Vec<(TypeSpec, TypeSpec)>),
|
||||
// Dict(),
|
||||
// Option(),
|
||||
And(Box<TypeSpec>, Box<TypeSpec>),
|
||||
|
@ -1795,6 +1797,13 @@ impl fmt::Display for TypeSpec {
|
|||
Self::Array(arr) => write!(f, "{arr}"),
|
||||
Self::Set(set) => write!(f, "{set}"),
|
||||
Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)),
|
||||
Self::Dict(dict) => {
|
||||
write!(f, "{{")?;
|
||||
for (k, v) in dict {
|
||||
write!(f, "{k}: {v}, ")?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
Self::Enum(elems) => write!(f, "{{{elems}}}"),
|
||||
Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()),
|
||||
Self::Subr(s) => write!(f, "{s}"),
|
||||
|
@ -1814,6 +1823,7 @@ impl Locational for TypeSpec {
|
|||
Self::Set(set) => set.loc(),
|
||||
// TODO: ユニット
|
||||
Self::Tuple(tys) => Location::concat(tys.first().unwrap(), tys.last().unwrap()),
|
||||
Self::Dict(dict) => Location::concat(&dict.first().unwrap().0, &dict.last().unwrap().1),
|
||||
Self::Enum(set) => set.loc(),
|
||||
Self::Interval { lhs, rhs, .. } => Location::concat(lhs, rhs),
|
||||
Self::Subr(s) => s.loc(),
|
||||
|
|
|
@ -3016,6 +3016,21 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn dict_to_dict_type_spec(dict: Dict) -> Result<Vec<(TypeSpec, TypeSpec)>, ParseError> {
|
||||
match dict {
|
||||
Dict::Normal(dic) => {
|
||||
let mut kvs = vec![];
|
||||
for kv in dic.kvs.into_iter() {
|
||||
let key = Self::expr_to_type_spec(kv.key)?;
|
||||
let value = Self::expr_to_type_spec(kv.value)?;
|
||||
kvs.push((key, value));
|
||||
}
|
||||
Ok(kvs)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr_to_type_spec(rhs: Expr) -> Result<TypeSpec, ParseError> {
|
||||
match rhs {
|
||||
Expr::Accessor(acc) => Self::accessor_to_type_spec(acc),
|
||||
|
@ -3035,6 +3050,10 @@ impl Parser {
|
|||
let set = Self::set_to_set_type_spec(set)?;
|
||||
Ok(TypeSpec::Set(set))
|
||||
}
|
||||
Expr::Dict(dict) => {
|
||||
let dict = Self::dict_to_dict_type_spec(dict)?;
|
||||
Ok(TypeSpec::Dict(dict))
|
||||
}
|
||||
Expr::BinOp(bin) => {
|
||||
if bin.op.kind.is_range_op() {
|
||||
let op = bin.op;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue