feat: (partial) comprehension support

This commit is contained in:
Shunsuke Shibayama 2023-09-11 02:24:03 +09:00
parent 482f22374b
commit 3fd66f1a32
14 changed files with 483 additions and 158 deletions

View file

@ -37,6 +37,13 @@ impl Context {
Bool,
);
let t_ascii = nd_func(vec![kw(KW_OBJECT, Obj)], None, Str);
let t_array = func(
vec![],
None,
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
array_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let t_assert = func(
vec![kw(KW_TEST, Bool)],
None,
@ -67,6 +74,16 @@ impl Context {
T.clone(),
)
.quantify();
let t_dict = func(
vec![],
None,
vec![kw(
KW_ITERABLE,
poly(ITERABLE, vec![ty_tp(tuple_t(vec![T.clone(), U.clone()]))]),
)],
dict! { T.clone() => U.clone() }.into(),
)
.quantify();
let t_discard = nd_func(vec![kw(KW_OBJ, Obj)], None, NoneType);
let t_enumerate = func(
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
@ -221,6 +238,13 @@ impl Context {
)
.quantify();
let t_round = nd_func(vec![kw(KW_NUMBER, Float)], None, Int);
let t_set = func(
vec![],
None,
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
set_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let t_slice = func(
vec![kw(KW_START, Int)],
None,
@ -256,6 +280,7 @@ impl Context {
self.register_py_builtin(FUNC_ABS, t_abs, Some(FUNC_ABS), 11);
self.register_py_builtin(FUNC_ALL, t_all, Some(FUNC_ALL), 22);
self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33);
self.register_py_builtin(FUNC_ARRAY, t_array, Some(FUNC_LIST), 215);
self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53);
// Leave as `Const`, as it may negatively affect assert casting.
self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis.clone());
@ -283,6 +308,7 @@ impl Context {
Some(FUNC_COMPILE),
);
self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis.clone());
self.register_py_builtin(FUNC_DICT, t_dict, Some(FUNC_DICT), 224);
self.register_builtin_py_impl(
FUNC_ENUMERATE,
t_enumerate,
@ -401,6 +427,7 @@ impl Context {
vis.clone(),
Some(FUNC_ROUND),
);
self.register_py_builtin(FUNC_SET, t_set, Some(FUNC_SET), 233);
self.register_builtin_py_impl(
FUNC_SLICE,
t_slice,

View file

@ -341,6 +341,7 @@ const GENERATOR: &str = "Generator";
const FUNC_RANGE: &str = "range";
const FUNC_ALL: &str = "all";
const FUNC_ANY: &str = "any";
const FUNC_ARRAY: &str = "array";
const FUNC_ASCII: &str = "ascii";
const FUNC_ASSERT: &str = "assert";
const FUNC_BIN: &str = "bin";
@ -360,6 +361,7 @@ const FUNC_POW: &str = "pow";
const FUNC_QUIT: &str = "quit";
const FUNC_REPR: &str = "repr";
const FUNC_ROUND: &str = "round";
const FUNC_SET: &str = "set";
const FUNC_SLICE: &str = "slice";
const FUNC_SORTED: &str = "sorted";
const FUNC_SUM: &str = "sum";

View file

@ -980,16 +980,18 @@ impl Context {
Ok(TyParam::Set(tp_set))
}
ast::ConstExpr::Set(ConstSet::Comprehension(set)) => {
if set.op.is(TokenKind::Colon) {
if set.layout.is_none() && set.generators.len() == 1 && set.guard.is_some() {
let (ident, expr) = set.generators.get(0).unwrap();
let iter = self.instantiate_const_expr(
&set.iter,
expr,
erased_idx,
tmp_tv_cache,
not_found_is_qvar,
)?;
let pred = self.instantiate_pred_from_expr(&set.pred, tmp_tv_cache)?;
let pred =
self.instantiate_pred_from_expr(set.guard.as_ref().unwrap(), tmp_tv_cache)?;
if let Ok(t) = self.instantiate_tp_as_type(iter, set) {
return Ok(TyParam::t(refinement(set.var.inspect().clone(), t, pred)));
return Ok(TyParam::t(refinement(ident.inspect().clone(), t, pred)));
}
}
type_feature_error!(

View file

@ -204,3 +204,30 @@ opened in a binary mode.
newline := Str or NoneType,
closefd := Bool,
) => File!
'''
Convert `iterable` into an array.
'''
'''erg
assert array() == []
assert array((1, 2)) == [1, 2]
'''
.array: |T| (iterable := Iterable(T)) -> [T; _]
'''
Convert `iterable` into a dict.
'''
'''erg
assert dict() == {:}
assert dict([("a", 1), ("b": 2)]) == {"a": 1, "b": 2}
'''
.dict: |K, V| (iterable := Iterable((K, V))) -> {K: V}
'''
Convert `iterable` into a set.
'''
'''erg
assert set() == {}
assert set([1, 2]) == {1, 2}
'''
.set: |T| (iterable := Iterable(T)) -> {T; _}