Skip to content

Commit

Permalink
Add DictTypeSpec
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 20, 2022
1 parent 7defa71 commit 45e34c6
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 3 deletions.
23 changes: 23 additions & 0 deletions compiler/erg_compiler/context/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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! {};
Expand Down
17 changes: 14 additions & 3 deletions compiler/erg_compiler/lib/std/_erg_std_prelude.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -63,7 +66,15 @@ def __repr__(self) -> str:
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):
Expand Down
10 changes: 10 additions & 0 deletions compiler/erg_parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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>),
Expand Down Expand Up @@ -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}"),
Expand All @@ -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(),
Expand Down
19 changes: 19 additions & 0 deletions compiler/erg_parser/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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;
Expand Down

0 comments on commit 45e34c6

Please sign in to comment.