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] 2│ l = [1, 2, 3]
3│ l.push!(x) 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: 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: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##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
``` ```
## Requirements ## Requirements

View file

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

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3] 2│ l = [1, 2, 3]
3│ l.push!(x) 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: 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: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##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
``` ```
## 要求 ## 要求

View file

@ -150,10 +150,10 @@
2│ l = [1, 2, 3] 2│ l = [1, 2, 3]
3│ l.push!(x) 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: 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: `List` has `push`, see https://erg-lang.github.io/docs/prelude/List/##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
``` ```
## 要求 ## 要求

14
TODO.md
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -44,7 +44,7 @@ impl Context {
expected: &Type, expected: &Type,
found: &Type, found: &Type,
) -> Option<String> { ) -> 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 len = &callee_t.typarams().get(1).cloned()?;
let (_, _, pred) = found.clone().deconstruct_refinement().ok()?; let (_, _, pred) = found.clone().deconstruct_refinement().ok()?;
if let Predicate::Equal { rhs: accessed, .. } = pred { if let Predicate::Equal { rhs: accessed, .. } = pred {
@ -58,10 +58,10 @@ impl Context {
accessed.clone() accessed.clone()
}; };
return Some(switch_lang! { return Some(switch_lang! {
"japanese" => format!("配列の長さは{len}ですが、{accessed}番目の要素にアクセスしようとしています"), "japanese" => format!("リストの長さは{len}ですが、{accessed}番目の要素にアクセスしようとしています"),
"simplified_chinese" => format!("数组长度为{len}但尝试访问第{accessed}个元素"), "simplified_chinese" => format!("数组长度为{len}但尝试访问第{accessed}个元素"),
"traditional_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, BYTES,
or( or(
mono(BYTES), 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( vec![kw(
@ -954,7 +954,7 @@ impl Context {
None, None,
vec![kw(KW_MAXSPLIT, Nat)], vec![kw(KW_MAXSPLIT, Nat)],
None, None,
unknown_len_array_t(Str), unknown_len_list_t(Str),
), ),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
@ -968,7 +968,7 @@ impl Context {
None, None,
vec![kw(KW_KEEPENDS, Bool)], vec![kw(KW_KEEPENDS, Bool)],
None, None,
unknown_len_array_t(Str), unknown_len_list_t(Str),
), ),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
@ -1356,14 +1356,14 @@ impl Context {
type_.register_superclass(Obj, &obj); type_.register_superclass(Obj, &obj);
type_.register_builtin_erg_impl( type_.register_builtin_erg_impl(
FUNC_MRO, FUNC_MRO,
fn0_met(Type, array_t(Type, TyParam::erased(Nat))), fn0_met(Type, list_t(Type, TyParam::erased(Nat))),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
// TODO: PolyType // TODO: PolyType
type_.register_builtin_erg_impl( type_.register_builtin_erg_impl(
FUNDAMENTAL_ARGS, FUNDAMENTAL_ARGS,
array_t(Type, TyParam::erased(Nat)), list_t(Type, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
@ -1424,31 +1424,31 @@ impl Context {
); );
code.register_builtin_erg_impl( code.register_builtin_erg_impl(
FUNC_CO_VARNAMES, FUNC_CO_VARNAMES,
array_t(Str, TyParam::erased(Nat)), list_t(Str, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
code.register_builtin_erg_impl( code.register_builtin_erg_impl(
FUNC_CO_CONSTS, FUNC_CO_CONSTS,
array_t(Obj, TyParam::erased(Nat)), list_t(Obj, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
code.register_builtin_erg_impl( code.register_builtin_erg_impl(
FUNC_CO_NAMES, FUNC_CO_NAMES,
array_t(Str, TyParam::erased(Nat)), list_t(Str, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
code.register_builtin_erg_impl( code.register_builtin_erg_impl(
FUNC_CO_FREEVARS, FUNC_CO_FREEVARS,
array_t(Str, TyParam::erased(Nat)), list_t(Str, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
code.register_builtin_erg_impl( code.register_builtin_erg_impl(
FUNC_CO_CELLVARS, FUNC_CO_CELLVARS,
array_t(Str, TyParam::erased(Nat)), list_t(Str, TyParam::erased(Nat)),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
@ -1566,100 +1566,100 @@ impl Context {
if ERG_MODE { if ERG_MODE {
py_module.register_superclass(g_module_t.clone(), &generic_module); py_module.register_superclass(g_module_t.clone(), &generic_module);
} }
/* GenericArray */ /* GenericList */
let mut generic_array = Self::builtin_mono_class(GENERIC_ARRAY, 1); let mut generic_list = Self::builtin_mono_class(GENERIC_LIST, 1);
generic_array.register_superclass(Obj, &obj); generic_list.register_superclass(Obj, &obj);
let mut arr_eq = Self::builtin_methods(Some(mono(EQ)), 2); let mut arr_eq = Self::builtin_methods(Some(mono(EQ)), 2);
arr_eq.register_builtin_erg_impl( arr_eq.register_builtin_erg_impl(
OP_EQ, OP_EQ,
fn1_met(mono(GENERIC_ARRAY), mono(GENERIC_ARRAY), Bool), fn1_met(mono(GENERIC_LIST), mono(GENERIC_LIST), Bool),
Const, Const,
Visibility::BUILTIN_PUBLIC, 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( let t_call = func1(
poly(ITERABLE, vec![ty_tp(T.clone())]), poly(ITERABLE, vec![ty_tp(T.clone())]),
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
) )
.quantify(); .quantify();
generic_array.register_builtin_erg_impl( generic_list.register_builtin_erg_impl(
FUNDAMENTAL_CALL, FUNDAMENTAL_CALL,
t_call, t_call,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
let mut array_hash = Self::builtin_methods(Some(mono(HASH)), 1); let mut list_hash = Self::builtin_methods(Some(mono(HASH)), 1);
array_hash.register_builtin_erg_impl( list_hash.register_builtin_erg_impl(
OP_HASH, OP_HASH,
fn0_met(mono(GENERIC_ARRAY), Int), fn0_met(mono(GENERIC_LIST), Int),
Const, Const,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
generic_array.register_trait_methods(mono(GENERIC_ARRAY), array_hash); generic_list.register_trait_methods(mono(GENERIC_LIST), list_hash);
let unsized_array_t = poly(UNSIZED_ARRAY, vec![ty_tp(T.clone())]); let unsized_list_t = poly(UNSIZED_LIST, vec![ty_tp(T.clone())]);
let mut unsized_array = let mut unsized_list =
Self::builtin_poly_class(UNSIZED_ARRAY, vec![ParamSpec::t_nd(TY_T)], 1); Self::builtin_poly_class(UNSIZED_LIST, vec![ParamSpec::t_nd(TY_T)], 1);
unsized_array.register_superclass(Obj, &obj); unsized_list.register_superclass(Obj, &obj);
unsized_array.register_builtin_decl(KW_ELEM, T.clone(), vis.clone(), Some(KW_ELEM)); unsized_list.register_builtin_decl(KW_ELEM, T.clone(), vis.clone(), Some(KW_ELEM));
/* Array */ /* List */
let mut array_ = let mut list_ =
Self::builtin_poly_class(ARRAY, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 10); Self::builtin_poly_class(LIST, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 10);
array_.register_superclass(mono(GENERIC_ARRAY), &generic_array); list_.register_superclass(mono(GENERIC_LIST), &generic_list);
array_ list_
.register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())])) .register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())]))
.unwrap(); .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( let t = no_var_fn_met(
arr_t.clone(), lis_t.clone(),
vec![kw(KW_RHS, array_t(T.clone(), M.clone()))], vec![kw(KW_RHS, list_t(T.clone(), M.clone()))],
vec![], vec![],
array_t(T.clone(), N.clone() + M.clone()), list_t(T.clone(), N.clone() + M.clone()),
) )
.quantify(); .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 = let t_count =
no_var_fn_met(arr_t.clone(), vec![kw(KW_X, T.clone())], vec![], Nat).quantify(); no_var_fn_met(lis_t.clone(), vec![kw(KW_X, T.clone())], vec![], Nat).quantify();
array_.register_py_builtin(FUNC_COUNT, t_count, Some(FUNC_COUNT), 17); list_.register_py_builtin(FUNC_COUNT, t_count, Some(FUNC_COUNT), 17);
let t_get = no_var_fn_met( let t_get = no_var_fn_met(
arr_t.clone(), lis_t.clone(),
vec![pos(Nat)], vec![pos(Nat)],
vec![ParamTy::kw_default(KW_DEFAULT.into(), U.clone(), NoneType)], vec![ParamTy::kw_default(KW_DEFAULT.into(), U.clone(), NoneType)],
or(T.clone(), U.clone()), or(T.clone(), U.clone()),
) )
.quantify(); .quantify();
array_.register_builtin_erg_impl(FUNC_GET, t_get, Immutable, Visibility::BUILTIN_PUBLIC); list_.register_builtin_erg_impl(FUNC_GET, t_get, Immutable, Visibility::BUILTIN_PUBLIC);
// Array(T, N)|<: Add(Array(T, M))|. // List(T, N)|<: Add(List(T, M))|.
// Output = Array(T, N + M) // Output = List(T, N + M)
// __add__: (self: Array(T, N), other: Array(T, M)) -> Array(T, N + M) = Array.concat // __add__: (self: List(T, N), other: List(T, M)) -> List(T, N + M) = List.concat
let mut array_add = Self::builtin_methods( let mut list_add = Self::builtin_methods(
Some(poly(ADD, vec![ty_tp(array_t(T.clone(), M.clone()))])), Some(poly(ADD, vec![ty_tp(list_t(T.clone(), M.clone()))])),
2, 2,
); );
array_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Visibility::BUILTIN_PUBLIC); list_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Visibility::BUILTIN_PUBLIC);
let out_t = array_t(T.clone(), N.clone() + M.clone()); let out_t = list_t(T.clone(), N.clone() + M.clone());
array_add.register_builtin_const( list_add.register_builtin_const(
OUTPUT, OUTPUT,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
None, None,
ValueObj::builtin_class(out_t), 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( let t = no_var_fn_met(
arr_t.clone(), lis_t.clone(),
vec![kw(KW_ELEM, T.clone())], vec![kw(KW_ELEM, T.clone())],
vec![], vec![],
array_t(T.clone(), N.clone() + value(1usize)), list_t(T.clone(), N.clone() + value(1usize)),
) )
.quantify(); .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( let repeat_t = no_var_fn_met(
arr_t.clone(), lis_t.clone(),
vec![pos(singleton(Nat, M.clone()))], vec![pos(singleton(Nat, M.clone()))],
vec![], vec![],
array_t(T.clone(), N.clone() * M.clone()), list_t(T.clone(), N.clone() * M.clone()),
) )
.quantify(); .quantify();
array_.register_builtin_erg_impl( list_.register_builtin_erg_impl(
FUNC_REPEAT, FUNC_REPEAT,
repeat_t, repeat_t,
Immutable, Immutable,
@ -1667,15 +1667,15 @@ impl Context {
); );
// [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!) // [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!)
let mut_type = let mut_type =
ValueObj::builtin_class(poly(MUT_ARRAY, vec![TyParam::t(T.clone()), N.clone()])); ValueObj::builtin_class(poly(MUT_LIST, vec![TyParam::t(T.clone()), N.clone()]));
let mut array_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); let mut list_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2);
array_mutizable.register_builtin_const( list_mutizable.register_builtin_const(
MUTABLE_MUT_TYPE, MUTABLE_MUT_TYPE,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
None, None,
mut_type, 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 var = FRESH_GEN.fresh_varname();
let input = refinement( let input = refinement(
var.clone(), var.clone(),
@ -1684,259 +1684,254 @@ impl Context {
); );
// __getitem__: |T, N|(self: [T; N], _: {I: Nat | I <= N}) -> T // __getitem__: |T, N|(self: [T; N], _: {I: Nat | I <= N}) -> T
// and (self: [T; N], _: Range(Int)) -> [T; _] // and (self: [T; N], _: Range(Int)) -> [T; _]
let array_getitem_t = (fn1_kw_met( let list_getitem_t =
array_t(T.clone(), N.clone()), (fn1_kw_met(list_t(T.clone(), N.clone()), anon(input.clone()), T.clone())
anon(input.clone()), & fn1_kw_met(
T.clone(), list_t(T.clone(), N.clone()),
) & fn1_kw_met( anon(poly(RANGE, vec![ty_tp(Int)])),
array_t(T.clone(), N.clone()), unknown_len_list_t(T.clone()),
anon(poly(RANGE, vec![ty_tp(Int)])), ))
unknown_len_array_t(T.clone()), .quantify();
))
.quantify();
let get_item = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let get_item = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNDAMENTAL_GETITEM, FUNDAMENTAL_GETITEM,
__array_getitem__, __list_getitem__,
array_getitem_t, list_getitem_t,
None, None,
))); )));
array_.register_builtin_const( list_.register_builtin_const(
FUNDAMENTAL_GETITEM, FUNDAMENTAL_GETITEM,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
None, None,
get_item, get_item,
); );
let array_insert_t = no_var_fn_met( let list_insert_t = no_var_fn_met(
array_t(T.clone(), N.clone()), list_t(T.clone(), N.clone()),
vec![pos(Nat), kw(KW_ELEM, T.clone())], vec![pos(Nat), kw(KW_ELEM, T.clone())],
vec![], vec![],
array_t(T.clone(), N.clone() + value(1usize)), list_t(T.clone(), N.clone() + value(1usize)),
) )
.quantify(); .quantify();
let array_insert = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let list_insert = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_INSERT, FUNC_INSERT,
array_insert_at, list_insert_at,
array_insert_t.clone(), list_insert_t.clone(),
None, None,
))); )));
array_._register_builtin_const( list_._register_builtin_const(
FUNC_INSERT, FUNC_INSERT,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(array_insert_t), Some(list_insert_t),
array_insert, list_insert,
Some(FUNC_INSERT_AT.into()), Some(FUNC_INSERT_AT.into()),
); );
let array_remove_at_t = no_var_fn_met( let list_remove_at_t = no_var_fn_met(
array_t(T.clone(), N.clone()), list_t(T.clone(), N.clone()),
vec![pos(Nat)], vec![pos(Nat)],
vec![], vec![],
array_t(T.clone(), N.clone() - value(1usize)), list_t(T.clone(), N.clone() - value(1usize)),
) )
.quantify(); .quantify();
let array_remove_at = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let list_remove_at = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REMOVE_AT, FUNC_REMOVE_AT,
array_remove_at, list_remove_at,
array_remove_at_t.clone(), list_remove_at_t.clone(),
None, None,
))); )));
array_.register_builtin_const( list_.register_builtin_const(
FUNC_REMOVE_AT, FUNC_REMOVE_AT,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(array_remove_at_t), Some(list_remove_at_t),
array_remove_at, list_remove_at,
); );
let array_remove_all_t = no_var_fn_met( let list_remove_all_t = no_var_fn_met(
array_t(T.clone(), N.clone()), list_t(T.clone(), N.clone()),
vec![kw(KW_ELEM, T.clone())], vec![kw(KW_ELEM, T.clone())],
vec![], vec![],
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
) )
.quantify(); .quantify();
let array_remove_all = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let list_remove_all = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REMOVE_ALL, FUNC_REMOVE_ALL,
array_remove_all, list_remove_all,
array_remove_all_t.clone(), list_remove_all_t.clone(),
None, None,
))); )));
array_.register_builtin_const( list_.register_builtin_const(
FUNC_REMOVE_ALL, FUNC_REMOVE_ALL,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(array_remove_all_t), Some(list_remove_all_t),
array_remove_all, list_remove_all,
); );
array_ list_
.register_trait(self, poly(INDEXABLE, vec![ty_tp(input), ty_tp(T.clone())])) .register_trait(self, poly(INDEXABLE, vec![ty_tp(input), ty_tp(T.clone())]))
.unwrap(); .unwrap();
array_ list_
.register_trait( .register_trait(
self, self,
poly( poly(
HAS_SHAPE, 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(); .unwrap();
array_ list_
.register_trait( .register_trait(
self, self,
poly( poly(
HAS_SCALAR_TYPE, 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(); .unwrap();
let mut array_sized = Self::builtin_methods(Some(mono(SIZED)), 2); let mut list_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
array_sized.register_builtin_erg_impl( list_sized.register_builtin_erg_impl(
FUNDAMENTAL_LEN, FUNDAMENTAL_LEN,
fn0_met(arr_t.clone(), Nat).quantify(), fn0_met(lis_t.clone(), Nat).quantify(),
Const, Const,
Visibility::BUILTIN_PUBLIC, 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 // 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( let union = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_UNION, FUNC_UNION,
array_union, list_union,
array_union_t, list_union_t,
None, 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; _] // shape: (self: [Type; _]) -> [Nat; _]
let array_shape_t = fn0_met( let list_shape_t =
array_t(Type, TyParam::erased(Nat)), fn0_met(list_t(Type, TyParam::erased(Nat)), unknown_len_list_t(Nat)).quantify();
unknown_len_array_t(Nat),
)
.quantify();
let shape = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let shape = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SHAPE, FUNC_SHAPE,
array_shape, list_shape,
array_shape_t, list_shape_t,
None, None,
))); )));
array_.register_builtin_const(FUNC_SHAPE, Visibility::BUILTIN_PUBLIC, None, shape); list_.register_builtin_const(FUNC_SHAPE, Visibility::BUILTIN_PUBLIC, None, shape);
let array_scalar_type_t = fn0_met(Type, Type).quantify(); let list_scalar_type_t = fn0_met(Type, Type).quantify();
let array_scalar_type = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let list_scalar_type = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SCALAR_TYPE, FUNC_SCALAR_TYPE,
array_scalar_type, list_scalar_type,
array_scalar_type_t, list_scalar_type_t,
None, None,
))); )));
array_.register_builtin_const( list_.register_builtin_const(
FUNC_SCALAR_TYPE, FUNC_SCALAR_TYPE,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
None, None,
array_scalar_type, list_scalar_type,
); );
let mut array_eq = Self::builtin_methods(Some(mono(EQ)), 2); let mut list_eq = Self::builtin_methods(Some(mono(EQ)), 2);
array_eq.register_builtin_erg_impl( list_eq.register_builtin_erg_impl(
OP_EQ, OP_EQ,
fn1_met(arr_t.clone(), arr_t.clone(), Bool).quantify(), fn1_met(lis_t.clone(), lis_t.clone(), Bool).quantify(),
Const, Const,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
array_.register_trait_methods(arr_t.clone(), array_eq); list_.register_trait_methods(lis_t.clone(), list_eq);
array_ list_
.register_trait(self, poly(SEQUENCE, vec![ty_tp(T.clone())])) .register_trait(self, poly(SEQUENCE, vec![ty_tp(T.clone())]))
.unwrap(); .unwrap();
array_.unregister_trait(&poly(INDEXABLE, vec![ty_tp(Nat), ty_tp(T.clone())])); list_.unregister_trait(&poly(INDEXABLE, vec![ty_tp(Nat), ty_tp(T.clone())]));
let mut array_show = Self::builtin_methods(Some(mono(SHOW)), 1); let mut list_show = Self::builtin_methods(Some(mono(SHOW)), 1);
array_show.register_builtin_py_impl( list_show.register_builtin_py_impl(
FUNDAMENTAL_STR, FUNDAMENTAL_STR,
fn0_met(arr_t.clone(), Str).quantify(), fn0_met(lis_t.clone(), Str).quantify(),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_STR), Some(FUNDAMENTAL_STR),
); );
array_.register_trait_methods(arr_t.clone(), array_show); list_.register_trait_methods(lis_t.clone(), list_show);
let mut array_iterable = let mut list_iterable =
Self::builtin_methods(Some(poly(ITERABLE, vec![ty_tp(T.clone())])), 2); Self::builtin_methods(Some(poly(ITERABLE, vec![ty_tp(T.clone())])), 2);
let array_iter = poly(ARRAY_ITERATOR, vec![ty_tp(T.clone())]); let list_iter = poly(LIST_ITERATOR, vec![ty_tp(T.clone())]);
let t = fn0_met(array_t(T.clone(), TyParam::erased(Nat)), array_iter.clone()).quantify(); let t = fn0_met(list_t(T.clone(), TyParam::erased(Nat)), list_iter.clone()).quantify();
array_iterable.register_builtin_py_impl( list_iterable.register_builtin_py_impl(
FUNC_ITER, FUNC_ITER,
t, t,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNDAMENTAL_ITER), Some(FUNDAMENTAL_ITER),
); );
array_iterable.register_builtin_const( list_iterable.register_builtin_const(
ITERATOR, ITERATOR,
vis.clone(), vis.clone(),
None, None,
ValueObj::builtin_class(array_iter), ValueObj::builtin_class(list_iter),
); );
array_.register_trait_methods(arr_t.clone(), array_iterable); list_.register_trait_methods(lis_t.clone(), list_iterable);
let mut array_collection = let mut list_collection =
Self::builtin_methods(Some(poly(COLLECTION, vec![ty_tp(T.clone())])), 4); 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, FUNDAMENTAL_CONTAINS,
fn1_met(arr_t.clone(), T.clone(), Bool).quantify(), fn1_met(lis_t.clone(), T.clone(), Bool).quantify(),
Const, Const,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
array_.register_trait_methods(arr_t.clone(), array_collection); list_.register_trait_methods(lis_t.clone(), list_collection);
array_ list_
.register_trait(self, poly(COLLECTION, vec![ty_tp(T.clone())])) .register_trait(self, poly(COLLECTION, vec![ty_tp(T.clone())]))
.unwrap(); .unwrap();
let t = fn1_met( let t = fn1_met(
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
func1(T.clone(), Bool), func1(T.clone(), Bool),
tuple_t(vec![ tuple_t(vec![
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
array_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( let t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
vec![], vec![],
vec![kw( vec![kw(
KW_SAME_BUCKET, KW_SAME_BUCKET,
or(func2(T.clone(), T.clone(), Bool), NoneType), 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( let sum_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
vec![], vec![],
vec![kw(KW_START, T.clone())], vec![kw(KW_START, T.clone())],
T.clone(), T.clone(),
); );
let sum = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let sum = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_SUM, FUNC_SUM,
array_sum, list_sum,
sum_t.quantify(), sum_t.quantify(),
None, 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( let prod_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
vec![], vec![],
vec![kw(KW_START, T.clone())], vec![kw(KW_START, T.clone())],
T.clone(), T.clone(),
); );
let prod = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let prod = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_PROD, FUNC_PROD,
array_prod, list_prod,
prod_t.quantify(), prod_t.quantify(),
None, 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( let reversed_t = no_var_fn_met(
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
vec![], vec![],
vec![], vec![],
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
); );
let reversed = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( let reversed = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
FUNC_REVERSED, FUNC_REVERSED,
array_reversed, list_reversed,
reversed_t.quantify(), reversed_t.quantify(),
None, None,
))); )));
array_.register_builtin_const(FUNC_REVERSED, Visibility::BUILTIN_PUBLIC, None, reversed); list_.register_builtin_const(FUNC_REVERSED, Visibility::BUILTIN_PUBLIC, None, reversed);
/* Slice */ /* Slice */
let mut slice = Self::builtin_mono_class(SLICE, 3); let mut slice = Self::builtin_mono_class(SLICE, 3);
slice.register_superclass(Obj, &obj); slice.register_superclass(Obj, &obj);
@ -2284,7 +2279,7 @@ impl Context {
/* GenericTuple */ /* GenericTuple */
let mut generic_tuple = Self::builtin_mono_class(GENERIC_TUPLE, 1); let mut generic_tuple = Self::builtin_mono_class(GENERIC_TUPLE, 1);
generic_tuple.register_superclass(Obj, &obj); 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); let mut tuple_eq = Self::builtin_methods(Some(mono(EQ)), 2);
tuple_eq.register_builtin_erg_impl( tuple_eq.register_builtin_erg_impl(
OP_EQ, OP_EQ,
@ -2302,14 +2297,11 @@ impl Context {
); );
generic_tuple.register_trait_methods(mono(GENERIC_TUPLE), tuple_hash); generic_tuple.register_trait_methods(mono(GENERIC_TUPLE), tuple_hash);
generic_tuple.register_trait(self, mono(EQ_HASH)).unwrap(); generic_tuple.register_trait(self, mono(EQ_HASH)).unwrap();
let Ts = mono_q_tp(TY_TS, instanceof(array_t(Type, N.clone()))); let Ts = mono_q_tp(TY_TS, instanceof(list_t(Type, N.clone())));
// Ts <: GenericArray // Ts <: GenericList
let _tuple_t = poly(TUPLE, vec![Ts.clone()]); let _tuple_t = poly(TUPLE, vec![Ts.clone()]);
let mut tuple_ = Self::builtin_poly_class( let mut tuple_ =
TUPLE, Self::builtin_poly_class(TUPLE, vec![PS::named_nd(TY_TS, list_t(Type, N.clone()))], 2);
vec![PS::named_nd(TY_TS, array_t(Type, N.clone()))],
2,
);
tuple_.register_superclass(mono(GENERIC_TUPLE), &generic_tuple); tuple_.register_superclass(mono(GENERIC_TUPLE), &generic_tuple);
tuple_ tuple_
.register_trait(self, poly(OUTPUT, vec![Ts.clone()])) .register_trait(self, poly(OUTPUT, vec![Ts.clone()]))
@ -2498,12 +2490,12 @@ impl Context {
str_iterator str_iterator
.register_trait(self, poly(OUTPUT, vec![ty_tp(Str)])) .register_trait(self, poly(OUTPUT, vec![ty_tp(Str)]))
.unwrap(); .unwrap();
let mut array_iterator = Self::builtin_poly_class(ARRAY_ITERATOR, vec![PS::t_nd(TY_T)], 1); let mut list_iterator = Self::builtin_poly_class(LIST_ITERATOR, vec![PS::t_nd(TY_T)], 1);
array_iterator.register_superclass(Obj, &obj); list_iterator.register_superclass(Obj, &obj);
array_iterator list_iterator
.register_trait(self, poly(ITERABLE, vec![ty_tp(T.clone())])) .register_trait(self, poly(ITERABLE, vec![ty_tp(T.clone())]))
.unwrap(); .unwrap();
array_iterator list_iterator
.register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())])) .register_trait(self, poly(OUTPUT, vec![ty_tp(T.clone())]))
.unwrap(); .unwrap();
let mut set_iterator = Self::builtin_poly_class(SET_ITERATOR, vec![PS::t_nd(TY_T)], 1); 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 file_mut
.register_trait(self, mono(CONTEXT_MANAGER)) .register_trait(self, mono(CONTEXT_MANAGER))
.unwrap(); .unwrap();
/* Array! */ /* List! */
let array_mut_t = poly(MUT_ARRAY, vec![ty_tp(T.clone()), N.clone()]); let list_mut_t = poly(MUT_LIST, vec![ty_tp(T.clone()), N.clone()]);
let mut array_mut_ = let mut list_mut_ =
Self::builtin_poly_class(MUT_ARRAY, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 2); Self::builtin_poly_class(MUT_LIST, vec![PS::t_nd(TY_T), PS::default(TY_N, Nat)], 2);
array_mut_.register_superclass(arr_t.clone(), &array_); list_mut_.register_superclass(lis_t.clone(), &list_);
let t = pr_met( let t = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly( Some(poly(
MUT_ARRAY, MUT_LIST,
vec![ty_tp(T.clone()), N.clone() + value(1usize)], vec![ty_tp(T.clone()), N.clone() + value(1usize)],
)), )),
), ),
@ -3023,18 +3015,15 @@ impl Context {
NoneType, NoneType,
) )
.quantify(); .quantify();
array_mut_.register_py_builtin(PROC_PUSH, t, Some(FUNC_APPEND), 15); list_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 t_copy = fn0_met(ref_(list_mut_t.clone()), list_mut_t.clone()).quantify();
let mut array_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2); let mut list_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
array_mut_copy.register_py_builtin(FUNC_COPY, t_copy, Some(FUNC_COPY), 116); list_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_trait_methods(list_mut_t.clone(), list_mut_copy);
let t_extend = pr_met( let t_extend = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly( Some(poly(MUT_LIST, vec![ty_tp(T.clone()), TyParam::erased(Nat)])),
MUT_ARRAY,
vec![ty_tp(T.clone()), TyParam::erased(Nat)],
)),
), ),
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))], vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
None, None,
@ -3042,12 +3031,12 @@ impl Context {
NoneType, NoneType,
) )
.quantify(); .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( let t_insert = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly( Some(poly(
MUT_ARRAY, MUT_LIST,
vec![ty_tp(T.clone()), N.clone() + value(1usize)], vec![ty_tp(T.clone()), N.clone() + value(1usize)],
)), )),
), ),
@ -3057,12 +3046,12 @@ impl Context {
NoneType, NoneType,
) )
.quantify(); .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( let t_remove = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly( Some(poly(
MUT_ARRAY, MUT_LIST,
vec![ty_tp(T.clone()), N.clone() - value(1usize)], vec![ty_tp(T.clone()), N.clone() - value(1usize)],
)), )),
), ),
@ -3072,12 +3061,12 @@ impl Context {
NoneType, NoneType,
) )
.quantify(); .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( let t_pop = pr_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly( Some(poly(
MUT_ARRAY, MUT_LIST,
vec![ty_tp(T.clone()), N.clone() - value(1usize)], vec![ty_tp(T.clone()), N.clone() - value(1usize)],
)), )),
), ),
@ -3087,18 +3076,18 @@ impl Context {
T.clone(), T.clone(),
) )
.quantify(); .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( let t_clear = pr0_met(
ref_mut( ref_mut(
array_mut_t.clone(), list_mut_t.clone(),
Some(poly(MUT_ARRAY, vec![ty_tp(T.clone()), value(0usize)])), Some(poly(MUT_LIST, vec![ty_tp(T.clone()), value(0usize)])),
), ),
NoneType, NoneType,
) )
.quantify(); .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( let t_sort = pr_met(
ref_mut(array_mut_t.clone(), None), ref_mut(list_mut_t.clone(), None),
vec![], vec![],
None, None,
vec![kw( vec![kw(
@ -3108,77 +3097,77 @@ impl Context {
NoneType, NoneType,
) )
.quantify(); .quantify();
array_mut_.register_py_builtin(PROC_SORT, t_sort, Some(FUNC_SORT), 78); list_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(); let t_reverse = pr0_met(ref_mut(list_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_REVERSE, t_reverse, Some(FUNC_REVERSE), 87);
let t = pr_met( 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()))], vec![kw(KW_FUNC, nd_func(vec![anon(T.clone())], None, T.clone()))],
None, None,
vec![], vec![],
NoneType, NoneType,
) )
.quantify(); .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( 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()))], vec![kw(KW_IDX, Nat), kw(KW_FUNC, func1(T.clone(), T.clone()))],
None, None,
vec![], vec![],
NoneType, NoneType,
) )
.quantify(); .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( let f_t = kw(
KW_FUNC, 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( let t = pr_met(
ref_mut(array_mut_t.clone(), None), ref_mut(list_mut_t.clone(), None),
vec![f_t], vec![f_t],
None, None,
vec![], vec![],
NoneType, NoneType,
) )
.quantify(); .quantify();
let mut array_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); let mut list_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2);
array_mut_mutable.register_builtin_py_impl( list_mut_mutable.register_builtin_py_impl(
PROC_UPDATE, PROC_UPDATE,
t, t,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNC_UPDATE), 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! */ /* ByteArray! */
let bytearray_mut_t = mono(BYTEARRAY); let bytelist_mut_t = mono(BYTEARRAY);
let mut bytearray_mut = Self::builtin_mono_class(BYTEARRAY, 2); let mut bytelist_mut = Self::builtin_mono_class(BYTEARRAY, 2);
let t_append = pr_met( 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))], vec![kw(KW_ELEM, int_interval(IntervalOp::Closed, 0, 255))],
None, None,
vec![], vec![],
NoneType, NoneType,
); );
bytearray_mut.register_builtin_py_impl( bytelist_mut.register_builtin_py_impl(
PROC_PUSH, PROC_PUSH,
t_append, t_append,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNC_APPEND), Some(FUNC_APPEND),
); );
let t_copy = fn0_met(ref_(bytearray_mut_t.clone()), bytearray_mut_t.clone()); let t_copy = fn0_met(ref_(bytelist_mut_t.clone()), bytelist_mut_t.clone());
let mut bytearray_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2); let mut bytelist_mut_copy = Self::builtin_methods(Some(mono(COPY)), 2);
bytearray_mut_copy.register_builtin_py_impl( bytelist_mut_copy.register_builtin_py_impl(
FUNC_COPY, FUNC_COPY,
t_copy, t_copy,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNC_COPY), 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( let t_extend = pr_met(
ref_mut(bytearray_mut_t.clone(), None), ref_mut(bytelist_mut_t.clone(), None),
vec![kw( vec![kw(
KW_ITERABLE, KW_ITERABLE,
poly( poly(
@ -3190,7 +3179,7 @@ impl Context {
vec![], vec![],
NoneType, NoneType,
); );
bytearray_mut.register_builtin_py_impl( bytelist_mut.register_builtin_py_impl(
PROC_EXTEND, PROC_EXTEND,
t_extend, t_extend,
Immutable, Immutable,
@ -3198,7 +3187,7 @@ impl Context {
Some(FUNC_EXTEND), Some(FUNC_EXTEND),
); );
let t_insert = pr_met( let t_insert = pr_met(
ref_mut(bytearray_mut_t.clone(), None), ref_mut(bytelist_mut_t.clone(), None),
vec![ vec![
kw(KW_INDEX, Nat), kw(KW_INDEX, Nat),
kw(KW_ELEM, int_interval(IntervalOp::Closed, 0, 255)), kw(KW_ELEM, int_interval(IntervalOp::Closed, 0, 255)),
@ -3207,7 +3196,7 @@ impl Context {
vec![], vec![],
NoneType, NoneType,
); );
bytearray_mut.register_builtin_py_impl( bytelist_mut.register_builtin_py_impl(
PROC_INSERT, PROC_INSERT,
t_insert, t_insert,
Immutable, Immutable,
@ -3215,18 +3204,18 @@ impl Context {
Some(FUNC_INSERT), Some(FUNC_INSERT),
); );
let t_pop = pr0_met( 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), int_interval(IntervalOp::Closed, 0, 255),
); );
bytearray_mut.register_builtin_py_impl( bytelist_mut.register_builtin_py_impl(
PROC_POP, PROC_POP,
t_pop, t_pop,
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some(FUNC_POP), Some(FUNC_POP),
); );
let t_reverse = pr0_met(ref_mut(bytearray_mut_t.clone(), None), NoneType); let t_reverse = pr0_met(ref_mut(bytelist_mut_t.clone(), None), NoneType);
bytearray_mut.register_builtin_py_impl( bytelist_mut.register_builtin_py_impl(
PROC_REVERSE, PROC_REVERSE,
t_reverse, t_reverse,
Immutable, Immutable,
@ -3445,7 +3434,7 @@ impl Context {
base_exception.register_superclass(Obj, &obj); base_exception.register_superclass(Obj, &obj);
base_exception.register_builtin_erg_impl( base_exception.register_builtin_erg_impl(
ATTR_ARGS, ATTR_ARGS,
unknown_len_array_t(Str), unknown_len_list_t(Str),
Immutable, Immutable,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
@ -3695,20 +3684,20 @@ impl Context {
Some(MODULE_TYPE), Some(MODULE_TYPE),
); );
self.register_builtin_type( self.register_builtin_type(
mono(GENERIC_ARRAY), mono(GENERIC_LIST),
generic_array, generic_list,
vis.clone(), vis.clone(),
Const, Const,
Some(ARRAY), Some(LIST),
); );
self.register_builtin_type( self.register_builtin_type(
unsized_array_t, unsized_list_t,
unsized_array, unsized_list,
vis.clone(), vis.clone(),
Const, 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(SLICE), slice, vis.clone(), Const, Some(FUNC_SLICE));
self.register_builtin_type( self.register_builtin_type(
mono(GENERIC_SET), mono(GENERIC_SET),
@ -3753,11 +3742,11 @@ impl Context {
Some(FUNC_STR_ITERATOR), Some(FUNC_STR_ITERATOR),
); );
self.register_builtin_type( self.register_builtin_type(
poly(ARRAY_ITERATOR, vec![ty_tp(T.clone())]), poly(LIST_ITERATOR, vec![ty_tp(T.clone())]),
array_iterator, list_iterator,
Visibility::BUILTIN_PRIVATE, Visibility::BUILTIN_PRIVATE,
Const, Const,
Some(FUNC_ARRAY_ITERATOR), Some(FUNC_LIST_ITERATOR),
); );
self.register_builtin_type( self.register_builtin_type(
poly(SET_ITERATOR, vec![ty_tp(T.clone())]), poly(SET_ITERATOR, vec![ty_tp(T.clone())]),
@ -3851,10 +3840,10 @@ impl Context {
Some(MEMORYVIEW), Some(MEMORYVIEW),
); );
self.register_builtin_type(mono(MUT_FILE), file_mut, vis.clone(), Const, Some(FILE)); 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( self.register_builtin_type(
bytearray_mut_t, bytelist_mut_t,
bytearray_mut, bytelist_mut,
vis.clone(), vis.clone(),
Const, Const,
Some(BYTEARRAY), 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()) 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 let slf = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("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, Ok(slf) => slf,
Err(val) => { Err(val) => {
return Err(type_mismatch("Array", val, "Self")); return Err(type_mismatch("List", val, "Self"));
} }
}; };
let index = args 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)]); // let keys = poly(DICT_KEYS, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into()) Ok(ValueObj::builtin_type(union).into())
} else { } 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)]); // let values = poly(DICT_VALUES, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into()) Ok(ValueObj::builtin_type(union).into())
} else { } 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)]); // let items = poly(DICT_ITEMS, vec![ty_tp(union)]);
Ok(ValueObj::builtin_type(union).into()) Ok(ValueObj::builtin_type(union).into())
} else { } else {
Ok(ValueObj::Array( Ok(ValueObj::List(
slf.into_iter() slf.into_iter()
.map(|(k, v)| ValueObj::Tuple(vec![k, v].into())) .map(|(k, v)| ValueObj::Tuple(vec![k, v].into()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -468,12 +468,12 @@ pub(crate) fn dict_diff(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
} }
/// `[Int, Str].union() == Int or Str` /// `[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 let slf = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let ValueObj::Array(slf) = slf else { let ValueObj::List(slf) = slf else {
return Err(type_mismatch("Array", slf, "Self")); return Err(type_mismatch("List", slf, "Self"));
}; };
let slf = slf let slf = slf
.iter() .iter()
@ -485,15 +485,15 @@ pub(crate) fn array_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
Ok(ValueObj::builtin_type(union).into()) 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 shape = vec![];
let mut arr = arr; let mut arr = arr;
loop { loop {
match arr { match arr {
ValueObj::Array(a) => { ValueObj::List(a) => {
shape.push(ValueObj::from(a.len()).into()); shape.push(ValueObj::from(a.len()).into());
match a.first() { match a.first() {
Some(arr_ @ (ValueObj::Array(_) | ValueObj::Type(_))) => { Some(arr_ @ (ValueObj::List(_) | ValueObj::Type(_))) => {
arr = arr_.clone(); 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 mut tps = t.typ().typarams();
let elem = match ctx.convert_tp_into_type(tps.remove(0)) { let elem = match ctx.convert_tp_into_type(tps.remove(0)) {
Ok(elem) => elem, Ok(elem) => elem,
@ -522,23 +522,23 @@ fn _arr_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
} }
/// ```erg /// ```erg
/// Array(Int, 2).shape() == [2,] /// List(Int, 2).shape() == [2,]
/// Array(Array(Int, 2), N).shape() == [N, 2] /// List(List(Int, 2), N).shape() == [N, 2]
/// [1, 2].shape() == [2,] /// [1, 2].shape() == [2,]
/// [[1, 2], [3, 4], [5, 6]].shape() == [3, 2] /// [[1, 2], [3, 4], [5, 6]].shape() == [3, 2]
/// ``` /// ```
pub(crate) fn array_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> { pub(crate) fn list_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let res = _arr_shape(arr, ctx).unwrap(); let res = _lis_shape(val, ctx).unwrap();
let arr = TyParam::Array(res); let lis = TyParam::List(res);
Ok(arr) 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 { loop {
if matches!(&typ.qual_name()[..], "Array" | "Array!" | "UnsizedArray") { if matches!(&typ.qual_name()[..], "List" | "List!" | "UnsizedList") {
let tp = typ.typarams().remove(0); let tp = typ.typarams().remove(0);
match ctx.convert_tp_into_type(tp) { match ctx.convert_tp_into_type(tp) {
Ok(typ_) => { 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 let slf = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let Ok(slf) = ctx.convert_value_into_type(slf.clone()) else { let Ok(slf) = ctx.convert_value_into_type(slf.clone()) else {
return Err(type_mismatch("Type", slf, "Self")); 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)) Ok(TyParam::t(res))
} }
fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> { fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
loop { loop {
match value { match value {
ValueObj::Array(a) => match a.first() { ValueObj::List(a) => match a.first() {
Some(elem) => { Some(elem) => {
value = elem.clone(); value = elem.clone();
} }
@ -592,7 +592,7 @@ fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
return Ok(Type::Never); return Ok(Type::Never);
} }
}, },
ValueObj::UnsizedArray(a) => { ValueObj::UnsizedList(a) => {
value = *a.clone(); value = *a.clone();
} }
other => { other => {
@ -608,17 +608,17 @@ fn _scalar_type(mut value: ValueObj, _ctx: &Context) -> Result<Type, String> {
/// ``` /// ```
#[allow(unused)] #[allow(unused)]
pub(crate) fn scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> { pub(crate) fn scalar_type(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let res = _scalar_type(arr, ctx).unwrap(); let res = _scalar_type(val, ctx).unwrap();
let arr = TyParam::t(res); let lis = TyParam::t(res);
Ok(arr) Ok(lis)
} }
fn _array_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> { fn _list_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr { match arr {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut sum = 0f64; let mut sum = 0f64;
for v in a.iter() { for v in a.iter() {
match v { match v {
@ -657,18 +657,18 @@ fn _array_sum(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
/// ```erg /// ```erg
/// [1, 2].sum() == [3,] /// [1, 2].sum() == [3,]
/// ``` /// ```
pub(crate) fn array_sum(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> { pub(crate) fn list_sum(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let res = _array_sum(arr, ctx).unwrap(); let res = _list_sum(val, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
fn _array_prod(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> { fn _list_prod(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr { match lis {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut prod = 1f64; let mut prod = 1f64;
for v in a.iter() { for v in a.iter() {
match v { match v {
@ -700,63 +700,63 @@ fn _array_prod(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
Ok(ValueObj::Float(prod)) Ok(ValueObj::Float(prod))
} }
} }
_ => Err(format!("Cannot prod {arr}")), _ => Err(format!("Cannot prod {lis}")),
} }
} }
/// ```erg /// ```erg
/// [1, 2].prod() == [2,] /// [1, 2].prod() == [2,]
/// ``` /// ```
pub(crate) fn array_prod(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> { pub(crate) fn list_prod(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let res = _array_prod(arr, ctx).unwrap(); let res = _list_prod(val, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
fn _array_reversed(arr: ValueObj, _ctx: &Context) -> Result<ValueObj, String> { fn _list_reversed(lis: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr { match lis {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut vec = a.to_vec(); let mut vec = a.to_vec();
vec.reverse(); 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> { pub(crate) fn list_reversed(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let res = _array_reversed(arr, ctx).unwrap(); let res = _list_reversed(val, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
fn _array_insert_at( fn _list_insert_at(
arr: ValueObj, lis: ValueObj,
index: usize, index: usize,
value: ValueObj, value: ValueObj,
_ctx: &Context, _ctx: &Context,
) -> Result<ValueObj, String> { ) -> Result<ValueObj, String> {
match arr { match lis {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut a = a.to_vec(); let mut a = a.to_vec();
if index > a.len() { if index > a.len() {
return Err(format!("Index out of range: {index}")); return Err(format!("Index out of range: {index}"));
} }
a.insert(index, value); 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> { pub(crate) fn list_insert_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let lis = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let index = args 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 { let Ok(index) = usize::try_from(&index) else {
return Err(type_mismatch("Nat", index, "Index")); return Err(type_mismatch("Nat", index, "Index"));
}; };
let res = _array_insert_at(arr, index, value, ctx).unwrap(); let res = _list_insert_at(lis, index, value, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
fn _array_remove_at(arr: ValueObj, index: usize, _ctx: &Context) -> Result<ValueObj, String> { fn _list_remove_at(lis: ValueObj, index: usize, _ctx: &Context) -> Result<ValueObj, String> {
match arr { match lis {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut a = a.to_vec(); let mut a = a.to_vec();
if index >= a.len() { if index >= a.len() {
return Err(format!("Index out of range: {index}")); return Err(format!("Index out of range: {index}"));
} }
a.remove(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> { pub(crate) fn list_remove_at(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let index = args 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 { let Ok(index) = usize::try_from(&index) else {
return Err(type_mismatch("Nat", index, "Index")); return Err(type_mismatch("Nat", index, "Index"));
}; };
let res = _array_remove_at(arr, index, ctx).unwrap(); let res = _list_remove_at(val, index, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
fn _array_remove_all(arr: ValueObj, value: ValueObj, _ctx: &Context) -> Result<ValueObj, String> { fn _list_remove_all(lis: ValueObj, value: ValueObj, _ctx: &Context) -> Result<ValueObj, String> {
match arr { match lis {
ValueObj::Array(a) => { ValueObj::List(a) => {
let mut a = a.to_vec(); let mut a = a.to_vec();
a.retain(|v| v != &value); 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> { pub(crate) fn list_remove_all(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<TyParam> {
let arr = args let val = args
.remove_left_or_key("Self") .remove_left_or_key("Self")
.ok_or_else(|| not_passed("Self"))?; .ok_or_else(|| not_passed("Self"))?;
let value = args let value = args
.remove_left_or_key("Value") .remove_left_or_key("Value")
.ok_or_else(|| not_passed("Value"))?; .ok_or_else(|| not_passed("Value"))?;
let res = _array_remove_all(arr, value, ctx).unwrap(); let res = _list_remove_all(val, value, ctx).unwrap();
let arr = TyParam::Value(res); let lis = TyParam::Value(res);
Ok(arr) Ok(lis)
} }
pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> { 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")); return Err(type_mismatch("Str", slf, "self"));
}; };
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), ValueObj::Set(s) => s.into_iter().collect(),
ValueObj::Dict(d) => d.into_keys().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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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> { 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let len = match container { let len = match container {
ValueObj::Array(a) => a.len(), ValueObj::List(a) => a.len(),
ValueObj::Tuple(t) => t.len(), ValueObj::Tuple(t) => t.len(),
ValueObj::Set(s) => s.len(), ValueObj::Set(s) => s.len(),
ValueObj::Dict(d) => d.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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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> { 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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") .remove_left_or_key("reversible")
.ok_or_else(|| not_passed("reversible"))?; .ok_or_else(|| not_passed("reversible"))?;
let arr = match reversible { let arr = match reversible {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
_ => { _ => {
return Err(type_mismatch("Reversible", reversible, "reversible")); 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() { for v in arr.into_iter().rev() {
reversed.push(v); 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> { 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") .remove_left_or_key("iterable")
.ok_or_else(|| not_passed("iterable"))?; .ok_or_else(|| not_passed("iterable"))?;
let arr = match iterable { let arr = match iterable {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), ValueObj::Set(s) => s.into_iter().collect(),
ValueObj::Dict(d) => d.into_keys().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") .remove_left_or_key("iterable2")
.ok_or_else(|| not_passed("iterable2"))?; .ok_or_else(|| not_passed("iterable2"))?;
let iterable1 = match iterable1 { let iterable1 = match iterable1 {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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 { let iterable2 = match iterable2 {
ValueObj::Array(a) => a.to_vec(), ValueObj::List(a) => a.to_vec(),
ValueObj::Tuple(t) => t.to_vec(), ValueObj::Tuple(t) => t.to_vec(),
ValueObj::Set(s) => s.into_iter().collect(), 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()) { for (v1, v2) in iterable1.into_iter().zip(iterable2.into_iter()) {
zipped.push(ValueObj::Tuple(vec![v1, v2].into())); zipped.push(ValueObj::Tuple(vec![v1, v2].into()));
} }
Ok(TyParam::Value(ValueObj::Array(zipped.into()))) Ok(TyParam::Value(ValueObj::List(zipped.into())))
} }
/// ```erg /// ```erg

View file

@ -53,12 +53,6 @@ impl Context {
None, None,
))); )));
let t_ascii = nd_func(vec![kw(KW_OBJECT, Obj)], None, Str); 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_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_bin = nd_func(vec![kw(KW_N, Int)], None, Str);
let t_bytes = func0(mono(BYTES)) let t_bytes = func0(mono(BYTES))
@ -182,7 +176,7 @@ impl Context {
let t_isinstance = nd_func( let t_isinstance = nd_func(
vec![ vec![
kw(KW_OBJECT, Obj), 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, None,
Bool, Bool,
@ -190,7 +184,7 @@ impl Context {
let t_issubclass = nd_func( let t_issubclass = nd_func(
vec![ vec![
kw(KW_SUBCLASS, ClassType), 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, None,
Bool, Bool,
@ -216,6 +210,12 @@ impl Context {
t_len.clone(), t_len.clone(),
None, 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( let t_log = func(
vec![], vec![],
Some(kw(KW_OBJECTS, ref_(Obj))), Some(kw(KW_OBJECTS, ref_(Obj))),
@ -341,7 +341,7 @@ impl Context {
let t_sorted = nd_func( let t_sorted = nd_func(
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))], vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
None, None,
array_t(T.clone(), TyParam::erased(Nat)), list_t(T.clone(), TyParam::erased(Nat)),
) )
.quantify(); .quantify();
let t_staticmethod = nd_func(vec![kw(KW_FUNC, F.clone())], None, F.clone()).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(FUNC_ANY),
Some(33), 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); self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53);
// Leave as `Const`, as it may negatively affect assert casting. // Leave as `Const`, as it may negatively affect assert casting.
let name = if PYTHON_MODE { FUNC_ASSERT } else { "assert__" }; 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 PATH: &str = "Path";
const MODULE: &str = "Module"; const MODULE: &str = "Module";
const PY_MODULE: &str = "PyModule"; const PY_MODULE: &str = "PyModule";
const GENERIC_ARRAY: &str = "GenericArray"; const GENERIC_LIST: &str = "GenericList";
const UNSIZED_ARRAY: &str = "UnsizedArray"; const UNSIZED_LIST: &str = "UnsizedList";
const ARRAY: &str = "Array"; const LIST: &str = "List";
const MUT_ARRAY: &str = "Array!"; const MUT_LIST: &str = "List!";
const FUNC_UPDATE_NTH: &str = "update_nth"; const FUNC_UPDATE_NTH: &str = "update_nth";
const PROC_UPDATE_NTH: &str = "update_nth!"; const PROC_UPDATE_NTH: &str = "update_nth!";
const FUNC_PARTITION: &str = "partition"; const FUNC_PARTITION: &str = "partition";
@ -273,7 +273,7 @@ const FUNC_REPEAT: &str = "repeat";
const PROC_PUSH: &str = "push!"; const PROC_PUSH: &str = "push!";
const FUNC_MERGE: &str = "merge"; const FUNC_MERGE: &str = "merge";
const PROC_MERGE: &str = "merge!"; const PROC_MERGE: &str = "merge!";
const ARRAY_ITERATOR: &str = "ArrayIterator"; const LIST_ITERATOR: &str = "ListIterator";
const GENERIC_SET: &str = "GenericSet"; const GENERIC_SET: &str = "GenericSet";
const SET: &str = "Set"; const SET: &str = "Set";
const MUT_SET: &str = "Set!"; const MUT_SET: &str = "Set!";
@ -375,7 +375,7 @@ const FUNC_DICT: &str = "dict";
const FUNC_TUPLE: &str = "tuple"; const FUNC_TUPLE: &str = "tuple";
const UNION: &str = "Union"; const UNION: &str = "Union";
const FUNC_STR_ITERATOR: &str = "str_iterator"; 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_SET_ITERATOR: &str = "set_iterator";
const FUNC_TUPLE_ITERATOR: &str = "tuple_iterator"; const FUNC_TUPLE_ITERATOR: &str = "tuple_iterator";
const FUNC_ENUMERATE: &str = "enumerate"; const FUNC_ENUMERATE: &str = "enumerate";
@ -391,7 +391,7 @@ const FUNC_NTH: &str = "nth";
const FUNC_SKIP: &str = "skip"; const FUNC_SKIP: &str = "skip";
const FUNC_POSITION: &str = "position"; const FUNC_POSITION: &str = "position";
const FUNC_CHAIN: &str = "chain"; const FUNC_CHAIN: &str = "chain";
const FUNC_INTO_ARRAY: &str = "into_array"; const FUNC_TO_LIST: &str = "to_list";
const FILE: &str = "File"; const FILE: &str = "File";
const CALLABLE: &str = "Callable"; const CALLABLE: &str = "Callable";
const GENERATOR: &str = "Generator"; const GENERATOR: &str = "Generator";
@ -478,7 +478,6 @@ const USER_WARNING: &str = "UserWarning";
const FUNC_RANGE: &str = "range"; const FUNC_RANGE: &str = "range";
const FUNC_ALL: &str = "all"; const FUNC_ALL: &str = "all";
const FUNC_ANY: &str = "any"; const FUNC_ANY: &str = "any";
const FUNC_ARRAY: &str = "array";
const FUNC_ASCII: &str = "ascii"; const FUNC_ASCII: &str = "ascii";
const FUNC_ASSERT: &str = "assert"; const FUNC_ASSERT: &str = "assert";
const FUNC_BIN: &str = "bin"; const FUNC_BIN: &str = "bin";
@ -1071,7 +1070,7 @@ impl Context {
}; };
let qual_name = t.qual_name(); let qual_name = t.qual_name();
let name = VarName::from_str(t.local_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 let nd_params = ctx
.params_spec .params_spec
.iter() .iter()

View file

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

View file

@ -80,7 +80,7 @@ impl Context {
); );
readable.register_builtin_decl( readable.register_builtin_decl(
PROC_READLINES, 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, Visibility::BUILTIN_PUBLIC,
Some(FUNC_READLINES), Some(FUNC_READLINES),
); );
@ -263,7 +263,7 @@ impl Context {
); );
let ret_t = poly( let ret_t = poly(
TUPLE, 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(); let t_enumerate = fn0_met(Slf.clone(), poly(ITERATOR, vec![ty_tp(ret_t)])).quantify();
iterable.register_builtin_decl( iterable.register_builtin_decl(
@ -362,10 +362,10 @@ impl Context {
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some("Function::iterable_chain"), 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( iterable.register_builtin_decl(
FUNC_INTO_ARRAY, FUNC_TO_LIST,
t_into_array, t_to_list,
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
Some("Function::list"), Some("Function::list"),
); );
@ -514,8 +514,8 @@ impl Context {
Visibility::BUILTIN_PUBLIC, Visibility::BUILTIN_PUBLIC,
); );
/* HasShape */ /* HasShape */
let S = mono_q_tp(TY_S, instanceof(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_array_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); let has_shape = Self::builtin_poly_trait(HAS_SHAPE, params.clone(), 2);
/* HasScalarType */ /* HasScalarType */
let Ty = mono_q_tp(TY_T, instanceof(Type)); 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 { pub fn meta_type(&self, typ: &Type) -> Type {
match typ { match typ {
Type::Poly { name, params } if &name[..] == "Array" || &name[..] == "Set" => poly( Type::Poly { name, params } if &name[..] == "List" || &name[..] == "Set" => poly(
name.clone(), name.clone(),
params params
.iter() .iter()
@ -3743,7 +3743,7 @@ impl Context {
/// ```erg /// ```erg
/// recover_typarams(Int, Nat) == Nat /// 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"} /// recover_typarams(Str or NoneType, {"a", "b"}) == {"a", "b"}
/// ``` /// ```
/// ```erg /// ```erg
@ -3773,7 +3773,7 @@ impl Context {
))); )));
} }
} }
// Array(Nat, 2) !<: Array!(Int, _) // List(Nat, 2) !<: List!(Int, _)
let base_def_t = self let base_def_t = self
.get_nominal_type_ctx(base) .get_nominal_type_ctx(base)
.map(|ctx| &ctx.typ) .map(|ctx| &ctx.typ)
@ -3783,7 +3783,7 @@ impl Context {
.map(|ctx| &ctx.typ) .map(|ctx| &ctx.typ)
.unwrap_or(&Type::Obj); .unwrap_or(&Type::Obj);
if self.related(base_def_t, assert_def_t) { 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()); let casted = poly(base.qual_name(), guard.to.typarams());
Ok(casted) Ok(casted)
} else { } 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`. /// 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`. /// 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 /// FIXME: current implementation is wrong
/// It will not work unless the type variable is used with the same name as the definition. /// It will not work unless the type variable is used with the same name as the definition.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -468,16 +468,16 @@ impl Context {
.collect::<TyCheckResult<_>>()?; .collect::<TyCheckResult<_>>()?;
Ok(TyParam::Dict(dict)) Ok(TyParam::Dict(dict))
} }
TyParam::Array(arr) => { TyParam::List(lis) => {
let arr = arr let lis = lis
.into_iter() .into_iter()
.map(|v| self.instantiate_tp(v, tmp_tv_cache, loc)) .map(|v| self.instantiate_tp(v, tmp_tv_cache, loc))
.collect::<TyCheckResult<_>>()?; .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)?; 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) => { TyParam::Set(set) => {
let set = set let set = set
@ -706,12 +706,12 @@ impl Context {
Ok(ValueObj::Subr(ConstSubr::User(user))) Ok(ValueObj::Subr(ConstSubr::User(user)))
} }
}, },
ValueObj::Array(arr) => { ValueObj::List(lis) => {
let mut new = vec![]; 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)?); new.push(self.instantiate_value(v, tmp_tv_cache, loc)?);
} }
Ok(ValueObj::Array(new.into())) Ok(ValueObj::List(new.into()))
} }
ValueObj::Tuple(tup) => { ValueObj::Tuple(tup) => {
let mut new = vec![]; let mut new = vec![];

View file

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

View file

@ -645,7 +645,7 @@ pub struct Context {
pub(crate) mono_types: Dict<VarName, TypeContext>, pub(crate) mono_types: Dict<VarName, TypeContext>,
// Implementation Contexts for Polymorphic Types // Implementation Contexts for Polymorphic Types
// Vec<TyParam> are specialization parameters // 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>, pub(crate) poly_types: Dict<VarName, TypeContext>,
// patches can be accessed like normal records // patches can be accessed like normal records
// but when used as a fallback to a type, values are traversed instead of accessing by keys // 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::{ use crate::ty::constructors::{
free_var, func, func0, func1, module, proc, py_module, ref_, ref_mut, str_dict_t, tp_enum, 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::free::{Constraint, HasLevel};
use crate::ty::typaram::TyParam; use crate::ty::typaram::TyParam;
@ -397,7 +397,7 @@ impl Context {
Err((ty, errs)) => (ty, errs), Err((ty, errs)) => (ty, errs),
}; };
let spec_t = match kind { 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), ParamKind::KwVarParams => str_dict_t(spec_t),
_ => spec_t, _ => spec_t,
}; };
@ -577,7 +577,7 @@ impl Context {
} }
if let Some(var_params) = &mut params.var_params { if let Some(var_params) = &mut params.var_params {
if let Some(pt) = &subr_t.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) = if let Err(es) =
self.assign_param(var_params, Some(&pt), tmp_tv_cache, ParamKind::VarParams) self.assign_param(var_params, Some(&pt), tmp_tv_cache, ParamKind::VarParams)
{ {
@ -2764,9 +2764,9 @@ impl Context {
} }
res res
} }
ast::Expr::Array(ast::Array::Normal(arr)) => { ast::Expr::List(ast::List::Normal(lis)) => {
let mut res = false; 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) { if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
res = true; res = true;
} }

View file

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

View file

@ -12,7 +12,7 @@ use erg_parser::desugar::Desugarer;
use crate::context::instantiate::TyVarCache; use crate::context::instantiate::TyVarCache;
use crate::context::{ClassDefType, Context, MethodContext, MethodPair, TraitImpl}; use crate::context::{ClassDefType, Context, MethodContext, MethodPair, TraitImpl};
use crate::lower::GenericASTLowerer; 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::free::{Constraint, HasLevel};
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{HasType, TyParam, Type, Visibility}; 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())) 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 { match arr {
ast::Array::WithLength(arr) => { ast::List::WithLength(lis) => {
let len = self.fake_lower_expr(*arr.len)?; let len = self.fake_lower_expr(*lis.len)?;
let elem = self.fake_lower_expr(arr.elem.expr)?; let elem = self.fake_lower_expr(lis.elem.expr)?;
Ok(hir::Array::WithLength(hir::ArrayWithLength::new( Ok(hir::List::WithLength(hir::ListWithLength::new(
arr.l_sqbr, lis.l_sqbr,
arr.r_sqbr, lis.r_sqbr,
Type::Failure, Type::Failure,
elem, elem,
Some(len), Some(len),
))) )))
} }
ast::Array::Normal(arr) => { ast::List::Normal(lis) => {
let mut elems = Vec::new(); let mut elems = Vec::new();
let (elems_, ..) = arr.elems.deconstruct(); let (elems_, ..) = lis.elems.deconstruct();
for elem in elems_.into_iter() { for elem in elems_.into_iter() {
let elem = self.fake_lower_expr(elem.expr)?; let elem = self.fake_lower_expr(elem.expr)?;
elems.push(hir::PosArg::new(elem)); elems.push(hir::PosArg::new(elem));
} }
let elems = hir::Args::new(elems, None, vec![], None, None); let elems = hir::Args::new(elems, None, vec![], None, None);
let t = array_t(Type::Failure, TyParam::value(elems.len())); let t = list_t(Type::Failure, TyParam::value(elems.len()));
Ok(hir::Array::Normal(hir::NormalArray::new( Ok(hir::List::Normal(hir::NormalList::new(
arr.l_sqbr, arr.r_sqbr, t, elems, lis.l_sqbr, lis.r_sqbr, t, elems,
))) )))
} }
other => Err(LowerErrors::from(LowerError::declare_error( 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::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::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::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::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::Record(rec) => Ok(hir::Expr::Record(self.fake_lower_record(rec)?)),
ast::Expr::Set(set) => Ok(hir::Expr::Set(self.fake_lower_set(set)?)), 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::context::Context;
use crate::error::{EffectError, EffectErrors}; 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}; use crate::ty::{HasType, Visibility};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -134,21 +134,21 @@ impl<'c> SideEffectChecker<'c> {
self.check_expr(&unary.expr); self.check_expr(&unary.expr);
} }
Expr::Accessor(_) | Expr::Literal(_) => {} Expr::Accessor(_) | Expr::Literal(_) => {}
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
for elem in arr.elems.pos_args.iter() { for elem in lis.elems.pos_args.iter() {
self.check_expr(&elem.expr); self.check_expr(&elem.expr);
} }
} }
Array::WithLength(arr) => { List::WithLength(lis) => {
self.check_expr(&arr.elem); self.check_expr(&lis.elem);
if let Some(len) = &arr.len { if let Some(len) = &lis.len {
self.check_expr(len); self.check_expr(len);
} }
} }
Array::Comprehension(arr) => { List::Comprehension(lis) => {
self.check_expr(&arr.elem); self.check_expr(&lis.elem);
self.check_expr(&arr.guard); self.check_expr(&lis.guard);
} }
}, },
Expr::Tuple(tuple) => match tuple { Expr::Tuple(tuple) => match tuple {
@ -350,21 +350,21 @@ impl<'c> SideEffectChecker<'c> {
self.check_expr(def); self.check_expr(def);
} }
} }
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
for elem in arr.elems.pos_args.iter() { for elem in lis.elems.pos_args.iter() {
self.check_expr(&elem.expr); self.check_expr(&elem.expr);
} }
} }
Array::WithLength(arr) => { List::WithLength(lis) => {
self.check_expr(&arr.elem); self.check_expr(&lis.elem);
if let Some(len) = &arr.len { if let Some(len) = &lis.len {
self.check_expr(len); self.check_expr(len);
} }
} }
Array::Comprehension(arr) => { List::Comprehension(lis) => {
self.check_expr(&arr.elem); self.check_expr(&lis.elem);
self.check_expr(&arr.guard); self.check_expr(&lis.guard);
} }
}, },
Expr::Tuple(tuple) => match tuple { 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::BinOp(bin) => Self::is_impure(&bin.lhs) || Self::is_impure(&bin.rhs),
Expr::UnaryOp(unary) => Self::is_impure(&unary.expr), Expr::UnaryOp(unary) => Self::is_impure(&unary.expr),
Expr::Array(arr) => match arr { Expr::List(lis) => match lis {
Array::Normal(arr) => arr List::Normal(lis) => lis
.elems .elems
.pos_args .pos_args
.iter() .iter()
.any(|elem| Self::is_impure(&elem.expr)), .any(|elem| Self::is_impure(&elem.expr)),
Array::WithLength(arr) => { List::WithLength(lis) => {
Self::is_impure(&arr.elem) Self::is_impure(&lis.elem)
|| arr.len.as_ref().map_or(false, |len| Self::is_impure(len)) || lis.len.as_ref().map_or(false, |len| Self::is_impure(len))
} }
_ => todo!(), _ => todo!(),
}, },

View file

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

View file

@ -1,9 +1,9 @@
# TODO: transition specifications # TODO: transition specifications
array = pyimport "Array" array = pyimport "List"
.Array!: ClassType .List!: ClassType
.Array! <: array.Array .List! <: array.List
.Array!. .List!.
''' '''
Append object to the end of the list. Append object to the end of the list.
''' '''
@ -12,7 +12,7 @@ array = pyimport "Array"
arr.push! 3 arr.push! 3
assert arr == [1, 2, 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`. Extend the list by appending all the items from `iterable`.
''' '''
@ -21,7 +21,7 @@ array = pyimport "Array"
arr.extend! [3, 4] arr.extend! [3, 4]
assert arr == [1, 2, 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`. Insert `elem` before `index`.
''' '''
@ -30,7 +30,7 @@ array = pyimport "Array"
arr.insert! 0, 3 arr.insert! 0, 3
assert arr == [3, 1, 2] 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`. Remove the first item from the list whose value is `value`.
''' '''
@ -39,7 +39,7 @@ array = pyimport "Array"
arr.remove! 1 arr.remove! 1
assert arr == [2] 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. Remove the item at the given position in the list, and return it.
''' '''
@ -49,7 +49,7 @@ array = pyimport "Array"
assert arr == [1] assert arr == [1]
assert i == 2 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. Remove all items from the list.
''' '''
@ -58,7 +58,7 @@ array = pyimport "Array"
arr.clear!() arr.clear!()
assert arr == [] 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`. Sort the list in ascending order and return `None`.
@ -75,7 +75,7 @@ array = pyimport "Array"
arr.sort!() arr.sort!()
assert arr == [1, 2, 3] 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`. Reverse the elements of the list in-place and return `None`.
''' '''
@ -84,7 +84,7 @@ array = pyimport "Array"
arr.reverse!() arr.reverse!()
assert arr == [2, 1, 3] 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`. 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 arr.strict_map! x -> x + 1
assert arr == [3, 4] 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`. 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 arr.udpate_nth! 0, x -> x + 1
assert arr == [2, 2] 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. Return a (deep) copy of the array.
''' '''
@ -113,4 +113,4 @@ array = pyimport "Array"
assert arr_copy == [1, 2, 3] assert arr_copy == [1, 2, 3]
assert arr == [1, 2] 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 .List: ClassType
.Array. .List.
''' '''
Concatenates two arrays. Same as `self + other`. Concatenates two arrays. Same as `self + other`.
''' '''
'''erg '''erg
assert [1, 2].concat([3, 4]) == [1, 2, 3, 4] 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. Returns the number of elements in the array.
''' '''
@ -14,7 +14,7 @@
assert [1, 2, 3, 1, 2].count(1) == 2 assert [1, 2, 3, 1, 2].count(1) == 2
assert ["a", "b", "c"].count("a") == 1 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. Remove array duplicates.
@ -25,7 +25,7 @@
assert [1, 1, 2].dedup() == [1, 2] 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] 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. Create two arrays according to the `predicate` function.
@ -34,25 +34,25 @@
'''erg '''erg
assert [-2, -1, 0, 1, 2].partition(x -> x >= 0) == ([0, 1, 2], [-2, -1]) 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. Returns the summation of all elements in the array.
''' '''
'''erg '''erg
assert [1, 2, 3].sum() == 6 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. Returns the product of all elements in the array.
''' '''
'''erg '''erg
assert [1, 2, 3].product() == 6 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. Returns the reversed array.
''' '''
'''erg '''erg
assert [1, 2, 3].reversed() == [3, 2, 1] 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 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 return type_check and len_check
elif _isinstance(elem, list): 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): elif callable(elem):
# TODO: # TODO:
return callable(y) return callable(y)

View file

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

View file

@ -1,5 +1,5 @@
# HACK: import MutType to suppress segfault in CPython 3.10 (cause unknown) # 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_bool import Bool
from _erg_bytes import Bytes from _erg_bytes import Bytes
from _erg_contains_operator import contains_operator from _erg_contains_operator import contains_operator

View file

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

View file

@ -1,4 +1,4 @@
.heappush!: |T: Type|(heap: Iterable(T), item: T) => NoneType # TODO: Push! .heappush!: |T: Type|(heap: Iterable(T), item: T) => NoneType # TODO: Push!
.heappop!: |T: Type|(heap: Iterable(T)) => T # TODO: Pop! .heappop!: |T: Type|(heap: Iterable(T)) => T # TODO: Pop!
.heappushpop!: |T: Type|(heap: Iterable(T), item: T) => T # TODO: Push! and 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; .seed_bits = Nat;
.cutoff = Int; .cutoff = Int;
} }
.path: Array!(Str, _) .path: List!(Str, _)
''' '''
* AIX -> 'aix' * AIX -> 'aix'
* FreeBSD -> 'freebsd' * FreeBSD -> 'freebsd'

View file

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

View file

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

View file

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

View file

@ -23,7 +23,7 @@ use crate::context::{Context, ContextProvider, ModuleContext};
use crate::desugar_hir::HIRDesugarer; use crate::desugar_hir::HIRDesugarer;
use crate::error::{CompileError, CompileErrors, CompileResult}; use crate::error::{CompileError, CompileErrors, CompileResult};
use crate::hir::{ 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, Literal, Params, PatchDef, ReDef, Record, Set, Signature, Tuple, UnaryOp, HIR,
}; };
use crate::link_hir::HIRLinker; use crate::link_hir::HIRLinker;
@ -476,7 +476,7 @@ impl PyScriptGenerator {
.replace("from _erg_str import Str", "") .replace("from _erg_str import Str", "")
.replace("from _erg_float import FloatMut", "") .replace("from _erg_float import FloatMut", "")
.replace("from _erg_float import Float", "") .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_range import Range", "")
.replace("from _erg_result import Error", "") .replace("from _erg_result import Error", "")
.replace("from _erg_result import is_ok", "") .replace("from _erg_result import is_ok", "")
@ -531,7 +531,7 @@ impl PyScriptGenerator {
self.load_contains_op_if_not(); self.load_contains_op_if_not();
if self.range_ops_loaded { 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_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_dict.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_set.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")); 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_bool.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_str.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_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_dict.py"));
self.prelude += &Self::replace_import(include_str!("lib/core/_erg_set.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")); 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::Call(call) => self.transpile_call(call),
Expr::BinOp(bin) => self.transpile_binop(bin), Expr::BinOp(bin) => self.transpile_binop(bin),
Expr::UnaryOp(unary) => self.transpile_unaryop(unary), Expr::UnaryOp(unary) => self.transpile_unaryop(unary),
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
self.load_builtin_types_if_not(); self.load_builtin_types_if_not();
let mut code = "Array([".to_string(); let mut code = "List([".to_string();
for elem in arr.elems.pos_args { for elem in lis.elems.pos_args {
code += &format!("{},", self.transpile_expr(elem.expr)); code += &format!("{},", self.transpile_expr(elem.expr));
} }
code += "])"; code += "])";
@ -762,7 +762,7 @@ impl PyScriptGenerator {
prefix.push('('); prefix.push('(');
} }
other => { 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(); self.load_builtin_types_if_not();
prefix.push_str(t); prefix.push_str(t);
prefix.push('('); prefix.push('(');
@ -773,9 +773,9 @@ impl PyScriptGenerator {
match acc { match acc {
Accessor::Ident(ident) => { Accessor::Ident(ident) => {
match &ident.inspect()[..] { 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!" | "Set" | "Str!" | "Bytes!" | "Bool!" | "Nat!" | "Int!" | "Float!"
| "Array!" => { | "List!" => {
self.load_builtin_types_if_not(); self.load_builtin_types_if_not();
} }
"if" | "if!" | "for!" | "while" | "discard" => { "if" | "if!" | "for!" | "while" | "discard" => {
@ -1288,24 +1288,24 @@ impl JsonGenerator {
fn expr_into_value(&self, expr: Expr) -> Option<ValueObj> { fn expr_into_value(&self, expr: Expr) -> Option<ValueObj> {
match expr { match expr {
Expr::Array(Array::Normal(arr)) => { Expr::List(List::Normal(lis)) => {
let mut vals = vec![]; 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) { if let Some(val) = self.expr_into_value(elem.expr) {
vals.push(val); vals.push(val);
} else { } else {
return None; return None;
} }
} }
Some(ValueObj::Array(vals.into())) Some(ValueObj::List(vals.into()))
} }
Expr::Array(Array::WithLength(arr)) => { Expr::List(List::WithLength(lis)) => {
let len = arr let len = lis
.len .len
.and_then(|len| self.expr_into_value(*len)) .and_then(|len| self.expr_into_value(*len))
.and_then(|v| usize::try_from(&v).ok())?; .and_then(|v| usize::try_from(&v).ok())?;
let vals = vec![self.expr_into_value(*arr.elem)?; len]; let vals = vec![self.expr_into_value(*lis.elem)?; len];
Some(ValueObj::Array(vals.into())) Some(ValueObj::List(vals.into()))
} }
Expr::Tuple(Tuple::Normal(tup)) => { Expr::Tuple(Tuple::Normal(tup)) => {
let mut vals = vec![]; let mut vals = vec![];
@ -1379,10 +1379,10 @@ impl JsonGenerator {
replace_non_symbolic(&acc.to_string()) replace_non_symbolic(&acc.to_string())
} }
} }
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
let mut code = "[".to_string(); 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 { if i > 0 {
code += ", "; 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)) Type::FreeVar(Free::new_named_unbound(name, 1, Constraint::Uninited))
} }
pub fn array_t(elem_t: Type, len: TyParam) -> Type { pub fn list_t(elem_t: Type, len: TyParam) -> Type {
poly("Array", vec![TyParam::t(elem_t), len]) poly("List", vec![TyParam::t(elem_t), len])
} }
pub fn array_mut(elem_t: Type, len: TyParam) -> Type { pub fn list_mut(elem_t: Type, len: TyParam) -> Type {
poly("Array!", vec![TyParam::t(elem_t), len]) poly("List!", vec![TyParam::t(elem_t), len])
} }
pub fn unknown_len_array_t(elem_t: Type) -> Type { pub fn unknown_len_list_t(elem_t: Type) -> Type {
array_t(elem_t, TyParam::erased(Type::Nat)) list_t(elem_t, TyParam::erased(Type::Nat))
} }
pub fn unknown_len_array_mut(elem_t: Type) -> Type { pub fn unknown_len_list_mut(elem_t: Type) -> Type {
array_mut(elem_t, TyParam::erased(Type::Nat)) list_mut(elem_t, TyParam::erased(Type::Nat))
} }
pub fn str_dict_t(value: Type) -> Type { pub fn str_dict_t(value: Type) -> Type {
dict! { Type::Str => value }.into() dict! { Type::Str => value }.into()
} }
/// `UnsizedArray` is a type of `[x; _]` (unsized array literal). /// `UnsizedList` is a type of `[x; _]` (unsized list literal).
/// `UnsizedArray(T) != Array(T, _)` /// `UnsizedList(T) != List(T, _)`
pub fn unsized_array_t(elem_t: Type) -> Type { pub fn unsized_list_t(elem_t: Type) -> Type {
poly("UnsizedArray", vec![TyParam::t(elem_t)]) poly("UnsizedList", vec![TyParam::t(elem_t)])
} }
pub fn tuple_t(args: Vec<Type>) -> Type { pub fn tuple_t(args: Vec<Type>) -> Type {
poly( poly(
"Tuple", "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 erg_common::{ArcArray, Str};
use super::codeobj::{CodeObj, FastKind}; use super::codeobj::{CodeObj, FastKind};
use super::constructors::array_t; use super::constructors::list_t;
use super::typaram::TyParam; use super::typaram::TyParam;
use super::value::ValueObj; use super::value::ValueObj;
use super::{HasType, Type}; use super::{HasType, Type};
@ -140,7 +140,7 @@ impl Deserializer {
} }
fn get_cached_arr(&mut self, arr: &[ValueObj]) -> ValueObj { 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] { pub fn vec_to_bytes<const LEN: usize>(vector: Vec<u8>) -> [u8; LEN] {
@ -226,7 +226,7 @@ impl Deserializer {
field: Option<&str>, field: Option<&str>,
) -> DeserializeResult<Vec<ValueObj>> { ) -> DeserializeResult<Vec<ValueObj>> {
match self.deserialize_const(v, python_ver)? { 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( other => Err(DeserializeError::type_error(
field, field,
&Type::Str, &Type::Str,
@ -242,7 +242,7 @@ impl Deserializer {
field: Option<&str>, field: Option<&str>,
) -> DeserializeResult<ArcArray<ValueObj>> { ) -> DeserializeResult<ArcArray<ValueObj>> {
match self.deserialize_const(v, python_ver)? { match self.deserialize_const(v, python_ver)? {
ValueObj::Array(arr) => Ok(arr), ValueObj::List(lis) => Ok(lis),
other => Err(DeserializeError::type_error( other => Err(DeserializeError::type_error(
field, field,
&Type::Str, &Type::Str,
@ -273,16 +273,16 @@ impl Deserializer {
field: Option<&str>, field: Option<&str>,
) -> DeserializeResult<Vec<Str>> { ) -> DeserializeResult<Vec<Str>> {
match self.deserialize_const(v, python_ver)? { match self.deserialize_const(v, python_ver)? {
ValueObj::Array(arr) | ValueObj::Tuple(arr) => { ValueObj::List(lis) | ValueObj::Tuple(lis) => {
let mut strs = Vec::with_capacity(arr.len()); let mut strs = Vec::with_capacity(lis.len());
for c in arr.iter().cloned() { for c in lis.iter().cloned() {
strs.push(self.try_into_str(c)?); strs.push(self.try_into_str(c)?);
} }
Ok(strs) Ok(strs)
} }
other => Err(DeserializeError::type_error( other => Err(DeserializeError::type_error(
field, field,
&array_t(Type::Str, TyParam::erased(Type::Nat)), &list_t(Type::Str, TyParam::erased(Type::Nat)),
&other.class(), &other.class(),
)), )),
} }

View file

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

View file

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

View file

@ -25,7 +25,7 @@ use crate::context::Context;
use self::value_set::inner_class; use self::value_set::inner_class;
use super::codeobj::{tuple_into_bytes, CodeObj}; 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::typaram::{OpKind, TyParam};
use super::{ConstSubr, Field, HasType, Predicate, Type}; use super::{ConstSubr, Field, HasType, Predicate, Type};
use super::{CONTAINER_OMIT_THRESHOLD, STR_OMIT_THRESHOLD}; use super::{CONTAINER_OMIT_THRESHOLD, STR_OMIT_THRESHOLD};
@ -502,8 +502,8 @@ pub enum ValueObj {
Float(f64), Float(f64),
Str(Str), Str(Str),
Bool(bool), Bool(bool),
Array(ArcArray<ValueObj>), List(ArcArray<ValueObj>),
UnsizedArray(Box<ValueObj>), UnsizedList(Box<ValueObj>),
Set(Set<ValueObj>), Set(Set<ValueObj>),
Dict(Dict<ValueObj, ValueObj>), Dict(Dict<ValueObj, ValueObj>),
Tuple(ArcArray<ValueObj>), Tuple(ArcArray<ValueObj>),
@ -562,8 +562,8 @@ impl fmt::Debug for ValueObj {
write!(f, "False") write!(f, "False")
} }
} }
Self::Array(arr) => write!(f, "[{}]", fmt_iter(arr.iter())), Self::List(lis) => write!(f, "[{}]", fmt_iter(lis.iter())),
Self::UnsizedArray(elem) => write!(f, "[{elem}; _]"), Self::UnsizedList(elem) => write!(f, "[{elem}; _]"),
Self::Dict(dict) => { Self::Dict(dict) => {
write!(f, "{{")?; write!(f, "{{")?;
for (i, (k, v)) in dict.iter().enumerate() { for (i, (k, v)) in dict.iter().enumerate() {
@ -624,9 +624,9 @@ impl LimitedDisplay for ValueObj {
write!(f, "\"{}\"", s.escape()) write!(f, "\"{}\"", s.escape())
} }
} }
Self::Array(arr) => { Self::List(lis) => {
write!(f, "[")?; write!(f, "[")?;
for (i, item) in arr.iter().enumerate() { for (i, item) in lis.iter().enumerate() {
if i != 0 { if i != 0 {
write!(f, ", ")?; write!(f, ", ")?;
} }
@ -751,8 +751,8 @@ impl Hash for ValueObj {
Self::Float(f) => f.to_bits().hash(state), Self::Float(f) => f.to_bits().hash(state),
Self::Str(s) => s.hash(state), Self::Str(s) => s.hash(state),
Self::Bool(b) => b.hash(state), Self::Bool(b) => b.hash(state),
Self::Array(arr) => arr.hash(state), Self::List(lis) => lis.hash(state),
Self::UnsizedArray(elem) => { Self::UnsizedList(elem) => {
"UnsizedArray".hash(state); "UnsizedArray".hash(state);
elem.hash(state) elem.hash(state)
} }
@ -855,7 +855,7 @@ impl From<CodeObj> for ValueObj {
impl<V: Into<ValueObj>> From<Vec<V>> for ValueObj { impl<V: Into<ValueObj>> From<Vec<V>> for ValueObj {
fn from(item: Vec<V>) -> Self { fn from(item: Vec<V>) -> Self {
ValueObj::Array(ArcArray::from( ValueObj::List(ArcArray::from(
&item.into_iter().map(Into::into).collect::<Vec<_>>()[..], &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 { impl<const N: usize, V: Into<ValueObj>> From<[V; N]> for ValueObj {
fn from(item: [V; N]) -> Self { 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 { pub const fn is_container(&self) -> bool {
matches!( matches!(
self, self,
Self::Array(_) Self::List(_)
| Self::UnsizedArray(_) | Self::UnsizedList(_)
| Self::Set(_) | Self::Set(_)
| Self::Dict(_) | Self::Dict(_)
| Self::Tuple(_) | Self::Tuple(_)
@ -1124,7 +1124,7 @@ impl ValueObj {
Self::Str(s) => str_into_bytes(s, false), Self::Str(s) => str_into_bytes(s, false),
Self::Bool(true) => vec![DataTypePrefix::True as u8], Self::Bool(true) => vec![DataTypePrefix::True as u8],
Self::Bool(false) => vec![DataTypePrefix::False 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 => { Self::None => {
vec![DataTypePrefix::None as u8] vec![DataTypePrefix::None as u8]
} }
@ -1169,15 +1169,15 @@ impl ValueObj {
Self::Float(_) => Type::Float, Self::Float(_) => Type::Float,
Self::Str(_) => Type::Str, Self::Str(_) => Type::Str,
Self::Bool(_) => Type::Bool, Self::Bool(_) => Type::Bool,
Self::Array(arr) => array_t( Self::List(lis) => list_t(
// REVIEW: Never? // REVIEW: Never?
arr.iter() lis.iter()
.next() .next()
.map(|elem| elem.class()) .map(|elem| elem.class())
.unwrap_or(Type::Never), .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) => { Self::Dict(dict) => {
let tp = dict let tp = dict
.iter() .iter()
@ -1295,9 +1295,9 @@ impl ValueObj {
(Self::Nat(l), Self::Float(r)) => Some(Self::Float(l as f64 - r)), (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::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::Str(l), Self::Str(r)) => Some(Self::Str(Str::from(format!("{l}{r}")))),
(Self::Array(l), Self::Array(r)) => { (Self::List(l), Self::List(r)) => {
let arr = Arc::from([l, r].concat()); let lis = Arc::from([l, r].concat());
Some(Self::Array(arr)) Some(Self::List(lis))
} }
(Self::Dict(l), Self::Dict(r)) => Some(Self::Dict(l.concat(r))), (Self::Dict(l), Self::Dict(r)) => Some(Self::Dict(l.concat(r))),
(inf @ (Self::Inf | Self::NegInf), _) | (_, inf @ (Self::Inf | Self::NegInf)) => { (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::artifact::{Buildable, ErrorArtifact};
use erg_compiler::build_package::PackageBuilder; use erg_compiler::build_package::PackageBuilder;
use erg_compiler::error::{CompileError, CompileErrors, CompileWarnings}; 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_compiler::module::SharedCompilerResource;
use erg_parser::ParserRunner; use erg_parser::ParserRunner;
@ -189,21 +189,21 @@ impl Linter {
} }
} }
} }
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
for elem in arr.elems.pos_args.iter() { for elem in lis.elems.pos_args.iter() {
lint_fn(self, &elem.expr); lint_fn(self, &elem.expr);
} }
} }
Array::WithLength(arr) => { List::WithLength(lis) => {
lint_fn(self, &arr.elem); lint_fn(self, &lis.elem);
if let Some(len) = &arr.len { if let Some(len) = &lis.len {
lint_fn(self, len); lint_fn(self, len);
} }
} }
Array::Comprehension(arr) => { List::Comprehension(lis) => {
lint_fn(self, &arr.elem); lint_fn(self, &lis.elem);
lint_fn(self, &arr.guard); lint_fn(self, &lis.guard);
} }
}, },
Expr::Tuple(tuple) => match tuple { 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)] #[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Literal { pub struct Literal {
@ -865,13 +865,13 @@ impl Accessor {
#[pyclass(get_all, set_all)] #[pyclass(get_all, set_all)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NormalArray { pub struct NormalList {
pub l_sqbr: Token, pub l_sqbr: Token,
pub r_sqbr: Token, pub r_sqbr: Token,
pub elems: Args, pub elems: Args,
} }
impl NestedDisplay for NormalArray { impl NestedDisplay for NormalList {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
writeln!(f, "[")?; writeln!(f, "[")?;
self.elems.fmt_nest(f, level + 1)?; self.elems.fmt_nest(f, level + 1)?;
@ -879,11 +879,11 @@ impl NestedDisplay for NormalArray {
} }
} }
impl_display_from_nested!(NormalArray); impl_display_from_nested!(NormalList);
impl_locational!(NormalArray, l_sqbr, elems, r_sqbr); impl_locational!(NormalList, l_sqbr, elems, r_sqbr);
#[pymethods] #[pymethods]
impl NormalArray { impl NormalList {
#[pyo3(name = "get")] #[pyo3(name = "get")]
fn _get(&self, index: usize) -> Option<Expr> { fn _get(&self, index: usize) -> Option<Expr> {
self.get(index).cloned() self.get(index).cloned()
@ -899,7 +899,7 @@ impl NormalArray {
} }
} }
impl NormalArray { impl NormalList {
pub fn get(&self, index: usize) -> Option<&Expr> { pub fn get(&self, index: usize) -> Option<&Expr> {
self.elems.pos_args.get(index).map(|a| &a.expr) self.elems.pos_args.get(index).map(|a| &a.expr)
} }
@ -911,24 +911,24 @@ impl NormalArray {
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayWithLength { pub struct ListWithLength {
pub l_sqbr: Token, pub l_sqbr: Token,
pub r_sqbr: Token, pub r_sqbr: Token,
pub elem: Box<PosArg>, pub elem: Box<PosArg>,
pub len: Box<Expr>, pub len: Box<Expr>,
} }
impl NestedDisplay for ArrayWithLength { impl NestedDisplay for ListWithLength {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}; {}]", self.elem, self.len) write!(f, "[{}; {}]", self.elem, self.len)
} }
} }
impl_display_from_nested!(ArrayWithLength); impl_display_from_nested!(ListWithLength);
impl_locational!(ArrayWithLength, l_sqbr, elem, r_sqbr); impl_locational!(ListWithLength, l_sqbr, elem, r_sqbr);
#[pymethods] #[pymethods]
impl ArrayWithLength { impl ListWithLength {
#[staticmethod] #[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elem: PosArg, len: Expr) -> Self { pub fn new(l_sqbr: Token, r_sqbr: Token, elem: PosArg, len: Expr) -> Self {
Self { Self {
@ -942,7 +942,7 @@ impl ArrayWithLength {
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayComprehension { pub struct ListComprehension {
pub l_sqbr: Token, pub l_sqbr: Token,
pub r_sqbr: Token, pub r_sqbr: Token,
pub layout: Option<Box<Expr>>, pub layout: Option<Box<Expr>>,
@ -950,7 +950,7 @@ pub struct ArrayComprehension {
pub guard: Option<Box<Expr>>, 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 { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
let mut generators = String::new(); let mut generators = String::new();
for (name, gen) in self.generators.iter() { for (name, gen) in self.generators.iter() {
@ -966,11 +966,11 @@ impl NestedDisplay for ArrayComprehension {
} }
} }
impl_display_from_nested!(ArrayComprehension); impl_display_from_nested!(ListComprehension);
impl_locational!(ArrayComprehension, l_sqbr, r_sqbr); impl_locational!(ListComprehension, l_sqbr, r_sqbr);
#[pymethods] #[pymethods]
impl ArrayComprehension { impl ListComprehension {
#[staticmethod] #[staticmethod]
#[pyo3(signature = (l_sqbr, r_sqbr, layout, generators, guard=None))] #[pyo3(signature = (l_sqbr, r_sqbr, layout, generators, guard=None))]
pub fn new( pub fn new(
@ -991,22 +991,22 @@ impl ArrayComprehension {
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Array { pub enum List {
Normal(NormalArray), Normal(NormalList),
WithLength(ArrayWithLength), WithLength(ListWithLength),
Comprehension(ArrayComprehension), Comprehension(ListComprehension),
} }
impl_nested_display_for_enum!(Array; Normal, WithLength, Comprehension); impl_nested_display_for_enum!(List; Normal, WithLength, Comprehension);
impl_display_for_enum!(Array; Normal, WithLength, Comprehension); impl_display_for_enum!(List; Normal, WithLength, Comprehension);
impl_locational_for_enum!(Array; Normal, WithLength, Comprehension); impl_locational_for_enum!(List; Normal, WithLength, Comprehension);
impl_into_py_for_enum!(Array; Normal, WithLength, Comprehension); impl_into_py_for_enum!(List; Normal, WithLength, Comprehension);
impl_from_py_for_enum!(Array; Normal(NormalArray), WithLength(ArrayWithLength), Comprehension(ArrayComprehension)); impl_from_py_for_enum!(List; Normal(NormalList), WithLength(ListWithLength), Comprehension(ListComprehension));
impl Array { impl List {
pub fn get(&self, index: usize) -> Option<&Expr> { pub fn get(&self, index: usize) -> Option<&Expr> {
match self { match self {
Self::Normal(array) => array.get(index), Self::Normal(list) => list.get(index),
_ => None, _ => None,
} }
} }
@ -2167,36 +2167,36 @@ impl ConstAccessor {
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ConstArray { pub enum ConstList {
Normal(ConstNormalArray), Normal(ConstNormalList),
WithLength(ConstArrayWithLength), WithLength(ConstListWithLength),
} }
impl_nested_display_for_enum!(ConstArray; Normal, WithLength); impl_nested_display_for_enum!(ConstList; Normal, WithLength);
impl_display_from_nested!(ConstArray); impl_display_from_nested!(ConstList);
impl_locational_for_enum!(ConstArray; Normal, WithLength); impl_locational_for_enum!(ConstList; Normal, WithLength);
impl_into_py_for_enum!(ConstArray; Normal, WithLength); impl_into_py_for_enum!(ConstList; Normal, WithLength);
impl_from_py_for_enum!(ConstArray; Normal(ConstNormalArray), WithLength(ConstArrayWithLength)); impl_from_py_for_enum!(ConstList; Normal(ConstNormalList), WithLength(ConstListWithLength));
impl ConstArray { impl ConstList {
pub fn downgrade(self) -> Array { pub fn downgrade(self) -> List {
match self { match self {
Self::Normal(normal) => Array::Normal(normal.downgrade()), Self::Normal(normal) => List::Normal(normal.downgrade()),
Self::WithLength(with_length) => Array::WithLength(with_length.downgrade()), Self::WithLength(with_length) => List::WithLength(with_length.downgrade()),
} }
} }
} }
#[pyclass] #[pyclass]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ConstNormalArray { pub struct ConstNormalList {
pub l_sqbr: Token, pub l_sqbr: Token,
pub r_sqbr: Token, pub r_sqbr: Token,
pub elems: ConstArgs, pub elems: ConstArgs,
pub guard: Option<Box<ConstExpr>>, 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 { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
if let Some(guard) = &self.guard { if let Some(guard) = &self.guard {
write!(f, "[{} | {}]", self.elems, guard) write!(f, "[{} | {}]", self.elems, guard)
@ -2206,11 +2206,11 @@ impl NestedDisplay for ConstNormalArray {
} }
} }
impl_display_from_nested!(ConstNormalArray); impl_display_from_nested!(ConstNormalList);
impl_locational!(ConstNormalArray, l_sqbr, elems, r_sqbr); impl_locational!(ConstNormalList, l_sqbr, elems, r_sqbr);
#[pymethods] #[pymethods]
impl ConstNormalArray { impl ConstNormalList {
#[staticmethod] #[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elems: ConstArgs, guard: Option<ConstExpr>) -> Self { pub fn new(l_sqbr: Token, r_sqbr: Token, elems: ConstArgs, guard: Option<ConstExpr>) -> Self {
Self { Self {
@ -2222,32 +2222,32 @@ impl ConstNormalArray {
} }
} }
impl ConstNormalArray { impl ConstNormalList {
pub fn downgrade(self) -> NormalArray { pub fn downgrade(self) -> NormalList {
NormalArray::new(self.l_sqbr, self.r_sqbr, self.elems.downgrade()) NormalList::new(self.l_sqbr, self.r_sqbr, self.elems.downgrade())
} }
} }
#[pyclass] #[pyclass]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ConstArrayWithLength { pub struct ConstListWithLength {
pub l_sqbr: Token, pub l_sqbr: Token,
pub r_sqbr: Token, pub r_sqbr: Token,
pub elem: Box<ConstExpr>, pub elem: Box<ConstExpr>,
pub length: 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 { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}; {}]", self.elem, self.length) write!(f, "[{}; {}]", self.elem, self.length)
} }
} }
impl_display_from_nested!(ConstArrayWithLength); impl_display_from_nested!(ConstListWithLength);
impl_locational!(ConstArrayWithLength, l_sqbr, elem, r_sqbr); impl_locational!(ConstListWithLength, l_sqbr, elem, r_sqbr);
#[pymethods] #[pymethods]
impl ConstArrayWithLength { impl ConstListWithLength {
#[staticmethod] #[staticmethod]
pub fn new(l_sqbr: Token, r_sqbr: Token, elem: ConstExpr, length: ConstExpr) -> Self { pub fn new(l_sqbr: Token, r_sqbr: Token, elem: ConstExpr, length: ConstExpr) -> Self {
Self { Self {
@ -2259,9 +2259,9 @@ impl ConstArrayWithLength {
} }
} }
impl ConstArrayWithLength { impl ConstListWithLength {
pub fn downgrade(self) -> ArrayWithLength { pub fn downgrade(self) -> ListWithLength {
ArrayWithLength::new( ListWithLength::new(
self.l_sqbr, self.l_sqbr,
self.r_sqbr, self.r_sqbr,
PosArg::new(self.elem.downgrade()), PosArg::new(self.elem.downgrade()),
@ -2830,7 +2830,7 @@ pub enum ConstExpr {
Lit(Literal), Lit(Literal),
Accessor(ConstAccessor), Accessor(ConstAccessor),
App(ConstApp), App(ConstApp),
Array(ConstArray), List(ConstList),
Set(ConstSet), Set(ConstSet),
Dict(ConstDict), Dict(ConstDict),
Tuple(ConstTuple), Tuple(ConstTuple),
@ -2842,11 +2842,11 @@ pub enum ConstExpr {
TypeAsc(ConstTypeAsc), 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_display_from_nested!(ConstExpr);
impl_locational_for_enum!(ConstExpr; Lit, Accessor, App, Array, Set, Dict, Tuple, Record, BinOp, UnaryOp, Def, Lambda, Set, TypeAsc); 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, Array, Set, Dict, Tuple, Record, Def, Lambda, BinOp, UnaryOp, 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), Array(ConstArray), Set(ConstSet), Dict(ConstDict), Tuple(ConstTuple), Record(ConstRecord), Def(ConstDef), Lambda(ConstLambda), BinOp(ConstBinOp), UnaryOp(ConstUnaryOp), TypeAsc(ConstTypeAsc)); 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 { impl TryFrom<&ParamPattern> for ConstExpr {
type Error = (); type Error = ();
@ -2856,7 +2856,7 @@ impl TryFrom<&ParamPattern> for ConstExpr {
Ok(ConstExpr::Accessor(ConstAccessor::local(name.0.clone()))) Ok(ConstExpr::Accessor(ConstAccessor::local(name.0.clone())))
} }
ParamPattern::Lit(lit) => Ok(ConstExpr::Lit(lit.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), ParamPattern::Tuple(tuple) => ConstExpr::try_from(tuple),
_ => Err(()), _ => Err(()),
} }
@ -2878,7 +2878,7 @@ impl ConstExpr {
Self::Lit(lit) => Expr::Literal(lit), Self::Lit(lit) => Expr::Literal(lit),
Self::Accessor(acc) => Expr::Accessor(acc.downgrade()), Self::Accessor(acc) => Expr::Accessor(acc.downgrade()),
Self::App(app) => Expr::Call(app.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::Set(set) => Expr::Set(set.downgrade()),
Self::Dict(dict) => Expr::Dict(dict.downgrade()), Self::Dict(dict) => Expr::Dict(dict.downgrade()),
Self::Tuple(tuple) => Expr::Tuple(tuple.downgrade()), Self::Tuple(tuple) => Expr::Tuple(tuple.downgrade()),
@ -3338,19 +3338,19 @@ impl SubrTypeSpec {
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayTypeSpec { pub struct ListTypeSpec {
pub sqbrs: Option<(Token, Token)>, pub sqbrs: Option<(Token, Token)>,
pub ty: Box<TypeSpec>, pub ty: Box<TypeSpec>,
pub len: ConstExpr, pub len: ConstExpr,
} }
impl fmt::Display for ArrayTypeSpec { impl fmt::Display for ListTypeSpec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}; {}]", self.ty, self.len) write!(f, "[{}; {}]", self.ty, self.len)
} }
} }
impl Locational for ArrayTypeSpec { impl Locational for ListTypeSpec {
fn loc(&self) -> Location { fn loc(&self) -> Location {
if let Some((lsqbr, rsqbr)) = &self.sqbrs { if let Some((lsqbr, rsqbr)) = &self.sqbrs {
Location::concat(lsqbr, rsqbr) 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 { pub fn new(ty: TypeSpec, len: ConstExpr, sqbrs: Option<(Token, Token)>) -> Self {
Self { Self {
ty: Box::new(ty), 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. /// * Dict: `[Str: Str]`, etc.
/// * And (Intersection type): Add and Sub and Mul (== Num), etc. /// * And (Intersection type): Add and Sub and Mul (== Num), etc.
/// * Not (Diff type): Pos == Nat not {0}, etc. /// * Not (Diff type): Pos == Nat not {0}, etc.
@ -3545,7 +3545,7 @@ pub enum TypeSpec {
Infer(Token), Infer(Token),
PreDeclTy(PreDeclTypeSpec), PreDeclTy(PreDeclTypeSpec),
/* Composite types */ /* Composite types */
Array(ArrayTypeSpec), List(ListTypeSpec),
SetWithLen(SetWithLenTypeSpec), SetWithLen(SetWithLenTypeSpec),
Tuple(TupleTypeSpec), Tuple(TupleTypeSpec),
Dict(DictTypeSpec), Dict(DictTypeSpec),
@ -3584,7 +3584,7 @@ impl fmt::Display for TypeSpec {
Self::And(lhs, rhs) => write!(f, "{lhs} and {rhs}"), Self::And(lhs, rhs) => write!(f, "{lhs} and {rhs}"),
Self::Not(ty) => write!(f, "not {ty}"), Self::Not(ty) => write!(f, "not {ty}"),
Self::Or(lhs, rhs) => write!(f, "{lhs} or {rhs}"), 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::SetWithLen(set) => write!(f, "{set}"),
Self::Tuple(tup) => write!(f, "{tup}"), Self::Tuple(tup) => write!(f, "{tup}"),
Self::Dict(dict) => dict.fmt(f), Self::Dict(dict) => dict.fmt(f),
@ -3613,7 +3613,7 @@ impl Locational for TypeSpec {
Location::concat(lhs.as_ref(), rhs.as_ref()) Location::concat(lhs.as_ref(), rhs.as_ref())
} }
Self::Not(ty) => ty.loc(), Self::Not(ty) => ty.loc(),
Self::Array(arr) => arr.loc(), Self::List(lis) => lis.loc(),
Self::SetWithLen(set) => set.loc(), Self::SetWithLen(set) => set.loc(),
Self::Tuple(tup) => tup.loc(), Self::Tuple(tup) => tup.loc(),
Self::Dict(dict) => dict.loc(), Self::Dict(dict) => dict.loc(),
@ -4253,21 +4253,21 @@ impl Identifier {
#[pyclass(get_all, set_all)] #[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct VarArrayPattern { pub struct VarListPattern {
l_sqbr: Token, l_sqbr: Token,
pub(crate) elems: Vars, pub(crate) elems: Vars,
r_sqbr: Token, r_sqbr: Token,
} }
impl fmt::Display for VarArrayPattern { impl fmt::Display for VarListPattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}]", self.elems) 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] #[inline]
fn payload(self) -> Vec<VarSignature> { fn payload(self) -> Vec<VarSignature> {
self.elems.payload() 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 { pub const fn new(l_sqbr: Token, elems: Vars, r_sqbr: Token) -> Self {
Self { Self {
l_sqbr, l_sqbr,
@ -4439,7 +4439,7 @@ pub enum VarPattern {
Discard(Token), Discard(Token),
Ident(Identifier), Ident(Identifier),
/// e.g. `[x, y, z]` of `[x, y, z] = [1, 2, 3]` /// 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)` /// e.g. `(x, y, z)` of `(x, y, z) = (1, 2, 3)`
Tuple(VarTuplePattern), Tuple(VarTuplePattern),
// e.g. `{name; age}`, `{_; [car, cdr]}` // e.g. `{name; age}`, `{_; [car, cdr]}`
@ -4453,7 +4453,7 @@ impl NestedDisplay for VarPattern {
match self { match self {
Self::Discard(_) => write!(f, "_"), Self::Discard(_) => write!(f, "_"),
Self::Ident(ident) => write!(f, "{ident}"), 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::Tuple(t) => write!(f, "{t}"),
Self::Record(r) => write!(f, "{r}"), Self::Record(r) => write!(f, "{r}"),
Self::DataPack(d) => write!(f, "{d}"), Self::DataPack(d) => write!(f, "{d}"),
@ -4462,9 +4462,9 @@ impl NestedDisplay for VarPattern {
} }
impl_display_from_nested!(VarPattern); impl_display_from_nested!(VarPattern);
impl_locational_for_enum!(VarPattern; Discard, Ident, Array, Tuple, Record, DataPack); impl_locational_for_enum!(VarPattern; Discard, Ident, List, Tuple, Record, DataPack);
impl_into_py_for_enum!(VarPattern; Discard, Ident, Array, 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), Array(VarArrayPattern), Tuple(VarTuplePattern), Record(VarRecordPattern), DataPack(VarDataPackPattern)); impl_from_py_for_enum!(VarPattern; Discard(Token), Ident(Identifier), List(VarListPattern), Tuple(VarTuplePattern), Record(VarRecordPattern), DataPack(VarDataPackPattern));
impl VarPattern { impl VarPattern {
pub const fn inspect(&self) -> Option<&Str> { pub const fn inspect(&self) -> Option<&Str> {
@ -4643,31 +4643,31 @@ impl Vars {
#[pyclass(get_all, set_all)] #[pyclass(get_all, set_all)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamArrayPattern { pub struct ParamListPattern {
pub l_sqbr: Token, pub l_sqbr: Token,
pub elems: Params, pub elems: Params,
pub r_sqbr: Token, pub r_sqbr: Token,
} }
impl NestedDisplay for ParamArrayPattern { impl NestedDisplay for ParamListPattern {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "[{}]", self.elems) write!(f, "[{}]", self.elems)
} }
} }
impl_display_from_nested!(ParamArrayPattern); impl_display_from_nested!(ParamListPattern);
impl_locational!(ParamArrayPattern, l_sqbr, r_sqbr); impl_locational!(ParamListPattern, l_sqbr, r_sqbr);
impl TryFrom<&ParamArrayPattern> for Expr { impl TryFrom<&ParamListPattern> for Expr {
type Error = (); type Error = ();
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> { fn try_from(value: &ParamListPattern) -> Result<Self, Self::Error> {
let mut new = vec![]; let mut new = vec![];
for elem in value.elems.non_defaults.iter() { for elem in value.elems.non_defaults.iter() {
new.push(PosArg::new(Expr::try_from(&elem.pat)?)); new.push(PosArg::new(Expr::try_from(&elem.pat)?));
} }
let elems = Args::pos_only(new, None); 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.l_sqbr.clone(),
value.r_sqbr.clone(), value.r_sqbr.clone(),
elems, elems,
@ -4675,16 +4675,16 @@ impl TryFrom<&ParamArrayPattern> for Expr {
} }
} }
impl TryFrom<&ParamArrayPattern> for ConstExpr { impl TryFrom<&ParamListPattern> for ConstExpr {
type Error = (); type Error = ();
fn try_from(value: &ParamArrayPattern) -> Result<Self, Self::Error> { fn try_from(value: &ParamListPattern) -> Result<Self, Self::Error> {
let mut new = vec![]; let mut new = vec![];
for elem in value.elems.non_defaults.iter() { for elem in value.elems.non_defaults.iter() {
new.push(ConstPosArg::new(ConstExpr::try_from(&elem.pat)?)); new.push(ConstPosArg::new(ConstExpr::try_from(&elem.pat)?));
} }
let elems = ConstArgs::pos_only(new, None); 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.l_sqbr.clone(),
value.r_sqbr.clone(), value.r_sqbr.clone(),
elems, elems,
@ -4694,7 +4694,7 @@ impl TryFrom<&ParamArrayPattern> for ConstExpr {
} }
#[pymethods] #[pymethods]
impl ParamArrayPattern { impl ParamListPattern {
#[staticmethod] #[staticmethod]
pub const fn new(l_sqbr: Token, elems: Params, r_sqbr: Token) -> Self { pub const fn new(l_sqbr: Token, elems: Params, r_sqbr: Token) -> Self {
Self { Self {
@ -4851,7 +4851,7 @@ pub enum ParamPattern {
VarName(VarName), VarName(VarName),
// TODO: ConstAttr(), // TODO: ConstAttr(),
Lit(Literal), Lit(Literal),
Array(ParamArrayPattern), List(ParamListPattern),
Tuple(ParamTuplePattern), Tuple(ParamTuplePattern),
Record(ParamRecordPattern), Record(ParamRecordPattern),
// DataPack(ParamDataPackPattern), // DataPack(ParamDataPackPattern),
@ -4859,7 +4859,7 @@ pub enum ParamPattern {
RefMut(VarName), 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 { impl NestedDisplay for ParamPattern {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { 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::Discard(tok) => write!(f, "{tok}"),
Self::VarName(var_name) => write!(f, "{var_name}"), Self::VarName(var_name) => write!(f, "{var_name}"),
Self::Lit(lit) => write!(f, "{lit}"), 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::Tuple(tuple) => write!(f, "{tuple}"),
Self::Record(record) => write!(f, "{record}"), Self::Record(record) => write!(f, "{record}"),
Self::Ref(var_name) => write!(f, "ref {var_name}"), 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()))) Ok(Expr::Accessor(Accessor::local(name.0.clone())))
} }
ParamPattern::Lit(lit) => Ok(Expr::Literal(lit.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), ParamPattern::Tuple(tuple) => Expr::try_from(tuple),
_ => Err(()), _ => Err(()),
} }
@ -4893,7 +4893,7 @@ impl TryFrom<&ParamPattern> for Expr {
} }
impl_display_from_nested!(ParamPattern); 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 { impl ParamPattern {
pub const fn inspect(&self) -> Option<&Str> { pub const fn inspect(&self) -> Option<&Str> {
@ -5890,7 +5890,7 @@ impl Compound {
pub enum Expr { pub enum Expr {
Literal(Literal), Literal(Literal),
Accessor(Accessor), Accessor(Accessor),
Array(Array), List(List),
Tuple(Tuple), Tuple(Tuple),
Dict(Dict), Dict(Dict),
Set(Set), Set(Set),
@ -5912,12 +5912,12 @@ pub enum Expr {
Dummy(Dummy), 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_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, 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, 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_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_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, 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, 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, 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, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
impl Expr { impl Expr {
pub fn is_match_call(&self) -> bool { pub fn is_match_call(&self) -> bool {
@ -5939,7 +5939,7 @@ impl Expr {
match self { match self {
Self::Literal(_) => "literal", Self::Literal(_) => "literal",
Self::Accessor(_) => "accessor", Self::Accessor(_) => "accessor",
Self::Array(_) => "array", Self::List(_) => "list",
Self::Tuple(_) => "tuple", Self::Tuple(_) => "tuple",
Self::Dict(_) => "dict", Self::Dict(_) => "dict",
Self::Set(_) => "set", Self::Set(_) => "set",
@ -6075,9 +6075,9 @@ impl Expr {
} }
sum sum
} }
Self::Array(Array::Normal(arr)) => { Self::List(List::Normal(lis)) => {
let mut sum = 0; 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 += elem.expr.complexity();
} }
sum sum

View file

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

View file

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

View file

@ -518,7 +518,7 @@ impl LexError {
let method = StyledStr::new("メソッド", Some(HINT), Some(ATTR)); let method = StyledStr::new("メソッド", Some(HINT), Some(ATTR));
let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR)); let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR));
let newline = StyledStr::new("改行", 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}") format!("予期: {method}{lit}{newline}{arr}")
}, },
"simplified_chinese" => { "simplified_chinese" => {
@ -539,7 +539,7 @@ impl LexError {
let method = StyledStr::new("method", Some(HINT), Some(ATTR)); let method = StyledStr::new("method", Some(HINT), Some(ATTR));
let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR)); let lit = StyledStr::new("NatLit", Some(HINT), Some(ATTR));
let newline = StyledStr::new("newline", 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}") 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)?)?; m.add_function(wrap_pyfunction!(_parse, m)?)?;
let expr = PyModule::new(py, "expr")?; let expr = PyModule::new(py, "expr")?;
expr.add_class::<ast::Literal>()?; expr.add_class::<ast::Literal>()?;
expr.add_class::<ast::NormalArray>()?; expr.add_class::<ast::NormalList>()?;
expr.add_class::<ast::NormalTuple>()?; expr.add_class::<ast::NormalTuple>()?;
expr.add_class::<ast::NormalDict>()?; expr.add_class::<ast::NormalDict>()?;
expr.add_class::<ast::NormalSet>()?; 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::TupleAttribute>()?;
ast.add_class::<ast::Subscript>()?; ast.add_class::<ast::Subscript>()?;
ast.add_class::<ast::TypeApp>()?; ast.add_class::<ast::TypeApp>()?;
ast.add_class::<ast::NormalArray>()?; ast.add_class::<ast::NormalList>()?;
ast.add_class::<ast::NormalTuple>()?; ast.add_class::<ast::NormalTuple>()?;
ast.add_class::<ast::NormalDict>()?; ast.add_class::<ast::NormalDict>()?;
ast.add_class::<ast::NormalSet>()?; ast.add_class::<ast::NormalSet>()?;

View file

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

View file

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

View file

@ -26,28 +26,28 @@ impl Parser {
"complex const accessor", "complex const accessor",
)), )),
}, },
Expr::Array(array) => match array { Expr::List(list) => match list {
Array::Normal(arr) => { List::Normal(lis) => {
let (elems, ..) = arr.elems.deconstruct(); let (elems, ..) = lis.elems.deconstruct();
let mut const_elems = vec![]; let mut const_elems = vec![];
for elem in elems.into_iter() { for elem in elems.into_iter() {
let const_expr = Self::validate_const_expr(elem.expr)?; let const_expr = Self::validate_const_expr(elem.expr)?;
const_elems.push(ConstPosArg::new(const_expr)); const_elems.push(ConstPosArg::new(const_expr));
} }
let elems = ConstArgs::pos_only(const_elems, None); let elems = ConstArgs::pos_only(const_elems, None);
let const_arr = ConstNormalArray::new(arr.l_sqbr, arr.r_sqbr, elems, None); let const_lis = ConstNormalList::new(lis.l_sqbr, lis.r_sqbr, elems, None);
Ok(ConstExpr::Array(ConstArray::Normal(const_arr))) Ok(ConstExpr::List(ConstList::Normal(const_lis)))
} }
Array::WithLength(arr) => { List::WithLength(lis) => {
let elem = Self::validate_const_expr(arr.elem.expr)?; let elem = Self::validate_const_expr(lis.elem.expr)?;
let len = Self::validate_const_expr(*arr.len)?; let len = Self::validate_const_expr(*lis.len)?;
let const_arr = ConstArrayWithLength::new(arr.l_sqbr, arr.r_sqbr, elem, len); let const_lis = ConstListWithLength::new(lis.l_sqbr, lis.r_sqbr, elem, len);
Ok(ConstExpr::Array(ConstArray::WithLength(const_arr))) Ok(ConstExpr::List(ConstList::WithLength(const_lis)))
} }
other => Err(ParseError::feature_error( other => Err(ParseError::feature_error(
line!() as usize, line!() as usize,
other.loc(), other.loc(),
"const array comprehension", "const list comprehension",
)), )),
}, },
Expr::Set(set) => match set { Expr::Set(set) => match set {
@ -375,25 +375,25 @@ impl Parser {
)) ))
} }
fn array_to_array_type_spec(array: Array) -> Result<ArrayTypeSpec, ParseError> { fn list_to_list_type_spec(list: List) -> Result<ListTypeSpec, ParseError> {
match array { match list {
Array::Normal(arr) => { List::Normal(lis) => {
// TODO: add hint // 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) Err(err)
} }
Array::WithLength(arr) => { List::WithLength(lis) => {
let t_spec = Self::expr_to_type_spec(arr.elem.expr)?; let t_spec = Self::expr_to_type_spec(lis.elem.expr)?;
let len = Self::validate_const_expr(*arr.len)?; let len = Self::validate_const_expr(*lis.len)?;
Ok(ArrayTypeSpec::new( Ok(ListTypeSpec::new(
t_spec, t_spec,
len, len,
Some((arr.l_sqbr, arr.r_sqbr)), Some((lis.l_sqbr, lis.r_sqbr)),
)) ))
} }
Array::Comprehension(arr) => { List::Comprehension(lis) => {
// TODO: add hint // 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) Err(err)
} }
} }
@ -508,9 +508,9 @@ impl Parser {
let lambda = Self::lambda_to_subr_type_spec(lambda)?; let lambda = Self::lambda_to_subr_type_spec(lambda)?;
Ok(TypeSpec::Subr(lambda)) Ok(TypeSpec::Subr(lambda))
} }
Expr::Array(array) => { Expr::List(list) => {
let array = Self::array_to_array_type_spec(array)?; let list = Self::list_to_list_type_spec(list)?;
Ok(TypeSpec::Array(array)) Ok(TypeSpec::List(list))
} }
Expr::Set(set) => { Expr::Set(set) => {
let set = Self::set_to_set_type_spec(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. 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`. 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 ### repeat|T|(x: T) -> RepeatIterator T
@ -96,11 +96,11 @@ match jan:
_ -> log "Other" _ -> log "Other"
``` ```
### Inherit ### Inherit
Inherit classes. You can use the methods of the parent class ('Super') as is. The second parameter 'Layout' can specify a new layout. 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'. It must be 'Super.Base:> Layout'.
```python ```python
@ Inheritable @ Inheritable
C = Class {i = Int} C = Class {i = Int}

View file

@ -20,5 +20,5 @@ Infers a function given its arguments and return value.
```python ```python
1.guess((1,), 2) # <Int.__add__ method> 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. 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) -> T
* sample! ref! self, M: Nat -> [T; M] * sample! ref! self, M: Nat -> [T; M]
Select a random element and return a copy. Select a random element and return a copy.
* shuffle!(ref! self) * shuffle!(ref! self)
Shuffle contents. Shuffle contents.
* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic * assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic
Verify length Verify length
Incorrect length will cause `panic` 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; _]`). `[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[]) assert all(False for _in[])
``` ```
## methods of Array T, N | T <: Eq ## methods of List T, N | T <: Eq
* freq self -> [{T: Nat}] * freq self -> [{T: Nat}]
Returns the frequency of occurrence of an object. Returns the frequency of occurrence of an object.

View file

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

View file

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

View file

@ -16,7 +16,7 @@
## impl classes ## impl classes
* `Array` * `List`
* `Tuple` * `Tuple`
* `Str` * `Str`
* `Range` * `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. 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. 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 ```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). 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``. Once the key is identified, the definition type is back-propagated to the type of ``?2``.
```erg ```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 ```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[ body: Block[
Unary Op { Unary Op {
op: "!", op: "!",
expr: Array([]), expr: List([]),
}, },
], ],
}, },
@ -82,7 +82,7 @@ HIR(Module[
body: Block[ body: Block[
expr: UnaryOp{ expr: UnaryOp{
op: "!", op: "!",
expr: Array([]), expr: List([]),
t: [0..10, 0]!, t: [0..10, 0]!,
}, },
], ],

View file

@ -50,19 +50,19 @@ The specific operations are as follows.
line 1. Def{sig: v, block: ![]} line 1. Def{sig: v, block: ![]}
get block type: get block type:
get UnaryOp type: get UnaryOp type:
getArray type: `['T; 0]` getList type: `['T; 0]`
instantiate: `[?T; 0]` instantiate: `[?T; 0]`
(substitute, eval are omitted) (substitute, eval are omitted)
result: `Γ: {v: [?T; 0]!}` result: `Γ: {v: [?T; 0]!}`
expr returns `NoneType`: OK expr returns `NoneType`: OK
line 2. CallMethod {obj: v, name: push!, args: [1]} line 2. CallMethod {obj: v, name: push!, args: [1]}
get obj type: `Array!(?T, 0)` get obj type: `List!(?T, 0)`
search: Array!(?T, 0).push!(Nat)` search: List!(?T, 0).push!(Nat)`
get: `Array!('T ~> 'T, 'N ~> 'N+1).push!: 'T => NoneType` get: `List!('T ~> 'T, 'N ~> 'N+1).push!: 'T => NoneType`
instantiate: `Array!(?T, ?N).push!(?T) => NoneType` instantiate: `List!(?T, ?N).push!(?T) => NoneType`
substitute(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!: Nat => NoneType` substitute(`S: {?T --> Nat, ?N --> 0}`): `List!(Nat ~> Nat, 0 ~> 0+1).push!: Nat => NoneType`
eval: `Array!(Nat, 0 ~> 1).push!: Nat => NoneType` eval: `List!(Nat, 0 ~> 1).push!: Nat => NoneType`
result: `Γ: {v: [Nat; 1]!}` result: `Γ: {v: [Nat; 1]!}`
expr returns `NoneType`: OK 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. There can even be a left-side value within a right-side value.
```python ```python
# i is the left-hand side value, Array(Int) and [1, 2, 3] are the right-hand side values # i is the left-hand side value, List(Int) and [1, 2, 3] are the right-hand side values
i: Array(Int) = [1, 2, 3] 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 # `[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 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 # {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__`)? ## 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. 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 ```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? ## 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. 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 ```python
[], [1], [1, 2, 3], ["1", "2",], ... [], [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"}, ... {}, {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 ```python
assert {1, 2, 1} == {1, 2} assert {1, 2, 1} == {1, 2}

View file

@ -29,7 +29,7 @@ l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed
```python ```python
# OK # OK
l1 = [1, 2, 3] 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. 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 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 ```python,compile_fail
n = 1 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'> <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> </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. A collection is an object that can hold multiple objects inside it.
```python ```python
@ -14,7 +14,7 @@ mut_a[0].inc!()
assert mut_a == [2, 2, 3] 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 ```python,compile_fail
[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str [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. However, you can bypass the restriction by explicitly specifying the type like this.
```python ```python
[1: Int or Str, "a"] [1, "a"]: [Int or Str; 2]
``` ```
## Slice ## 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 ```python
l = [1, 2, 3, 4] l = [1, 2, 3, 4]
@ -41,7 +41,7 @@ assert l[1..1] == [2]
assert l[..].step(2) == [2, 4] 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 ```python
print! Typeof l[1..2] # [Int; 4] print! Typeof l[1..2] # [Int; 4]

View file

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

View file

@ -32,22 +32,22 @@ The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind i
```python ```python
assert [1, 2, 3] in Iterable(Int) assert [1, 2, 3] in Iterable(Int)
assert 1..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 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> 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). 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 ```mermaid
classDiagram classDiagram
class Array~T~ { class List~T~ {
... ...
iter() ArrayIterator~T~ iter() ListIterator~T~
} }
class Range~T~ { class Range~T~ {
... ...
@ -57,10 +57,10 @@ classDiagram
<<trait>> <<trait>>
iter() Iterator~T~ iter() Iterator~T~
} }
Iterable~T~ <|.. Array~T~: Impl Iterable~T~ <|.. List~T~: Impl
Iterable~T~ <|.. Range~T~: Impl Iterable~T~ <|.. Range~T~: Impl
class ArrayIterator~T~ { class ListIterator~T~ {
array: Array~T~ list: List~T~
next() T next() T
} }
class RangeIterator~T~ { class RangeIterator~T~ {
@ -71,10 +71,10 @@ classDiagram
<<trait>> <<trait>>
next() T next() T
} }
Iterator~T~ <|.. ArrayIterator~T~: Impl Iterator~T~ <|.. ListIterator~T~: Impl
Iterator~T~ <|.. RangeIterator~T~: Impl Iterator~T~ <|.. RangeIterator~T~: Impl
Array <-- ArrayIterator List <-- ListIterator
Range <-- RangeIterator Range <-- RangeIterator
``` ```

View file

@ -31,7 +31,7 @@ print! id! _a # 0x000002A798DFE980
The `id!` procedure returns the address in memory where the object resides. 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 ```python
b = ![1, 2, 3] 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 ```python
capitalize s: Str!= capitalize s: Str!=
s. capitalize!() s.capitalize!()
s s
s1 = !"hello" s1 = !"hello"
s2 = capitalize s1.clone() s2 = capitalize s1.copy()
log s2, s1 # !"HELLO hello" 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 ```python
i = !0 i = !0
immut_i = i.clone().freeze() immut_i = i.copy().freeze()
fx = immut_i + x fx = immut_i + x
assert f 1 == 1 assert f 1 == 1
i.add! 1 i.add! 1

View file

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

View file

@ -1,6 +1,6 @@
# Comprehension # 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 set with `{(expr |)? (name <- iterable;)+ (| predicate)?}`,
a Dict with `{(key: value |)? (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 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, # 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 # or
__evens = 1..100 \ __evens = 1..100 \
.iter() \ .iter() \
.filter i -> i % 2 == 0 \ .filter i -> i % 2 == 0 \
.collect Array .collect List
``` ```
<p align='center'> <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) - [Side effects and procedures](./07_side_effect.md)
- [Procedures](./08_procedure.md) - [Procedures](./08_procedure.md)
- [Built-in procedure](./09_builtin_procs.md) - [Built-in procedure](./09_builtin_procs.md)
- [Array](./10_array.md) - [List](./10_list.md)
- [Dict](./11_dict.md) - [Dict](./11_dict.md)
- [Subscript (index access)](./12_container_ownership.md) - [Subscript (index access)](./12_container_ownership.md)
- [Tuple](./13_tuple.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) * ! → [side&nbsp;effect](./07_side_effect.md)
* !-type → [mutable&nbsp;type](./type/18_mut.md) * !-type → [mutable&nbsp;type](./type/18_mut.md)
* ? → [error&nbsp;handling](./31_error_handling.md) * ? → [error&nbsp;handling](./32_error_handling.md)
* &#35; → [Str](./00_basic.md/#comments) * &#35; → [Str](./00_basic.md#comments)
* $ → [shared](./type/advanced/shared.md) * $ → [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) * [&quot;&nbsp;(double&nbsp;quote)](./01_literal.md#str-literal)
* &lpar;&rpar; → [Tuple](./13_tuple.md) * &lpar;&rpar; → [Tuple](./13_tuple.md)
* &ast; * &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; (prefix) → [operator](./06_operator.md)
* &plus;_ → &plus; (prefix) * &plus;_ → &plus; (prefix)
* &plus; (infix) → [operator](./06_operator.md) * &plus; (infix) → [operator](./06_operator.md)
@ -28,42 +28,42 @@ Also, see [here](../terms.md) for terminology.
* &minus;_ → &minus; (prefix) * &minus;_ → &minus; (prefix)
* &minus; (infix) → [operator](./06_operator.md) * &minus; (infix) → [operator](./06_operator.md)
* &minus; (infix) → [Trait](./type/03_trait.md) * &minus; (infix) → [Trait](./type/03_trait.md)
* &minus;> → [anonymous&nbsp;function](./22_lambda.md) * &minus;> → [anonymous&nbsp;function](./23_lambda.md)
* . → [Visibility](./20_visibility.md) * . → [Visibility](./21_visibility.md)
* .. → [closed range operator](./01_literal.md/#range-object) * .. → [closed range operator](./01_literal.md#range-object)
* ..< → [right-open 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) * ... → [Variable-length arguments](./04_function.md#variable-length-arguments)
* / * /
* : * :
* : → [Colon&nbsp;application&nbsp;style](./04_function.md) * : → [Colon&nbsp;application&nbsp;style](./04_function.md)
* : → [Type ascription](./03_declaration.md) * : → [Type ascription](./03_declaration.md)
* : → [Keyword&nbsp;arguments](./04_function.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) * := → [default&nbsp;parameters](./04_function.md)
* ; * ;
* &lt; * &lt;
* &lt;: → [Subtype&nbsp;specification](./type/02_basic.md) * &lt;: → [Subtype&nbsp;specification](./type/02_basic.md)
* &lt;&lt; * &lt;&lt;
* &lt;= * &lt;=
* &lt;.. → [left-open range operator](./01_literal.md/#range-object) * &lt;.. → [left-open range operator](./01_literal.md#range-object)
* &lt;..&lt; → [open range operator](./01_literal.md/#range-object) * &lt;..&lt; → [open range operator](./01_literal.md#range-object)
* = → [Variable](./20_visibility.md) * = → [Variable](./21_visibility.md)
* == * ==
* => → [anonymous procedure operator](./08_procedure.md) * => → [anonymous procedure operator](./08_procedure.md)
* &gt; * &gt;
* &gt;&gt; * &gt;&gt;
* &gt;= * &gt;=
* @ → [decorator](./30_decorator.md) * @ → [decorator](./31_decorator.md)
* [] → [Array](./10_array.md) * [] → [List](./10_list.md)
* \ → [Escaping](./00_basic.md) * \ → [Escaping](./00_basic.md)
* ^ * ^
* ^^ * ^^
* _ → [Type&nbsp;erasure](./type/advanced/erasure.md) * _ → [Type&nbsp;erasure](./type/advanced/erasure.md)
* &#95;+&#95;&plus; (infix) * &#95;+&#95;&plus; (infix)
* &#95;-&#95;&minus; (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](./type/01_type_system.md)
* {=} → [Type&nbsp;System](./type/01_type_system.md#classification) * {=} → [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) * [algebraic&nbsp;type](./type/13_algebraic.md)
* [And] * [And]
* [and] * [and]
* [anonymous&nbsp;function](./22_lambda.md) * [anonymous&nbsp;function](./23_lambda.md)
* anonymous type → [Type&nbsp;system](./type/01_type_system.md) * anonymous type → [Type&nbsp;system](./type/01_type_system.md)
* [Array](./10_array.md) * [List](./10_list.md)
* assert * assert
* [Attach](./30_decorator.md#attach) * [Attach](./31_decorator.md#attach)
* [attribute](type/09_attributive.md) * [attribute](type/09_attributive.md)
* [Attribute&nbsp;definitions](./type/02_basic.md#attribute-definitions) * [Attribute&nbsp;definitions](./type/02_basic.md#attribute-definitions)
* [Attribute&nbsp;type](./type/09_attributive.md) * [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) * [Bool, Boolean](./01_literal.md#boolean-object)
* [Boolean&nbsp;object](./01_literal.md#boolean-object) * [Boolean&nbsp;object](./01_literal.md#boolean-object)
* [borrowing](./19_ownership.md#borrow) * [borrowing](./20_ownership.md#borrow)
### C ### C
@ -104,24 +104,24 @@ Also, see [here](../terms.md) for terminology.
* [Comments](./00_basic.md#comments) * [Comments](./00_basic.md#comments)
* [Complex&nbsp;object](./01_literal.md#complex-object) * [Complex&nbsp;object](./01_literal.md#complex-object)
* [Compile-time&nbsp;functions](./04_function.md#compile-time-functions) * [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](./type/04_class.md)
* [Class&nbsp;relationship](./type/04_class.md#class-relationships) * [Class&nbsp;relationship](./type/04_class.md#class-relationships)
* [Class&nbsp;upcasting](./type/16_subtyping.md#class-upcasting) * [Class&nbsp;upcasting](./type/16_subtyping.md#class-upcasting)
* [Colon&nbsp;application&nbsp;style](./04_function.md#colon-application-style) * [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) * [Compound literals](./01_literal.md#compound-literals)
* [Complement](./type/13_algebraic.md#complement) * [Complement](./type/13_algebraic.md#complement)
* [Comprehension](./28_comprehension.md) * [Comprehension](./29_comprehension.md)
* [constant](./18_mutability.md#constant) * [constant](./19_mutability.md#constant)
* [Constants](./02_name.md#constants) * [Constants](./02_name.md#constants)
* [Context](./31_error_handling.md#context) * [Context](./32_error_handling.md#context)
### D ### D
* [Data&nbsp;type](./type/01_type_system.md#data-type) * [Data&nbsp;type](./type/01_type_system.md#data-type)
* [Declaration](./03_declaration.md) * [Declaration](./03_declaration.md)
* [decorator](./30_decorator.md) * [decorator](./31_decorator.md)
* [Default&nbsp;parameters](./04_function.md#default-parameters) * [Default&nbsp;parameters](./04_function.md#default-parameters)
* [Del](./02_name.md#delete-an-variable) * [Del](./02_name.md#delete-an-variable)
* [Dependent&nbsp;type](./type/14_dependent.md) * [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;class](./type/04_class.md#enum-class)
* [Enum&nbsp;type](./type/11_enum.md) * [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) * [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) * [Existential&nbsp;type](./type/advanced/existential.md)
* [Exponential&nbsp;literal](./01_literal.md#exponential-literal) * [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 ### F
@ -148,14 +148,14 @@ Also, see [here](../terms.md) for terminology.
* [Float&nbsp;object](./01_literal.md#float-object) * [Float&nbsp;object](./01_literal.md#float-object)
* [for](./05_builtin_funcs.md#for) * [for](./05_builtin_funcs.md#for)
* [For-All&nbsp;patch](./type/07_patch.md#for-all-patch) * [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](./04_function.md)
* [Function&nbsp;definition&nbsp;with&nbsp;multiple patterns](./04_function.md#function-definition-with-multiple-patterns) * [Function&nbsp;definition&nbsp;with&nbsp;multiple patterns](./04_function.md#function-definition-with-multiple-patterns)
### G ### G
* [GADTs(Generalized&nbsp;Algebraic&nbsp;Data&nbsp;Types)](./type/advanced/GADTs.md) * [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) * [Glue&nbsp;Patch](./type/07_patch.md#glue-patch)
### H ### H
@ -166,19 +166,19 @@ Also, see [here](../terms.md) for terminology.
* [id](./09_builtin_procs.md#id) * [id](./09_builtin_procs.md#id)
* [if](./05_builtin_funcs.md#if) * [if](./05_builtin_funcs.md#if)
* [import](./34_package_system.md) * [import](./35_package_system.md)
* [impl](./30_decorator.md#impl) * [impl](./31_decorator.md#impl)
* in * in
* [Indention](./00_basic.md#indentation) * [Indention](./00_basic.md#indentation)
* [Instant&nbsp;block](./14_record.md#instant-block) * [Instant&nbsp;block](./14_record.md#instant-block)
* [Instance/class&nbsp;attributes](./type/04_class.md#instance-and-class-attributes) * [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) * [inheritance](./type/05_inheritance.md)
* [Int](./01_literal.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) * [Interval&nbsp;Type](./type/10_interval.md)
* [Intersection](./type/13_algebraic.md#intersection) * [Intersection](./type/13_algebraic.md#intersection)
* [Iterator](./17_iterator.md) * [Iterator](./18_iterator.md)
### J ### J
@ -189,22 +189,22 @@ Also, see [here](../terms.md) for terminology.
### L ### L
* lambda → [anonymous&nbsp;function](./22_lambda.md) * lambda → [anonymous&nbsp;function](./23_lambda.md)
* let-polymorphism → [rank&nbsp;1&nbsp;polymorphism] * 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 ### M
* match * match
* [Marker&nbsp;trait](./type/advanced/marker_trait.md) * [Marker&nbsp;trait](./type/advanced/marker_trait.md)
* [Method](./07_side_effect.md#methods) * [Method](./07_side_effect.md#methods)
* Modifier → [decorator](./30_decorator.md) * Modifier → [decorator](./31_decorator.md)
* [module](./25_module.md) * [module](./26_module.md)
* [Multiple&nbsp;inheritance](type/05_inheritance.md#multiple-inheritance) * [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) * [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;type](./type/18_mut.md)
* [Mutable&nbsp;structure&nbsp;type](./type/advanced/mut_struct.md) * [Mutable&nbsp;structure&nbsp;type](./type/advanced/mut_struct.md)
* [Mutability](./18_mutability.md) * [Mutability](./19_mutability.md)
### N ### N
@ -220,28 +220,28 @@ Also, see [here](../terms.md) for terminology.
### O ### O
* [Object](./26_object_system.md) * [Object](./27_object_system.md)
* [Option] * [Option]
* [Or] * [Or]
* [or] * [or]
* [Ord] * [Ord]
* [ownership&nbsp;system](./19_ownership.md) * [ownership&nbsp;system](./20_ownership.md)
* [Overloading](./type/advanced/overloading.md) * [Overloading](./type/advanced/overloading.md)
* [Overriding](./type/05_inheritance.md#overriding) * [Overriding](./type/05_inheritance.md#overriding)
* [Override&nbsp;in&nbsp;trait](./type/03_trait.md#override-in-trait) * [Override&nbsp;in&nbsp;trait](./type/03_trait.md#override-in-trait)
### P ### P
* [Panic](./31_error_handling.md#panic) * [Panic](./32_error_handling.md#panic)
* [Patch](./type/07_patch.md) * [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) * [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) * [Predicate](./type/19_bound.md#predicate)
* print! * print!
* [Procedures](./08_procedure.md) * [Procedures](./08_procedure.md)
* [Projection&nbsp;type](./type/advanced/projection.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 ### Q
@ -257,9 +257,9 @@ Also, see [here](../terms.md) for terminology.
* [Recursive&nbsp;functions](./04_function.md#recursive-functions) * [Recursive&nbsp;functions](./04_function.md#recursive-functions)
* [Refinement&nbsp;pattern](./type/12_refinement.md#refinement-pattern) * [Refinement&nbsp;pattern](./type/12_refinement.md#refinement-pattern)
* [Refinement&nbsp;type](./type/12_refinement.md) * [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) * [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 ### S
@ -269,9 +269,9 @@ Also, see [here](../terms.md) for terminology.
* [Shared&nbsp;reference](./type/advanced/shared.md) * [Shared&nbsp;reference](./type/advanced/shared.md)
* [side-effect](./07_side_effect.md) * [side-effect](./07_side_effect.md)
* [Smart&nbsp;cast](./type/12_refinement.md#smart-cast) * [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) * [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) * [Structure&nbsp;type](./type/01_type_system.md#structure-type-anonymous-type)
* [Structural&nbsp;patch](./type/07_patch.md#structural-patch) * [Structural&nbsp;patch](./type/07_patch.md#structural-patch)
* [Structural&nbsp;trait](./type/03_trait.md#structural-traits) * [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) * [Subtyping&nbsp;of&nbsp;subroutines](./type/16_subtyping.md#subtyping-of-subroutines)
* [Subtype&nbsp;specification](./type/02_basic.md#subtype-specification) * [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) * [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 ### T
* [Test](./30_decorator.md#test) * [Test](./31_decorator.md#test)
* [Traits](./type/03_trait.md) * [Traits](./type/03_trait.md)
* [Trait&nbsp;inclusion](./type/03_trait.md#trait-inclusion) * [Trait&nbsp;inclusion](./type/03_trait.md#trait-inclusion)
* True → [Boolean&nbsp;object](./01_literal.md#boolean-object) * True → [Boolean&nbsp;object](./01_literal.md#boolean-object)

View file

@ -222,7 +222,7 @@ right(_, r) = r
### Variable length patterns ### 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 ```python
[i, *j] = [1, 2, 3, 4] [i, *j] = [1, 2, 3, 4]
@ -240,7 +240,7 @@ assert first(1, 2, 3) == 1
m, n = 1, 2 m, n = 1, 2
``` ```
### Array pattern ### List pattern
```python ```python
length [] = 0 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`). 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`. 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. The upper class of all classes is `Object == Class {:}` and the lower class of all types is `Never == Class {}`. This is described below.
## Types ## 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. 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. 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. > __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. 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. 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 ```python
Add R = Trait { Add R = Trait {

View file

@ -15,11 +15,11 @@ Type specifications are more useful when defining subroutines and types.
```python ```python
# Type specification for parameters # Type specification for parameters
f x, y: Array Int = ... f x, y: List Int = ...
T X, Y: Array 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 ```python
# The value of a capital variable must be a constant expression # 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 Id = Int
Point3D = {x = Int; y = Int; z = Int} Point3D = {x = Int; y = Int; z = Int}
IorS = Int or Str 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. 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 Id = Int
UserId = Int # TypeWarning: duplicate aliases: Id and UserId UserId = Int # TypeWarning: duplicate aliases: Id and UserId
Ids = Array Id Ids = List Id
Ints = Array Int # TypeWarning: duplicate aliases: Isd and Ints Ints = List Int # TypeWarning: duplicate aliases: Isd and Ints
IorS = Int or Str IorS = Int or Str
IorSorB = IorS or Bool 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 ```python
points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] 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 ## Trait inclusion
@ -151,11 +151,11 @@ Mapper T: Type = Trait {
.map = (self: Self, T -> U) -> Self.MapIter U .map = (self: Self, T -> U) -> Self.MapIter U
} }
# ArrayIterator <: Mapper # ListIterator <: Mapper
# ArrayIterator.MapIter == ArrayMapper # ListIterator.MapIter == ListMapper
# [1, 2, 3].iter(): ArrayIterator Int # [1, 2, 3].iter(): ListIterator Int
# [1, 2, 3].iter().map(x -> "\{x}"): ArrayMapper Str # [1, 2, 3].iter().map(x -> "\{x}"): ListMapper Str
assert [1, 2, 3].iter().map(x -> "\{x}").collect(Array) == ["1", "2", "3"]. assert [1, 2, 3].iter().map(x -> "\{x}").collect(List) == ["1", "2", "3"].
``` ```
## Override in Trait ## Override in Trait

View file

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

View file

@ -10,8 +10,8 @@ Nat = 0.. _
Odd = {N: Int | N % 2 == 1} Odd = {N: Int | N % 2 == 1}
Char = StrWithLen 1 Char = StrWithLen 1
# StrWithLen 1 == {_: StrWithLen N | N == 1} # StrWithLen 1 == {_: StrWithLen N | N == 1}
[Int; 3] == {_: Array Int, N | N == 3} [Int; 3] == {_: List Int, N | N == 3}
Array3OrMore == {A: Array _, 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. 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 ```python
# method `.m` is defined for arrays of length 3 or greater # method `.m` is defined for arrays of length 3 or greater
Array(T, N | N >= 3) List(T, N | N >= 3)
.m(&self) = ... .m(&self) = ...
``` ```

View file

@ -3,7 +3,7 @@
Dependent types are a feature that can be said to be the biggest feature of Erg. 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. 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`. 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 ```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. You can also embed or inherit existing types to create dependent types.
```python ```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 # The type of self: Self(T, N) changes in conjunction with .array
MyStruct!(T, N: Nat!) = Class {.array: [T; !N]} MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
@ -75,4 +75,4 @@ MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
<p align='center'> <p align='center'>
<a href='./13_algebraic.md'>Previous</a> | <a href='./15_quantified.md'>Next</a> <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 = [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. 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 ```python
a = [1, 2, 3].into [Nat; !3] 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. 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. 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 ```erg
[], [X; 0], [X; 1], [X; 2], ..., [X; _] == [X] [], [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) * 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 ```erg
[Int, Str] [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. 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. 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. 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 ```python
i: _ # i: Object 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. 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 ```python
implicit = (1..5).iter().map(i -> i * 2).to_arr() 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. 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 ```python
# collect is a higher-order Kind method that takes Kind # collect is a higher-order Kind method that takes Kind
hk = (1..5).iter().map(i -> i * 2).collect(Array) hk = (1..5).iter().map(i -> i * 2).collect(List)
hk: Array(Int) 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 `*`. 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. 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. 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. 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. 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 ```python
NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0} 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. 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`. 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`. 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)`. Consider the typical polymorphic type `List!(T)`.
Note that this time it's not `Array!(T, N)` because we don't care about the number of elements. Note that this time it's not `List!(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: 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 List.push!: Self(T).(T) => NoneType
Array.pop!: Self(T).() => T List.pop!: Self(T).() => T
As can be intuitively understood, As can be intuitively understood,
* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`) * `List!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
* When `o: Object`, `Array!(Str).push!(o)` is NG * When `o: Object`, `List!(Str).push!(o)` is NG
* `Array!(Object).pop!().into(Str)` is NG * `List!(Object).pop!().into(Str)` is NG
* `Array!(Str).pop!().into(Object)` is OK * `List!(Str).pop!().into(Object)` is OK
is. In terms of the type system, this is 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. Giving arguments to a subroutine object and getting a result.
Use Call. This is because Application has a usage of "application software". 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 ## 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. 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`を使う。 ただしクラスは比較できないため、インスタンス判定がしたい場合は`classof(object) == Class`ではなく`object in Class`を使う。
コンパイル時に決定される構造型は`Typeof`で得られる。 コンパイル時に決定される構造型は`Typeof`で得られる。
## Iterator, Array生成系 ## Iterator, List生成系
### repeat|T|(x: T) -> RepeatIterator T ### repeat|T|(x: T) -> RepeatIterator T

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