refactor!: rename Array -> List

This commit is contained in:
Shunsuke Shibayama 2024-04-04 23:24:07 +09:00
parent 41bf14629b
commit c6eb78a44d
248 changed files with 1948 additions and 1985 deletions

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3]
3│ l.push!(x)
^^^^^
AttributeError: Array object has no attribute `.push!`
AttributeError: List object has no attribute `.push!`
hint: to update the internal state of an object, make it mutable by using `!` operator
hint: `Array` has `push`, see https://erg-lang.github.io/docs/prelude/Array/##push for more information
hint: `Array!` has `push!`, see https://erg-lang.github.io/docs/prelude/Array!/##push! for more information
hint: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##push for more information
hint: `List!` has `push!`, see https://erg-lang.github.io/docs/prelude/List!/##push! for more information
```
## Requirements

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3]
3│ l.push!(x)
^^^^^
AttributeError: Arrayオブジェクトは`.push!`という属性を持っていません
AttributeError: Listオブジェクトは`.push!`という属性を持っていません
ヒント: オブジェクトの内部状態を変更したい場合は、`!`演算子を使って可変化してください
ヒント: `Array`は`push`メソッドを持っています、詳しくは https://erg-lang.github.io/docs/prelude/Array/##push を参照してください
ヒント: `Array!`は`push!`メソッドを持っています、詳しくは https://erg-lang.github.io/docs/prelude/Array!/##push! を参照してください
ヒント: `List`は`push`メソッドを持っています、詳しくは https://erg-lang.github.io/docs/prelude/List/##push を参照してください
ヒント: `List!`は`push!`メソッドを持っています、詳しくは https://erg-lang.github.io/docs/prelude/List!/##push! を参照してください
```
## Requirements

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3]
3│ l.push!(x)
^^^^^
AttributeError: Array object has no attribute `.push!`
AttributeError: List object has no attribute `.push!`
hint: to update the internal state of an object, make it mutable by using `!` operator
hint: `Array` has `push`, see https://erg-lang.github.io/docs/prelude/Array/##push for more information
hint: `Array!` has `push!`, see https://erg-lang.github.io/docs/prelude/Array!/##push! for more information
hint: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##push for more information
hint: `List!` has `push!`, see https://erg-lang.github.io/docs/prelude/List!/##push! for more information
```
## 要求

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3]
3│ l.push!(x)
^^^^^
AttributeError: Array object has no attribute `.push!`
AttributeError: List object has no attribute `.push!`
hint: to update the internal state of an object, make it mutable by using `!` operator
hint: `Array` has `push`, see https://erg-lang.github.io/docs/prelude/Array/##push for more information
hint: `Array!` has `push!`, see https://erg-lang.github.io/docs/prelude/Array!/##push! for more information
hint: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##push for more information
hint: `List!` has `push!`, see https://erg-lang.github.io/docs/prelude/List!/##push! for more information
```
## 要求

14
TODO.md
View file

@ -21,7 +21,7 @@
* [ ] Pattern-matching
* [x] Variable Pattern
* [x] Literal Pattern
* [x] Array Pattern
* [x] List Pattern
* [x] Tuple Pattern
* [x] Record Pattern
* [x] Data Type Pattern
@ -30,7 +30,7 @@
* [x] Positional arguments
* [x] Keyword arguments
* [x] Variable length arguments
* [x] Array literal
* [x] List literal
* [x] Record literal
* [x] Set literal
* [x] Dict literal
@ -58,11 +58,11 @@
* [ ] Patch definition
* [ ] Glue Patch definition
* [x] Range object
* [ ] Decorator
* [x] Decorator
* [ ] Comprehension
* [ ] Array
* [ ] Dict
* [ ] Set
* [x] List
* [x] Dict
* [x] Set
* [ ] Tuple
* [x] Pipeline operator
* [ ] ? operator
@ -91,7 +91,7 @@
* [x] `sys` (partially)
* [x] `time` (partially)
* [x] Load User Module
* [ ] Recursive module
* [x] Recursive module
* [x] Visibility check
* [x] Patching
* [ ] Implement a side-effect checker

View file

@ -3,7 +3,7 @@ use std::str::FromStr;
use erg_compiler::artifact::BuildRunnable;
use erg_compiler::erg_parser::parse::Parsable;
use erg_compiler::hir::{Accessor, Array, Def, Dict, Expr, KeyValue, Set, Tuple};
use erg_compiler::hir::{Accessor, Def, Dict, Expr, KeyValue, List, Set, Tuple};
use erg_compiler::varinfo::{AbsLocation, VarInfo};
use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
@ -145,8 +145,8 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
calls
}
Expr::UnaryOp(unop) => self.gen_outgoing_call(&unop.expr),
Expr::Array(Array::Normal(arr)) => {
for arg in arr.elems.pos_args.iter() {
Expr::List(List::Normal(lis)) => {
for arg in lis.elems.pos_args.iter() {
calls.extend(self.gen_outgoing_call(&arg.expr));
}
calls

View file

@ -142,7 +142,7 @@ impl<'a> HIRVisitor<'a> {
| Expr::Accessor(_)
| Expr::BinOp(_)
| Expr::UnaryOp(_)
| Expr::Array(_)
| Expr::List(_)
| Expr::Dict(_)
| Expr::Set(_)
| Expr::Tuple(_)
@ -275,7 +275,7 @@ impl<'a> HIRVisitor<'a> {
Expr::Def(def) => self.get_expr_from_def(expr, def, pos),
Expr::PatchDef(patch_def) => self.get_expr_from_patch_def(expr, patch_def, pos),
Expr::Lambda(lambda) => self.get_expr_from_lambda(expr, lambda, pos),
Expr::Array(arr) => self.get_expr_from_array(expr, arr, pos),
Expr::List(lis) => self.get_expr_from_list(expr, lis, pos),
Expr::Dict(dict) => self.get_expr_from_dict(expr, dict, pos),
Expr::Record(record) => self.get_expr_from_record(expr, record, pos),
Expr::Set(set) => self.get_expr_from_set(expr, set, pos),
@ -440,18 +440,18 @@ impl<'a> HIRVisitor<'a> {
self.get_expr_from_block(lambda.body.iter(), pos)
}
fn get_expr_from_array<'e>(
fn get_expr_from_list<'e>(
&'e self,
expr: &'e Expr,
arr: &'e Array,
lis: &'e List,
pos: Position,
) -> Option<&Expr> {
if arr.ln_end() == pos.ln_end() && self.search.matches(expr) {
if lis.ln_end() == pos.ln_end() && self.search.matches(expr) {
// arr: `[1, 2]`, pos: `]`
return Some(expr);
}
match arr {
Array::Normal(arr) => self.get_expr_from_args(&arr.elems, pos),
match lis {
List::Normal(lis) => self.get_expr_from_args(&lis.elems, pos),
_ => None, // todo!(),
}
}
@ -587,7 +587,7 @@ impl<'a> HIRVisitor<'a> {
Expr::PatchDef(patch_def) => self.get_patch_def_info(patch_def, token),
Expr::Def(def) => self.get_def_info(def, token),
Expr::Lambda(lambda) => self.get_lambda_info(lambda, token),
Expr::Array(arr) => self.get_array_info(arr, token),
Expr::List(lis) => self.get_list_info(lis, token),
Expr::Dict(dict) => self.get_dict_info(dict, token),
Expr::Record(record) => self.get_record_info(record, token),
Expr::Set(set) => self.get_set_info(set, token),
@ -764,9 +764,9 @@ impl<'a> HIRVisitor<'a> {
.or_else(|| self.get_block_info(lambda.body.iter(), token))
}
fn get_array_info(&self, arr: &Array, token: &Token) -> Option<VarInfo> {
match arr {
Array::Normal(arr) => self.get_args_info(&arr.elems, token),
fn get_list_info(&self, lis: &List, token: &Token) -> Option<VarInfo> {
match lis {
List::Normal(lis) => self.get_args_info(&lis.elems, token),
_ => None, // todo!(),
}
}

View file

@ -272,12 +272,12 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
lsp_log!("failed to get packages: {}", artifact.ast);
return cfg;
};
let Some(ast::Expr::Array(ast::Array::Normal(arr))) = pkgs.body.block.first() else {
let Some(ast::Expr::List(ast::List::Normal(lis))) = pkgs.body.block.first() else {
lsp_log!("packages must be an array: {pkgs}");
return cfg;
};
let mut packages = vec![];
for rec in arr.iter() {
for rec in lis.iter() {
let ast::Expr::Record(rec) = rec else {
lsp_log!("packages must be records: {rec}");
break;

View file

@ -35,11 +35,11 @@ use erg_parser::token::{Token, TokenKind};
use crate::compile::{AccessKind, Name, StoreLoadKind};
use crate::context::ControlKind;
use crate::error::CompileError;
use crate::hir::ArrayWithLength;
use crate::hir::DefaultParamSignature;
use crate::hir::ListWithLength;
use crate::hir::{
Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, GuardClause,
Identifier, Lambda, Literal, NonDefaultParamSignature, Params, PatchDef, PosArg, ReDef, Record,
Accessor, Args, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, GuardClause, Identifier,
Lambda, List, Literal, NonDefaultParamSignature, Params, PatchDef, PosArg, ReDef, Record,
Signature, SubrSignature, Tuple, UnaryOp, VarSignature, HIR,
};
use crate::ty::codeobj::{CodeObj, CodeObjFlags, MakeFunctionFlags};
@ -3031,20 +3031,20 @@ impl PyCodeGenerator {
}
// TODO: list comprehension
fn emit_array(&mut self, array: Array) {
fn emit_list(&mut self, list: List) {
let init_stack_len = self.stack_len();
if !self.cfg.no_std {
self.emit_push_null();
if array.is_unsized() {
self.emit_load_name_instr(Identifier::static_public("UnsizedArray"));
if list.is_unsized() {
self.emit_load_name_instr(Identifier::static_public("UnsizedList"));
} else {
self.emit_load_name_instr(Identifier::static_public("Array"));
self.emit_load_name_instr(Identifier::static_public("List"));
}
}
match array {
Array::Normal(mut arr) => {
let len = arr.elems.len();
while let Some(arg) = arr.elems.try_remove_pos(0) {
match list {
List::Normal(mut lis) => {
let len = lis.elems.len();
while let Some(arg) = lis.elems.try_remove_pos(0) {
self.emit_expr(arg.expr);
}
self.write_instr(BUILD_LIST);
@ -3055,7 +3055,7 @@ impl PyCodeGenerator {
self.stack_dec_n(len - 1);
}
}
Array::WithLength(ArrayWithLength {
List::WithLength(ListWithLength {
elem,
len: Some(len),
..
@ -3066,10 +3066,10 @@ impl PyCodeGenerator {
self.emit_call_instr(1, Name);
self.stack_dec();
self.emit_expr(*len);
self.emit_binop_instr(Token::dummy(TokenKind::Star, "*"), TypePair::ArrayNat);
self.emit_binop_instr(Token::dummy(TokenKind::Star, "*"), TypePair::ListNat);
return;
}
Array::WithLength(ArrayWithLength {
List::WithLength(ListWithLength {
elem, len: None, ..
}) => {
self.emit_expr(*elem);
@ -3331,7 +3331,7 @@ impl PyCodeGenerator {
Expr::UnaryOp(unary) => self.emit_unaryop(unary),
Expr::BinOp(bin) => self.emit_binop(bin),
Expr::Call(call) => self.emit_call(call),
Expr::Array(arr) => self.emit_array(arr),
Expr::List(lis) => self.emit_list(lis),
Expr::Tuple(tup) => self.emit_tuple(tup),
Expr::Set(set) => self.emit_set(set),
Expr::Dict(dict) => self.emit_dict(dict),
@ -3355,7 +3355,7 @@ impl PyCodeGenerator {
self.emit_load_name_instr(Identifier::public(&v.qual_name()));
}
other => match &other.qual_name()[..] {
t @ ("Bytes" | "Array" | "Dict" | "Set") => {
t @ ("Bytes" | "List" | "Dict" | "Set") => {
self.emit_push_null();
self.emit_load_name_instr(Identifier::public(t));
}
@ -3378,7 +3378,7 @@ impl PyCodeGenerator {
Expr::UnaryOp(unary) => self.emit_unaryop(unary),
Expr::BinOp(bin) => self.emit_binop(bin),
Expr::Call(call) => self.emit_call(call),
Expr::Array(arr) => self.emit_array(arr),
Expr::List(lis) => self.emit_list(lis),
Expr::Tuple(tup) => self.emit_tuple(tup),
Expr::Set(set) => self.emit_set(set),
Expr::Dict(dict) => self.emit_dict(dict),

View file

@ -192,7 +192,7 @@ impl Context {
..
}),
) if &n[..] == "GenericProc" => (Absolutely, true),
(Mono(l), Poly { name: r, .. }) if &l[..] == "GenericArray" && &r[..] == "Array" => {
(Mono(l), Poly { name: r, .. }) if &l[..] == "GenericList" && &r[..] == "List" => {
(Absolutely, true)
}
(Mono(l), Poly { name: r, .. }) if &l[..] == "GenericDict" && &r[..] == "Dict" => {
@ -494,8 +494,8 @@ impl Context {
} else if let Some(lfvt) = lfv.get_type() {
// e.g. lfv: ?L(: Int) is unreachable
// but
// ?L(: Array(Type, 3)) :> Array(Int, 3)
// => Array(Type, 3) :> Array(Typeof(Int), 3)
// ?L(: List(Type, 3)) :> List(Int, 3)
// => List(Type, 3) :> List(Typeof(Int), 3)
// => true
let rhs_meta = self.meta_type(rhs);
self.supertype_of(&lfvt, &rhs_meta)
@ -568,7 +568,7 @@ impl Context {
self.convert_tp_into_value(params[0].clone()).is_ok()
}
(ty @ (Type | ClassType | TraitType), Poly { name, params })
if &name[..] == "Array" || &name[..] == "UnsizedArray" || &name[..] == "Set" =>
if &name[..] == "List" || &name[..] == "UnsizedList" || &name[..] == "Set" =>
{
let Ok(elem_t) = self.convert_tp_into_type(params[0].clone()) else {
return false;
@ -666,8 +666,8 @@ impl Context {
// Int :> {I: Str| ...} == false
// Bool :> {1} == true
// Bool :> {2} == false
// [2, 3]: {A: Array(Nat) | A.prod() == 6}
// Array({1, 2}, _) :> {[3, 4]} == false
// [2, 3]: {A: List(Nat) | A.prod() == 6}
// List({1, 2}, _) :> {[3, 4]} == false
(l, Refinement(r)) => {
// Type / {S: Set(Str) | S == {"a", "b"}}
// TODO: GeneralEq
@ -698,7 +698,7 @@ impl Context {
// {N: Nat | ...} :> Int) == false
// ({I: Int | I >= 0} :> Int) == false
// {U(: Type)} :> { .x = {Int} }(== {{ .x = Int }}) == true
// {[1]} == Array({1}, 1) :> Array({1}, _) == true
// {[1]} == List({1}, 1) :> List({1}, _) == true
(Refinement(l), r) => {
if let Some(r) = r.to_singleton() {
return self.structural_supertype_of(lhs, &Type::Refinement(r));
@ -804,7 +804,7 @@ impl Context {
return false;
}
// [Int; 2] :> [Int; 3]
if &ln[..] == "Array" || &ln[..] == "Set" {
if &ln[..] == "List" || &ln[..] == "Set" {
let Ok(lt) = self.convert_tp_into_type(lparams[0].clone()) else {
return false;
};
@ -941,7 +941,7 @@ impl Context {
self.supertype_of(&self.get_tp_t(sup_p).unwrap_or(Obj), t)
}
},
(TyParam::Array(sup), TyParam::Array(sub))
(TyParam::List(sup), TyParam::List(sub))
| (TyParam::Tuple(sup), TyParam::Tuple(sub)) => {
if sup.len() > sub.len() || (variance.is_invariant() && sup.len() != sub.len()) {
return false;
@ -991,7 +991,7 @@ impl Context {
}
true
}
(TyParam::UnsizedArray(sup), TyParam::UnsizedArray(sub)) => {
(TyParam::UnsizedList(sup), TyParam::UnsizedList(sub)) => {
self.supertype_of_tp(sup, sub, variance)
}
(TyParam::Type(sup), TyParam::Type(sub)) => match variance {
@ -1308,8 +1308,8 @@ impl Context {
/// union(Nat, Int) == Int
/// union(Int, Str) == Int or Str
/// union(?T(<: Str), ?U(<: Int)) == ?T or ?U
/// union(Array(Int, 2), Array(Str, 2)) == Array(Int or Str, 2)
/// union(Array(Int, 2), Array(Str, 3)) == Array(Int, 2) or Array(Int, 3)
/// union(List(Int, 2), List(Str, 2)) == List(Int or Str, 2)
/// union(List(Int, 2), List(Str, 3)) == List(Int, 2) or List(Int, 3)
/// union({ .a = Int }, { .a = Str }) == { .a = Int or Str }
/// union({ .a = Int }, { .a = Int; .b = Int }) == { .a = Int } or { .a = Int; .b = Int } # not to lost `b` information
/// union((A and B) or C) == (A or C) and (B or C)
@ -1387,7 +1387,7 @@ impl Context {
t
}
(t, Type::Never) | (Type::Never, t) => t.clone(),
// Array({1, 2}, 2), Array({3, 4}, 2) ==> Array({1, 2, 3, 4}, 2)
// List({1, 2}, 2), List({3, 4}, 2) ==> List({1, 2, 3, 4}, 2)
(
Type::Poly {
name: ln,
@ -1430,7 +1430,7 @@ impl Context {
Some(TyParam::t(self.union(l, r.typ())))
}
(TyParam::Type(l), TyParam::Type(r)) => Some(TyParam::t(self.union(l, r))),
(TyParam::Array(l), TyParam::Array(r)) => {
(TyParam::List(l), TyParam::List(r)) => {
let mut tps = vec![];
for (l, r) in l.iter().zip(r.iter()) {
if let Some(tp) = self.union_tp(l, r) {
@ -1439,7 +1439,7 @@ impl Context {
return None;
}
}
Some(TyParam::Array(tps))
Some(TyParam::List(tps))
}
(fv @ TyParam::FreeVar(f), other) | (other, fv @ TyParam::FreeVar(f))
if f.is_unbound() =>
@ -2195,7 +2195,7 @@ impl Context {
}
}
/// {[]} == {A: Array(Never, _) | A == []} => Array(Never, 0)
/// {[]} == {A: List(Never, _) | A == []} => List(Never, 0)
pub(crate) fn refinement_to_poly(&self, refine: &RefinementType) -> Option<Type> {
if refine.t.is_monomorphic() {
return None;
@ -2207,7 +2207,7 @@ impl Context {
return None;
}
match &refine.t.qual_name()[..] {
"Array" => self.get_tp_t(rhs).ok().map(|t| t.derefine()),
"List" => self.get_tp_t(rhs).ok().map(|t| t.derefine()),
_ => None,
}
}

View file

@ -20,9 +20,9 @@ use erg_parser::desugar::Desugarer;
use erg_parser::token::{Token, TokenKind};
use crate::ty::constructors::{
array_t, bounded, closed_range, dict_t, func, guard, mono, mono_q, named_free_var, poly, proj,
bounded, closed_range, dict_t, func, guard, list_t, mono, mono_q, named_free_var, poly, proj,
proj_call, ref_, ref_mut, refinement, set_t, subr_t, subtypeof, tp_enum, try_v_enum, tuple_t,
unknown_len_array_t, v_enum,
unknown_len_list_t, v_enum,
};
use crate::ty::free::HasLevel;
use crate::ty::typaram::{OpKind, TyParam};
@ -154,13 +154,13 @@ impl<'c> Substituter<'c> {
/// e.g.
/// ```erg
/// qt: Array(T, N), st: Array(Int, 3)
/// qt: List(T, N), st: List(Int, 3)
/// qt: T or NoneType, st: NoneType or Int (T == Int)
/// ```
/// invalid (no effect):
/// ```erg
/// qt: Iterable(T), st: Array(Int, 3)
/// qt: Array(T, N), st: Array!(Int, 3) # TODO
/// qt: Iterable(T), st: List(Int, 3)
/// qt: List(T, N), st: List!(Int, 3) # TODO
/// ```
pub(crate) fn substitute_typarams(
ctx: &'c Context,
@ -282,9 +282,9 @@ impl<'c> Substituter<'c> {
if !qt.is_undoable_linked_var() && qt.is_generalized() && qt.is_free_var() {
qt.undoable_link(&st, &self.undoable_linked);
} else if qt.is_undoable_linked_var() && qt != st {
// e.g. Array(T, N) <: Add(Array(T, M))
// Array((Int), (3)) <: Add(Array((Int), (4))): OK
// Array((Int), (3)) <: Add(Array((Str), (4))): NG
// e.g. List(T, N) <: Add(List(T, M))
// List((Int), (3)) <: Add(List((Int), (4))): OK
// List((Int), (3)) <: Add(List((Str), (4))): NG
if let Some(union) = self.ctx.unify(&qt, &st) {
qt.undoable_link(&union, &self.undoable_linked);
} else {
@ -331,7 +331,7 @@ impl<'c> Substituter<'c> {
}
// NOTE: Rarely, double overwriting occurs.
// Whether this could be a problem is under consideration.
// e.g. `T` of Array(T, N) <: Add(T, M)
// e.g. `T` of List(T, N) <: Add(T, M)
TyParam::FreeVar(ref fv) if fv.is_generalized() => {
qtp.undoable_link(&stp, &self.undoable_linked);
/*if let Err(errs) = self.sub_unify_tp(&stp, &qtp, None, &(), false) {
@ -785,23 +785,23 @@ impl Context {
}
}
pub(crate) fn eval_const_normal_array(&self, arr: &NormalArray) -> EvalResult<ValueObj> {
pub(crate) fn eval_const_normal_list(&self, lis: &NormalList) -> EvalResult<ValueObj> {
let mut elems = vec![];
for elem in arr.elems.pos_args().iter() {
for elem in lis.elems.pos_args().iter() {
let elem = self.eval_const_expr(&elem.expr)?;
elems.push(elem);
}
Ok(ValueObj::Array(ArcArray::from(elems)))
Ok(ValueObj::List(ArcArray::from(elems)))
}
fn eval_const_array(&self, arr: &Array) -> EvalResult<ValueObj> {
match arr {
Array::Normal(arr) => self.eval_const_normal_array(arr),
Array::WithLength(arr) => {
let elem = self.eval_const_expr(&arr.elem.expr)?;
match arr.len.as_ref() {
fn eval_const_list(&self, lis: &List) -> EvalResult<ValueObj> {
match lis {
List::Normal(lis) => self.eval_const_normal_list(lis),
List::WithLength(lis) => {
let elem = self.eval_const_expr(&lis.elem.expr)?;
match lis.len.as_ref() {
Expr::Accessor(Accessor::Ident(ident)) if ident.is_discarded() => {
Ok(ValueObj::UnsizedArray(Box::new(elem)))
Ok(ValueObj::UnsizedList(Box::new(elem)))
}
other => {
let len = self.eval_const_expr(other)?;
@ -820,14 +820,14 @@ impl Context {
)
})?;
let arr = vec![elem; len];
Ok(ValueObj::Array(ArcArray::from(arr)))
Ok(ValueObj::List(ArcArray::from(arr)))
}
}
}
_ => Err(EvalErrors::from(EvalError::not_const_expr(
self.cfg.input.clone(),
line!() as usize,
arr.loc(),
lis.loc(),
self.caused_by(),
))),
}
@ -836,8 +836,8 @@ impl Context {
fn eval_const_set(&self, set: &AstSet) -> EvalResult<ValueObj> {
let mut elems = vec![];
match set {
AstSet::Normal(arr) => {
for elem in arr.elems.pos_args().iter() {
AstSet::Normal(lis) => {
for elem in lis.elems.pos_args().iter() {
let elem = self.eval_const_expr(&elem.expr)?;
elems.push(elem);
}
@ -875,8 +875,8 @@ impl Context {
fn eval_const_tuple(&self, tuple: &Tuple) -> EvalResult<ValueObj> {
let mut elems = vec![];
match tuple {
Tuple::Normal(arr) => {
for elem in arr.elems.pos_args().iter() {
Tuple::Normal(lis) => {
for elem in lis.elems.pos_args().iter() {
let elem = self.eval_const_expr(&elem.expr)?;
elems.push(elem);
}
@ -1109,7 +1109,7 @@ impl Context {
Expr::BinOp(bin) => self.eval_const_bin(bin),
Expr::UnaryOp(unary) => self.eval_const_unary(unary),
Expr::Call(call) => self.eval_const_call(call),
Expr::Array(arr) => self.eval_const_array(arr),
Expr::List(lis) => self.eval_const_list(lis),
Expr::Set(set) => self.eval_const_set(set),
Expr::Dict(dict) => self.eval_const_dict(dict),
Expr::Tuple(tuple) => self.eval_const_tuple(tuple),
@ -1139,7 +1139,7 @@ impl Context {
Expr::BinOp(bin) => self.eval_const_bin(bin),
Expr::UnaryOp(unary) => self.eval_const_unary(unary),
Expr::Call(call) => self.eval_const_call(call),
Expr::Array(arr) => self.eval_const_array(arr),
Expr::List(lis) => self.eval_const_list(lis),
Expr::Set(set) => self.eval_const_set(set),
Expr::Dict(dict) => self.eval_const_dict(dict),
Expr::Tuple(tuple) => self.eval_const_tuple(tuple),
@ -1412,8 +1412,8 @@ impl Context {
(TyParam::Dict(l), TyParam::Dict(r)) if op == OpKind::Add => {
Ok(TyParam::Dict(l.concat(r)))
}
(TyParam::Array(l), TyParam::Array(r)) if op == OpKind::Add => {
Ok(TyParam::Array([l, r].concat()))
(TyParam::List(l), TyParam::List(r)) if op == OpKind::Add => {
Ok(TyParam::List([l, r].concat()))
}
(TyParam::FreeVar(fv), r) if fv.is_linked() => {
let t = fv.crack().clone();
@ -1563,16 +1563,16 @@ impl Context {
TyParam::App { name, args } => self.eval_app(name, args),
TyParam::BinOp { op, lhs, rhs } => self.eval_bin_tp(op, *lhs, *rhs),
TyParam::UnaryOp { op, val } => self.eval_unary_tp(op, *val),
TyParam::Array(tps) => {
TyParam::List(tps) => {
let mut new_tps = Vec::with_capacity(tps.len());
for tp in tps {
new_tps.push(self.eval_tp(tp)?);
}
Ok(TyParam::Array(new_tps))
Ok(TyParam::List(new_tps))
}
TyParam::UnsizedArray(elem) => {
TyParam::UnsizedList(elem) => {
let elem = self.eval_tp(*elem)?;
Ok(TyParam::UnsizedArray(Box::new(elem)))
Ok(TyParam::UnsizedList(Box::new(elem)))
}
TyParam::Tuple(tps) => {
let mut new_tps = Vec::with_capacity(tps.len());
@ -2055,17 +2055,17 @@ impl Context {
}
Ok(tuple_t(ts))
}
TyParam::Array(tps) => {
TyParam::List(tps) => {
let mut union = Type::Never;
let len = tps.len();
for tp in tps {
union = self.union(&union, &self.convert_tp_into_type(tp)?);
}
Ok(array_t(union, TyParam::value(len)))
Ok(list_t(union, TyParam::value(len)))
}
TyParam::UnsizedArray(elem) => {
TyParam::UnsizedList(elem) => {
let elem = self.convert_tp_into_type(*elem)?;
Ok(unknown_len_array_t(elem))
Ok(unknown_len_list_t(elem))
}
TyParam::Set(tps) => {
let mut union = Type::Never;
@ -2095,7 +2095,7 @@ impl Context {
let t = fv.crack().clone();
self.convert_tp_into_type(t)
}
// TyParam(Ts: Array(Type)) -> Type(Ts: Array(Type))
// TyParam(Ts: List(Type)) -> Type(Ts: List(Type))
// TyParam(?S(: Str)) -> Err(...),
// TyParam(?D(: GenericDict)) -> Ok(?D(: GenericDict)),
// FIXME: GenericDict
@ -2136,17 +2136,17 @@ impl Context {
self.convert_tp_into_value(tp)
}
TyParam::Value(v) => Ok(v),
TyParam::Array(arr) => {
TyParam::List(lis) => {
let mut new = vec![];
for elem in arr {
for elem in lis {
let elem = self.convert_tp_into_value(elem)?;
new.push(elem);
}
Ok(ValueObj::Array(new.into()))
Ok(ValueObj::List(new.into()))
}
TyParam::UnsizedArray(elem) => {
TyParam::UnsizedList(elem) => {
let elem = self.convert_tp_into_value(*elem)?;
Ok(ValueObj::UnsizedArray(Box::new(elem)))
Ok(ValueObj::UnsizedList(Box::new(elem)))
}
TyParam::Tuple(tys) => {
let mut new = vec![];
@ -2244,17 +2244,17 @@ impl Context {
}
Ok(tuple_t(new_ts))
}
ValueObj::Array(arr) => {
let len = TyParam::value(arr.len());
ValueObj::List(lis) => {
let len = TyParam::value(lis.len());
let mut union = Type::Never;
for v in arr.iter().cloned() {
for v in lis.iter().cloned() {
union = self.union(&union, &self.convert_value_into_type(v)?);
}
Ok(array_t(union, len))
Ok(list_t(union, len))
}
ValueObj::UnsizedArray(elem) => {
ValueObj::UnsizedList(elem) => {
let elem = self.convert_value_into_type(*elem)?;
Ok(unknown_len_array_t(elem))
Ok(unknown_len_list_t(elem))
}
ValueObj::Set(set) => try_v_enum(set).map_err(ValueObj::Set),
ValueObj::Dict(dic) => {
@ -2279,23 +2279,23 @@ impl Context {
pub(crate) fn convert_value_into_tp(value: ValueObj) -> Result<TyParam, TyParam> {
match value {
ValueObj::Type(t) => Ok(TyParam::t(t.into_typ())),
ValueObj::Array(arr) => {
let mut new_arr = vec![];
for v in arr.iter().cloned() {
ValueObj::List(lis) => {
let mut new_lis = vec![];
for v in lis.iter().cloned() {
let tp = match Self::convert_value_into_tp(v) {
Ok(tp) => tp,
Err(tp) => tp,
};
new_arr.push(tp);
new_lis.push(tp);
}
Ok(TyParam::Array(new_arr))
Ok(TyParam::List(new_lis))
}
ValueObj::UnsizedArray(elem) => {
ValueObj::UnsizedList(elem) => {
let tp = match Self::convert_value_into_tp(*elem) {
Ok(tp) => tp,
Err(tp) => tp,
};
Ok(TyParam::UnsizedArray(Box::new(tp)))
Ok(TyParam::UnsizedList(Box::new(tp)))
}
ValueObj::Tuple(vs) => {
let mut new_ts = vec![];
@ -2404,14 +2404,14 @@ impl Context {
}
}
pub(crate) fn convert_type_to_array(&self, ty: Type) -> Result<Vec<ValueObj>, Type> {
pub(crate) fn convert_type_to_list(&self, ty: Type) -> Result<Vec<ValueObj>, Type> {
match ty {
Type::FreeVar(fv) if fv.is_linked() => {
let t = fv.crack().clone();
self.convert_type_to_array(t)
self.convert_type_to_list(t)
}
Type::Refinement(refine) => self.convert_type_to_array(*refine.t),
Type::Poly { name, params } if &name[..] == "Array" || &name[..] == "Array!" => {
Type::Refinement(refine) => self.convert_type_to_list(*refine.t),
Type::Poly { name, params } if &name[..] == "List" || &name[..] == "List!" => {
let Ok(t) = self.convert_tp_into_type(params[0].clone()) else {
log!(err "cannot convert to type: {}", params[0]);
return Err(poly(name, params));
@ -2429,14 +2429,11 @@ impl Context {
}
}
pub(crate) fn convert_value_into_array(
&self,
val: ValueObj,
) -> Result<Vec<ValueObj>, ValueObj> {
pub(crate) fn convert_value_into_list(&self, val: ValueObj) -> Result<Vec<ValueObj>, ValueObj> {
match val {
ValueObj::Array(arr) => Ok(arr.to_vec()),
ValueObj::List(lis) => Ok(lis.to_vec()),
ValueObj::Type(t) => self
.convert_type_to_array(t.into_typ())
.convert_type_to_list(t.into_typ())
.map_err(ValueObj::builtin_type),
_ => Err(val),
}
@ -2972,13 +2969,13 @@ impl Context {
line!(),
))
}),
TyParam::Array(tps) => {
TyParam::List(tps) => {
let tp_t = if let Some(fst) = tps.first() {
self.get_tp_t(fst)?
} else {
Never
};
let t = array_t(tp_t, TyParam::value(tps.len()));
let t = list_t(tp_t, TyParam::value(tps.len()));
Ok(t)
}
TyParam::Tuple(tps) => {
@ -3113,7 +3110,7 @@ impl Context {
(TyParam::Type(l), TyParam::Type(r)) => l == r,
(TyParam::Value(l), TyParam::Value(r)) => l == r,
(TyParam::Erased(l), TyParam::Erased(r)) => l == r,
(TyParam::Array(l), TyParam::Array(r)) => l == r,
(TyParam::List(l), TyParam::List(r)) => l == r,
(TyParam::Tuple(l), TyParam::Tuple(r)) => l == r,
(TyParam::Set(l), TyParam::Set(r)) => l == r, // FIXME:
(TyParam::Dict(l), TyParam::Dict(r)) => l == r,

View file

@ -59,7 +59,7 @@ impl Generalizer {
fv.generalize();
TyParam::FreeVar(fv)
}
TyParam::Array(tps) => TyParam::Array(
TyParam::List(tps) => TyParam::List(
tps.into_iter()
.map(|tp| self.generalize_tp(tp, uninit))
.collect(),
@ -496,12 +496,12 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
val: Box::new(val),
})
}
TyParam::Array(tps) => {
TyParam::List(tps) => {
let mut new_tps = vec![];
for tp in tps {
new_tps.push(self.deref_tp(tp)?);
}
Ok(TyParam::Array(new_tps))
Ok(TyParam::List(new_tps))
}
TyParam::Tuple(tps) => {
let mut new_tps = vec![];
@ -1374,24 +1374,24 @@ impl Context {
}
Ok(())
}
hir::Expr::Array(array) => match array {
hir::Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter_mut() {
hir::Expr::List(list) => match list {
hir::List::Normal(lis) => {
for elem in lis.elems.pos_args.iter_mut() {
self.resolve_expr_t(&mut elem.expr, qnames)?;
}
let t = mem::take(&mut arr.t);
let mut dereferencer = Dereferencer::simple(self, qnames, arr);
arr.t = dereferencer.deref_tyvar(t)?;
let t = mem::take(&mut lis.t);
let mut dereferencer = Dereferencer::simple(self, qnames, lis);
lis.t = dereferencer.deref_tyvar(t)?;
Ok(())
}
hir::Array::WithLength(arr) => {
self.resolve_expr_t(&mut arr.elem, qnames)?;
if let Some(len) = &mut arr.len {
hir::List::WithLength(lis) => {
self.resolve_expr_t(&mut lis.elem, qnames)?;
if let Some(len) = &mut lis.len {
self.resolve_expr_t(len, qnames)?;
}
let t = mem::take(&mut arr.t);
let mut dereferencer = Dereferencer::simple(self, qnames, arr);
arr.t = dereferencer.deref_tyvar(t)?;
let t = mem::take(&mut lis.t);
let mut dereferencer = Dereferencer::simple(self, qnames, lis);
lis.t = dereferencer.deref_tyvar(t)?;
Ok(())
}
other => feature_error!(

View file

@ -44,7 +44,7 @@ impl Context {
expected: &Type,
found: &Type,
) -> Option<String> {
if &callee_t.qual_name()[..] == "Array" && attr == Some("__getitem__") && nth == 1 {
if &callee_t.qual_name()[..] == "List" && attr == Some("__getitem__") && nth == 1 {
let len = &callee_t.typarams().get(1).cloned()?;
let (_, _, pred) = found.clone().deconstruct_refinement().ok()?;
if let Predicate::Equal { rhs: accessed, .. } = pred {
@ -58,10 +58,10 @@ impl Context {
accessed.clone()
};
return Some(switch_lang! {
"japanese" => format!("配列の長さは{len}ですが、{accessed}番目の要素にアクセスしようとしています"),
"japanese" => format!("リストの長さは{len}ですが、{accessed}番目の要素にアクセスしようとしています"),
"simplified_chinese" => format!("数组长度为{len}但尝试访问第{accessed}个元素"),
"traditional_chinese" => format!("陣列長度為{len}但嘗試訪問第{accessed}個元素"),
"english" => format!("Array length is {len} but tried to access the {accessed}th element"),
"english" => format!("List length is {len} but tried to access the {accessed}th element"),
});
}
}

View file

@ -489,7 +489,7 @@ impl Context {
BYTES,
or(
mono(BYTES),
array_t(Type::from(value(0)..=value(255)), TyParam::erased(Nat)),
list_t(Type::from(value(0)..=value(255)), TyParam::erased(Nat)),
),
)],
vec![kw(
@ -954,7 +954,7 @@ impl Context {
None,
vec![kw(KW_MAXSPLIT, Nat)],
None,
unknown_len_array_t(Str),
unknown_len_list_t(Str),
),
Immutable,
Visibility::BUILTIN_PUBLIC,
@ -968,7 +968,7 @@ impl Context {
None,
vec![kw(KW_KEEPENDS, Bool)],
None,
unknown_len_array_t(Str),
unknown_len_list_t(Str),
),
Immutable,
Visibility::BUILTIN_PUBLIC,
@ -1356,14 +1356,14 @@ impl Context {
type_.register_superclass(Obj, &obj);
type_.register_builtin_erg_impl(
FUNC_MRO,
fn0_met(Type, array_t(Type, TyParam::erased(Nat))),
fn0_met(Type, list_t(Type, TyParam::erased(Nat))),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
// TODO: PolyType
type_.register_builtin_erg_impl(
FUNDAMENTAL_ARGS,
array_t(Type, TyParam::erased(Nat)),
list_t(Type, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
@ -1424,31 +1424,31 @@ impl Context {
);
code.register_builtin_erg_impl(
FUNC_CO_VARNAMES,
array_t(Str, TyParam::erased(Nat)),
list_t(Str, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
code.register_builtin_erg_impl(
FUNC_CO_CONSTS,
array_t(Obj, TyParam::erased(Nat)),
list_t(Obj, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
code.register_builtin_erg_impl(
FUNC_CO_NAMES,
array_t(Str, TyParam::erased(Nat)),
list_t(Str, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
code.register_builtin_erg_impl(
FUNC_CO_FREEVARS,
array_t(Str, TyParam::erased(Nat)),
list_t(Str, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
code.register_builtin_erg_impl(
FUNC_CO_CELLVARS,
array_t(Str, TyParam::erased(Nat)),
list_t(Str, TyParam::erased(Nat)),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
@ -1566,100 +1566,100 @@ impl Context {
if ERG_MODE {
py_module.register_superclass(g_module_t.clone(), &generic_module);
}
/* GenericArray */
let mut generic_array = Self::builtin_mono_class(GENERIC_ARRAY, 1);
generic_array.register_superclass(Obj, &obj);
/* GenericList */
let mut generic_list = Self::builtin_mono_class(GENERIC_LIST, 1);
generic_list.register_superclass(Obj, &obj);
let mut arr_eq = Self::builtin_methods(Some(mono(EQ)), 2);
arr_eq.register_builtin_erg_impl(
OP_EQ,
fn1_met(mono(GENERIC_ARRAY), mono(GENERIC_ARRAY), Bool),
fn1_met(mono(GENERIC_LIST), mono(GENERIC_LIST), Bool),
Const,
Visibility::BUILTIN_PUBLIC,
);
generic_array.register_trait_methods(mono(GENERIC_ARRAY), arr_eq);
generic_list.register_trait_methods(mono(GENERIC_LIST), arr_eq);
let t_call = func1(
poly(ITERABLE, vec![ty_tp(T.clone())]),
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
generic_array.register_builtin_erg_impl(
generic_list.register_builtin_erg_impl(
FUNDAMENTAL_CALL,
t_call,
Immutable,
Visibility::BUILTIN_PUBLIC,
);
let mut array_hash = Self::builtin_methods(Some(mono(HASH)), 1);
array_hash.register_builtin_erg_impl(
let mut list_hash = Self::builtin_methods(Some(mono(HASH)), 1);
list_hash.register_builtin_erg_impl(
OP_HASH,
fn0_met(mono(GENERIC_ARRAY), Int),
fn0_met(mono(GENERIC_LIST), Int),
Const,
Visibility::BUILTIN_PUBLIC,
);
generic_array.register_trait_methods(mono(GENERIC_ARRAY), array_hash);
let unsized_array_t = poly(UNSIZED_ARRAY, vec![ty_tp(T.clone())]);
let mut unsized_array =
Self::builtin_poly_class(UNSIZED_ARRAY, vec![ParamSpec::t_nd(TY_T)], 1);
unsized_array.register_superclass(Obj, &obj);
unsized_array.register_builtin_decl(KW_ELEM, T.clone(), vis.clone(), Some(KW_ELEM));
/* Array */
let mut array_ =
Self::builtin_poly_class(ARRAY, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 10);
array_.register_superclass(mono(GENERIC_ARRAY), &generic_array);
array_
generic_list.register_trait_methods(mono(GENERIC_LIST), list_hash);
let unsized_list_t = poly(UNSIZED_LIST, vec![ty_tp(T.clone())]);
let mut unsized_list =
Self::builtin_poly_class(UNSIZED_LIST, vec![ParamSpec::t_nd(TY_T)], 1);
unsized_list.register_superclass(Obj, &obj);
unsized_list.register_builtin_decl(KW_ELEM, T.clone(), vis.clone(), Some(KW_ELEM));
/* List */
let mut list_ =
Self::builtin_poly_class(LIST, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 10);
list_.register_superclass(mono(GENERIC_LIST), &generic_list);
list_
.register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())]))
.unwrap();
let arr_t = array_t(T.clone(), N.clone());
let lis_t = list_t(T.clone(), N.clone());
let t = no_var_fn_met(
arr_t.clone(),
vec![kw(KW_RHS, array_t(T.clone(), M.clone()))],
lis_t.clone(),
vec![kw(KW_RHS, list_t(T.clone(), M.clone()))],
vec![],
array_t(T.clone(), N.clone() + M.clone()),
list_t(T.clone(), N.clone() + M.clone()),
)
.quantify();
array_.register_py_builtin(FUNC_CONCAT, t.clone(), Some(OP_ADD), 9);
list_.register_py_builtin(FUNC_CONCAT, t.clone(), Some(OP_ADD), 9);
let t_count =
no_var_fn_met(arr_t.clone(), vec![kw(KW_X, T.clone())], vec![], Nat).quantify();
array_.register_py_builtin(FUNC_COUNT, t_count, Some(FUNC_COUNT), 17);
no_var_fn_met(lis_t.clone(), vec![kw(KW_X, T.clone())], vec![], Nat).quantify();
list_.register_py_builtin(FUNC_COUNT, t_count, Some(FUNC_COUNT), 17);
let t_get = no_var_fn_met(
arr_t.clone(),
lis_t.clone(),
vec![pos(Nat)],
vec![ParamTy::kw_default(KW_DEFAULT.into(), U.clone(), NoneType)],
or(T.clone(), U.clone()),
)
.quantify();
array_.register_builtin_erg_impl(FUNC_GET, t_get, Immutable, Visibility::BUILTIN_PUBLIC);
// Array(T, N)|<: Add(Array(T, M))|.
// Output = Array(T, N + M)
// __add__: (self: Array(T, N), other: Array(T, M)) -> Array(T, N + M) = Array.concat
let mut array_add = Self::builtin_methods(
Some(poly(ADD, vec![ty_tp(array_t(T.clone(), M.clone()))])),
list_.register_builtin_erg_impl(FUNC_GET, t_get, Immutable, Visibility::BUILTIN_PUBLIC);
// List(T, N)|<: Add(List(T, M))|.
// Output = List(T, N + M)
// __add__: (self: List(T, N), other: List(T, M)) -> List(T, N + M) = List.concat
let mut list_add = Self::builtin_methods(
Some(poly(ADD, vec![ty_tp(list_t(T.clone(), M.clone()))])),
2,
);
array_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Visibility::BUILTIN_PUBLIC);
let out_t = array_t(T.clone(), N.clone() + M.clone());
array_add.register_builtin_const(
list_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Visibility::BUILTIN_PUBLIC);
let out_t = list_t(T.clone(), N.clone() + M.clone());
list_add.register_builtin_const(
OUTPUT,
Visibility::BUILTIN_PUBLIC,
None,
ValueObj::builtin_class(out_t),
);
array_.register_trait_methods(arr_t.clone(), array_add);
list_.register_trait_methods(lis_t.clone(), list_add);
let t = no_var_fn_met(
arr_t.clone(),
lis_t.clone(),
vec![kw(KW_ELEM, T.clone())],
vec![],
array_t(T.clone(), N.clone() + value(1usize)),
list_t(T.clone(), N.clone() + value(1usize)),
)
.quantify();
array_.register_builtin_erg_impl(FUNC_PUSH, t, Immutable, Visibility::BUILTIN_PUBLIC);
list_.register_builtin_erg_impl(FUNC_PUSH, t, Immutable, Visibility::BUILTIN_PUBLIC);
let repeat_t = no_var_fn_met(
arr_t.clone(),
lis_t.clone(),
vec![pos(singleton(Nat, M.clone()))],
vec![],
array_t(T.clone(), N.clone() * M.clone()),
list_t(T.clone(), N.clone() * M.clone()),
)
.quantify();
array_.register_builtin_erg_impl(
list_.register_builtin_erg_impl(
FUNC_REPEAT,
repeat_t,
Immutable,
@ -1667,15 +1667,15 @@ impl Context {
);
// [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!)
let mut_type =
ValueObj::builtin_class(poly(MUT_ARRAY, vec![TyParam::t(T.clone()), N.clone()]));
let mut array_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2);
array_mutizable.register_builtin_const(
ValueObj::builtin_class(poly(MUT_LIST, vec![TyParam::t(T.clone()), N.clone()]));
let mut list_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2);
list_mutizable.register_builtin_const(
MUTABLE_MUT_TYPE,
Visibility::BUILTIN_PUBLIC,
None,
mut_type,
);
array_.register_trait_methods(arr_t.clone(), array_mutizable);
list_.register_trait_methods(lis_t.clone(), list_mutizable);
let var = FRESH_GEN.fresh_varname();
let input = refinement(
var.clone(),
@ -1684,259 +1684,254 @@ impl Context {
);
// __getitem__: |T, N|(self: [T; N], _: {I: Nat | I <= N}) -> T
// and (self: [T; N], _: Range(Int)) -> [T; _]
let array_getitem_t = (fn1_kw_met(
array_t(T.clone(), N.clone()),
anon(input.clone()),
T.clone(),
) & fn1_kw_met(
array_t(T.clone(), N.clone()),
anon(poly(RANGE, vec![ty_tp(Int)])),
unknown_len_array_t(T.clone()),
))
.quantify();
let list_getitem_t =
(fn1_kw_met(list_t(T.clone(), N.clone()), anon(input.clone()), T.clone())
& fn1_kw_met(
list_t(T.clone(), N.clone()),
anon(poly(RANGE, vec![ty_tp(Int)])),
unknown_len_list_t(T.clone()),
))
.quantify();
let get_item = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNDAMENTAL_GETITEM,
__array_getitem__,
array_getitem_t,
__list_getitem__,
list_getitem_t,
None,
)));
array_.register_builtin_const(
list_.register_builtin_const(
FUNDAMENTAL_GETITEM,
Visibility::BUILTIN_PUBLIC,
None,
get_item,
);
let array_insert_t = no_var_fn_met(
array_t(T.clone(), N.clone()),
let list_insert_t = no_var_fn_met(
list_t(T.clone(), N.clone()),
vec![pos(Nat), kw(KW_ELEM, T.clone())],
vec![],
array_t(T.clone(), N.clone() + value(1usize)),
list_t(T.clone(), N.clone() + value(1usize)),
)
.quantify();
let array_insert = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
let list_insert = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_INSERT,
array_insert_at,
array_insert_t.clone(),
list_insert_at,
list_insert_t.clone(),
None,
)));
array_._register_builtin_const(
list_._register_builtin_const(
FUNC_INSERT,
Visibility::BUILTIN_PUBLIC,
Some(array_insert_t),
array_insert,
Some(list_insert_t),
list_insert,
Some(FUNC_INSERT_AT.into()),
);
let array_remove_at_t = no_var_fn_met(
array_t(T.clone(), N.clone()),
let list_remove_at_t = no_var_fn_met(
list_t(T.clone(), N.clone()),
vec![pos(Nat)],
vec![],
array_t(T.clone(), N.clone() - value(1usize)),
list_t(T.clone(), N.clone() - value(1usize)),
)
.quantify();
let array_remove_at = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
let list_remove_at = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REMOVE_AT,
array_remove_at,
array_remove_at_t.clone(),
list_remove_at,
list_remove_at_t.clone(),
None,
)));
array_.register_builtin_const(
list_.register_builtin_const(
FUNC_REMOVE_AT,
Visibility::BUILTIN_PUBLIC,
Some(array_remove_at_t),
array_remove_at,
Some(list_remove_at_t),
list_remove_at,
);
let array_remove_all_t = no_var_fn_met(
array_t(T.clone(), N.clone()),
let list_remove_all_t = no_var_fn_met(
list_t(T.clone(), N.clone()),
vec![kw(KW_ELEM, T.clone())],
vec![],
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let array_remove_all = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
let list_remove_all = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REMOVE_ALL,
array_remove_all,
array_remove_all_t.clone(),
list_remove_all,
list_remove_all_t.clone(),
None,
)));
array_.register_builtin_const(
list_.register_builtin_const(
FUNC_REMOVE_ALL,
Visibility::BUILTIN_PUBLIC,
Some(array_remove_all_t),
array_remove_all,
Some(list_remove_all_t),
list_remove_all,
);
array_
list_
.register_trait(self, poly(INDEXABLE, vec![ty_tp(input), ty_tp(T.clone())]))
.unwrap();
array_
list_
.register_trait(
self,
poly(
HAS_SHAPE,
vec![ty_tp(arr_t.clone()).proj_call(FUNC_SHAPE.into(), vec![])],
vec![ty_tp(lis_t.clone()).proj_call(FUNC_SHAPE.into(), vec![])],
),
)
.unwrap();
array_
list_
.register_trait(
self,
poly(
HAS_SCALAR_TYPE,
vec![ty_tp(arr_t.clone()).proj_call(FUNC_SCALAR_TYPE.into(), vec![])],
vec![ty_tp(lis_t.clone()).proj_call(FUNC_SCALAR_TYPE.into(), vec![])],
),
)
.unwrap();
let mut array_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
array_sized.register_builtin_erg_impl(
let mut list_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
list_sized.register_builtin_erg_impl(
FUNDAMENTAL_LEN,
fn0_met(arr_t.clone(), Nat).quantify(),
fn0_met(lis_t.clone(), Nat).quantify(),
Const,
Visibility::BUILTIN_PUBLIC,
);
array_.register_trait_methods(arr_t.clone(), array_sized);
list_.register_trait_methods(lis_t.clone(), list_sized);
// union: (self: [Type; _]) -> Type
let array_union_t = fn0_met(array_t(Type, TyParam::erased(Nat)), Type).quantify();
let list_union_t = fn0_met(list_t(Type, TyParam::erased(Nat)), Type).quantify();
let union = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_UNION,
array_union,
array_union_t,
list_union,
list_union_t,
None,
)));
array_.register_builtin_const(FUNC_UNION, Visibility::BUILTIN_PUBLIC, None, union);
list_.register_builtin_const(FUNC_UNION, Visibility::BUILTIN_PUBLIC, None, union);
// shape: (self: [Type; _]) -> [Nat; _]
let array_shape_t = fn0_met(
array_t(Type, TyParam::erased(Nat)),
unknown_len_array_t(Nat),
)
.quantify();
let list_shape_t =
fn0_met(list_t(Type, TyParam::erased(Nat)), unknown_len_list_t(Nat)).quantify();
let shape = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SHAPE,
array_shape,
array_shape_t,
list_shape,
list_shape_t,
None,
)));
array_.register_builtin_const(FUNC_SHAPE, Visibility::BUILTIN_PUBLIC, None, shape);
let array_scalar_type_t = fn0_met(Type, Type).quantify();
let array_scalar_type = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
list_.register_builtin_const(FUNC_SHAPE, Visibility::BUILTIN_PUBLIC, None, shape);
let list_scalar_type_t = fn0_met(Type, Type).quantify();
let list_scalar_type = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SCALAR_TYPE,
array_scalar_type,
array_scalar_type_t,
list_scalar_type,
list_scalar_type_t,
None,
)));
array_.register_builtin_const(
list_.register_builtin_const(
FUNC_SCALAR_TYPE,
Visibility::BUILTIN_PUBLIC,
None,
array_scalar_type,
list_scalar_type,
);
let mut array_eq = Self::builtin_methods(Some(mono(EQ)), 2);
array_eq.register_builtin_erg_impl(
let mut list_eq = Self::builtin_methods(Some(mono(EQ)), 2);
list_eq.register_builtin_erg_impl(
OP_EQ,
fn1_met(arr_t.clone(), arr_t.clone(), Bool).quantify(),
fn1_met(lis_t.clone(), lis_t.clone(), Bool).quantify(),
Const,
Visibility::BUILTIN_PUBLIC,
);
array_.register_trait_methods(arr_t.clone(), array_eq);
array_
list_.register_trait_methods(lis_t.clone(), list_eq);
list_
.register_trait(self, poly(SEQUENCE, vec![ty_tp(T.clone())]))
.unwrap();
array_.unregister_trait(&poly(INDEXABLE, vec![ty_tp(Nat), ty_tp(T.clone())]));
let mut array_show = Self::builtin_methods(Some(mono(SHOW)), 1);
array_show.register_builtin_py_impl(
list_.unregister_trait(&poly(INDEXABLE, vec![ty_tp(Nat), ty_tp(T.clone())]));
let mut list_show = Self::builtin_methods(Some(mono(SHOW)), 1);
list_show.register_builtin_py_impl(
FUNDAMENTAL_STR,
fn0_met(arr_t.clone(), Str).quantify(),
fn0_met(lis_t.clone(), Str).quantify(),
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_STR),
);
array_.register_trait_methods(arr_t.clone(), array_show);
let mut array_iterable =
list_.register_trait_methods(lis_t.clone(), list_show);
let mut list_iterable =
Self::builtin_methods(Some(poly(ITERABLE, vec![ty_tp(T.clone())])), 2);
let array_iter = poly(ARRAY_ITERATOR, vec![ty_tp(T.clone())]);
let t = fn0_met(array_t(T.clone(), TyParam::erased(Nat)), array_iter.clone()).quantify();
array_iterable.register_builtin_py_impl(
let list_iter = poly(LIST_ITERATOR, vec![ty_tp(T.clone())]);
let t = fn0_met(list_t(T.clone(), TyParam::erased(Nat)), list_iter.clone()).quantify();
list_iterable.register_builtin_py_impl(
FUNC_ITER,
t,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_ITER),
);
array_iterable.register_builtin_const(
list_iterable.register_builtin_const(
ITERATOR,
vis.clone(),
None,
ValueObj::builtin_class(array_iter),
ValueObj::builtin_class(list_iter),
);
array_.register_trait_methods(arr_t.clone(), array_iterable);
let mut array_collection =
list_.register_trait_methods(lis_t.clone(), list_iterable);
let mut list_collection =
Self::builtin_methods(Some(poly(COLLECTION, vec![ty_tp(T.clone())])), 4);
array_collection.register_builtin_erg_impl(
list_collection.register_builtin_erg_impl(
FUNDAMENTAL_CONTAINS,
fn1_met(arr_t.clone(), T.clone(), Bool).quantify(),
fn1_met(lis_t.clone(), T.clone(), Bool).quantify(),
Const,
Visibility::BUILTIN_PUBLIC,
);
array_.register_trait_methods(arr_t.clone(), array_collection);
array_
list_.register_trait_methods(lis_t.clone(), list_collection);
list_
.register_trait(self, poly(COLLECTION, vec![ty_tp(T.clone())]))
.unwrap();
let t = fn1_met(
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
func1(T.clone(), Bool),
tuple_t(vec![
array_t(T.clone(), TyParam::erased(Nat)),
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
]),
);
array_.register_py_builtin(FUNC_PARTITION, t.quantify(), Some(FUNC_PARTITION), 37);
list_.register_py_builtin(FUNC_PARTITION, t.quantify(), Some(FUNC_PARTITION), 37);
let t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
vec![],
vec![kw(
KW_SAME_BUCKET,
or(func2(T.clone(), T.clone(), Bool), NoneType),
)],
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
);
array_.register_py_builtin(FUNC_DEDUP, t.quantify(), Some(FUNC_DEDUP), 28);
list_.register_py_builtin(FUNC_DEDUP, t.quantify(), Some(FUNC_DEDUP), 28);
let sum_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
vec![],
vec![kw(KW_START, T.clone())],
T.clone(),
);
let sum = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SUM,
array_sum,
list_sum,
sum_t.quantify(),
None,
)));
array_.register_builtin_const(FUNC_SUM, Visibility::BUILTIN_PUBLIC, None, sum);
list_.register_builtin_const(FUNC_SUM, Visibility::BUILTIN_PUBLIC, None, sum);
let prod_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
vec![],
vec![kw(KW_START, T.clone())],
T.clone(),
);
let prod = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_PROD,
array_prod,
list_prod,
prod_t.quantify(),
None,
)));
array_.register_builtin_const(FUNC_PROD, Visibility::BUILTIN_PUBLIC, None, prod);
list_.register_builtin_const(FUNC_PROD, Visibility::BUILTIN_PUBLIC, None, prod);
let reversed_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
vec![],
vec![],
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
);
let reversed = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REVERSED,
array_reversed,
list_reversed,
reversed_t.quantify(),
None,
)));
array_.register_builtin_const(FUNC_REVERSED, Visibility::BUILTIN_PUBLIC, None, reversed);
list_.register_builtin_const(FUNC_REVERSED, Visibility::BUILTIN_PUBLIC, None, reversed);
/* Slice */
let mut slice = Self::builtin_mono_class(SLICE, 3);
slice.register_superclass(Obj, &obj);
@ -2284,7 +2279,7 @@ impl Context {
/* GenericTuple */
let mut generic_tuple = Self::builtin_mono_class(GENERIC_TUPLE, 1);
generic_tuple.register_superclass(Obj, &obj);
// tuple doesn't have a constructor, use `Array` instead
// tuple doesn't have a constructor, use `List` instead
let mut tuple_eq = Self::builtin_methods(Some(mono(EQ)), 2);
tuple_eq.register_builtin_erg_impl(
OP_EQ,
@ -2302,14 +2297,11 @@ impl Context {
);
generic_tuple.register_trait_methods(mono(GENERIC_TUPLE), tuple_hash);
generic_tuple.register_trait(self, mono(EQ_HASH)).unwrap();
let Ts = mono_q_tp(TY_TS, instanceof(array_t(Type, N.clone())));
// Ts <: GenericArray
let Ts = mono_q_tp(TY_TS, instanceof(list_t(Type, N.clone())));
// Ts <: GenericList
let _tuple_t = poly(TUPLE, vec![Ts.clone()]);
let mut tuple_ = Self::builtin_poly_class(
TUPLE,
vec![PS::named_nd(TY_TS, array_t(Type, N.clone()))],
2,
);
let mut tuple_ =
Self::builtin_poly_class(TUPLE, vec![PS::named_nd(TY_TS, list_t(Type, N.clone()))], 2);
tuple_.register_superclass(mono(GENERIC_TUPLE), &generic_tuple);
tuple_
.register_trait(self, poly(OUTPUT, vec![Ts.clone()]))
@ -2498,12 +2490,12 @@ impl Context {
str_iterator
.register_trait(self, poly(OUTPUT, vec![ty_tp(Str)]))
.unwrap();
let mut array_iterator = Self::builtin_poly_class(ARRAY_ITERATOR, vec![PS::t_nd(TY_T)], 1);
array_iterator.register_superclass(Obj, &obj);
array_iterator
let mut list_iterator = Self::builtin_poly_class(LIST_ITERATOR, vec![PS::t_nd(TY_T)], 1);
list_iterator.register_superclass(Obj, &obj);
list_iterator
.register_trait(self, poly(ITERABLE, vec![ty_tp(T.clone())]))
.unwrap();
array_iterator
list_iterator
.register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())]))
.unwrap();
let mut set_iterator = Self::builtin_poly_class(SET_ITERATOR, vec![PS::t_nd(TY_T)], 1);
@ -3004,16 +2996,16 @@ impl Context {
file_mut
.register_trait(self, mono(CONTEXT_MANAGER))
.unwrap();
/* Array! */
let array_mut_t = poly(MUT_ARRAY, vec![ty_tp(T.clone()), N.clone()]);
let mut array_mut_ =
Self::builtin_poly_class(MUT_ARRAY, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 2);
array_mut_.register_superclass(arr_t.clone(), &array_);
/* List! */
let list_mut_t = poly(MUT_LIST, vec![ty_tp(T.clone()), N.clone()]);
let mut list_mut_ =
Self::builtin_poly_class(MUT_LIST, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 2);
list_mut_.register_superclass(lis_t.clone(), &list_);
let t = pr_met(
ref_mut(
array_mut_t.clone(),
list_mut_t.clone(),
Some(poly(
MUT_ARRAY,
MUT_LIST,
vec![ty_tp(T.clone()), N.clone() + value(1usize)],
)),
),
@ -3023,18 +3015,15 @@ impl Context {
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_PUSH, t, Some(FUNC_APPEND), 15);
let t_copy = fn0_met(ref_(array_mut_t.clone()), array_mut_t.clone()).quantify();
let mut array_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
array_mut_copy.register_py_builtin(FUNC_COPY, t_copy, Some(FUNC_COPY), 116);
array_mut_.register_trait_methods(array_mut_t.clone(), array_mut_copy);
list_mut_.register_py_builtin(PROC_PUSH, t, Some(FUNC_APPEND), 15);
let t_copy = fn0_met(ref_(list_mut_t.clone()), list_mut_t.clone()).quantify();
let mut list_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
list_mut_copy.register_py_builtin(FUNC_COPY, t_copy, Some(FUNC_COPY), 116);
list_mut_.register_trait_methods(list_mut_t.clone(), list_mut_copy);
let t_extend = pr_met(
ref_mut(
array_mut_t.clone(),
Some(poly(
MUT_ARRAY,
vec![ty_tp(T.clone()), TyParam::erased(Nat)],
)),
list_mut_t.clone(),
Some(poly(MUT_LIST, vec![ty_tp(T.clone()), TyParam::erased(Nat)])),
),
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
None,
@ -3042,12 +3031,12 @@ impl Context {
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_EXTEND, t_extend, Some(FUNC_EXTEND), 24);
list_mut_.register_py_builtin(PROC_EXTEND, t_extend, Some(FUNC_EXTEND), 24);
let t_insert = pr_met(
ref_mut(
array_mut_t.clone(),
list_mut_t.clone(),
Some(poly(
MUT_ARRAY,
MUT_LIST,
vec![ty_tp(T.clone()), N.clone() + value(1usize)],
)),
),
@ -3057,12 +3046,12 @@ impl Context {
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_INSERT, t_insert, Some(FUNC_INSERT), 33);
list_mut_.register_py_builtin(PROC_INSERT, t_insert, Some(FUNC_INSERT), 33);
let t_remove = pr_met(
ref_mut(
array_mut_t.clone(),
list_mut_t.clone(),
Some(poly(
MUT_ARRAY,
MUT_LIST,
vec![ty_tp(T.clone()), N.clone() - value(1usize)],
)),
),
@ -3072,12 +3061,12 @@ impl Context {
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_REMOVE, t_remove, Some(FUNC_REMOVE), 42);
list_mut_.register_py_builtin(PROC_REMOVE, t_remove, Some(FUNC_REMOVE), 42);
let t_pop = pr_met(
ref_mut(
array_mut_t.clone(),
list_mut_t.clone(),
Some(poly(
MUT_ARRAY,
MUT_LIST,
vec![ty_tp(T.clone()), N.clone() - value(1usize)],
)),
),
@ -3087,18 +3076,18 @@ impl Context {
T.clone(),
)
.quantify();
array_mut_.register_py_builtin(PROC_POP, t_pop, Some(FUNC_POP), 52);
list_mut_.register_py_builtin(PROC_POP, t_pop, Some(FUNC_POP), 52);
let t_clear = pr0_met(
ref_mut(
array_mut_t.clone(),
Some(poly(MUT_ARRAY, vec![ty_tp(T.clone()), value(0usize)])),
list_mut_t.clone(),
Some(poly(MUT_LIST, vec![ty_tp(T.clone()), value(0usize)])),
),
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_CLEAR, t_clear, Some(FUNC_CLEAR), 61);
list_mut_.register_py_builtin(PROC_CLEAR, t_clear, Some(FUNC_CLEAR), 61);
let t_sort = pr_met(
ref_mut(array_mut_t.clone(), None),
ref_mut(list_mut_t.clone(), None),
vec![],
None,
vec![kw(
@ -3108,77 +3097,77 @@ impl Context {
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_SORT, t_sort, Some(FUNC_SORT), 78);
let t_reverse = pr0_met(ref_mut(array_mut_t.clone(), None), NoneType).quantify();
array_mut_.register_py_builtin(PROC_REVERSE, t_reverse, Some(FUNC_REVERSE), 87);
list_mut_.register_py_builtin(PROC_SORT, t_sort, Some(FUNC_SORT), 78);
let t_reverse = pr0_met(ref_mut(list_mut_t.clone(), None), NoneType).quantify();
list_mut_.register_py_builtin(PROC_REVERSE, t_reverse, Some(FUNC_REVERSE), 87);
let t = pr_met(
array_mut_t.clone(),
list_mut_t.clone(),
vec![kw(KW_FUNC, nd_func(vec![anon(T.clone())], None, T.clone()))],
None,
vec![],
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_STRICT_MAP, t, None, 96);
list_mut_.register_py_builtin(PROC_STRICT_MAP, t, None, 96);
let t_update_nth = pr_met(
ref_mut(array_mut_t.clone(), None),
ref_mut(list_mut_t.clone(), None),
vec![kw(KW_IDX, Nat), kw(KW_FUNC, func1(T.clone(), T.clone()))],
None,
vec![],
NoneType,
)
.quantify();
array_mut_.register_py_builtin(PROC_UPDATE_NTH, t_update_nth, Some(FUNC_UPDATE_NTH), 105);
list_mut_.register_py_builtin(PROC_UPDATE_NTH, t_update_nth, Some(FUNC_UPDATE_NTH), 105);
let f_t = kw(
KW_FUNC,
no_var_func(vec![kw(KW_OLD, arr_t.clone())], vec![], arr_t.clone()),
no_var_func(vec![kw(KW_OLD, lis_t.clone())], vec![], lis_t.clone()),
);
let t = pr_met(
ref_mut(array_mut_t.clone(), None),
ref_mut(list_mut_t.clone(), None),
vec![f_t],
None,
vec![],
NoneType,
)
.quantify();
let mut array_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2);
array_mut_mutable.register_builtin_py_impl(
let mut list_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2);
list_mut_mutable.register_builtin_py_impl(
PROC_UPDATE,
t,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_UPDATE),
);
array_mut_.register_trait_methods(array_mut_t.clone(), array_mut_mutable);
list_mut_.register_trait_methods(list_mut_t.clone(), list_mut_mutable);
/* ByteArray! */
let bytearray_mut_t = mono(BYTEARRAY);
let mut bytearray_mut = Self::builtin_mono_class(BYTEARRAY, 2);
let bytelist_mut_t = mono(BYTEARRAY);
let mut bytelist_mut = Self::builtin_mono_class(BYTEARRAY, 2);
let t_append = pr_met(
ref_mut(bytearray_mut_t.clone(), None),
ref_mut(bytelist_mut_t.clone(), None),
vec![kw(KW_ELEM, int_interval(IntervalOp::Closed, 0, 255))],
None,
vec![],
NoneType,
);
bytearray_mut.register_builtin_py_impl(
bytelist_mut.register_builtin_py_impl(
PROC_PUSH,
t_append,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_APPEND),
);
let t_copy = fn0_met(ref_(bytearray_mut_t.clone()), bytearray_mut_t.clone());
let mut bytearray_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
bytearray_mut_copy.register_builtin_py_impl(
let t_copy = fn0_met(ref_(bytelist_mut_t.clone()), bytelist_mut_t.clone());
let mut bytelist_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
bytelist_mut_copy.register_builtin_py_impl(
FUNC_COPY,
t_copy,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_COPY),
);
bytearray_mut.register_trait_methods(bytearray_mut_t.clone(), bytearray_mut_copy);
bytelist_mut.register_trait_methods(bytelist_mut_t.clone(), bytelist_mut_copy);
let t_extend = pr_met(
ref_mut(bytearray_mut_t.clone(), None),
ref_mut(bytelist_mut_t.clone(), None),
vec![kw(
KW_ITERABLE,
poly(
@ -3190,7 +3179,7 @@ impl Context {
vec![],
NoneType,
);
bytearray_mut.register_builtin_py_impl(
bytelist_mut.register_builtin_py_impl(
PROC_EXTEND,
t_extend,
Immutable,
@ -3198,7 +3187,7 @@ impl Context {
Some(FUNC_EXTEND),
);
let t_insert = pr_met(
ref_mut(bytearray_mut_t.clone(), None),
ref_mut(bytelist_mut_t.clone(), None),
vec![
kw(KW_INDEX, Nat),
kw(KW_ELEM, int_interval(IntervalOp::Closed, 0, 255)),
@ -3207,7 +3196,7 @@ impl Context {
vec![],
NoneType,
);
bytearray_mut.register_builtin_py_impl(
bytelist_mut.register_builtin_py_impl(
PROC_INSERT,
t_insert,
Immutable,
@ -3215,18 +3204,18 @@ impl Context {
Some(FUNC_INSERT),
);
let t_pop = pr0_met(
ref_mut(bytearray_mut_t.clone(), None),
ref_mut(bytelist_mut_t.clone(), None),
int_interval(IntervalOp::Closed, 0, 255),
);
bytearray_mut.register_builtin_py_impl(
bytelist_mut.register_builtin_py_impl(
PROC_POP,
t_pop,
Immutable,
Visibility::BUILTIN_PUBLIC,
Some(FUNC_POP),
);
let t_reverse = pr0_met(ref_mut(bytearray_mut_t.clone(), None), NoneType);
bytearray_mut.register_builtin_py_impl(
let t_reverse = pr0_met(ref_mut(bytelist_mut_t.clone(), None), NoneType);
bytelist_mut.register_builtin_py_impl(
PROC_REVERSE,
t_reverse,
Immutable,
@ -3445,7 +3434,7 @@ impl Context {
base_exception.register_superclass(Obj, &obj);
base_exception.register_builtin_erg_impl(
ATTR_ARGS,
unknown_len_array_t(Str),
unknown_len_list_t(Str),
Immutable,
Visibility::BUILTIN_PUBLIC,
);
@ -3695,20 +3684,20 @@ impl Context {
Some(MODULE_TYPE),
);
self.register_builtin_type(
mono(GENERIC_ARRAY),
generic_array,
mono(GENERIC_LIST),
generic_list,
vis.clone(),
Const,
Some(ARRAY),
Some(LIST),
);
self.register_builtin_type(
unsized_array_t,
unsized_array,
unsized_list_t,
unsized_list,
vis.clone(),
Const,
Some(UNSIZED_ARRAY),
Some(UNSIZED_LIST),
);
self.register_builtin_type(arr_t, array_, vis.clone(), Const, Some(ARRAY));
self.register_builtin_type(lis_t, list_, vis.clone(), Const, Some(LIST));
self.register_builtin_type(mono(SLICE), slice, vis.clone(), Const, Some(FUNC_SLICE));
self.register_builtin_type(
mono(GENERIC_SET),
@ -3753,11 +3742,11 @@ impl Context {
Some(FUNC_STR_ITERATOR),
);
self.register_builtin_type(
poly(ARRAY_ITERATOR, vec![ty_tp(T.clone())]),
array_iterator,
poly(LIST_ITERATOR, vec![ty_tp(T.clone())]),
list_iterator,
Visibility::BUILTIN_PRIVATE,
Const,
Some(FUNC_ARRAY_ITERATOR),
Some(FUNC_LIST_ITERATOR),
);
self.register_builtin_type(
poly(SET_ITERATOR, vec![ty_tp(T.clone())]),
@ -3851,10 +3840,10 @@ impl Context {
Some(MEMORYVIEW),
);
self.register_builtin_type(mono(MUT_FILE), file_mut, vis.clone(), Const, Some(FILE));
self.register_builtin_type(array_mut_t, array_mut_, vis.clone(), Const, Some(ARRAY));
self.register_builtin_type(list_mut_t, list_mut_, vis.clone(), Const, Some(LIST));
self.register_builtin_type(
bytearray_mut_t,
bytearray_mut,
bytelist_mut_t,
bytelist_mut,
vis.clone(),
Const,
Some(BYTEARRAY),

View file

@ -186,14 +186,14 @@ pub(crate) fn structural_func(mut args: ValueArgs, ctx: &Context) -> EvalValueRe
Ok(ValueObj::gen_t(GenTypeObj::structural(t, base)).into())
}
pub(crate) fn __array_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
pub(crate) fn __list_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let slf = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let slf = match ctx.convert_value_into_array(slf) {
let slf = match ctx.convert_value_into_list(slf) {
Ok(slf) => slf,
Err(val) => {
return Err(type_mismatch("Array", val, "Self"));
return Err(type_mismatch("List", val, "Self"));
}
};
let index = args
@ -369,7 +369,7 @@ pub(crate) fn dict_keys(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<T
// let keys = poly(DICT_KEYS, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into())
} else {
Ok(ValueObj::Array(slf.into_keys().collect::<Vec<_>>().into()).into())
Ok(ValueObj::List(slf.into_keys().collect::<Vec<_>>().into()).into())
}
}
@ -396,7 +396,7 @@ pub(crate) fn dict_values(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
// let values = poly(DICT_VALUES, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into())
} else {
Ok(ValueObj::Array(slf.into_values().collect::<Vec<_>>().into()).into())
Ok(ValueObj::List(slf.into_values().collect::<Vec<_>>().into()).into())
}
}
@ -423,7 +423,7 @@ pub(crate) fn dict_items(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<
// let items = poly(DICT_ITEMS, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into())
} else {
Ok(ValueObj::Array(
Ok(ValueObj::List(
slf.into_iter()
.map(|(k, v)| ValueObj::Tuple(vec![k, v].into()))
.collect::<Vec<_>>()
@ -468,12 +468,12 @@ pub(crate) fn dict_diff(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
}
/// `[Int, Str].union() == Int or Str`
pub(crate) fn array_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
pub(crate) fn list_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let slf = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let ValueObj::Array(slf) = slf else {
return Err(type_mismatch("Array", slf, "Self"));
let ValueObj::List(slf) = slf else {
return Err(type_mismatch("List", slf, "Self"));
};
let slf = slf
.iter()
@ -485,15 +485,15 @@ pub(crate) fn array_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
Ok(ValueObj::builtin_type(union).into())
}
fn _arr_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
fn _lis_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
let mut shape = vec![];
let mut arr = arr;
loop {
match arr {
ValueObj::Array(a) => {
ValueObj::List(a) => {
shape.push(ValueObj::from(a.len()).into());
match a.first() {
Some(arr_ @ (ValueObj::Array(_) | ValueObj::Type(_))) => {
Some(arr_ @ (ValueObj::List(_) | ValueObj::Type(_))) => {
arr = arr_.clone();
}
_ => {
@ -501,7 +501,7 @@ fn _arr_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
}
}
}
ValueObj::Type(ref t) if &t.typ().qual_name()[..] == "Array" => {
ValueObj::Type(ref t) if &t.typ().qual_name()[..] == "List" => {
let mut tps = t.typ().typarams();
let elem = match ctx.convert_tp_into_type(tps.remove(0)) {
Ok(elem) => elem,
@ -522,23 +522,23 @@ fn _arr_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
}
/// ```erg
/// Array(Int, 2).shape() == [2,]
/// Array(Array(Int, 2), N).shape() == [N, 2]
/// List(Int, 2).shape() == [2,]
/// List(List(Int, 2), N).shape() == [N, 2]
/// [1, 2].shape() == [2,]
/// [[1, 2], [3, 4], [5, 6]].shape() == [3, 2]
/// ```
pub(crate) fn array_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let res = _arr_shape(arr, ctx).unwrap();
let arr = TyParam::Array(res);
Ok(arr)
let res = _lis_shape(val, ctx).unwrap();
let lis = TyParam::List(res);
Ok(lis)
}
fn _array_scalar_type(mut typ: Type, ctx: &Context) -> Result<Type, String> {
fn _list_scalar_type(mut typ: Type, ctx: &Context) -> Result<Type, String> {
loop {
if matches!(&typ.qual_name()[..], "Array" | "Array!" | "UnsizedArray") {
if matches!(&typ.qual_name()[..], "List" | "List!" | "UnsizedList") {
let tp = typ.typarams().remove(0);
match ctx.convert_tp_into_type(tp) {
Ok(typ_) => {
@ -554,21 +554,21 @@ fn _array_scalar_type(mut typ: Type, ctx: &Context) -> Result<Type, String> {
}
}
pub(crate) fn array_scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
pub(crate) fn list_scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let slf = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let Ok(slf) = ctx.convert_value_into_type(slf.clone()) else {
return Err(type_mismatch("Type", slf, "Self"));
};
let res = _array_scalar_type(slf, ctx).unwrap();
let res = _list_scalar_type(slf, ctx).unwrap();
Ok(TyParam::t(res))
}
fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
loop {
match value {
ValueObj::Array(a) => match a.first() {
ValueObj::List(a) => match a.first() {
Some(elem) => {
value = elem.clone();
}
@ -592,7 +592,7 @@ fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
return Ok(Type::Never);
}
},
ValueObj::UnsizedArray(a) => {
ValueObj::UnsizedList(a) => {
value = *a.clone();
}
other => {
@ -608,17 +608,17 @@ fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
/// ```
#[allow(unused)]
pub(crate) fn scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let res = _scalar_type(arr, ctx).unwrap();
let arr = TyParam::t(res);
Ok(arr)
let res = _scalar_type(val, ctx).unwrap();
let lis = TyParam::t(res);
Ok(lis)
}
fn _array_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
fn _list_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
ValueObj::List(a) => {
let mut sum = 0f64;
for v in a.iter() {
match v {
@ -657,18 +657,18 @@ fn _array_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
/// ```erg
/// [1, 2].sum() == [3,]
/// ```
pub(crate) fn array_sum(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_sum(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let res = _array_sum(arr, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_sum(val, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
fn _array_prod(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
fn _list_prod(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match lis {
ValueObj::List(a) => {
let mut prod = 1f64;
for v in a.iter() {
match v {
@ -700,63 +700,63 @@ fn _array_prod(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
Ok(ValueObj::Float(prod))
}
}
_ => Err(format!("Cannot prod {arr}")),
_ => Err(format!("Cannot prod {lis}")),
}
}
/// ```erg
/// [1, 2].prod() == [2,]
/// ```
pub(crate) fn array_prod(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_prod(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let res = _array_prod(arr, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_prod(val, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
fn _array_reversed(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
fn _list_reversed(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match lis {
ValueObj::List(a) => {
let mut vec = a.to_vec();
vec.reverse();
Ok(ValueObj::Array(vec.into()))
Ok(ValueObj::List(vec.into()))
}
_ => Err(format!("Cannot reverse {arr}")),
_ => Err(format!("Cannot reverse {lis}")),
}
}
pub(crate) fn array_reversed(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_reversed(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let res = _array_reversed(arr, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_reversed(val, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
fn _array_insert_at(
arr: ValueObj,
fn _list_insert_at(
lis: ValueObj,
index: usize,
value: ValueObj,
_ctx: &Context,
) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
match lis {
ValueObj::List(a) => {
let mut a = a.to_vec();
if index > a.len() {
return Err(format!("Index out of range: {index}"));
}
a.insert(index, value);
Ok(ValueObj::Array(a.into()))
Ok(ValueObj::List(a.into()))
}
_ => Err(format!("Cannot insert into {arr}")),
_ => Err(format!("Cannot insert into {lis}")),
}
}
pub(crate) fn array_insert_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_insert_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let lis = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let index = args
@ -768,27 +768,27 @@ pub(crate) fn array_insert_at(mut args: ValueArgs, ctx: &Context) -> EvalValueRe
let Ok(index) = usize::try_from(&index) else {
return Err(type_mismatch("Nat", index, "Index"));
};
let res = _array_insert_at(arr, index, value, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_insert_at(lis, index, value, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
fn _array_remove_at(arr: ValueObj, index: usize, _ctx: &Context) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
fn _list_remove_at(lis: ValueObj, index: usize, _ctx: &Context) -> Result<ValueObj, String> {
match lis {
ValueObj::List(a) => {
let mut a = a.to_vec();
if index >= a.len() {
return Err(format!("Index out of range: {index}"));
}
a.remove(index);
Ok(ValueObj::Array(a.into()))
Ok(ValueObj::List(a.into()))
}
_ => Err(format!("Cannot remove from {arr}")),
_ => Err(format!("Cannot remove from {lis}")),
}
}
pub(crate) fn array_remove_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_remove_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let index = args
@ -797,32 +797,32 @@ pub(crate) fn array_remove_at(mut args: ValueArgs, ctx: &Context) -> EvalValueRe
let Ok(index) = usize::try_from(&index) else {
return Err(type_mismatch("Nat", index, "Index"));
};
let res = _array_remove_at(arr, index, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_remove_at(val, index, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
fn _array_remove_all(arr: ValueObj, value: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr {
ValueObj::Array(a) => {
fn _list_remove_all(lis: ValueObj, value: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match lis {
ValueObj::List(a) => {
let mut a = a.to_vec();
a.retain(|v| v != &value);
Ok(ValueObj::Array(a.into()))
Ok(ValueObj::List(a.into()))
}
_ => Err(format!("Cannot remove from {arr}")),
_ => Err(format!("Cannot remove from {lis}")),
}
}
pub(crate) fn array_remove_all(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args
pub(crate) fn list_remove_all(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let val = args
.remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?;
let value = args
.remove_left_or_key("Value")
.ok_or_else(|| not_passed("Value"))?;
let res = _array_remove_all(arr, value, ctx).unwrap();
let arr = TyParam::Value(res);
Ok(arr)
let res = _list_remove_all(val, value, ctx).unwrap();
let lis = TyParam::Value(res);
Ok(lis)
}
pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
@ -1058,7 +1058,7 @@ pub(crate) fn str_join(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
return Err(type_mismatch("Str", slf, "self"));
};
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
ValueObj::Dict(d) => d.into_keys().collect(),
@ -1136,7 +1136,7 @@ pub(crate) fn all_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1162,7 +1162,7 @@ pub(crate) fn any_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1191,7 +1191,7 @@ pub(crate) fn filter_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1223,7 +1223,7 @@ pub(crate) fn filter_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
}
}
}
Ok(TyParam::Value(ValueObj::Array(filtered.into())))
Ok(TyParam::Value(ValueObj::List(filtered.into())))
}
pub(crate) fn len_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
@ -1231,7 +1231,7 @@ pub(crate) fn len_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let len = match container {
ValueObj::Array(a) => a.len(),
ValueObj::List(a) => a.len(),
ValueObj::Tuple(t) => t.len(),
ValueObj::Set(s) => s.len(),
ValueObj::Dict(d) => d.len(),
@ -1252,7 +1252,7 @@ pub(crate) fn map_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Ty
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1277,7 +1277,7 @@ pub(crate) fn map_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Ty
}
}
}
Ok(TyParam::Array(mapped))
Ok(TyParam::List(mapped))
}
pub(crate) fn max_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
@ -1285,7 +1285,7 @@ pub(crate) fn max_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1320,7 +1320,7 @@ pub(crate) fn min_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1365,7 +1365,7 @@ pub(crate) fn reversed_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueRes
.remove_left_or_key("reversible")
.ok_or_else(|| not_passed("reversible"))?;
let arr = match reversible {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
_ => {
return Err(type_mismatch("Reversible", reversible, "reversible"));
@ -1375,7 +1375,7 @@ pub(crate) fn reversed_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueRes
for v in arr.into_iter().rev() {
reversed.push(v);
}
Ok(TyParam::Value(ValueObj::Array(reversed.into())))
Ok(TyParam::Value(ValueObj::List(reversed.into())))
}
pub(crate) fn str_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
@ -1390,7 +1390,7 @@ pub(crate) fn sum_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
ValueObj::Dict(d) => d.into_keys().collect(),
@ -1502,7 +1502,7 @@ pub(crate) fn zip_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
.remove_left_or_key("iterable2")
.ok_or_else(|| not_passed("iterable2"))?;
let iterable1 = match iterable1 {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1510,7 +1510,7 @@ pub(crate) fn zip_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
}
};
let iterable2 = match iterable2 {
ValueObj::Array(a) => a.to_vec(),
ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(),
_ => {
@ -1521,7 +1521,7 @@ pub(crate) fn zip_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<T
for (v1, v2) in iterable1.into_iter().zip(iterable2.into_iter()) {
zipped.push(ValueObj::Tuple(vec![v1, v2].into()));
}
Ok(TyParam::Value(ValueObj::Array(zipped.into())))
Ok(TyParam::Value(ValueObj::List(zipped.into())))
}
/// ```erg

View file

@ -53,12 +53,6 @@ impl Context {
None,
)));
let t_ascii = nd_func(vec![kw(KW_OBJECT, Obj)], None, Str);
let t_array = no_var_func(
vec![],
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
array_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let t_assert = no_var_func(vec![kw(KW_TEST, Bool)], vec![kw(KW_MSG, Str)], NoneType);
let t_bin = nd_func(vec![kw(KW_N, Int)], None, Str);
let t_bytes = func0(mono(BYTES))
@ -182,7 +176,7 @@ impl Context {
let t_isinstance = nd_func(
vec![
kw(KW_OBJECT, Obj),
kw(KW_CLASSINFO, ClassType | unknown_len_array_t(ClassType)), // TODO: => ClassInfo
kw(KW_CLASSINFO, ClassType | unknown_len_list_t(ClassType)), // TODO: => ClassInfo
],
None,
Bool,
@ -190,7 +184,7 @@ impl Context {
let t_issubclass = nd_func(
vec![
kw(KW_SUBCLASS, ClassType),
kw(KW_CLASSINFO, ClassType | unknown_len_array_t(ClassType)), // TODO: => ClassInfo
kw(KW_CLASSINFO, ClassType | unknown_len_list_t(ClassType)), // TODO: => ClassInfo
],
None,
Bool,
@ -216,6 +210,12 @@ impl Context {
t_len.clone(),
None,
)));
let t_list = no_var_func(
vec![],
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
list_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let t_log = func(
vec![],
Some(kw(KW_OBJECTS, ref_(Obj))),
@ -341,7 +341,7 @@ impl Context {
let t_sorted = nd_func(
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
None,
array_t(T.clone(), TyParam::erased(Nat)),
list_t(T.clone(), TyParam::erased(Nat)),
)
.quantify();
let t_staticmethod = nd_func(vec![kw(KW_FUNC, F.clone())], None, F.clone()).quantify();
@ -411,7 +411,7 @@ impl Context {
Some(FUNC_ANY),
Some(33),
);
self.register_py_builtin(FUNC_ARRAY, t_array, Some(FUNC_LIST), 215);
self.register_py_builtin(FUNC_LIST, t_list, 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.
let name = if PYTHON_MODE { FUNC_ASSERT } else { "assert__" };

View file

@ -258,10 +258,10 @@ const GENERIC_MODULE: &str = "GenericModule";
const PATH: &str = "Path";
const MODULE: &str = "Module";
const PY_MODULE: &str = "PyModule";
const GENERIC_ARRAY: &str = "GenericArray";
const UNSIZED_ARRAY: &str = "UnsizedArray";
const ARRAY: &str = "Array";
const MUT_ARRAY: &str = "Array!";
const GENERIC_LIST: &str = "GenericList";
const UNSIZED_LIST: &str = "UnsizedList";
const LIST: &str = "List";
const MUT_LIST: &str = "List!";
const FUNC_UPDATE_NTH: &str = "update_nth";
const PROC_UPDATE_NTH: &str = "update_nth!";
const FUNC_PARTITION: &str = "partition";
@ -273,7 +273,7 @@ const FUNC_REPEAT: &str = "repeat";
const PROC_PUSH: &str = "push!";
const FUNC_MERGE: &str = "merge";
const PROC_MERGE: &str = "merge!";
const ARRAY_ITERATOR: &str = "ArrayIterator";
const LIST_ITERATOR: &str = "ListIterator";
const GENERIC_SET: &str = "GenericSet";
const SET: &str = "Set";
const MUT_SET: &str = "Set!";
@ -375,7 +375,7 @@ const FUNC_DICT: &str = "dict";
const FUNC_TUPLE: &str = "tuple";
const UNION: &str = "Union";
const FUNC_STR_ITERATOR: &str = "str_iterator";
const FUNC_ARRAY_ITERATOR: &str = "array_iterator";
const FUNC_LIST_ITERATOR: &str = "list_iterator";
const FUNC_SET_ITERATOR: &str = "set_iterator";
const FUNC_TUPLE_ITERATOR: &str = "tuple_iterator";
const FUNC_ENUMERATE: &str = "enumerate";
@ -391,7 +391,7 @@ const FUNC_NTH: &str = "nth";
const FUNC_SKIP: &str = "skip";
const FUNC_POSITION: &str = "position";
const FUNC_CHAIN: &str = "chain";
const FUNC_INTO_ARRAY: &str = "into_array";
const FUNC_TO_LIST: &str = "to_list";
const FILE: &str = "File";
const CALLABLE: &str = "Callable";
const GENERATOR: &str = "Generator";
@ -478,7 +478,6 @@ const USER_WARNING: &str = "UserWarning";
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";
@ -1071,7 +1070,7 @@ impl Context {
};
let qual_name = t.qual_name();
let name = VarName::from_str(t.local_name());
// e.g Array!: |T, N|(_: {T}, _:= {N}) -> {Array!(T, N)}
// e.g. List!: |T, N|(_: {T}, _:= {N}) -> {List!(T, N)}
let nd_params = ctx
.params_spec
.iter()

View file

@ -30,7 +30,7 @@ impl Context {
let t_dir = no_var_proc(
vec![],
vec![kw("object", ref_(Obj))],
array_t(Str, TyParam::erased(Nat)),
list_t(Str, TyParam::erased(Nat)),
);
let t_print = proc(
vec![],

View file

@ -80,7 +80,7 @@ impl Context {
);
readable.register_builtin_decl(
PROC_READLINES,
pr0_met(ref_mut(Slf, None), unknown_len_array_t(Str)),
pr0_met(ref_mut(Slf, None), unknown_len_list_t(Str)),
Visibility::BUILTIN_PUBLIC,
Some(FUNC_READLINES),
);
@ -263,7 +263,7 @@ impl Context {
);
let ret_t = poly(
TUPLE,
vec![TyParam::Array(vec![ty_tp(Nat), ty_tp(T.clone())])],
vec![TyParam::List(vec![ty_tp(Nat), ty_tp(T.clone())])],
);
let t_enumerate = fn0_met(Slf.clone(), poly(ITERATOR, vec![ty_tp(ret_t)])).quantify();
iterable.register_builtin_decl(
@ -362,10 +362,10 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
Some("Function::iterable_chain"),
);
let t_into_array = fn0_met(Slf.clone(), unknown_len_array_t(T.clone())).quantify();
let t_to_list = fn0_met(Slf.clone(), unknown_len_list_t(T.clone())).quantify();
iterable.register_builtin_decl(
FUNC_INTO_ARRAY,
t_into_array,
FUNC_TO_LIST,
t_to_list,
Visibility::BUILTIN_PUBLIC,
Some("Function::list"),
);
@ -514,8 +514,8 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
);
/* HasShape */
let S = mono_q_tp(TY_S, instanceof(unknown_len_array_t(Nat)));
let params = vec![PS::named_nd("S", unknown_len_array_t(Nat))];
let S = mono_q_tp(TY_S, instanceof(unknown_len_list_t(Nat)));
let params = vec![PS::named_nd("S", unknown_len_list_t(Nat))];
let has_shape = Self::builtin_poly_trait(HAS_SHAPE, params.clone(), 2);
/* HasScalarType */
let Ty = mono_q_tp(TY_T, instanceof(Type));

View file

@ -3690,7 +3690,7 @@ impl Context {
/// ```
pub fn meta_type(&self, typ: &Type) -> Type {
match typ {
Type::Poly { name, params } if &name[..] == "Array" || &name[..] == "Set" => poly(
Type::Poly { name, params } if &name[..] == "List" || &name[..] == "Set" => poly(
name.clone(),
params
.iter()
@ -3743,7 +3743,7 @@ impl Context {
/// ```erg
/// recover_typarams(Int, Nat) == Nat
/// recover_typarams(Array!(Int, _), Array(Nat, 2)) == Array!(Nat, 2)
/// recover_typarams(List!(Int, _), List(Nat, 2)) == List!(Nat, 2)
/// recover_typarams(Str or NoneType, {"a", "b"}) == {"a", "b"}
/// ```
/// ```erg
@ -3773,7 +3773,7 @@ impl Context {
)));
}
}
// Array(Nat, 2) !<: Array!(Int, _)
// List(Nat, 2) !<: List!(Int, _)
let base_def_t = self
.get_nominal_type_ctx(base)
.map(|ctx| &ctx.typ)
@ -3783,7 +3783,7 @@ impl Context {
.map(|ctx| &ctx.typ)
.unwrap_or(&Type::Obj);
if self.related(base_def_t, assert_def_t) {
// FIXME: Vec(_), Array(Int, 2) -> Vec(2)
// FIXME: Vec(_), List(Int, 2) -> Vec(2)
let casted = poly(base.qual_name(), guard.to.typarams());
Ok(casted)
} else {

View file

@ -30,7 +30,7 @@ use crate::hir;
/// For example, cloning each type variable of quantified type `?T -> ?T` would result in `?1 -> ?2`.
/// To avoid this, an environment to store type variables is needed, which is `TyVarCache`.
/// 量化型をインスタンス化するための文脈
/// e.g. Array -> [("T": ?T(: Type)), ("N": ?N(: Nat))]
/// e.g. List -> [("T": ?T(: Type)), ("N": ?N(: Nat))]
/// FIXME: current implementation is wrong
/// It will not work unless the type variable is used with the same name as the definition.
#[derive(Debug, Clone)]
@ -468,16 +468,16 @@ impl Context {
.collect::<TyCheckResult<_>>()?;
Ok(TyParam::Dict(dict))
}
TyParam::Array(arr) => {
let arr = arr
TyParam::List(lis) => {
let lis = lis
.into_iter()
.map(|v| self.instantiate_tp(v, tmp_tv_cache, loc))
.collect::<TyCheckResult<_>>()?;
Ok(TyParam::Array(arr))
Ok(TyParam::List(lis))
}
TyParam::UnsizedArray(elem) => {
TyParam::UnsizedList(elem) => {
let elem = self.instantiate_tp(*elem, tmp_tv_cache, loc)?;
Ok(TyParam::UnsizedArray(Box::new(elem)))
Ok(TyParam::UnsizedList(Box::new(elem)))
}
TyParam::Set(set) => {
let set = set
@ -706,12 +706,12 @@ impl Context {
Ok(ValueObj::Subr(ConstSubr::User(user)))
}
},
ValueObj::Array(arr) => {
ValueObj::List(lis) => {
let mut new = vec![];
for v in arr.iter().cloned() {
for v in lis.iter().cloned() {
new.push(self.instantiate_value(v, tmp_tv_cache, loc)?);
}
Ok(ValueObj::Array(new.into()))
Ok(ValueObj::List(new.into()))
}
ValueObj::Tuple(tup) => {
let mut new = vec![];

View file

@ -10,7 +10,7 @@ use ast::{
NonDefaultParamSignature, ParamTySpec, PreDeclTypeSpec, TypeBoundSpec, TypeBoundSpecs, TypeSpec,
};
use erg_parser::ast::{
self, ConstApp, ConstArgs, ConstArray, ConstExpr, ConstSet, Identifier, VarName,
self, ConstApp, ConstArgs, ConstExpr, ConstList, ConstSet, Identifier, VarName,
VisModifierSpec, VisRestriction,
};
use erg_parser::token::TokenKind;
@ -443,13 +443,13 @@ impl Context {
ast::ParamPattern::Ref(_) => ref_(gen_free_t()),
ast::ParamPattern::RefMut(_) => ref_mut(gen_free_t(), None),
// ast::ParamPattern::VarName(name) if &name.inspect()[..] == "_" => Type::Obj,
// TODO: Array<Lit>
// TODO: List<Lit>
_ => gen_free_t(),
}
};
if let Some(decl_pt) = opt_decl_t {
if kind.is_var_params() {
let spec_t = unknown_len_array_t(spec_t.clone());
let spec_t = unknown_len_list_t(spec_t.clone());
self.sub_unify(
decl_pt.typ(),
&spec_t,
@ -710,9 +710,9 @@ impl Context {
not_found_is_qvar: bool,
) -> Failable<Type> {
match name.inspect().trim_start_matches([':', '.']) {
"Array" => {
"List" => {
let ctx = &self
.get_nominal_type_ctx(&array_t(Type::Obj, TyParam::Failure))
.get_nominal_type_ctx(&list_t(Type::Obj, TyParam::Failure))
.unwrap()
.ctx;
// TODO: kw
@ -737,9 +737,9 @@ impl Context {
} else {
TyParam::erased(Nat)
};
Ok(array_t(t, len))
Ok(list_t(t, len))
} else {
Ok(mono("GenericArray"))
Ok(mono("GenericList"))
}
}
"Ref" => {
@ -1250,7 +1250,7 @@ impl Context {
}
/// erased_index:
/// e.g. `instantiate_const_expr(Array(Str, _), Some((self, 1))) => Array(Str, _: Nat)`
/// e.g. `instantiate_const_expr(List(Str, _), Some((self, 1))) => List(Str, _: Nat)`
pub(crate) fn instantiate_const_expr(
&self,
expr: &ast::ConstExpr,
@ -1269,40 +1269,40 @@ impl Context {
ast::ConstExpr::App(app) => {
self.instantiate_app(app, erased_idx, tmp_tv_cache, not_found_is_qvar)
}
ast::ConstExpr::Array(ConstArray::Normal(array)) => {
let mut tp_arr = vec![];
for (i, elem) in array.elems.pos_args().enumerate() {
ast::ConstExpr::List(ConstList::Normal(list)) => {
let mut tp_lis = vec![];
for (i, elem) in list.elems.pos_args().enumerate() {
let el = self.instantiate_const_expr(
&elem.expr,
Some((self, i)),
tmp_tv_cache,
not_found_is_qvar,
)?;
tp_arr.push(el);
tp_lis.push(el);
}
Ok(TyParam::Array(tp_arr))
Ok(TyParam::List(tp_lis))
}
ast::ConstExpr::Array(ConstArray::WithLength(arr)) => {
ast::ConstExpr::List(ConstList::WithLength(lis)) => {
let elem = self.instantiate_const_expr(
&arr.elem,
&lis.elem,
erased_idx,
tmp_tv_cache,
not_found_is_qvar,
)?;
let length = self.instantiate_const_expr(
&arr.length,
&lis.length,
erased_idx,
tmp_tv_cache,
not_found_is_qvar,
)?;
if length.is_erased() {
if let Ok(elem_t) = self.instantiate_tp_as_type(elem, arr) {
return Ok(TyParam::t(unknown_len_array_t(elem_t)));
if let Ok(elem_t) = self.instantiate_tp_as_type(elem, lis) {
return Ok(TyParam::t(unknown_len_list_t(elem_t)));
}
}
type_feature_error!(
self,
arr.loc(),
lis.loc(),
&format!("instantiating const expression {expr}")
)
}
@ -1636,14 +1636,14 @@ impl Context {
TyParam::Value(value) => self.convert_value_into_type(value).or_else(|value| {
type_feature_error!(self, loc.loc(), &format!("instantiate `{value}` as type"))
}),
TyParam::Array(arr) => {
let len = TyParam::value(arr.len());
TyParam::List(lis) => {
let len = TyParam::value(lis.len());
let mut union = Type::Never;
for tp in arr {
for tp in lis {
let t = self.instantiate_tp_as_type(tp, loc)?;
union = self.union(&union, &t);
}
Ok(array_t(union, len))
Ok(list_t(union, len))
}
TyParam::Set(set) => {
let t = set
@ -1962,20 +1962,20 @@ impl Context {
mode,
not_found_is_qvar,
)?)),
TypeSpec::Array(arr) => {
TypeSpec::List(lis) => {
let elem_t = self.instantiate_typespec_full(
&arr.ty,
&lis.ty,
opt_decl_t,
tmp_tv_cache,
mode,
not_found_is_qvar,
)?;
let mut len =
self.instantiate_const_expr(&arr.len, None, tmp_tv_cache, not_found_is_qvar)?;
self.instantiate_const_expr(&lis.len, None, tmp_tv_cache, not_found_is_qvar)?;
if let TyParam::Erased(t) = &mut len {
*t.as_mut() = Type::Nat;
}
Ok(array_t(elem_t, len))
Ok(list_t(elem_t, len))
}
TypeSpec::SetWithLen(set) => {
let elem_t = self.instantiate_typespec_full(

View file

@ -645,7 +645,7 @@ pub struct Context {
pub(crate) mono_types: Dict<VarName, TypeContext>,
// Implementation Contexts for Polymorphic Types
// Vec<TyParam> are specialization parameters
// e.g. {"Array": [(Array(Nat), ctx), (Array(Int), ctx), (Array(Str), ctx), (Array(Obj), ctx), (Array('T), ctx)], ...}
// e.g. {"List": [(List(Nat), ctx), (List(Int), ctx), (List(Str), ctx), (List(Obj), ctx), (List('T), ctx)], ...}
pub(crate) poly_types: Dict<VarName, TypeContext>,
// patches can be accessed like normal records
// but when used as a fallback to a type, values are traversed instead of accessing by keys

View file

@ -21,7 +21,7 @@ use erg_parser::ast::{self, ClassAttr, RecordAttrOrIdent, TypeSpecWithOp};
use crate::ty::constructors::{
free_var, func, func0, func1, module, proc, py_module, ref_, ref_mut, str_dict_t, tp_enum,
unknown_len_array_t, v_enum,
unknown_len_list_t, v_enum,
};
use crate::ty::free::{Constraint, HasLevel};
use crate::ty::typaram::TyParam;
@ -397,7 +397,7 @@ impl Context {
Err((ty, errs)) => (ty, errs),
};
let spec_t = match kind {
ParamKind::VarParams => unknown_len_array_t(spec_t),
ParamKind::VarParams => unknown_len_list_t(spec_t),
ParamKind::KwVarParams => str_dict_t(spec_t),
_ => spec_t,
};
@ -577,7 +577,7 @@ impl Context {
}
if let Some(var_params) = &mut params.var_params {
if let Some(pt) = &subr_t.var_params {
let pt = pt.clone().map_type(unknown_len_array_t);
let pt = pt.clone().map_type(unknown_len_list_t);
if let Err(es) =
self.assign_param(var_params, Some(&pt), tmp_tv_cache, ParamKind::VarParams)
{
@ -2764,9 +2764,9 @@ impl Context {
}
res
}
ast::Expr::Array(ast::Array::Normal(arr)) => {
ast::Expr::List(ast::List::Normal(lis)) => {
let mut res = false;
for val in arr.elems.pos_args().iter() {
for val in lis.elems.pos_args().iter() {
if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
res = true;
}

View file

@ -525,7 +525,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
self.sub_unify(sub, &r)?;
Ok(())
}
(TyParam::Array(sub), TyParam::Array(sup))
(TyParam::List(sub), TyParam::List(sup))
| (TyParam::Tuple(sub), TyParam::Tuple(sup)) => {
for (l, r) in sub.iter().zip(sup.iter()) {
self.sub_unify_tp(l, r, _variance, allow_divergence)?;
@ -1208,8 +1208,8 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
};
self.sub_unify(&sub, &new_sup)?;
// ?T(:> Int, <: Int) ==> ?T == Int
// ?T(:> Array(Int, 3), <: Array(?T, ?N)) ==> ?T == Array(Int, 3)
// ?T(:> Array(Int, 3), <: Indexable(?K, ?V)) ==> ?T(:> Array(Int, 3), <: Indexable(0..2, Int))
// ?T(:> List(Int, 3), <: List(?T, ?N)) ==> ?T == List(Int, 3)
// ?T(:> List(Int, 3), <: Indexable(?K, ?V)) ==> ?T(:> List(Int, 3), <: Indexable(0..2, Int))
if !sub.is_refinement()
&& new_sup.qual_name() == sub.qual_name()
&& !new_sup.is_unbound_var()
@ -1384,7 +1384,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
},
) => {
// e.g. Set(?T) <: Eq(Set(?T))
// Array(Str) <: Iterable(Str)
// List(Str) <: Iterable(Str)
// Zip(T, U) <: Iterable(Tuple([T, U]))
if ln != rn {
self.nominal_sub_unify(maybe_sub, maybe_sup, rps)?;
@ -1542,7 +1542,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
(Subr(_) | Record(_), Type) => {}
(Guard(_), Bool) | (Bool, Guard(_)) => {}
// REVIEW: correct?
(Poly { name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => {}
(Poly { name, .. }, Type) if &name[..] == "List" || &name[..] == "Tuple" => {}
(Poly { .. }, _) => {
if maybe_sub.has_no_qvar() && maybe_sup.has_no_qvar() {
return Ok(());

View file

@ -12,7 +12,7 @@ use erg_parser::desugar::Desugarer;
use crate::context::instantiate::TyVarCache;
use crate::context::{ClassDefType, Context, MethodContext, MethodPair, TraitImpl};
use crate::lower::GenericASTLowerer;
use crate::ty::constructors::{array_t, mono, mono_q, mono_q_tp, poly, v_enum};
use crate::ty::constructors::{list_t, mono, mono_q, mono_q_tp, poly, v_enum};
use crate::ty::free::{Constraint, HasLevel};
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{HasType, TyParam, Type, Visibility};
@ -288,30 +288,30 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
Ok(hir::UnaryOp::new(unaryop.op, expr, VarInfo::default()))
}
fn fake_lower_array(&self, arr: ast::Array) -> LowerResult<hir::Array> {
fn fake_lower_list(&self, arr: ast::List) -> LowerResult<hir::List> {
match arr {
ast::Array::WithLength(arr) => {
let len = self.fake_lower_expr(*arr.len)?;
let elem = self.fake_lower_expr(arr.elem.expr)?;
Ok(hir::Array::WithLength(hir::ArrayWithLength::new(
arr.l_sqbr,
arr.r_sqbr,
ast::List::WithLength(lis) => {
let len = self.fake_lower_expr(*lis.len)?;
let elem = self.fake_lower_expr(lis.elem.expr)?;
Ok(hir::List::WithLength(hir::ListWithLength::new(
lis.l_sqbr,
lis.r_sqbr,
Type::Failure,
elem,
Some(len),
)))
}
ast::Array::Normal(arr) => {
ast::List::Normal(lis) => {
let mut elems = Vec::new();
let (elems_, ..) = arr.elems.deconstruct();
let (elems_, ..) = lis.elems.deconstruct();
for elem in elems_.into_iter() {
let elem = self.fake_lower_expr(elem.expr)?;
elems.push(hir::PosArg::new(elem));
}
let elems = hir::Args::new(elems, None, vec![], None, None);
let t = array_t(Type::Failure, TyParam::value(elems.len()));
Ok(hir::Array::Normal(hir::NormalArray::new(
arr.l_sqbr, arr.r_sqbr, t, elems,
let t = list_t(Type::Failure, TyParam::value(elems.len()));
Ok(hir::List::Normal(hir::NormalList::new(
lis.l_sqbr, lis.r_sqbr, t, elems,
)))
}
other => Err(LowerErrors::from(LowerError::declare_error(
@ -612,7 +612,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
ast::Expr::Literal(lit) => Ok(hir::Expr::Literal(self.fake_lower_literal(lit)?)),
ast::Expr::BinOp(binop) => Ok(hir::Expr::BinOp(self.fake_lower_binop(binop)?)),
ast::Expr::UnaryOp(unop) => Ok(hir::Expr::UnaryOp(self.fake_lower_unaryop(unop)?)),
ast::Expr::Array(arr) => Ok(hir::Expr::Array(self.fake_lower_array(arr)?)),
ast::Expr::List(lis) => Ok(hir::Expr::List(self.fake_lower_list(lis)?)),
ast::Expr::Tuple(tup) => Ok(hir::Expr::Tuple(self.fake_lower_tuple(tup)?)),
ast::Expr::Record(rec) => Ok(hir::Expr::Record(self.fake_lower_record(rec)?)),
ast::Expr::Set(set) => Ok(hir::Expr::Set(self.fake_lower_set(set)?)),

View file

@ -10,7 +10,7 @@ use erg_parser::token::TokenKind;
use crate::context::Context;
use crate::error::{EffectError, EffectErrors};
use crate::hir::{Array, Call, Def, Dict, Expr, Params, Set, Signature, Tuple, HIR};
use crate::hir::{Call, Def, Dict, Expr, List, Params, Set, Signature, Tuple, HIR};
use crate::ty::{HasType, Visibility};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -134,21 +134,21 @@ impl<'c> SideEffectChecker<'c> {
self.check_expr(&unary.expr);
}
Expr::Accessor(_) | Expr::Literal(_) => {}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter() {
Expr::List(list) => match list {
List::Normal(lis) => {
for elem in lis.elems.pos_args.iter() {
self.check_expr(&elem.expr);
}
}
Array::WithLength(arr) => {
self.check_expr(&arr.elem);
if let Some(len) = &arr.len {
List::WithLength(lis) => {
self.check_expr(&lis.elem);
if let Some(len) = &lis.len {
self.check_expr(len);
}
}
Array::Comprehension(arr) => {
self.check_expr(&arr.elem);
self.check_expr(&arr.guard);
List::Comprehension(lis) => {
self.check_expr(&lis.elem);
self.check_expr(&lis.guard);
}
},
Expr::Tuple(tuple) => match tuple {
@ -350,21 +350,21 @@ impl<'c> SideEffectChecker<'c> {
self.check_expr(def);
}
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter() {
Expr::List(list) => match list {
List::Normal(lis) => {
for elem in lis.elems.pos_args.iter() {
self.check_expr(&elem.expr);
}
}
Array::WithLength(arr) => {
self.check_expr(&arr.elem);
if let Some(len) = &arr.len {
List::WithLength(lis) => {
self.check_expr(&lis.elem);
if let Some(len) = &lis.len {
self.check_expr(len);
}
}
Array::Comprehension(arr) => {
self.check_expr(&arr.elem);
self.check_expr(&arr.guard);
List::Comprehension(lis) => {
self.check_expr(&lis.elem);
self.check_expr(&lis.guard);
}
},
Expr::Tuple(tuple) => match tuple {
@ -538,15 +538,15 @@ impl<'c> SideEffectChecker<'c> {
}
Expr::BinOp(bin) => Self::is_impure(&bin.lhs) || Self::is_impure(&bin.rhs),
Expr::UnaryOp(unary) => Self::is_impure(&unary.expr),
Expr::Array(arr) => match arr {
Array::Normal(arr) => arr
Expr::List(lis) => match lis {
List::Normal(lis) => lis
.elems
.pos_args
.iter()
.any(|elem| Self::is_impure(&elem.expr)),
Array::WithLength(arr) => {
Self::is_impure(&arr.elem)
|| arr.len.as_ref().map_or(false, |len| Self::is_impure(len))
List::WithLength(lis) => {
Self::is_impure(&lis.elem)
|| lis.len.as_ref().map_or(false, |len| Self::is_impure(len))
}
_ => todo!(),
},

View file

@ -744,7 +744,7 @@ impl Accessor {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayWithLength {
pub struct ListWithLength {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub t: Type,
@ -752,7 +752,7 @@ pub struct ArrayWithLength {
pub len: Option<Box<Expr>>,
}
impl NestedDisplay for ArrayWithLength {
impl NestedDisplay for ListWithLength {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(
f,
@ -764,7 +764,7 @@ impl NestedDisplay for ArrayWithLength {
}
}
impl NoTypeDisplay for ArrayWithLength {
impl NoTypeDisplay for ListWithLength {
fn to_string_notype(&self) -> String {
format!(
"[{}; {}]",
@ -774,11 +774,11 @@ impl NoTypeDisplay for ArrayWithLength {
}
}
impl_display_from_nested!(ArrayWithLength);
impl_locational!(ArrayWithLength, l_sqbr, elem, r_sqbr);
impl_t!(ArrayWithLength);
impl_display_from_nested!(ListWithLength);
impl_locational!(ListWithLength, l_sqbr, elem, r_sqbr);
impl_t!(ListWithLength);
impl ArrayWithLength {
impl ListWithLength {
pub fn new(l_sqbr: Token, r_sqbr: Token, t: Type, elem: Expr, len: Option<Expr>) -> Self {
Self {
l_sqbr,
@ -796,7 +796,7 @@ impl ArrayWithLength {
// TODO: generators
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayComprehension {
pub struct ListComprehension {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub t: Type,
@ -804,13 +804,13 @@ pub struct ArrayComprehension {
pub guard: Box<Expr>,
}
impl NestedDisplay for ArrayComprehension {
impl NestedDisplay for ListComprehension {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{} | {}](: {})", self.elem, self.guard, self.t)
}
}
impl NoTypeDisplay for ArrayComprehension {
impl NoTypeDisplay for ListComprehension {
fn to_string_notype(&self) -> String {
format!(
"[{} | {}]",
@ -820,19 +820,19 @@ impl NoTypeDisplay for ArrayComprehension {
}
}
impl_display_from_nested!(ArrayComprehension);
impl_locational!(ArrayComprehension, l_sqbr, elem, r_sqbr);
impl_t!(ArrayComprehension);
impl_display_from_nested!(ListComprehension);
impl_locational!(ListComprehension, l_sqbr, elem, r_sqbr);
impl_t!(ListComprehension);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NormalArray {
pub struct NormalList {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub t: Type,
pub elems: Args,
}
impl NestedDisplay for NormalArray {
impl NestedDisplay for NormalList {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
writeln!(f, "[")?;
self.elems.fmt_nest(f, level + 1)?;
@ -840,7 +840,7 @@ impl NestedDisplay for NormalArray {
}
}
impl NoTypeDisplay for NormalArray {
impl NoTypeDisplay for NormalList {
fn to_string_notype(&self) -> String {
format!(
"[{}]",
@ -854,11 +854,11 @@ impl NoTypeDisplay for NormalArray {
}
}
impl_display_from_nested!(NormalArray);
impl_locational!(NormalArray, l_sqbr, elems, r_sqbr);
impl_t!(NormalArray);
impl_display_from_nested!(NormalList);
impl_locational!(NormalList, l_sqbr, elems, r_sqbr);
impl_t!(NormalList);
impl NormalArray {
impl NormalList {
pub fn new(l_sqbr: Token, r_sqbr: Token, t: Type, elems: Args) -> Self {
Self {
l_sqbr,
@ -874,21 +874,21 @@ impl NormalArray {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Array {
Normal(NormalArray),
Comprehension(ArrayComprehension),
WithLength(ArrayWithLength),
pub enum List {
Normal(NormalList),
Comprehension(ListComprehension),
WithLength(ListWithLength),
}
impl_nested_display_for_enum!(Array; Normal, Comprehension, WithLength);
impl_no_type_display_for_enum!(Array; Normal, Comprehension, WithLength);
impl_display_for_enum!(Array; Normal, Comprehension, WithLength);
impl_locational_for_enum!(Array; Normal, Comprehension, WithLength);
impl_t_for_enum!(Array; Normal, Comprehension, WithLength);
impl_nested_display_for_enum!(List; Normal, Comprehension, WithLength);
impl_no_type_display_for_enum!(List; Normal, Comprehension, WithLength);
impl_display_for_enum!(List; Normal, Comprehension, WithLength);
impl_locational_for_enum!(List; Normal, Comprehension, WithLength);
impl_t_for_enum!(List; Normal, Comprehension, WithLength);
impl Array {
impl List {
pub const fn is_unsized(&self) -> bool {
matches!(self, Self::WithLength(arr) if arr.is_unsized())
matches!(self, Self::WithLength(lis) if lis.is_unsized())
}
}
@ -2733,7 +2733,7 @@ impl TypeAscription {
pub enum Expr {
Literal(Literal),
Accessor(Accessor),
Array(Array),
List(List),
Tuple(Tuple),
Set(Set),
Dict(Dict),
@ -2753,13 +2753,13 @@ pub enum Expr {
Dummy(Dummy), // for mapping to Python AST
}
impl_nested_display_for_chunk_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_no_type_display_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_nested_display_for_chunk_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_no_type_display_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_display_from_nested!(Expr);
impl_locational_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_t_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_from_trait_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Set, Dummy);
impl_try_from_trait_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Set, Dummy);
impl_locational_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_t_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy);
impl_from_trait_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Set, Dummy);
impl_try_from_trait_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Set, Dummy);
impl Default for Expr {
fn default() -> Self {
@ -2849,7 +2849,7 @@ impl Expr {
match self {
Self::Literal(_) => "literal",
Self::Accessor(_) => "accessor",
Self::Array(_) => "array",
Self::List(_) => "array",
Self::Tuple(_) => "tuple",
Self::Dict(_) => "dict",
Self::Set(_) => "set",
@ -2945,9 +2945,9 @@ impl Expr {
}
sum
}
Self::Array(Array::Normal(arr)) => {
Self::List(List::Normal(lis)) => {
let mut sum = 0;
for elem in arr.elems.pos_args.iter() {
for elem in lis.elems.pos_args.iter() {
sum += elem.expr.complexity();
}
sum

View file

@ -1,9 +1,9 @@
# TODO: transition specifications
array = pyimport "Array"
array = pyimport "List"
.Array!: ClassType
.Array! <: array.Array
.Array!.
.List!: ClassType
.List! <: array.List
.List!.
'''
Append object to the end of the list.
'''
@ -12,7 +12,7 @@ array = pyimport "Array"
arr.push! 3
assert arr == [1, 2, 3]
'''
push!: |T, N: Nat|(self: Array!(T, N), elem: T) => NoneType
push!: |T, N: Nat|(self: List!(T, N), elem: T) => NoneType
'''
Extend the list by appending all the items from `iterable`.
'''
@ -21,7 +21,7 @@ array = pyimport "Array"
arr.extend! [3, 4]
assert arr == [1, 2, 3, 4]
'''
extend!: |T, N: Nat|(self: Array!(T, N), iterable: Iterable(T)) => NoneType
extend!: |T, N: Nat|(self: List!(T, N), iterable: Iterable(T)) => NoneType
'''
Insert `elem` before `index`.
'''
@ -30,7 +30,7 @@ array = pyimport "Array"
arr.insert! 0, 3
assert arr == [3, 1, 2]
'''
insert!: |T, N: Nat|(self: Array!(T, N), index: Nat, elem: T) => NoneType
insert!: |T, N: Nat|(self: List!(T, N), index: Nat, elem: T) => NoneType
'''
Remove the first item from the list whose value is `value`.
'''
@ -39,7 +39,7 @@ array = pyimport "Array"
arr.remove! 1
assert arr == [2]
'''
remove!: |T, N: Nat|(self: Array!(T, N), value: T) => NoneType
remove!: |T, N: Nat|(self: List!(T, N), value: T) => NoneType
'''
Remove the item at the given position in the list, and return it.
'''
@ -49,7 +49,7 @@ array = pyimport "Array"
assert arr == [1]
assert i == 2
'''
pop!: |T, N: Nat|(self: Array!(T, N), index := Nat or {-1}) => T
pop!: |T, N: Nat|(self: List!(T, N), index := Nat or {-1}) => T
'''
Remove all items from the list.
'''
@ -58,7 +58,7 @@ array = pyimport "Array"
arr.clear!()
assert arr == []
'''
clear!: |T, N: Nat|(self: Array!(T, N)) => NoneType
clear!: |T, N: Nat|(self: List!(T, N)) => NoneType
'''
Sort the list in ascending order and return `None`.
@ -75,7 +75,7 @@ array = pyimport "Array"
arr.sort!()
assert arr == [1, 2, 3]
'''
sort!: |T, N: Nat|(self: Array!(T, N)) => NoneType
sort!: |T, N: Nat|(self: List!(T, N)) => NoneType
'''
Reverse the elements of the list in-place and return `None`.
'''
@ -84,7 +84,7 @@ array = pyimport "Array"
arr.reverse!()
assert arr == [2, 1, 3]
'''
reverse!: |T, N: Nat|(self: Array!(T, N)) => NoneType
reverse!: |T, N: Nat|(self: List!(T, N)) => NoneType
'''
Update each element of the array according to the passed function `f`.
'''
@ -93,7 +93,7 @@ array = pyimport "Array"
arr.strict_map! x -> x + 1
assert arr == [3, 4]
'''
strict_map!: |T, N: Nat|(self: Array!(T, N), f: T -> T) => NoneType
strict_map!: |T, N: Nat|(self: List!(T, N), f: T -> T) => NoneType
'''
Update `index`-th element of the array according to the passed function `f`.
'''
@ -102,7 +102,7 @@ array = pyimport "Array"
arr.udpate_nth! 0, x -> x + 1
assert arr == [2, 2]
'''
update_nth!: |T, N: Nat|(self: Array!(T, N), index: Nat, f: T -> T) => NoneType
update_nth!: |T, N: Nat|(self: List!(T, N), index: Nat, f: T -> T) => NoneType
'''
Return a (deep) copy of the array.
'''
@ -113,4 +113,4 @@ array = pyimport "Array"
assert arr_copy == [1, 2, 3]
assert arr == [1, 2]
'''
copy: |T, N: Nat|(self: Ref(Array!(T, N))) => Array!(T, N)
copy: |T, N: Nat|(self: Ref(List!(T, N))) => List!(T, N)

View file

@ -1,12 +1,12 @@
.Array: ClassType
.Array.
.List: ClassType
.List.
'''
Concatenates two arrays. Same as `self + other`.
'''
'''erg
assert [1, 2].concat([3, 4]) == [1, 2, 3, 4]
'''
concat: |T: Type, M: Nat, N: Nat|(self: Array(T, M), other: Array(T, N)) -> Array(T, M + N)
concat: |T: Type, M: Nat, N: Nat|(self: List(T, M), other: List(T, N)) -> List(T, M + N)
'''
Returns the number of elements in the array.
'''
@ -14,7 +14,7 @@
assert [1, 2, 3, 1, 2].count(1) == 2
assert ["a", "b", "c"].count("a") == 1
'''
count: |T: Type, N: Nat|(self: Array(T, N), x: T) -> Nat
count: |T: Type, N: Nat|(self: List(T, N), x: T) -> Nat
'''
Remove array duplicates.
@ -25,7 +25,7 @@
assert [1, 1, 2].dedup() == [1, 2]
assert [0.0, 0.1, 10.0, 20.0, 20.1].dedup((lhs, rhs) -> abs(lhs - rhs) < 1.0) == [0.1, 10.0, 20.1]
'''
dedup: |T: Type|(self: Array(T, _), same_bucket := (T, T) -> Bool) -> Array(T, _)
dedup: |T: Type|(self: List(T, _), same_bucket := (T, T) -> Bool) -> List(T, _)
'''
Create two arrays according to the `predicate` function.
@ -34,25 +34,25 @@
'''erg
assert [-2, -1, 0, 1, 2].partition(x -> x >= 0) == ([0, 1, 2], [-2, -1])
'''
partition: |T: Type|(self: Array(T, _), predicate: T -> Bool) -> (Array(T, _), Array(T, _))
partition: |T: Type|(self: List(T, _), predicate: T -> Bool) -> (List(T, _), List(T, _))
'''
Returns the summation of all elements in the array.
'''
'''erg
assert [1, 2, 3].sum() == 6
'''
sum: |T: Type|(self: Array(T, _), start := T) -> T
sum: |T: Type|(self: List(T, _), start := T) -> T
'''
Returns the product of all elements in the array.
'''
'''erg
assert [1, 2, 3].product() == 6
'''
prod: |T: Type|(self: Array(T, _), start := T) -> T
prod: |T: Type|(self: List(T, _), start := T) -> T
'''
Returns the reversed array.
'''
'''erg
assert [1, 2, 3].reversed() == [3, 2, 1]
'''
reversed: |T: Type, N: Nat|(self: Array(T, N)) -> Array(T, N)
reversed: |T: Type, N: Nat|(self: List(T, N)) -> List(T, N)

View file

@ -60,9 +60,9 @@ def contains_operator(y, elem) -> bool:
len_check = True # It can be True even if either elem or y has the larger number of elems
return type_check and len_check
elif _isinstance(elem, list):
from _erg_array import Array
from _erg_list import List
return contains_operator(y, Array(elem))
return contains_operator(y, List(elem))
elif callable(elem):
# TODO:
return callable(y)

View file

@ -8,21 +8,21 @@ from _erg_result import is_ok
from _erg_type import UnionType
class Array(list):
class List(list):
@staticmethod
def try_new(arr): # -> Result[Array]
if isinstance(arr, list):
return Array(arr)
def try_new(lis): # -> Result[List]
if isinstance(lis, list):
return List(lis)
else:
return Error("not a list")
def generic_try_new(arr, cls=None): # -> Result[Array]
def generic_try_new(lis, cls=None): # -> Result[List]
if cls is None:
return Array.try_new(arr)
return List.try_new(lis)
else:
elem_t = cls.__args__[0]
elems = []
for elem in arr:
for elem in lis:
if not hasattr(elem_t, "try_new"):
return Error("not a " + str(elem_t))
# TODO: nested check
@ -31,11 +31,11 @@ class Array(list):
elems.append(elem)
else:
return Error("not a " + str(elem_t))
return Array(elems)
return List(elems)
def dedup(self, same_bucket=None):
if same_bucket is None:
return Array(list(set(self)))
return List(list(set(self)))
else:
removes = []
for lhs, rhs in zip(self, self[1:]):
@ -56,20 +56,20 @@ class Array(list):
return self
def partition(self, f):
return Array(list(filter(f, self))), Array(
return List(list(filter(f, self))), List(
list(filter(lambda x: not f(x), self))
)
def __mul__(self, n):
return then__(list.__mul__(self, n), Array)
return then__(list.__mul__(self, n), List)
def __getitem__(self, index_or_slice):
if isinstance(index_or_slice, slice):
return Array(list.__getitem__(self, index_or_slice))
return List(list.__getitem__(self, index_or_slice))
elif isinstance(index_or_slice, NatMut) or isinstance(index_or_slice, IntMut):
return list.__getitem__(self, int(index_or_slice))
elif isinstance(index_or_slice, Range):
return Array(list.__getitem__(self, index_or_slice.into_slice()))
return List(list.__getitem__(self, index_or_slice.into_slice()))
else:
return list.__getitem__(self, index_or_slice)
@ -77,7 +77,7 @@ class Array(list):
return hash(tuple(self))
def update(self, f):
self = Array(f(self))
self = List(f(self))
def type_check(self, t: type) -> bool:
if isinstance(t, list):
@ -114,7 +114,7 @@ class Array(list):
return reduce(lambda x, y: x * y, self, start)
def reversed(self):
return Array(list.__reversed__(self))
return List(list.__reversed__(self))
def insert_at(self, index, value):
self.insert(index, value)
@ -135,10 +135,10 @@ class Array(list):
new = []
for _ in range(n):
new.extend(deepcopy(self))
return Array(new)
return List(new)
class UnsizedArray:
class UnsizedList:
elem: object
def __init__(self, elem):

View file

@ -1,5 +1,5 @@
# HACK: import MutType to suppress segfault in CPython 3.10 (cause unknown)
from _erg_array import Array, UnsizedArray
from _erg_list import List, UnsizedList
from _erg_bool import Bool
from _erg_bytes import Bytes
from _erg_contains_operator import contains_operator

View file

@ -206,13 +206,13 @@ opened in a binary mode.
) => File!
'''
Convert `iterable` into an array.
Convert `iterable` into a list.
'''
'''erg
assert array() == []
assert array((1, 2)) == [1, 2]
assert list() == []
assert list((1, 2)) == [1, 2]
'''
.array: |T| (iterable := Iterable(T)) -> [T; _]
.list: |T| (iterable := Iterable(T)) -> [T; _]
'''
Convert `iterable` into a dict.

View file

@ -1,4 +1,4 @@
.heappush!: |T: Type|(heap: Iterable(T), item: T) => NoneType # TODO: Push!
.heappop!: |T: Type|(heap: Iterable(T)) => T # TODO: Pop!
.heappushpop!: |T: Type|(heap: Iterable(T), item: T) => T # TODO: Push! and Pop!
.heapify!: (heap: Array(Obj, _)) => NoneType
.heapify!: (heap: List(Obj, _)) => NoneType

View file

@ -56,7 +56,7 @@ io = pyimport "io"
.seed_bits = Nat;
.cutoff = Int;
}
.path: Array!(Str, _)
.path: List!(Str, _)
'''
* AIX -> 'aix'
* FreeBSD -> 'freebsd'

View file

@ -121,15 +121,15 @@ impl<'a> HIRLinker<'a> {
}
}
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter_mut() {
Expr::List(list) => match list {
List::Normal(lis) => {
for elem in lis.elems.pos_args.iter_mut() {
Self::resolve_pymod_path(&mut elem.expr);
}
}
Array::WithLength(arr) => {
Self::resolve_pymod_path(&mut arr.elem);
if let Some(len) = arr.len.as_deref_mut() {
List::WithLength(lis) => {
Self::resolve_pymod_path(&mut lis.elem);
if let Some(len) = lis.len.as_deref_mut() {
Self::resolve_pymod_path(len);
}
}
@ -245,15 +245,15 @@ impl<'a> HIRLinker<'a> {
},
}
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter_mut() {
Expr::List(list) => match list {
List::Normal(lis) => {
for elem in lis.elems.pos_args.iter_mut() {
self.replace_import(&mut elem.expr);
}
}
Array::WithLength(arr) => {
self.replace_import(&mut arr.elem);
if let Some(len) = arr.len.as_deref_mut() {
List::WithLength(lis) => {
self.replace_import(&mut lis.elem);
if let Some(len) = lis.len.as_deref_mut() {
self.replace_import(len);
}
}

View file

@ -33,8 +33,8 @@ use crate::artifact::{BuildRunnable, Buildable, CompleteArtifact, IncompleteArti
use crate::build_package::CheckStatus;
use crate::module::SharedCompilerResource;
use crate::ty::constructors::{
array_t, free_var, func, guard, mono, poly, proc, refinement, set_t, singleton, ty_tp,
unsized_array_t, v_enum,
free_var, func, guard, list_t, mono, poly, proc, refinement, set_t, singleton, ty_tp,
unsized_list_t, v_enum,
};
use crate::ty::free::Constraint;
use crate::ty::typaram::TyParam;
@ -335,21 +335,19 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
Ok(lit)
}
fn lower_array(&mut self, array: ast::Array, expect: Option<&Type>) -> LowerResult<hir::Array> {
log!(info "entered {}({array})", fn_name!());
match array {
ast::Array::Normal(arr) => {
Ok(hir::Array::Normal(self.lower_normal_array(arr, expect)?))
}
ast::Array::WithLength(arr) => Ok(hir::Array::WithLength(
self.lower_array_with_length(arr, expect)?,
fn lower_list(&mut self, list: ast::List, expect: Option<&Type>) -> LowerResult<hir::List> {
log!(info "entered {}({list})", fn_name!());
match list {
ast::List::Normal(lis) => Ok(hir::List::Normal(self.lower_normal_list(lis, expect)?)),
ast::List::WithLength(lis) => Ok(hir::List::WithLength(
self.lower_list_with_length(lis, expect)?,
)),
other => feature_error!(
LowerErrors,
LowerError,
self.module.context,
other.loc(),
"array comprehension"
"list comprehension"
),
}
}
@ -364,10 +362,10 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
elem.loc(),
String::from(&self.module.context.name[..]),
switch_lang!(
"japanese" => "配列の要素は全て同じ型である必要があります",
"japanese" => "リストの要素は全て同じ型である必要があります",
"simplified_chinese" => "数组元素必须全部是相同类型",
"traditional_chinese" => "數組元素必須全部是相同類型",
"english" => "all elements of an array must be of the same type",
"english" => "all elements of a list must be of the same type",
)
.to_owned(),
Some(switch_lang!(
@ -379,18 +377,18 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
))
}
fn lower_normal_array(
fn lower_normal_list(
&mut self,
array: ast::NormalArray,
list: ast::NormalList,
expect: Option<&Type>,
) -> LowerResult<hir::NormalArray> {
log!(info "entered {}({array})", fn_name!());
let mut new_array = vec![];
let eval_result = self.module.context.eval_const_normal_array(&array);
let (elems, ..) = array.elems.deconstruct();
) -> LowerResult<hir::NormalList> {
log!(info "entered {}({list})", fn_name!());
let mut new_list = vec![];
let eval_result = self.module.context.eval_const_normal_list(&list);
let (elems, ..) = list.elems.deconstruct();
let expect_elem = expect.and_then(|t| {
// REVIEW: are these all?
if !(t.is_array() || t.is_array_mut() || t.is_iterable()) {
if !(t.is_list() || t.is_list_mut() || t.is_iterable()) {
return None;
}
self.module
@ -404,7 +402,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
let union_ = self.module.context.union(&union, elem.ref_t());
self.homogeneity_check(expect_elem.as_ref(), &union_, &union, &elem)?;
union = union_;
new_array.push(elem);
new_list.push(elem);
}
let elem_t = if union == Type::Never {
free_var(
@ -414,14 +412,14 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
} else {
union
};
let elems = hir::Args::values(new_array, None);
let t = array_t(elem_t, TyParam::value(elems.len()));
let elems = hir::Args::values(new_list, None);
let t = list_t(elem_t, TyParam::value(elems.len()));
let t = if let Ok(value) = eval_result {
singleton(t, TyParam::Value(value))
} else {
t
};
Ok(hir::NormalArray::new(array.l_sqbr, array.r_sqbr, t, elems))
Ok(hir::NormalList::new(list.l_sqbr, list.r_sqbr, t, elems))
}
fn homogeneity_check(
@ -466,14 +464,14 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
Ok(())
}
fn lower_array_with_length(
fn lower_list_with_length(
&mut self,
array: ast::ArrayWithLength,
list: ast::ListWithLength,
expect: Option<&Type>,
) -> LowerResult<hir::ArrayWithLength> {
log!(info "entered {}({array})", fn_name!());
) -> LowerResult<hir::ListWithLength> {
log!(info "entered {}({list})", fn_name!());
let expect_elem = expect.and_then(|t| {
if !(t.is_array() || t.is_array_mut() || t.is_iterable()) {
if !(t.is_list() || t.is_list_mut() || t.is_iterable()) {
return None;
}
self.module
@ -481,26 +479,26 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
.convert_tp_into_type(t.typarams().first()?.clone())
.ok()
});
let elem = self.lower_expr(array.elem.expr, expect_elem.as_ref())?;
let array_t = self.gen_array_with_length_type(&elem, &array.len);
let len = match *array.len {
let elem = self.lower_expr(list.elem.expr, expect_elem.as_ref())?;
let list_t = self.gen_list_with_length_type(&elem, &list.len);
let len = match *list.len {
ast::Expr::Accessor(ast::Accessor::Ident(ident)) if ident.is_discarded() => None,
len => Some(self.lower_expr(len, Some(&Type::Nat))?),
};
let hir_array = hir::ArrayWithLength::new(array.l_sqbr, array.r_sqbr, array_t, elem, len);
Ok(hir_array)
let hir_list = hir::ListWithLength::new(list.l_sqbr, list.r_sqbr, list_t, elem, len);
Ok(hir_list)
}
fn gen_array_with_length_type(&self, elem: &hir::Expr, len: &ast::Expr) -> Type {
fn gen_list_with_length_type(&self, elem: &hir::Expr, len: &ast::Expr) -> Type {
match len {
ast::Expr::Accessor(ast::Accessor::Ident(ident)) if ident.is_discarded() => {
return unsized_array_t(elem.t());
return unsized_list_t(elem.t());
}
_ => {}
}
let maybe_len = self.module.context.eval_const_expr(len);
match maybe_len {
Ok(v @ ValueObj::Nat(_)) => array_t(elem.t(), TyParam::Value(v)),
Ok(v @ ValueObj::Nat(_)) => list_t(elem.t(), TyParam::Value(v)),
Ok(other) => todo!("{other} is not a Nat object"),
Err(err) => todo!("{err}"),
}
@ -2947,7 +2945,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
let casted = self.module.context.get_casted_type(&expr);
let mut expr = match expr {
ast::Expr::Literal(lit) => hir::Expr::Literal(self.lower_literal(lit, expect)?),
ast::Expr::Array(arr) => hir::Expr::Array(self.lower_array(arr, expect)?),
ast::Expr::List(lis) => hir::Expr::List(self.lower_list(lis, expect)?),
ast::Expr::Tuple(tup) => hir::Expr::Tuple(self.lower_tuple(tup, expect)?),
ast::Expr::Record(rec) => hir::Expr::Record(self.lower_record(rec, expect)?),
ast::Expr::Set(set) => hir::Expr::Set(self.lower_set(set, expect)?),

View file

@ -13,7 +13,7 @@ use erg_parser::ast::{ParamPattern, VarName};
use crate::ty::{HasType, Ownership, Visibility};
use crate::error::{OwnershipError, OwnershipErrors};
use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR};
use crate::hir::{self, Accessor, Block, Def, Expr, Identifier, List, Signature, Tuple, HIR};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WrapperKind {
@ -222,23 +222,23 @@ impl OwnershipChecker {
Expr::UnaryOp(unary) => {
self.check_expr(&unary.expr, ownership, false);
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for a in arr.elems.pos_args.iter() {
Expr::List(list) => match list {
List::Normal(lis) => {
for a in lis.elems.pos_args.iter() {
self.check_expr(&a.expr, ownership, false);
}
}
Array::WithLength(arr) => {
self.check_expr(&arr.elem, ownership, false);
if let Some(len) = &arr.len {
List::WithLength(lis) => {
self.check_expr(&lis.elem, ownership, false);
if let Some(len) = &lis.len {
self.check_expr(len, ownership, false);
}
}
_ => todo!(),
},
Expr::Tuple(tuple) => match tuple {
Tuple::Normal(arr) => {
for a in arr.elems.pos_args.iter() {
Tuple::Normal(lis) => {
for a in lis.elems.pos_args.iter() {
self.check_expr(&a.expr, ownership, false);
}
}

View file

@ -40,4 +40,4 @@ val!() =
val = val!()
xs as [Nat or Str; _] = [1, 2, "aa"]
ys = array filter x -> x in Int, xs
ys = list filter x -> x in Int, xs

View file

@ -12,8 +12,8 @@ use erg_compiler::error::CompileErrors;
use erg_compiler::lower::ASTLowerer;
use erg_compiler::ty::constructors::{
array_t, func0, func1, func2, kw, mono, nd_func, nd_proc, or, poly, proc1, subtype_q, ty_tp,
type_q, unknown_len_array_mut, unknown_len_array_t, v_enum,
func0, func1, func2, kw, list_t, mono, nd_func, nd_proc, or, poly, proc1, subtype_q, ty_tp,
type_q, unknown_len_list_mut, unknown_len_list_t, v_enum,
};
use erg_compiler::ty::Type::*;
@ -71,15 +71,15 @@ fn _test_infer_types() -> Result<(), ()> {
module.context.assert_var_type("abs2", &abs_t)?;
let norm_t = func1(mono("<module>::Norm"), Nat);
module.context.assert_var_type("norm", &norm_t)?;
let a_t = array_t(
let a_t = list_t(
v_enum(set! {1.into(), 2.into(), 3.into(), 4.into()}),
4.into(),
);
module.context.assert_var_type("a", &a_t)?;
let abc_t = unknown_len_array_t(v_enum(set! {"a".into(), "b".into(), "c".into()}));
let abc_t = unknown_len_list_t(v_enum(set! {"a".into(), "b".into(), "c".into()}));
module.context.assert_var_type("abc", &abc_t)?;
let t = type_q("T");
let f_t = proc1(t.clone(), unknown_len_array_mut(t)).quantify();
let f_t = proc1(t.clone(), unknown_len_list_mut(t)).quantify();
module.context.assert_var_type("f!", &f_t)?;
let r = type_q("R");
let add_r = poly("Add", vec![ty_tp(r.clone())]);
@ -92,7 +92,7 @@ fn _test_infer_types() -> Result<(), ()> {
.assert_var_type("val", &v_enum(set! { "b".into(), "d".into() }))?;
module
.context
.assert_var_type("ys", &unknown_len_array_t(Nat))?;
.assert_var_type("ys", &unknown_len_list_t(Nat))?;
Ok(())
}

View file

@ -23,7 +23,7 @@ use crate::context::{Context, ContextProvider, ModuleContext};
use crate::desugar_hir::HIRDesugarer;
use crate::error::{CompileError, CompileErrors, CompileResult};
use crate::hir::{
Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier, Lambda,
Accessor, Args, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier, Lambda, List,
Literal, Params, PatchDef, ReDef, Record, Set, Signature, Tuple, UnaryOp, HIR,
};
use crate::link_hir::HIRLinker;
@ -476,7 +476,7 @@ impl PyScriptGenerator {
.replace("from _erg_str import Str", "")
.replace("from _erg_float import FloatMut", "")
.replace("from _erg_float import Float", "")
.replace("from _erg_array import Array", "")
.replace("from _erg_list import List", "")
.replace("from _erg_range import Range", "")
.replace("from _erg_result import Error", "")
.replace("from _erg_result import is_ok", "")
@ -531,7 +531,7 @@ impl PyScriptGenerator {
self.load_contains_op_if_not();
if self.range_ops_loaded {
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_float.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_array.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_list.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_dict.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_set.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_bytes.py"));
@ -541,7 +541,7 @@ impl PyScriptGenerator {
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_bool.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_str.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_float.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_array.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_list.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_dict.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_set.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_bytes.py"));
@ -578,11 +578,11 @@ impl PyScriptGenerator {
Expr::Call(call) => self.transpile_call(call),
Expr::BinOp(bin) => self.transpile_binop(bin),
Expr::UnaryOp(unary) => self.transpile_unaryop(unary),
Expr::Array(array) => match array {
Array::Normal(arr) => {
Expr::List(list) => match list {
List::Normal(lis) => {
self.load_builtin_types_if_not();
let mut code = "Array([".to_string();
for elem in arr.elems.pos_args {
let mut code = "List([".to_string();
for elem in lis.elems.pos_args {
code += &format!("{},", self.transpile_expr(elem.expr));
}
code += "])";
@ -762,7 +762,7 @@ impl PyScriptGenerator {
prefix.push('(');
}
other => {
if let t @ ("Bytes" | "Array" | "Dict" | "Set") = &other.qual_name()[..] {
if let t @ ("Bytes" | "List" | "Dict" | "Set") = &other.qual_name()[..] {
self.load_builtin_types_if_not();
prefix.push_str(t);
prefix.push('(');
@ -773,9 +773,9 @@ impl PyScriptGenerator {
match acc {
Accessor::Ident(ident) => {
match &ident.inspect()[..] {
"Str" | "Bytes" | "Bool" | "Nat" | "Int" | "Float" | "Array" | "Dict"
"Str" | "Bytes" | "Bool" | "Nat" | "Int" | "Float" | "List" | "Dict"
| "Set" | "Str!" | "Bytes!" | "Bool!" | "Nat!" | "Int!" | "Float!"
| "Array!" => {
| "List!" => {
self.load_builtin_types_if_not();
}
"if" | "if!" | "for!" | "while" | "discard" => {
@ -1288,24 +1288,24 @@ impl JsonGenerator {
fn expr_into_value(&self, expr: Expr) -> Option<ValueObj> {
match expr {
Expr::Array(Array::Normal(arr)) => {
Expr::List(List::Normal(lis)) => {
let mut vals = vec![];
for elem in arr.elems.pos_args {
for elem in lis.elems.pos_args {
if let Some(val) = self.expr_into_value(elem.expr) {
vals.push(val);
} else {
return None;
}
}
Some(ValueObj::Array(vals.into()))
Some(ValueObj::List(vals.into()))
}
Expr::Array(Array::WithLength(arr)) => {
let len = arr
Expr::List(List::WithLength(lis)) => {
let len = lis
.len
.and_then(|len| self.expr_into_value(*len))
.and_then(|v| usize::try_from(&v).ok())?;
let vals = vec![self.expr_into_value(*arr.elem)?; len];
Some(ValueObj::Array(vals.into()))
let vals = vec![self.expr_into_value(*lis.elem)?; len];
Some(ValueObj::List(vals.into()))
}
Expr::Tuple(Tuple::Normal(tup)) => {
let mut vals = vec![];
@ -1379,10 +1379,10 @@ impl JsonGenerator {
replace_non_symbolic(&acc.to_string())
}
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
Expr::List(list) => match list {
List::Normal(lis) => {
let mut code = "[".to_string();
for (i, elem) in arr.elems.pos_args.into_iter().enumerate() {
for (i, elem) in lis.elems.pos_args.into_iter().enumerate() {
if i > 0 {
code += ", ";
}

View file

@ -44,36 +44,36 @@ pub fn named_uninit_var(name: Str) -> Type {
Type::FreeVar(Free::new_named_unbound(name, 1, Constraint::Uninited))
}
pub fn array_t(elem_t: Type, len: TyParam) -> Type {
poly("Array", vec![TyParam::t(elem_t), len])
pub fn list_t(elem_t: Type, len: TyParam) -> Type {
poly("List", vec![TyParam::t(elem_t), len])
}
pub fn array_mut(elem_t: Type, len: TyParam) -> Type {
poly("Array!", vec![TyParam::t(elem_t), len])
pub fn list_mut(elem_t: Type, len: TyParam) -> Type {
poly("List!", vec![TyParam::t(elem_t), len])
}
pub fn unknown_len_array_t(elem_t: Type) -> Type {
array_t(elem_t, TyParam::erased(Type::Nat))
pub fn unknown_len_list_t(elem_t: Type) -> Type {
list_t(elem_t, TyParam::erased(Type::Nat))
}
pub fn unknown_len_array_mut(elem_t: Type) -> Type {
array_mut(elem_t, TyParam::erased(Type::Nat))
pub fn unknown_len_list_mut(elem_t: Type) -> Type {
list_mut(elem_t, TyParam::erased(Type::Nat))
}
pub fn str_dict_t(value: Type) -> Type {
dict! { Type::Str => value }.into()
}
/// `UnsizedArray` is a type of `[x; _]` (unsized array literal).
/// `UnsizedArray(T) != Array(T, _)`
pub fn unsized_array_t(elem_t: Type) -> Type {
poly("UnsizedArray", vec![TyParam::t(elem_t)])
/// `UnsizedList` is a type of `[x; _]` (unsized list literal).
/// `UnsizedList(T) != List(T, _)`
pub fn unsized_list_t(elem_t: Type) -> Type {
poly("UnsizedList", vec![TyParam::t(elem_t)])
}
pub fn tuple_t(args: Vec<Type>) -> Type {
poly(
"Tuple",
vec![TyParam::Array(args.into_iter().map(TyParam::t).collect())],
vec![TyParam::List(args.into_iter().map(TyParam::t).collect())],
)
}

View file

@ -12,7 +12,7 @@ use erg_common::{fn_name, switch_lang};
use erg_common::{ArcArray, Str};
use super::codeobj::{CodeObj, FastKind};
use super::constructors::array_t;
use super::constructors::list_t;
use super::typaram::TyParam;
use super::value::ValueObj;
use super::{HasType, Type};
@ -140,7 +140,7 @@ impl Deserializer {
}
fn get_cached_arr(&mut self, arr: &[ValueObj]) -> ValueObj {
ValueObj::Array(self.arr_cache.get(arr))
ValueObj::List(self.arr_cache.get(arr))
}
pub fn vec_to_bytes<const LEN: usize>(vector: Vec<u8>) -> [u8; LEN] {
@ -226,7 +226,7 @@ impl Deserializer {
field: Option<&str>,
) -> DeserializeResult<Vec<ValueObj>> {
match self.deserialize_const(v, python_ver)? {
ValueObj::Array(arr) => Ok(arr.to_vec()),
ValueObj::List(lis) => Ok(lis.to_vec()),
other => Err(DeserializeError::type_error(
field,
&Type::Str,
@ -242,7 +242,7 @@ impl Deserializer {
field: Option<&str>,
) -> DeserializeResult<ArcArray<ValueObj>> {
match self.deserialize_const(v, python_ver)? {
ValueObj::Array(arr) => Ok(arr),
ValueObj::List(lis) => Ok(lis),
other => Err(DeserializeError::type_error(
field,
&Type::Str,
@ -273,16 +273,16 @@ impl Deserializer {
field: Option<&str>,
) -> DeserializeResult<Vec<Str>> {
match self.deserialize_const(v, python_ver)? {
ValueObj::Array(arr) | ValueObj::Tuple(arr) => {
let mut strs = Vec::with_capacity(arr.len());
for c in arr.iter().cloned() {
ValueObj::List(lis) | ValueObj::Tuple(lis) => {
let mut strs = Vec::with_capacity(lis.len());
for c in lis.iter().cloned() {
strs.push(self.try_into_str(c)?);
}
Ok(strs)
}
other => Err(DeserializeError::type_error(
field,
&array_t(Type::Str, TyParam::erased(Type::Nat)),
&list_t(Type::Str, TyParam::erased(Type::Nat)),
&other.class(),
)),
}

View file

@ -2040,8 +2040,8 @@ impl Type {
_ => None,
},
Self::Poly { name, params } => match &name[..] {
"Array!" => Some(Self::Poly {
name: "Array".into(),
"List!" => Some(Self::Poly {
name: "List".into(),
params: params.clone(),
}),
"Set!" => Some(Self::Poly {
@ -2106,13 +2106,13 @@ impl Type {
}
}
/// value class := mono value object class | (Array | Set)(value class)
/// value class := mono value object class | (List | Set)(value class)
pub fn is_value_class(&self) -> bool {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_value_class(),
Self::Refinement(refine) => refine.t.is_value_class(),
Self::Poly { name, params } => {
if &name[..] == "Array" || &name[..] == "Set" {
if &name[..] == "List" || &name[..] == "Set" {
let Some(elem_t) = params.first().and_then(|p| <&Type>::try_from(p).ok())
else {
if DEBUG_MODE {
@ -2195,7 +2195,7 @@ impl Type {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_singleton(),
Self::Refinement(refine) => refine.t.is_singleton(),
Self::Poly { name, params } => {
if &name[..] == "Array" || &name[..] == "Set" {
if &name[..] == "List" || &name[..] == "Set" {
let Some(elem_t) = params.first().and_then(|p| <&Type>::try_from(p).ok())
else {
if DEBUG_MODE {
@ -2373,11 +2373,11 @@ impl Type {
}
}
pub fn is_array(&self) -> bool {
pub fn is_list(&self) -> bool {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_array(),
Self::Poly { name, .. } => &name[..] == "Array",
Self::Refinement(refine) => refine.t.is_array(),
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_list(),
Self::Poly { name, .. } => &name[..] == "List",
Self::Refinement(refine) => refine.t.is_list(),
_ => false,
}
}
@ -2391,11 +2391,11 @@ impl Type {
}
}
pub fn is_array_mut(&self) -> bool {
pub fn is_list_mut(&self) -> bool {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_array_mut(),
Self::Poly { name, .. } => &name[..] == "Array!",
Self::Refinement(refine) => refine.t.is_array_mut(),
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_list_mut(),
Self::Poly { name, .. } => &name[..] == "List!",
Self::Refinement(refine) => refine.t.is_list_mut(),
_ => false,
}
}
@ -3391,7 +3391,7 @@ impl Type {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().container_len(),
Self::Poly { name, params } => match &name[..] {
"Array" => {
"List" => {
if let TyParam::Value(ValueObj::Nat(n)) = &params[0] {
Some(*n as usize)
} else {
@ -3691,7 +3691,7 @@ impl Type {
/// ```erg
/// (Failure -> Int).replace_failure() == (Obj -> Int)
/// (Int -> Failure).replace_failure() == (Int -> Never)
/// Array(Failure, 3).replace_failure() == Array(Never, 3)
/// List(Failure, 3).replace_failure() == List(Never, 3)
/// ```
pub fn replace_failure(&self) -> Type {
match self {
@ -4093,7 +4093,7 @@ impl Type {
/// ```erg
/// Int.contained_ts() == {Int}
/// Array(Array(Int)).contained_ts() == {Array(Int), Int}
/// List(List(Int)).contained_ts() == {List(Int), Int}
/// (Int or Str).contained_ts() == {Int, Str}
/// ```
pub fn contained_ts(&self) -> Set<Type> {
@ -4460,8 +4460,8 @@ pub enum TypeCode {
Bool,
Str,
StrMut,
Array, // 要素数は検査済みなので、気にする必要はない
ArrayMut,
List, // 要素数は検査済みなので、気にする必要はない
ListMut,
// Dict,
Set,
SetMut,
@ -4493,7 +4493,7 @@ impl From<&Type> for TypeCode {
_ => Self::Other,
},
Type::Poly { name, .. } => match &name[..] {
"Array" | "Array!" => Self::Array,
"List" | "List!" => Self::List,
"Set" | "Set!" => Self::Set,
"Func" => Self::Func,
"Proc" => Self::Proc,
@ -4516,7 +4516,7 @@ pub enum TypePair {
IntFloat,
IntStr,
IntBool,
IntArray,
IntList,
IntFunc,
IntProc,
NatInt,
@ -4524,7 +4524,7 @@ pub enum TypePair {
NatFloat,
NatStr,
NatBool,
NatArray,
NatList,
NatFunc,
NatProc,
FloatInt,
@ -4532,7 +4532,7 @@ pub enum TypePair {
FloatFloat,
FloatStr,
FloatBool,
FloatArray,
FloatList,
FloatFunc,
FloatProc,
BoolInt,
@ -4540,7 +4540,7 @@ pub enum TypePair {
BoolFloat,
BoolStr,
BoolBool,
BoolArray,
BoolList,
BoolFunc,
BoolProc,
StrInt,
@ -4548,24 +4548,24 @@ pub enum TypePair {
StrFloat,
StrBool,
StrStr,
StrArray,
StrList,
StrFunc,
StrProc,
// 要素数は検査済みなので、気にする必要はない
ArrayInt,
ArrayNat,
ArrayFloat,
ArrayStr,
ArrayBool,
ArrayArray,
ArrayFunc,
ArrayProc,
ListInt,
ListNat,
ListFloat,
ListStr,
ListBool,
ListList,
ListFunc,
ListProc,
FuncInt,
FuncNat,
FuncFloat,
FuncStr,
FuncBool,
FuncArray,
FuncList,
FuncFunc,
FuncProc,
ProcInt,
@ -4573,7 +4573,7 @@ pub enum TypePair {
ProcFloat,
ProcStr,
ProcBool,
ProcArray,
ProcList,
ProcFunc,
ProcProc,
Others,
@ -4588,7 +4588,7 @@ impl From<u8> for TypePair {
3 => Self::IntFloat,
4 => Self::IntStr,
5 => Self::IntBool,
6 => Self::IntArray,
6 => Self::IntList,
7 => Self::IntFunc,
8 => Self::IntProc,
9 => Self::NatInt,
@ -4596,7 +4596,7 @@ impl From<u8> for TypePair {
11 => Self::NatFloat,
12 => Self::NatStr,
13 => Self::NatBool,
14 => Self::NatArray,
14 => Self::NatList,
15 => Self::NatFunc,
16 => Self::NatProc,
17 => Self::FloatInt,
@ -4604,7 +4604,7 @@ impl From<u8> for TypePair {
19 => Self::FloatFloat,
20 => Self::FloatStr,
21 => Self::FloatBool,
22 => Self::FloatArray,
22 => Self::FloatList,
23 => Self::FloatFunc,
24 => Self::FloatProc,
25 => Self::BoolInt,
@ -4612,7 +4612,7 @@ impl From<u8> for TypePair {
27 => Self::BoolFloat,
28 => Self::BoolStr,
29 => Self::BoolBool,
30 => Self::BoolArray,
30 => Self::BoolList,
31 => Self::BoolFunc,
32 => Self::BoolProc,
33 => Self::StrInt,
@ -4620,24 +4620,24 @@ impl From<u8> for TypePair {
35 => Self::StrFloat,
36 => Self::StrBool,
37 => Self::StrStr,
38 => Self::StrArray,
38 => Self::StrList,
39 => Self::StrFunc,
40 => Self::StrProc,
// 要素数は検査済みなので、気にする必要はない
41 => Self::ArrayInt,
42 => Self::ArrayNat,
43 => Self::ArrayFloat,
44 => Self::ArrayStr,
45 => Self::ArrayBool,
46 => Self::ArrayArray,
47 => Self::ArrayFunc,
48 => Self::ArrayProc,
41 => Self::ListInt,
42 => Self::ListNat,
43 => Self::ListFloat,
44 => Self::ListStr,
45 => Self::ListBool,
46 => Self::ListList,
47 => Self::ListFunc,
48 => Self::ListProc,
49 => Self::FuncInt,
50 => Self::FuncNat,
51 => Self::FuncFloat,
52 => Self::FuncStr,
53 => Self::FuncBool,
54 => Self::FuncArray,
54 => Self::FuncList,
55 => Self::FuncFunc,
56 => Self::FuncProc,
57 => Self::ProcInt,
@ -4645,7 +4645,7 @@ impl From<u8> for TypePair {
59 => Self::ProcFloat,
60 => Self::ProcStr,
61 => Self::ProcBool,
62 => Self::ProcArray,
62 => Self::ProcList,
63 => Self::ProcProc,
64 => Self::Others,
_ => Self::Illegals,
@ -4662,7 +4662,7 @@ impl TypePair {
(Type::Int, Type::Float) => Self::IntFloat,
(Type::Int, Type::Str) => Self::IntStr,
(Type::Int, Type::Bool) => Self::IntBool,
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Array" => Self::IntArray,
(Type::Int, Type::Poly { name, .. }) if &name[..] == "List" => Self::IntList,
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Func" => Self::IntFunc,
(Type::Int, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::IntProc,
(Type::Nat, Type::Int) => Self::NatInt,
@ -4670,7 +4670,7 @@ impl TypePair {
(Type::Nat, Type::Float) => Self::NatFloat,
(Type::Nat, Type::Str) => Self::NatStr,
(Type::Nat, Type::Bool) => Self::NatBool,
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Array" => Self::NatArray,
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "List" => Self::NatList,
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Func" => Self::NatFunc,
(Type::Nat, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::NatProc,
(Type::Float, Type::Int) => Self::FloatInt,
@ -4678,7 +4678,7 @@ impl TypePair {
(Type::Float, Type::Float) => Self::FloatFloat,
(Type::Float, Type::Str) => Self::FloatStr,
(Type::Float, Type::Bool) => Self::FloatBool,
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Array" => Self::FloatArray,
(Type::Float, Type::Poly { name, .. }) if &name[..] == "List" => Self::FloatList,
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Func" => Self::FloatFunc,
(Type::Float, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::FloatProc,
(Type::Bool, Type::Int) => Self::BoolInt,
@ -4686,7 +4686,7 @@ impl TypePair {
(Type::Bool, Type::Float) => Self::BoolFloat,
(Type::Bool, Type::Str) => Self::BoolStr,
(Type::Bool, Type::Bool) => Self::BoolBool,
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Array" => Self::BoolArray,
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "List" => Self::BoolList,
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Func" => Self::BoolFunc,
(Type::Bool, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::BoolProc,
(Type::Str, Type::Int) => Self::StrInt,
@ -4694,29 +4694,29 @@ impl TypePair {
(Type::Str, Type::Float) => Self::StrFloat,
(Type::Str, Type::Bool) => Self::StrBool,
(Type::Str, Type::Str) => Self::StrStr,
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Array" => Self::StrArray,
(Type::Str, Type::Poly { name, .. }) if &name[..] == "List" => Self::StrList,
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Func" => Self::StrFunc,
(Type::Str, Type::Poly { name, .. }) if &name[..] == "Proc" => Self::StrProc,
// 要素数は検査済みなので、気にする必要はない
(Type::Poly { name, .. }, Type::Int) if &name[..] == "Array" => Self::ArrayInt,
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "Array" => Self::ArrayNat,
(Type::Poly { name, .. }, Type::Float) if &name[..] == "Array" => Self::ArrayFloat,
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Array" => Self::ArrayStr,
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Array" => Self::ArrayBool,
(Type::Poly { name, .. }, Type::Int) if &name[..] == "List" => Self::ListInt,
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "List" => Self::ListNat,
(Type::Poly { name, .. }, Type::Float) if &name[..] == "List" => Self::ListFloat,
(Type::Poly { name, .. }, Type::Str) if &name[..] == "List" => Self::ListStr,
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "List" => Self::ListBool,
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Array" && &rn[..] == "Array" =>
if &ln[..] == "List" && &rn[..] == "List" =>
{
Self::ArrayArray
Self::ListList
}
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Array" && &rn[..] == "Func" =>
if &ln[..] == "List" && &rn[..] == "Func" =>
{
Self::ArrayFunc
Self::ListFunc
}
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Array" && &rn[..] == "Proc" =>
if &ln[..] == "List" && &rn[..] == "Proc" =>
{
Self::ArrayProc
Self::ListProc
}
(Type::Poly { name, .. }, Type::Int) if &name[..] == "Func" => Self::FuncInt,
(Type::Poly { name, .. }, Type::Nat) if &name[..] == "Func" => Self::FuncNat,
@ -4724,9 +4724,9 @@ impl TypePair {
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Func" => Self::FuncStr,
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Func" => Self::FuncBool,
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Func" && &rn[..] == "Array" =>
if &ln[..] == "Func" && &rn[..] == "List" =>
{
Self::FuncArray
Self::FuncList
}
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Func" && &rn[..] == "Func" =>
@ -4744,9 +4744,9 @@ impl TypePair {
(Type::Poly { name, .. }, Type::Str) if &name[..] == "Proc" => Self::ProcStr,
(Type::Poly { name, .. }, Type::Bool) if &name[..] == "Proc" => Self::ProcBool,
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Proc" && &rn[..] == "Array" =>
if &ln[..] == "Proc" && &rn[..] == "List" =>
{
Self::ProcArray
Self::ProcList
}
(Type::Poly { name: ln, .. }, Type::Poly { name: rn, .. })
if &ln[..] == "Proc" && &rn[..] == "Func" =>

View file

@ -240,9 +240,9 @@ impl TyParamLambda {
/// * Type: Int, Add(?R, ?O), ...
/// * Mono: I, N, ...
/// * Attr: math.PI, ...
/// * Array: `[1, 2, N]`
/// * List: `[1, 2, N]`
/// * Tuple: (1, N, True)
/// * App: Array(Int), Fib(10), ...
/// * App: List(Int), Fib(10), ...
/// * QuantVar: N: Nat, ...
/// * FreeVar: ?I: Int, ...
/// * UnaryOp: -N, ~B, ...
@ -252,8 +252,8 @@ impl TyParamLambda {
pub enum TyParam {
Value(ValueObj),
Type(Box<Type>),
Array(Vec<TyParam>),
UnsizedArray(Box<TyParam>),
List(Vec<TyParam>),
UnsizedList(Box<TyParam>),
Tuple(Vec<TyParam>),
Set(Set<TyParam>),
Dict(Dict<TyParam, TyParam>),
@ -296,8 +296,8 @@ impl PartialEq for TyParam {
match (self, other) {
(Self::Value(l), Self::Value(r)) => l == r,
(Self::Type(l), Self::Type(r)) => l == r,
(Self::Array(l), Self::Array(r)) => l == r,
(Self::UnsizedArray(l), Self::UnsizedArray(r)) => l == r,
(Self::List(l), Self::List(r)) => l == r,
(Self::UnsizedList(l), Self::UnsizedList(r)) => l == r,
(Self::Tuple(l), Self::Tuple(r)) => l == r,
(Self::Dict(l), Self::Dict(r)) => l == r,
(Self::Record(l), Self::Record(r)) => l == r,
@ -435,9 +435,9 @@ impl LimitedDisplay for TyParam {
write!(f, ")")?;
Ok(())
}
Self::Array(arr) => {
Self::List(lis) => {
write!(f, "[")?;
for (i, t) in arr.iter().enumerate() {
for (i, t) in lis.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
@ -449,7 +449,7 @@ impl LimitedDisplay for TyParam {
}
write!(f, "]")
}
Self::UnsizedArray(elem) => {
Self::UnsizedList(elem) => {
write!(f, "[")?;
elem.limited_fmt(f, limit - 1)?;
write!(f, "; _]")
@ -685,16 +685,16 @@ impl TryFrom<TyParam> for ValueObj {
type Error = ();
fn try_from(tp: TyParam) -> Result<Self, ()> {
match tp {
TyParam::Array(tps) => {
TyParam::List(tps) => {
let mut vals = vec![];
for tp in tps {
vals.push(ValueObj::try_from(tp)?);
}
Ok(ValueObj::Array(Arc::from(vals)))
Ok(ValueObj::List(Arc::from(vals)))
}
TyParam::UnsizedArray(elem) => {
TyParam::UnsizedList(elem) => {
let elem = ValueObj::try_from(*elem)?;
Ok(ValueObj::UnsizedArray(Box::new(elem)))
Ok(ValueObj::UnsizedList(Box::new(elem)))
}
TyParam::Tuple(tps) => {
let mut vals = vec![];
@ -768,7 +768,7 @@ impl TryFrom<TyParam> for Vec<TyParam> {
fn try_from(tp: TyParam) -> Result<Self, ()> {
match tp {
TyParam::FreeVar(fv) if fv.is_linked() => Vec::try_from(fv.crack().clone()),
TyParam::Array(tps) => Ok(tps),
TyParam::List(tps) => Ok(tps),
_ => Err(()),
}
}
@ -783,7 +783,7 @@ impl<'a> TryFrom<&'a TyParam> for &'a Type {
}
TyParam::Type(t) => Ok(t.as_ref()),
TyParam::Value(v) => <&Type>::try_from(v),
// TODO: Array, Dict, Set
// TODO: List, Dict, Set
_ => Err(()),
}
}
@ -805,7 +805,7 @@ impl HasLevel for TyParam {
match self {
Self::Type(t) => t.level(),
Self::FreeVar(fv) => fv.level(),
Self::Array(tps) | Self::Tuple(tps) => tps.iter().filter_map(|tp| tp.level()).min(),
Self::List(tps) | Self::Tuple(tps) => tps.iter().filter_map(|tp| tp.level()).min(),
Self::Dict(tps) => tps
.iter()
.map(|(k, v)| {
@ -844,7 +844,7 @@ impl HasLevel for TyParam {
v.set_level(level);
}
}
Self::Array(tps) => {
Self::List(tps) => {
for tp in tps {
tp.set_level(level);
}
@ -883,7 +883,7 @@ impl StructuralEq for TyParam {
fn structural_eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Type(l), Self::Type(r)) => l.structural_eq(r),
(Self::Array(l), Self::Array(r)) => l.iter().zip(r).all(|(l, r)| l.structural_eq(r)),
(Self::List(l), Self::List(r)) => l.iter().zip(r).all(|(l, r)| l.structural_eq(r)),
(Self::Tuple(l), Self::Tuple(r)) => l.iter().zip(r).all(|(l, r)| l.structural_eq(r)),
(Self::Dict(l), Self::Dict(r)) => {
if l.len() != r.len() {
@ -1076,8 +1076,8 @@ impl TyParam {
Self::Erased(Box::new(t))
}
pub fn unsized_array(elem: TyParam) -> Self {
Self::UnsizedArray(Box::new(elem))
pub fn unsized_list(elem: TyParam) -> Self {
Self::UnsizedList(Box::new(elem))
}
// if self: Ratio, Succ(self) => self+ε
@ -1196,7 +1196,7 @@ impl TyParam {
}
Self::Type(t) => t.qvars(),
Self::Proj { obj, .. } => obj.qvars(),
Self::Array(ts) | Self::Tuple(ts) => {
Self::List(ts) | Self::Tuple(ts) => {
ts.iter().fold(set! {}, |acc, t| acc.concat(t.qvars()))
}
Self::Set(ts) => ts.iter().fold(set! {}, |acc, t| acc.concat(t.qvars())),
@ -1225,7 +1225,7 @@ impl TyParam {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().has_qvar(),
Self::Type(t) => t.has_qvar(),
Self::Proj { obj, .. } => obj.has_qvar(),
Self::Array(tps) | Self::Tuple(tps) => tps.iter().any(|tp| tp.has_qvar()),
Self::List(tps) | Self::Tuple(tps) => tps.iter().any(|tp| tp.has_qvar()),
Self::Set(tps) => tps.iter().any(|tp| tp.has_qvar()),
Self::Dict(tps) => tps.iter().any(|(k, v)| k.has_qvar() || v.has_qvar()),
Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
@ -1247,7 +1247,7 @@ impl TyParam {
Self::Type(t) => t.contains_tvar(target),
Self::Erased(t) => t.contains_tvar(target),
Self::Proj { obj, .. } => obj.contains_tvar(target),
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tvar(target)),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tvar(target)),
Self::Set(ts) => ts.iter().any(|t| t.contains_tvar(target)),
Self::Dict(ts) => ts
.iter()
@ -1273,8 +1273,8 @@ impl TyParam {
Self::ProjCall { obj, args, .. } => {
obj.contains_type(target) || args.iter().any(|t| t.contains_type(target))
}
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_type(target)),
Self::UnsizedArray(elem) => elem.contains_type(target),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_type(target)),
Self::UnsizedList(elem) => elem.contains_type(target),
Self::Set(ts) => ts.iter().any(|t| t.contains_type(target)),
Self::Dict(ts) => ts
.iter()
@ -1303,8 +1303,8 @@ impl TyParam {
Self::ProjCall { obj, args, .. } => {
obj.contains_tp(target) || args.iter().any(|t| t.contains_tp(target))
}
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(target)),
Self::UnsizedArray(elem) => elem.contains_tp(target),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(target)),
Self::UnsizedList(elem) => elem.contains_tp(target),
Self::Set(ts) => ts.iter().any(|t| t.contains_tp(target)),
Self::Dict(ts) => ts
.iter()
@ -1333,8 +1333,8 @@ impl TyParam {
Self::UnaryOp { val, .. } => val.contains_tp(self),
Self::App { args, .. } => args.iter().any(|t| t.contains_tp(self)),
Self::Lambda(lambda) => lambda.body.iter().any(|t| t.contains_tp(self)),
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(self)),
Self::UnsizedArray(elem) => elem.contains_tp(self),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(self)),
Self::UnsizedList(elem) => elem.contains_tp(self),
Self::Set(ts) => ts.iter().any(|t| t.contains_tp(self)),
Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
rec.iter().any(|(_, t)| t.contains_tp(self))
@ -1372,8 +1372,8 @@ impl TyParam {
Self::ProjCall { obj, args, .. } => {
obj.has_unbound_var() || args.iter().any(|t| t.has_unbound_var())
}
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_unbound_var()),
Self::UnsizedArray(elem) => elem.has_unbound_var(),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_unbound_var()),
Self::UnsizedList(elem) => elem.has_unbound_var(),
Self::Set(ts) => ts.iter().any(|t| t.has_unbound_var()),
Self::Dict(kv) => kv
.iter()
@ -1403,8 +1403,8 @@ impl TyParam {
Self::ProjCall { obj, args, .. } => {
obj.has_undoable_linked_var() || args.iter().any(|t| t.has_undoable_linked_var())
}
Self::Array(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_undoable_linked_var()),
Self::UnsizedArray(elem) => elem.has_undoable_linked_var(),
Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_undoable_linked_var()),
Self::UnsizedList(elem) => elem.has_undoable_linked_var(),
Self::Set(ts) => ts.iter().any(|t| t.has_undoable_linked_var()),
Self::Dict(kv) => kv
.iter()
@ -1432,10 +1432,10 @@ impl TyParam {
Self::ProjCall { obj, args, .. } => obj
.union_size()
.max(args.iter().map(|t| t.union_size()).max().unwrap_or(1)),
Self::Array(ts) | Self::Tuple(ts) => {
Self::List(ts) | Self::Tuple(ts) => {
ts.iter().map(|t| t.union_size()).max().unwrap_or(1)
}
Self::UnsizedArray(elem) => elem.union_size(),
Self::UnsizedList(elem) => elem.union_size(),
Self::Set(ts) => ts.iter().map(|t| t.union_size()).max().unwrap_or(1),
Self::Dict(kv) => kv
.iter()
@ -1517,10 +1517,10 @@ impl TyParam {
let new_val = val.substitute(var, to);
TyParam::unary(op, new_val)
}
TyParam::UnsizedArray(elem) => TyParam::unsized_array(elem.substitute(var, to)),
TyParam::Array(tps) => {
TyParam::UnsizedList(elem) => TyParam::unsized_list(elem.substitute(var, to)),
TyParam::List(tps) => {
let new_tps = tps.into_iter().map(|t| t.substitute(var, to)).collect();
TyParam::Array(new_tps)
TyParam::List(new_tps)
}
TyParam::Tuple(tps) => {
let new_tps = tps.into_iter().map(|t| t.substitute(var, to)).collect();
@ -1610,10 +1610,10 @@ impl TyParam {
let new_val = val.replace(target, to);
TyParam::unary(op, new_val)
}
TyParam::UnsizedArray(elem) => TyParam::unsized_array(elem.replace(target, to)),
TyParam::Array(tps) => {
TyParam::UnsizedList(elem) => TyParam::unsized_list(elem.replace(target, to)),
TyParam::List(tps) => {
let new_tps = tps.into_iter().map(|t| t.replace(target, to)).collect();
TyParam::Array(new_tps)
TyParam::List(new_tps)
}
TyParam::Tuple(tps) => {
let new_tps = tps.into_iter().map(|t| t.replace(target, to)).collect();
@ -1844,12 +1844,12 @@ impl TyParam {
arg.dereference();
}
}
Self::Array(ts) | Self::Tuple(ts) => {
Self::List(ts) | Self::Tuple(ts) => {
for t in ts {
t.dereference();
}
}
Self::UnsizedArray(elem) => elem.dereference(),
Self::UnsizedList(elem) => elem.dereference(),
Self::Set(ts) => {
let ts_ = std::mem::take(ts);
*ts = ts_
@ -1922,7 +1922,7 @@ impl TyParam {
}
set
}
Self::Array(tps) | Self::Tuple(tps) => {
Self::List(tps) | Self::Tuple(tps) => {
tps.iter().fold(set! {}, |acc, t| acc.concat(t.variables()))
}
Self::Set(tps) => tps.iter().fold(set! {}, |acc, t| acc.concat(t.variables())),
@ -1932,7 +1932,7 @@ impl TyParam {
Self::Dict(tps) => tps.iter().fold(set! {}, |acc, (k, v)| {
acc.concat(k.variables().concat(v.variables()))
}),
Self::UnsizedArray(elem) => elem.variables(),
Self::UnsizedList(elem) => elem.variables(),
Self::BinOp { lhs, rhs, .. } => lhs.variables().concat(rhs.variables()),
Self::UnaryOp { val, .. } => val.variables(),
Self::Lambda(lambda) => lambda

View file

@ -25,7 +25,7 @@ use crate::context::Context;
use self::value_set::inner_class;
use super::codeobj::{tuple_into_bytes, CodeObj};
use super::constructors::{array_t, dict_t, refinement, set_t, tuple_t, unsized_array_t};
use super::constructors::{dict_t, list_t, refinement, set_t, tuple_t, unsized_list_t};
use super::typaram::{OpKind, TyParam};
use super::{ConstSubr, Field, HasType, Predicate, Type};
use super::{CONTAINER_OMIT_THRESHOLD, STR_OMIT_THRESHOLD};
@ -502,8 +502,8 @@ pub enum ValueObj {
Float(f64),
Str(Str),
Bool(bool),
Array(ArcArray<ValueObj>),
UnsizedArray(Box<ValueObj>),
List(ArcArray<ValueObj>),
UnsizedList(Box<ValueObj>),
Set(Set<ValueObj>),
Dict(Dict<ValueObj, ValueObj>),
Tuple(ArcArray<ValueObj>),
@ -562,8 +562,8 @@ impl fmt::Debug for ValueObj {
write!(f, "False")
}
}
Self::Array(arr) => write!(f, "[{}]", fmt_iter(arr.iter())),
Self::UnsizedArray(elem) => write!(f, "[{elem}; _]"),
Self::List(lis) => write!(f, "[{}]", fmt_iter(lis.iter())),
Self::UnsizedList(elem) => write!(f, "[{elem}; _]"),
Self::Dict(dict) => {
write!(f, "{{")?;
for (i, (k, v)) in dict.iter().enumerate() {
@ -624,9 +624,9 @@ impl LimitedDisplay for ValueObj {
write!(f, "\"{}\"", s.escape())
}
}
Self::Array(arr) => {
Self::List(lis) => {
write!(f, "[")?;
for (i, item) in arr.iter().enumerate() {
for (i, item) in lis.iter().enumerate() {
if i != 0 {
write!(f, ", ")?;
}
@ -751,8 +751,8 @@ impl Hash for ValueObj {
Self::Float(f) => f.to_bits().hash(state),
Self::Str(s) => s.hash(state),
Self::Bool(b) => b.hash(state),
Self::Array(arr) => arr.hash(state),
Self::UnsizedArray(elem) => {
Self::List(lis) => lis.hash(state),
Self::UnsizedList(elem) => {
"UnsizedArray".hash(state);
elem.hash(state)
}
@ -855,7 +855,7 @@ impl From<CodeObj> for ValueObj {
impl<V: Into<ValueObj>> From<Vec<V>> for ValueObj {
fn from(item: Vec<V>) -> Self {
ValueObj::Array(ArcArray::from(
ValueObj::List(ArcArray::from(
&item.into_iter().map(Into::into).collect::<Vec<_>>()[..],
))
}
@ -863,7 +863,7 @@ impl<V: Into<ValueObj>> From<Vec<V>> for ValueObj {
impl<const N: usize, V: Into<ValueObj>> From<[V; N]> for ValueObj {
fn from(item: [V; N]) -> Self {
ValueObj::Array(ArcArray::from(&item.map(Into::into)[..]))
ValueObj::List(ArcArray::from(&item.map(Into::into)[..]))
}
}
@ -1031,8 +1031,8 @@ impl ValueObj {
pub const fn is_container(&self) -> bool {
matches!(
self,
Self::Array(_)
| Self::UnsizedArray(_)
Self::List(_)
| Self::UnsizedList(_)
| Self::Set(_)
| Self::Dict(_)
| Self::Tuple(_)
@ -1124,7 +1124,7 @@ impl ValueObj {
Self::Str(s) => str_into_bytes(s, false),
Self::Bool(true) => vec![DataTypePrefix::True as u8],
Self::Bool(false) => vec![DataTypePrefix::False as u8],
Self::Array(elems) | Self::Tuple(elems) => tuple_into_bytes(&elems, python_ver),
Self::List(elems) | Self::Tuple(elems) => tuple_into_bytes(&elems, python_ver),
Self::None => {
vec![DataTypePrefix::None as u8]
}
@ -1169,15 +1169,15 @@ impl ValueObj {
Self::Float(_) => Type::Float,
Self::Str(_) => Type::Str,
Self::Bool(_) => Type::Bool,
Self::Array(arr) => array_t(
Self::List(lis) => list_t(
// REVIEW: Never?
arr.iter()
lis.iter()
.next()
.map(|elem| elem.class())
.unwrap_or(Type::Never),
TyParam::value(arr.len()),
TyParam::value(lis.len()),
),
Self::UnsizedArray(elem) => unsized_array_t(elem.class()),
Self::UnsizedList(elem) => unsized_list_t(elem.class()),
Self::Dict(dict) => {
let tp = dict
.iter()
@ -1295,9 +1295,9 @@ impl ValueObj {
(Self::Nat(l), Self::Float(r)) => Some(Self::Float(l as f64 - r)),
(Self::Float(l), Self::Int(r)) => Some(Self::Float(l - r as f64)),
(Self::Str(l), Self::Str(r)) => Some(Self::Str(Str::from(format!("{l}{r}")))),
(Self::Array(l), Self::Array(r)) => {
let arr = Arc::from([l, r].concat());
Some(Self::Array(arr))
(Self::List(l), Self::List(r)) => {
let lis = Arc::from([l, r].concat());
Some(Self::List(lis))
}
(Self::Dict(l), Self::Dict(r)) => Some(Self::Dict(l.concat(r))),
(inf @ (Self::Inf | Self::NegInf), _) | (_, inf @ (Self::Inf | Self::NegInf)) => {

View file

@ -8,7 +8,7 @@ use erg_common::traits::{BlockKind, ExitStatus, Locational, New, Runnable, Strea
use erg_compiler::artifact::{Buildable, ErrorArtifact};
use erg_compiler::build_package::PackageBuilder;
use erg_compiler::error::{CompileError, CompileErrors, CompileWarnings};
use erg_compiler::hir::{Accessor, Array, Def, Dict, Expr, Set, Signature, Tuple};
use erg_compiler::hir::{Accessor, Def, Dict, Expr, List, Set, Signature, Tuple};
use erg_compiler::module::SharedCompilerResource;
use erg_parser::ParserRunner;
@ -189,21 +189,21 @@ impl Linter {
}
}
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
for elem in arr.elems.pos_args.iter() {
Expr::List(list) => match list {
List::Normal(lis) => {
for elem in lis.elems.pos_args.iter() {
lint_fn(self, &elem.expr);
}
}
Array::WithLength(arr) => {
lint_fn(self, &arr.elem);
if let Some(len) = &arr.len {
List::WithLength(lis) => {
lint_fn(self, &lis.elem);
if let Some(len) = &lis.len {
lint_fn(self, len);
}
}
Array::Comprehension(arr) => {
lint_fn(self, &arr.elem);
lint_fn(self, &arr.guard);
List::Comprehension(lis) => {
lint_fn(self, &lis.elem);
lint_fn(self, &lis.guard);
}
},
Expr::Tuple(tuple) => match tuple {

View file

@ -202,7 +202,7 @@ pub fn fmt_lines<'a, T: NestedDisplay + 'a>(
}
/// リテラルに実際の値が格納された構造体(定数畳み込み用)
/// ArrayやDictはまた別に
/// ListやDictはまた別に
#[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Literal {
@ -865,13 +865,13 @@ impl Accessor {
#[pyclass(get_all, set_all)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NormalArray {
pub struct NormalList {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub elems: Args,
}
impl NestedDisplay for NormalArray {
impl NestedDisplay for NormalList {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
writeln!(f, "[")?;
self.elems.fmt_nest(f, level + 1)?;
@ -879,11 +879,11 @@ impl NestedDisplay for NormalArray {
}
}
impl_display_from_nested!(NormalArray);
impl_locational!(NormalArray, l_sqbr, elems, r_sqbr);
impl_display_from_nested!(NormalList);
impl_locational!(NormalList, l_sqbr, elems, r_sqbr);
#[pymethods]
impl NormalArray {
impl NormalList {
#[pyo3(name = "get")]
fn _get(&self, index: usize) -> Option<Expr> {
self.get(index).cloned()
@ -899,7 +899,7 @@ impl NormalArray {
}
}
impl NormalArray {
impl NormalList {
pub fn get(&self, index: usize) -> Option<&Expr> {
self.elems.pos_args.get(index).map(|a| &a.expr)
}
@ -911,24 +911,24 @@ impl NormalArray {
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayWithLength {
pub struct ListWithLength {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub elem: Box<PosArg>,
pub len: Box<Expr>,
}
impl NestedDisplay for ArrayWithLength {
impl NestedDisplay for ListWithLength {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}; {}]", self.elem, self.len)
}
}
impl_display_from_nested!(ArrayWithLength);
impl_locational!(ArrayWithLength, l_sqbr, elem, r_sqbr);
impl_display_from_nested!(ListWithLength);
impl_locational!(ListWithLength, l_sqbr, elem, r_sqbr);
#[pymethods]
impl ArrayWithLength {
impl ListWithLength {
#[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elem: PosArg, len: Expr) -> Self {
Self {
@ -942,7 +942,7 @@ impl ArrayWithLength {
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayComprehension {
pub struct ListComprehension {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub layout: Option<Box<Expr>>,
@ -950,7 +950,7 @@ pub struct ArrayComprehension {
pub guard: Option<Box<Expr>>,
}
impl NestedDisplay for ArrayComprehension {
impl NestedDisplay for ListComprehension {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
let mut generators = String::new();
for (name, gen) in self.generators.iter() {
@ -966,11 +966,11 @@ impl NestedDisplay for ArrayComprehension {
}
}
impl_display_from_nested!(ArrayComprehension);
impl_locational!(ArrayComprehension, l_sqbr, r_sqbr);
impl_display_from_nested!(ListComprehension);
impl_locational!(ListComprehension, l_sqbr, r_sqbr);
#[pymethods]
impl ArrayComprehension {
impl ListComprehension {
#[staticmethod]
#[pyo3(signature = (l_sqbr, r_sqbr, layout, generators, guard=None))]
pub fn new(
@ -991,22 +991,22 @@ impl ArrayComprehension {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Array {
Normal(NormalArray),
WithLength(ArrayWithLength),
Comprehension(ArrayComprehension),
pub enum List {
Normal(NormalList),
WithLength(ListWithLength),
Comprehension(ListComprehension),
}
impl_nested_display_for_enum!(Array; Normal, WithLength, Comprehension);
impl_display_for_enum!(Array; Normal, WithLength, Comprehension);
impl_locational_for_enum!(Array; Normal, WithLength, Comprehension);
impl_into_py_for_enum!(Array; Normal, WithLength, Comprehension);
impl_from_py_for_enum!(Array; Normal(NormalArray), WithLength(ArrayWithLength), Comprehension(ArrayComprehension));
impl_nested_display_for_enum!(List; Normal, WithLength, Comprehension);
impl_display_for_enum!(List; Normal, WithLength, Comprehension);
impl_locational_for_enum!(List; Normal, WithLength, Comprehension);
impl_into_py_for_enum!(List; Normal, WithLength, Comprehension);
impl_from_py_for_enum!(List; Normal(NormalList), WithLength(ListWithLength), Comprehension(ListComprehension));
impl Array {
impl List {
pub fn get(&self, index: usize) -> Option<&Expr> {
match self {
Self::Normal(array) => array.get(index),
Self::Normal(list) => list.get(index),
_ => None,
}
}
@ -2167,36 +2167,36 @@ impl ConstAccessor {
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ConstArray {
Normal(ConstNormalArray),
WithLength(ConstArrayWithLength),
pub enum ConstList {
Normal(ConstNormalList),
WithLength(ConstListWithLength),
}
impl_nested_display_for_enum!(ConstArray; Normal, WithLength);
impl_display_from_nested!(ConstArray);
impl_locational_for_enum!(ConstArray; Normal, WithLength);
impl_into_py_for_enum!(ConstArray; Normal, WithLength);
impl_from_py_for_enum!(ConstArray; Normal(ConstNormalArray), WithLength(ConstArrayWithLength));
impl_nested_display_for_enum!(ConstList; Normal, WithLength);
impl_display_from_nested!(ConstList);
impl_locational_for_enum!(ConstList; Normal, WithLength);
impl_into_py_for_enum!(ConstList; Normal, WithLength);
impl_from_py_for_enum!(ConstList; Normal(ConstNormalList), WithLength(ConstListWithLength));
impl ConstArray {
pub fn downgrade(self) -> Array {
impl ConstList {
pub fn downgrade(self) -> List {
match self {
Self::Normal(normal) => Array::Normal(normal.downgrade()),
Self::WithLength(with_length) => Array::WithLength(with_length.downgrade()),
Self::Normal(normal) => List::Normal(normal.downgrade()),
Self::WithLength(with_length) => List::WithLength(with_length.downgrade()),
}
}
}
#[pyclass]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ConstNormalArray {
pub struct ConstNormalList {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub elems: ConstArgs,
pub guard: Option<Box<ConstExpr>>,
}
impl NestedDisplay for ConstNormalArray {
impl NestedDisplay for ConstNormalList {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
if let Some(guard) = &self.guard {
write!(f, "[{} | {}]", self.elems, guard)
@ -2206,11 +2206,11 @@ impl NestedDisplay for ConstNormalArray {
}
}
impl_display_from_nested!(ConstNormalArray);
impl_locational!(ConstNormalArray, l_sqbr, elems, r_sqbr);
impl_display_from_nested!(ConstNormalList);
impl_locational!(ConstNormalList, l_sqbr, elems, r_sqbr);
#[pymethods]
impl ConstNormalArray {
impl ConstNormalList {
#[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elems: ConstArgs, guard: Option<ConstExpr>) -> Self {
Self {
@ -2222,32 +2222,32 @@ impl ConstNormalArray {
}
}
impl ConstNormalArray {
pub fn downgrade(self) -> NormalArray {
NormalArray::new(self.l_sqbr, self.r_sqbr, self.elems.downgrade())
impl ConstNormalList {
pub fn downgrade(self) -> NormalList {
NormalList::new(self.l_sqbr, self.r_sqbr, self.elems.downgrade())
}
}
#[pyclass]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ConstArrayWithLength {
pub struct ConstListWithLength {
pub l_sqbr: Token,
pub r_sqbr: Token,
pub elem: Box<ConstExpr>,
pub length: Box<ConstExpr>,
}
impl NestedDisplay for ConstArrayWithLength {
impl NestedDisplay for ConstListWithLength {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}; {}]", self.elem, self.length)
}
}
impl_display_from_nested!(ConstArrayWithLength);
impl_locational!(ConstArrayWithLength, l_sqbr, elem, r_sqbr);
impl_display_from_nested!(ConstListWithLength);
impl_locational!(ConstListWithLength, l_sqbr, elem, r_sqbr);
#[pymethods]
impl ConstArrayWithLength {
impl ConstListWithLength {
#[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elem: ConstExpr, length: ConstExpr) -> Self {
Self {
@ -2259,9 +2259,9 @@ impl ConstArrayWithLength {
}
}
impl ConstArrayWithLength {
pub fn downgrade(self) -> ArrayWithLength {
ArrayWithLength::new(
impl ConstListWithLength {
pub fn downgrade(self) -> ListWithLength {
ListWithLength::new(
self.l_sqbr,
self.r_sqbr,
PosArg::new(self.elem.downgrade()),
@ -2830,7 +2830,7 @@ pub enum ConstExpr {
Lit(Literal),
Accessor(ConstAccessor),
App(ConstApp),
Array(ConstArray),
List(ConstList),
Set(ConstSet),
Dict(ConstDict),
Tuple(ConstTuple),
@ -2842,11 +2842,11 @@ pub enum ConstExpr {
TypeAsc(ConstTypeAsc),
}
impl_nested_display_for_chunk_enum!(ConstExpr; Lit, Accessor, App, Array, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc);
impl_nested_display_for_chunk_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc);
impl_display_from_nested!(ConstExpr);
impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, Array, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc);
impl_into_py_for_enum!(ConstExpr; Lit, Accessor, App, Array, Set, Dict, Tuple, Record, Def, Lambda, BinOp, UnaryOp, TypeAsc);
impl_from_py_for_enum!(ConstExpr; Lit(Literal), Accessor(ConstAccessor), App(ConstApp), Array(ConstArray), Set(ConstSet), Dict(ConstDict), Tuple(ConstTuple), Record(ConstRecord), Def(ConstDef), Lambda(ConstLambda), BinOp(ConstBinOp), UnaryOp(ConstUnaryOp), TypeAsc(ConstTypeAsc));
impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc);
impl_into_py_for_enum!(ConstExpr; Lit, Accessor, App, List, Set, Dict, Tuple, Record, Def, Lambda, BinOp, UnaryOp, TypeAsc);
impl_from_py_for_enum!(ConstExpr; Lit(Literal), Accessor(ConstAccessor), App(ConstApp), List(ConstList), Set(ConstSet), Dict(ConstDict), Tuple(ConstTuple), Record(ConstRecord), Def(ConstDef), Lambda(ConstLambda), BinOp(ConstBinOp), UnaryOp(ConstUnaryOp), TypeAsc(ConstTypeAsc));
impl TryFrom<&ParamPattern> for ConstExpr {
type Error = ();
@ -2856,7 +2856,7 @@ impl TryFrom<&ParamPattern> for ConstExpr {
Ok(ConstExpr::Accessor(ConstAccessor::local(name.0.clone())))
}
ParamPattern::Lit(lit) => Ok(ConstExpr::Lit(lit.clone())),
ParamPattern::Array(array) => ConstExpr::try_from(array),
ParamPattern::List(list) => ConstExpr::try_from(list),
ParamPattern::Tuple(tuple) => ConstExpr::try_from(tuple),
_ => Err(()),
}
@ -2878,7 +2878,7 @@ impl ConstExpr {
Self::Lit(lit) => Expr::Literal(lit),
Self::Accessor(acc) => Expr::Accessor(acc.downgrade()),
Self::App(app) => Expr::Call(app.downgrade()),
Self::Array(arr) => Expr::Array(arr.downgrade()),
Self::List(lis) => Expr::List(lis.downgrade()),
Self::Set(set) => Expr::Set(set.downgrade()),
Self::Dict(dict) => Expr::Dict(dict.downgrade()),
Self::Tuple(tuple) => Expr::Tuple(tuple.downgrade()),
@ -3338,19 +3338,19 @@ impl SubrTypeSpec {
#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayTypeSpec {
pub struct ListTypeSpec {
pub sqbrs: Option<(Token, Token)>,
pub ty: Box<TypeSpec>,
pub len: ConstExpr,
}
impl fmt::Display for ArrayTypeSpec {
impl fmt::Display for ListTypeSpec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}; {}]", self.ty, self.len)
}
}
impl Locational for ArrayTypeSpec {
impl Locational for ListTypeSpec {
fn loc(&self) -> Location {
if let Some((lsqbr, rsqbr)) = &self.sqbrs {
Location::concat(lsqbr, rsqbr)
@ -3360,7 +3360,7 @@ impl Locational for ArrayTypeSpec {
}
}
impl ArrayTypeSpec {
impl ListTypeSpec {
pub fn new(ty: TypeSpec, len: ConstExpr, sqbrs: Option<(Token, Token)>) -> Self {
Self {
ty: Box::new(ty),
@ -3529,7 +3529,7 @@ impl RefinementTypeSpec {
}
}
/// * Array: `[Int; 3]`, `[Int, Ratio, Complex]`, etc.
/// * List: `[Int; 3]`, `[Int, Ratio, Complex]`, etc.
/// * Dict: `[Str: Str]`, etc.
/// * And (Intersection type): Add and Sub and Mul (== Num), etc.
/// * Not (Diff type): Pos == Nat not {0}, etc.
@ -3545,7 +3545,7 @@ pub enum TypeSpec {
Infer(Token),
PreDeclTy(PreDeclTypeSpec),
/* Composite types */
Array(ArrayTypeSpec),
List(ListTypeSpec),
SetWithLen(SetWithLenTypeSpec),
Tuple(TupleTypeSpec),
Dict(DictTypeSpec),
@ -3584,7 +3584,7 @@ impl fmt::Display for TypeSpec {
Self::And(lhs, rhs) => write!(f, "{lhs} and {rhs}"),
Self::Not(ty) => write!(f, "not {ty}"),
Self::Or(lhs, rhs) => write!(f, "{lhs} or {rhs}"),
Self::Array(arr) => write!(f, "{arr}"),
Self::List(lis) => write!(f, "{lis}"),
Self::SetWithLen(set) => write!(f, "{set}"),
Self::Tuple(tup) => write!(f, "{tup}"),
Self::Dict(dict) => dict.fmt(f),
@ -3613,7 +3613,7 @@ impl Locational for TypeSpec {
Location::concat(lhs.as_ref(), rhs.as_ref())
}
Self::Not(ty) => ty.loc(),
Self::Array(arr) => arr.loc(),
Self::List(lis) => lis.loc(),
Self::SetWithLen(set) => set.loc(),
Self::Tuple(tup) => tup.loc(),
Self::Dict(dict) => dict.loc(),
@ -4253,21 +4253,21 @@ impl Identifier {
#[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct VarArrayPattern {
pub struct VarListPattern {
l_sqbr: Token,
pub(crate) elems: Vars,
r_sqbr: Token,
}
impl fmt::Display for VarArrayPattern {
impl fmt::Display for VarListPattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}]", self.elems)
}
}
impl_locational!(VarArrayPattern, l_sqbr, r_sqbr);
impl_locational!(VarListPattern, l_sqbr, r_sqbr);
impl Stream<VarSignature> for VarArrayPattern {
impl Stream<VarSignature> for VarListPattern {
#[inline]
fn payload(self) -> Vec<VarSignature> {
self.elems.payload()
@ -4282,7 +4282,7 @@ impl Stream<VarSignature> for VarArrayPattern {
}
}
impl VarArrayPattern {
impl VarListPattern {
pub const fn new(l_sqbr: Token, elems: Vars, r_sqbr: Token) -> Self {
Self {
l_sqbr,
@ -4439,7 +4439,7 @@ pub enum VarPattern {
Discard(Token),
Ident(Identifier),
/// e.g. `[x, y, z]` of `[x, y, z] = [1, 2, 3]`
Array(VarArrayPattern),
List(VarListPattern),
/// e.g. `(x, y, z)` of `(x, y, z) = (1, 2, 3)`
Tuple(VarTuplePattern),
// e.g. `{name; age}`, `{_; [car, cdr]}`
@ -4453,7 +4453,7 @@ impl NestedDisplay for VarPattern {
match self {
Self::Discard(_) => write!(f, "_"),
Self::Ident(ident) => write!(f, "{ident}"),
Self::Array(a) => write!(f, "{a}"),
Self::List(l) => write!(f, "{l}"),
Self::Tuple(t) => write!(f, "{t}"),
Self::Record(r) => write!(f, "{r}"),
Self::DataPack(d) => write!(f, "{d}"),
@ -4462,9 +4462,9 @@ impl NestedDisplay for VarPattern {
}
impl_display_from_nested!(VarPattern);
impl_locational_for_enum!(VarPattern; Discard, Ident, Array, Tuple, Record, DataPack);
impl_into_py_for_enum!(VarPattern; Discard, Ident, Array, Tuple, Record, DataPack);
impl_from_py_for_enum!(VarPattern; Discard(Token), Ident(Identifier), Array(VarArrayPattern), Tuple(VarTuplePattern), Record(VarRecordPattern), DataPack(VarDataPackPattern));
impl_locational_for_enum!(VarPattern; Discard, Ident, List, Tuple, Record, DataPack);
impl_into_py_for_enum!(VarPattern; Discard, Ident, List, Tuple, Record, DataPack);
impl_from_py_for_enum!(VarPattern; Discard(Token), Ident(Identifier), List(VarListPattern), Tuple(VarTuplePattern), Record(VarRecordPattern), DataPack(VarDataPackPattern));
impl VarPattern {
pub const fn inspect(&self) -> Option<&Str> {
@ -4643,31 +4643,31 @@ impl Vars {
#[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamArrayPattern {
pub struct ParamListPattern {
pub l_sqbr: Token,
pub elems: Params,
pub r_sqbr: Token,
}
impl NestedDisplay for ParamArrayPattern {
impl NestedDisplay for ParamListPattern {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}]", self.elems)
}
}
impl_display_from_nested!(ParamArrayPattern);
impl_locational!(ParamArrayPattern, l_sqbr, r_sqbr);
impl_display_from_nested!(ParamListPattern);
impl_locational!(ParamListPattern, l_sqbr, r_sqbr);
impl TryFrom<&ParamArrayPattern> for Expr {
impl TryFrom<&ParamListPattern> for Expr {
type Error = ();
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> {
fn try_from(value: &ParamListPattern) -> Result<Self, Self::Error> {
let mut new = vec![];
for elem in value.elems.non_defaults.iter() {
new.push(PosArg::new(Expr::try_from(&elem.pat)?));
}
let elems = Args::pos_only(new, None);
Ok(Expr::Array(Array::Normal(NormalArray::new(
Ok(Expr::List(List::Normal(NormalList::new(
value.l_sqbr.clone(),
value.r_sqbr.clone(),
elems,
@ -4675,16 +4675,16 @@ impl TryFrom<&ParamArrayPattern> for Expr {
}
}
impl TryFrom<&ParamArrayPattern> for ConstExpr {
impl TryFrom<&ParamListPattern> for ConstExpr {
type Error = ();
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> {
fn try_from(value: &ParamListPattern) -> Result<Self, Self::Error> {
let mut new = vec![];
for elem in value.elems.non_defaults.iter() {
new.push(ConstPosArg::new(ConstExpr::try_from(&elem.pat)?));
}
let elems = ConstArgs::pos_only(new, None);
Ok(ConstExpr::Array(ConstArray::Normal(ConstNormalArray::new(
Ok(ConstExpr::List(ConstList::Normal(ConstNormalList::new(
value.l_sqbr.clone(),
value.r_sqbr.clone(),
elems,
@ -4694,7 +4694,7 @@ impl TryFrom<&ParamArrayPattern> for ConstExpr {
}
#[pymethods]
impl ParamArrayPattern {
impl ParamListPattern {
#[staticmethod]
pub const fn new(l_sqbr: Token, elems: Params, r_sqbr: Token) -> Self {
Self {
@ -4851,7 +4851,7 @@ pub enum ParamPattern {
VarName(VarName),
// TODO: ConstAttr(),
Lit(Literal),
Array(ParamArrayPattern),
List(ParamListPattern),
Tuple(ParamTuplePattern),
Record(ParamRecordPattern),
// DataPack(ParamDataPackPattern),
@ -4859,7 +4859,7 @@ pub enum ParamPattern {
RefMut(VarName),
}
impl_into_py_for_enum!(ParamPattern; Discard, VarName, Lit, Array, Tuple, Record, Ref, RefMut);
impl_into_py_for_enum!(ParamPattern; Discard, VarName, Lit, List, Tuple, Record, Ref, RefMut);
impl NestedDisplay for ParamPattern {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
@ -4867,7 +4867,7 @@ impl NestedDisplay for ParamPattern {
Self::Discard(tok) => write!(f, "{tok}"),
Self::VarName(var_name) => write!(f, "{var_name}"),
Self::Lit(lit) => write!(f, "{lit}"),
Self::Array(array) => write!(f, "{array}"),
Self::List(list) => write!(f, "{list}"),
Self::Tuple(tuple) => write!(f, "{tuple}"),
Self::Record(record) => write!(f, "{record}"),
Self::Ref(var_name) => write!(f, "ref {var_name}"),
@ -4885,7 +4885,7 @@ impl TryFrom<&ParamPattern> for Expr {
Ok(Expr::Accessor(Accessor::local(name.0.clone())))
}
ParamPattern::Lit(lit) => Ok(Expr::Literal(lit.clone())),
ParamPattern::Array(array) => Expr::try_from(array),
ParamPattern::List(list) => Expr::try_from(list),
ParamPattern::Tuple(tuple) => Expr::try_from(tuple),
_ => Err(()),
}
@ -4893,7 +4893,7 @@ impl TryFrom<&ParamPattern> for Expr {
}
impl_display_from_nested!(ParamPattern);
impl_locational_for_enum!(ParamPattern; Discard, VarName, Lit, Array, Tuple, Record, Ref, RefMut);
impl_locational_for_enum!(ParamPattern; Discard, VarName, Lit, List, Tuple, Record, Ref, RefMut);
impl ParamPattern {
pub const fn inspect(&self) -> Option<&Str> {
@ -5890,7 +5890,7 @@ impl Compound {
pub enum Expr {
Literal(Literal),
Accessor(Accessor),
Array(Array),
List(List),
Tuple(Tuple),
Dict(Dict),
Set(Set),
@ -5912,12 +5912,12 @@ pub enum Expr {
Dummy(Dummy),
}
impl_nested_display_for_chunk_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_from_trait_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_nested_display_for_chunk_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_from_trait_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_display_from_nested!(Expr);
impl_locational_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_into_py_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_from_py_for_enum!(Expr; Literal, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_locational_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_into_py_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl_from_py_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl Expr {
pub fn is_match_call(&self) -> bool {
@ -5939,7 +5939,7 @@ impl Expr {
match self {
Self::Literal(_) => "literal",
Self::Accessor(_) => "accessor",
Self::Array(_) => "array",
Self::List(_) => "list",
Self::Tuple(_) => "tuple",
Self::Dict(_) => "dict",
Self::Set(_) => "set",
@ -6075,9 +6075,9 @@ impl Expr {
}
sum
}
Self::Array(Array::Normal(arr)) => {
Self::List(List::Normal(lis)) => {
let mut sum = 0;
for elem in arr.elems.pos_args.iter() {
for elem in lis.elems.pos_args.iter() {
sum += elem.expr.complexity();
}
sum

View file

@ -27,11 +27,11 @@ impl Parser {
debug_exit_info!(self);
Ok(Signature::Subr(subr))
}
Expr::Array(array) => {
let array_pat = self
.convert_array_to_array_pat(array)
Expr::List(list) => {
let list_pat = self
.convert_list_to_list_pat(list)
.map_err(|_| self.stack_dec(fn_name!()))?;
let var = VarSignature::new(VarPattern::Array(array_pat), None);
let var = VarSignature::new(VarPattern::List(list_pat), None);
debug_exit_info!(self);
Ok(Signature::Var(var))
}
@ -96,12 +96,12 @@ impl Parser {
}
}
fn convert_array_to_array_pat(&mut self, array: Array) -> ParseResult<VarArrayPattern> {
fn convert_list_to_list_pat(&mut self, list: List) -> ParseResult<VarListPattern> {
debug_call_info!(self);
match array {
Array::Normal(arr) => {
match list {
List::Normal(lis) => {
let mut vars = Vars::empty();
for elem in arr.elems.pos_args {
for elem in lis.elems.pos_args {
let pat = self
.convert_rhs_to_sig(elem.expr)
.map_err(|_| self.stack_dec(fn_name!()))?;
@ -117,7 +117,7 @@ impl Parser {
}
}
}
if let Some(var) = arr.elems.var_args {
if let Some(var) = lis.elems.var_args {
let pat = self
.convert_rhs_to_sig(var.expr)
.map_err(|_| self.stack_dec(fn_name!()))?;
@ -133,21 +133,21 @@ impl Parser {
}
}
}
let pat = VarArrayPattern::new(arr.l_sqbr, vars, arr.r_sqbr);
let pat = VarListPattern::new(lis.l_sqbr, vars, lis.r_sqbr);
debug_exit_info!(self);
Ok(pat)
}
Array::Comprehension(arr) => {
let err = ParseError::simple_syntax_error(line!() as usize, arr.loc());
List::Comprehension(lis) => {
let err = ParseError::simple_syntax_error(line!() as usize, lis.loc());
self.errs.push(err);
debug_exit_info!(self);
Err(())
}
Array::WithLength(arr) => {
List::WithLength(lis) => {
let err = ParseError::feature_error(
line!() as usize,
arr.loc(),
"array-with-length pattern",
lis.loc(),
"list-with-length pattern",
);
self.errs.push(err);
debug_exit_info!(self);
@ -480,11 +480,11 @@ impl Parser {
debug_exit_info!(self);
Ok(param)
}
Expr::Array(array) => {
let array_pat = self
.convert_array_to_param_array_pat(array)
Expr::List(list) => {
let list_pat = self
.convert_list_to_param_list_pat(list)
.map_err(|_| self.stack_dec(fn_name!()))?;
let pat = ParamPattern::Array(array_pat);
let pat = ParamPattern::List(list_pat);
let param = NonDefaultParamSignature::new(pat, None);
debug_exit_info!(self);
Ok(param)
@ -570,17 +570,17 @@ impl Parser {
Ok(param)
}
fn convert_array_to_param_array_pat(&mut self, array: Array) -> ParseResult<ParamArrayPattern> {
fn convert_list_to_param_list_pat(&mut self, list: List) -> ParseResult<ParamListPattern> {
debug_call_info!(self);
match array {
Array::Normal(arr) => {
match list {
List::Normal(lis) => {
let mut params = vec![];
for arg in arr.elems.into_iters().0 {
for arg in lis.elems.into_iters().0 {
params.push(self.convert_pos_arg_to_non_default_param(arg, false)?);
}
let params = Params::new(params, None, vec![], None, None);
debug_exit_info!(self);
Ok(ParamArrayPattern::new(arr.l_sqbr, params, arr.r_sqbr))
Ok(ParamListPattern::new(lis.l_sqbr, params, lis.r_sqbr))
}
other => {
let err = ParseError::feature_error(line!() as usize, other.loc(), "?");
@ -717,11 +717,11 @@ impl Parser {
debug_exit_info!(self);
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty()))
}
Expr::Array(array) => {
let arr = self
.convert_array_to_param_array_pat(array)
Expr::List(list) => {
let lis = self
.convert_list_to_param_list_pat(list)
.map_err(|_| self.stack_dec(fn_name!()))?;
let param = NonDefaultParamSignature::new(ParamPattern::Array(arr), None);
let param = NonDefaultParamSignature::new(ParamPattern::List(lis), None);
let params = Params::single(param);
debug_exit_info!(self);
Ok(LambdaSignature::new(params, None, TypeBoundSpecs::empty()))

View file

@ -4,7 +4,6 @@
//! e.g. Literal parameters, Multi assignment
//! 型チェックなどによる検証は行わない
use erg_common::consts::PYTHON_MODE;
use erg_common::error::Location;
use erg_common::fresh::FreshNameGenerator;
use erg_common::traits::{Locational, Stream};
@ -12,16 +11,15 @@ use erg_common::{debug_power_assert, Str};
use erg_common::{enum_unwrap, get_hash, log, set};
use crate::ast::{
Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, BinOp, Block, Call,
ClassAttr, ClassAttrs, ClassDef, Compound, ConstExpr, DataPack, Def, DefBody, DefId,
DefaultParamSignature, Dict, Dummy, Expr, GuardClause, Identifier, InlineModule, KeyValue,
KwArg, Lambda, LambdaSignature, Literal, Methods, MixedRecord, Module,
NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple,
ParamPattern, ParamRecordAttr, ParamTuplePattern, Params, PatchDef, PosArg, ReDef, Record,
RecordAttrOrIdent, RecordAttrs, RecordTypeSpec, Set as astSet, SetComprehension, SetWithLength,
Signature, SubrSignature, Tuple, TupleTypeSpec, TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs,
TypeSpec, TypeSpecWithOp, UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature,
VisModifierSpec, AST,
Accessor, Args, BinOp, Block, Call, ClassAttr, ClassAttrs, ClassDef, Compound, ConstExpr,
DataPack, Def, DefBody, DefId, DefaultParamSignature, Dict, Dummy, Expr, GuardClause,
Identifier, InlineModule, KeyValue, KwArg, Lambda, LambdaSignature, List, ListComprehension,
ListTypeSpec, ListWithLength, Literal, Methods, MixedRecord, Module, NonDefaultParamSignature,
NormalDict, NormalList, NormalRecord, NormalSet, NormalTuple, ParamPattern, ParamRecordAttr,
ParamTuplePattern, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent, RecordAttrs,
RecordTypeSpec, Set as astSet, SetComprehension, SetWithLength, Signature, SubrSignature,
Tuple, TupleTypeSpec, TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs, TypeSpec, TypeSpecWithOp,
UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature, VisModifierSpec, AST,
};
use crate::token::{Token, TokenKind, COLON, DOT};
@ -57,7 +55,7 @@ pub fn symop_to_dname(op: &str) -> Option<&'static str> {
#[derive(Debug, Clone, PartialEq, Eq)]
enum BufIndex<'i> {
Array(usize),
List(usize),
Tuple(usize),
Record(&'i Identifier),
}
@ -189,34 +187,34 @@ impl Desugarer {
};
Expr::DataPack(DataPack::new(class, pack.connector, args))
}
Expr::Array(array) => match array {
Array::Normal(arr) => {
let (elems, ..) = arr.elems.deconstruct();
Expr::List(list) => match list {
List::Normal(lis) => {
let (elems, ..) = lis.elems.deconstruct();
let elems = elems
.into_iter()
.map(|elem| PosArg::new(desugar(elem.expr)))
.collect();
let elems = Args::pos_only(elems, None);
let arr = NormalArray::new(arr.l_sqbr, arr.r_sqbr, elems);
Expr::Array(Array::Normal(arr))
let lis = NormalList::new(lis.l_sqbr, lis.r_sqbr, elems);
Expr::List(List::Normal(lis))
}
Array::WithLength(arr) => {
let elem = PosArg::new(desugar(arr.elem.expr));
let len = desugar(*arr.len);
let arr = ArrayWithLength::new(arr.l_sqbr, arr.r_sqbr, elem, len);
Expr::Array(Array::WithLength(arr))
List::WithLength(lis) => {
let elem = PosArg::new(desugar(lis.elem.expr));
let len = desugar(*lis.len);
let lis = ListWithLength::new(lis.l_sqbr, lis.r_sqbr, elem, len);
Expr::List(List::WithLength(lis))
}
Array::Comprehension(arr) => {
let layout = arr.layout.map(|ex| desugar(*ex));
let generators = arr
List::Comprehension(lis) => {
let layout = lis.layout.map(|ex| desugar(*ex));
let generators = lis
.generators
.into_iter()
.map(|(ident, gen)| (ident, desugar(gen)))
.collect();
let guard = arr.guard.map(|ex| desugar(*ex));
let arr =
ArrayComprehension::new(arr.l_sqbr, arr.r_sqbr, layout, generators, guard);
Expr::Array(Array::Comprehension(arr))
let guard = lis.guard.map(|ex| desugar(*ex));
let lis =
ListComprehension::new(lis.l_sqbr, lis.r_sqbr, layout, generators, guard);
Expr::List(List::Comprehension(lis))
}
},
Expr::Tuple(tuple) => match tuple {
@ -718,16 +716,16 @@ impl Desugarer {
self.desugar_rest_values(new, var, &buf_name, elems_len);
}
}
VarPattern::Array(arr) => {
VarPattern::List(lis) => {
let (buf_name, buf_sig) = self.gen_buf_name_and_sig(v.loc(), v.t_spec);
let body = self.desugar_pattern_in_body(body);
let buf_def = Def::new(buf_sig, body);
new.push(Expr::Def(buf_def));
for (n, elem) in arr.elems.iter().enumerate() {
self.desugar_nested_var_pattern(new, elem, &buf_name, BufIndex::Array(n));
for (n, elem) in lis.elems.iter().enumerate() {
self.desugar_nested_var_pattern(new, elem, &buf_name, BufIndex::List(n));
}
let elems_len = arr.elems.len();
if let Some(var) = arr.elems.starred.as_ref() {
let elems_len = lis.elems.len();
if let Some(var) = lis.elems.starred.as_ref() {
self.desugar_rest_values(new, var, &buf_name, elems_len);
}
}
@ -886,7 +884,7 @@ impl Desugarer {
);
let acc = match buf_index {
BufIndex::Tuple(n) => obj.tuple_attr(Literal::nat(n, sig.ln_begin().unwrap_or(1))),
BufIndex::Array(n) => {
BufIndex::List(n) => {
let r_brace = Token::new(
TokenKind::RBrace,
"]",
@ -921,17 +919,12 @@ impl Desugarer {
);
}
}
VarPattern::Array(arr) => {
VarPattern::List(lis) => {
let (buf_name, buf_sig) = self.gen_buf_name_and_sig(sig.loc(), None);
let buf_def = Def::new(buf_sig, body);
new_module.push(Expr::Def(buf_def));
for (n, elem) in arr.elems.iter().enumerate() {
self.desugar_nested_var_pattern(
new_module,
elem,
&buf_name,
BufIndex::Array(n),
);
for (n, elem) in lis.elems.iter().enumerate() {
self.desugar_nested_var_pattern(new_module, elem, &buf_name, BufIndex::List(n));
}
}
VarPattern::Record(rec) => {
@ -1054,7 +1047,7 @@ impl Desugarer {
NormalRecord::new(record.l_brace, record.r_brace, attrs)
}
fn dummy_array_expr(len: Literal) -> Expr {
fn dummy_list_expr(len: Literal) -> Expr {
let l_sqbr = Token {
content: "[".into(),
kind: TokenKind::LSqBr,
@ -1066,13 +1059,13 @@ impl Desugarer {
..len.token
};
let elem = Expr::local("Obj", l_sqbr.lineno, l_sqbr.col_begin, l_sqbr.col_end);
let array = Array::WithLength(ArrayWithLength::new(
let list = List::WithLength(ListWithLength::new(
l_sqbr,
r_sqbr,
PosArg::new(elem),
Expr::Literal(len),
));
Expr::Array(array)
Expr::List(list)
}
fn dummy_set_expr(lit: Literal) -> Expr {
@ -1271,11 +1264,11 @@ impl Desugarer {
param.pat = buf_param;
guards
}
ParamPattern::Array(arr) => {
ParamPattern::List(lis) => {
fn const_check(expr: &Expr) -> bool {
match &expr {
Expr::Accessor(Accessor::Ident(ident)) => ident.is_const(),
Expr::Array(Array::Normal(arr)) => arr
Expr::List(List::Normal(lis)) => lis
.elems
.pos_args()
.iter()
@ -1283,21 +1276,21 @@ impl Desugarer {
_ => true,
}
}
let expr = Expr::try_from(&*arr).and_then(|expr| {
let expr = Expr::try_from(&*lis).and_then(|expr| {
if const_check(&expr) {
Ok(expr)
} else {
Err(())
}
});
let (buf_name, buf_param) = self.gen_buf_nd_param(arr.loc());
guards.push(Self::len_guard(buf_name.clone(), arr.elems.len(), arr));
for (n, elem) in arr.elems.non_defaults.iter_mut().enumerate() {
let gs = self.desugar_nested_param_pattern(elem, &buf_name, BufIndex::Array(n));
let (buf_name, buf_param) = self.gen_buf_nd_param(lis.loc());
guards.push(Self::len_guard(buf_name.clone(), lis.elems.len(), lis));
for (n, elem) in lis.elems.non_defaults.iter_mut().enumerate() {
let gs = self.desugar_nested_param_pattern(elem, &buf_name, BufIndex::List(n));
guards.extend(gs);
}
if param.t_spec.is_none() {
let len = arr.elems.non_defaults.len();
let len = lis.elems.non_defaults.len();
let len = Literal::new(Token::new_fake(
TokenKind::NatLit,
len.to_string(),
@ -1306,10 +1299,10 @@ impl Desugarer {
0,
));
let infer = Token::new_fake(TokenKind::Try, "?", line, 0, 0);
let t_spec = ArrayTypeSpec::new(
let t_spec = ListTypeSpec::new(
TypeSpec::Infer(infer),
ConstExpr::Lit(len.clone()),
Some((arr.l_sqbr.clone(), arr.r_sqbr.clone())),
Some((lis.l_sqbr.clone(), lis.r_sqbr.clone())),
);
// [1, 2] -> ...
// => _: {[1, 2]} -> ...
@ -1320,11 +1313,11 @@ impl Desugarer {
Args::single(PosArg::new(expr)),
)))
} else {
Self::dummy_array_expr(len)
Self::dummy_list_expr(len)
};
param.t_spec = Some(TypeSpecWithOp::new(
Token::dummy(TokenKind::Colon, ":"),
TypeSpec::Array(t_spec),
TypeSpec::List(t_spec),
t_spec_as_expr,
));
}
@ -1419,7 +1412,7 @@ impl Desugarer {
);
let acc = match buf_index {
BufIndex::Tuple(n) => obj.tuple_attr(Literal::nat(n, sig.ln_begin().unwrap_or(1))),
BufIndex::Array(n) => {
BufIndex::List(n) => {
let r_brace = Token::new(
TokenKind::RBrace,
"]",
@ -1490,8 +1483,8 @@ impl Desugarer {
sig.pat = buf_sig;
guards
}
ParamPattern::Array(arr) => {
let (buf_name, buf_sig) = self.gen_buf_nd_param(arr.loc());
ParamPattern::List(lis) => {
let (buf_name, buf_sig) = self.gen_buf_nd_param(lis.loc());
let def = Def::new(
Signature::Var(VarSignature::new(
VarPattern::Ident(Identifier::private(Str::from(&buf_name))),
@ -1500,13 +1493,13 @@ impl Desugarer {
body,
);
guards.push(GuardClause::Bind(def));
guards.push(Self::len_guard(buf_name.clone(), arr.elems.len(), arr));
for (n, elem) in arr.elems.non_defaults.iter_mut().enumerate() {
let gs = self.desugar_nested_param_pattern(elem, &buf_name, BufIndex::Array(n));
guards.push(Self::len_guard(buf_name.clone(), lis.elems.len(), lis));
for (n, elem) in lis.elems.non_defaults.iter_mut().enumerate() {
let gs = self.desugar_nested_param_pattern(elem, &buf_name, BufIndex::List(n));
guards.extend(gs);
}
if sig.t_spec.is_none() {
let len = arr.elems.non_defaults.len();
let len = lis.elems.non_defaults.len();
let len = Literal::new(Token::new_fake(
TokenKind::NatLit,
len.to_string(),
@ -1515,15 +1508,15 @@ impl Desugarer {
0,
));
let infer = Token::new_fake(TokenKind::Try, "?", line, 0, 0);
let t_spec = ArrayTypeSpec::new(
let t_spec = ListTypeSpec::new(
TypeSpec::Infer(infer),
ConstExpr::Lit(len.clone()),
Some((arr.l_sqbr.clone(), arr.r_sqbr.clone())),
Some((lis.l_sqbr.clone(), lis.r_sqbr.clone())),
);
let t_spec_as_expr = Self::dummy_array_expr(len);
let t_spec_as_expr = Self::dummy_list_expr(len);
sig.t_spec = Some(TypeSpecWithOp::new(
COLON,
TypeSpec::Array(t_spec),
TypeSpec::List(t_spec),
t_spec_as_expr,
));
}
@ -1754,8 +1747,8 @@ impl Desugarer {
}
/// ```erg
/// [y | x <- xs] ==> array(map(x -> y, xs))
/// [(a, b) | x <- xs; y <- ys] ==> array(map(((x, y),) -> (a, b), itertools.product(xs, ys)))
/// [y | x <- xs] ==> list(map(x -> y, xs))
/// [(a, b) | x <- xs; y <- ys] ==> list(map(((x, y),) -> (a, b), itertools.product(xs, ys)))
/// {k: v | x <- xs} ==> dict(map(x -> (k, v), xs))
/// {y | x <- xs} ==> set(map(x -> y, xs))
/// {x <- xs | x <= 10} ==> set(filter(x -> x <= 10, xs))
@ -1763,15 +1756,16 @@ impl Desugarer {
/// ```
fn rec_desugar_comprehension(expr: Expr) -> Expr {
match expr {
Expr::Array(Array::Comprehension(mut comp)) => {
Expr::List(List::Comprehension(mut comp)) => {
debug_power_assert!(comp.generators.len(), >, 0);
if comp.generators.len() != 1 {
return Expr::Array(Array::Comprehension(comp));
return Expr::List(List::Comprehension(comp));
}
let (ident, iter) = comp.generators.remove(0);
let iterator = Self::desugar_layout_and_guard(ident, iter, comp.layout, comp.guard);
let array = if PYTHON_MODE { "list" } else { "array" };
Identifier::auto(array.into()).call1(iterator.into()).into()
Identifier::auto("list".into())
.call1(iterator.into())
.into()
}
Expr::Dict(Dict::Comprehension(mut comp)) => {
debug_power_assert!(comp.generators.len(), >, 0);

View file

@ -518,7 +518,7 @@ impl LexError {
let method = StyledStr::new("メソッド", Some(HINT), Some(ATTR));
let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR));
let newline = StyledStr::new("改行", Some(HINT), Some(ATTR));
let arr = StyledStr::new("配列", Some(HINT), Some(ATTR));
let arr = StyledStr::new("リスト", Some(HINT), Some(ATTR));
format!("予期: {method}{lit}{newline}{arr}")
},
"simplified_chinese" => {
@ -539,7 +539,7 @@ impl LexError {
let method = StyledStr::new("method", Some(HINT), Some(ATTR));
let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR));
let newline = StyledStr::new("newline", Some(HINT), Some(ATTR));
let arr = StyledStr::new("array", Some(HINT), Some(ATTR));
let arr = StyledStr::new("list", Some(HINT), Some(ATTR));
format!("expect: {method}, {lit}, {newline}, {arr}")
},
);

View file

@ -40,7 +40,7 @@ pub fn erg_parser(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(_parse, m)?)?;
let expr = PyModule::new(py, "expr")?;
expr.add_class::<ast::Literal>()?;
expr.add_class::<ast::NormalArray>()?;
expr.add_class::<ast::NormalList>()?;
expr.add_class::<ast::NormalTuple>()?;
expr.add_class::<ast::NormalDict>()?;
expr.add_class::<ast::NormalSet>()?;
@ -71,7 +71,7 @@ pub fn erg_parser(py: Python<'_>, m: &PyModule) -> PyResult<()> {
ast.add_class::<ast::TupleAttribute>()?;
ast.add_class::<ast::Subscript>()?;
ast.add_class::<ast::TypeApp>()?;
ast.add_class::<ast::NormalArray>()?;
ast.add_class::<ast::NormalList>()?;
ast.add_class::<ast::NormalTuple>()?;
ast.add_class::<ast::NormalDict>()?;
ast.add_class::<ast::NormalSet>()?;

View file

@ -135,7 +135,7 @@ enum ArgKind {
KwVar(PosArg),
}
pub enum ArrayInner {
pub enum ListInner {
Normal(Args),
WithLength(PosArg, Expr),
Comprehension {
@ -145,7 +145,7 @@ pub enum ArrayInner {
},
}
impl ArrayInner {
impl ListInner {
pub const fn comp(
layout: Option<Expr>,
generators: Vec<(Identifier, Expr)>,
@ -857,7 +857,7 @@ impl Parser {
Ok(acc)
}
fn try_reduce_array_elems(&mut self) -> ParseResult<ArrayInner> {
fn try_reduce_list_elems(&mut self) -> ParseResult<ListInner> {
debug_call_info!(self);
if self.cur_is(EOF) {
let tk = self.tokens.last().unwrap();
@ -868,7 +868,7 @@ impl Parser {
if self.cur_category_is(TC::REnclosure) {
let args = Args::empty();
debug_exit_info!(self);
return Ok(ArrayInner::Normal(args));
return Ok(ListInner::Normal(args));
}
let first = self
.try_reduce_elem()
@ -891,7 +891,7 @@ impl Parser {
self.stack_dec(fn_name!())
})?;
debug_exit_info!(self);
return Ok(ArrayInner::WithLength(elems.remove_pos(0), len));
return Ok(ListInner::WithLength(elems.remove_pos(0), len));
}
Some(PreStar) => {
self.lpop();
@ -900,7 +900,7 @@ impl Parser {
.map_err(|_| self.stack_dec(fn_name!()))?;
elems.set_var_args(PosArg::new(rest));
debug_exit_info!(self);
return Ok(ArrayInner::Normal(elems));
return Ok(ListInner::Normal(elems));
}
Some(Inclusion) => {
self.lpop();
@ -925,7 +925,7 @@ impl Parser {
.try_reduce_expr(false, false, false, false)
.map_err(|_| self.stack_dec(fn_name!()))?;
debug_exit_info!(self);
return Ok(ArrayInner::comp(None, generators, Some(guard)));
return Ok(ListInner::comp(None, generators, Some(guard)));
}
Some(VBar) => {
self.lpop();
@ -956,7 +956,7 @@ impl Parser {
None
};
debug_exit_info!(self);
return Ok(ArrayInner::comp(Some(elem), generators, guard));
return Ok(ListInner::comp(Some(elem), generators, guard));
}
Some(RParen | RSqBr | RBrace | Dedent | Comma) => {}
Some(_) => {
@ -1027,7 +1027,7 @@ impl Parser {
}
}
debug_exit_info!(self);
Ok(ArrayInner::Normal(elems))
Ok(ListInner::Normal(elems))
}
fn try_reduce_elem(&mut self) -> ParseResult<PosArg> {
@ -2601,11 +2601,11 @@ impl Parser {
Ok(expr)
}
Some(t) if t.is(LSqBr) => {
let array = self
.try_reduce_array()
let list = self
.try_reduce_list()
.map_err(|_| self.stack_dec(fn_name!()))?;
debug_exit_info!(self);
Ok(Expr::Array(array))
Ok(Expr::List(list))
}
Some(t) if t.is(LBrace) => {
match self
@ -2874,15 +2874,15 @@ impl Parser {
}
#[inline]
fn try_reduce_array(&mut self) -> ParseResult<Array> {
fn try_reduce_list(&mut self) -> ParseResult<List> {
debug_call_info!(self);
let l_sqbr = expect_pop!(self, fail_next LSqBr);
let inner = self
.try_reduce_array_elems()
.try_reduce_list_elems()
.map_err(|_| self.stack_dec(fn_name!()))?;
let r_sqbr = expect_pop!(self, fail_next RSqBr);
let arr = match inner {
ArrayInner::Normal(mut elems) => {
let lis = match inner {
ListInner::Normal(mut elems) => {
let elems = if elems
.pos_args()
.first()
@ -2896,21 +2896,21 @@ impl Parser {
} else {
elems
};
Array::Normal(NormalArray::new(l_sqbr, r_sqbr, elems))
List::Normal(NormalList::new(l_sqbr, r_sqbr, elems))
}
ArrayInner::WithLength(elem, len) => {
Array::WithLength(ArrayWithLength::new(l_sqbr, r_sqbr, elem, len))
ListInner::WithLength(elem, len) => {
List::WithLength(ListWithLength::new(l_sqbr, r_sqbr, elem, len))
}
ArrayInner::Comprehension {
ListInner::Comprehension {
layout,
generators,
guard,
} => Array::Comprehension(ArrayComprehension::new(
} => List::Comprehension(ListComprehension::new(
l_sqbr, r_sqbr, layout, generators, guard,
)),
};
debug_exit_info!(self);
Ok(arr)
Ok(lis)
}
/// Set, Dict, Record

View file

@ -1,4 +1,4 @@
#[array]#
#[list]#
[1,,]
[Nat;2;] # [Nat; 1]
a = [1: "a"] # [1: Nat]
@ -37,4 +37,4 @@ t = (1, True, "a")
t.-1
r = {name = "John Doe"; age = 21; from="Unknown"}
r.attr
r.attr

View file

@ -26,28 +26,28 @@ impl Parser {
"complex const accessor",
)),
},
Expr::Array(array) => match array {
Array::Normal(arr) => {
let (elems, ..) = arr.elems.deconstruct();
Expr::List(list) => match list {
List::Normal(lis) => {
let (elems, ..) = lis.elems.deconstruct();
let mut const_elems = vec![];
for elem in elems.into_iter() {
let const_expr = Self::validate_const_expr(elem.expr)?;
const_elems.push(ConstPosArg::new(const_expr));
}
let elems = ConstArgs::pos_only(const_elems, None);
let const_arr = ConstNormalArray::new(arr.l_sqbr, arr.r_sqbr, elems, None);
Ok(ConstExpr::Array(ConstArray::Normal(const_arr)))
let const_lis = ConstNormalList::new(lis.l_sqbr, lis.r_sqbr, elems, None);
Ok(ConstExpr::List(ConstList::Normal(const_lis)))
}
Array::WithLength(arr) => {
let elem = Self::validate_const_expr(arr.elem.expr)?;
let len = Self::validate_const_expr(*arr.len)?;
let const_arr = ConstArrayWithLength::new(arr.l_sqbr, arr.r_sqbr, elem, len);
Ok(ConstExpr::Array(ConstArray::WithLength(const_arr)))
List::WithLength(lis) => {
let elem = Self::validate_const_expr(lis.elem.expr)?;
let len = Self::validate_const_expr(*lis.len)?;
let const_lis = ConstListWithLength::new(lis.l_sqbr, lis.r_sqbr, elem, len);
Ok(ConstExpr::List(ConstList::WithLength(const_lis)))
}
other => Err(ParseError::feature_error(
line!() as usize,
other.loc(),
"const array comprehension",
"const list comprehension",
)),
},
Expr::Set(set) => match set {
@ -375,25 +375,25 @@ impl Parser {
))
}
fn array_to_array_type_spec(array: Array) -> Result<ArrayTypeSpec, ParseError> {
match array {
Array::Normal(arr) => {
fn list_to_list_type_spec(list: List) -> Result<ListTypeSpec, ParseError> {
match list {
List::Normal(lis) => {
// TODO: add hint
let err = ParseError::simple_syntax_error(line!() as usize, arr.loc());
let err = ParseError::simple_syntax_error(line!() as usize, lis.loc());
Err(err)
}
Array::WithLength(arr) => {
let t_spec = Self::expr_to_type_spec(arr.elem.expr)?;
let len = Self::validate_const_expr(*arr.len)?;
Ok(ArrayTypeSpec::new(
List::WithLength(lis) => {
let t_spec = Self::expr_to_type_spec(lis.elem.expr)?;
let len = Self::validate_const_expr(*lis.len)?;
Ok(ListTypeSpec::new(
t_spec,
len,
Some((arr.l_sqbr, arr.r_sqbr)),
Some((lis.l_sqbr, lis.r_sqbr)),
))
}
Array::Comprehension(arr) => {
List::Comprehension(lis) => {
// TODO: add hint
let err = ParseError::simple_syntax_error(line!() as usize, arr.loc());
let err = ParseError::simple_syntax_error(line!() as usize, lis.loc());
Err(err)
}
}
@ -508,9 +508,9 @@ impl Parser {
let lambda = Self::lambda_to_subr_type_spec(lambda)?;
Ok(TypeSpec::Subr(lambda))
}
Expr::Array(array) => {
let array = Self::array_to_array_type_spec(array)?;
Ok(TypeSpec::Array(array))
Expr::List(list) => {
let list = Self::list_to_list_type_spec(list)?;
Ok(TypeSpec::List(list))
}
Expr::Set(set) => {
let set = Self::set_to_set_type_spec(set)?;

View file

@ -52,7 +52,7 @@ Returns the class of `object`.
However, since classes cannot be compared, use `object in Class` instead of `classof(object) == Class` if you want to judge instances.
The structure type determined at compile time is obtained with `Typeof`.
## Iterator, Array generation system
## Iterator, List generation system
### repeat|T|(x: T) -> RepeatIterator T
@ -96,11 +96,11 @@ match jan:
_ -> log "Other"
```
### Inherit
Inherit classes. You can use the methods of the parent class ('Super') as is. The second parameter 'Layout' can specify a new layout.
It must be 'Super.Base:> Layout'.
```python
@ Inheritable
C = Class {i = Int}

View file

@ -20,5 +20,5 @@ Infers a function given its arguments and return value.
```python
1.guess((1,), 2) # <Int.__add__ method>
[1, 2].guess((3, 4), [1, 2, 3, 4]) # <Array(T, N).concat method>
```
[1, 2].guess((3, 4), [1, 2, 3, 4]) # <List(T, N).concat method>
```

View file

@ -1,4 +1,4 @@
# Array! T, N
# List! T, N
Variable length array at compile time. `[t; n]` There is also a sugar cane syntax.
@ -11,17 +11,14 @@ Variable length array at compile time. `[t; n]` There is also a sugar cane synta
* sample!(ref! self) -> T
* sample! ref! self, M: Nat -> [T; M]
Select a random element and return a copy.
* shuffle!(ref! self)
Shuffle contents.
* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic
Verify length
Incorrect length will cause `panic`

View file

@ -1,4 +1,4 @@
# Array T: Type, N: Nat
# List T: Type, N: Nat
`[T; N]` is syntactic sugar. `N` can be emitted (`[T; _]`).
@ -23,7 +23,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
assert all(False for _in[])
```
## methods of Array T, N | T <: Eq
## methods of List T, N | T <: Eq
* freq self -> [{T: Nat}]
Returns the frequency of occurrence of an object.

View file

@ -10,7 +10,7 @@
## impl classes
* `Array`
* `List`
* `Tuple`
* `Str`
* `Range`

View file

@ -1,4 +1,4 @@
# Hashable
# Hash
## required methods

View file

@ -16,7 +16,7 @@
## impl classes
* `Array`
* `List`
* `Tuple`
* `Str`
* `Range`

View file

@ -30,10 +30,10 @@ It succeeds only if the only type with `co_consts` in the namespace is `Code` (o
Erg closes function type checking within a module, so even if a type with `co_consts` is defined outside the module, passing an instance of it to the `consts` function will result in an error (to make this possible, you must use `Structural`, described below). This constraint allows the `consts` function to infer.
When a class attribute is defined, the type inferrer keeps track of the "attribute" and "defining class, attribute type" pairs.
In the case of ``co_consts``, this pair is `{co_consts: {Code, Array(Obj, _)}}`.
In the case of ``co_consts``, this pair is `{co_consts: {Code, List(Obj, _)}}`.
```erg
method_to_classes: {co_consts: [{Code, Array(Obj, _)}], real: [{Int, Int}], times!: [{Nat, (self: Nat, proc!: () => NoneType) => NoneType}], ...}
method_to_classes: {co_consts: [{Code, List(Obj, _)}], real: [{Int, Int}], times!: [{Nat, (self: Nat, proc!: () => NoneType) => NoneType}], ...}
```
Note that the value of the key-value pair is an array. Only if this array is of length 1, or has the smallest type element, the key is uniquely determined (otherwise a type error will occur).
@ -41,11 +41,11 @@ Note that the value of the key-value pair is an array. Only if this array is of
Once the key is identified, the definition type is back-propagated to the type of ``?2``.
```erg
?2(<: Code).co_consts: Array(Obj, _)
?2(<: Code).co_consts: List(Obj, _)
```
Finally, the type of `consts` is `Code -> Array(Obj, _)`.
Finally, the type of `consts` is `Code -> List(Obj, _)`.
```erg
consts(c: Code): Array(Obj, _) = c.co_consts
consts(c: Code): List(Obj, _) = c.co_consts
```

View file

@ -25,7 +25,7 @@ AST(Module[
body: Block[
Unary Op {
op: "!",
expr: Array([]),
expr: List([]),
},
],
},
@ -82,7 +82,7 @@ HIR(Module[
body: Block[
expr: UnaryOp{
op: "!",
expr: Array([]),
expr: List([]),
t: [0..10, 0]!,
},
],

View file

@ -50,19 +50,19 @@ The specific operations are as follows.
line 1. Def{sig: v, block: ![]}
get block type:
get UnaryOp type:
getArray type: `['T; 0]`
getList type: `['T; 0]`
instantiate: `[?T; 0]`
(substitute, eval are omitted)
result: `Γ: {v: [?T; 0]!}`
expr returns `NoneType`: OK
line 2. CallMethod {obj: v, name: push!, args: [1]}
get obj type: `Array!(?T, 0)`
search: Array!(?T, 0).push!(Nat)`
get: `Array!('T ~> 'T, 'N ~> 'N+1).push!: 'T => NoneType`
instantiate: `Array!(?T, ?N).push!(?T) => NoneType`
substitute(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!: Nat => NoneType`
eval: `Array!(Nat, 0 ~> 1).push!: Nat => NoneType`
get obj type: `List!(?T, 0)`
search: List!(?T, 0).push!(Nat)`
get: `List!('T ~> 'T, 'N ~> 'N+1).push!: 'T => NoneType`
instantiate: `List!(?T, ?N).push!(?T) => NoneType`
substitute(`S: {?T --> Nat, ?N --> 0}`): `List!(Nat ~> Nat, 0 ~> 0+1).push!: Nat => NoneType`
eval: `List!(Nat, 0 ~> 1).push!: Nat => NoneType`
result: `Γ: {v: [Nat; 1]!}`
expr returns `NoneType`: OK

View file

@ -21,8 +21,8 @@ In fact, there is (very confusingly) a right-sided value on the left side of `=`
There can even be a left-side value within a right-side value.
```python
# i is the left-hand side value, Array(Int) and [1, 2, 3] are the right-hand side values
i: Array(Int) = [1, 2, 3]
# i is the left-hand side value, List(Int) and [1, 2, 3] are the right-hand side values
i: List(Int) = [1, 2, 3]
# `[1, 2, 3].iter().map i -> i + 1` is the right-hand side value, but i to the left of -> is the left-hand side value
a = [1, 2, 3].iter().map i -> i + 1
# {x = 1; y = 2} is the right side value, but x, y are the left side values

View file

@ -35,10 +35,10 @@ Also, input that is valid according to the specification but deemed undesirable
## Why doesn't Tuple have a constructor (`__call__`)?
Erg tuples must have a compile-time length. Therefore, a tuple is constructed almost only by a tuple literal.
If the length is not known until runtime, an immutable array (`Array`) can be used instead.
If the length is not known until runtime, an immutable array (`List`) can be used instead.
```erg
arr = Array map(int, input!().split " ")
arr = List map(int, input!().split " ")
```
## I got runtime errors in Erg that I did not get in Python. What could be the cause?

View file

@ -70,7 +70,7 @@ assert 1e-10 == 0.0000000001
Each of these literals has its own documentation describing them separately, so please refer to that documentation for details.
### [Array Literal](./10_array.md)
### [List Literal](./10_list.md)
```python
[], [1], [1, 2, 3], ["1", "2",], ...
@ -100,7 +100,7 @@ Each of these literals has its own documentation describing them separately, so
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, ...
```
As a difference from `Array` literals, duplicate elements are removed in `Set`.
As a difference from `List` literals, duplicate elements are removed in `Set`.
```python
assert {1, 2, 1} == {1, 2}

View file

@ -29,7 +29,7 @@ l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed
```python
# OK
l1 = [1, 2, 3]
l2 = l1.clone()
l2 = l1
```
It is also not possible to reassign to a variable. The syntax that can be used instead, to hold mutable states, are described later.

View file

@ -28,7 +28,7 @@ C!.
x
```
Procedural methods can also take [ownership](./19_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
Procedural methods can also take [ownership](./20_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
```python,compile_fail
n = 1

View file

@ -10,5 +10,5 @@ Although in pure Erg semantics no difference can be found between objects with t
```
<p align='center'>
<a href='./08_procedure.md'>Previous</a> | <a href='./10_array.md'>Next</a>
<a href='./08_procedure.md'>Previous</a> | <a href='./10_list.md'>Next</a>
</p>

View file

@ -1,6 +1,6 @@
# Array
# List
Arrays are the most basic __collection (aggregate)__.
A list is the most basic __collection (aggregate)__.
A collection is an object that can hold multiple objects inside it.
```python
@ -14,7 +14,7 @@ mut_a[0].inc!()
assert mut_a == [2, 2, 3]
```
As a rule, arrays cannot contain objects of different types.
As a rule, lists cannot contain objects of different types.
```python,compile_fail
[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str
@ -23,12 +23,12 @@ As a rule, arrays cannot contain objects of different types.
However, you can bypass the restriction by explicitly specifying the type like this.
```python
[1: Int or Str, "a"]
[1, "a"]: [Int or Str; 2]
```
## Slice
An array can also have multiple values taken out at once. This is called slicing.
A list can also have multiple values taken out at once. This is called slicing.
```python
l = [1, 2, 3, 4]
@ -41,7 +41,7 @@ assert l[1..1] == [2]
assert l[..].step(2) == [2, 4]
```
The object obtained by slicing is an (immutable) copy to an array.
The object obtained by slicing is an (immutable) copy to a list.
```python
print! Typeof l[1..2] # [Int; 4]

View file

@ -7,7 +7,7 @@ ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
assert ids["Alice"] == 145
```
The key does not have to be a string if it is a `Hashable` object.
The key does not have to be a string if it is a `Hash` object.
```python
# deprecated to use a range object as a key (confused with slice)
@ -73,5 +73,5 @@ x = "a"
```
<p align='center'>
<a href='./10_array.md'>Previous</a> | <a href='./12_container_ownership.md'>Next</a>
</p>
<a href='./10_list.md'>Previous</a> | <a href='./12_container_ownership.md'>Next</a>
</p>

View file

@ -32,22 +32,22 @@ The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind i
```python
assert [1, 2, 3] in Iterable(Int)
assert 1..3 in Iterable(Int)
assert [1, 2, 3].Iterator == ArrayIterator
assert [1, 2, 3].Iterator == ListIterator
assert (1..3).Iterator == RangeIterator
log [1, 2, 3].iter() # <ArrayIterator object
log [1, 2, 3].iter() # <ListIterator object
log (1..3).iter() # <RangeIterator object>
```
Both `ArrayIterator` and `RangeIterator` are classes that implement `Iterator` and exist only to give `Array` and `Range` iteration functions.
Both `ListIterator` and `RangeIterator` are classes that implement `Iterator` and exist only to give `List` and `Range` iteration functions.
Such a design pattern is called companion class [<sup id="f1">1</sup>](#1).
And the `IteratorImpl` patch is the core of the iteration functionality. `Iterator` requires only one `.next` method, `IteratorImpl` provides dozens of methods indeed. `ArrayIterator` and `RangeIterator` can use the implementation method of `IteratorImpl` just by implementing the `.next` method. For this convenience, the standard library implements a number of iterators.
And the `IteratorImpl` patch is the core of the iteration functionality. `Iterator` requires only one `.next` method, `IteratorImpl` provides dozens of methods indeed. `ListIterator` and `RangeIterator` can use the implementation method of `IteratorImpl` just by implementing the `.next` method. For this convenience, the standard library implements a number of iterators.
```mermaid
classDiagram
class Array~T~ {
class List~T~ {
...
iter() ArrayIterator~T~
iter() ListIterator~T~
}
class Range~T~ {
...
@ -57,10 +57,10 @@ classDiagram
<<trait>>
iter() Iterator~T~
}
Iterable~T~ <|.. Array~T~: Impl
Iterable~T~ <|.. List~T~: Impl
Iterable~T~ <|.. Range~T~: Impl
class ArrayIterator~T~ {
array: Array~T~
class ListIterator~T~ {
list: List~T~
next() T
}
class RangeIterator~T~ {
@ -71,10 +71,10 @@ classDiagram
<<trait>>
next() T
}
Iterator~T~ <|.. ArrayIterator~T~: Impl
Iterator~T~ <|.. ListIterator~T~: Impl
Iterator~T~ <|.. RangeIterator~T~: Impl
Array <-- ArrayIterator
List <-- ListIterator
Range <-- RangeIterator
```

View file

@ -31,7 +31,7 @@ print! id! _a # 0x000002A798DFE980
The `id!` procedure returns the address in memory where the object resides.
`b` is a `Nat` "dynamic" array. The content of the object changes, but the variables point to the same thing.
`b` is a `Nat` "dynamic" list. The content of the object changes, but the variables point to the same thing.
```python
b = ![1, 2, 3]

View file

@ -36,11 +36,11 @@ A subroutine that needs to duplicate an object is said to be an "argument consum
```python
capitalize s: Str!=
s. capitalize!()
s.capitalize!()
s
s1 = !"hello"
s2 = capitalize s1.clone()
s2 = capitalize s1.copy()
log s2, s1 # !"HELLO hello"
```

View file

@ -41,7 +41,7 @@ Call `.clone` if you want the contents of the mutable object at the time the fun
```python
i = !0
immut_i = i.clone().freeze()
immut_i = i.copy().freeze()
fx = immut_i + x
assert f 1 == 1
i.add! 1

View file

@ -23,7 +23,7 @@ fn: Int -> Int = x -> x + 1
# higher-order type
a: [Int; 4] = [0, 1, 2, 3]
# or
a: Array Int, 4 = [0, 1, 2, 3]
a: List Int, 4 = [0, 1, 2, 3]
```
### Literal patterns
@ -66,8 +66,8 @@ name = match num:
```python,checker_ignore
# these two are the same
Array(T, N: {N | N >= 3})
Array(T, N | N >= 3)
List(T, N: {N | N >= 3})
List(T, N | N >= 3)
f M, N | M >= 0, N >= 1 = ...
f(1, 0) # TypeError: N (2nd parameter) must be 1 or more
@ -106,7 +106,7 @@ m, n = 1, 2
f(x, y) = ...
```
### array pattern
### list pattern
```python
[i, j] = [1, 2]

View file

@ -1,6 +1,6 @@
# Comprehension
You can create an Array with `[(expr |)? (name <- iterable;)+ (| predicate)?]`,
You can create an List with `[(expr |)? (name <- iterable;)+ (| predicate)?]`,
a set with `{(expr |)? (name <- iterable;)+ (| predicate)?}`,
a Dict with `{(key: value |)? (name <- iterable;)+ (| predicate)?}`.

View file

@ -17,14 +17,14 @@ log rand # 0.2597...
1+1*2 |>.times do log("a", end := "") # aaa
evens = 1..100 |>.iter() |>.filter i -> i % 2 == 0 |>.collect Array
evens = 1..100 |>.iter() |>.filter i -> i % 2 == 0 |>.collect List
# When implemented without the pipeline operator,
_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)
_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(List)
# or
__evens = 1..100 \
.iter() \
.filter i -> i % 2 == 0 \
.collect Array
.collect List
```
<p align='center'>

View file

@ -15,7 +15,7 @@ This file is for generating The Erg Book. Do not add badges, etc.
- [Side effects and procedures](./07_side_effect.md)
- [Procedures](./08_procedure.md)
- [Built-in procedure](./09_builtin_procs.md)
- [Array](./10_array.md)
- [List](./10_list.md)
- [Dict](./11_dict.md)
- [Subscript (index access)](./12_container_ownership.md)
- [Tuple](./13_tuple.md)

View file

@ -8,17 +8,17 @@ Also, see [here](../terms.md) for terminology.
* ! → [side&nbsp;effect](./07_side_effect.md)
* !-type → [mutable&nbsp;type](./type/18_mut.md)
* ? → [error&nbsp;handling](./31_error_handling.md)
* &#35; → [Str](./00_basic.md/#comments)
* ? → [error&nbsp;handling](./32_error_handling.md)
* &#35; → [Str](./00_basic.md#comments)
* $ → [shared](./type/advanced/shared.md)
* %
* &
* &&
* [&prime;&nbsp;(single&nbsp;quote)](./21_naming_rule.md#literal-identifiers)
* [&prime;&nbsp;(single&nbsp;quote)](./22_naming_rule.md#literal-identifiers)
* [&quot;&nbsp;(double&nbsp;quote)](./01_literal.md#str-literal)
* &lpar;&rpar; → [Tuple](./13_tuple.md)
* &ast;
* &ast; → [*-less&nbsp;multiplication](./01_literal.md/#less-multiplication)
* &ast; → [*-less&nbsp;multiplication](./01_literal.md#less-multiplication)
* &plus; (prefix) → [operator](./06_operator.md)
* &plus;_ → &plus; (prefix)
* &plus; (infix) → [operator](./06_operator.md)
@ -28,42 +28,42 @@ Also, see [here](../terms.md) for terminology.
* &minus;_ → &minus; (prefix)
* &minus; (infix) → [operator](./06_operator.md)
* &minus; (infix) → [Trait](./type/03_trait.md)
* &minus;> → [anonymous&nbsp;function](./22_lambda.md)
* . → [Visibility](./20_visibility.md)
* .. → [closed range operator](./01_literal.md/#range-object)
* ..< → [right-open range operator](./01_literal.md/#range-object)
* &minus;> → [anonymous&nbsp;function](./23_lambda.md)
* . → [Visibility](./21_visibility.md)
* .. → [closed range operator](./01_literal.md#range-object)
* ..< → [right-open range operator](./01_literal.md#range-object)
* ...
* ... → [Extract&nbsp;assignment](./29_spread_syntax.md#extract-assignment)
* ... → [Extract&nbsp;assignment](./30_spread_syntax.md#extract-assignment)
* ... → [Variable-length arguments](./04_function.md#variable-length-arguments)
* /
* :
* : → [Colon&nbsp;application&nbsp;style](./04_function.md)
* : → [Type ascription](./03_declaration.md)
* : → [Keyword&nbsp;arguments](./04_function.md)
* :: → [private variable modifier](./20_visibility.md)
* :: → [private variable modifier](./21_visibility.md)
* := → [default&nbsp;parameters](./04_function.md)
* ;
* &lt;
* &lt;: → [Subtype&nbsp;specification](./type/02_basic.md)
* &lt;&lt;
* &lt;=
* &lt;.. → [left-open range operator](./01_literal.md/#range-object)
* &lt;..&lt; → [open range operator](./01_literal.md/#range-object)
* = → [Variable](./20_visibility.md)
* &lt;.. → [left-open range operator](./01_literal.md#range-object)
* &lt;..&lt; → [open range operator](./01_literal.md#range-object)
* = → [Variable](./21_visibility.md)
* ==
* => → [anonymous procedure operator](./08_procedure.md)
* &gt;
* &gt;&gt;
* &gt;=
* @ → [decorator](./30_decorator.md)
* [] → [Array](./10_array.md)
* @ → [decorator](./31_decorator.md)
* [] → [List](./10_list.md)
* \ → [Escaping](./00_basic.md)
* ^
* ^^
* _ → [Type&nbsp;erasure](./type/advanced/erasure.md)
* &#95;+&#95;&plus; (infix)
* &#95;-&#95;&minus; (infix)
* [``&nbsp;(back&nbsp;quote)](./23_subroutine.md#operator)
* [``&nbsp;(back&nbsp;quote)](./24_subroutine.md#operator)
* {}
* [{} type](./type/01_type_system.md)
* {=} → [Type&nbsp;System](./type/01_type_system.md#classification)
@ -83,11 +83,11 @@ Also, see [here](../terms.md) for terminology.
* [algebraic&nbsp;type](./type/13_algebraic.md)
* [And]
* [and]
* [anonymous&nbsp;function](./22_lambda.md)
* [anonymous&nbsp;function](./23_lambda.md)
* anonymous type → [Type&nbsp;system](./type/01_type_system.md)
* [Array](./10_array.md)
* [List](./10_list.md)
* assert
* [Attach](./30_decorator.md#attach)
* [Attach](./31_decorator.md#attach)
* [attribute](type/09_attributive.md)
* [Attribute&nbsp;definitions](./type/02_basic.md#attribute-definitions)
* [Attribute&nbsp;type](./type/09_attributive.md)
@ -96,7 +96,7 @@ Also, see [here](../terms.md) for terminology.
* [Bool, Boolean](./01_literal.md#boolean-object)
* [Boolean&nbsp;object](./01_literal.md#boolean-object)
* [borrowing](./19_ownership.md#borrow)
* [borrowing](./20_ownership.md#borrow)
### C
@ -104,24 +104,24 @@ Also, see [here](../terms.md) for terminology.
* [Comments](./00_basic.md#comments)
* [Complex&nbsp;object](./01_literal.md#complex-object)
* [Compile-time&nbsp;functions](./04_function.md#compile-time-functions)
* [circular&nbsp;references](./19_ownership.md#circular-references)
* [circular&nbsp;references](./20_ownership.md#circular-references)
* [Class](./type/04_class.md)
* [Class&nbsp;relationship](./type/04_class.md#class-relationships)
* [Class&nbsp;upcasting](./type/16_subtyping.md#class-upcasting)
* [Colon&nbsp;application&nbsp;style](./04_function.md#colon-application-style)
* [Closure](./24_closure.md)
* [Closure](./25_closure.md)
* [Compound literals](./01_literal.md#compound-literals)
* [Complement](./type/13_algebraic.md#complement)
* [Comprehension](./28_comprehension.md)
* [constant](./18_mutability.md#constant)
* [Comprehension](./29_comprehension.md)
* [constant](./19_mutability.md#constant)
* [Constants](./02_name.md#constants)
* [Context](./31_error_handling.md#context)
* [Context](./32_error_handling.md#context)
### D
* [Data&nbsp;type](./type/01_type_system.md#data-type)
* [Declaration](./03_declaration.md)
* [decorator](./30_decorator.md)
* [decorator](./31_decorator.md)
* [Default&nbsp;parameters](./04_function.md#default-parameters)
* [Del](./02_name.md#delete-an-variable)
* [Dependent&nbsp;type](./type/14_dependent.md)
@ -137,10 +137,10 @@ Also, see [here](../terms.md) for terminology.
* [Enum&nbsp;class](./type/04_class.md#enum-class)
* [Enum&nbsp;type](./type/11_enum.md)
* [Enumerated,&nbsp;Interval&nbsp;and&nbsp;Refinement&nbsp;types](./type/12_refinement.md#enumerated-interval-and-refinement-types)
* [error&nbsp;handling](./31_error_handling.md)
* [error&nbsp;handling](./32_error_handling.md)
* [Existential&nbsp;type](./type/advanced/existential.md)
* [Exponential&nbsp;literal](./01_literal.md#exponential-literal)
* [Extract&nbsp;assignment](./29_spread_syntax.md#extract-assignment)
* [Extract&nbsp;assignment](./30_spread_syntax.md#extract-assignment)
### F
@ -148,14 +148,14 @@ Also, see [here](../terms.md) for terminology.
* [Float&nbsp;object](./01_literal.md#float-object)
* [for](./05_builtin_funcs.md#for)
* [For-All&nbsp;patch](./type/07_patch.md#for-all-patch)
* [freeze](./19_ownership.md#freeze)
* [freeze](./20_ownership.md#freeze)
* [Function](./04_function.md)
* [Function&nbsp;definition&nbsp;with&nbsp;multiple patterns](./04_function.md#function-definition-with-multiple-patterns)
### G
* [GADTs(Generalized&nbsp;Algebraic&nbsp;Data&nbsp;Types)](./type/advanced/GADTs.md)
* [Generator](./35_generator.md)
* [Generator](./36_generator.md)
* [Glue&nbsp;Patch](./type/07_patch.md#glue-patch)
### H
@ -166,19 +166,19 @@ Also, see [here](../terms.md) for terminology.
* [id](./09_builtin_procs.md#id)
* [if](./05_builtin_funcs.md#if)
* [import](./34_package_system.md)
* [impl](./30_decorator.md#impl)
* [import](./35_package_system.md)
* [impl](./31_decorator.md#impl)
* in
* [Indention](./00_basic.md#indentation)
* [Instant&nbsp;block](./14_record.md#instant-block)
* [Instance/class&nbsp;attributes](./type/04_class.md#instance-and-class-attributes)
* [inheritable](./30_decorator.md#inheritable)
* [inheritable](./31_decorator.md#inheritable)
* [inheritance](./type/05_inheritance.md)
* [Int](./01_literal.md)
* [Integration&nbsp;with&nbsp;Python](./33_integration_with_Python.md)
* [Integration&nbsp;with&nbsp;Python](./34_integration_with_Python.md)
* [Interval&nbsp;Type](./type/10_interval.md)
* [Intersection](./type/13_algebraic.md#intersection)
* [Iterator](./17_iterator.md)
* [Iterator](./18_iterator.md)
### J
@ -189,22 +189,22 @@ Also, see [here](../terms.md) for terminology.
### L
* lambda → [anonymous&nbsp;function](./22_lambda.md)
* lambda → [anonymous&nbsp;function](./23_lambda.md)
* let-polymorphism → [rank&nbsp;1&nbsp;polymorphism]
* [Literal&nbsp;Identifiers](./21_naming_rule.md#literal-identifiers)
* [Literal&nbsp;Identifiers](./22_naming_rule.md#literal-identifiers)
### M
* match
* [Marker&nbsp;trait](./type/advanced/marker_trait.md)
* [Method](./07_side_effect.md#methods)
* Modifier → [decorator](./30_decorator.md)
* [module](./25_module.md)
* Modifier → [decorator](./31_decorator.md)
* [module](./26_module.md)
* [Multiple&nbsp;inheritance](type/05_inheritance.md#multiple-inheritance)
* [Multi-layer&nbsp;(multi-level)&nbsp;Inheritance](type/05_inheritance.md#multi-layer-multi-level-inheritance)
* [Mutable&nbsp;type](./type/18_mut.md)
* [Mutable&nbsp;structure&nbsp;type](./type/advanced/mut_struct.md)
* [Mutability](./18_mutability.md)
* [Mutability](./19_mutability.md)
### N
@ -220,28 +220,28 @@ Also, see [here](../terms.md) for terminology.
### O
* [Object](./26_object_system.md)
* [Object](./27_object_system.md)
* [Option]
* [Or]
* [or]
* [Ord]
* [ownership&nbsp;system](./19_ownership.md)
* [ownership&nbsp;system](./20_ownership.md)
* [Overloading](./type/advanced/overloading.md)
* [Overriding](./type/05_inheritance.md#overriding)
* [Override&nbsp;in&nbsp;trait](./type/03_trait.md#override-in-trait)
### P
* [Panic](./31_error_handling.md#panic)
* [Panic](./32_error_handling.md#panic)
* [Patch](./type/07_patch.md)
* [Pattern&nbsp;match](./27_pattern_matching.md)
* [Pattern&nbsp;match](./28_pattern_matching.md)
* [Phantom&nbsp;class](./type/advanced/phantom.md)
* [pipeline&nbsp;operator](./32_pipeline.md)
* [pipeline&nbsp;operator](./33_pipeline.md)
* [Predicate](./type/19_bound.md#predicate)
* print!
* [Procedures](./08_procedure.md)
* [Projection&nbsp;type](./type/advanced/projection.md)
* Python → [Integration&nbsp;with&nbsp;Python](./33_integration_with_Python.md)
* Python → [Integration&nbsp;with&nbsp;Python](./34_integration_with_Python.md)
### Q
@ -257,9 +257,9 @@ Also, see [here](../terms.md) for terminology.
* [Recursive&nbsp;functions](./04_function.md#recursive-functions)
* [Refinement&nbsp;pattern](./type/12_refinement.md#refinement-pattern)
* [Refinement&nbsp;type](./type/12_refinement.md)
* [replication](./19_ownership.md#replication)
* [replication](./20_ownership.md#replication)
* [Replacing&nbsp;traits](./type/05_inheritance.md#replacing-traits-or-what-looks-like-it)
* Result → [error&nbsp;handling](./31_error_handling.md)
* Result → [error&nbsp;handling](./32_error_handling.md)
### S
@ -269,9 +269,9 @@ Also, see [here](../terms.md) for terminology.
* [Shared&nbsp;reference](./type/advanced/shared.md)
* [side-effect](./07_side_effect.md)
* [Smart&nbsp;cast](./type/12_refinement.md#smart-cast)
* [Spread&nbsp;assignment](./29_spread_syntax.md)
* [Spread&nbsp;assignment](./30_spread_syntax.md)
* [special&nbsp;type&nbsp;variables](./type/advanced/special.md#special-type-variables)
* [Stack&nbsp;trace](./31_error_handling.md#stack-trace)
* [Stack&nbsp;trace](./32_error_handling.md#stack-trace)
* [Structure&nbsp;type](./type/01_type_system.md#structure-type-anonymous-type)
* [Structural&nbsp;patch](./type/07_patch.md#structural-patch)
* [Structural&nbsp;trait](./type/03_trait.md#structural-traits)
@ -282,11 +282,11 @@ Also, see [here](../terms.md) for terminology.
* [Subtyping&nbsp;of&nbsp;subroutines](./type/16_subtyping.md#subtyping-of-subroutines)
* [Subtype&nbsp;specification](./type/02_basic.md#subtype-specification)
* [Subtyping&nbsp;of&nbsp;polymorphic&nbsp;function types](./type/15_quantified.md#subtyping-of-polymorphic-function-types)
* [Subroutine&nbsp;signatures](./23_subroutine.md)
* [Subroutine&nbsp;signatures](./24_subroutine.md)
### T
* [Test](./30_decorator.md#test)
* [Test](./31_decorator.md#test)
* [Traits](./type/03_trait.md)
* [Trait&nbsp;inclusion](./type/03_trait.md#trait-inclusion)
* True → [Boolean&nbsp;object](./01_literal.md#boolean-object)

View file

@ -222,7 +222,7 @@ right(_, r) = r
### Variable length patterns
Used in combination with the tuple/array/record pattern described later.
Used in combination with the tuple/list/record pattern described later.
```python
[i, *j] = [1, 2, 3, 4]
@ -240,7 +240,7 @@ assert first(1, 2, 3) == 1
m, n = 1, 2
```
### Array pattern
### List pattern
```python
length [] = 0

View file

@ -45,14 +45,14 @@ In Erg, the nominal types are classes and traits. When we simply say class/trait
The type for the entire nominal type (`NominalType`) and the type for the entire structural type (`StructuralType`) are subtypes of the type for the entire type (`Type`).
Erg can pass arguments (type arguments) to the type definition. An `Option`, `Array`, etc. with type arguments are called a polynomial kind. These are not themselves types, but they become types by applying arguments. Types such as `Int`, `Str`, etc., which have no arguments, are called simple types (scalar types).
Erg can pass arguments (type arguments) to the type definition. An `Option`, `List`, etc. with type arguments are called a polynomial kind. These are not themselves types, but they become types by applying arguments. Types such as `Int`, `Str`, etc., which have no arguments, are called simple types (scalar types).
A type can be regarded as a set, and there is an inclusion relation. For example, `Num` contains `Add`, `Sub`, etc., and `Int` contains `Nat`.
The upper class of all classes is `Object == Class {:}` and the lower class of all types is `Never == Class {}`. This is described below.
## Types
A type like `Array T` can be regarded as a function of type `Type -> Type` that takes type `T` as an argument and returns type `Array T` (also called Kind in type theory). Types like `Array T` are specifically called polymorphic types, and `Array` itself is called unary Kind.
A type like `List T` can be regarded as a function of type `Type -> Type` that takes type `T` as an argument and returns type `List T` (also called Kind in type theory). Types like `List T` are specifically called polymorphic types, and `List` itself is called unary Kind.
The type of a function whose argument and return types are known is denoted as `(T, U) -> V`. If you want to specify an entire two-argument function of the same type, you can use `|T| (T, T) -> T`, and if you want to specify an entire N-argument function, you can use `Func N`. However, the `Func N` type has no information about the number of arguments or their types, so all return values are of type `Obj` when called.
@ -60,7 +60,7 @@ The `Proc` type is denoted as `() => Int` and so on. Also, the name of the `Proc
A `Method` type is a function/procedure whose first argument is the object `self` to which it belongs (by reference). For dependent types, you can also specify the type of yourself after the method is applied. This is `T!(!N)` type and `T!(N ~> N-1). () => Int` and so on.
Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class that contains three objects of type `Int`.
Erg's array (List) is what Python calls a list. `[Int; 3]` is an array class that contains three objects of type `Int`.
> __Note__: `(Type; N)` is both a type and a value, so it can be used like this.
>
@ -113,7 +113,7 @@ Since types are also objects, there are attributes on the types themselves. Such
As mentioned earlier, a "type" in Erg roughly means a set of objects.
The following is a definition of the `Add` type, which requires `+` (the middle operator). `R, O` are the so-called type parameters, which can be a true type (class) such as `Int` or `Str`. In other languages, type parameters are given a special notation (generics, templates, etc.), but in Erg they can be defined just like normal parameters.
Type parameters can also be used for types other than type objects. For example, the array type `[Int; 3]` is a syntax sugar for `Array Int, 3`. If the type implementations overlap, the user must explicitly choose one.
Type parameters can also be used for types other than type objects. For example, the array type `[Int; 3]` is a syntax sugar for `List Int, 3`. If the type implementations overlap, the user must explicitly choose one.
```python
Add R = Trait {

View file

@ -15,11 +15,11 @@ Type specifications are more useful when defining subroutines and types.
```python
# Type specification for parameters
f x, y: Array Int = ...
T X, Y: Array Int = ...
f x, y: List Int = ...
T X, Y: List Int = ...
```
Note that in the above case, `x, y` are both `Array Int`.
Note that in the above case, `x, y` are both `List Int`.
```python
# The value of a capital variable must be a constant expression
@ -137,7 +137,7 @@ Types can be aliased. This allows long types, such as record types, to be shorte
Id = Int
Point3D = {x = Int; y = Int; z = Int}
IorS = Int or Str
Vector = Array Int
Vector = List Int
```
Also, when displaying errors, the compiler will use aliases for composite types (in the above example, right-hand-side types other than the first) if they are defined.
@ -150,8 +150,8 @@ The purpose is also to prevent adding aliases on top of types that already have
Id = Int
UserId = Int # TypeWarning: duplicate aliases: Id and UserId
Ids = Array Id
Ints = Array Int # TypeWarning: duplicate aliases: Isd and Ints
Ids = List Id
Ints = List Int # TypeWarning: duplicate aliases: Isd and Ints
IorS = Int or Str
IorSorB = IorS or Bool

View file

@ -77,7 +77,7 @@ Trait is also a type, so it can be used for normal type specification.
```python
points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)]
assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25].
assert points.iter().map(x -> x.norm()).collect(List) == [5, 25].
```
## Trait inclusion
@ -151,11 +151,11 @@ Mapper T: Type = Trait {
.map = (self: Self, T -> U) -> Self.MapIter U
}
# ArrayIterator <: Mapper
# ArrayIterator.MapIter == ArrayMapper
# [1, 2, 3].iter(): ArrayIterator Int
# [1, 2, 3].iter().map(x -> "\{x}"): ArrayMapper Str
assert [1, 2, 3].iter().map(x -> "\{x}").collect(Array) == ["1", "2", "3"].
# ListIterator <: Mapper
# ListIterator.MapIter == ListMapper
# [1, 2, 3].iter(): ListIterator Int
# [1, 2, 3].iter().map(x -> "\{x}"): ListMapper Str
assert [1, 2, 3].iter().map(x -> "\{x}").collect(List) == ["1", "2", "3"].
```
## Override in Trait

View file

@ -12,7 +12,7 @@ Value = (
or Bool
or Str
or NoneType
or Array Const
or List Const
or Tuple Const
or Set Const
or ConstFunc(Const, _)

View file

@ -10,8 +10,8 @@ Nat = 0.. _
Odd = {N: Int | N % 2 == 1}
Char = StrWithLen 1
# StrWithLen 1 == {_: StrWithLen N | N == 1}
[Int; 3] == {_: Array Int, N | N == 3}
Array3OrMore == {A: Array _, N | N >= 3}
[Int; 3] == {_: List Int, N | N == 3}
List3OrMore == {A: List _, N | N >= 3}
```
When there are multiple preds, they can be separated by `;` or `and` or `or`. `;` and `and` mean the same thing.
@ -83,7 +83,7 @@ Just as `_: {X}` can be rewritten as `X` (constant pattern), `_: {X: T | Pred}`
```python
# method `.m` is defined for arrays of length 3 or greater
Array(T, N | N >= 3)
List(T, N | N >= 3)
.m(&self) = ...
```

View file

@ -3,7 +3,7 @@
Dependent types are a feature that can be said to be the biggest feature of Erg.
A dependent type is a type that takes a value as an argument. Ordinary polymorphic types can take only types as arguments, but dependent types relax that restriction.
Dependent types are equivalent to `[T; N]` (`Array(T, N)`).
Dependent types are equivalent to `[T; N]` (`List(T, N)`).
This type is determined not only by the content type `T` but also by the number of contents `N`. `N` contains an object of type `Nat`.
```python
@ -67,7 +67,7 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!()
You can also embed or inherit existing types to create dependent types.
```python
MyArray(T, N) = Inherit[T; N]
MyList(T, N) = Inherit[T; N]
# The type of self: Self(T, N) changes in conjunction with .array
MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
@ -75,4 +75,4 @@ MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
<p align='center'>
<a href='./13_algebraic.md'>Previous</a> | <a href='./15_quantified.md'>Next</a>
</p>
</p>

View file

@ -99,7 +99,7 @@ Iterator T = Trait {
}
it = [1, 2, 3].iter().map i -> i + 1
it.collect(Array) # [2, 3, 4].
it.collect(List) # [2, 3, 4].
```
Type variables can only be declared during `||`. However, once declared, they can be used anywhere until they exit scope.

View file

@ -37,7 +37,7 @@ The `.freeze_map` method operates on values unchanged.
```python
a = [1, 2, 3].into [Nat; !3]
x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array)
x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(List)
```
In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable.

View file

@ -24,7 +24,7 @@ However, these rules do not apply to the tuple-like part of a Function type, bec
In addition, return values of Unit types can be ignored, but return values of other tuple types cannot be ignored.
## Array Type
## List Type
```erg
[], [X; 0], [X; 1], [X; 2], ..., [X; _] == [X]
@ -37,7 +37,7 @@ The same subtype rules exist for arrays as for tuples.
* forall N in 0..<Len(T) (Len(T) <= Len(U)), U[N] == T[N] => U <: T (oblivion rule)
```
Arrays like the one below are not valid types. It is an intentional design to emphasize that the elements of the array are homogenized.
Lists like the one below are not valid types. It is an intentional design to emphasize that the elements of the array are homogenized.
```erg
[Int, Str]

View file

@ -2,7 +2,7 @@
Type erasure is the process of setting a type argument to `_` and deliberately discarding its information. Type erasure is a feature of many polymorphic languages, but in the context of Erg's syntax, it is more accurate to call it type argument erasure.
The most common example of a type that has been type-erased is `[T, _]`. Arrays are not always known their length at compile-time. For example, `sys.argv`, which refers to command line arguments, is of type `[Str, _]`. Since Erg's compiler has no way of knowing the length of command line arguments, information about their length must be given up.
The most common example of a type that has been type-erased is `[T, _]`. Lists are not always known their length at compile-time. For example, `sys.argv`, which refers to command line arguments, is of type `[Str, _]`. Since Erg's compiler has no way of knowing the length of command line arguments, information about their length must be given up.
However, a type that has been type-erased becomes a supertype of a type that has not been (e.g. `[T; N] <: [T; _]`), so it can accept more objects.
Objects of type `[T; N]` can of course use methods of type `[T; _]`, but the `N` information is erased after use. If the length does not change, then it is possible to use `[T; N]` in the signature. If the length remains the same, it must be indicated by a signature.
@ -18,14 +18,14 @@ For non-type type arguments (Int, Bool, etc.), the parameter with `_` will be un
```python
i: _ # i: Object
[_; _] == [Object; _] == Array
[_; _] == [Object; _] == List
```
Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again.
```python
implicit = (1..5).iter().map(i -> i * 2).to_arr()
explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
explicit = (1..5).iter().map(i -> i * 2).into(List(Nat))
```
In Rust, this corresponds to the following code.
@ -38,6 +38,6 @@ Erg does not allow partial omission of types, but uses higher-order kind polymor
```python
# collect is a higher-order Kind method that takes Kind
hk = (1..5).iter().map(i -> i * 2).collect(Array)
hk: Array(Int)
hk = (1..5).iter().map(i -> i * 2).collect(List)
hk: List(Int)
```

View file

@ -2,7 +2,7 @@
Everything is typed in Erg. Types themselves are no exception. __kind__ represents the "type of type". For example, `Int` belongs to `Type`, just as `1` belongs to `Int`. `Type` is the simplest kind, the __atomic kind__. In type-theoretic notation, `Type` corresponds to `*`.
In the concept of kind, what is practically important is one or more kinds (multinomial kind). One-term kind, for example `Option`, belongs to it. A unary kind is represented as `Type -> Type` [<sup id="f1">1</sup>](#1). A __container__ such as `Array` or `Option` is specifically a polynomial kind that takes a type as an argument.
In the concept of kind, what is practically important is one or more kinds (multinomial kind). One-term kind, for example `Option`, belongs to it. A unary kind is represented as `Type -> Type` [<sup id="f1">1</sup>](#1). A __container__ such as `List` or `Option` is specifically a polynomial kind that takes a type as an argument.
As the notation `Type -> Type` indicates, `Option` is actually a function that receives a type `T` and returns a type `Option T`. However, since this function is not a function in the usual sense, it is usually called the unary kind.
Note that `->` itself, which is an anonymous function operator, can also be seen as a kind when it receives a type and returns a type.

View file

@ -26,7 +26,7 @@ v: [Str; !1].
```
For mutable structure types, Mutable type arguments are marked with `!`. In the above case, the type `[Str; !0]` can be changed to `[Str; !1]` and so on. That is, the length can be changed.
Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ArrayWithLength!(T, !N)` type.
Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ListWithLength!(T, !N)` type.
Mutable structure types can of course be user-defined. Note, however, that there are some differences from invariant structure types in terms of the construction method.

View file

@ -4,7 +4,7 @@ Erg has quantified and dependent types. Then naturally, it is possible to create
```python
NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0}
NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0}
NonEmptyList = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: List(_, N); N > 0}
```
The standard form of quantified dependent types are `K(A, ... | Pred)`. ``K`` is a type constructor, `A, B` are type arguments, and `Pred` is a conditional expression.

View file

@ -5,19 +5,19 @@ Erg can subtype polymorphic types, but there are some caveats.
First, consider the inclusion relation of ordinary polymorphic types. In general, there is a container `K` and a type `A, B` to which it assigns, and when `A < B`, `K A < K B`.
For example, `Option Int < Option Object`. Therefore, methods defined in `Option Object` can also be used in `Option Int`.
Consider the typical polymorphic type `Array!(T)`.
Note that this time it's not `Array!(T, N)` because we don't care about the number of elements.
Now, the `Array!(T)` type has methods called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type:
Consider the typical polymorphic type `List!(T)`.
Note that this time it's not `List!(T, N)` because we don't care about the number of elements.
Now, the `List!(T)` type has methods called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type:
Array.push!: Self(T).(T) => NoneType
Array.pop!: Self(T).() => T
List.push!: Self(T).(T) => NoneType
List.pop!: Self(T).() => T
As can be intuitively understood,
* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
* When `o: Object`, `Array!(Str).push!(o)` is NG
* `Array!(Object).pop!().into(Str)` is NG
* `Array!(Str).pop!().into(Object)` is OK
* `List!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
* When `o: Object`, `List!(Str).push!(o)` is NG
* `List!(Object).pop!().into(Str)` is NG
* `List!(Str).pop!().into(Object)` is OK
is. In terms of the type system, this is

View file

@ -46,11 +46,6 @@ Use attributes. By the way, a record is a function that can define an object wit
Giving arguments to a subroutine object and getting a result.
Use Call. This is because Application has a usage of "application software".
## Array, List
Use Arrays. Erg arrays are (generally) contiguous in memory.
List refers to a so-called linked list, or a list as a Python data type.
## lambda functions, lambda expressions, anonymous functions
Unify with anonymous functions. In English, Lambda can be used to shorten the number of characters, but the official name is Anonymous function.

View file

@ -56,7 +56,7 @@ codeをコードとして評価し返す。
ただしクラスは比較できないため、インスタンス判定がしたい場合は`classof(object) == Class`ではなく`object in Class`を使う。
コンパイル時に決定される構造型は`Typeof`で得られる。
## Iterator, Array生成系
## Iterator, List生成系
### repeat|T|(x: T) -> RepeatIterator T

Some files were not shown because too many files have changed in this diff Show more