aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-17 22:22:46 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-03-17 22:22:46 -0400
commit5109fad68b801a5e89da69976a1a8a4d819d1689 (patch)
treeb87e32b769c17372b82080f314a7082c330fdabe
parentca62aa365faee27895f8cb1eccddd7af8a7d15c9 (diff)
Fully rename array to list
-rw-r--r--Makefile2
-rw-r--r--README.md8
-rw-r--r--ast.c4
-rw-r--r--ast.h8
-rw-r--r--compile.c260
-rw-r--r--docs/README.md2
-rw-r--r--docs/command-line-parsing.md6
-rw-r--r--docs/lists.md (renamed from docs/arrays.md)268
-rw-r--r--docs/metamethods.md10
-rw-r--r--docs/nums.md2
-rw-r--r--docs/operators.md12
-rw-r--r--docs/optionals.md8
-rw-r--r--docs/paths.md10
-rw-r--r--docs/patterns.md2
-rw-r--r--docs/pointers.md14
-rw-r--r--docs/reductions.md2
-rw-r--r--docs/rng.md8
-rw-r--r--docs/serialization.md6
-rw-r--r--docs/sets.md8
-rw-r--r--docs/tables.md6
-rw-r--r--docs/text.md42
-rw-r--r--environment.c12
-rw-r--r--environment.h2
-rw-r--r--examples/commands/commands.c32
-rw-r--r--examples/learnxiny.tm24
-rw-r--r--parse.c34
-rw-r--r--repl.c30
-rw-r--r--stdlib/README.md2
-rw-r--r--stdlib/arrays.h137
-rw-r--r--stdlib/c_strings.c2
-rw-r--r--stdlib/datatypes.h34
-rw-r--r--stdlib/enums.c4
-rw-r--r--stdlib/enums.h2
-rw-r--r--stdlib/integers.c16
-rw-r--r--stdlib/integers.h6
-rw-r--r--stdlib/lists.c (renamed from stdlib/arrays.c)286
-rw-r--r--stdlib/lists.h137
-rw-r--r--stdlib/metamethods.c16
-rw-r--r--stdlib/metamethods.h8
-rw-r--r--stdlib/nums.c2
-rw-r--r--stdlib/optionals.c6
-rw-r--r--stdlib/optionals.h6
-rw-r--r--stdlib/paths.c104
-rw-r--r--stdlib/paths.h18
-rw-r--r--stdlib/patterns.c58
-rw-r--r--stdlib/patterns.h8
-rw-r--r--stdlib/pointers.c4
-rw-r--r--stdlib/pointers.h2
-rw-r--r--stdlib/rng.c10
-rw-r--r--stdlib/rng.h6
-rw-r--r--stdlib/stdlib.c28
-rw-r--r--stdlib/structs.c4
-rw-r--r--stdlib/structs.h2
-rw-r--r--stdlib/tables.c24
-rw-r--r--stdlib/tables.h12
-rw-r--r--stdlib/text.c72
-rw-r--r--stdlib/text.h20
-rw-r--r--stdlib/threads.c4
-rw-r--r--stdlib/tomo.h2
-rw-r--r--stdlib/types.c2
-rw-r--r--stdlib/types.h6
-rw-r--r--test/lists.tm (renamed from test/arrays.tm)2
-rw-r--r--test/optionals.tm8
-rw-r--r--test/rng.tm2
-rw-r--r--tomo.c52
-rw-r--r--typecheck.c68
-rw-r--r--types.c28
-rw-r--r--types.h6
68 files changed, 1019 insertions, 1019 deletions
diff --git a/Makefile b/Makefile
index 3d66ae61..29a541fc 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ O=-Og
CFLAGS=$(CCONFIG) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LTO)
CFLAGS_PLACEHOLDER="$$(echo -e '\033[2m<flags...>\033[m')"
LDLIBS=-lgc -lcord -lm -lunistring -lgmp -ldl
-BUILTIN_OBJS=stdlib/siphash.o stdlib/arrays.o stdlib/bools.o stdlib/bytes.o stdlib/nums.o stdlib/integers.o \
+BUILTIN_OBJS=stdlib/siphash.o stdlib/lists.o stdlib/bools.o stdlib/bytes.o stdlib/nums.o stdlib/integers.o \
stdlib/pointers.o stdlib/memory.o stdlib/text.o stdlib/threads.o stdlib/c_strings.o stdlib/tables.o \
stdlib/types.o stdlib/util.o stdlib/files.o stdlib/paths.o stdlib/rng.o \
stdlib/optionals.o stdlib/patterns.o stdlib/metamethods.o stdlib/functiontype.o stdlib/stdlib.o \
diff --git a/README.md b/README.md
index 730613dc..d983161f 100644
--- a/README.md
+++ b/README.md
@@ -45,8 +45,8 @@ of many language features or the other example programs/modules in
### Safety
- Memory safety (garbage collection, [compiler-enforced null
- safety](docs/pointers.md), [automatic array bounds
- checking](docs/arrays.md), and no uninitialized variables)
+ safety](docs/pointers.md), [automatic list bounds
+ checking](docs/lists.md), and no uninitialized variables)
- High-performance [arbitrary-precision integers](docs/integers.md) by default
with opt-in fixed-size integers with arithmetic overflow checking
- [Type-safe strings representing different languages](docs/langs.md) with
@@ -55,7 +55,7 @@ of many language features or the other example programs/modules in
unions/enums)](docs/enums.md)
- Type-safe [optional values](docs/optionals.tm) with low syntax overhead
- Efficient datastructures with immutable value semantics:
- [arrays](docs/arrays.md), [tables](docs/tables.md), [sets](docs/sets.md),
+ [lists](docs/lists.md), [tables](docs/tables.md), [sets](docs/sets.md),
[text](docs/text.md).
- [Privacy-protecting types](docs/structs.md#Secret-Values) that help prevent
accidentally logging sensitive information
@@ -70,7 +70,7 @@ of many language features or the other example programs/modules in
- [String interpolation](docs/text.md) and debug printing builtins
- Built-in datastructures with a rich library of commonly used methods:
- [arrays](docs/arrays.md), [tables](docs/tables.md), [sets](docs/sets.md),
+ [lists](docs/lists.md), [tables](docs/tables.md), [sets](docs/sets.md),
[text](docs/text.md).
- Full-featured [libraries/modules](docs/libraries.md)
- [Full UTF8 support](docs/text.md) for all text operations
diff --git a/ast.c b/ast.c
index 982ef7dc..ab152597 100644
--- a/ast.c
+++ b/ast.c
@@ -121,7 +121,7 @@ CORD ast_to_xml(ast_t *ast)
T(Holding, "<Holding>%r%r</Holding>", ast_to_xml(data.mutexed), ast_to_xml(data.body))
T(Min, "<Min>%r%r%r</Min>", ast_to_xml(data.lhs), ast_to_xml(data.rhs), optional_tagged("key", data.key))
T(Max, "<Max>%r%r%r</Max>", ast_to_xml(data.lhs), ast_to_xml(data.rhs), optional_tagged("key", data.key))
- T(Array, "<Array>%r%r</Array>", optional_tagged_type("item-type", data.item_type), ast_list_to_xml(data.items))
+ T(List, "<List>%r%r</List>", optional_tagged_type("item-type", data.item_type), ast_list_to_xml(data.items))
T(Set, "<Set>%r%r</Set>",
optional_tagged_type("item-type", data.item_type),
ast_list_to_xml(data.items))
@@ -184,7 +184,7 @@ CORD type_ast_to_xml(type_ast_t *t)
T(VarTypeAST, "%s", data.name)
T(PointerTypeAST, "<PointerType is_stack=\"%s\">%r</PointerType>",
data.is_stack ? "yes" : "no", type_ast_to_xml(data.pointed))
- T(ArrayTypeAST, "<ArrayType>%r</ArrayType>", type_ast_to_xml(data.item))
+ T(ListTypeAST, "<ListType>%r</ListType>", type_ast_to_xml(data.item))
T(SetTypeAST, "<TableType>%r</TableType>", type_ast_to_xml(data.item))
T(TableTypeAST, "<TableType>%r %r</TableType>", type_ast_to_xml(data.key), type_ast_to_xml(data.value))
T(FunctionTypeAST, "<FunctionType>%r %r</FunctionType>", arg_list_to_xml(data.args), type_ast_to_xml(data.ret))
diff --git a/ast.h b/ast.h
index c9db9061..9c9d107c 100644
--- a/ast.h
+++ b/ast.h
@@ -71,7 +71,7 @@ typedef enum {
UnknownTypeAST,
VarTypeAST,
PointerTypeAST,
- ArrayTypeAST,
+ ListTypeAST,
SetTypeAST,
TableTypeAST,
FunctionTypeAST,
@@ -101,7 +101,7 @@ struct type_ast_s {
} PointerTypeAST;
struct {
type_ast_t *item;
- } ArrayTypeAST;
+ } ListTypeAST;
struct {
type_ast_t *key, *value;
ast_t *default_value;
@@ -129,7 +129,7 @@ typedef enum {
BinaryOp, UpdateAssign,
Not, Negative, HeapAllocate, StackReference, Mutexed, Holding,
Min, Max,
- Array, Set, Table, TableEntry, Comprehension,
+ List, Set, Table, TableEntry, Comprehension,
FunctionDef, Lambda, ConvertDef,
FunctionCall, MethodCall,
Block,
@@ -206,7 +206,7 @@ struct ast_s {
struct {
type_ast_t *item_type;
ast_list_t *items;
- } Array;
+ } List;
struct {
type_ast_t *item_type;
ast_list_t *items;
diff --git a/compile.c b/compile.c
index 84d48368..68ad7247 100644
--- a/compile.c
+++ b/compile.c
@@ -160,9 +160,9 @@ static bool promote(env_t *env, ast_t *ast, CORD *code, type_t *actual, type_t *
return true;
}
- // Set -> Array promotion:
- if (needed->tag == ArrayType && actual->tag == SetType
- && type_eq(Match(needed, ArrayType)->item_type, Match(actual, SetType)->item_type)) {
+ // Set -> List promotion:
+ if (needed->tag == ListType && actual->tag == SetType
+ && type_eq(Match(needed, ListType)->item_type, Match(actual, SetType)->item_type)) {
*code = CORD_all("(", *code, ").entries");
return true;
}
@@ -173,8 +173,8 @@ static bool promote(env_t *env, ast_t *ast, CORD *code, type_t *actual, type_t *
CORD compile_maybe_incref(env_t *env, ast_t *ast, type_t *t)
{
if (is_idempotent(ast) && can_be_mutated(env, ast)) {
- if (t->tag == ArrayType)
- return CORD_all("ARRAY_COPY(", compile_to_type(env, ast, t), ")");
+ if (t->tag == ListType)
+ return CORD_all("LIST_COPY(", compile_to_type(env, ast, t), ")");
else if (t->tag == TableType || t->tag == SetType)
return CORD_all("TABLE_COPY(", compile_to_type(env, ast, t), ")");
}
@@ -252,8 +252,8 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
add_closed_vars(closed_vars, enclosing_scope, env, Match(ast, Max)->key);
break;
}
- case Array: {
- for (ast_list_t *item = Match(ast, Array)->items; item; item = item->next)
+ case List: {
+ for (ast_list_t *item = Match(ast, List)->items; item; item = item->next)
add_closed_vars(closed_vars, enclosing_scope, env, item->ast);
break;
}
@@ -282,7 +282,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
return add_closed_vars(closed_vars, enclosing_scope, env, loop);
}
- // Array/Set/Table comprehension:
+ // List/Set/Table comprehension:
ast_t *body = comp->expr;
if (comp->filter)
body = WrapAST(comp->expr, If, .condition=comp->filter, .body=body);
@@ -528,7 +528,7 @@ CORD compile_type(type_t *t)
else
return CORD_all(namespace_prefix(text->env, text->env->namespace->parent), text->lang, "$$type");
}
- case ArrayType: return "Array_t";
+ case ListType: return "List_t";
case SetType: return "Table_t";
case TableType: return "Table_t";
case FunctionType: {
@@ -562,7 +562,7 @@ CORD compile_type(type_t *t)
case TextType:
return Match(nonnull, TextType)->lang ? compile_type(nonnull) : "OptionalText_t";
case IntType: case BigIntType: case NumType: case BoolType: case ByteType:
- case ArrayType: case TableType: case SetType: case MomentType:
+ case ListType: case TableType: case SetType: case MomentType:
return CORD_all("Optional", compile_type(nonnull));
case StructType: {
if (nonnull == THREAD_TYPE)
@@ -608,15 +608,15 @@ static CORD compile_lvalue(env_t *env, ast_t *ast)
return compile(env, ast);
container_t = value_type(container_t);
- if (container_t->tag == ArrayType) {
+ if (container_t->tag == ListType) {
CORD target_code = compile_to_pointer_depth(env, index->indexed, 1, false);
- type_t *item_type = Match(container_t, ArrayType)->item_type;
+ type_t *item_type = Match(container_t, ListType)->item_type;
if (index->unchecked) {
- return CORD_all("Array_lvalue_unchecked(", compile_type(item_type), ", ", target_code, ", ",
+ return CORD_all("List_lvalue_unchecked(", compile_type(item_type), ", ", target_code, ", ",
compile_int_to_type(env, index->index, Type(IntType, .bits=TYPE_IBITS64)),
", sizeof(", compile_type(item_type), "))");
} else {
- return CORD_all("Array_lvalue(", compile_type(item_type), ", ", target_code, ", ",
+ return CORD_all("List_lvalue(", compile_type(item_type), ", ", target_code, ", ",
compile_int_to_type(env, index->index, Type(IntType, .bits=TYPE_IBITS64)),
", ", heap_strf("%ld", ast->start - ast->file->text),
", ", heap_strf("%ld", ast->end - ast->file->text), ")");
@@ -706,7 +706,7 @@ CORD check_none(type_t *t, CORD value)
return CORD_all("((", value, ").fn == NULL)");
else if (t->tag == NumType)
return CORD_all("isnan(", value, ")");
- else if (t->tag == ArrayType)
+ else if (t->tag == ListType)
return CORD_all("((", value, ").length < 0)");
else if (t->tag == TableType || t->tag == SetType)
return CORD_all("((", value, ").entries.length < 0)");
@@ -732,7 +732,7 @@ static CORD compile_condition(env_t *env, ast_t *ast)
return compile(env, ast);
} else if (t->tag == TextType) {
return CORD_all("(", compile(env, ast), ").length");
- } else if (t->tag == ArrayType) {
+ } else if (t->tag == ListType) {
return CORD_all("(", compile(env, ast), ").length");
} else if (t->tag == TableType || t->tag == SetType) {
return CORD_all("(", compile(env, ast), ").entries.length");
@@ -1163,13 +1163,13 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
case BINOP_CONCAT: {
if (lhs_t->tag == TextType) {
return CORD_all(lhs, " = Texts(", lhs, ", ", rhs, ");");
- } else if (lhs_t->tag == ArrayType) {
- CORD padded_item_size = CORD_all("sizeof(", compile_type(Match(lhs_t, ArrayType)->item_type), ")");
+ } else if (lhs_t->tag == ListType) {
+ CORD padded_item_size = CORD_all("sizeof(", compile_type(Match(lhs_t, ListType)->item_type), ")");
// arr ++= [...]
if (update->lhs->tag == Var)
- return CORD_all("Array$insert_all(&", lhs, ", ", rhs, ", I(0), ", padded_item_size, ");");
+ return CORD_all("List$insert_all(&", lhs, ", ", rhs, ", I(0), ", padded_item_size, ");");
else
- return CORD_all(lhs, " = Array$concat(", lhs, ", ", rhs, ", ", padded_item_size, ");");
+ return CORD_all(lhs, " = List$concat(", lhs, ", ", rhs, ", ", padded_item_size, ");");
} else {
code_err(ast, "'++=' is not implemented for %T types", lhs_t);
}
@@ -1369,7 +1369,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
auto for_ = Match(ast, For);
// If we're iterating over a comprehension, that's actually just doing
- // one loop, we don't need to compile the comprehension as an array
+ // one loop, we don't need to compile the comprehension as an list
// comprehension. This is a common case for reducers like `(+: i*2 for i in 5)`
// or `(and) x:is_good() for x in xs`
if (for_->iter->tag == Comprehension) {
@@ -1472,8 +1472,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
type_t *iter_value_t = value_type(iter_t);
switch (iter_value_t->tag) {
- case ArrayType: {
- type_t *item_t = Match(iter_value_t, ArrayType)->item_type;
+ case ListType: {
+ type_t *item_t = Match(iter_value_t, ListType)->item_type;
CORD index = CORD_EMPTY;
CORD value = CORD_EMPTY;
if (for_->vars) {
@@ -1508,17 +1508,17 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (iter_t->tag == PointerType) {
loop = CORD_all("{\n"
- "Array_t *ptr = ", compile_to_pointer_depth(env, for_->iter, 1, false), ";\n"
- "\nARRAY_INCREF(*ptr);\n"
- "Array_t iterating = *ptr;\n",
+ "List_t *ptr = ", compile_to_pointer_depth(env, for_->iter, 1, false), ";\n"
+ "\nLIST_INCREF(*ptr);\n"
+ "List_t iterating = *ptr;\n",
loop,
stop,
- "\nARRAY_DECREF(*ptr);\n"
+ "\nLIST_DECREF(*ptr);\n"
"}\n");
} else {
loop = CORD_all("{\n"
- "Array_t iterating = ", compile_to_pointer_depth(env, for_->iter, 0, false), ";\n",
+ "List_t iterating = ", compile_to_pointer_depth(env, for_->iter, 0, false), ";\n",
loop,
stop,
"}\n");
@@ -1564,15 +1564,15 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
loop = CORD_all(
"{\n",
"Table_t *t = ", compile_to_pointer_depth(env, for_->iter, 1, false), ";\n"
- "ARRAY_INCREF(t->entries);\n"
- "Array_t iterating = t->entries;\n",
+ "LIST_INCREF(t->entries);\n"
+ "List_t iterating = t->entries;\n",
loop,
- "ARRAY_DECREF(t->entries);\n"
+ "LIST_DECREF(t->entries);\n"
"}\n");
} else {
loop = CORD_all(
"{\n",
- "Array_t iterating = (", compile_to_pointer_depth(env, for_->iter, 0, false), ").entries;\n",
+ "List_t iterating = (", compile_to_pointer_depth(env, for_->iter, 0, false), ").entries;\n",
loop,
"}\n");
}
@@ -1739,7 +1739,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
return compile_statement(env, loop);
}
- // Array/Set/Table comprehension:
+ // List/Set/Table comprehension:
comprehension_body_t get_body = (void*)env->comprehension_action->fn;
ast_t *body = get_body(comp->expr, env->comprehension_action->userdata);
if (comp->filter)
@@ -1806,7 +1806,7 @@ CORD expr_as_text(CORD expr, type_t *t, CORD color)
return CORD_asprintf("%r$as_text(stack(%r), %r, &%r$info)", name, expr, color, name);
}
case TextType: return CORD_asprintf("Text$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
- case ArrayType: return CORD_asprintf("Array$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
+ case ListType: return CORD_asprintf("List$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
case SetType: return CORD_asprintf("Table$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
case TableType: return CORD_asprintf("Table$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
case FunctionType: case ClosureType: return CORD_asprintf("Func$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(t));
@@ -1859,8 +1859,8 @@ CORD compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool
t = ptr->pointed;
}
- if (needs_incref && t->tag == ArrayType)
- val = CORD_all("ARRAY_COPY(", val, ")");
+ if (needs_incref && t->tag == ListType)
+ val = CORD_all("LIST_COPY(", val, ")");
else if (needs_incref && (t->tag == TableType || t->tag == SetType))
val = CORD_all("TABLE_COPY(", val, ")");
@@ -2207,7 +2207,7 @@ CORD compile_none(type_t *t)
}
case BoolType: return "NONE_BOOL";
case ByteType: return "NONE_BYTE";
- case ArrayType: return "NONE_ARRAY";
+ case ListType: return "NONE_LIST";
case TableType: return "NONE_TABLE";
case SetType: return "NONE_TABLE";
case TextType: return "NONE_TEXT";
@@ -2233,7 +2233,7 @@ static ast_t *add_to_table_comprehension(ast_t *entry, ast_t *subject)
.args=new(arg_ast_t, .value=e->key, .next=new(arg_ast_t, .value=e->value)));
}
-static ast_t *add_to_array_comprehension(ast_t *item, ast_t *subject)
+static ast_t *add_to_list_comprehension(ast_t *item, ast_t *subject)
{
return WrapAST(item, MethodCall, .name="insert", .self=subject, .args=new(arg_ast_t, .value=item));
}
@@ -2297,7 +2297,7 @@ CORD compile(env_t *env, ast_t *ast)
return CORD_all("!(", compile(env, value), ")");
else if (t->tag == IntType || t->tag == ByteType)
return CORD_all("~(", compile(env, value), ")");
- else if (t->tag == ArrayType)
+ else if (t->tag == ListType)
return CORD_all("((", compile(env, value), ").length == 0)");
else if (t->tag == SetType || t->tag == TableType)
return CORD_all("((", compile(env, value), ").entries.length == 0)");
@@ -2628,8 +2628,8 @@ CORD compile(env_t *env, ast_t *ast)
case TextType: {
return CORD_all("Text$concat(", lhs, ", ", rhs, ")");
}
- case ArrayType: {
- return CORD_all("Array$concat(", lhs, ", ", rhs, ", sizeof(", compile_type(Match(operand_t, ArrayType)->item_type), "))");
+ case ListType: {
+ return CORD_all("List$concat(", lhs, ", ", rhs, ", sizeof(", compile_type(Match(operand_t, ListType)->item_type), "))");
}
default:
code_err(ast, "Concatenation isn't supported between %T and %T values", lhs_t, rhs_t);
@@ -2762,49 +2762,49 @@ CORD compile(env_t *env, ast_t *ast)
comparison, " ? ternary$lhs : ternary$rhs;\n"
"})");
}
- case Array: {
- type_t *array_type = get_type(env, ast);
- type_t *item_type = Match(array_type, ArrayType)->item_type;
- // if (type_size(Match(array_type, ArrayType)->item_type) > ARRAY_MAX_STRIDE)
- // code_err(ast, "This array holds items that take up %ld bytes, but the maximum supported size is %ld bytes. Consider using an array of pointers instead.",
- // type_size(item_type), ARRAY_MAX_STRIDE);
+ case List: {
+ type_t *list_type = get_type(env, ast);
+ type_t *item_type = Match(list_type, ListType)->item_type;
+ // if (type_size(Match(list_type, ListType)->item_type) > LIST_MAX_STRIDE)
+ // code_err(ast, "This list holds items that take up %ld bytes, but the maximum supported size is %ld bytes. Consider using an list of pointers instead.",
+ // type_size(item_type), LIST_MAX_STRIDE);
- auto array = Match(ast, Array);
- if (!array->items)
- return "(Array_t){.length=0}";
+ auto list = Match(ast, List);
+ if (!list->items)
+ return "(List_t){.length=0}";
int64_t n = 0;
- for (ast_list_t *item = array->items; item; item = item->next) {
+ for (ast_list_t *item = list->items; item; item = item->next) {
++n;
if (item->ast->tag == Comprehension)
- goto array_comprehension;
+ goto list_comprehension;
}
{
env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env;
- CORD code = CORD_all("TypedArrayN(", compile_type(item_type), CORD_asprintf(", %ld", n));
- for (ast_list_t *item = array->items; item; item = item->next) {
+ CORD code = CORD_all("TypedListN(", compile_type(item_type), CORD_asprintf(", %ld", n));
+ for (ast_list_t *item = list->items; item; item = item->next) {
code = CORD_all(code, ", ", compile_to_type(scope, item->ast, item_type));
}
return CORD_cat(code, ")");
}
- array_comprehension:
+ list_comprehension:
{
env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env);
static int64_t comp_num = 1;
const char *comprehension_name = heap_strf("arr$%ld", comp_num++);
ast_t *comprehension_var = FakeAST(InlineCCode, .code=CORD_all("&", comprehension_name),
- .type=Type(PointerType, .pointed=array_type, .is_stack=true));
- Closure_t comp_action = {.fn=add_to_array_comprehension, .userdata=comprehension_var};
+ .type=Type(PointerType, .pointed=list_type, .is_stack=true));
+ Closure_t comp_action = {.fn=add_to_list_comprehension, .userdata=comprehension_var};
scope->comprehension_action = &comp_action;
- CORD code = CORD_all("({ Array_t ", comprehension_name, " = {};");
- // set_binding(scope, comprehension_name, array_type, comprehension_name);
- for (ast_list_t *item = array->items; item; item = item->next) {
+ CORD code = CORD_all("({ List_t ", comprehension_name, " = {};");
+ // set_binding(scope, comprehension_name, list_type, comprehension_name);
+ for (ast_list_t *item = list->items; item; item = item->next) {
if (item->ast->tag == Comprehension)
code = CORD_all(code, "\n", compile_statement(scope, item->ast));
else
- code = CORD_all(code, compile_statement(env, add_to_array_comprehension(item->ast, comprehension_var)));
+ code = CORD_all(code, compile_statement(env, add_to_list_comprehension(item->ast, comprehension_var)));
}
code = CORD_all(code, " ", comprehension_name, "; })");
return code;
@@ -2939,7 +2939,7 @@ CORD compile(env_t *env, ast_t *ast)
if (base->tag == TableEntry)
return compile(env, WrapAST(ast, Table, .entries=new(ast_list_t, .ast=ast)));
else
- return compile(env, WrapAST(ast, Array, .items=new(ast_list_t, .ast=ast)));
+ return compile(env, WrapAST(ast, List, .items=new(ast_list_t, .ast=ast)));
}
case Lambda: {
auto lambda = Match(ast, Lambda);
@@ -3009,8 +3009,8 @@ CORD compile(env_t *env, ast_t *ast)
binding_t *b = get_binding(env, entry->name);
assert(b);
CORD binding_code = b->code;
- if (entry->b->type->tag == ArrayType)
- userdata = CORD_all(userdata, ", ARRAY_COPY(", binding_code, ")");
+ if (entry->b->type->tag == ListType)
+ userdata = CORD_all(userdata, ", LIST_COPY(", binding_code, ")");
else if (entry->b->type->tag == TableType || entry->b->type->tag == SetType)
userdata = CORD_all(userdata, ", TABLE_COPY(", binding_code, ")");
else
@@ -3057,68 +3057,68 @@ CORD compile(env_t *env, ast_t *ast)
else if (pointer_depth > 1) code_err(call->self, "I expected "article" "name" pointer here, not a nested "name" pointer"); \
} while (0)
switch (self_value_t->tag) {
- case ArrayType: {
- type_t *item_t = Match(self_value_t, ArrayType)->item_type;
+ case ListType: {
+ type_t *item_t = Match(self_value_t, ListType)->item_type;
CORD padded_item_size = CORD_all("sizeof(", compile_type(item_t), ")");
ast_t *default_rng = FakeAST(InlineCCode, .code="default_rng", .type=RNG_TYPE);
if (streq(call->name, "insert")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t,
.next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0")));
- return CORD_all("Array$insert_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$insert_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "insert_all")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="items", .type=self_value_t,
.next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0")));
- return CORD_all("Array$insert_all(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$insert_all(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "remove_at")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1"),
.next=new(arg_t, .name="count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1")));
- return CORD_all("Array$remove_at(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$remove_at(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "remove_item")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t,
.next=new(arg_t, .name="max_count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1")));
- return CORD_all("Array$remove_item_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$remove_item_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
compile_type_info(self_value_t), ")");
} else if (streq(call->name, "random")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="rng", .type=RNG_TYPE, .default_val=default_rng);
- return CORD_all("Array$random_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type(item_t), ")");
+ return CORD_all("List$random_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type(item_t), ")");
} else if (streq(call->name, "has")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t);
- return CORD_all("Array$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
compile_type_info(self_value_t), ")");
} else if (streq(call->name, "sample")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="count", .type=INT_TYPE,
- .next=new(arg_t, .name="weights", .type=Type(ArrayType, .item_type=Type(NumType)),
- .default_val=FakeAST(None, .type=new(type_ast_t, .tag=ArrayTypeAST,
- .__data.ArrayTypeAST.item=new(type_ast_t, .tag=VarTypeAST, .__data.VarTypeAST.name="Num"))),
+ .next=new(arg_t, .name="weights", .type=Type(ListType, .item_type=Type(NumType)),
+ .default_val=FakeAST(None, .type=new(type_ast_t, .tag=ListTypeAST,
+ .__data.ListTypeAST.item=new(type_ast_t, .tag=VarTypeAST, .__data.VarTypeAST.name="Num"))),
.next=new(arg_t, .name="rng", .type=RNG_TYPE, .default_val=default_rng)));
- return CORD_all("Array$sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
+ return CORD_all("List$sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "shuffle")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="rng", .type=RNG_TYPE, .default_val=default_rng);
- return CORD_all("Array$shuffle(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
+ return CORD_all("List$shuffle(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
} else if (streq(call->name, "shuffled")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="rng", .type=RNG_TYPE, .default_val=default_rng);
- return CORD_all("Array$shuffled(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
+ return CORD_all("List$shuffled(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
} else if (streq(call->name, "slice")) {
self = compile_to_pointer_depth(env, call->self, 0, true);
arg_t *arg_spec = new(arg_t, .name="first", .type=INT_TYPE, .next=new(arg_t, .name="last", .type=INT_TYPE));
- return CORD_all("Array$slice(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
+ return CORD_all("List$slice(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
} else if (streq(call->name, "sort") || streq(call->name, "sorted")) {
if (streq(call->name, "sort"))
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
else
self = compile_to_pointer_depth(env, call->self, 0, false);
CORD comparison;
@@ -3131,9 +3131,9 @@ CORD compile(env_t *env, ast_t *ast)
} else {
comparison = CORD_all("((Closure_t){.fn=generic_compare, .userdata=(void*)", compile_type_info(item_t), "})");
}
- return CORD_all("Array$", call->name, "(", self, ", ", comparison, ", ", padded_item_size, ")");
+ return CORD_all("List$", call->name, "(", self, ", ", comparison, ", ", padded_item_size, ")");
} else if (streq(call->name, "heapify")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
CORD comparison;
if (call->args) {
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
@@ -3144,9 +3144,9 @@ CORD compile(env_t *env, ast_t *ast)
} else {
comparison = CORD_all("((Closure_t){.fn=generic_compare, .userdata=(void*)", compile_type_info(item_t), "})");
}
- return CORD_all("Array$heapify(", self, ", ", comparison, ", ", padded_item_size, ")");
+ return CORD_all("List$heapify(", self, ", ", comparison, ", ", padded_item_size, ")");
} else if (streq(call->name, "heap_push")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
.ret=Type(IntType, .bits=TYPE_IBITS32));
@@ -3157,9 +3157,9 @@ CORD compile(env_t *env, ast_t *ast)
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t,
.next=new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp));
CORD arg_code = compile_arguments(env, ast, arg_spec, call->args);
- return CORD_all("Array$heap_push_value(", self, ", ", arg_code, ", ", padded_item_size, ")");
+ return CORD_all("List$heap_push_value(", self, ", ", arg_code, ", ", padded_item_size, ")");
} else if (streq(call->name, "heap_pop")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
.ret=Type(IntType, .bits=TYPE_IBITS32));
@@ -3169,7 +3169,7 @@ CORD compile(env_t *env, ast_t *ast)
.type=Type(ClosureType, .fn=fn_t));
arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp);
CORD arg_code = compile_arguments(env, ast, arg_spec, call->args);
- return CORD_all("Array$heap_pop_value(", self, ", ", arg_code, ", ", compile_type(item_t), ", _, ",
+ return CORD_all("List$heap_pop_value(", self, ", ", arg_code, ", ", compile_type(item_t), ", _, ",
promote_to_optional(item_t, "_"), ", ", compile_none(item_t), ")");
} else if (streq(call->name, "binary_search")) {
self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL);
@@ -3183,15 +3183,15 @@ CORD compile(env_t *env, ast_t *ast)
arg_t *arg_spec = new(arg_t, .name="target", .type=item_t,
.next=new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp));
CORD arg_code = compile_arguments(env, ast, arg_spec, call->args);
- return CORD_all("Array$binary_search_value(", self, ", ", arg_code, ")");
+ return CORD_all("List$binary_search_value(", self, ", ", arg_code, ")");
} else if (streq(call->name, "clear")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
(void)compile_arguments(env, ast, NULL, call->args);
- return CORD_all("Array$clear(", self, ")");
+ return CORD_all("List$clear(", self, ")");
} else if (streq(call->name, "find")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t);
- return CORD_all("Array$find_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args),
+ return CORD_all("List$find_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args),
", ", compile_type_info(self_value_t), ")");
} else if (streq(call->name, "first")) {
self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL);
@@ -3199,38 +3199,38 @@ CORD compile(env_t *env, ast_t *ast)
type_t *predicate_type = Type(
ClosureType, .fn=Type(FunctionType, .args=new(arg_t, .name="item", .type=item_ptr), .ret=Type(BoolType)));
arg_t *arg_spec = new(arg_t, .name="predicate", .type=predicate_type);
- return CORD_all("Array$first(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
+ return CORD_all("List$first(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
} else if (streq(call->name, "from")) {
self = compile_to_pointer_depth(env, call->self, 0, true);
arg_t *arg_spec = new(arg_t, .name="first", .type=INT_TYPE);
- return CORD_all("Array$from(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
+ return CORD_all("List$from(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
} else if (streq(call->name, "to")) {
self = compile_to_pointer_depth(env, call->self, 0, true);
arg_t *arg_spec = new(arg_t, .name="last", .type=INT_TYPE);
- return CORD_all("Array$to(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
+ return CORD_all("List$to(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
} else if (streq(call->name, "by")) {
self = compile_to_pointer_depth(env, call->self, 0, true);
arg_t *arg_spec = new(arg_t, .name="stride", .type=INT_TYPE);
- return CORD_all("Array$by(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
+ return CORD_all("List$by(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")");
} else if (streq(call->name, "reversed")) {
self = compile_to_pointer_depth(env, call->self, 0, true);
(void)compile_arguments(env, ast, NULL, call->args);
- return CORD_all("Array$reversed(", self, ", ", padded_item_size, ")");
+ return CORD_all("List$reversed(", self, ", ", padded_item_size, ")");
} else if (streq(call->name, "unique")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
(void)compile_arguments(env, ast, NULL, call->args);
return CORD_all("Table$from_entries(", self, ", Set$info(", compile_type_info(item_t), "))");
} else if (streq(call->name, "pop")) {
- EXPECT_POINTER("an", "array");
+ EXPECT_POINTER("an", "list");
arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, "-1"));
CORD index = compile_arguments(env, ast, arg_spec, call->args);
- return CORD_all("Array$pop(", self, ", ", index, ", ", compile_type(item_t), ", _, ",
+ return CORD_all("List$pop(", self, ", ", index, ", ", compile_type(item_t), ", _, ",
promote_to_optional(item_t, "_"), ", ", compile_none(item_t), ")");
} else if (streq(call->name, "counts")) {
self = compile_to_pointer_depth(env, call->self, 0, false);
(void)compile_arguments(env, ast, NULL, call->args);
- return CORD_all("Array$counts(", self, ", ", compile_type_info(self_value_t), ")");
- } else code_err(ast, "There is no '%s' method for arrays", call->name);
+ return CORD_all("List$counts(", self, ", ", compile_type_info(self_value_t), ")");
+ } else code_err(ast, "There is no '%s' method for lists", call->name);
}
case SetType: {
auto set = Match(self_value_t, SetType);
@@ -3246,9 +3246,9 @@ CORD compile(env_t *env, ast_t *ast)
compile_type_info(self_value_t), ")");
} else if (streq(call->name, "add_all")) {
EXPECT_POINTER("a", "set");
- arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ArrayType, .item_type=Match(self_value_t, SetType)->item_type));
+ arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ListType, .item_type=Match(self_value_t, SetType)->item_type));
return CORD_all("({ Table_t *set = ", self, "; ",
- "Array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
+ "List_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
"for (int64_t i = 0; i < to_add.length; i++)\n"
"Table$set(set, to_add.data + i*to_add.stride, NULL, ", compile_type_info(self_value_t), ");\n",
"(void)0; })");
@@ -3259,9 +3259,9 @@ CORD compile(env_t *env, ast_t *ast)
compile_type_info(self_value_t), ")");
} else if (streq(call->name, "remove_all")) {
EXPECT_POINTER("a", "set");
- arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ArrayType, .item_type=Match(self_value_t, SetType)->item_type));
+ arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ListType, .item_type=Match(self_value_t, SetType)->item_type));
return CORD_all("({ Table_t *set = ", self, "; ",
- "Array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
+ "List_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
"for (int64_t i = 0; i < to_add.length; i++)\n"
"Table$remove(set, to_add.data + i*to_add.stride, ", compile_type_info(self_value_t), ");\n",
"(void)0; })");
@@ -3434,8 +3434,8 @@ CORD compile(env_t *env, ast_t *ast)
case Deserialize: {
ast_t *value = Match(ast, Deserialize)->value;
type_t *value_type = get_type(env, value);
- if (!type_eq(value_type, Type(ArrayType, Type(ByteType))))
- code_err(value, "This value should be an array of bytes, not a %T", value_type);
+ if (!type_eq(value_type, Type(ListType, Type(ByteType))))
+ code_err(value, "This value should be an list of bytes, not a %T", value_type);
type_t *t = parse_type_ast(env, Match(ast, Deserialize)->type);
return CORD_all("({ ", compile_declaration(t, "deserialized"), ";\n"
"generic_deserialize(", compile(env, value), ", &deserialized, ", compile_type_info(t), ");\n"
@@ -3701,14 +3701,14 @@ CORD compile(env_t *env, ast_t *ast)
}
code_err(ast, "The field '%s' is not a valid tag name of %T", f->field, value_t);
}
- case ArrayType: {
+ case ListType: {
if (streq(f->field, "length"))
return CORD_all("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)");
- code_err(ast, "There is no %s field on arrays", f->field);
+ code_err(ast, "There is no %s field on lists", f->field);
}
case SetType: {
if (streq(f->field, "items"))
- return CORD_all("ARRAY_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
+ return CORD_all("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
else if (streq(f->field, "length"))
return CORD_all("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)");
code_err(ast, "There is no '%s' field on sets", f->field);
@@ -3717,13 +3717,13 @@ CORD compile(env_t *env, ast_t *ast)
if (streq(f->field, "length")) {
return CORD_all("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)");
} else if (streq(f->field, "keys")) {
- return CORD_all("ARRAY_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
+ return CORD_all("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
} else if (streq(f->field, "values")) {
auto table = Match(value_t, TableType);
CORD offset = CORD_all("offsetof(struct { ", compile_declaration(table->key_type, "k"), "; ", compile_declaration(table->value_type, "v"), "; }, v)");
- return CORD_all("({ Array_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries;\n"
- "ARRAY_INCREF(*entries);\n"
- "Array_t values = *entries;\n"
+ return CORD_all("({ List_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries;\n"
+ "LIST_INCREF(*entries);\n"
+ "List_t values = *entries;\n"
"values.data += ", offset, ";\n"
"values; })");
} else if (streq(f->field, "fallback")) {
@@ -3755,8 +3755,8 @@ CORD compile(env_t *env, ast_t *ast)
if (indexed_type->tag != PointerType)
code_err(ast, "Only pointers can use the '[]' operator to dereference the entire value.");
auto ptr = Match(indexed_type, PointerType);
- if (ptr->pointed->tag == ArrayType) {
- return CORD_all("*({ Array_t *arr = ", compile(env, indexing->indexed), "; ARRAY_INCREF(*arr); arr; })");
+ if (ptr->pointed->tag == ListType) {
+ return CORD_all("*({ List_t *arr = ", compile(env, indexing->indexed), "; LIST_INCREF(*arr); arr; })");
} else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) {
return CORD_all("*({ Table_t *t = ", compile(env, indexing->indexed), "; TABLE_INCREF(*t); t; })");
} else {
@@ -3766,10 +3766,10 @@ CORD compile(env_t *env, ast_t *ast)
type_t *container_t = value_type(indexed_type);
type_t *index_t = get_type(env, indexing->index);
- if (container_t->tag == ArrayType) {
+ if (container_t->tag == ListType) {
if (index_t->tag != IntType && index_t->tag != BigIntType && index_t->tag != ByteType)
- code_err(indexing->index, "Arrays can only be indexed by integers, not %T", index_t);
- type_t *item_type = Match(container_t, ArrayType)->item_type;
+ code_err(indexing->index, "Lists can only be indexed by integers, not %T", index_t);
+ type_t *item_type = Match(container_t, ListType)->item_type;
CORD arr = compile_to_pointer_depth(env, indexing->indexed, 0, false);
file_t *f = indexing->index->file;
CORD index_code = indexing->index->tag == Int
@@ -3777,9 +3777,9 @@ CORD compile(env_t *env, ast_t *ast)
: (index_t->tag == BigIntType ? CORD_all("Int64$from_int(", compile(env, indexing->index), ", no)")
: CORD_all("(Int64_t)(", compile(env, indexing->index), ")"));
if (indexing->unchecked)
- return CORD_all("Array_get_unchecked(", compile_type(item_type), ", ", arr, ", ", index_code, ")");
+ return CORD_all("List_get_unchecked(", compile_type(item_type), ", ", arr, ", ", index_code, ")");
else
- return CORD_all("Array_get(", compile_type(item_type), ", ", arr, ", ", index_code, ", ",
+ return CORD_all("List_get(", compile_type(item_type), ", ", arr, ", ", index_code, ", ",
CORD_asprintf("%ld", (int64_t)(indexing->index->start - f->text)), ", ",
CORD_asprintf("%ld", (int64_t)(indexing->index->end - f->text)),
")");
@@ -3858,9 +3858,9 @@ CORD compile_type_info(type_t *t)
auto e = Match(t, EnumType);
return CORD_all("(&", namespace_prefix(e->env, e->env->namespace->parent), e->name, "$$info)");
}
- case ArrayType: {
- type_t *item_t = Match(t, ArrayType)->item_type;
- return CORD_all("Array$info(", compile_type_info(item_t), ")");
+ case ListType: {
+ type_t *item_t = Match(t, ListType)->item_type;
+ return CORD_all("List$info(", compile_type_info(item_t), ")");
}
case SetType: {
type_t *item_type = Match(t, SetType)->item_type;
@@ -3958,7 +3958,7 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type)
} else {
if (t->tag == BoolType || (t->tag == OptionalType && Match(t, OptionalType)->type->tag == BoolType))
usage = CORD_all(usage, "[--", flag, "]");
- else if (t->tag == ArrayType)
+ else if (t->tag == ListType)
usage = CORD_all(usage, "[--", flag, " ", get_flag_options(t, "|"), "]");
else
usage = CORD_all(usage, "[--", flag, "=", get_flag_options(t, "|"), "]");
@@ -3968,7 +3968,7 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type)
usage = CORD_all(usage, "<--", flag, "|--no-", flag, ">");
else if (t->tag == EnumType)
usage = CORD_all(usage, get_flag_options(t, "|"));
- else if (t->tag == ArrayType)
+ else if (t->tag == ListType)
usage = CORD_all(usage, "[", flag, "...]");
else
usage = CORD_all(usage, "<", flag, ">");
diff --git a/docs/README.md b/docs/README.md
index 4bfc2e1e..beb05c3f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -18,7 +18,7 @@ A few topics that are documented:
Information about Tomo's built-in types can be found here:
-- [Arrays](arrays.md)
+- [Lists](lists.md)
- [Booleans](booleans.md)
- [Bytes](bytes.md)
- [Moment](moments.md)
diff --git a/docs/command-line-parsing.md b/docs/command-line-parsing.md
index 230105d5..ac906c91 100644
--- a/docs/command-line-parsing.md
+++ b/docs/command-line-parsing.md
@@ -97,10 +97,10 @@ foo: Invalid value provided for --foo; valid values are: One Two
Signature: foo [--help] <foo>
```
-### Arrays of Text
+### Lists of Text
-Currently, Tomo supports accepting arguments that take an array of text.
-Array-of-text arguments can be passed like this:
+Currently, Tomo supports accepting arguments that take an list of text.
+List-of-text arguments can be passed like this:
```tomo
# many-texts.tm
diff --git a/docs/arrays.md b/docs/lists.md
index 8715cf3c..c2e72973 100644
--- a/docs/arrays.md
+++ b/docs/lists.md
@@ -1,31 +1,31 @@
-# Arrays
+# Lists
-Tomo supports arrays as a container type that holds a list of elements of any
-type in a compact format. Arrays are immutable by default, but use
-copy-on-write semantics to efficiently mutate in place when possible. **Arrays
-are 1-indexed**, which means the first item in the array has index `1`.
+Tomo supports lists as a container type that holds a list of elements of any
+type in a compact format. Lists are immutable by default, but use
+copy-on-write semantics to efficiently mutate in place when possible. **Lists
+are 1-indexed**, which means the first item in the list has index `1`.
## Syntax
-Arrays are written using square brackets and a list of comma-separated elements:
+Lists are written using square brackets and a list of comma-separated elements:
```tomo
nums := [10, 20, 30]
```
Each element must have the same type (or be easily promoted to the same type). If
-you want to have an empty array, you must specify what type goes inside the array
+you want to have an empty list, you must specify what type goes inside the list
like this:
```tomo
empty := [:Int]
```
-For type annotations, an array that holds items with type `T` is written as `[T]`.
+For type annotations, an list that holds items with type `T` is written as `[T]`.
-### Array Comprehensions
+### List Comprehensions
-Arrays can also use comprehensions, where you specify how to dynamically create
+Lists can also use comprehensions, where you specify how to dynamically create
all the elements by iteration instead of manually specifying each:
```tomo
@@ -44,7 +44,7 @@ Comprehensions can be combined with regular items or other comprehensions:
## Length
-Array length can be accessed by the `.length` field:
+List length can be accessed by the `.length` field:
```tomo
>> [10, 20, 30].length
@@ -53,9 +53,9 @@ Array length can be accessed by the `.length` field:
## Indexing
-Array values are accessed using square bracket indexing. Since arrays are
-1-indexed, the index `1` corresponds to the first item in the array. Negative
-indices are used to refer to items from the back of the array, so `-1` is the
+List values are accessed using square bracket indexing. Since lists are
+1-indexed, the index `1` corresponds to the first item in the list. Negative
+indices are used to refer to items from the back of the list, so `-1` is the
last item, `-2` is the second-to-last, and so on.
```tomo
@@ -73,34 +73,34 @@ arr := [10, 20, 30, 40]
= 30
```
-If an array index of `0` or any value larger than the length of the array is
-used, it will trigger a runtime error that will print what the invalid array
-index was, the length of the array, and a stack trace. As a performance
-operation, if array bounds checking proves to be a performance hot spot, you
+If an list index of `0` or any value larger than the length of the list is
+used, it will trigger a runtime error that will print what the invalid list
+index was, the length of the list, and a stack trace. As a performance
+operation, if list bounds checking proves to be a performance hot spot, you
can explicitly disable bounds checking by adding `arr[i; unchecked]` to the
-array access.
+list access.
## Iteration
-You can iterate over the items in an array like this:
+You can iterate over the items in an list like this:
```tomo
-for item in array:
+for item in list:
...
-for i, item in array:
+for i, item in list:
...
```
-Array iteration operates over the value of the array when the loop began, so
-modifying the array during iteration is safe and will not result in the loop
+List iteration operates over the value of the list when the loop began, so
+modifying the list during iteration is safe and will not result in the loop
iterating over any of the new values.
## Concatenation
-Arrays can be concatenated with the `++` operator, which returns an array that
+Lists can be concatenated with the `++` operator, which returns an list that
has the items from one appended to the other. This should not be confused with
-the addition operator `+`, which does not work with arrays.
+the addition operator `+`, which does not work with lists.
```tomo
>> [1, 2] ++ [3, 4]
@@ -109,58 +109,58 @@ the addition operator `+`, which does not work with arrays.
## Implementation Details
-Under the hood, arrays are implemented as a struct that contains a pointer to a
-contiguous chunk of memory storing the elements of the array and some other
+Under the hood, lists are implemented as a struct that contains a pointer to a
+contiguous chunk of memory storing the elements of the list and some other
metadata. Since Tomo has datatypes with different sizes, like `Bool`s which
take one byte and `struct`s which can take up many bytes, it's worth noting
-that arrays store the elements compactly and inline, without the need for each
-array cell to hold a pointer to where the data actually lives.
+that lists store the elements compactly and inline, without the need for each
+list cell to hold a pointer to where the data actually lives.
-The other metadata stored with an array includes its length as well as the
-_stride_ of the array. The stride is not exposed to the user, but it's the gap
-in bytes between each element in the array. The reason this is mentioned is
-that it is possible to create immutable slices of arrays in constant time by
+The other metadata stored with an list includes its length as well as the
+_stride_ of the list. The stride is not exposed to the user, but it's the gap
+in bytes between each element in the list. The reason this is mentioned is
+that it is possible to create immutable slices of lists in constant time by
creating a new struct that points to the appropriate starting place for the
-array items and has the appropriate stride. The upshot is that a method like
-`array:reversed()` does not actually copy the array, it simply returns a struct
-that points to the back of the array with a negative stride. Arrays adhere to
+list items and has the appropriate stride. The upshot is that a method like
+`list:reversed()` does not actually copy the list, it simply returns a struct
+that points to the back of the list with a negative stride. Lists adhere to
copy-on-write semantics, so we can cheaply create many read-only references to
the same data, and only need to do copying if we plan to modify data. After
doing a modification, future modifications can be done in-place as long as
there is only one reference to that data.
Internally, we also take advantage of this inside of tables, which compactly
-store all of the key/value pairs in a contiguous array and we can return an
-immutable slice of that array showing only the keys or only the values by
+store all of the key/value pairs in a contiguous list and we can return an
+immutable slice of that list showing only the keys or only the values by
choosing the right starting point and stride.
## Copy on Write
-Arrays can be thought of as values that have copy-on-write semantics that use
+Lists can be thought of as values that have copy-on-write semantics that use
reference counting to perform efficient in-place mutations instead of copying
as a performance optimization when it wouldn't affect the program's semantics.
Without getting too deep into the details, suffice it to say that when you
-create an array, that array can be thought of as a singular "value" in the same
+create an list, that list can be thought of as a singular "value" in the same
way that `123` is a value. That variable's value will never change unless you
explicitly perform an assignment operation on the variable or call a method on
the variable.
-Because it would be tedious to require users to write all array operations as
-pure functions like `array = array:with_value_at_index(value=x, index=i)`, Tomo
-provides the familiar imperative syntax for modifying arrays, but keeps the
-semantics of the pure functional style. Writing `array[i] = x` is
-_semantically_ equivalent to `array = array:with_value_at_index(value=x,
+Because it would be tedious to require users to write all list operations as
+pure functions like `list = list:with_value_at_index(value=x, index=i)`, Tomo
+provides the familiar imperative syntax for modifying lists, but keeps the
+semantics of the pure functional style. Writing `list[i] = x` is
+_semantically_ equivalent to `list = list:with_value_at_index(value=x,
index=i)`, but much more readable and easy to write. Similarly,
-`array:insert(x)` is semantically equivalent to `array =
-array:with_value_inserted(x)`. We implement these mutating methods as functions
-that take a pointer to an array variable, which then either mutate the array's
+`list:insert(x)` is semantically equivalent to `list =
+list:with_value_inserted(x)`. We implement these mutating methods as functions
+that take a pointer to an list variable, which then either mutate the list's
data in-place (if this is the only thing referencing that data) or construct a
-new array and store its value in the memory where the array variable is stored.
+new list and store its value in the memory where the list variable is stored.
-When there is only a single reference to an array value, we can perform these
-modifications in-place (arrays typically have a little bit of spare capacity at
+When there is only a single reference to an list value, we can perform these
+modifications in-place (lists typically have a little bit of spare capacity at
the end, so appending usually doesn't trigger a reallocation). When there are
-shared references, we must create a copy of the array's data before modifying
+shared references, we must create a copy of the list's data before modifying
it so the other references don't see the effects of the mutation. Here are some
simple examples:
@@ -192,18 +192,18 @@ nums[4] = -1
= [10, 20, 30, -1]
```
-Array reference counting is _approximate_, but will only ever err on the side
+List reference counting is _approximate_, but will only ever err on the side
of correctness at the expense of performance, not the other way around.
Occasionally, unnecessary copying may occur, but you should never experience an
-array value changing because of some operation performed on a different array
+list value changing because of some operation performed on a different list
value.
-## Array Pointers
+## List Pointers
-Since the normal case of arrays is to treat them like immutable values, what do
-we do if we actually want to have a shared reference to an array whose contents
+Since the normal case of lists is to treat them like immutable values, what do
+we do if we actually want to have a shared reference to an list whose contents
change over time? In that case, we want to use the `@` operator to create a
-pointer to a heap-allocated array and pass that pointer around. This is the same
+pointer to a heap-allocated list and pass that pointer around. This is the same
behavior that you get in Python when you create a `list`:
```tomo
@@ -215,8 +215,8 @@ nums:insert(40)
= @[10, 20, 30, 40]
```
-Having multiple pointers to the same heap-allocated array does not cause the
-array's reference count to increase, because there is only one "value" in play:
+Having multiple pointers to the same heap-allocated list does not cause the
+list's reference count to increase, because there is only one "value" in play:
the one stored on the heap. It's only when we store the "value" in multiple
places that we need to increment the reference count:
@@ -227,10 +227,10 @@ value := nums[]
```
The TL;DR is: you can cheaply modify local variables that aren't aliased or
-`@`-allocated arrays, but if you assign a local variable array to another
+`@`-allocated lists, but if you assign a local variable list to another
variable or dereference a heap pointer, it may trigger copy-on-write behavior.
-## Array Methods
+## List Methods
- [`func binary_search(arr:List(T), by: func(x,y:&T->Int32) = T.compare -> Int)`](#binary_search)
- [`func by(arr:List(T), step: Int -> List(T))`](#by)
@@ -260,21 +260,21 @@ variable or dereference a heap pointer, it may trigger copy-on-write behavior.
- [`unique(arr:List(T) -> Set(T))`](#unique)
### `binary_search`
-Performs a binary search on a sorted array.
+Performs a binary search on a sorted list.
```tomo
func binary_search(arr:List(T), by: func(x,y:&T->Int32) = T.compare -> Int)
```
-- `arr`: The sorted array to search.
+- `arr`: The sorted list to search.
- `by`: The comparison function used to determine order. If not specified, the
default comparison function for the item type will be used.
**Returns:**
-Assuming the input array is sorted according to the given comparison function,
+Assuming the input list is sorted according to the given comparison function,
return the index where the given item would be inserted to maintain the sorted
order. That is, if the item is found, return its index, otherwise return the
-place where it would be found if it were inserted and the array were sorted.
+place where it would be found if it were inserted and the list were sorted.
**Example:**
```tomo
@@ -291,17 +291,17 @@ place where it would be found if it were inserted and the array were sorted.
---
### `by`
-Creates a new array with elements spaced by the specified step value.
+Creates a new list with elements spaced by the specified step value.
```tomo
func by(arr:List(T), step: Int -> List(T))
```
-- `arr`: The original array.
+- `arr`: The original list.
- `step`: The step value for selecting elements.
**Returns:**
-A new array with every `step`-th element from the original array.
+A new list with every `step`-th element from the original list.
**Example:**
```tomo
@@ -312,32 +312,32 @@ A new array with every `step`-th element from the original array.
---
### `clear`
-Clears all elements from the array.
+Clears all elements from the list.
```tomo
func clear(arr:@List(T) -> Void)
```
-- `arr`: The mutable reference to the array to be cleared.
+- `arr`: The mutable reference to the list to be cleared.
**Returns:**
Nothing.
**Example:**
```tomo
->> my_array:clear()
+>> my_list:clear()
```
---
### `counts`
-Counts the occurrences of each element in the array.
+Counts the occurrences of each element in the list.
```tomo
func counts(arr:List(T) -> Table(T, Int))
```
-- `arr`: The array to count elements in.
+- `arr`: The list to count elements in.
**Returns:**
A table mapping each element to its count.
@@ -357,8 +357,8 @@ Finds the index of the first occurrence of an element (if any).
func find(arr:List(T), target: T -> Int?)
```
-- `arr`: The array to search through.
-- `item`: The item to find in the array.
+- `arr`: The list to search through.
+- `item`: The item to find in the list.
**Returns:**
The index of the first occurrence or `!Int` if not found.
@@ -381,7 +381,7 @@ Find the index of the first item that matches a predicate function (if any).
func first(arr:List(T), predicate: func(item:&T -> Bool) -> Int)
```
-- `arr`: The array to search through.
+- `arr`: The list to search through.
- `predicate`: A function that returns `yes` if the item should be returned or
`no` if it should not.
@@ -400,17 +400,17 @@ item matches.
---
### `from`
-Returns a slice of the array starting from a specified index.
+Returns a slice of the list starting from a specified index.
```tomo
func from(arr:List(T), first: Int -> List(T))
```
-- `arr`: The original array.
+- `arr`: The original list.
- `first`: The index to start from.
**Returns:**
-A new array starting from the specified index.
+A new list starting from the specified index.
**Example:**
```tomo
@@ -421,16 +421,16 @@ A new array starting from the specified index.
---
### `has`
-Checks if the array has any elements.
+Checks if the list has any elements.
```tomo
func has(arr:List(T) -> Bool)
```
-- `arr`: The array to check.
+- `arr`: The list to check.
**Returns:**
-`yes` if the array has elements, `no` otherwise.
+`yes` if the list has elements, `no` otherwise.
**Example:**
```tomo
@@ -441,7 +441,7 @@ func has(arr:List(T) -> Bool)
---
### `heap_pop`
-Removes and returns the top element of a heap or `none` if the array is empty.
+Removes and returns the top element of a heap or `none` if the list is empty.
By default, this is the *minimum* value in the heap.
```tomo
@@ -453,7 +453,7 @@ func heap_pop(arr:@List(T), by: func(x,y:&T->Int32) = T.compare -> T?)
default comparison function for the item type will be used.
**Returns:**
-The removed top element of the heap or `none` if the array is empty.
+The removed top element of the heap or `none` if the list is empty.
**Example:**
```tomo
@@ -489,13 +489,13 @@ Nothing.
---
### `heapify`
-Converts an array into a heap.
+Converts an list into a heap.
```tomo
func heapify(arr:@List(T), by: func(x,y:&T->Int32) = T.compare -> Void)
```
-- `arr`: The mutable reference to the array to be heapified.
+- `arr`: The mutable reference to the list to be heapified.
- `by`: The comparison function used to determine order. If not specified, the
default comparison function for the item type will be used.
@@ -511,13 +511,13 @@ Nothing.
---
### `insert`
-Inserts an element at a specified position in the array.
+Inserts an element at a specified position in the list.
```tomo
func insert(arr:@List(T), item: T, at: Int = 0 -> Void)
```
-- `arr`: The mutable reference to the array.
+- `arr`: The mutable reference to the list.
- `item`: The item to be inserted.
- `at`: The index at which to insert the item (default is `0`). Since indices
are 1-indexed and negative indices mean "starting from the back", an index of
@@ -541,13 +541,13 @@ Nothing.
---
### `insert_all`
-Inserts an array of items at a specified position in the array.
+Inserts an list of items at a specified position in the list.
```tomo
func insert_all(arr:@List(T), items:List(T), at: Int = 0 -> Void)
```
-- `arr`: The mutable reference to the array.
+- `arr`: The mutable reference to the list.
- `items`: The items to be inserted.
- `at`: The index at which to insert the item (default is `0`). Since indices
are 1-indexed and negative indices mean "starting from the back", an index of
@@ -571,19 +571,19 @@ arr:insert_all([99, 100], at=2)
---
### `pop`
-Removes and returns an item from the array. If the given index is present in
-the array, the item at that index will be removed and the array will become one
+Removes and returns an item from the list. If the given index is present in
+the list, the item at that index will be removed and the list will become one
element shorter.
```tomo
func pop(arr:&List(T), index: Int = -1 -> T?)
```
-- `arr`: The array to remove an item from.
+- `arr`: The list to remove an item from.
- `index`: The index from which to remove the item (default: the last item).
**Returns:**
-`none` if the array is empty or the given index does not exist in the array,
+`none` if the list is empty or the given index does not exist in the list,
otherwise the item at the given index.
**Example:**
@@ -604,17 +604,17 @@ otherwise the item at the given index.
---
### `random`
-Selects a random element from the array.
+Selects a random element from the list.
```tomo
func random(arr:List(T), rng: RNG = random -> T)
```
-- `arr`: The array from which to select a random element.
+- `arr`: The list from which to select a random element.
- `rng`: The [random number generator](rng.md) to use.
**Returns:**
-A random element from the array.
+A random element from the list.
**Example:**
```tomo
@@ -625,14 +625,14 @@ A random element from the array.
---
### `remove_at`
-Removes elements from the array starting at a specified index.
+Removes elements from the list starting at a specified index.
```tomo
func remove_at(arr:@List(T), at: Int = -1, count: Int = 1 -> Void)
```
-- `arr`: The mutable reference to the array.
-- `at`: The index at which to start removing elements (default is `-1`, which means the end of the array).
+- `arr`: The mutable reference to the list.
+- `at`: The index at which to start removing elements (default is `-1`, which means the end of the list).
- `count`: The number of elements to remove (default is `1`).
**Returns:**
@@ -653,13 +653,13 @@ arr:remove_at(2, count=2)
---
### `remove_item`
-Removes all occurrences of a specified item from the array.
+Removes all occurrences of a specified item from the list.
```tomo
func remove_item(arr:@List(T), item: T, max_count: Int = -1 -> Void)
```
-- `arr`: The mutable reference to the array.
+- `arr`: The mutable reference to the list.
- `item`: The item to be removed.
- `max_count`: The maximum number of occurrences to remove (default is `-1`, meaning all occurrences).
@@ -681,16 +681,16 @@ arr:remove_item(20, max_count=1)
---
### `reversed`
-Returns a reversed slice of the array.
+Returns a reversed slice of the list.
```tomo
func reversed(arr:List(T) -> List(T))
```
-- `arr`: The array to be reversed.
+- `arr`: The list to be reversed.
**Returns:**
-A slice of the array with elements in reverse order.
+A slice of the list with elements in reverse order.
**Example:**
```tomo
@@ -701,16 +701,16 @@ A slice of the array with elements in reverse order.
---
### `sample`
-Selects a sample of elements from the array, optionally with weighted
+Selects a sample of elements from the list, optionally with weighted
probabilities.
```tomo
func sample(arr:List(T), count: Int, weights:List(Num)? = ![Num], rng: RNG = random -> List(T))
```
-- `arr`: The array to sample from.
+- `arr`: The list to sample from.
- `count`: The number of elements to sample.
-- `weights`: The probability weights for each element in the array. These
+- `weights`: The probability weights for each element in the list. These
values do not need to add up to any particular number, they are relative
weights. If no weights are given, elements will be sampled with uniform
probability.
@@ -718,14 +718,14 @@ func sample(arr:List(T), count: Int, weights:List(Num)? = ![Num], rng: RNG = ran
**Errors:**
Errors will be raised if any of the following conditions occurs:
-- The given array has no elements and `count >= 1`
+- The given list has no elements and `count >= 1`
- `count < 0` (negative count)
-- The number of weights provided doesn't match the length of the array.
-- Any weight in the weights array is negative, infinite, or `NaN`
+- The number of weights provided doesn't match the length of the list.
+- Any weight in the weights list is negative, infinite, or `NaN`
- The sum of the given weights is zero (zero probability for every element).
**Returns:**
-A list of sampled elements from the array.
+A list of sampled elements from the list.
**Example:**
```tomo
@@ -736,13 +736,13 @@ A list of sampled elements from the array.
---
### `shuffle`
-Shuffles the elements of the array in place.
+Shuffles the elements of the list in place.
```tomo
func shuffle(arr:@List(T), rng: RNG = random -> Void)
```
-- `arr`: The mutable reference to the array to be shuffled.
+- `arr`: The mutable reference to the list to be shuffled.
- `rng`: The [random number generator](rng.md) to use.
**Returns:**
@@ -756,17 +756,17 @@ Nothing.
---
### `shuffled`
-Creates a new array with elements shuffled.
+Creates a new list with elements shuffled.
```tomo
func shuffled(arr:List(T), rng: RNG = random -> List(T))
```
-- `arr`: The array to be shuffled.
+- `arr`: The list to be shuffled.
- `rng`: The [random number generator](rng.md) to use.
**Returns:**
-A new array with shuffled elements.
+A new list with shuffled elements.
**Example:**
```tomo
@@ -777,19 +777,19 @@ A new array with shuffled elements.
---
### `slice`
-Returns a slice of the array spanning the given indices (inclusive).
+Returns a slice of the list spanning the given indices (inclusive).
```tomo
func slice(arr:List(T), from: Int, to: Int -> List(T))
```
-- `arr`: The original array.
+- `arr`: The original list.
- `from`: The first index to include.
- `to`: The last index to include.
**Returns:**
-A new array spanning the given indices. Note: negative indices are counted from
-the back of the array, so `-1` refers to the last element, `-2` the
+A new list spanning the given indices. Note: negative indices are counted from
+the back of the list, so `-1` refers to the last element, `-2` the
second-to-last, and so on.
**Example:**
@@ -804,13 +804,13 @@ second-to-last, and so on.
---
### `sort`
-Sorts the elements of the array in place in ascending order (small to large).
+Sorts the elements of the list in place in ascending order (small to large).
```tomo
func sort(arr:@List(T), by=T.compare -> Void)
```
-- `arr`: The mutable reference to the array to be sorted.
+- `arr`: The mutable reference to the list to be sorted.
- `by`: The comparison function used to determine order. If not specified, the
default comparison function for the item type will be used.
@@ -832,18 +832,18 @@ arr:sort(func(a,b:&Int): a:abs() <> b:abs())
---
### `sorted`
-Creates a new array with elements sorted.
+Creates a new list with elements sorted.
```tomo
sorted(arr:List(T), by=T.compare -> List(T))
```
-- `arr`: The array to be sorted.
+- `arr`: The list to be sorted.
- `by`: The comparison function used to determine order. If not specified, the
default comparison function for the item type will be used.
**Returns:**
-A new array with sorted elements.
+A new list with sorted elements.
**Example:**
```tomo
@@ -857,17 +857,17 @@ A new array with sorted elements.
---
### `to`
-Returns a slice of the array from the start of the original array up to a specified index (inclusive).
+Returns a slice of the list from the start of the original list up to a specified index (inclusive).
```tomo
to(arr:List(T), last: Int -> List(T))
```
-- `arr`: The original array.
+- `arr`: The original list.
- `last`: The index up to which elements should be included.
**Returns:**
-A new array containing elements from the start up to the specified index.
+A new list containing elements from the start up to the specified index.
**Example:**
```tomo
@@ -881,16 +881,16 @@ A new array containing elements from the start up to the specified index.
---
### `unique`
-Returns a Set that contains the unique elements of the array.
+Returns a Set that contains the unique elements of the list.
```tomo
unique(arr:List(T) -> Set(T))
```
-- `arr`: The array to process.
+- `arr`: The list to process.
**Returns:**
-A set containing only unique elements from the array.
+A set containing only unique elements from the list.
**Example:**
```tomo
diff --git a/docs/metamethods.md b/docs/metamethods.md
index 0983aff0..f47c8233 100644
--- a/docs/metamethods.md
+++ b/docs/metamethods.md
@@ -31,17 +31,17 @@ enums. At this time, metamethods may not be overridden.
## Generic Metamethods
-Due to the presence of pointers, arrays, tables, and functions, there are
+Due to the presence of pointers, lists, tables, and functions, there are
potentially a very large number of metamethods that would be required if
_every_ type had its own set of metamethods. To reduce the amount of generated
code, Tomo uses generic metamethods, which are general-purpose functions that
take an object pointer and a type info struct pointer that has metadata about
the object's type. That metadata is added automatically at compile time and
-used to perform the appropriate operations. As an example, every array follows
+used to perform the appropriate operations. As an example, every list follows
the same logic when performing comparisons, except that each item is compared
-using the item's comparison function. Therefore, we can compile a single array
-comparison function and reuse it for each type of array if we pass in some
-metadata about how to compare the array's items.
+using the item's comparison function. Therefore, we can compile a single list
+comparison function and reuse it for each type of list if we pass in some
+metadata about how to compare the list's items.
When possible, we avoid calling metamethods (for example, doing fixed-sized
integer comparisons does not require calling a function), but metamethods are
diff --git a/docs/nums.md b/docs/nums.md
index 7a86a585..8b6da8d9 100644
--- a/docs/nums.md
+++ b/docs/nums.md
@@ -27,7 +27,7 @@ differentiate between possibly-NaN values and definitely-not-NaN values.
Tomo has a separate concept for expressing the lack of a defined value:
optional types. Consequently, Tomo has merged these two concepts, so `NaN` is
called `none` and has the type `Num?` or `Num32?`. In this way, it's no
-different from optional integers or optional arrays. This means that if a
+different from optional integers or optional lists. This means that if a
variable has type `Num`, it is guaranteed to not hold a NaN value. This also
means that operations which may produce NaN values have a result type of
`Num?`. For example, division can take two non-NaN values and return a result
diff --git a/docs/operators.md b/docs/operators.md
index 25f78689..8d0bf6c8 100644
--- a/docs/operators.md
+++ b/docs/operators.md
@@ -7,8 +7,8 @@ Tomo supports a number of operators, both infix and prefix:
- `^`: exponentiation for integers and floating point numbers
- `mod`: modulus for integers and floating point numbers
- `mod1`: clock-style modulus, which is equivalent to `1 + ((x-1) mod y)`. This
- is particularly useful for doing wraparound behavior on 1-indexed arrays.
-- `++`: concatenation (for text and arrays)
+ is particularly useful for doing wraparound behavior on 1-indexed lists.
+- `++`: concatenation (for text and lists)
- `<<`, `>>`: bitwise left shift and right shift for integers
- `<<<`, `>>>`: unsigned bitwise left shift and right shift for integers
- `_min_`/`_max_`: minimum and maximum (see below)
@@ -33,7 +33,7 @@ value to the user.
= 1[32]
```
-It's particularly handy for using the array `sort()` method, which takes a
+It's particularly handy for using the list `sort()` method, which takes a
function that returns a signed integer:
```tomo
@@ -153,16 +153,16 @@ struct Person(name:Text, age:Int)
>> Person("Alice", 33) _max_.age Person("Bob", 20)
= Person(name="Alice", age=33)
-// Get the longest of two arrays:
+// Get the longest of two lists:
>> [10, 20, 30, 40] _max_.length [99, 1]
= [10, 20, 30, 40]
-// Get the array with the highest value in the last position:
+// Get the list with the highest value in the last position:
>> [10, 20, 999] _max_[-1] [99, 1]
= [10, 20, 999]
```
-The keyed comparison can chain together multiple field accesses, array index
+The keyed comparison can chain together multiple field accesses, list index
operations, method calls, etc. If you wanted to, for example, get the item
whose `x` field has the highest absolute value, you could use `_max_.x:abs()`.
diff --git a/docs/optionals.md b/docs/optionals.md
index fbd7bac7..85ccfb9b 100644
--- a/docs/optionals.md
+++ b/docs/optionals.md
@@ -32,7 +32,7 @@ conventions and which would generate a lot of unnecessary code.
## Syntax
Optional types are written using a `?` after the type name. So, an optional
-integer would be written as `Int?` and an optional array of texts would be
+integer would be written as `Int?` and an optional list of texts would be
written as `[Text]?`.
None can be written explicitly using `none` with a type annotation. For
@@ -43,7 +43,7 @@ value or `none` and initialize it as none, you would write it as:
x := none:Int
```
-Similarly, if you wanted to declare a variable that could be an array of texts
+Similarly, if you wanted to declare a variable that could be an list of texts
or none and initialize it as none, you would write:
```tomo
@@ -127,10 +127,10 @@ for line in lines:
## Implementation Notes
The implementation of optional types is highly efficient and has no memory
-overhead for pointers, collection types (arrays, sets, tables), booleans,
+overhead for pointers, collection types (lists, sets, tables), booleans,
texts, enums, nums, or integers (`Int` type only). This is done by using
carefully chosen values, such as `0` for pointers, `2` for booleans, or a
-negative length for arrays. However, for fixed-size integers (`Int64`, `Int32`,
+negative length for lists. However, for fixed-size integers (`Int64`, `Int32`,
`Int16`, and `Int8`), bytes, and structs, an additional byte is required for
out-of-band information about whether the value is none or not.
diff --git a/docs/paths.md b/docs/paths.md
index 9d80244b..2e786fa8 100644
--- a/docs/paths.md
+++ b/docs/paths.md
@@ -452,13 +452,13 @@ A list of file paths.
---
### `from_components`
-Returns a path built from an array of path components.
+Returns a path built from an list of path components.
```tomo
func from_components(components:List(Text) -> Path)
```
-- `components`: An array of path components.
+- `components`: An list of path components.
**Returns:**
A path representing the given components.
@@ -476,7 +476,7 @@ A path representing the given components.
---
### `glob`
-Perform a globbing operation and return an array of matching paths. Some glob
+Perform a globbing operation and return an list of matching paths. Some glob
specific details:
- The paths "." and ".." are *not* included in any globbing results.
@@ -510,7 +510,7 @@ A list of file paths that match the glob.
>> (./.*):glob()
= [(./.hidden)]
-# Globs with no matches return an empty array:
+# Globs with no matches return an empty list:
>> (./*.xxx):glob()
= []
```
@@ -914,7 +914,7 @@ func write(path: Path, bytes:List(Byte), permissions=0o644[32] -> Void)
```
- `path`: The path of the file to write to.
-- `bytes`: An array of bytes to write to the file.
+- `bytes`: An list of bytes to write to the file.
- `permissions`: The permissions to set on the file if it is created (default is `0o644`).
**Returns:**
diff --git a/docs/patterns.md b/docs/patterns.md
index c14ca23f..39c97a6d 100644
--- a/docs/patterns.md
+++ b/docs/patterns.md
@@ -37,7 +37,7 @@ Pattern matching functions work with a type called `Match` that has three fields
- `text`: The full text of the match.
- `index`: The index in the text where the match was found.
-- `captures`: An array containing the matching text of each non-literal pattern group.
+- `captures`: An list containing the matching text of each non-literal pattern group.
See [Text Functions](text.md#Text-Functions) for the full API documentation.
diff --git a/docs/pointers.md b/docs/pointers.md
index 5cada7c6..f619959f 100644
--- a/docs/pointers.md
+++ b/docs/pointers.md
@@ -13,8 +13,8 @@ replace the value that previously resided there.
```tomo
func no_mutation_possible(nums:List(Int)):
- nums[1] = 10 // This performs a copy-on-write and creates a new array
- // The new array is only accessible as a local variable here
+ nums[1] = 10 // This performs a copy-on-write and creates a new list
+ // The new list is only accessible as a local variable here
...
my_nums := [0, 1, 2]
no_mutation_possible(my_nums)
@@ -93,17 +93,17 @@ else:
For convenience, most operations that work on values can work with pointers to
values implicitly. For example, if you have a struct type with a `.foo` field,
you can use `ptr.foo` on a pointer to that struct type as well, without needing
-to use `ptr[].foo`. The same is true for array accesses like `ptr[i]` and method
+to use `ptr[].foo`. The same is true for list accesses like `ptr[i]` and method
calls like `ptr:reversed()`.
# Read-Only Views
-In a small number of API methods (`array:first()`, `array:binary_search()`,
-`array:sort()`, `array:sorted()`, and `array:heapify()`), the methods allow you
+In a small number of API methods (`list:first()`, `list:binary_search()`,
+`list:sort()`, `list:sorted()`, and `list:heapify()`), the methods allow you
to provide custom comparison functions. However, for safety, we don't actually
want the comparison methods to be able mutate the values inside of immutable
-array values. For implementation reasons, we can't pass the values themselves
-to the comparison functions, but need to pass pointers to the array members.
+list values. For implementation reasons, we can't pass the values themselves
+to the comparison functions, but need to pass pointers to the list members.
So, to work around this, Tomo allows you to define functions that take
immutable view pointers as arguments. These behave similarly to `@` pointers,
but their type signature uses `&` instead of `@` and read-only view pointers
diff --git a/docs/reductions.md b/docs/reductions.md
index 58cfa314..3fc91047 100644
--- a/docs/reductions.md
+++ b/docs/reductions.md
@@ -86,7 +86,7 @@ maximum value _according to some feature_.
## Comprehensions
-Reductions work not only with iterable values (arrays, sets, integers, etc.),
+Reductions work not only with iterable values (lists, sets, integers, etc.),
but also with comprehensions. You can use comprehensions to perform reductions
while filtering out values or while applying a transformation:
diff --git a/docs/rng.md b/docs/rng.md
index 398215c0..b56722e1 100644
--- a/docs/rng.md
+++ b/docs/rng.md
@@ -16,8 +16,8 @@ a Tomo program launches.
## RNG Functions
This documentation provides details on RNG functions available in the API.
-[Arrays](arrays.md) also have some methods which use RNG values:
-`array:shuffle()`, `array:shuffled()`, `array:random()`, and `array:sample()`.
+[Lists](lists.md) also have some methods which use RNG values:
+`list:shuffle()`, `list:shuffled()`, `list:random()`, and `list:sample()`.
- [`func bool(rng: RNG, p: Num = 0.5 -> Bool)`](#bool)
- [`func byte(rng: RNG -> Byte)`](#byte)
@@ -74,7 +74,7 @@ A random byte (0-255).
---
### `bytes`
-Generate an array of uniformly random bytes with the given length.
+Generate an list of uniformly random bytes with the given length.
```tomo
func bytes(rng: RNG, count: Int -> List(Byte))
@@ -84,7 +84,7 @@ func bytes(rng: RNG, count: Int -> List(Byte))
- `count`: The number of random bytes to return.
**Returns:**
-An array of length `count` random bytes with uniform random distribution (0-255).
+An list of length `count` random bytes with uniform random distribution (0-255).
**Example:**
```tomo
diff --git a/docs/serialization.md b/docs/serialization.md
index af100c92..c1d9fd67 100644
--- a/docs/serialization.md
+++ b/docs/serialization.md
@@ -11,7 +11,7 @@ original value.
## Serializing
To serialize data, simply call the method `:serialized()` on any value and it
-will return an array of bytes that encode the value's data:
+will return an list of bytes that encode the value's data:
```tomo
value := Int64(5)
@@ -19,7 +19,7 @@ value := Int64(5)
= [0x0A] : List(Byte)
```
-Serialization produces a fairly compact representation of data as a flat array
+Serialization produces a fairly compact representation of data as a flat list
of bytes. In this case, a 64-bit integer can be represented in a single byte
because it's a small number.
@@ -72,5 +72,5 @@ only 9 bytes for the whole thing!
Unfortunately, not all types can be easily serialized. In particular,
`Thread`s, types, and functions cannot be serialized because their data
-contents cannot be easily converted to portable byte arrays. All other
+contents cannot be easily converted to portable byte lists. All other
datatypes _can_ be serialized.
diff --git a/docs/sets.md b/docs/sets.md
index a7c88d0e..f191b224 100644
--- a/docs/sets.md
+++ b/docs/sets.md
@@ -28,7 +28,7 @@ For type annotations, a set that holds items with type `T` is written as `{T}`.
### Comprehensions
-Similar to arrays, sets can use comprehensions:
+Similar to lists, sets can use comprehensions:
```tomo
set := {10*i for i in 10}
@@ -38,7 +38,7 @@ set3 := {-10, 10*i for i in 10}
## Accessing Items
-Sets internally store their items in an array, which you can access with the
+Sets internally store their items in an list, which you can access with the
`.items` field. This is a constant-time operation that produces an immutable
view:
@@ -115,7 +115,7 @@ func add_all(set:@Set(T), items:List(T) -> Void)
```
- `set`: The mutable reference to the set.
-- `items`: The array of items to add to the set.
+- `items`: The list of items to add to the set.
**Returns:**
Nothing.
@@ -257,7 +257,7 @@ func remove_all(set:@Set(T), items:List(T) -> Void)
```
- `set`: The mutable reference to the set.
-- `items`: The array of items to remove from the set.
+- `items`: The list of items to remove from the set.
**Returns:**
Nothing.
diff --git a/docs/tables.md b/docs/tables.md
index 78c91c5d..b3d178b4 100644
--- a/docs/tables.md
+++ b/docs/tables.md
@@ -2,7 +2,7 @@
Tables are Tomo's associative mapping structure, also known as a Dictionary or
Map. Tables are efficiently implemented as a hash table that preserves
-insertion order and has fast access to keys and values as array slices. Tables
+insertion order and has fast access to keys and values as list slices. Tables
support *all* types as both keys and values.
## Syntax
@@ -25,7 +25,7 @@ For type annotations, a table that maps keys with type `K` to values of type
### Comprehensions
-Similar to arrays, tables can use comprehensions to dynamically construct tables:
+Similar to lists, tables can use comprehensions to dynamically construct tables:
```tomo
t := {i=10*i for i in 10}
@@ -104,7 +104,7 @@ Table length can be accessed by the `.length` field:
## Accessing Keys and Values
-The keys and values of a table can be efficiently accessed as arrays using a
+The keys and values of a table can be efficiently accessed as lists using a
constant-time immutable slice of the internal data from the table:
```tomo
diff --git a/docs/text.md b/docs/text.md
index 1467a9e4..91b947a9 100644
--- a/docs/text.md
+++ b/docs/text.md
@@ -3,7 +3,7 @@
`Text` is Tomo's datatype to represent text. The name `Text` is used instead of
"string" because Tomo text represents immutable, normalized unicode data with
fast indexing that has an implementation that is efficient for concatenation.
-These are _not_ C-style NUL-terminated character arrays. GNU libunistring is
+These are _not_ C-style NUL-terminated character lists. GNU libunistring is
used for full Unicode functionality (grapheme cluster counts, capitalization,
etc.).
@@ -12,8 +12,8 @@ etc.).
Internally, Tomo text's implementation is based on [Raku/MoarVM's
strings](https://docs.raku.org/language/unicode) and [Boehm et al's
Cords](https://www.cs.tufts.edu/comp/150FP/archive/hans-boehm/ropes.pdf).
-Strings store their grapheme cluster count and either a compact array of 8-bit
-ASCII characters (for ASCII text), an array of 32-bit normal-form grapheme
+Strings store their grapheme cluster count and either a compact list of 8-bit
+ASCII characters (for ASCII text), an list of 32-bit normal-form grapheme
cluster values (see below), or a (roughly) balanced binary tree concatenation
of two texts. The upside is that repeated concatenations are typically a
constant-time operation, which will occasionally require a small rebalancing
@@ -33,7 +33,7 @@ non-ASCII text is stored as 32-bit normal-form graphemes. A normal-form
grapheme is either a positive value representing a Unicode codepoint that
corresponds to a grapheme cluster (most Unicode letters used in natural
language fall into this category after normalization) or a negative value
-representing an index into an internal array of "synthetic grapheme cluster
+representing an index into an internal list of "synthetic grapheme cluster
codepoints." Here are some examples:
- `A` is a normal codepoint that is also a grapheme cluster, so it would
@@ -223,7 +223,7 @@ shorthand for `${}"foo"`. Singly quoted text with no dollar sign (e.g.
Concatenation in the typical case is a fast operation: `"{x}{y}"` or `x ++ y`.
Because text concatenation is typically fast, there is no need for a separate
-"string builder" class in the language and no need to use an array of text
+"string builder" class in the language and no need to use an list of text
fragments.
### Text Length
@@ -435,7 +435,7 @@ for chunk in text:by_split($/,/):
---
### `bytes`
-Converts a `Text` value to an array of bytes representing a UTF8 encoding of
+Converts a `Text` value to an list of bytes representing a UTF8 encoding of
the text.
```tomo
@@ -445,7 +445,7 @@ func bytes(text: Text -> List(Byte))
- `text`: The text to be converted to UTF8 bytes.
**Returns:**
-An array of bytes (`[Byte]`) representing the text in UTF8 encoding.
+An list of bytes (`[Byte]`) representing the text in UTF8 encoding.
**Example:**
```tomo
@@ -483,7 +483,7 @@ func caseless_equals(a: Text, b:Text, language:Text = "C" -> Bool)
---
### `codepoint_names`
-Returns an array of the names of each codepoint in the text.
+Returns an list of the names of each codepoint in the text.
```tomo
func codepoint_names(text: Text -> List(Text))
@@ -492,7 +492,7 @@ func codepoint_names(text: Text -> List(Text))
- `text`: The text from which to extract codepoint names.
**Returns:**
-An array of codepoint names (`[Text]`).
+An list of codepoint names (`[Text]`).
**Example:**
```tomo
@@ -590,8 +590,8 @@ func find_all(text: Text, pattern: Pattern -> List(Match))
- `pattern`: The [pattern](patterns.md) to search for.
**Returns:**
-An array of every match of the [pattern](patterns.md) in the given text.
-Note: if `text` or `pattern` is empty, an empty array will be returned.
+An list of every match of the [pattern](patterns.md) in the given text.
+Note: if `text` or `pattern` is empty, an empty list will be returned.
**Example:**
```tomo
@@ -760,14 +760,14 @@ func has(text: Text, pattern: Pattern -> Bool)
---
### `join`
-Joins an array of text pieces with a specified glue.
+Joins an list of text pieces with a specified glue.
```tomo
func join(glue: Text, pieces:List(Text) -> Text)
```
- `glue`: The text used to join the pieces.
-- `pieces`: The array of text pieces to be joined.
+- `pieces`: The list of text pieces to be joined.
**Returns:**
A single `Text` value with the pieces joined by the glue.
@@ -833,7 +833,7 @@ exact desired length.
---
### `lines`
-Splits the text into an array of lines of text, preserving blank lines,
+Splits the text into an list of lines of text, preserving blank lines,
ignoring trailing newlines, and handling `\r\n` the same as `\n`.
```tomo
@@ -843,7 +843,7 @@ func lines(text: Text -> List(Text))
- `text`: The text to be split into lines.
**Returns:**
-An array of substrings resulting from the split.
+An list of substrings resulting from the split.
**Example:**
```tomo
@@ -914,7 +914,7 @@ function to each.
---
### `matches`
-Checks if the `Text` matches target [pattern](patterns.md) and returns an array
+Checks if the `Text` matches target [pattern](patterns.md) and returns an list
of the matching text captures or a null value if the entire text doesn't match
the pattern.
@@ -926,7 +926,7 @@ func matches(text: Text, pattern: Pattern -> List(Text))
- `pattern`: The [pattern](patterns.md) to search for.
**Returns:**
-An array of the matching text captures if the entire text matches the pattern,
+An list of the matching text captures if the entire text matches the pattern,
or a null value otherwise.
**Example:**
@@ -1165,7 +1165,7 @@ the string.
---
### `split`
-Splits the text into an array of substrings based on a [pattern](patterns.md).
+Splits the text into an list of substrings based on a [pattern](patterns.md).
```tomo
func split(text: Text, pattern: Pattern = "" -> List(Text))
@@ -1176,7 +1176,7 @@ func split(text: Text, pattern: Pattern = "" -> List(Text))
is the empty string, the text will be split into individual grapheme clusters.
**Returns:**
-An array of substrings resulting from the split.
+An list of substrings resulting from the split.
**Example:**
```tomo
@@ -1323,7 +1323,7 @@ The uppercase version of the text.
---
### `utf32_codepoints`
-Returns an array of Unicode code points for UTF32 encoding of the text.
+Returns an list of Unicode code points for UTF32 encoding of the text.
```tomo
func utf32_codepoints(text: Text -> List(Int32))
@@ -1332,7 +1332,7 @@ func utf32_codepoints(text: Text -> List(Int32))
- `text`: The text from which to extract Unicode code points.
**Returns:**
-An array of 32-bit integer Unicode code points (`[Int32]`).
+An list of 32-bit integer Unicode code points (`[Int32]`).
**Example:**
```tomo
diff --git a/environment.c b/environment.c
index 5c93295c..ba34ff5b 100644
--- a/environment.c
+++ b/environment.c
@@ -77,7 +77,7 @@ env_t *new_compilation_unit(CORD libname)
type_t *type;
CORD typename;
CORD typeinfo;
- Array_t namespace;
+ List_t namespace;
} global_types[] = {
{"Void", Type(VoidType), "Void_t", "Void$info", {}},
{"Abort", Type(AbortType), "void", "Abort$info", {}},
@@ -454,7 +454,7 @@ env_t *new_compilation_unit(CORD libname)
struct { const char *c_name, *type_str; } constructor_infos[] = {__VA_ARGS__}; \
for (size_t i = 0; i < sizeof(constructor_infos)/sizeof(constructor_infos[0]); i++) { \
type_t *t = parse_type_string(ns_env, constructor_infos[i].type_str); \
- Array$insert(&ns_env->namespace->constructors, \
+ List$insert(&ns_env->namespace->constructors, \
((binding_t[1]){{.code=constructor_infos[i].c_name, \
.type=Match(t, ClosureType)->fn}}), I(0), sizeof(binding_t)); \
} \
@@ -671,8 +671,8 @@ env_t *for_scope(env_t *env, ast_t *ast)
env_t *scope = fresh_scope(env);
switch (iter_t->tag) {
- case ArrayType: {
- type_t *item_t = Match(iter_t, ArrayType)->item_type;
+ case ListType: {
+ type_t *item_t = Match(iter_t, ListType)->item_type;
const char *vars[2] = {};
int64_t num_vars = 0;
for (ast_list_t *var = for_->vars; var; var = var->next) {
@@ -748,7 +748,7 @@ env_t *get_namespace_by_type(env_t *env, type_t *t)
{
t = value_type(t);
switch (t->tag) {
- case ArrayType: return NULL;
+ case ListType: return NULL;
case TableType: return NULL;
case CStringType: case MomentType:
case BoolType: case IntType: case BigIntType: case NumType: case ByteType: {
@@ -806,7 +806,7 @@ PUREFUNC binding_t *get_constructor(env_t *env, type_t *t, arg_ast_t *args)
{
env_t *type_env = get_namespace_by_type(env, t);
if (!type_env) return NULL;
- Array_t constructors = type_env->namespace->constructors;
+ List_t constructors = type_env->namespace->constructors;
// Prioritize exact matches:
for (int64_t i = constructors.length-1; i >= 0; i--) {
binding_t *b = constructors.data + i*constructors.stride;
diff --git a/environment.h b/environment.h
index b86fba20..75658b07 100644
--- a/environment.h
+++ b/environment.h
@@ -31,7 +31,7 @@ typedef struct loop_ctx_s {
typedef struct namespace_s {
const char *name;
- Array_t constructors;
+ List_t constructors;
struct namespace_s *parent;
} namespace_t;
diff --git a/examples/commands/commands.c b/examples/commands/commands.c
index f07b5c32..6d9b1c63 100644
--- a/examples/commands/commands.c
+++ b/examples/commands/commands.c
@@ -14,8 +14,8 @@
#define READ_END 0
#define WRITE_END 1
-public int run_command(Text_t exe, Array_t arg_array, Table_t env_table,
- Array_t input_bytes, Array_t *output_bytes, Array_t *error_bytes)
+public int run_command(Text_t exe, List_t arg_list, Table_t env_table,
+ List_t input_bytes, List_t *output_bytes, List_t *error_bytes)
{
pthread_testcancel();
@@ -50,28 +50,28 @@ public int run_command(Text_t exe, Array_t arg_array, Table_t env_table,
const char *exe_str = Text$as_c_string(exe);
- Array_t arg_strs = {};
- Array$insert_value(&arg_strs, exe_str, I(0), sizeof(char*));
- for (int64_t i = 0; i < arg_array.length; i++)
- Array$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_array.data + i*arg_array.stride)), I(0), sizeof(char*));
- Array$insert_value(&arg_strs, NULL, I(0), sizeof(char*));
+ List_t arg_strs = {};
+ List$insert_value(&arg_strs, exe_str, I(0), sizeof(char*));
+ for (int64_t i = 0; i < arg_list.length; i++)
+ List$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*));
+ List$insert_value(&arg_strs, NULL, I(0), sizeof(char*));
char **args = arg_strs.data;
extern char **environ;
char **env = environ;
if (env_table.entries.length > 0) {
- Array_t env_array = {}; // Array of const char*
+ List_t env_list = {}; // List of const char*
for (char **e = environ; *e; e++)
- Array$insert(&env_array, e, I(0), sizeof(char*));
+ List$insert(&env_list, e, I(0), sizeof(char*));
for (int64_t i = 0; i < env_table.entries.length; i++) {
struct { Text_t key, value; } *entry = env_table.entries.data + env_table.entries.stride*i;
const char *env_entry = heap_strf("%k=%k", &entry->key, &entry->value);
- Array$insert(&env_array, &env_entry, I(0), sizeof(char*));
+ List$insert(&env_list, &env_entry, I(0), sizeof(char*));
}
- Array$insert_value(&env_array, NULL, I(0), sizeof(char*));
- assert(env_array.stride == sizeof(char*));
- env = env_array.data;
+ List$insert_value(&env_list, NULL, I(0), sizeof(char*));
+ assert(env_list.stride == sizeof(char*));
+ env = env_list.data;
}
pid_t pid;
@@ -95,11 +95,11 @@ public int run_command(Text_t exe, Array_t arg_array, Table_t env_table,
};
if (input_bytes.length > 0 && input_bytes.stride != 1)
- Array$compact(&input_bytes, sizeof(char));
+ List$compact(&input_bytes, sizeof(char));
if (output_bytes)
- *output_bytes = (Array_t){.atomic=1, .stride=1, .length=0};
+ *output_bytes = (List_t){.atomic=1, .stride=1, .length=0};
if (error_bytes)
- *error_bytes = (Array_t){.atomic=1, .stride=1, .length=0};
+ *error_bytes = (List_t){.atomic=1, .stride=1, .length=0};
for (;;) {
(void)poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), -1); // Wait for data or readiness
diff --git a/examples/learnxiny.tm b/examples/learnxiny.tm
index d015137d..4f25df32 100644
--- a/examples/learnxiny.tm
+++ b/examples/learnxiny.tm
@@ -55,23 +55,23 @@ func main():
else:
say("else")
- # Arrays:
+ # Lists:
my_numbers := [10, 20, 30]
- # Empty arrays require specifying the type:
- empty_array := [:Int]
- >> empty_array.length
+ # Empty lists require specifying the type:
+ empty_list := [:Int]
+ >> empty_list.length
= 0
- # Arrays are 1-indexed, so the first element is at index 1:
+ # Lists are 1-indexed, so the first element is at index 1:
>> my_numbers[1]
= 10
- # Negative indices can be used to get items from the back of the array:
+ # Negative indices can be used to get items from the back of the list:
>> my_numbers[-1]
= 30
- # If an invalid index outside the array's bounds is used (e.g.
+ # If an invalid index outside the list's bounds is used (e.g.
# my_numbers[999]), an error message will be printed and the program will
# exit.
@@ -83,7 +83,7 @@ func main():
for index, num in my_numbers:
pass # Pass means "do nothing"
- # Arrays can be created with array comprehensions, which are loops:
+ # Lists can be created with list comprehensions, which are loops:
>> [x*10 for x in my_numbers]
= [100, 200, 300]
>> [x*10 for x in my_numbers if x != 20]
@@ -133,7 +133,7 @@ func main():
pass
# Tables also have ".keys" and ".values" fields to explicitly access the
- # array of keys or values in the table.
+ # list of keys or values in the table.
>> table.keys
= ["one", "two"]
>> table.values
@@ -154,7 +154,7 @@ func main():
# If no default is provided and a missing key is looked up, the program
# will print an error message and halt.
- # Any types can be used in tables, for example, a table mapping arrays to
+ # Any types can be used in tables, for example, a table mapping lists to
# strings:
table3 := {[10, 20]="one", [30, 40, 50]="two"}
>> table3[[10, 20]]!
@@ -242,9 +242,9 @@ func takes_many_types(
integer:Int,
floating_point_number:Num,
text_aka_string:Text,
- array_of_ints:List(Int),
+ list_of_ints:List(Int),
table_of_text_to_bools:Table(Text,Bool),
- pointer_to_mutable_array_of_ints:@List(Int),
+ pointer_to_mutable_list_of_ints:@List(Int),
optional_int:Int?,
function_from_int_to_text:func(x:Int -> Text),
):
diff --git a/parse.c b/parse.c
index 637a6dc8..9c80779b 100644
--- a/parse.c
+++ b/parse.c
@@ -81,7 +81,7 @@ static ast_t *parse_non_optional_suffix(parse_ctx_t *ctx, ast_t *lhs);
static ast_t *parse_optional_conditional_suffix(parse_ctx_t *ctx, ast_t *stmt);
static ast_t *parse_optional_suffix(parse_ctx_t *ctx, ast_t *lhs);
static arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos);
-static type_ast_t *parse_array_type(parse_ctx_t *ctx, const char *pos);
+static type_ast_t *parse_list_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_pointer_type(parse_ctx_t *ctx, const char *pos);
@@ -90,7 +90,7 @@ static type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos);
static type_ast_t *parse_type_name(parse_ctx_t *ctx, const char *pos);
-static PARSER(parse_array);
+static PARSER(parse_list);
static PARSER(parse_assignment);
static PARSER(parse_block);
static PARSER(parse_bool);
@@ -609,13 +609,13 @@ type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos) {
return NewTypeAST(ctx->file, start, pos, FunctionTypeAST, .args=args, .ret=ret);
}
-type_ast_t *parse_array_type(parse_ctx_t *ctx, const char *pos) {
+type_ast_t *parse_list_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match(&pos, "List(")) return NULL;
type_ast_t *type = expect(ctx, start, &pos, parse_type,
- "I couldn't parse an array item type after this point");
- expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this array type");
- return NewTypeAST(ctx->file, start, pos, ArrayTypeAST, .item=type);
+ "I couldn't parse an list item type after this point");
+ expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this list type");
+ return NewTypeAST(ctx->file, start, pos, ListTypeAST, .item=type);
}
type_ast_t *parse_pointer_type(parse_ctx_t *ctx, const char *pos) {
@@ -672,7 +672,7 @@ type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos) {
type_ast_t *type = NULL;
bool success = (false
|| (type=parse_pointer_type(ctx, pos))
- || (type=parse_array_type(ctx, pos))
+ || (type=parse_list_type(ctx, pos))
|| (type=parse_table_type(ctx, pos))
|| (type=parse_set_type(ctx, pos))
|| (type=parse_type_name(ctx, pos))
@@ -757,15 +757,15 @@ static INLINE bool match_separator(const char **pos) { // Either comma or newlin
}
}
-PARSER(parse_array) {
+PARSER(parse_list) {
const char *start = pos;
if (match(&pos, "List(")) {
whitespace(&pos);
- type_ast_t *item_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a type for this array");
+ type_ast_t *item_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a type for this list");
whitespace(&pos);
- expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this array");
- return NewAST(ctx->file, start, pos, Array, .item_type=item_type);
+ expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this list");
+ return NewAST(ctx->file, start, pos, List, .item_type=item_type);
}
if (!match(&pos, "[")) return NULL;
@@ -776,7 +776,7 @@ PARSER(parse_array) {
type_ast_t *item_type = NULL;
if (match(&pos, ":")) {
whitespace(&pos);
- item_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a type for this array");
+ item_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a type for this list");
whitespace(&pos);
match(&pos, ",");
whitespace(&pos);
@@ -796,13 +796,13 @@ PARSER(parse_array) {
break;
}
whitespace(&pos);
- expect_closing(ctx, &pos, "]", "I wasn't able to parse the rest of this array");
+ expect_closing(ctx, &pos, "]", "I wasn't able to parse the rest of this list");
if (!item_type && !items)
- parser_err(ctx, start, pos, "Empty arrays must specify what type they would contain (e.g. [:Int])");
+ parser_err(ctx, start, pos, "Empty lists must specify what type they would contain (e.g. [:Int])");
REVERSE_LIST(items);
- return NewAST(ctx->file, start, pos, Array, .item_type=item_type, .items=items);
+ return NewAST(ctx->file, start, pos, List, .item_type=item_type, .items=items);
}
PARSER(parse_table) {
@@ -1675,7 +1675,7 @@ PARSER(parse_term_no_suffix) {
|| (term=parse_set(ctx, pos))
|| (term=parse_deserialize(ctx, pos))
|| (term=parse_var(ctx, pos))
- || (term=parse_array(ctx, pos))
+ || (term=parse_list(ctx, pos))
|| (term=parse_reduction(ctx, pos))
|| (term=parse_pass(ctx, pos))
|| (term=parse_defer(ctx, pos))
@@ -2572,7 +2572,7 @@ PARSER(parse_use) {
// When `use`ing a URL, convert it to a hash:
Text_t text = Text$from_str(name);
- Array_t m = Text$matches(text, Pattern("{url}"));
+ List_t m = Text$matches(text, Pattern("{url}"));
if (m.length >= 0) {
text = Text$trim(text, Pattern("http{0-1 s}://"), true, false);
FILE *shasum = popen(heap_strf("echo -n '%s' | sha256sum", Text$as_c_string(text)), "r");
diff --git a/repl.c b/repl.c
index 474532ec..ce176481 100644
--- a/repl.c
+++ b/repl.c
@@ -130,10 +130,10 @@ const TypeInfo_t *type_to_type_info(type_t *t)
default: errx(1, "Invalid bits");
}
case TextType: return &Text$info;
- case ArrayType: {
- const TypeInfo_t *item_info = type_to_type_info(Match(t, ArrayType)->item_type);
- TypeInfo_t array_info = *Array$info(item_info);
- return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &array_info, sizeof(TypeInfo_t));
+ case ListType: {
+ const TypeInfo_t *item_info = type_to_type_info(Match(t, ListType)->item_type);
+ TypeInfo_t list_info = *List$info(item_info);
+ return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &list_info, sizeof(TypeInfo_t));
}
case TableType: {
const TypeInfo_t *key_info = type_to_type_info(Match(t, TableType)->key_type);
@@ -464,16 +464,16 @@ void eval(env_t *env, ast_t *ast, void *dest)
type_t *indexed_t = get_type(env, index->indexed);
// type_t *index_t = get_type(env, index->index);
switch (indexed_t->tag) {
- case ArrayType: {
- Array_t arr;
+ case ListType: {
+ List_t arr;
eval(env, index->indexed, &arr);
int64_t raw_index = Int64$from_int(ast_to_int(env, index->index), false);
int64_t index_int = raw_index;
if (index_int < 1) index_int = arr.length + index_int + 1;
if (index_int < 1 || index_int > arr.length)
- repl_err(index->index, "%ld is an invalid index for an array with length %ld",
+ repl_err(index->index, "%ld is an invalid index for an list with length %ld",
raw_index, arr.length);
- size_t item_size = type_size(Match(indexed_t, ArrayType)->item_type);
+ size_t item_size = type_size(Match(indexed_t, ListType)->item_type);
memcpy(dest, arr.data + arr.stride*(index_int-1), item_size);
break;
}
@@ -500,16 +500,16 @@ void eval(env_t *env, ast_t *ast, void *dest)
}
break;
}
- case Array: {
- assert(t->tag == ArrayType);
- Array_t arr = {};
- size_t item_size = type_size(Match(t, ArrayType)->item_type);
+ case List: {
+ assert(t->tag == ListType);
+ List_t arr = {};
+ size_t item_size = type_size(Match(t, ListType)->item_type);
char item_buf[item_size] = {};
- for (ast_list_t *item = Match(ast, Array)->items; item; item = item->next) {
+ for (ast_list_t *item = Match(ast, List)->items; item; item = item->next) {
eval(env, item->ast, item_buf);
- Array$insert(&arr, item_buf, I(0), (int64_t)type_size(Match(t, ArrayType)->item_type));
+ List$insert(&arr, item_buf, I(0), (int64_t)type_size(Match(t, ListType)->item_type));
}
- memcpy(dest, &arr, sizeof(Array_t));
+ memcpy(dest, &arr, sizeof(List_t));
break;
}
case Table: {
diff --git a/stdlib/README.md b/stdlib/README.md
index ba47dd0a..630617c2 100644
--- a/stdlib/README.md
+++ b/stdlib/README.md
@@ -16,7 +16,7 @@ some common functionality.
## Core Data Types
- Datatypes (type definitions): [header](stdlib/datatypes.h), [implementation](stdlib/datatypes.c)
-- Arrays: [header](stdlib/arrays.h), [implementation](stdlib/arrays.c)
+- Lists: [header](stdlib/lists.h), [implementation](stdlib/lists.c)
- Bools: [header](stdlib/bools.h), [implementation](stdlib/bools.c)
- Bytes: [header](stdlib/bytes.h), [implementation](stdlib/bytes.c)
- C Strings: [header](stdlib/c_strings.h), [implementation](stdlib/c_strings.c)
diff --git a/stdlib/arrays.h b/stdlib/arrays.h
deleted file mode 100644
index 6b88b1ee..00000000
--- a/stdlib/arrays.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#pragma once
-
-// Functions that operate on arrays
-
-#include <stdbool.h>
-
-#include "datatypes.h"
-#include "integers.h"
-#include "types.h"
-#include "util.h"
-
-// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1
-#define Array_get(item_type, arr_expr, index_expr, start, end) *({ \
- const Array_t arr = arr_expr; int64_t index = index_expr; \
- int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
- if (unlikely(off < 0 || off >= arr.length)) \
- fail_source(__SOURCE_FILE__, start, end, "Invalid array index: %s (array has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr.length); \
- (item_type*)(arr.data + arr.stride * off);})
-#define Array_get_unchecked(type, x, i) *({ const Array_t arr = x; int64_t index = i; \
- int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
- (type*)(arr.data + arr.stride * off);})
-#define Array_lvalue(item_type, arr_expr, index_expr, start, end) *({ \
- Array_t *arr = arr_expr; int64_t index = index_expr; \
- int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
- if (unlikely(off < 0 || off >= arr->length)) \
- fail_source(__SOURCE_FILE__, start, end, "Invalid array index: %s (array has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr->length); \
- if (arr->data_refcount > 0) \
- Array$compact(arr, sizeof(item_type)); \
- (item_type*)(arr->data + arr->stride * off); })
-#define Array_lvalue_unchecked(item_type, arr_expr, index_expr) *({ \
- Array_t *arr = arr_expr; int64_t index = index_expr; \
- int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
- if (arr->data_refcount > 0) \
- Array$compact(arr, sizeof(item_type)); \
- (item_type*)(arr->data + arr->stride * off); })
-#define Array_set(item_type, arr, index, value, start, end) \
- Array_lvalue(item_type, arr_expr, index, start, end) = value
-#define is_atomic(x) _Generic(x, bool: true, int8_t: true, int16_t: true, int32_t: true, int64_t: true, float: true, double: true, default: false)
-#define TypedList(t, ...) ({ t items[] = {__VA_ARGS__}; \
- (Array_t){.length=sizeof(items)/sizeof(items[0]), \
- .stride=(int64_t)&items[1] - (int64_t)&items[0], \
- .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
- .atomic=0, \
- .data_refcount=0}; })
-#define TypedArrayN(t, N, ...) ({ t items[N] = {__VA_ARGS__}; \
- (Array_t){.length=N, \
- .stride=(int64_t)&items[1] - (int64_t)&items[0], \
- .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
- .atomic=0, \
- .data_refcount=0}; })
-#define List(x, ...) ({ __typeof(x) items[] = {x, __VA_ARGS__}; \
- (Array_t){.length=sizeof(items)/sizeof(items[0]), \
- .stride=(int64_t)&items[1] - (int64_t)&items[0], \
- .data=memcpy(is_atomic(x) ? GC_MALLOC_ATOMIC(sizeof(items)) : GC_MALLOC(sizeof(items)), items, sizeof(items)), \
- .atomic=is_atomic(x), \
- .data_refcount=0}; })
-// Array refcounts use a saturating add, where once it's at the max value, it stays there.
-#define ARRAY_INCREF(arr) (arr).data_refcount += ((arr).data_refcount < ARRAY_MAX_DATA_REFCOUNT)
-#define ARRAY_DECREF(arr) (arr).data_refcount -= ((arr).data_refcount < ARRAY_MAX_DATA_REFCOUNT)
-#define ARRAY_COPY(arr) ({ ARRAY_INCREF(arr); arr; })
-
-#define Array$insert_value(arr, item_expr, index, padded_item_size) Array$insert(arr, (__typeof(item_expr)[1]){item_expr}, index, padded_item_size)
-void Array$insert(Array_t *arr, const void *item, Int_t index, int64_t padded_item_size);
-void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t index, int64_t padded_item_size);
-void Array$remove_at(Array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
-void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type);
-#define Array$remove_item_value(arr, item_expr, max, type) Array$remove_item(arr, (__typeof(item_expr)[1]){item_expr}, max, type)
-
-#define Array$pop(arr_expr, index_expr, item_type, nonnone_var, nonnone_expr, none_expr) ({ \
- Array_t *arr = arr_expr; \
- Int_t index = index_expr; \
- int64_t index64 = Int64$from_int(index, false); \
- int64_t off = index64 + (index64 < 0) * (arr->length + 1) - 1; \
- (off >= 0 && off < arr->length) ? ({ \
- item_type nonnone_var = *(item_type*)(arr->data + off*arr->stride); \
- Array$remove_at(arr, index, I_small(1), sizeof(item_type)); \
- nonnone_expr; \
- }) : none_expr; })
-
-OptionalInt_t Array$find(Array_t arr, void *item, const TypeInfo_t *type);
-#define Array$find_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$find(arr, &item, type); })
-OptionalInt_t Array$first(Array_t arr, Closure_t predicate);
-void Array$sort(Array_t *arr, Closure_t comparison, int64_t padded_item_size);
-Array_t Array$sorted(Array_t arr, Closure_t comparison, int64_t padded_item_size);
-void Array$shuffle(Array_t *arr, RNG_t rng, int64_t padded_item_size);
-Array_t Array$shuffled(Array_t arr, RNG_t rng, int64_t padded_item_size);
-void *Array$random(Array_t arr, RNG_t rng);
-#define Array$random_value(arr, rng, t) ({ Array_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty array!"); *(t*)Array$random(_arr, rng); })
-Array_t Array$sample(Array_t arr, Int_t n, Array_t weights, RNG_t rng, int64_t padded_item_size);
-Table_t Array$counts(Array_t arr, const TypeInfo_t *type);
-void Array$clear(Array_t *array);
-void Array$compact(Array_t *arr, int64_t padded_item_size);
-PUREFUNC bool Array$has(Array_t array, void *item, const TypeInfo_t *type);
-#define Array$has_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$has(arr, &item, type); })
-PUREFUNC Array_t Array$from(Array_t array, Int_t first);
-PUREFUNC Array_t Array$to(Array_t array, Int_t last);
-PUREFUNC Array_t Array$by(Array_t array, Int_t stride, int64_t padded_item_size);
-PUREFUNC Array_t Array$slice(Array_t array, Int_t int_first, Int_t int_last);
-PUREFUNC Array_t Array$reversed(Array_t array, int64_t padded_item_size);
-Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size);
-PUREFUNC uint64_t Array$hash(const void *arr, const TypeInfo_t *type);
-PUREFUNC int32_t Array$compare(const void *x, const void *y, const TypeInfo_t *type);
-PUREFUNC bool Array$equal(const void *x, const void *y, const TypeInfo_t *type);
-PUREFUNC bool Array$is_none(const void *obj, const TypeInfo_t*);
-Text_t Array$as_text(const void *arr, bool colorize, const TypeInfo_t *type);
-void Array$heapify(Array_t *heap, Closure_t comparison, int64_t padded_item_size);
-void Array$heap_push(Array_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size);
-#define Array$heap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; Array$heap_push(heap, &value, comparison, padded_item_size); })
-void Array$heap_pop(Array_t *heap, Closure_t comparison, int64_t padded_item_size);
-#define Array$heap_pop_value(heap, comparison, type, nonnone_var, nonnone_expr, none_expr) \
- ({ Array_t *_heap = heap; \
- (_heap->length > 0) ? ({ \
- type nonnone_var = *(type*)_heap->data; \
- Array$heap_pop(_heap, comparison, sizeof(type)); \
- nonnone_expr; \
- }) : none_expr; })
-Int_t Array$binary_search(Array_t array, void *target, Closure_t comparison);
-#define Array$binary_search_value(array, target, comparison) \
- ({ __typeof(target) _target = target; Array$binary_search(array, &_target, comparison); })
-void Array$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Array$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t *type);
-
-#define Array$metamethods ((metamethods_t){ \
- .as_text=Array$as_text, \
- .compare=Array$compare, \
- .equal=Array$equal, \
- .hash=Array$hash, \
- .is_none=Array$is_none, \
- .serialize=Array$serialize, \
- .deserialize=Array$deserialize, \
-})
-
-#define Array$info(item_info) &((TypeInfo_t){.size=sizeof(Array_t), .align=__alignof__(Array_t), \
- .tag=ArrayInfo, .ArrayInfo.item=item_info, \
- .metamethods=Array$metamethods})
-
-// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/stdlib/c_strings.c b/stdlib/c_strings.c
index 7987a234..d61918f2 100644
--- a/stdlib/c_strings.c
+++ b/stdlib/c_strings.c
@@ -59,7 +59,7 @@ static void CString$serialize(const void *obj, FILE *out, Table_t *pointers, con
fwrite(str, sizeof(char), (size_t)len, out);
}
-static void CString$deserialize(FILE *in, void *out, Array_t *pointers, const TypeInfo_t *)
+static void CString$deserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *)
{
int64_t len = -1;
Int64$deserialize(in, &len, pointers, &Int64$info);
diff --git a/stdlib/datatypes.h b/stdlib/datatypes.h
index dc121c82..78a35bf7 100644
--- a/stdlib/datatypes.h
+++ b/stdlib/datatypes.h
@@ -1,6 +1,6 @@
#pragma once
-// Common datastructures (arrays, tables, closures)
+// Common datastructures (lists, tables, closures)
#include <gmp.h>
#include <pthread.h>
@@ -8,16 +8,16 @@
#include <stdint.h>
#include <time.h>
-#define ARRAY_LENGTH_BITS 42
-#define ARRAY_FREE_BITS 6
-#define ARRAY_REFCOUNT_BITS 3
-#define ARRAY_STRIDE_BITS 12
+#define LIST_LENGTH_BITS 42
+#define LIST_FREE_BITS 6
+#define LIST_REFCOUNT_BITS 3
+#define LIST_STRIDE_BITS 12
#define MAX_FOR_N_BITS(N) ((1<<(N))-1)
-#define ARRAY_MAX_STRIDE MAX_FOR_N_BITS(ARRAY_STRIDE_BITS-1)
-#define ARRAY_MIN_STRIDE (~MAX_FOR_N_BITS(ARRAY_STRIDE_BITS-1))
-#define ARRAY_MAX_DATA_REFCOUNT MAX_FOR_N_BITS(ARRAY_REFCOUNT_BITS)
-#define ARRAY_MAX_FREE_ENTRIES MAX_FOR_N_BITS(ARRAY_FREE_BITS)
+#define LIST_MAX_STRIDE MAX_FOR_N_BITS(LIST_STRIDE_BITS-1)
+#define LIST_MIN_STRIDE (~MAX_FOR_N_BITS(LIST_STRIDE_BITS-1))
+#define LIST_MAX_DATA_REFCOUNT MAX_FOR_N_BITS(LIST_REFCOUNT_BITS)
+#define LIST_MAX_FREE_ENTRIES MAX_FOR_N_BITS(LIST_FREE_BITS)
#define Num_t double
#define Num32_t float
@@ -36,16 +36,16 @@ typedef union {
typedef struct {
void *data;
- // All of the following fields add up to 64 bits, which means that array
+ // All of the following fields add up to 64 bits, which means that list
// structs can be passed in two 64-bit registers. C will handle doing the
// bit arithmetic to extract the necessary values, which is cheaper than
// spilling onto the stack and needing to retrieve data from the stack.
- int64_t length:ARRAY_LENGTH_BITS;
- uint8_t free:ARRAY_FREE_BITS;
+ int64_t length:LIST_LENGTH_BITS;
+ uint8_t free:LIST_FREE_BITS;
bool atomic:1;
- uint8_t data_refcount:ARRAY_REFCOUNT_BITS;
- int16_t stride:ARRAY_STRIDE_BITS;
-} Array_t;
+ uint8_t data_refcount:LIST_REFCOUNT_BITS;
+ int16_t stride:LIST_STRIDE_BITS;
+} List_t;
typedef struct {
uint32_t occupied:1, index:31;
@@ -62,7 +62,7 @@ typedef struct {
} bucket_info_t;
typedef struct table_s {
- Array_t entries;
+ List_t entries;
uint64_t hash;
bucket_info_t *bucket_info;
struct table_s *fallback;
@@ -98,7 +98,7 @@ typedef struct Text_s {
typedef struct {
enum { PATH_NONE, PATH_RELATIVE, PATH_ABSOLUTE, PATH_HOME } type;
- Array_t components;
+ List_t components;
} Path_t;
#define OptionalPath_t Path_t
diff --git a/stdlib/enums.c b/stdlib/enums.c
index b66a1711..bcf47d8e 100644
--- a/stdlib/enums.c
+++ b/stdlib/enums.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include <string.h>
-#include "arrays.h"
+#include "lists.h"
#include "bools.h"
#include "functiontype.h"
#include "integers.h"
@@ -102,7 +102,7 @@ public void Enum$serialize(const void *obj, FILE *out, Table_t *pointers, const
}
}
-public void Enum$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void Enum$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type)
{
int32_t tag = 0;
Int32$deserialize(in, &tag, pointers, &Int32$info);
diff --git a/stdlib/enums.h b/stdlib/enums.h
index a61daacc..afe6e69d 100644
--- a/stdlib/enums.h
+++ b/stdlib/enums.h
@@ -13,7 +13,7 @@ PUREFUNC bool Enum$equal(const void *x, const void *y, const TypeInfo_t *type);
PUREFUNC Text_t Enum$as_text(const void *obj, bool colorize, const TypeInfo_t *type);
PUREFUNC bool Enum$is_none(const void *obj, const TypeInfo_t *type);
void Enum$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Enum$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type);
+void Enum$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type);
#define Enum$metamethods ((metamethods_t){ \
.as_text=Enum$as_text, \
diff --git a/stdlib/integers.c b/stdlib/integers.c
index c4fcdfb5..53587764 100644
--- a/stdlib/integers.c
+++ b/stdlib/integers.c
@@ -8,7 +8,7 @@
#include <stdint.h>
#include <stdlib.h>
-#include "arrays.h"
+#include "lists.h"
#include "datatypes.h"
#include "integers.h"
#include "optionals.h"
@@ -466,7 +466,7 @@ static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const T
}
}
-static void Int$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t*)
+static void Int$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t*)
{
if (fgetc(in) == 0) {
int64_t i = 0;
@@ -505,7 +505,7 @@ public void Int64$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo
fputc((uint8_t)z, out);
}
-public void Int64$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*)
+public void Int64$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*)
{
uint64_t z = 0;
for(size_t shift = 0; ; shift += 7) {
@@ -527,7 +527,7 @@ public void Int32$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo
fputc((uint8_t)z, out);
}
-public void Int32$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*)
+public void Int32$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*)
{
uint32_t z = 0;
for(size_t shift = 0; ; shift += 7) {
@@ -566,14 +566,14 @@ public void Int32$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t
Int_t as_int = Int$from_int64((int64_t)i); \
return Int$octal(as_int, digits_int, prefix); \
} \
- public Array_t KindOfInt ## $bits(c_type x) { \
- Array_t bit_array = (Array_t){.data=GC_MALLOC_ATOMIC(sizeof(bool[8*sizeof(c_type)])), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \
- bool *bits = bit_array.data + sizeof(c_type)*8; \
+ public List_t KindOfInt ## $bits(c_type x) { \
+ List_t bit_list = (List_t){.data=GC_MALLOC_ATOMIC(sizeof(bool[8*sizeof(c_type)])), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \
+ bool *bits = bit_list.data + sizeof(c_type)*8; \
for (size_t i = 0; i < 8*sizeof(c_type); i++) { \
*(bits--) = x & 1; \
x >>= 1; \
} \
- return bit_array; \
+ return bit_list; \
} \
typedef struct { \
Optional##KindOfInt##_t current, last; \
diff --git a/stdlib/integers.h b/stdlib/integers.h
index 3bc3abeb..d7bd2e64 100644
--- a/stdlib/integers.h
+++ b/stdlib/integers.h
@@ -28,7 +28,7 @@
Text_t type_name ## $format(c_type i, Int_t digits); \
Text_t type_name ## $hex(c_type i, Int_t digits, bool uppercase, bool prefix); \
Text_t type_name ## $octal(c_type i, Int_t digits, bool prefix); \
- Array_t type_name ## $bits(c_type x); \
+ List_t type_name ## $bits(c_type x); \
Closure_t type_name ## $to(c_type first, c_type last, Optional ## type_name ## _t step); \
Closure_t type_name ## $onward(c_type first, c_type step); \
PUREFUNC Optional ## type_name ## _t type_name ## $parse(Text_t text); \
@@ -83,9 +83,9 @@ DEFINE_INT_TYPE(int8_t, Int8)
#define Int8$abs(...) I8(abs(__VA_ARGS__))
void Int64$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*);
-void Int64$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*);
+void Int64$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*);
void Int32$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*);
-void Int32$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*);
+void Int32$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*);
#define OptionalInt_t Int_t
diff --git a/stdlib/arrays.c b/stdlib/lists.c
index 1e1ce5f0..00b44517 100644
--- a/stdlib/arrays.c
+++ b/stdlib/lists.c
@@ -1,11 +1,11 @@
-// Functions that operate on arrays
+// Functions that operate on lists
#include <gc.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/param.h>
-#include "arrays.h"
+#include "lists.h"
#include "integers.h"
#include "math.h"
#include "metamethods.h"
@@ -21,15 +21,15 @@
PUREFUNC static INLINE int64_t get_padded_item_size(const TypeInfo_t *info)
{
- int64_t size = info->ArrayInfo.item->size;
- if (info->ArrayInfo.item->align > 1 && size % info->ArrayInfo.item->align)
+ int64_t size = info->ListInfo.item->size;
+ if (info->ListInfo.item->align > 1 && size % info->ListInfo.item->align)
errx(1, "Item size is not padded!");
return size;
}
-// Replace the array's .data pointer with a new pointer to a copy of the
+// Replace the list's .data pointer with a new pointer to a copy of the
// data that is compacted and has a stride of exactly `padded_item_size`
-public void Array$compact(Array_t *arr, int64_t padded_item_size)
+public void List$compact(List_t *arr, int64_t padded_item_size)
{
void *copy = NULL;
if (arr->length > 0) {
@@ -42,7 +42,7 @@ public void Array$compact(Array_t *arr, int64_t padded_item_size)
memcpy(copy + i*padded_item_size, arr->data + arr->stride*i, (size_t)padded_item_size);
}
}
- *arr = (Array_t){
+ *arr = (List_t){
.data=copy,
.length=arr->length,
.stride=padded_item_size,
@@ -50,14 +50,14 @@ public void Array$compact(Array_t *arr, int64_t padded_item_size)
};
}
-public void Array$insert(Array_t *arr, const void *item, Int_t int_index, int64_t padded_item_size)
+public void List$insert(List_t *arr, const void *item, Int_t int_index, int64_t padded_item_size)
{
int64_t index = Int64$from_int(int_index, false);
if (index <= 0) index = arr->length + index + 1;
if (index < 1) index = 1;
else if (index > (int64_t)arr->length + 1)
- fail("Invalid insertion index %ld for an array with length %ld", index, arr->length);
+ fail("Invalid insertion index %ld for an list with length %ld", index, arr->length);
if (!arr->data) {
arr->free = 4;
@@ -65,8 +65,8 @@ public void Array$insert(Array_t *arr, const void *item, Int_t int_index, int64_
: GC_MALLOC((size_t)arr->free * (size_t)padded_item_size);
arr->stride = padded_item_size;
} else if (arr->free < 1 || arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size) {
- // Resize policy: +50% growth (clamped between 8 and ARRAY_MAX_FREE_ENTRIES)
- arr->free = MIN(ARRAY_MAX_FREE_ENTRIES, MAX(8, arr->length)/2);
+ // Resize policy: +50% growth (clamped between 8 and LIST_MAX_FREE_ENTRIES)
+ arr->free = MIN(LIST_MAX_FREE_ENTRIES, MAX(8, arr->length)/2);
void *copy = arr->atomic ? GC_MALLOC_ATOMIC((size_t)(arr->length + arr->free) * (size_t)padded_item_size)
: GC_MALLOC((size_t)(arr->length + arr->free) * (size_t)padded_item_size);
for (int64_t i = 0; i < index-1; i++)
@@ -89,7 +89,7 @@ public void Array$insert(Array_t *arr, const void *item, Int_t int_index, int64_
memcpy((void*)arr->data + (index-1)*padded_item_size, item, (size_t)padded_item_size);
}
-public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, int64_t padded_item_size)
+public void List$insert_all(List_t *arr, List_t to_insert, Int_t int_index, int64_t padded_item_size)
{
int64_t index = Int64$from_int(int_index, false);
if (to_insert.length == 0)
@@ -97,7 +97,7 @@ public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, i
if (!arr->data) {
*arr = to_insert;
- ARRAY_INCREF(*arr);
+ LIST_INCREF(*arr);
return;
}
@@ -105,12 +105,12 @@ public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, i
if (index < 1) index = 1;
else if (index > (int64_t)arr->length + 1)
- fail("Invalid insertion index %ld for an array with length %ld", index, arr->length);
+ fail("Invalid insertion index %ld for an list with length %ld", index, arr->length);
if ((int64_t)arr->free >= (int64_t)to_insert.length // Adequate free space
&& arr->data_refcount == 0 // Not aliased memory
- && (int64_t)arr->stride == padded_item_size) { // Contiguous array
- // If we can fit this within the array's preallocated free space, do that:
+ && (int64_t)arr->stride == padded_item_size) { // Contiguous list
+ // If we can fit this within the list's preallocated free space, do that:
arr->free -= to_insert.length;
arr->length += to_insert.length;
if (index != arr->length+1)
@@ -121,9 +121,9 @@ public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, i
memcpy((void*)arr->data + (index-1 + i)*padded_item_size,
to_insert.data + i*to_insert.stride, (size_t)padded_item_size);
} else {
- // Otherwise, allocate a new chunk of memory for the array and populate it:
+ // Otherwise, allocate a new chunk of memory for the list and populate it:
int64_t new_len = arr->length + to_insert.length;
- arr->free = MIN(ARRAY_MAX_FREE_ENTRIES, MAX(8, new_len/4));
+ arr->free = MIN(LIST_MAX_FREE_ENTRIES, MAX(8, new_len/4));
void *data = arr->atomic ? GC_MALLOC_ATOMIC((size_t)((new_len + arr->free) * padded_item_size))
: GC_MALLOC((size_t)((new_len + arr->free) * padded_item_size));
void *p = data;
@@ -162,7 +162,7 @@ public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, i
}
}
-public void Array$remove_at(Array_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
+public void List$remove_at(List_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
{
int64_t index = Int64$from_int(int_index, false);
if (index < 1) index = arr->length + index + 1;
@@ -199,18 +199,18 @@ public void Array$remove_at(Array_t *arr, Int_t int_index, Int_t int_count, int6
if (arr->length == 0) arr->data = NULL;
}
-public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type)
+public void List$remove_item(List_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type)
{
int64_t padded_item_size = get_padded_item_size(type);
const Int_t ZERO = (Int_t){.small=(0<<2)|1};
const Int_t ONE = (Int_t){.small=(1<<2)|1};
- const TypeInfo_t *item_type = type->ArrayInfo.item;
+ const TypeInfo_t *item_type = type->ListInfo.item;
for (int64_t i = 0; i < arr->length; ) {
if (max_removals.small == ZERO.small) // zero
break;
if (generic_equal(item, arr->data + i*arr->stride, item_type)) {
- Array$remove_at(arr, I(i+1), ONE, padded_item_size);
+ List$remove_at(arr, I(i+1), ONE, padded_item_size);
max_removals = Int$minus(max_removals, ONE);
} else {
i++;
@@ -218,9 +218,9 @@ public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, cons
}
}
-public OptionalInt_t Array$find(Array_t arr, void *item, const TypeInfo_t *type)
+public OptionalInt_t List$find(List_t arr, void *item, const TypeInfo_t *type)
{
- const TypeInfo_t *item_type = type->ArrayInfo.item;
+ const TypeInfo_t *item_type = type->ListInfo.item;
for (int64_t i = 0; i < arr.length; i++) {
if (generic_equal(item, arr.data + i*arr.stride, item_type))
return I(i+1);
@@ -228,7 +228,7 @@ public OptionalInt_t Array$find(Array_t arr, void *item, const TypeInfo_t *type)
return NONE_INT;
}
-public OptionalInt_t Array$first(Array_t arr, Closure_t predicate)
+public OptionalInt_t List$first(List_t arr, Closure_t predicate)
{
bool (*is_good)(void*, void*) = (void*)predicate.fn;
for (int64_t i = 0; i < arr.length; i++) {
@@ -238,25 +238,25 @@ public OptionalInt_t Array$first(Array_t arr, Closure_t predicate)
return NONE_INT;
}
-public void Array$sort(Array_t *arr, Closure_t comparison, int64_t padded_item_size)
+public void List$sort(List_t *arr, Closure_t comparison, int64_t padded_item_size)
{
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
- Array$compact(arr, padded_item_size);
+ List$compact(arr, padded_item_size);
qsort_r(arr->data, (size_t)arr->length, (size_t)padded_item_size, comparison.fn, comparison.userdata);
}
-public Array_t Array$sorted(Array_t arr, Closure_t comparison, int64_t padded_item_size)
+public List_t List$sorted(List_t arr, Closure_t comparison, int64_t padded_item_size)
{
- Array$compact(&arr, padded_item_size);
+ List$compact(&arr, padded_item_size);
qsort_r(arr.data, (size_t)arr.length, (size_t)padded_item_size, comparison.fn, comparison.userdata);
return arr;
}
-public void Array$shuffle(Array_t *arr, RNG_t rng, int64_t padded_item_size)
+public void List$shuffle(List_t *arr, RNG_t rng, int64_t padded_item_size)
{
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
- Array$compact(arr, padded_item_size);
+ List$compact(arr, padded_item_size);
char tmp[padded_item_size];
for (int64_t i = arr->length-1; i > 1; i--) {
@@ -267,26 +267,26 @@ public void Array$shuffle(Array_t *arr, RNG_t rng, int64_t padded_item_size)
}
}
-public Array_t Array$shuffled(Array_t arr, RNG_t rng, int64_t padded_item_size)
+public List_t List$shuffled(List_t arr, RNG_t rng, int64_t padded_item_size)
{
- Array$compact(&arr, padded_item_size);
- Array$shuffle(&arr, rng, padded_item_size);
+ List$compact(&arr, padded_item_size);
+ List$shuffle(&arr, rng, padded_item_size);
return arr;
}
-public void *Array$random(Array_t arr, RNG_t rng)
+public void *List$random(List_t arr, RNG_t rng)
{
if (arr.length == 0)
- return NULL; // fail("Cannot get a random item from an empty array!");
+ return NULL; // fail("Cannot get a random item from an empty list!");
int64_t index = RNG$int64(rng, 0, arr.length-1);
return arr.data + arr.stride*index;
}
-public Table_t Array$counts(Array_t arr, const TypeInfo_t *type)
+public Table_t List$counts(List_t arr, const TypeInfo_t *type)
{
Table_t counts = {};
- const TypeInfo_t count_type = *Table$info(type->ArrayInfo.item, &Int$info);
+ const TypeInfo_t count_type = *Table$info(type->ListInfo.item, &Int$info);
for (int64_t i = 0; i < arr.length; i++) {
void *key = arr.data + i*arr.stride;
int64_t *count = Table$get(counts, key, &count_type);
@@ -296,19 +296,19 @@ public Table_t Array$counts(Array_t arr, const TypeInfo_t *type)
return counts;
}
-public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng, int64_t padded_item_size)
+public List_t List$sample(List_t arr, Int_t int_n, List_t weights, RNG_t rng, int64_t padded_item_size)
{
int64_t n = Int64$from_int(int_n, false);
if (n < 0)
fail("Cannot select a negative number of values");
if (n == 0)
- return (Array_t){};
+ return (List_t){};
if (arr.length == 0)
- fail("There are no elements in this array!");
+ fail("There are no elements in this list!");
- Array_t selected = {
+ List_t selected = {
.data=arr.atomic ? GC_MALLOC_ATOMIC((size_t)(n * padded_item_size)) : GC_MALLOC((size_t)(n * padded_item_size)),
.length=n,
.stride=padded_item_size, .atomic=arr.atomic};
@@ -322,7 +322,7 @@ public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng
}
if (weights.length != arr.length)
- fail("Array has %ld elements, but there are %ld weights given", arr.length, weights.length);
+ fail("List has %ld elements, but there are %ld weights given", arr.length, weights.length);
double total = 0.0;
for (int64_t i = 0; i < weights.length && i < arr.length; i++) {
@@ -388,92 +388,92 @@ public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng
return selected;
}
-public Array_t Array$from(Array_t array, Int_t first)
+public List_t List$from(List_t list, Int_t first)
{
- return Array$slice(array, first, I_small(-1));
+ return List$slice(list, first, I_small(-1));
}
-public Array_t Array$to(Array_t array, Int_t last)
+public List_t List$to(List_t list, Int_t last)
{
- return Array$slice(array, I_small(1), last);
+ return List$slice(list, I_small(1), last);
}
-public Array_t Array$by(Array_t array, Int_t int_stride, int64_t padded_item_size)
+public List_t List$by(List_t list, Int_t int_stride, int64_t padded_item_size)
{
int64_t stride = Int64$from_int(int_stride, false);
// In the unlikely event that the stride value would be too large to fit in
- // a 15-bit integer, fall back to creating a copy of the array:
- if (unlikely(array.stride*stride < ARRAY_MIN_STRIDE || array.stride*stride > ARRAY_MAX_STRIDE)) {
+ // a 15-bit integer, fall back to creating a copy of the list:
+ if (unlikely(list.stride*stride < LIST_MIN_STRIDE || list.stride*stride > LIST_MAX_STRIDE)) {
void *copy = NULL;
- int64_t len = (stride < 0 ? array.length / -stride : array.length / stride) + ((array.length % stride) != 0);
+ int64_t len = (stride < 0 ? list.length / -stride : list.length / stride) + ((list.length % stride) != 0);
if (len > 0) {
- copy = array.atomic ? GC_MALLOC_ATOMIC((size_t)(len * padded_item_size)) : GC_MALLOC((size_t)(len * padded_item_size));
- void *start = (stride < 0 ? array.data + (array.stride * (array.length - 1)) : array.data);
+ copy = list.atomic ? GC_MALLOC_ATOMIC((size_t)(len * padded_item_size)) : GC_MALLOC((size_t)(len * padded_item_size));
+ void *start = (stride < 0 ? list.data + (list.stride * (list.length - 1)) : list.data);
for (int64_t i = 0; i < len; i++)
- memcpy(copy + i*padded_item_size, start + array.stride*stride*i, (size_t)padded_item_size);
+ memcpy(copy + i*padded_item_size, start + list.stride*stride*i, (size_t)padded_item_size);
}
- return (Array_t){
+ return (List_t){
.data=copy,
.length=len,
.stride=padded_item_size,
- .atomic=array.atomic,
+ .atomic=list.atomic,
};
}
if (stride == 0)
- return (Array_t){.atomic=array.atomic};
-
- return (Array_t){
- .atomic=array.atomic,
- .data=(stride < 0 ? array.data + (array.stride * (array.length - 1)) : array.data),
- .length=(stride < 0 ? array.length / -stride : array.length / stride) + ((array.length % stride) != 0),
- .stride=array.stride * stride,
- .data_refcount=array.data_refcount,
+ return (List_t){.atomic=list.atomic};
+
+ return (List_t){
+ .atomic=list.atomic,
+ .data=(stride < 0 ? list.data + (list.stride * (list.length - 1)) : list.data),
+ .length=(stride < 0 ? list.length / -stride : list.length / stride) + ((list.length % stride) != 0),
+ .stride=list.stride * stride,
+ .data_refcount=list.data_refcount,
};
}
-public Array_t Array$slice(Array_t array, Int_t int_first, Int_t int_last)
+public List_t List$slice(List_t list, Int_t int_first, Int_t int_last)
{
int64_t first = Int64$from_int(int_first, false);
if (first < 0)
- first = array.length + first + 1;
+ first = list.length + first + 1;
int64_t last = Int64$from_int(int_last, false);
if (last < 0)
- last = array.length + last + 1;
+ last = list.length + last + 1;
- if (last > array.length)
- last = array.length;
+ if (last > list.length)
+ last = list.length;
- if (first < 1 || first > array.length || last == 0)
- return (Array_t){.atomic=array.atomic};
+ if (first < 1 || first > list.length || last == 0)
+ return (List_t){.atomic=list.atomic};
- return (Array_t){
- .atomic=array.atomic,
- .data=array.data + array.stride*(first-1),
+ return (List_t){
+ .atomic=list.atomic,
+ .data=list.data + list.stride*(first-1),
.length=last - first + 1,
- .stride=array.stride,
- .data_refcount=array.data_refcount,
+ .stride=list.stride,
+ .data_refcount=list.data_refcount,
};
}
-public Array_t Array$reversed(Array_t array, int64_t padded_item_size)
+public List_t List$reversed(List_t list, int64_t padded_item_size)
{
// Just in case negating the stride gives a value that doesn't fit into a
- // 15-bit integer, fall back to Array$by()'s more general method of copying
- // the array. This should only happen if array.stride is MIN_STRIDE to
+ // 15-bit integer, fall back to List$by()'s more general method of copying
+ // the list. This should only happen if list.stride is MIN_STRIDE to
// begin with (very unlikely).
- if (unlikely(-array.stride < ARRAY_MIN_STRIDE || -array.stride > ARRAY_MAX_STRIDE))
- return Array$by(array, I(-1), padded_item_size);
+ if (unlikely(-list.stride < LIST_MIN_STRIDE || -list.stride > LIST_MAX_STRIDE))
+ return List$by(list, I(-1), padded_item_size);
- Array_t reversed = array;
- reversed.stride = -array.stride;
- reversed.data = array.data + (array.length-1)*array.stride;
+ List_t reversed = list;
+ reversed.stride = -list.stride;
+ reversed.data = list.data + (list.length-1)*list.stride;
return reversed;
}
-public Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size)
+public List_t List$concat(List_t x, List_t y, int64_t padded_item_size)
{
void *data = x.atomic ? GC_MALLOC_ATOMIC((size_t)(padded_item_size*(x.length + y.length)))
: GC_MALLOC((size_t)(padded_item_size*(x.length + y.length)));
@@ -492,7 +492,7 @@ public Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size)
memcpy(dest + i*padded_item_size, y.data + i*y.stride, (size_t)padded_item_size);
}
- return (Array_t){
+ return (List_t){
.data=data,
.length=x.length + y.length,
.stride=padded_item_size,
@@ -500,32 +500,32 @@ public Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size)
};
}
-public bool Array$has(Array_t array, void *item, const TypeInfo_t *type)
+public bool List$has(List_t list, void *item, const TypeInfo_t *type)
{
- const TypeInfo_t *item_type = type->ArrayInfo.item;
- for (int64_t i = 0; i < array.length; i++) {
- if (generic_equal(array.data + i*array.stride, item, item_type))
+ const TypeInfo_t *item_type = type->ListInfo.item;
+ for (int64_t i = 0; i < list.length; i++) {
+ if (generic_equal(list.data + i*list.stride, item, item_type))
return true;
}
return false;
}
-public void Array$clear(Array_t *array)
+public void List$clear(List_t *list)
{
- *array = (Array_t){.data=0, .length=0};
+ *list = (List_t){.data=0, .length=0};
}
-public int32_t Array$compare(const void *vx, const void *vy, const TypeInfo_t *type)
+public int32_t List$compare(const void *vx, const void *vy, const TypeInfo_t *type)
{
- const Array_t *x = (Array_t*)vx, *y = (Array_t*)vy;
- // Early out for arrays with the same data, e.g. two copies of the same array:
+ const List_t *x = (List_t*)vx, *y = (List_t*)vy;
+ // Early out for lists with the same data, e.g. two copies of the same list:
if (x->data == y->data && x->stride == y->stride)
return (x->length > y->length) - (x->length < y->length);
- const TypeInfo_t *item = type->ArrayInfo.item;
+ const TypeInfo_t *item = type->ListInfo.item;
if (item->tag == PointerInfo || !item->metamethods.compare) { // data comparison
- int64_t item_padded_size = type->ArrayInfo.item->size;
- if (type->ArrayInfo.item->align > 1 && item_padded_size % type->ArrayInfo.item->align)
+ int64_t item_padded_size = type->ListInfo.item->size;
+ if (type->ListInfo.item->align > 1 && item_padded_size % type->ListInfo.item->align)
errx(1, "Item size is not padded!");
if ((int64_t)x->stride == item_padded_size && (int64_t)y->stride == item_padded_size && item->size == item_padded_size) {
@@ -546,18 +546,18 @@ public int32_t Array$compare(const void *vx, const void *vy, const TypeInfo_t *t
return (x->length > y->length) - (x->length < y->length);
}
-public bool Array$equal(const void *x, const void *y, const TypeInfo_t *type)
+public bool List$equal(const void *x, const void *y, const TypeInfo_t *type)
{
- return x == y || (((Array_t*)x)->length == ((Array_t*)y)->length && Array$compare(x, y, type) == 0);
+ return x == y || (((List_t*)x)->length == ((List_t*)y)->length && List$compare(x, y, type) == 0);
}
-public Text_t Array$as_text(const void *obj, bool colorize, const TypeInfo_t *type)
+public Text_t List$as_text(const void *obj, bool colorize, const TypeInfo_t *type)
{
- Array_t *arr = (Array_t*)obj;
+ List_t *arr = (List_t*)obj;
if (!arr)
- return Text$concat(Text("List("), generic_as_text(NULL, false, type->ArrayInfo.item), Text(")"));
+ return Text$concat(Text("List("), generic_as_text(NULL, false, type->ListInfo.item), Text(")"));
- const TypeInfo_t *item_type = type->ArrayInfo.item;
+ const TypeInfo_t *item_type = type->ListInfo.item;
Text_t text = Text("[");
for (int64_t i = 0; i < arr->length; i++) {
if (i > 0)
@@ -569,10 +569,10 @@ public Text_t Array$as_text(const void *obj, bool colorize, const TypeInfo_t *ty
return text;
}
-public uint64_t Array$hash(const void *obj, const TypeInfo_t *type)
+public uint64_t List$hash(const void *obj, const TypeInfo_t *type)
{
- const Array_t *arr = (Array_t*)obj;
- const TypeInfo_t *item = type->ArrayInfo.item;
+ const List_t *arr = (List_t*)obj;
+ const TypeInfo_t *item = type->ListInfo.item;
siphash sh;
siphashinit(&sh, sizeof(uint64_t[arr->length]));
if (item->tag == PointerInfo || (!item->metamethods.hash && item->size == sizeof(void*))) { // Raw data hash
@@ -587,7 +587,7 @@ public uint64_t Array$hash(const void *obj, const TypeInfo_t *type)
return siphashfinish_last_part(&sh, 0);
}
-static void siftdown(Array_t *heap, int64_t startpos, int64_t pos, Closure_t comparison, int64_t padded_item_size)
+static void siftdown(List_t *heap, int64_t startpos, int64_t pos, Closure_t comparison, int64_t padded_item_size)
{
assert(pos > 0 && pos < heap->length);
char newitem[padded_item_size];
@@ -605,7 +605,7 @@ static void siftdown(Array_t *heap, int64_t startpos, int64_t pos, Closure_t com
memcpy(heap->data + heap->stride*pos, newitem, (size_t)(padded_item_size));
}
-static void siftup(Array_t *heap, int64_t pos, Closure_t comparison, int64_t padded_item_size)
+static void siftup(List_t *heap, int64_t pos, Closure_t comparison, int64_t padded_item_size)
{
int64_t endpos = heap->length;
int64_t startpos = pos;
@@ -635,58 +635,58 @@ static void siftup(Array_t *heap, int64_t pos, Closure_t comparison, int64_t pad
siftdown(heap, startpos, pos, comparison, padded_item_size);
}
-public void Array$heap_push(Array_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size)
+public void List$heap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size)
{
- Array$insert(heap, item, I(0), padded_item_size);
+ List$insert(heap, item, I(0), padded_item_size);
if (heap->length > 1) {
if (heap->data_refcount != 0)
- Array$compact(heap, padded_item_size);
+ List$compact(heap, padded_item_size);
siftdown(heap, 0, heap->length-1, comparison, padded_item_size);
}
}
-public void Array$heap_pop(Array_t *heap, Closure_t comparison, int64_t padded_item_size)
+public void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size)
{
if (heap->length == 0)
- fail("Attempt to pop from an empty array");
+ fail("Attempt to pop from an empty list");
if (heap->length == 1) {
- *heap = (Array_t){};
+ *heap = (List_t){};
} else if (heap->length == 2) {
heap->data += heap->stride;
--heap->length;
} else {
if (heap->data_refcount != 0)
- Array$compact(heap, padded_item_size);
+ List$compact(heap, padded_item_size);
memcpy(heap->data, heap->data + heap->stride*(heap->length-1), (size_t)(padded_item_size));
--heap->length;
siftup(heap, 0, comparison, padded_item_size);
}
}
-public void Array$heapify(Array_t *heap, Closure_t comparison, int64_t padded_item_size)
+public void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size)
{
if (heap->data_refcount != 0)
- Array$compact(heap, padded_item_size);
+ List$compact(heap, padded_item_size);
// It's necessary to bump the refcount because the user's comparison
// function could do stuff that modifies the heap's data.
- ARRAY_INCREF(*heap);
+ LIST_INCREF(*heap);
int64_t i, n = heap->length;
for (i = (n >> 1) - 1 ; i >= 0 ; i--)
siftup(heap, i, comparison, padded_item_size);
- ARRAY_DECREF(*heap);
+ LIST_DECREF(*heap);
}
-public Int_t Array$binary_search(Array_t array, void *target, Closure_t comparison)
+public Int_t List$binary_search(List_t list, void *target, Closure_t comparison)
{
typedef int32_t (*cmp_fn_t)(void*, void*, void*);
- int64_t lo = 0, hi = array.length-1;
+ int64_t lo = 0, hi = list.length-1;
while (lo <= hi) {
int64_t mid = (lo + hi) / 2;
int32_t cmp = ((cmp_fn_t)comparison.fn)(
- array.data + array.stride*mid, target, comparison.userdata);
+ list.data + list.stride*mid, target, comparison.userdata);
if (cmp == 0)
return I(mid+1);
else if (cmp < 0)
@@ -697,51 +697,51 @@ public Int_t Array$binary_search(Array_t array, void *target, Closure_t comparis
return I(lo+1); // Return the index where the target would be inserted
}
-public PUREFUNC bool Array$is_none(const void *obj, const TypeInfo_t*)
+public PUREFUNC bool List$is_none(const void *obj, const TypeInfo_t*)
{
- return ((Array_t*)obj)->length < 0;
+ return ((List_t*)obj)->length < 0;
}
-public void Array$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type)
+public void List$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type)
{
- Array_t arr = *(Array_t*)obj;
+ List_t arr = *(List_t*)obj;
int64_t len = arr.length;
Int64$serialize(&len, out, pointers, &Int64$info);
- auto item_serialize = type->ArrayInfo.item->metamethods.serialize;
+ auto item_serialize = type->ListInfo.item->metamethods.serialize;
if (item_serialize) {
for (int64_t i = 0; i < len; i++)
- item_serialize(arr.data + i*arr.stride, out, pointers, type->ArrayInfo.item);
- } else if (arr.stride == type->ArrayInfo.item->size) {
- fwrite(arr.data, (size_t)type->ArrayInfo.item->size, (size_t)len, out);
+ item_serialize(arr.data + i*arr.stride, out, pointers, type->ListInfo.item);
+ } else if (arr.stride == type->ListInfo.item->size) {
+ fwrite(arr.data, (size_t)type->ListInfo.item->size, (size_t)len, out);
} else {
for (int64_t i = 0; i < len; i++)
- fwrite(arr.data + i*arr.stride, (size_t)type->ArrayInfo.item->size, 1, out);
+ fwrite(arr.data + i*arr.stride, (size_t)type->ListInfo.item->size, 1, out);
}
}
-public void Array$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t *type)
+public void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type)
{
int64_t len = -1;
Int64$deserialize(in, &len, pointers, &Int64$info);
- int64_t padded_size = type->ArrayInfo.item->size;
- if (type->ArrayInfo.item->align > 0 && padded_size % type->ArrayInfo.item->align > 0)
- padded_size += type->ArrayInfo.item->align - (padded_size % type->ArrayInfo.item->align);
- Array_t arr = {
+ int64_t padded_size = type->ListInfo.item->size;
+ if (type->ListInfo.item->align > 0 && padded_size % type->ListInfo.item->align > 0)
+ padded_size += type->ListInfo.item->align - (padded_size % type->ListInfo.item->align);
+ List_t arr = {
.length=len,
.data=GC_MALLOC((size_t)(len*padded_size)),
.stride=padded_size,
};
- auto item_deserialize = type->ArrayInfo.item->metamethods.deserialize;
+ auto item_deserialize = type->ListInfo.item->metamethods.deserialize;
if (item_deserialize) {
for (int64_t i = 0; i < len; i++)
- item_deserialize(in, arr.data + i*arr.stride, pointers, type->ArrayInfo.item);
- } else if (arr.stride == type->ArrayInfo.item->size) {
- fread(arr.data, (size_t)type->ArrayInfo.item->size, (size_t)len, in);
+ item_deserialize(in, arr.data + i*arr.stride, pointers, type->ListInfo.item);
+ } else if (arr.stride == type->ListInfo.item->size) {
+ fread(arr.data, (size_t)type->ListInfo.item->size, (size_t)len, in);
} else {
for (int64_t i = 0; i < len; i++)
- fread(arr.data + i*arr.stride, (size_t)type->ArrayInfo.item->size, 1, in);
+ fread(arr.data + i*arr.stride, (size_t)type->ListInfo.item->size, 1, in);
}
- *(Array_t*)obj = arr;
+ *(List_t*)obj = arr;
}
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/stdlib/lists.h b/stdlib/lists.h
new file mode 100644
index 00000000..40790d5d
--- /dev/null
+++ b/stdlib/lists.h
@@ -0,0 +1,137 @@
+#pragma once
+
+// Functions that operate on lists
+
+#include <stdbool.h>
+
+#include "datatypes.h"
+#include "integers.h"
+#include "types.h"
+#include "util.h"
+
+// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1
+#define List_get(item_type, arr_expr, index_expr, start, end) *({ \
+ const List_t arr = arr_expr; int64_t index = index_expr; \
+ int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
+ if (unlikely(off < 0 || off >= arr.length)) \
+ fail_source(__SOURCE_FILE__, start, end, "Invalid list index: %s (list has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr.length); \
+ (item_type*)(arr.data + arr.stride * off);})
+#define List_get_unchecked(type, x, i) *({ const List_t arr = x; int64_t index = i; \
+ int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
+ (type*)(arr.data + arr.stride * off);})
+#define List_lvalue(item_type, arr_expr, index_expr, start, end) *({ \
+ List_t *arr = arr_expr; int64_t index = index_expr; \
+ int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
+ if (unlikely(off < 0 || off >= arr->length)) \
+ fail_source(__SOURCE_FILE__, start, end, "Invalid list index: %s (list has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr->length); \
+ if (arr->data_refcount > 0) \
+ List$compact(arr, sizeof(item_type)); \
+ (item_type*)(arr->data + arr->stride * off); })
+#define List_lvalue_unchecked(item_type, arr_expr, index_expr) *({ \
+ List_t *arr = arr_expr; int64_t index = index_expr; \
+ int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
+ if (arr->data_refcount > 0) \
+ List$compact(arr, sizeof(item_type)); \
+ (item_type*)(arr->data + arr->stride * off); })
+#define List_set(item_type, arr, index, value, start, end) \
+ List_lvalue(item_type, arr_expr, index, start, end) = value
+#define is_atomic(x) _Generic(x, bool: true, int8_t: true, int16_t: true, int32_t: true, int64_t: true, float: true, double: true, default: false)
+#define TypedList(t, ...) ({ t items[] = {__VA_ARGS__}; \
+ (List_t){.length=sizeof(items)/sizeof(items[0]), \
+ .stride=(int64_t)&items[1] - (int64_t)&items[0], \
+ .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
+ .atomic=0, \
+ .data_refcount=0}; })
+#define TypedListN(t, N, ...) ({ t items[N] = {__VA_ARGS__}; \
+ (List_t){.length=N, \
+ .stride=(int64_t)&items[1] - (int64_t)&items[0], \
+ .data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
+ .atomic=0, \
+ .data_refcount=0}; })
+#define List(x, ...) ({ __typeof(x) items[] = {x, __VA_ARGS__}; \
+ (List_t){.length=sizeof(items)/sizeof(items[0]), \
+ .stride=(int64_t)&items[1] - (int64_t)&items[0], \
+ .data=memcpy(is_atomic(x) ? GC_MALLOC_ATOMIC(sizeof(items)) : GC_MALLOC(sizeof(items)), items, sizeof(items)), \
+ .atomic=is_atomic(x), \
+ .data_refcount=0}; })
+// List refcounts use a saturating add, where once it's at the max value, it stays there.
+#define LIST_INCREF(arr) (arr).data_refcount += ((arr).data_refcount < LIST_MAX_DATA_REFCOUNT)
+#define LIST_DECREF(arr) (arr).data_refcount -= ((arr).data_refcount < LIST_MAX_DATA_REFCOUNT)
+#define LIST_COPY(arr) ({ LIST_INCREF(arr); arr; })
+
+#define List$insert_value(arr, item_expr, index, padded_item_size) List$insert(arr, (__typeof(item_expr)[1]){item_expr}, index, padded_item_size)
+void List$insert(List_t *arr, const void *item, Int_t index, int64_t padded_item_size);
+void List$insert_all(List_t *arr, List_t to_insert, Int_t index, int64_t padded_item_size);
+void List$remove_at(List_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
+void List$remove_item(List_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type);
+#define List$remove_item_value(arr, item_expr, max, type) List$remove_item(arr, (__typeof(item_expr)[1]){item_expr}, max, type)
+
+#define List$pop(arr_expr, index_expr, item_type, nonnone_var, nonnone_expr, none_expr) ({ \
+ List_t *arr = arr_expr; \
+ Int_t index = index_expr; \
+ int64_t index64 = Int64$from_int(index, false); \
+ int64_t off = index64 + (index64 < 0) * (arr->length + 1) - 1; \
+ (off >= 0 && off < arr->length) ? ({ \
+ item_type nonnone_var = *(item_type*)(arr->data + off*arr->stride); \
+ List$remove_at(arr, index, I_small(1), sizeof(item_type)); \
+ nonnone_expr; \
+ }) : none_expr; })
+
+OptionalInt_t List$find(List_t arr, void *item, const TypeInfo_t *type);
+#define List$find_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; List$find(arr, &item, type); })
+OptionalInt_t List$first(List_t arr, Closure_t predicate);
+void List$sort(List_t *arr, Closure_t comparison, int64_t padded_item_size);
+List_t List$sorted(List_t arr, Closure_t comparison, int64_t padded_item_size);
+void List$shuffle(List_t *arr, RNG_t rng, int64_t padded_item_size);
+List_t List$shuffled(List_t arr, RNG_t rng, int64_t padded_item_size);
+void *List$random(List_t arr, RNG_t rng);
+#define List$random_value(arr, rng, t) ({ List_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty list!"); *(t*)List$random(_arr, rng); })
+List_t List$sample(List_t arr, Int_t n, List_t weights, RNG_t rng, int64_t padded_item_size);
+Table_t List$counts(List_t arr, const TypeInfo_t *type);
+void List$clear(List_t *list);
+void List$compact(List_t *arr, int64_t padded_item_size);
+PUREFUNC bool List$has(List_t list, void *item, const TypeInfo_t *type);
+#define List$has_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; List$has(arr, &item, type); })
+PUREFUNC List_t List$from(List_t list, Int_t first);
+PUREFUNC List_t List$to(List_t list, Int_t last);
+PUREFUNC List_t List$by(List_t list, Int_t stride, int64_t padded_item_size);
+PUREFUNC List_t List$slice(List_t list, Int_t int_first, Int_t int_last);
+PUREFUNC List_t List$reversed(List_t list, int64_t padded_item_size);
+List_t List$concat(List_t x, List_t y, int64_t padded_item_size);
+PUREFUNC uint64_t List$hash(const void *arr, const TypeInfo_t *type);
+PUREFUNC int32_t List$compare(const void *x, const void *y, const TypeInfo_t *type);
+PUREFUNC bool List$equal(const void *x, const void *y, const TypeInfo_t *type);
+PUREFUNC bool List$is_none(const void *obj, const TypeInfo_t*);
+Text_t List$as_text(const void *arr, bool colorize, const TypeInfo_t *type);
+void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size);
+void List$heap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size);
+#define List$heap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; List$heap_push(heap, &value, comparison, padded_item_size); })
+void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size);
+#define List$heap_pop_value(heap, comparison, type, nonnone_var, nonnone_expr, none_expr) \
+ ({ List_t *_heap = heap; \
+ (_heap->length > 0) ? ({ \
+ type nonnone_var = *(type*)_heap->data; \
+ List$heap_pop(_heap, comparison, sizeof(type)); \
+ nonnone_expr; \
+ }) : none_expr; })
+Int_t List$binary_search(List_t list, void *target, Closure_t comparison);
+#define List$binary_search_value(list, target, comparison) \
+ ({ __typeof(target) _target = target; List$binary_search(list, &_target, comparison); })
+void List$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
+void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type);
+
+#define List$metamethods ((metamethods_t){ \
+ .as_text=List$as_text, \
+ .compare=List$compare, \
+ .equal=List$equal, \
+ .hash=List$hash, \
+ .is_none=List$is_none, \
+ .serialize=List$serialize, \
+ .deserialize=List$deserialize, \
+})
+
+#define List$info(item_info) &((TypeInfo_t){.size=sizeof(List_t), .align=__alignof__(List_t), \
+ .tag=ListInfo, .ListInfo.item=item_info, \
+ .metamethods=List$metamethods})
+
+// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/stdlib/metamethods.c b/stdlib/metamethods.c
index c0e11cfc..c0c5e0e2 100644
--- a/stdlib/metamethods.c
+++ b/stdlib/metamethods.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include <string.h>
-#include "arrays.h"
+#include "lists.h"
#include "bools.h"
#include "bytes.h"
#include "functiontype.h"
@@ -61,7 +61,7 @@ public void _serialize(const void *obj, FILE *out, Table_t *pointers, const Type
fwrite(obj, (size_t)type->size, 1, out);
}
-public Array_t generic_serialize(const void *x, const TypeInfo_t *type)
+public List_t generic_serialize(const void *x, const TypeInfo_t *type)
{
char *buf = NULL;
size_t size = 0;
@@ -69,7 +69,7 @@ public Array_t generic_serialize(const void *x, const TypeInfo_t *type)
Table_t pointers = {};
_serialize(x, stream, &pointers, type);
fclose(stream);
- Array_t bytes = {
+ List_t bytes = {
.data=GC_MALLOC_ATOMIC(size),
.length=(int64_t)size,
.stride=1,
@@ -80,7 +80,7 @@ public Array_t generic_serialize(const void *x, const TypeInfo_t *type)
return bytes;
}
-public void _deserialize(FILE *input, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void _deserialize(FILE *input, void *outval, List_t *pointers, const TypeInfo_t *type)
{
if (type->metamethods.deserialize) {
type->metamethods.deserialize(input, outval, pointers, type);
@@ -90,13 +90,13 @@ public void _deserialize(FILE *input, void *outval, Array_t *pointers, const Typ
fread(outval, (size_t)type->size, 1, input);
}
-public void generic_deserialize(Array_t bytes, void *outval, const TypeInfo_t *type)
+public void generic_deserialize(List_t bytes, void *outval, const TypeInfo_t *type)
{
if (bytes.stride != 1)
- Array$compact(&bytes, 1);
+ List$compact(&bytes, 1);
FILE *input = fmemopen(bytes.data, (size_t)bytes.length, "r");
- Array_t pointers = {};
+ List_t pointers = {};
_deserialize(input, outval, &pointers, type);
fclose(input);
}
@@ -115,7 +115,7 @@ public void cannot_serialize(const void*, FILE*, Table_t*, const TypeInfo_t *typ
}
__attribute__((noreturn))
-public void cannot_deserialize(FILE*, void*, Array_t*, const TypeInfo_t *type)
+public void cannot_deserialize(FILE*, void*, List_t*, const TypeInfo_t *type)
{
Text_t typestr = generic_as_text(NULL, false, type);
fail("Values of type %k cannot be serialized or deserialized!", &typestr);
diff --git a/stdlib/metamethods.h b/stdlib/metamethods.h
index a75fcf7f..ca0a1e7e 100644
--- a/stdlib/metamethods.h
+++ b/stdlib/metamethods.h
@@ -12,11 +12,11 @@ PUREFUNC int32_t generic_compare(const void *x, const void *y, const TypeInfo_t
PUREFUNC bool generic_equal(const void *x, const void *y, const TypeInfo_t *type);
Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo_t *type);
void _serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-Array_t generic_serialize(const void *x, const TypeInfo_t *type);
-void _deserialize(FILE *input, void *outval, Array_t *pointers, const TypeInfo_t *type);
-void generic_deserialize(Array_t bytes, void *outval, const TypeInfo_t *type);
+List_t generic_serialize(const void *x, const TypeInfo_t *type);
+void _deserialize(FILE *input, void *outval, List_t *pointers, const TypeInfo_t *type);
+void generic_deserialize(List_t bytes, void *outval, const TypeInfo_t *type);
int generic_print(const void *obj, bool colorize, const TypeInfo_t *type);
void cannot_serialize(const void*, FILE*, Table_t*, const TypeInfo_t *type);
-void cannot_deserialize(FILE*, void*, Array_t*, const TypeInfo_t *type);
+void cannot_deserialize(FILE*, void*, List_t*, const TypeInfo_t *type);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/stdlib/nums.c b/stdlib/nums.c
index 98f7b509..d9c38500 100644
--- a/stdlib/nums.c
+++ b/stdlib/nums.c
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <stdlib.h>
-#include "arrays.h"
+#include "lists.h"
#include "nums.h"
#include "string.h"
#include "text.h"
diff --git a/stdlib/optionals.c b/stdlib/optionals.c
index d91ebffc..66c11bd3 100644
--- a/stdlib/optionals.c
+++ b/stdlib/optionals.c
@@ -66,7 +66,7 @@ public void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, co
_serialize(obj, out, pointers, type->OptionalInfo.type);
}
-public void Optional$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type)
{
bool has_value = (bool)fgetc(in);
const TypeInfo_t *nonnull = type->OptionalInfo.type;
@@ -76,8 +76,8 @@ public void Optional$deserialize(FILE *in, void *outval, Array_t *pointers, cons
} else {
if (nonnull->tag == TextInfo)
*(Text_t*)outval = NONE_TEXT;
- else if (nonnull->tag == ArrayInfo)
- *(Array_t*)outval = (Array_t){.length=-1};
+ else if (nonnull->tag == ListInfo)
+ *(List_t*)outval = (List_t){.length=-1};
else if (nonnull->tag == TableInfo)
*(Table_t*)outval = (Table_t){.entries={.length=-1}};
else if (nonnull == &Num$info)
diff --git a/stdlib/optionals.h b/stdlib/optionals.h
index 882fb891..41ce6205 100644
--- a/stdlib/optionals.h
+++ b/stdlib/optionals.h
@@ -11,12 +11,12 @@
#include "util.h"
#define OptionalBool_t uint8_t
-#define OptionalArray_t Array_t
+#define OptionalList_t List_t
#define OptionalTable_t Table_t
#define OptionalText_t Text_t
#define OptionalClosure_t Closure_t
-#define NONE_ARRAY ((Array_t){.length=-1})
+#define NONE_LIST ((List_t){.length=-1})
#define NONE_BOOL ((OptionalBool_t)2)
#define NONE_INT ((OptionalInt_t){.small=0})
#define NONE_TABLE ((OptionalTable_t){.entries.length=-1})
@@ -31,7 +31,7 @@ PUREFUNC int32_t Optional$compare(const void *x, const void *y, const TypeInfo_t
PUREFUNC bool Optional$equal(const void *x, const void *y, const TypeInfo_t *type);
Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t *type);
void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Optional$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type);
+void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type);
#define Optional$metamethods ((metamethods_t){ \
.hash=Optional$hash, \
diff --git a/stdlib/paths.c b/stdlib/paths.c
index bac37b27..09e7e43a 100644
--- a/stdlib/paths.c
+++ b/stdlib/paths.c
@@ -16,7 +16,7 @@
#include <unistd.h>
#include <unistr.h>
-#include "arrays.h"
+#include "lists.h"
#include "files.h"
#include "integers.h"
#include "optionals.h"
@@ -32,16 +32,16 @@
static const Path_t HOME_PATH = {.type=PATH_HOME}, ROOT_PATH = {.type=PATH_ABSOLUTE}, CURDIR_PATH = {.type=PATH_RELATIVE};
-static void clean_components(Array_t *components)
+static void clean_components(List_t *components)
{
for (int64_t i = 0; i < components->length; ) {
Text_t *component = (Text_t*)(components->data + i*components->stride);
if (component->length == 0 || Text$equal_values(*component, Text("."))) {
- Array$remove_at(components, I(i+1), I(1), sizeof(Text_t));
+ List$remove_at(components, I(i+1), I(1), sizeof(Text_t));
} else if (i > 0 && Text$equal_values(*component, Text(".."))) {
Text_t *prev = (Text_t*)(components->data + (i-1)*components->stride);
if (!Text$equal_values(*prev, Text(".."))) {
- Array$remove_at(components, I(i), I(2), sizeof(Text_t));
+ List$remove_at(components, I(i), I(2), sizeof(Text_t));
i -= 1;
} else {
i += 1;
@@ -81,10 +81,10 @@ public Path_t Path$from_str(const char *str)
&& result.components.length > 1
&& !Text$equal_values(Text(".."), *(Text_t*)(result.components.data + result.components.stride*(result.components.length-1)))) {
// Pop off /foo/baz/.. -> /foo
- Array$remove_at(&result.components, I(result.components.length), I(1), sizeof(Text_t));
+ List$remove_at(&result.components, I(result.components.length), I(1), sizeof(Text_t));
} else {
Text_t component = Text$from_strn(str, component_len);
- Array$insert_value(&result.components, component, I(0), sizeof(Text_t));
+ List$insert_value(&result.components, component, I(0), sizeof(Text_t));
}
str += component_len;
}
@@ -102,7 +102,7 @@ public Path_t Path$expand_home(Path_t path)
{
if (path.type == PATH_HOME) {
Path_t pwd = Path$from_str(getenv("HOME"));
- Array_t components = Array$concat(pwd.components, path.components, sizeof(Text_t));
+ List_t components = List$concat(pwd.components, path.components, sizeof(Text_t));
assert(components.length == path.components.length + pwd.components.length);
clean_components(&components);
path = (Path_t){.type=PATH_ABSOLUTE, .components=components};
@@ -114,12 +114,12 @@ public Path_t Path$_concat(int n, Path_t items[n])
{
assert(n > 0);
Path_t result = items[0];
- ARRAY_INCREF(result.components);
+ LIST_INCREF(result.components);
for (int i = 1; i < n; i++) {
if (items[i].type != PATH_RELATIVE)
fail("Cannot concatenate an absolute or home-based path onto another path: (%s)\n",
Path$as_c_string(items[i]));
- Array$insert_all(&result.components, items[i].components, I(0), sizeof(Text_t));
+ List$insert_all(&result.components, items[i].components, I(0), sizeof(Text_t));
}
clean_components(&result.components);
return result;
@@ -130,8 +130,8 @@ public Path_t Path$resolved(Path_t path, Path_t relative_to)
if (path.type == PATH_RELATIVE && !(relative_to.type == PATH_RELATIVE && relative_to.components.length == 0)) {
Path_t result = {.type=relative_to.type};
result.components = relative_to.components;
- ARRAY_INCREF(result.components);
- Array$insert_all(&result.components, path.components, I(0), sizeof(Text_t));
+ LIST_INCREF(result.components);
+ List$insert_all(&result.components, path.components, I(0), sizeof(Text_t));
clean_components(&result.components);
return result;
}
@@ -154,11 +154,11 @@ public Path_t Path$relative_to(Path_t path, Path_t relative_to)
}
for (int64_t i = shared; i < relative_to.components.length; i++)
- Array$insert_value(&result.components, Text(".."), I(1), sizeof(Text_t));
+ List$insert_value(&result.components, Text(".."), I(1), sizeof(Text_t));
for (int64_t i = shared; i < path.components.length; i++) {
Text_t *p = (Text_t*)(path.components.data + i*path.components.stride);
- Array$insert(&result.components, p, I(0), sizeof(Text_t));
+ List$insert(&result.components, p, I(0), sizeof(Text_t));
}
//clean_components(&result.components);
return result;
@@ -263,7 +263,7 @@ public OptionalMoment_t Path$changed(Path_t path, bool follow_symlinks)
return (Moment_t){.tv_sec=sb.st_ctime};
}
-static void _write(Path_t path, Array_t bytes, int mode, int permissions)
+static void _write(Path_t path, List_t bytes, int mode, int permissions)
{
path = Path$expand_home(path);
const char *path_str = Path$as_c_string(path);
@@ -272,7 +272,7 @@ static void _write(Path_t path, Array_t bytes, int mode, int permissions)
fail("Could not write to file: %s\n%s", path_str, strerror(errno));
if (bytes.stride != 1)
- Array$compact(&bytes, 1);
+ List$compact(&bytes, 1);
ssize_t written = write(fd, bytes.data, (size_t)bytes.length);
if (written != (ssize_t)bytes.length)
fail("Could not write to file: %s\n%s", path_str, strerror(errno));
@@ -280,36 +280,36 @@ static void _write(Path_t path, Array_t bytes, int mode, int permissions)
public void Path$write(Path_t path, Text_t text, int permissions)
{
- Array_t bytes = Text$utf8_bytes(text);
+ List_t bytes = Text$utf8_bytes(text);
_write(path, bytes, O_WRONLY | O_CREAT, permissions);
}
-public void Path$write_bytes(Path_t path, Array_t bytes, int permissions)
+public void Path$write_bytes(Path_t path, List_t bytes, int permissions)
{
_write(path, bytes, O_WRONLY | O_CREAT, permissions);
}
public void Path$append(Path_t path, Text_t text, int permissions)
{
- Array_t bytes = Text$utf8_bytes(text);
+ List_t bytes = Text$utf8_bytes(text);
_write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions);
}
-public void Path$append_bytes(Path_t path, Array_t bytes, int permissions)
+public void Path$append_bytes(Path_t path, List_t bytes, int permissions)
{
_write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions);
}
-public OptionalArray_t Path$read_bytes(Path_t path, OptionalInt_t count)
+public OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t count)
{
path = Path$expand_home(path);
int fd = open(Path$as_c_string(path), O_RDONLY);
if (fd == -1)
- return NONE_ARRAY;
+ return NONE_LIST;
struct stat sb;
if (fstat(fd, &sb) != 0)
- return NONE_ARRAY;
+ return NONE_LIST;
int64_t const target_count = count.small ? Int64$from_int(count, false) : INT64_MAX;
if (target_count < 0)
@@ -324,7 +324,7 @@ public OptionalArray_t Path$read_bytes(Path_t path, OptionalInt_t count)
if (count.small && (int64_t)sb.st_size < target_count)
fail("Could not read %ld bytes from %k (only got %zu)", target_count, &path, sb.st_size);
int64_t len = count.small ? target_count : (int64_t)sb.st_size;
- return (Array_t){.data=content, .atomic=1, .stride=1, .length=len};
+ return (List_t){.data=content, .atomic=1, .stride=1, .length=len};
} else {
size_t capacity = 256, len = 0;
char *content = GC_MALLOC_ATOMIC(capacity);
@@ -335,7 +335,7 @@ public OptionalArray_t Path$read_bytes(Path_t path, OptionalInt_t count)
ssize_t just_read = read(fd, chunk, to_read);
if (just_read < 0) {
close(fd);
- return NONE_ARRAY;
+ return NONE_LIST;
} else if (just_read == 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
@@ -353,13 +353,13 @@ public OptionalArray_t Path$read_bytes(Path_t path, OptionalInt_t count)
close(fd);
if (count.small != 0 && (int64_t)len < target_count)
fail("Could not read %ld bytes from %k (only got %zu)", target_count, &path, len);
- return (Array_t){.data=content, .atomic=1, .stride=1, .length=len};
+ return (List_t){.data=content, .atomic=1, .stride=1, .length=len};
}
}
public OptionalText_t Path$read(Path_t path)
{
- Array_t bytes = Path$read_bytes(path, NONE_INT);
+ List_t bytes = Path$read_bytes(path, NONE_INT);
if (bytes.length < 0) return NONE_TEXT;
return Text$from_bytes(bytes);
}
@@ -433,11 +433,11 @@ public void Path$create_directory(Path_t path, int permissions)
fail("Could not create directory: %s (%s)", c_path, strerror(errno));
}
-static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filter)
+static List_t _filtered_children(Path_t path, bool include_hidden, mode_t filter)
{
path = Path$expand_home(path);
struct dirent *dir;
- Array_t children = {};
+ List_t children = {};
const char *path_str = Path$as_c_string(path);
size_t path_len = strlen(path_str);
DIR *d = opendir(path_str);
@@ -461,23 +461,23 @@ static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filte
continue;
Path_t child = Path$from_str(child_str);
- Array$insert(&children, &child, I(0), sizeof(Path_t));
+ List$insert(&children, &child, I(0), sizeof(Path_t));
}
closedir(d);
return children;
}
-public Array_t Path$children(Path_t path, bool include_hidden)
+public List_t Path$children(Path_t path, bool include_hidden)
{
return _filtered_children(path, include_hidden, (mode_t)-1);
}
-public Array_t Path$files(Path_t path, bool include_hidden)
+public List_t Path$files(Path_t path, bool include_hidden)
{
return _filtered_children(path, include_hidden, S_IFREG);
}
-public Array_t Path$subdirectories(Path_t path, bool include_hidden)
+public List_t Path$subdirectories(Path_t path, bool include_hidden)
{
return _filtered_children(path, include_hidden, S_IFDIR);
}
@@ -497,7 +497,7 @@ public Path_t Path$unique_directory(Path_t path)
return Path$from_str(created);
}
-public Path_t Path$write_unique_bytes(Path_t path, Array_t bytes)
+public Path_t Path$write_unique_bytes(Path_t path, List_t bytes)
{
path = Path$expand_home(path);
const char *path_str = Path$as_c_string(path);
@@ -517,7 +517,7 @@ public Path_t Path$write_unique_bytes(Path_t path, Array_t bytes)
fail("Could not write to unique file: %s\n%s", buf, strerror(errno));
if (bytes.stride != 1)
- Array$compact(&bytes, 1);
+ List$compact(&bytes, 1);
ssize_t written = write(fd, bytes.data, (size_t)bytes.length);
if (written != (ssize_t)bytes.length)
@@ -536,11 +536,11 @@ public Path_t Path$parent(Path_t path)
return path;
} else if (path.components.length > 0 && !Text$equal_values(*(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)),
Text(".."))) {
- return (Path_t){.type=path.type, .components=Array$slice(path.components, I(1), I(-2))};
+ return (Path_t){.type=path.type, .components=List$slice(path.components, I(1), I(-2))};
} else {
Path_t result = {.type=path.type, .components=path.components};
- ARRAY_INCREF(result.components);
- Array$insert_value(&result.components, Text(".."), I(0), sizeof(Text_t));
+ LIST_INCREF(result.components);
+ List$insert_value(&result.components, Text(".."), I(0), sizeof(Text_t));
return result;
}
}
@@ -560,7 +560,7 @@ public PUREFUNC Text_t Path$base_name(Path_t path)
public Text_t Path$extension(Path_t path, bool full)
{
Text_t base = Path$base_name(path);
- Array_t results = Text$matches(base, full ? Pattern(".{!.}.{..}") : Pattern(".{..}.{!.}{end}"));
+ List_t results = Text$matches(base, full ? Pattern(".{!.}.{..}") : Pattern(".{..}.{!.}{end}"));
if (results.length > 0)
return *((Text_t*)(results.data + results.stride*1));
results = Text$matches(base, full ? Pattern("{!.}.{..}") : Pattern("{..}.{!.}{end}"));
@@ -576,8 +576,8 @@ public Path_t Path$with_component(Path_t path, Text_t component)
.type=path.type,
.components=path.components,
};
- ARRAY_INCREF(result.components);
- Array$insert(&result.components, &component, I(0), sizeof(Text_t));
+ LIST_INCREF(result.components);
+ List$insert(&result.components, &component, I(0), sizeof(Text_t));
clean_components(&result.components);
return result;
}
@@ -591,9 +591,9 @@ public Path_t Path$with_extension(Path_t path, Text_t extension, bool replace)
.type=path.type,
.components=path.components,
};
- ARRAY_INCREF(result.components);
+ LIST_INCREF(result.components);
Text_t last = *(Text_t*)(path.components.data + path.components.stride*(path.components.length-1));
- Array$remove_at(&result.components, I(-1), I(1), sizeof(Text_t));
+ List$remove_at(&result.components, I(-1), I(1), sizeof(Text_t));
if (replace) {
if (Text$starts_with(last, Text(".")))
last = Text$replace(last, Pattern(".{!.}.{..}"), Text(".@1"), Pattern("@"), false);
@@ -602,7 +602,7 @@ public Path_t Path$with_extension(Path_t path, Text_t extension, bool replace)
}
last = Text$concat(last, extension);
- Array$insert(&result.components, &last, I(0), sizeof(Text_t));
+ List$insert(&result.components, &last, I(0), sizeof(Text_t));
return result;
}
@@ -651,21 +651,21 @@ public OptionalClosure_t Path$by_line(Path_t path)
return (Closure_t){.fn=(void*)_next_line, .userdata=wrapper};
}
-public Array_t Path$glob(Path_t path)
+public List_t Path$glob(Path_t path)
{
glob_t glob_result;
int status = glob(Path$as_c_string(path), GLOB_BRACE | GLOB_TILDE | GLOB_TILDE_CHECK, NULL, &glob_result);
if (status != 0 && status != GLOB_NOMATCH)
fail("Failed to perform globbing");
- Array_t glob_files = {};
+ List_t glob_files = {};
for (size_t i = 0; i < glob_result.gl_pathc; i++) {
size_t len = strlen(glob_result.gl_pathv[i]);
if ((len >= 2 && glob_result.gl_pathv[i][len-1] == '.' && glob_result.gl_pathv[i][len-2] == '/')
|| (len >= 2 && glob_result.gl_pathv[i][len-1] == '.' && glob_result.gl_pathv[i][len-2] == '.' && glob_result.gl_pathv[i][len-3] == '/'))
continue;
Path_t p = Path$from_str(glob_result.gl_pathv[i]);
- Array$insert(&glob_files, &p, I(0), sizeof(Path_t));
+ List$insert(&glob_files, &p, I(0), sizeof(Path_t));
}
return glob_files;
}
@@ -689,7 +689,7 @@ public PUREFUNC int32_t Path$compare(const void *va, const void *vb, const TypeI
Path_t *a = (Path_t*)va, *b = (Path_t*)vb;
int diff = ((int)a->type - (int)b->type);
if (diff != 0) return diff;
- return Array$compare(&a->components, &b->components, Array$info(&Text$info));
+ return List$compare(&a->components, &b->components, List$info(&Text$info));
}
public PUREFUNC bool Path$equal(const void *va, const void *vb, const TypeInfo_t *type)
@@ -697,13 +697,13 @@ public PUREFUNC bool Path$equal(const void *va, const void *vb, const TypeInfo_t
(void)type;
Path_t *a = (Path_t*)va, *b = (Path_t*)vb;
if (a->type != b->type) return false;
- return Array$equal(&a->components, &b->components, Array$info(&Text$info));
+ return List$equal(&a->components, &b->components, List$info(&Text$info));
}
public PUREFUNC bool Path$equal_values(Path_t a, Path_t b)
{
if (a.type != b.type) return false;
- return Array$equal(&a.components, &b.components, Array$info(&Text$info));
+ return List$equal(&a.components, &b.components, List$info(&Text$info));
}
public const char *Path$as_c_string(Path_t path)
@@ -774,15 +774,15 @@ public void Path$serialize(const void *obj, FILE *out, Table_t *pointers, const
(void)type;
Path_t *path = (Path_t*)obj;
fputc((int)path->type, out);
- Array$serialize(&path->components, out, pointers, Array$info(&Text$info));
+ List$serialize(&path->components, out, pointers, List$info(&Text$info));
}
-public void Path$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t *type)
+public void Path$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type)
{
(void)type;
Path_t path = {};
path.type = fgetc(in);
- Array$deserialize(in, &path.components, pointers, Array$info(&Text$info));
+ List$deserialize(in, &path.components, pointers, List$info(&Text$info));
*(Path_t*)obj = path;
}
diff --git a/stdlib/paths.h b/stdlib/paths.h
index f65bd3ca..9869c701 100644
--- a/stdlib/paths.h
+++ b/stdlib/paths.h
@@ -31,29 +31,29 @@ OptionalMoment_t Path$modified(Path_t path, bool follow_symlinks);
OptionalMoment_t Path$accessed(Path_t path, bool follow_symlinks);
OptionalMoment_t Path$changed(Path_t path, bool follow_symlinks);
void Path$write(Path_t path, Text_t text, int permissions);
-void Path$write_bytes(Path_t path, Array_t bytes, int permissions);
+void Path$write_bytes(Path_t path, List_t bytes, int permissions);
void Path$append(Path_t path, Text_t text, int permissions);
-void Path$append_bytes(Path_t path, Array_t bytes, int permissions);
+void Path$append_bytes(Path_t path, List_t bytes, int permissions);
OptionalText_t Path$read(Path_t path);
-OptionalArray_t Path$read_bytes(Path_t path, OptionalInt_t limit);
+OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t limit);
void Path$set_owner(Path_t path, OptionalText_t owner, OptionalText_t group, bool follow_symlinks);
OptionalText_t Path$owner(Path_t path, bool follow_symlinks);
OptionalText_t Path$group(Path_t path, bool follow_symlinks);
void Path$remove(Path_t path, bool ignore_missing);
void Path$create_directory(Path_t path, int permissions);
-Array_t Path$children(Path_t path, bool include_hidden);
-Array_t Path$files(Path_t path, bool include_hidden);
-Array_t Path$subdirectories(Path_t path, bool include_hidden);
+List_t Path$children(Path_t path, bool include_hidden);
+List_t Path$files(Path_t path, bool include_hidden);
+List_t Path$subdirectories(Path_t path, bool include_hidden);
Path_t Path$unique_directory(Path_t path);
Path_t Path$write_unique(Path_t path, Text_t text);
-Path_t Path$write_unique_bytes(Path_t path, Array_t bytes);
+Path_t Path$write_unique_bytes(Path_t path, List_t bytes);
Path_t Path$parent(Path_t path);
Text_t Path$base_name(Path_t path);
Text_t Path$extension(Path_t path, bool full);
Path_t Path$with_component(Path_t path, Text_t component);
Path_t Path$with_extension(Path_t path, Text_t extension, bool replace);
Closure_t Path$by_line(Path_t path);
-Array_t Path$glob(Path_t path);
+List_t Path$glob(Path_t path);
uint64_t Path$hash(const void *obj, const TypeInfo_t*);
int32_t Path$compare(const void *a, const void *b, const TypeInfo_t *type);
@@ -62,7 +62,7 @@ bool Path$equal_values(Path_t a, Path_t b);
Text_t Path$as_text(const void *obj, bool color, const TypeInfo_t *type);
bool Path$is_none(const void *obj, const TypeInfo_t *type);
void Path$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Path$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t *type);
+void Path$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type);
extern const TypeInfo_t Path$info;
diff --git a/stdlib/patterns.c b/stdlib/patterns.c
index 7a165836..a7936530 100644
--- a/stdlib/patterns.c
+++ b/stdlib/patterns.c
@@ -5,7 +5,7 @@
#include <unictype.h>
#include <uniname.h>
-#include "arrays.h"
+#include "lists.h"
#include "integers.h"
#include "optionals.h"
#include "patterns.h"
@@ -34,7 +34,7 @@ typedef struct {
};
} pat_t;
-static Text_t Text$replace_array(Text_t text, Array_t replacements, Text_t backref_pat, bool recursive);
+static Text_t Text$replace_list(Text_t text, List_t replacements, Text_t backref_pat, bool recursive);
static INLINE void skip_whitespace(TextIter_t *state, int64_t *i)
{
@@ -822,15 +822,15 @@ public OptionalMatch_t Text$find(Text_t text, Pattern_t pattern, Int_t from_inde
if (found == -1)
return NONE_MATCH;
- Array_t capture_array = {};
+ List_t capture_list = {};
for (int i = 0; captures[i].occupied; i++) {
Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length));
- Array$insert(&capture_array, &capture, I(0), sizeof(Text_t));
+ List$insert(&capture_list, &capture, I(0), sizeof(Text_t));
}
return (OptionalMatch_t){
.text=Text$slice(text, I(found+1), I(found+len)),
.index=I(found+1),
- .captures=capture_array,
+ .captures=capture_list,
};
}
@@ -852,33 +852,33 @@ PUREFUNC public bool Text$has(Text_t text, Pattern_t pattern)
}
}
-public OptionalArray_t Text$matches(Text_t text, Pattern_t pattern)
+public OptionalList_t Text$matches(Text_t text, Pattern_t pattern)
{
capture_t captures[MAX_BACKREFS] = {};
int64_t match_len = match(text, 0, pattern, 0, captures, 0);
if (match_len != text.length)
- return NONE_ARRAY;
+ return NONE_LIST;
- Array_t capture_array = {};
+ List_t capture_list = {};
for (int i = 0; captures[i].occupied; i++) {
Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length));
- Array$insert(&capture_array, &capture, I(0), sizeof(Text_t));
+ List$insert(&capture_list, &capture, I(0), sizeof(Text_t));
}
- return capture_array;
+ return capture_list;
}
-public Array_t Text$find_all(Text_t text, Pattern_t pattern)
+public List_t Text$find_all(Text_t text, Pattern_t pattern)
{
if (pattern.length == 0) // special case
- return (Array_t){.length=0};
+ return (List_t){.length=0};
- Array_t matches = {};
+ List_t matches = {};
for (int64_t i = 1; ; ) {
OptionalMatch_t m = Text$find(text, pattern, I(i));
if (!m.index.small)
break;
i = Int64$from_int(m.index, false) + m.text.length;
- Array$insert(&matches, &m, I_small(0), sizeof(Match_t));
+ List$insert(&matches, &m, I_small(0), sizeof(Match_t));
}
return matches;
}
@@ -910,7 +910,7 @@ public Closure_t Text$by_match(Text_t text, Pattern_t pattern)
};
}
-static Text_t apply_backrefs(Text_t text, Array_t recursive_replacements, Text_t replacement, Pattern_t backref_pat, capture_t *captures)
+static Text_t apply_backrefs(Text_t text, List_t recursive_replacements, Text_t replacement, Pattern_t backref_pat, capture_t *captures)
{
if (backref_pat.length == 0)
return replacement;
@@ -954,7 +954,7 @@ static Text_t apply_backrefs(Text_t text, Array_t recursive_replacements, Text_t
Text_t backref_text = Text$slice(text, I(captures[backref].index+1), I(captures[backref].index + captures[backref].length));
if (captures[backref].recursive && recursive_replacements.length > 0)
- backref_text = Text$replace_array(backref_text, recursive_replacements, backref_pat, true);
+ backref_text = Text$replace_list(backref_text, recursive_replacements, backref_pat, true);
if (pos > nonmatching_pos) {
Text_t before_slice = Text$slice(replacement, I(nonmatching_pos+1), I(pos));
@@ -983,7 +983,7 @@ public Text_t Text$replace(Text_t text, Pattern_t pattern, Text_t replacement, P
&& !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION));
Text_t entries[2] = {pattern, replacement};
- Array_t replacements = {
+ List_t replacements = {
.data=entries,
.length=1,
.stride=sizeof(entries),
@@ -1009,7 +1009,7 @@ public Text_t Text$replace(Text_t text, Pattern_t pattern, Text_t replacement, P
.occupied = true, .recursive = false,
};
- Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (Array_t){}, replacement, backref_pat, captures);
+ Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (List_t){}, replacement, backref_pat, captures);
if (pos > nonmatching_pos) {
Text_t before_slice = Text$slice(text, I(nonmatching_pos+1), I(pos));
ret = Text$concat(ret, before_slice, replacement_text);
@@ -1078,7 +1078,7 @@ public Text_t Text$map(Text_t text, Pattern_t pattern, Closure_t fn, bool recurs
Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length));
if (recursive)
capture = Text$map(capture, pattern, fn, recursive);
- Array$insert(&m.captures, &capture, I(0), sizeof(Text_t));
+ List$insert(&m.captures, &capture, I(0), sizeof(Text_t));
}
Text_t replacement = text_mapper(m, fn.userdata);
@@ -1127,7 +1127,7 @@ public void Text$each(Text_t text, Pattern_t pattern, Closure_t fn, bool recursi
Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length));
if (recursive)
Text$each(capture, pattern, fn, recursive);
- Array$insert(&m.captures, &capture, I(0), sizeof(Text_t));
+ List$insert(&m.captures, &capture, I(0), sizeof(Text_t));
}
action(m, fn.userdata);
@@ -1135,7 +1135,7 @@ public void Text$each(Text_t text, Pattern_t pattern, Closure_t fn, bool recursi
}
}
-Text_t Text$replace_array(Text_t text, Array_t replacements, Text_t backref_pat, bool recursive)
+Text_t Text$replace_list(Text_t text, List_t replacements, Text_t backref_pat, bool recursive)
{
if (replacements.length == 0) return text;
@@ -1160,7 +1160,7 @@ Text_t Text$replace_array(Text_t text, Array_t replacements, Text_t backref_pat,
// Concatenate the replacement:
Text_t replacement = *(Text_t*)(replacements.data + i*replacements.stride + sizeof(Text_t));
- Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (Array_t){}, replacement, backref_pat, captures);
+ Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (List_t){}, replacement, backref_pat, captures);
ret = Text$concat(ret, replacement_text);
pos += MAX(len, 1);
nonmatch_pos = pos;
@@ -1181,18 +1181,18 @@ Text_t Text$replace_array(Text_t text, Array_t replacements, Text_t backref_pat,
public Text_t Text$replace_all(Text_t text, Table_t replacements, Text_t backref_pat, bool recursive)
{
- return Text$replace_array(text, replacements.entries, backref_pat, recursive);
+ return Text$replace_list(text, replacements.entries, backref_pat, recursive);
}
-public Array_t Text$split(Text_t text, Pattern_t pattern)
+public List_t Text$split(Text_t text, Pattern_t pattern)
{
if (text.length == 0) // special case
- return (Array_t){.length=0};
+ return (List_t){.length=0};
if (pattern.length == 0) // special case
return Text$clusters(text);
- Array_t chunks = {};
+ List_t chunks = {};
int64_t i = 0;
for (;;) {
@@ -1202,12 +1202,12 @@ public Array_t Text$split(Text_t text, Pattern_t pattern)
found = _find(text, pattern, i + 1, text.length-1, &len, NULL);
if (found < 0) break;
Text_t chunk = Text$slice(text, I(i+1), I(found));
- Array$insert(&chunks, &chunk, I_small(0), sizeof(Text_t));
+ List$insert(&chunks, &chunk, I_small(0), sizeof(Text_t));
i = MAX(found + len, i + 1);
}
Text_t last_chunk = Text$slice(text, I(i+1), I(text.length));
- Array$insert(&chunks, &last_chunk, I_small(0), sizeof(Text_t));
+ List$insert(&chunks, &last_chunk, I_small(0), sizeof(Text_t));
return chunks;
}
@@ -1270,7 +1270,7 @@ public const TypeInfo_t Pattern$info = {
static NamedType_t _match_fields[3] = {
{"text", &Text$info},
{"index", &Int$info},
- {"captures", Array$info(&Text$info)},
+ {"captures", List$info(&Text$info)},
};
static bool Match$is_none(const void *m, const TypeInfo_t*)
diff --git a/stdlib/patterns.h b/stdlib/patterns.h
index 53db0978..895f56d5 100644
--- a/stdlib/patterns.h
+++ b/stdlib/patterns.h
@@ -17,7 +17,7 @@
typedef struct {
Text_t text;
Int_t index;
- Array_t captures;
+ List_t captures;
} Match_t;
typedef Match_t OptionalMatch_t;
@@ -26,14 +26,14 @@ typedef Match_t OptionalMatch_t;
Text_t Text$replace(Text_t str, Pattern_t pat, Text_t replacement, Pattern_t backref_pat, bool recursive);
Pattern_t Pattern$escape_text(Text_t text);
Text_t Text$replace_all(Text_t text, Table_t replacements, Pattern_t backref_pat, bool recursive);
-Array_t Text$split(Text_t text, Pattern_t pattern);
+List_t Text$split(Text_t text, Pattern_t pattern);
Closure_t Text$by_split(Text_t text, Pattern_t pattern);
Text_t Text$trim(Text_t text, Pattern_t pattern, bool trim_left, bool trim_right);
OptionalMatch_t Text$find(Text_t text, Pattern_t pattern, Int_t i);
-Array_t Text$find_all(Text_t text, Pattern_t pattern);
+List_t Text$find_all(Text_t text, Pattern_t pattern);
Closure_t Text$by_match(Text_t text, Pattern_t pattern);
PUREFUNC bool Text$has(Text_t text, Pattern_t pattern);
-OptionalArray_t Text$matches(Text_t text, Pattern_t pattern);
+OptionalList_t Text$matches(Text_t text, Pattern_t pattern);
Text_t Text$map(Text_t text, Pattern_t pattern, Closure_t fn, bool recursive);
void Text$each(Text_t text, Pattern_t pattern, Closure_t fn, bool recursive);
diff --git a/stdlib/pointers.c b/stdlib/pointers.c
index 76e882ec..b674ac6f 100644
--- a/stdlib/pointers.c
+++ b/stdlib/pointers.c
@@ -104,7 +104,7 @@ public void Pointer$serialize(const void *obj, FILE *out, Table_t *pointers, con
_serialize(ptr, out, pointers, type->PointerInfo.pointed);
}
-public void Pointer$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void Pointer$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type)
{
int64_t id = 0;
Int64$deserialize(in, &id, pointers, &Int64$info);
@@ -112,7 +112,7 @@ public void Pointer$deserialize(FILE *in, void *outval, Array_t *pointers, const
if (id > pointers->length) {
void *obj = GC_MALLOC((size_t)type->PointerInfo.pointed->size);
- Array$insert(pointers, &obj, I(0), sizeof(void*));
+ List$insert(pointers, &obj, I(0), sizeof(void*));
_deserialize(in, obj, pointers, type->PointerInfo.pointed);
*(void**)outval = obj;
} else {
diff --git a/stdlib/pointers.h b/stdlib/pointers.h
index 1cd76366..ef8b44d3 100644
--- a/stdlib/pointers.h
+++ b/stdlib/pointers.h
@@ -14,7 +14,7 @@ PUREFUNC int32_t Pointer$compare(const void *x, const void *y, const TypeInfo_t
PUREFUNC bool Pointer$equal(const void *x, const void *y, const TypeInfo_t *type);
PUREFUNC bool Pointer$is_none(const void *x, const TypeInfo_t*);
void Pointer$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Pointer$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type);
+void Pointer$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type);
#define Null(t) (t*)NULL
#define POINTER_TYPE(_sigil, _pointed) (&(TypeInfo_t){\
diff --git a/stdlib/rng.c b/stdlib/rng.c
index 07b2f36c..bf6a85b3 100644
--- a/stdlib/rng.c
+++ b/stdlib/rng.c
@@ -10,7 +10,7 @@
#include <string.h>
#include <sys/param.h>
-#include "arrays.h"
+#include "lists.h"
#include "datatypes.h"
#include "rng.h"
#include "text.h"
@@ -35,7 +35,7 @@ PUREFUNC static Text_t RNG$as_text(const void *rng, bool colorize, const TypeInf
#define KEYSZ 32
#define IVSZ 8
-public void RNG$set_seed(RNG_t rng, Array_t seed)
+public void RNG$set_seed(RNG_t rng, List_t seed)
{
uint8_t seed_bytes[KEYSZ + IVSZ] = {};
for (int64_t i = 0; i < (int64_t)sizeof(seed_bytes); i++)
@@ -53,7 +53,7 @@ public RNG_t RNG$copy(RNG_t rng)
return copy;
}
-public RNG_t RNG$new(Array_t seed)
+public RNG_t RNG$new(List_t seed)
{
RNG_t rng = GC_MALLOC_ATOMIC(sizeof(struct RNGState_t));
RNG$set_seed(rng, seed);
@@ -249,12 +249,12 @@ public Byte_t RNG$byte(RNG_t rng)
return b;
}
-public Array_t RNG$bytes(RNG_t rng, Int_t count)
+public List_t RNG$bytes(RNG_t rng, Int_t count)
{
int64_t n = Int64$from_int(count, false);
Byte_t *r = GC_MALLOC_ATOMIC(sizeof(Byte_t[n]));
random_bytes(rng, r, sizeof(Byte_t[n]));
- return (Array_t){.data=r, .length=n, .stride=1, .atomic=1};
+ return (List_t){.data=r, .length=n, .stride=1, .atomic=1};
}
public const TypeInfo_t RNG$info = {
diff --git a/stdlib/rng.h b/stdlib/rng.h
index 5bc4794f..0f21e04f 100644
--- a/stdlib/rng.h
+++ b/stdlib/rng.h
@@ -11,8 +11,8 @@
#include "bytes.h"
#include "util.h"
-RNG_t RNG$new(Array_t seed);
-void RNG$set_seed(RNG_t rng, Array_t seed);
+RNG_t RNG$new(List_t seed);
+void RNG$set_seed(RNG_t rng, List_t seed);
RNG_t RNG$copy(RNG_t rng);
Bool_t RNG$bool(RNG_t rng, Num_t p);
Int_t RNG$int(RNG_t rng, Int_t min, Int_t max);
@@ -21,7 +21,7 @@ Int32_t RNG$int32(RNG_t rng, Int32_t min, Int32_t max);
Int16_t RNG$int16(RNG_t rng, Int16_t min, Int16_t max);
Int8_t RNG$int8(RNG_t rng, Int8_t min, Int8_t max);
Byte_t RNG$byte(RNG_t rng);
-Array_t RNG$bytes(RNG_t rng, Int_t count);
+List_t RNG$bytes(RNG_t rng, Int_t count);
Num_t RNG$num(RNG_t rng, Num_t min, Num_t max);
Num32_t RNG$num32(RNG_t rng, Num32_t min, Num32_t max);
diff --git a/stdlib/stdlib.c b/stdlib/stdlib.c
index 9b117a24..2607f8f9 100644
--- a/stdlib/stdlib.c
+++ b/stdlib/stdlib.c
@@ -54,7 +54,7 @@ public void tomo_init(void)
uint8_t *random_bytes[40] = {};
getrandom(random_bytes, sizeof(random_bytes), 0);
- Array_t rng_seed = {.length=sizeof(random_bytes), .data=random_bytes, .stride=1, .atomic=1};
+ List_t rng_seed = {.length=sizeof(random_bytes), .data=random_bytes, .stride=1, .atomic=1};
RNG$set_seed(default_rng, rng_seed);
if (register_printf_specifier('k', printf_text, printf_text_size))
@@ -154,8 +154,8 @@ static bool parse_single_arg(const TypeInfo_t *info, char *arg, void *dest)
Text_t t = generic_as_text(NULL, false, info);
errx(1, "Unsupported multi-argument struct type for argument parsing: %k", &t);
- } else if (info->tag == ArrayInfo) {
- errx(1, "Array arguments must be specified as `--flag ...` not `--flag=...`");
+ } else if (info->tag == ListInfo) {
+ errx(1, "List arguments must be specified as `--flag ...` not `--flag=...`");
} else if (info->tag == TableInfo) {
errx(1, "Table arguments must be specified as `--flag ...` not `--flag=...`");
} else {
@@ -164,13 +164,13 @@ static bool parse_single_arg(const TypeInfo_t *info, char *arg, void *dest)
}
}
-static Array_t parse_array(const TypeInfo_t *item_info, int n, char *args[])
+static List_t parse_list(const TypeInfo_t *item_info, int n, char *args[])
{
int64_t padded_size = item_info->size;
if ((padded_size % item_info->align) > 0)
padded_size = padded_size + item_info->align - (padded_size % item_info->align);
- Array_t items = {
+ List_t items = {
.stride=padded_size,
.length=n,
.data=GC_MALLOC((size_t)(padded_size*n)),
@@ -195,7 +195,7 @@ static Table_t parse_table(const TypeInfo_t *table, int n, char *args[])
if ((padded_size % key->align) > 0)
padded_size = padded_size + key->align - (padded_size % key->align);
- Array_t entries = {
+ List_t entries = {
.stride=padded_size,
.length=n,
.data=GC_MALLOC((size_t)(padded_size*n)),
@@ -254,7 +254,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
char after_name = argv[i][2+strlen(spec[s].name)];
if (after_name == '\0') { // --foo val
used_args[i] = true;
- if (non_opt_type->tag == ArrayInfo) {
+ if (non_opt_type->tag == ListInfo) {
int num_args = 0;
while (i + 1 + num_args < argc) {
if (argv[i+1+num_args][0] == '-')
@@ -263,7 +263,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
num_args += 1;
}
populated_args[s] = true;
- *(OptionalArray_t*)spec[s].dest = parse_array(non_opt_type->ArrayInfo.item, num_args, &argv[i+1]);
+ *(OptionalList_t*)spec[s].dest = parse_list(non_opt_type->ListInfo.item, num_args, &argv[i+1]);
} else if (non_opt_type->tag == TableInfo) {
int num_args = 0;
while (i + 1 + num_args < argc) {
@@ -313,7 +313,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
while (non_opt_type->tag == OptionalInfo)
non_opt_type = non_opt_type->OptionalInfo.type;
- if (non_opt_type->tag == ArrayInfo) {
+ if (non_opt_type->tag == ListInfo) {
if (f[1]) errx(1, "No value provided for -%c\n%k", *f, &usage);
int num_args = 0;
while (i + 1 + num_args < argc) {
@@ -323,7 +323,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
num_args += 1;
}
populated_args[s] = true;
- *(OptionalArray_t*)spec[s].dest = parse_array(non_opt_type->ArrayInfo.item, num_args, &argv[i+1]);
+ *(OptionalList_t*)spec[s].dest = parse_list(non_opt_type->ListInfo.item, num_args, &argv[i+1]);
} else if (non_opt_type->tag == TableInfo) {
int num_args = 0;
while (i + 1 + num_args < argc) {
@@ -389,7 +389,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
if (non_opt_type == &Bool$info)
goto next_non_bool_flag;
- if (non_opt_type->tag == ArrayInfo) {
+ if (non_opt_type->tag == ListInfo) {
int num_args = 0;
while (i + num_args < argc) {
if (!ignore_dashes && argv[i+num_args][0] == '-')
@@ -398,7 +398,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
num_args += 1;
}
populated_args[s] = true;
- *(OptionalArray_t*)spec[s].dest = parse_array(non_opt_type->ArrayInfo.item, num_args, &argv[i]);
+ *(OptionalList_t*)spec[s].dest = parse_list(non_opt_type->ListInfo.item, num_args, &argv[i]);
} else if (non_opt_type->tag == TableInfo) {
int num_args = 0;
while (i + num_args < argc) {
@@ -419,8 +419,8 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
for (int s = 0; s < spec_len; s++) {
if (!populated_args[s] && spec[s].required) {
- if (spec[s].type->tag == ArrayInfo)
- *(OptionalArray_t*)spec[s].dest = (Array_t){};
+ if (spec[s].type->tag == ListInfo)
+ *(OptionalList_t*)spec[s].dest = (List_t){};
else if (spec[s].type->tag == TableInfo)
*(OptionalTable_t*)spec[s].dest = (Table_t){};
else
diff --git a/stdlib/structs.c b/stdlib/structs.c
index 0b1385ee..933b3fb4 100644
--- a/stdlib/structs.c
+++ b/stdlib/structs.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include <string.h>
-#include "arrays.h"
+#include "lists.h"
#include "bools.h"
#include "functiontype.h"
#include "metamethods.h"
@@ -207,7 +207,7 @@ public void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, cons
}
}
-public void Struct$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void Struct$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type)
{
ptrdiff_t byte_offset = 0;
ptrdiff_t bit_offset = 0;
diff --git a/stdlib/structs.h b/stdlib/structs.h
index b027a01e..d1982456 100644
--- a/stdlib/structs.h
+++ b/stdlib/structs.h
@@ -15,7 +15,7 @@ PUREFUNC bool PackedData$equal(const void *x, const void *y, const TypeInfo_t *t
PUREFUNC Text_t Struct$as_text(const void *obj, bool colorize, const TypeInfo_t *type);
PUREFUNC bool Struct$is_none(const void *obj, const TypeInfo_t *type);
void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Struct$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type);
+void Struct$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type);
#define Struct$metamethods ((metamethods_t){ \
.hash=Struct$hash, \
diff --git a/stdlib/tables.c b/stdlib/tables.c
index 73a3af19..23932212 100644
--- a/stdlib/tables.c
+++ b/stdlib/tables.c
@@ -16,7 +16,7 @@
#include <string.h>
#include <sys/param.h>
-#include "arrays.h"
+#include "lists.h"
#include "c_strings.h"
#include "datatypes.h"
#include "memory.h"
@@ -102,7 +102,7 @@ static INLINE void hshow(const Table_t *t)
static void maybe_copy_on_write(Table_t *t, const TypeInfo_t *type)
{
if (t->entries.data_refcount != 0)
- Array$compact(&t->entries, (int64_t)entry_size(type));
+ List$compact(&t->entries, (int64_t)entry_size(type));
if (t->bucket_info && t->bucket_info->data_refcount != 0) {
size_t size = sizeof(bucket_info_t) + sizeof(bucket_t[t->bucket_info->count]);
@@ -276,7 +276,7 @@ public void *Table$reserve(Table_t *t, const void *key, const void *value, const
memcpy(buf + value_offset(type), value, (size_t)value_size);
else
memset(buf + value_offset(type), 0, (size_t)value_size);
- Array$insert(&t->entries, buf, I(0), (int64_t)entry_size(type));
+ List$insert(&t->entries, buf, I(0), (int64_t)entry_size(type));
int64_t entry_index = t->entries.length-1;
void *entry = GET_ENTRY(*t, entry_index);
@@ -344,7 +344,7 @@ public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type)
// instead of O(N)
int64_t last_entry = t->entries.length-1;
if (bucket->index != last_entry) {
- hdebug("Removing key/value from the middle of the entries array\n");
+ hdebug("Removing key/value from the middle of the entries list\n");
// Find the bucket that points to the last entry's index:
uint64_t i = HASH_KEY(*t, GET_ENTRY(*t, last_entry));
@@ -354,7 +354,7 @@ public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type)
// where the removed entry currently sits):
t->bucket_info->buckets[i].index = bucket->index;
- // Clobber the entry being removed (in the middle of the array) with
+ // Clobber the entry being removed (in the middle of the list) with
// the last entry:
memcpy(GET_ENTRY(*t, bucket->index), GET_ENTRY(*t, last_entry), entry_size(type));
}
@@ -362,7 +362,7 @@ public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type)
// Last entry is being removed, so clear it out to be safe:
memset(GET_ENTRY(*t, last_entry), 0, entry_size(type));
- Array$remove_at(&t->entries, I(t->entries.length), I(1), (int64_t)entry_size(type));
+ List$remove_at(&t->entries, I(t->entries.length), I(1), (int64_t)entry_size(type));
int64_t bucket_to_clear;
if (prev) { // Middle (or end) of a chain
@@ -400,7 +400,7 @@ public void Table$clear(Table_t *t)
public Table_t Table$sorted(Table_t t, const TypeInfo_t *type)
{
Closure_t cmp = (Closure_t){.fn=generic_compare, .userdata=(void*)type->TableInfo.key};
- Array_t entries = Array$sorted(t.entries, cmp, (int64_t)entry_size(type));
+ List_t entries = List$sorted(t.entries, cmp, (int64_t)entry_size(type));
return Table$from_entries(entries, type);
}
@@ -446,10 +446,10 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type
// Table comparison rules:
// - If two tables have different keys, then compare as if comparing a
- // sorted array of the keys of the two tables:
+ // sorted list of the keys of the two tables:
// `x.keys:sorted() <> y.keys:sorted()`
- // - Otherwise, compare as if comparing arrays of values for the sorted key
- // arrays:
+ // - Otherwise, compare as if comparing lists of values for the sorted key
+ // lists:
// `[x[k] for k in x.keys:sorted()] <> [y[k] for k in y.keys:sorted()]`
//
// We can do this in _linear_ time if we find the smallest `k` such that
@@ -613,7 +613,7 @@ public Text_t Table$as_text(const void *obj, bool colorize, const TypeInfo_t *ty
return text;
}
-public Table_t Table$from_entries(Array_t entries, const TypeInfo_t *type)
+public Table_t Table$from_entries(List_t entries, const TypeInfo_t *type)
{
assert(type->tag == TableInfo);
if (entries.length == 0)
@@ -775,7 +775,7 @@ public void Table$serialize(const void *obj, FILE *out, Table_t *pointers, const
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstack-protector"
-public void Table$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type)
+public void Table$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type)
{
int64_t len;
Int64$deserialize(in, &len, pointers, &Int$info);
diff --git a/stdlib/tables.h b/stdlib/tables.h
index 405cc7df..84686250 100644
--- a/stdlib/tables.h
+++ b/stdlib/tables.h
@@ -6,14 +6,14 @@
#include <stdbool.h>
#include <string.h>
-#include "arrays.h"
+#include "lists.h"
#include "datatypes.h"
#include "types.h"
#include "util.h"
#define Table(key_t, val_t, key_info, value_info, fb, N, ...) ({ \
struct { key_t k; val_t v; } ents[N] = {__VA_ARGS__}; \
- Table_t table = Table$from_entries((Array_t){ \
+ Table_t table = Table$from_entries((List_t){ \
.data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \
.length=sizeof(ents)/sizeof(ents[0]), \
.stride=(void*)&ents[1] - (void*)&ents[0], \
@@ -22,14 +22,14 @@
table; })
#define Set(item_t, item_info, N, ...) ({ \
item_t ents[N] = {__VA_ARGS__}; \
- Table_t set = Table$from_entries((Array_t){ \
+ Table_t set = Table$from_entries((List_t){ \
.data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \
.length=sizeof(ents)/sizeof(ents[0]), \
.stride=(void*)&ents[1] - (void*)&ents[0], \
}, Set$info(item_info)); \
set; })
-Table_t Table$from_entries(Array_t entries, const TypeInfo_t *type);
+Table_t Table$from_entries(List_t entries, const TypeInfo_t *type);
void *Table$get(Table_t t, const void *key, const TypeInfo_t *type);
#define Table$get_optional(table_expr, key_t, val_t, key_expr, nonnull_var, nonnull_expr, null_expr, info_expr) ({ \
const Table_t t = table_expr; const key_t k = key_expr; \
@@ -71,7 +71,7 @@ PUREFUNC bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const Type
void Table$clear(Table_t *t);
Table_t Table$sorted(Table_t t, const TypeInfo_t *type);
void Table$mark_copy_on_write(Table_t *t);
-#define TABLE_INCREF(t) ({ ARRAY_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info->data_refcount += ((t).bucket_info->data_refcount < TABLE_MAX_DATA_REFCOUNT); })
+#define TABLE_INCREF(t) ({ LIST_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info->data_refcount += ((t).bucket_info->data_refcount < TABLE_MAX_DATA_REFCOUNT); })
#define TABLE_COPY(t) ({ TABLE_INCREF(t); t; })
PUREFUNC int32_t Table$compare(const void *x, const void *y, const TypeInfo_t *type);
PUREFUNC bool Table$equal(const void *x, const void *y, const TypeInfo_t *type);
@@ -86,7 +86,7 @@ void Table$str_set(Table_t *t, const char *key, const void *value);
void *Table$str_reserve(Table_t *t, const char *key, const void *value);
void Table$str_remove(Table_t *t, const char *key);
void Table$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type);
-void Table$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type);
+void Table$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type);
#define Table$length(t) ((t).entries.length)
diff --git a/stdlib/text.c b/stdlib/text.c
index adbac3f0..d828270c 100644
--- a/stdlib/text.c
+++ b/stdlib/text.c
@@ -27,7 +27,7 @@
// is basically what Zalgo text is).
//
// There are a lot of benefits to storing unicode text with one grapheme
-// cluster per index in a densely packed array instead of storing the text as
+// cluster per index in a densely packed list instead of storing the text as
// variable-width UTF8-encoded bytes. It lets us have one canonical length for
// the text that can be precomputed and is meaningful to users. It lets us
// quickly get the Nth "letter" in the text. Substring slicing is fast.
@@ -38,7 +38,7 @@
// Graphemes, aka NFG). A synthetic grapheme is a negative 32-bit signed
// integer that represents a multi-codepoint grapheme cluster that has been
// encountered during the program's runtime. These clusters are stored in a
-// lookup array and hash map so that we can rapidly convert between the
+// lookup list and hash map so that we can rapidly convert between the
// synthetic grapheme integer ID and the unicode codepoints associated with it.
// Essentially, it's like we create a supplement to the unicode standard with
// things that would be nice if they had their own codepoint so things worked
@@ -49,7 +49,7 @@
// WITH ACUTE This would be stored as: (int32_t[]){0x48, 0xE9} Example 2:
// U+0048, U+0065, U+0309 AKA: LATIN CAPITAL LETTER H, LATIN SMALL LETTER E,
// COMBINING VERTICAL LINE BELOW This would be stored as: (int32_t[]){0x48, -2}
-// Where -2 is used as a lookup in an array that holds the actual unicode
+// Where -2 is used as a lookup in an list that holds the actual unicode
// codepoints: (ucs4_t[]){0x65, 0x0309}
#include <assert.h>
@@ -67,7 +67,7 @@
#include <unigbrk.h>
#include <uniname.h>
-#include "arrays.h"
+#include "lists.h"
#include "integers.h"
#include "patterns.h"
#include "tables.h"
@@ -86,7 +86,7 @@ typedef struct {
// Synthetic grapheme clusters (clusters of more than one codepoint):
static Table_t grapheme_ids_by_codepoints = {}; // ucs4_t* length-prefixed codepoints -> int32_t ID
-// This will hold a dynamically growing array of synthetic graphemes:
+// This will hold a dynamically growing list of synthetic graphemes:
static synthetic_grapheme_t *synthetic_graphemes = NULL;
static int32_t synthetic_grapheme_capacity = 0;
static int32_t num_synthetic_graphemes = 0;
@@ -697,7 +697,7 @@ Text_t text_from_u32(ucs4_t *codepoints, int64_t num_codepoints, bool normalize)
// Intentionally overallocate here: allocate assuming each codepoint is a
// grapheme cluster. If that's not true, we'll have extra space at the end
- // of the array, but the length will still be calculated correctly.
+ // of the list, but the length will still be calculated correctly.
int32_t *graphemes = GC_MALLOC_ATOMIC(sizeof(int32_t[num_codepoints]));
struct Text_s ret = {
.tag=TEXT_GRAPHEMES,
@@ -1038,7 +1038,7 @@ PUREFUNC public bool Text$equal_ignoring_case(Text_t a, Text_t b, Text_t languag
public Text_t Text$upper(Text_t text, Text_t language)
{
if (text.length == 0) return text;
- Array_t codepoints = Text$utf32_codepoints(text);
+ List_t codepoints = Text$utf32_codepoints(text);
const char *uc_language = Text$as_c_string(language);
ucs4_t buf[128];
size_t out_len = sizeof(buf)/sizeof(buf[0]);
@@ -1051,7 +1051,7 @@ public Text_t Text$upper(Text_t text, Text_t language)
public Text_t Text$lower(Text_t text, Text_t language)
{
if (text.length == 0) return text;
- Array_t codepoints = Text$utf32_codepoints(text);
+ List_t codepoints = Text$utf32_codepoints(text);
const char *uc_language = Text$as_c_string(language);
ucs4_t buf[128];
size_t out_len = sizeof(buf)/sizeof(buf[0]);
@@ -1064,7 +1064,7 @@ public Text_t Text$lower(Text_t text, Text_t language)
public Text_t Text$title(Text_t text, Text_t language)
{
if (text.length == 0) return text;
- Array_t codepoints = Text$utf32_codepoints(text);
+ List_t codepoints = Text$utf32_codepoints(text);
const char *uc_language = Text$as_c_string(language);
ucs4_t buf[128];
size_t out_len = sizeof(buf)/sizeof(buf[0]);
@@ -1233,7 +1233,7 @@ public Text_t Text$quoted(Text_t text, bool colorize)
return _quoted(text, colorize, '"');
}
-public Text_t Text$join(Text_t glue, Array_t pieces)
+public Text_t Text$join(Text_t glue, List_t pieces)
{
if (pieces.length == 0) return EMPTY_TEXT;
@@ -1259,38 +1259,38 @@ public Text_t Text$format(const char *fmt, ...)
return ret;
}
-public Array_t Text$clusters(Text_t text)
+public List_t Text$clusters(Text_t text)
{
- Array_t clusters = {};
+ List_t clusters = {};
for (int64_t i = 1; i <= text.length; i++) {
Text_t cluster = Text$slice(text, I(i), I(i));
- Array$insert(&clusters, &cluster, I_small(0), sizeof(Text_t));
+ List$insert(&clusters, &cluster, I_small(0), sizeof(Text_t));
}
return clusters;
}
-public Array_t Text$utf32_codepoints(Text_t text)
+public List_t Text$utf32_codepoints(Text_t text)
{
- Array_t codepoints = {.atomic=1};
+ List_t codepoints = {.atomic=1};
TextIter_t state = NEW_TEXT_ITER_STATE(text);
for (int64_t i = 0; i < text.length; i++) {
int32_t grapheme = Text$get_grapheme_fast(&state, i);
if (grapheme < 0) {
for (int64_t c = 0; c < NUM_GRAPHEME_CODEPOINTS(grapheme); c++) {
ucs4_t subg = GRAPHEME_CODEPOINTS(grapheme)[c];
- Array$insert(&codepoints, &subg, I_small(0), sizeof(ucs4_t));
+ List$insert(&codepoints, &subg, I_small(0), sizeof(ucs4_t));
}
} else {
- Array$insert(&codepoints, &grapheme, I_small(0), sizeof(ucs4_t));
+ List$insert(&codepoints, &grapheme, I_small(0), sizeof(ucs4_t));
}
}
return codepoints;
}
-public Array_t Text$utf8_bytes(Text_t text)
+public List_t Text$utf8_bytes(Text_t text)
{
const char *str = Text$as_c_string(text);
- return (Array_t){.length=strlen(str), .stride=1, .atomic=1, .data=(void*)str};
+ return (List_t){.length=strlen(str), .stride=1, .atomic=1, .data=(void*)str};
}
static INLINE const char *codepoint_name(ucs4_t c)
@@ -1304,9 +1304,9 @@ static INLINE const char *codepoint_name(ucs4_t c)
return name;
}
-public Array_t Text$codepoint_names(Text_t text)
+public List_t Text$codepoint_names(Text_t text)
{
- Array_t names = {};
+ List_t names = {};
TextIter_t state = NEW_TEXT_ITER_STATE(text);
for (int64_t i = 0; i < text.length; i++) {
int32_t grapheme = Text$get_grapheme_fast(&state, i);
@@ -1314,65 +1314,65 @@ public Array_t Text$codepoint_names(Text_t text)
for (int64_t c = 0; c < NUM_GRAPHEME_CODEPOINTS(grapheme); c++) {
const char *name = codepoint_name(GRAPHEME_CODEPOINTS(grapheme)[c]);
Text_t name_text = Text$from_str(name);
- Array$insert(&names, &name_text, I_small(0), sizeof(Text_t));
+ List$insert(&names, &name_text, I_small(0), sizeof(Text_t));
}
} else {
const char *name = codepoint_name((ucs4_t)grapheme);
Text_t name_text = Text$from_str(name);
- Array$insert(&names, &name_text, I_small(0), sizeof(Text_t));
+ List$insert(&names, &name_text, I_small(0), sizeof(Text_t));
}
}
return names;
}
-public Text_t Text$from_codepoints(Array_t codepoints)
+public Text_t Text$from_codepoints(List_t codepoints)
{
if (codepoints.stride != sizeof(int32_t))
- Array$compact(&codepoints, sizeof(int32_t));
+ List$compact(&codepoints, sizeof(int32_t));
return text_from_u32(codepoints.data, codepoints.length, true);
}
-public OptionalText_t Text$from_codepoint_names(Array_t codepoint_names)
+public OptionalText_t Text$from_codepoint_names(List_t codepoint_names)
{
- Array_t codepoints = {};
+ List_t codepoints = {};
for (int64_t i = 0; i < codepoint_names.length; i++) {
Text_t *name = ((Text_t*)(codepoint_names.data + i*codepoint_names.stride));
const char *name_str = Text$as_c_string(*name);
ucs4_t codepoint = unicode_name_character(name_str);
if (codepoint == UNINAME_INVALID)
return NONE_TEXT;
- Array$insert(&codepoints, &codepoint, I_small(0), sizeof(ucs4_t));
+ List$insert(&codepoints, &codepoint, I_small(0), sizeof(ucs4_t));
}
return Text$from_codepoints(codepoints);
}
-public OptionalText_t Text$from_bytes(Array_t bytes)
+public OptionalText_t Text$from_bytes(List_t bytes)
{
if (bytes.stride != sizeof(int8_t))
- Array$compact(&bytes, sizeof(int8_t));
+ List$compact(&bytes, sizeof(int8_t));
return Text$from_strn(bytes.data, (size_t)bytes.length);
}
-public Array_t Text$lines(Text_t text)
+public List_t Text$lines(Text_t text)
{
- Array_t lines = {};
+ List_t lines = {};
TextIter_t state = NEW_TEXT_ITER_STATE(text);
for (int64_t i = 0, line_start = 0; i < text.length; i++) {
int32_t grapheme = Text$get_grapheme_fast(&state, i);
if (grapheme == '\r' && Text$get_grapheme_fast(&state, i + 1) == '\n') { // CRLF
Text_t line = Text$slice(text, I(line_start+1), I(i));
- Array$insert(&lines, &line, I_small(0), sizeof(Text_t));
+ List$insert(&lines, &line, I_small(0), sizeof(Text_t));
i += 1; // skip one extra for CR
line_start = i + 1;
} else if (grapheme == '\n') { // newline
Text_t line = Text$slice(text, I(line_start+1), I(i));
- Array$insert(&lines, &line, I_small(0), sizeof(Text_t));
+ List$insert(&lines, &line, I_small(0), sizeof(Text_t));
line_start = i + 1;
} else if (i == text.length-1 && line_start != i) { // last line
Text_t line = Text$slice(text, I(line_start+1), I(i+1));
- Array$insert(&lines, &line, I_small(0), sizeof(Text_t));
+ List$insert(&lines, &line, I_small(0), sizeof(Text_t));
}
}
return lines;
@@ -1426,7 +1426,7 @@ public void Text$serialize(const void *obj, FILE *out, Table_t *pointers, const
fwrite(str, sizeof(char), (size_t)len, out);
}
-public void Text$deserialize(FILE *in, void *out, Array_t *pointers, const TypeInfo_t *)
+public void Text$deserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *)
{
int64_t len = -1;
Int64$deserialize(in, &len, pointers, &Int64$info);
diff --git a/stdlib/text.h b/stdlib/text.h
index 9923403c..bc961192 100644
--- a/stdlib/text.h
+++ b/stdlib/text.h
@@ -57,16 +57,16 @@ PUREFUNC bool Text$ends_with(Text_t text, Text_t suffix);
char *Text$as_c_string(Text_t text);
__attribute__((format(printf, 1, 2)))
public Text_t Text$format(const char *fmt, ...);
-Array_t Text$clusters(Text_t text);
-Array_t Text$utf32_codepoints(Text_t text);
-Array_t Text$utf8_bytes(Text_t text);
-Array_t Text$codepoint_names(Text_t text);
-Text_t Text$from_codepoints(Array_t codepoints);
-OptionalText_t Text$from_codepoint_names(Array_t codepoint_names);
-OptionalText_t Text$from_bytes(Array_t bytes);
-Array_t Text$lines(Text_t text);
+List_t Text$clusters(Text_t text);
+List_t Text$utf32_codepoints(Text_t text);
+List_t Text$utf8_bytes(Text_t text);
+List_t Text$codepoint_names(Text_t text);
+Text_t Text$from_codepoints(List_t codepoints);
+OptionalText_t Text$from_codepoint_names(List_t codepoint_names);
+OptionalText_t Text$from_bytes(List_t bytes);
+List_t Text$lines(Text_t text);
Closure_t Text$by_line(Text_t text);
-Text_t Text$join(Text_t glue, Array_t pieces);
+Text_t Text$join(Text_t glue, List_t pieces);
Text_t Text$repeat(Text_t text, Int_t count);
Text_t Text$left_pad(Text_t text, Int_t count, Text_t padding);
Text_t Text$right_pad(Text_t text, Int_t count, Text_t padding);
@@ -74,7 +74,7 @@ Text_t Text$middle_pad(Text_t text, Int_t count, Text_t padding);
int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index);
uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index);
void Text$serialize(const void *obj, FILE *out, Table_t *, const TypeInfo_t *);
-void Text$deserialize(FILE *in, void *out, Array_t *, const TypeInfo_t *);
+void Text$deserialize(FILE *in, void *out, List_t *, const TypeInfo_t *);
MACROLIKE int32_t Text$get_grapheme(Text_t text, int64_t index)
{
diff --git a/stdlib/threads.c b/stdlib/threads.c
index efd23546..fe55c5c8 100644
--- a/stdlib/threads.c
+++ b/stdlib/threads.c
@@ -12,7 +12,7 @@
#include <sys/param.h>
#include <sys/random.h>
-#include "arrays.h"
+#include "lists.h"
#include "datatypes.h"
#include "metamethods.h"
#include "rng.h"
@@ -25,7 +25,7 @@ static void *run_thread(Closure_t *closure)
{
uint8_t *random_bytes = GC_MALLOC_ATOMIC(40);
getrandom(random_bytes, 40, 0);
- Array_t rng_seed = {.length=40, .data=random_bytes, .stride=1, .atomic=1};
+ List_t rng_seed = {.length=40, .data=random_bytes, .stride=1, .atomic=1};
default_rng = RNG$new(rng_seed);
((void(*)(void*))closure->fn)(closure->userdata);
return NULL;
diff --git a/stdlib/tomo.h b/stdlib/tomo.h
index 61dba404..01e668fe 100644
--- a/stdlib/tomo.h
+++ b/stdlib/tomo.h
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <sys/param.h>
-#include "arrays.h"
+#include "lists.h"
#include "bools.h"
#include "bytes.h"
#include "c_strings.h"
diff --git a/stdlib/types.c b/stdlib/types.c
index 8ced9051..0f51d6ea 100644
--- a/stdlib/types.c
+++ b/stdlib/types.c
@@ -6,7 +6,7 @@
#include <sys/param.h>
#include "util.h"
-#include "arrays.h"
+#include "lists.h"
#include "pointers.h"
#include "tables.h"
#include "text.h"
diff --git a/stdlib/types.h b/stdlib/types.h
index c7b938a0..45ad39c5 100644
--- a/stdlib/types.h
+++ b/stdlib/types.h
@@ -17,7 +17,7 @@ typedef struct {
Text_t (*as_text)(const void*, bool, const TypeInfo_t*);
bool (*is_none)(const void*, const TypeInfo_t*);
void (*serialize)(const void*, FILE*, Table_t*, const TypeInfo_t*);
- void (*deserialize)(FILE*, void*, Array_t*, const TypeInfo_t*);
+ void (*deserialize)(FILE*, void*, List_t*, const TypeInfo_t*);
} metamethods_t;
typedef struct {
@@ -29,7 +29,7 @@ struct TypeInfo_s {
int64_t size, align;
metamethods_t metamethods;
struct { // Anonymous tagged union for convenience
- enum { OpaqueInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ArrayInfo, TableInfo, FunctionInfo,
+ enum { OpaqueInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ListInfo, TableInfo, FunctionInfo,
OptionalInfo, MutexedDataInfo, TypeInfoInfo } tag;
union {
struct {} OpaqueInfo;
@@ -42,7 +42,7 @@ struct TypeInfo_s {
} TextInfo;
struct {
const TypeInfo_t *item;
- } ArrayInfo;
+ } ListInfo;
struct {
const TypeInfo_t *key, *value;
} TableInfo;
diff --git a/test/arrays.tm b/test/lists.tm
index 30a0a2c7..1cf83285 100644
--- a/test/arrays.tm
+++ b/test/lists.tm
@@ -144,7 +144,7 @@ func main():
>> [i*10 for i in 10]:by(2):by(-1)
= [90, 70, 50, 30, 10]
- # Test iterating over array:from() and array:to()
+ # Test iterating over list:from() and list:to()
xs := ["A", "B", "C", "D"]
for i,x in xs:to(-2):
for y in xs:from(i+1):
diff --git a/test/optionals.tm b/test/optionals.tm
index f5d26707..4af465b4 100644
--- a/test/optionals.tm
+++ b/test/optionals.tm
@@ -25,7 +25,7 @@ func maybe_int64(should_i:Bool->Int64?):
else:
return none
-func maybe_array(should_i:Bool-> List(Int)?):
+func maybe_list(should_i:Bool-> List(Int)?):
if should_i:
return [10, 20, 30]
else:
@@ -126,10 +126,10 @@ func main():
do:
!! ...
- !! Arrays:
- >> yep := maybe_array(yes)
+ !! Lists:
+ >> yep := maybe_list(yes)
= [10, 20, 30] : List(Int)?
- >> nope := maybe_array(no)
+ >> nope := maybe_list(no)
= none : List(Int)?
>> if yep:
>> yep
diff --git a/test/rng.tm b/test/rng.tm
index fe3d9f75..d010e3ba 100644
--- a/test/rng.tm
+++ b/test/rng.tm
@@ -30,7 +30,7 @@ func main():
>> rng:num32(1, 1000)
= 761.05908 : Num32
- !! Random array methods:
+ !! Random list methods:
>> nums := [10*i for i in 10]
>> nums:shuffled(rng=rng)
= [30, 50, 100, 20, 90, 10, 80, 40, 70, 60]
diff --git a/tomo.c b/tomo.c
index 1115c43c..88dfc4a5 100644
--- a/tomo.c
+++ b/tomo.c
@@ -15,7 +15,7 @@
#include "cordhelpers.h"
#include "parse.h"
#include "repl.h"
-#include "stdlib/arrays.h"
+#include "stdlib/lists.h"
#include "stdlib/bools.h"
#include "stdlib/datatypes.h"
#include "stdlib/integers.h"
@@ -27,9 +27,9 @@
#include "types.h"
#define run_cmd(...) ({ const char *_cmd = heap_strf(__VA_ARGS__); if (verbose) puts(_cmd); popen(_cmd, "w"); })
-#define array_str(arr) Text$as_c_string(Text$join(Text(" "), arr))
+#define list_str(arr) Text$as_c_string(Text$join(Text(" "), arr))
-static const char *paths_str(Array_t paths) {
+static const char *paths_str(List_t paths) {
Text_t result = EMPTY_TEXT;
for (int64_t i = 0; i < paths.length; i++) {
if (i > 0) result = Texts(result, Text(" "));
@@ -38,10 +38,10 @@ static const char *paths_str(Array_t paths) {
return Text$as_c_string(result);
}
-static OptionalArray_t files = NONE_ARRAY,
- args = NONE_ARRAY,
- uninstall = NONE_ARRAY,
- libraries = NONE_ARRAY;
+static OptionalList_t files = NONE_LIST,
+ args = NONE_LIST,
+ uninstall = NONE_LIST,
+ libraries = NONE_LIST;
static OptionalBool_t verbose = false,
stop_at_transpile = false,
stop_at_obj_compilation = false,
@@ -64,11 +64,11 @@ static OptionalText_t
static void transpile_header(env_t *base_env, Path_t path, bool force_retranspile);
static void transpile_code(env_t *base_env, Path_t path, bool force_retranspile);
static void compile_object_file(Path_t path, bool force_recompile);
-static Path_t compile_executable(env_t *base_env, Path_t path, Array_t object_files, Array_t extra_ldlibs);
+static Path_t compile_executable(env_t *base_env, Path_t path, List_t object_files, List_t extra_ldlibs);
static void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_link);
static Text_t escape_lib_name(Text_t lib_name);
static void build_library(Text_t lib_dir_name);
-static void compile_files(env_t *env, Array_t files, bool only_compile_arguments, Array_t *object_files, Array_t *ldlibs);
+static void compile_files(env_t *env, List_t files, bool only_compile_arguments, List_t *object_files, List_t *ldlibs);
static bool is_stale(Path_t path, Path_t relative_to);
#pragma GCC diagnostic push
@@ -108,8 +108,8 @@ int main(int argc, char *argv[])
Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage);
tomo_parse_args(
argc, argv, usage, help,
- {"files", true, Array$info(&Path$info), &files},
- {"args", true, Array$info(&Text$info), &args},
+ {"files", true, List$info(&Path$info), &files},
+ {"args", true, List$info(&Text$info), &args},
{"verbose", false, &Bool$info, &verbose},
{"v", false, &Bool$info, &verbose},
{"transpile", false, &Bool$info, &stop_at_transpile},
@@ -118,10 +118,10 @@ int main(int argc, char *argv[])
{"c", false, &Bool$info, &stop_at_obj_compilation},
{"compile-exe", false, &Bool$info, &stop_at_exe_compilation},
{"e", false, &Bool$info, &stop_at_exe_compilation},
- {"uninstall", false, Array$info(&Text$info), &uninstall},
- {"u", false, Array$info(&Text$info), &uninstall},
- {"library", false, Array$info(&Path$info), &libraries},
- {"L", false, Array$info(&Path$info), &libraries},
+ {"uninstall", false, List$info(&Text$info), &uninstall},
+ {"u", false, List$info(&Text$info), &uninstall},
+ {"library", false, List$info(&Path$info), &libraries},
+ {"L", false, List$info(&Path$info), &libraries},
{"show-codegen", false, &Text$info, &show_codegen},
{"C", false, &Text$info, &show_codegen},
{"repl", false, &Bool$info, &run_repl},
@@ -175,7 +175,7 @@ int main(int argc, char *argv[])
errx(1, "Too many files specified!");
Path_t path = *(Path_t*)files.data;
env_t *env = new_compilation_unit(NULL);
- Array_t object_files = {},
+ List_t object_files = {},
extra_ldlibs = {};
compile_files(env, files, false, &object_files, &extra_ldlibs);
Path_t exe_name = compile_executable(env, path, object_files, extra_ldlibs);
@@ -188,7 +188,7 @@ int main(int argc, char *argv[])
errx(1, "Failed to run compiled program");
} else {
env_t *env = new_compilation_unit(NULL);
- Array_t object_files = {},
+ List_t object_files = {},
extra_ldlibs = {};
compile_files(env, files, stop_at_obj_compilation, &object_files, &extra_ldlibs);
if (stop_at_obj_compilation)
@@ -310,9 +310,9 @@ static void _compile_file_header_for_library(env_t *env, Path_t path, Table_t *v
void build_library(Text_t lib_dir_name)
{
- Array_t tm_files = Path$glob(Path("./[!._0-9]*.tm"));
+ List_t tm_files = Path$glob(Path("./[!._0-9]*.tm"));
env_t *env = new_compilation_unit(NULL);
- Array_t object_files = {},
+ List_t object_files = {},
extra_ldlibs = {};
compile_files(env, tm_files, false, &object_files, &extra_ldlibs);
@@ -348,7 +348,7 @@ void build_library(Text_t lib_dir_name)
}
prog = run_cmd("%k -O%k %k %k %k %s -Wl,-soname='lib%k.so' -shared %s -o 'lib%k.so'",
- &cc, &optimization, &cflags, &ldflags, &ldlibs, array_str(extra_ldlibs), &lib_dir_name,
+ &cc, &optimization, &cflags, &ldflags, &ldlibs, list_str(extra_ldlibs), &lib_dir_name,
paths_str(object_files), &lib_dir_name);
if (!prog)
errx(1, "Failed to run C compiler: %k", &cc);
@@ -389,7 +389,7 @@ void build_library(Text_t lib_dir_name)
}
}
-void compile_files(env_t *env, Array_t to_compile, bool only_compile_arguments, Array_t *object_files, Array_t *extra_ldlibs)
+void compile_files(env_t *env, List_t to_compile, bool only_compile_arguments, List_t *object_files, List_t *extra_ldlibs)
{
TypeInfo_t *path_table_info = Table$info(&Path$info, &Path$info);
Table_t to_link = {};
@@ -454,13 +454,13 @@ void compile_files(env_t *env, Array_t to_compile, bool only_compile_arguments,
for (int64_t i = 0; i < dependency_files.entries.length; i++) {
Path_t path = *(Path_t*)(dependency_files.entries.data + i*dependency_files.entries.stride);
path = build_file(path, ".o");
- Array$insert(object_files, &path, I(0), sizeof(Path_t));
+ List$insert(object_files, &path, I(0), sizeof(Path_t));
}
}
if (extra_ldlibs) {
for (int64_t i = 0; i < to_link.entries.length; i++) {
Text_t lib = *(Text_t*)(to_link.entries.data + i*to_link.entries.stride);
- Array$insert(extra_ldlibs, &lib, I(0), sizeof(Text_t));
+ List$insert(extra_ldlibs, &lib, I(0), sizeof(Text_t));
}
}
}
@@ -503,7 +503,7 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l
Text_t lib = Text$format("'%s/.local/share/tomo/installed/%s/lib%s.so'", getenv("HOME"), use->path, use->path);
Table$set(to_link, &lib, ((Bool_t[1]){1}), Table$info(&Text$info, &Bool$info));
- Array_t children = Path$glob(Path$from_str(heap_strf("%s/.local/share/tomo/installed/%s/*.tm", getenv("HOME"), use->path)));
+ List_t children = Path$glob(Path$from_str(heap_strf("%s/.local/share/tomo/installed/%s/*.tm", getenv("HOME"), use->path)));
for (int64_t i = 0; i < children.length; i++) {
Path_t *child = (Path_t*)(children.data + i*children.stride);
Table_t discarded = {.fallback=to_compile};
@@ -635,7 +635,7 @@ void compile_object_file(Path_t path, bool force_recompile)
printf("\x1b[2mCompiled to %s\x1b[m\n", Path$as_c_string(obj_file));
}
-Path_t compile_executable(env_t *base_env, Path_t path, Array_t object_files, Array_t extra_ldlibs)
+Path_t compile_executable(env_t *base_env, Path_t path, List_t object_files, List_t extra_ldlibs)
{
ast_t *ast = parse_file(Path$as_c_string(path), NULL);
if (!ast)
@@ -648,7 +648,7 @@ Path_t compile_executable(env_t *base_env, Path_t path, Array_t object_files, Ar
Path_t bin_name = Path$with_extension(path, Text(""), true);
FILE *runner = run_cmd("%k %k -O%k %k %k %s %s -x c - -o %s",
&cc, &cflags, &optimization, &ldflags, &ldlibs,
- array_str(extra_ldlibs), paths_str(object_files), Path$as_c_string(bin_name));
+ list_str(extra_ldlibs), paths_str(object_files), Path$as_c_string(bin_name));
CORD program = CORD_all(
"extern int ", main_binding->code, "$parse_and_run(int argc, char *argv[]);\n"
"int main(int argc, char *argv[]) {\n"
diff --git a/typecheck.c b/typecheck.c
index 0d0690bb..1118add2 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -50,26 +50,26 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
code_err(ast, "Void pointers are not supported. You probably meant 'Memory' instead of 'Void'");
return Type(PointerType, .pointed=pointed_t, .is_stack=ptr->is_stack);
}
- case ArrayTypeAST: {
- type_ast_t *item_type = Match(ast, ArrayTypeAST)->item;
+ case ListTypeAST: {
+ type_ast_t *item_type = Match(ast, ListTypeAST)->item;
type_t *item_t = parse_type_ast(env, item_type);
if (!item_t) code_err(item_type, "I can't figure out what this type is.");
if (has_stack_memory(item_t))
- code_err(item_type, "Arrays can't have stack references because the array may outlive the stack frame.");
- if (type_size(item_t) > ARRAY_MAX_STRIDE)
- code_err(ast, "This array holds items that take up %ld bytes, but the maximum supported size is %ld bytes. Consider using an array of pointers instead.",
- type_size(item_t), ARRAY_MAX_STRIDE);
- return Type(ArrayType, .item_type=item_t);
+ code_err(item_type, "Lists can't have stack references because the list may outlive the stack frame.");
+ if (type_size(item_t) > LIST_MAX_STRIDE)
+ code_err(ast, "This list holds items that take up %ld bytes, but the maximum supported size is %ld bytes. Consider using an list of pointers instead.",
+ type_size(item_t), LIST_MAX_STRIDE);
+ return Type(ListType, .item_type=item_t);
}
case SetTypeAST: {
type_ast_t *item_type = Match(ast, SetTypeAST)->item;
type_t *item_t = parse_type_ast(env, item_type);
if (!item_t) code_err(item_type, "I can't figure out what this type is.");
if (has_stack_memory(item_t))
- code_err(item_type, "Sets can't have stack references because the array may outlive the stack frame.");
- if (type_size(item_t) > ARRAY_MAX_STRIDE)
+ code_err(item_type, "Sets can't have stack references because the list may outlive the stack frame.");
+ if (type_size(item_t) > LIST_MAX_STRIDE)
code_err(ast, "This set holds items that take up %ld bytes, but the maximum supported size is %ld bytes. Consider using an set of pointers instead.",
- type_size(item_t), ARRAY_MAX_STRIDE);
+ type_size(item_t), LIST_MAX_STRIDE);
return Type(SetType, .item_type=item_t);
}
case TableTypeAST: {
@@ -78,12 +78,12 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
type_t *key_type = parse_type_ast(env, key_type_ast);
if (!key_type) code_err(key_type_ast, "I can't figure out what type this is.");
if (has_stack_memory(key_type))
- code_err(key_type_ast, "Tables can't have stack references because the array may outlive the stack frame.");
+ code_err(key_type_ast, "Tables can't have stack references because the list may outlive the stack frame.");
if (table_type->value) {
type_t *val_type = parse_type_ast(env, table_type->value);
if (!val_type) code_err(table_type->value, "I can't figure out what type this is.");
if (has_stack_memory(val_type))
- code_err(table_type->value, "Tables can't have stack references because the array may outlive the stack frame.");
+ code_err(table_type->value, "Tables can't have stack references because the list may outlive the stack frame.");
else if (val_type->tag == OptionalType)
code_err(ast, "Tables with optional-typed values are not currently supported");
return Type(TableType, .key_type=key_type, .value_type=val_type, .env=env);
@@ -92,7 +92,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
.value_type=get_type(env, table_type->default_value), .default_value=table_type->default_value,
.env=env);
if (has_stack_memory(t))
- code_err(ast, "Tables can't have stack references because the array may outlive the stack frame.");
+ code_err(ast, "Tables can't have stack references because the list may outlive the stack frame.");
return t;
} else {
code_err(ast, "No value type or default value!");
@@ -319,7 +319,7 @@ void bind_statement(env_t *env, ast_t *statement)
get_line_number(statement->file, statement->start));
binding_t binding = {.type=type, .code=code};
env_t *type_ns = get_namespace_by_type(env, ret_t);
- Array$insert(&type_ns->namespace->constructors, &binding, I(0), sizeof(binding));
+ List$insert(&type_ns->namespace->constructors, &binding, I(0), sizeof(binding));
break;
}
case StructDef: {
@@ -628,7 +628,7 @@ type_t *get_type(env_t *env, ast_t *ast)
code_err(ast, "'&' stack references can only be used on the fields of pointers and local variables");
}
case Index:
- code_err(ast, "'&' stack references are not supported for array or table indexing");
+ code_err(ast, "'&' stack references are not supported for list or table indexing");
default:
return Type(PointerType, .pointed=get_type(env, value), .is_stack=true);
}
@@ -666,13 +666,13 @@ type_t *get_type(env_t *env, ast_t *ast)
if (b) return b->type;
code_err(ast, "I don't know what \"%s\" refers to", var->name);
}
- case Array: {
- auto array = Match(ast, Array);
+ case List: {
+ auto list = Match(ast, List);
type_t *item_type = NULL;
- if (array->item_type) {
- item_type = parse_type_ast(env, array->item_type);
- } else if (array->items) {
- for (ast_list_t *item = array->items; item; item = item->next) {
+ if (list->item_type) {
+ item_type = parse_type_ast(env, list->item_type);
+ } else if (list->items) {
+ for (ast_list_t *item = list->items; item; item = item->next) {
ast_t *item_ast = item->ast;
env_t *scope = env;
while (item_ast->tag == Comprehension) {
@@ -685,16 +685,16 @@ type_t *get_type(env_t *env, ast_t *ast)
type_t *merged = item_type ? type_or_type(item_type, t2) : t2;
if (!merged)
code_err(item->ast,
- "This array item has type %T, which is different from earlier array items which have type %T",
+ "This list item has type %T, which is different from earlier list items which have type %T",
t2, item_type);
item_type = merged;
}
} else {
- code_err(ast, "I can't figure out what type this array has because it has no members or explicit type");
+ code_err(ast, "I can't figure out what type this list has because it has no members or explicit type");
}
if (has_stack_memory(item_type))
- code_err(ast, "Arrays cannot hold stack references, because the array may outlive the stack frame the reference was created in.");
- return Type(ArrayType, .item_type=item_type);
+ code_err(ast, "Lists cannot hold stack references, because the list may outlive the stack frame the reference was created in.");
+ return Type(ListType, .item_type=item_type);
}
case Set: {
auto set = Match(ast, Set);
@@ -780,7 +780,7 @@ type_t *get_type(env_t *env, ast_t *ast)
auto e = Match(comp->expr, TableEntry);
return Type(TableType, .key_type=get_type(scope, e->key), .value_type=get_type(scope, e->value), .env=env);
} else {
- return Type(ArrayType, .item_type=get_type(scope, comp->expr));
+ return Type(ListType, .item_type=get_type(scope, comp->expr));
}
}
case FieldAccess: {
@@ -813,11 +813,11 @@ type_t *get_type(env_t *env, ast_t *ast)
return Match(indexed_t, PointerType)->pointed;
type_t *value_t = value_type(indexed_t);
- if (value_t->tag == ArrayType) {
+ if (value_t->tag == ListType) {
if (!indexing->index) return indexed_t;
type_t *index_t = get_type(env, indexing->index);
if (index_t->tag == IntType || index_t->tag == BigIntType || index_t->tag == ByteType)
- return Match(value_t, ArrayType)->item_type;
+ return Match(value_t, ListType)->item_type;
code_err(indexing->index, "I only know how to index lists using integers, not %T", index_t);
} else if (value_t->tag == TableType) {
auto table_type = Match(value_t, TableType);
@@ -861,12 +861,12 @@ type_t *get_type(env_t *env, ast_t *ast)
auto call = Match(ast, MethodCall);
if (streq(call->name, "serialized")) // Data serialization
- return Type(ArrayType, Type(ByteType));
+ return Type(ListType, Type(ByteType));
type_t *self_value_t = value_type(get_type(env, call->self));
switch (self_value_t->tag) {
- case ArrayType: {
- type_t *item_type = Match(self_value_t, ArrayType)->item_type;
+ case ListType: {
+ type_t *item_type = Match(self_value_t, ListType)->item_type;
if (streq(call->name, "binary_search")) return INT_TYPE;
else if (streq(call->name, "by")) return self_value_t;
else if (streq(call->name, "clear")) return Type(VoidType);
@@ -893,7 +893,7 @@ type_t *get_type(env_t *env, ast_t *ast)
else if (streq(call->name, "sorted")) return self_value_t;
else if (streq(call->name, "to")) return self_value_t;
else if (streq(call->name, "unique")) return Type(SetType, .item_type=item_type);
- else code_err(ast, "There is no '%s' method for arrays", call->name);
+ else code_err(ast, "There is no '%s' method for lists", call->name);
}
case SetType: {
if (streq(call->name, "add")) return Type(VoidType);
@@ -1155,10 +1155,10 @@ type_t *get_type(env_t *env, ast_t *ast)
if (!type_eq(lhs_t, rhs_t))
code_err(ast, "The type on the left side of this concatenation doesn't match the right side: %T vs. %T",
lhs_t, rhs_t);
- if (lhs_t->tag == ArrayType || lhs_t->tag == TextType || lhs_t->tag == SetType)
+ if (lhs_t->tag == ListType || lhs_t->tag == TextType || lhs_t->tag == SetType)
return lhs_t;
- code_err(ast, "Only array/set/text value types support concatenation, not %T", lhs_t);
+ code_err(ast, "Only list/set/text value types support concatenation, not %T", lhs_t);
}
case BINOP_EQ: case BINOP_NE: case BINOP_LT: case BINOP_LE: case BINOP_GT: case BINOP_GE: {
if (!can_promote(lhs_t, rhs_t) && !can_promote(rhs_t, lhs_t))
diff --git a/types.c b/types.c
index f09d3170..4ab11280 100644
--- a/types.c
+++ b/types.c
@@ -34,9 +34,9 @@ CORD type_to_cord(type_t *t) {
case BigIntType: return "Int";
case IntType: return CORD_asprintf("Int%d", Match(t, IntType)->bits);
case NumType: return Match(t, NumType)->bits == TYPE_NBITS32 ? "Num32" : "Num";
- case ArrayType: {
- auto array = Match(t, ArrayType);
- return CORD_asprintf("List(%r)", type_to_cord(array->item_type));
+ case ListType: {
+ auto list = Match(t, ListType);
+ return CORD_asprintf("List(%r)", type_to_cord(list->item_type));
}
case TableType: {
auto table = Match(t, TableType);
@@ -258,7 +258,7 @@ PUREFUNC precision_cmp_e compare_precision(type_t *a, type_t *b)
PUREFUNC bool has_heap_memory(type_t *t)
{
switch (t->tag) {
- case ArrayType: return true;
+ case ListType: return true;
case TableType: return true;
case SetType: return true;
case PointerType: return true;
@@ -421,9 +421,9 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed)
&& can_promote(actual_ret, needed_ret)));
}
- // Set -> Array promotion
- if (needed->tag == ArrayType && actual->tag == SetType
- && type_eq(Match(needed, ArrayType)->item_type, Match(actual, SetType)->item_type))
+ // Set -> List promotion
+ if (needed->tag == ListType && actual->tag == SetType
+ && type_eq(Match(needed, ListType)->item_type, Match(actual, SetType)->item_type))
return true;
return false;
@@ -518,7 +518,7 @@ PUREFUNC size_t type_size(type_t *t)
}
case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? sizeof(double) : sizeof(float);
case TextType: return sizeof(Text_t);
- case ArrayType: return sizeof(Array_t);
+ case ListType: return sizeof(List_t);
case SetType: return sizeof(Table_t);
case TableType: return sizeof(Table_t);
case FunctionType: return sizeof(void*);
@@ -607,7 +607,7 @@ PUREFUNC size_t type_align(type_t *t)
case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? __alignof__(double) : __alignof__(float);
case TextType: return __alignof__(Text_t);
case SetType: return __alignof__(Table_t);
- case ArrayType: return __alignof__(Array_t);
+ case ListType: return __alignof__(List_t);
case TableType: return __alignof__(Table_t);
case FunctionType: return __alignof__(void*);
case ClosureType: return __alignof__(struct {void *fn, *userdata;});
@@ -687,21 +687,21 @@ type_t *get_field_type(type_t *t, const char *field_name)
if (streq(field_name, "length"))
return INT_TYPE;
else if (streq(field_name, "items"))
- return Type(ArrayType, .item_type=Match(t, SetType)->item_type);
+ return Type(ListType, .item_type=Match(t, SetType)->item_type);
return NULL;
}
case TableType: {
if (streq(field_name, "length"))
return INT_TYPE;
else if (streq(field_name, "keys"))
- return Type(ArrayType, Match(t, TableType)->key_type);
+ return Type(ListType, Match(t, TableType)->key_type);
else if (streq(field_name, "values"))
- return Type(ArrayType, Match(t, TableType)->value_type);
+ return Type(ListType, Match(t, TableType)->value_type);
else if (streq(field_name, "fallback"))
return Type(OptionalType, .type=t);
return NULL;
}
- case ArrayType: {
+ case ListType: {
if (streq(field_name, "length")) return INT_TYPE;
return NULL;
}
@@ -719,7 +719,7 @@ PUREFUNC type_t *get_iterated_type(type_t *t)
type_t *iter_value_t = value_type(t);
switch (iter_value_t->tag) {
case BigIntType: case IntType: return iter_value_t; break;
- case ArrayType: return Match(iter_value_t, ArrayType)->item_type; break;
+ case ListType: return Match(iter_value_t, ListType)->item_type; break;
case SetType: return Match(iter_value_t, SetType)->item_type; break;
case TableType: return NULL;
case FunctionType: case ClosureType: {
diff --git a/types.h b/types.h
index 780c4d5c..0bca1d0a 100644
--- a/types.h
+++ b/types.h
@@ -6,7 +6,7 @@
#include <stdlib.h>
#include "ast.h"
-#include "stdlib/arrays.h"
+#include "stdlib/lists.h"
typedef struct type_s type_t;
@@ -50,7 +50,7 @@ struct type_s {
CStringType,
MomentType,
TextType,
- ArrayType,
+ ListType,
SetType,
TableType,
FunctionType,
@@ -85,7 +85,7 @@ struct type_s {
} TextType;
struct {
type_t *item_type;
- } ArrayType;
+ } ListType;
struct {
type_t *item_type;
} SetType;