mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
feat: (partial) comprehension support
This commit is contained in:
parent
482f22374b
commit
3fd66f1a32
14 changed files with 483 additions and 158 deletions
|
@ -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,
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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; _}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue