mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 20:34:44 +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 std::option::Option; // conflicting to Type::Option
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
use erg_common::astr::AtomicStr;
|
||||||
|
use erg_common::dict;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -933,6 +934,28 @@ impl Context {
|
||||||
}
|
}
|
||||||
Ok(tuple_t(inst_tys))
|
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: エラー処理(リテラルでない)はパーサーにやらせる
|
// TODO: エラー処理(リテラルでない)はパーサーにやらせる
|
||||||
TypeSpec::Enum(set) => {
|
TypeSpec::Enum(set) => {
|
||||||
let mut new_set = set! {};
|
let mut new_set = set! {};
|
||||||
|
|
|
@ -31,8 +31,11 @@ def in_operator(x, y):
|
||||||
type_check = in_operator(x[0], y[0])
|
type_check = in_operator(x[0], y[0])
|
||||||
len_check = len(x) == len(y)
|
len_check = len(x) == len(y)
|
||||||
return type_check and len_check
|
return type_check and len_check
|
||||||
elif type(y) == dict and type(y[0]) == type:
|
elif type(y) == dict and type(next(iter(y.keys()))) == type:
|
||||||
NotImplemented
|
# 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:
|
else:
|
||||||
return x in y
|
return x in y
|
||||||
|
|
||||||
|
@ -63,7 +66,15 @@ class Bool(Nat):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
class Str(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:
|
class Range:
|
||||||
def __init__(self, start, end):
|
def __init__(self, start, end):
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::fmt::Write as _;
|
||||||
|
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::set::Set as HashSet;
|
use erg_common::set::Set as HashSet;
|
||||||
|
// use erg_common::dict::Dict as HashMap;
|
||||||
use erg_common::traits::{Locational, NestedDisplay, Stream};
|
use erg_common::traits::{Locational, NestedDisplay, Stream};
|
||||||
use erg_common::vis::{Field, Visibility};
|
use erg_common::vis::{Field, Visibility};
|
||||||
use erg_common::{
|
use erg_common::{
|
||||||
|
@ -1766,6 +1767,7 @@ pub enum TypeSpec {
|
||||||
Array(ArrayTypeSpec),
|
Array(ArrayTypeSpec),
|
||||||
Set(SetTypeSpec),
|
Set(SetTypeSpec),
|
||||||
Tuple(Vec<TypeSpec>),
|
Tuple(Vec<TypeSpec>),
|
||||||
|
Dict(Vec<(TypeSpec, TypeSpec)>),
|
||||||
// Dict(),
|
// Dict(),
|
||||||
// Option(),
|
// Option(),
|
||||||
And(Box<TypeSpec>, Box<TypeSpec>),
|
And(Box<TypeSpec>, Box<TypeSpec>),
|
||||||
|
@ -1795,6 +1797,13 @@ impl fmt::Display for TypeSpec {
|
||||||
Self::Array(arr) => write!(f, "{arr}"),
|
Self::Array(arr) => write!(f, "{arr}"),
|
||||||
Self::Set(set) => write!(f, "{set}"),
|
Self::Set(set) => write!(f, "{set}"),
|
||||||
Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)),
|
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::Enum(elems) => write!(f, "{{{elems}}}"),
|
||||||
Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()),
|
Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()),
|
||||||
Self::Subr(s) => write!(f, "{s}"),
|
Self::Subr(s) => write!(f, "{s}"),
|
||||||
|
@ -1814,6 +1823,7 @@ impl Locational for TypeSpec {
|
||||||
Self::Set(set) => set.loc(),
|
Self::Set(set) => set.loc(),
|
||||||
// TODO: ユニット
|
// TODO: ユニット
|
||||||
Self::Tuple(tys) => Location::concat(tys.first().unwrap(), tys.last().unwrap()),
|
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::Enum(set) => set.loc(),
|
||||||
Self::Interval { lhs, rhs, .. } => Location::concat(lhs, rhs),
|
Self::Interval { lhs, rhs, .. } => Location::concat(lhs, rhs),
|
||||||
Self::Subr(s) => s.loc(),
|
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> {
|
pub fn expr_to_type_spec(rhs: Expr) -> Result<TypeSpec, ParseError> {
|
||||||
match rhs {
|
match rhs {
|
||||||
Expr::Accessor(acc) => Self::accessor_to_type_spec(acc),
|
Expr::Accessor(acc) => Self::accessor_to_type_spec(acc),
|
||||||
|
@ -3035,6 +3050,10 @@ impl Parser {
|
||||||
let set = Self::set_to_set_type_spec(set)?;
|
let set = Self::set_to_set_type_spec(set)?;
|
||||||
Ok(TypeSpec::Set(set))
|
Ok(TypeSpec::Set(set))
|
||||||
}
|
}
|
||||||
|
Expr::Dict(dict) => {
|
||||||
|
let dict = Self::dict_to_dict_type_spec(dict)?;
|
||||||
|
Ok(TypeSpec::Dict(dict))
|
||||||
|
}
|
||||||
Expr::BinOp(bin) => {
|
Expr::BinOp(bin) => {
|
||||||
if bin.op.kind.is_range_op() {
|
if bin.op.kind.is_range_op() {
|
||||||
let op = bin.op;
|
let op = bin.op;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue