aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c6
-rw-r--r--src/ast.h8
-rw-r--r--src/compile/binops.c18
-rw-r--r--src/compile/compilation.h1
-rw-r--r--src/compile/conditionals.c2
-rw-r--r--src/compile/expressions.c14
-rw-r--r--src/compile/fieldaccess.c7
-rw-r--r--src/compile/functions.c11
-rw-r--r--src/compile/indexing.c2
-rw-r--r--src/compile/lists.c2
-rw-r--r--src/compile/loops.c39
-rw-r--r--src/compile/optionals.c3
-rw-r--r--src/compile/pointers.c2
-rw-r--r--src/compile/promotions.c9
-rw-r--r--src/compile/sets.c138
-rw-r--r--src/compile/sets.h11
-rw-r--r--src/compile/text.c1
-rw-r--r--src/compile/types.c8
-rw-r--r--src/environment.c9
-rw-r--r--src/formatter/formatter.c14
-rw-r--r--src/formatter/types.c3
-rw-r--r--src/parse/containers.c30
-rw-r--r--src/parse/containers.h1
-rw-r--r--src/parse/expressions.c9
-rw-r--r--src/parse/types.c17
-rw-r--r--src/parse/types.h1
-rw-r--r--src/stdlib/tables.c12
-rw-r--r--src/stdlib/tables.h20
-rw-r--r--src/typecheck.c73
-rw-r--r--src/types.c25
-rw-r--r--src/types.h4
31 files changed, 64 insertions, 436 deletions
diff --git a/src/ast.c b/src/ast.c
index 7d5e7b65..06a0e486 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -145,7 +145,6 @@ Text_t type_ast_to_sexp(type_ast_t *t) {
T(PointerTypeAST, "(PointerType \"", data.is_stack ? "stack" : "heap", "\" ", type_ast_to_sexp(data.pointed),
")");
T(ListTypeAST, "(ListType ", type_ast_to_sexp(data.item), ")");
- T(SetTypeAST, "(SetType ", type_ast_to_sexp(data.item), ")");
T(TableTypeAST, "(TableType ", type_ast_to_sexp(data.key), " ", type_ast_to_sexp(data.value), ")");
T(FunctionTypeAST, "(FunctionType ", arg_defs_to_sexp(data.args), " ", type_ast_to_sexp(data.ret), ")");
T(OptionalTypeAST, "(OptionalType ", type_ast_to_sexp(data.type), ")");
@@ -233,7 +232,6 @@ Text_t ast_to_sexp(ast_t *ast) {
T(Min, "(Min ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")");
T(Max, "(Max ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")");
T(List, "(List", ast_list_to_sexp(data.items), ")");
- T(Set, "(Set", ast_list_to_sexp(data.items), ")");
T(Table, "(Table", optional_sexp("default", data.default_value), optional_sexp("fallback", data.fallback),
ast_list_to_sexp(data.entries), ")");
T(TableEntry, "(TableEntry ", ast_to_sexp(data.key), " ", ast_to_sexp(data.value), ")");
@@ -523,10 +521,6 @@ void ast_visit(ast_t *ast, void (*visitor)(ast_t *, void *), void *userdata) {
ast_visit_list(Match(ast, List)->items, visitor, userdata);
return;
}
- case Set: {
- ast_visit_list(Match(ast, Set)->items, visitor, userdata);
- return;
- }
case Table: {
DeclareMatch(table, ast, Table);
ast_visit_list(table->entries, visitor, userdata);
diff --git a/src/ast.h b/src/ast.h
index 29141490..a545e68c 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -83,7 +83,6 @@ typedef enum {
VarTypeAST,
PointerTypeAST,
ListTypeAST,
- SetTypeAST,
TableTypeAST,
FunctionTypeAST,
OptionalTypeAST,
@@ -121,9 +120,6 @@ struct type_ast_s {
ast_t *default_value;
} TableTypeAST;
struct {
- type_ast_t *item;
- } SetTypeAST;
- struct {
arg_ast_t *args;
type_ast_t *ret;
} FunctionTypeAST;
@@ -248,7 +244,6 @@ typedef enum {
Min,
Max,
List,
- Set,
Table,
TableEntry,
Comprehension,
@@ -343,9 +338,6 @@ struct ast_s {
ast_list_t *items;
} List;
struct {
- ast_list_t *items;
- } Set;
- struct {
ast_t *default_value;
ast_t *fallback;
ast_list_t *entries;
diff --git a/src/compile/binops.c b/src/compile/binops.c
index 9710019b..0bff98c0 100644
--- a/src/compile/binops.c
+++ b/src/compile/binops.c
@@ -160,8 +160,8 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) {
return Texts("(", lhs, " + ", rhs, ")");
}
case Minus: {
- if (overall_t->tag == SetType)
- return Texts("Table$without(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
+ if (overall_t->tag == TableType)
+ return Texts("Table$minus(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType)
code_err(ast,
"Math operations are only supported for values of the same "
@@ -204,8 +204,8 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) {
case And: {
if (overall_t->tag == BoolType) return Texts("(", lhs, " && ", rhs, ")");
else if (overall_t->tag == IntType || overall_t->tag == ByteType) return Texts("(", lhs, " & ", rhs, ")");
- else if (overall_t->tag == SetType)
- return Texts("Table$overlap(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
+ else if (overall_t->tag == TableType)
+ return Texts("Table$and(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
else
code_err(ast, "The 'and' operator isn't supported between ", type_to_text(lhs_t), " and ",
type_to_text(rhs_t), " values");
@@ -218,18 +218,18 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) {
return Texts("(", lhs, " || ", rhs, ")");
} else if (overall_t->tag == IntType || overall_t->tag == ByteType) {
return Texts("(", lhs, " | ", rhs, ")");
- } else if (overall_t->tag == SetType) {
- return Texts("Table$with(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
+ } else if (overall_t->tag == TableType) {
+ return Texts("Table$or(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
} else {
- code_err(ast, "The 'or' operator isn't supported between ", type_to_text(lhs_t), " and ", type_to_text(rhs_t),
- " values");
+ code_err(ast, "The 'or' operator isn't supported between ", type_to_text(lhs_t), " and ",
+ type_to_text(rhs_t), " values");
}
}
case Xor: {
// TODO: support optional values in `xor` expressions
if (overall_t->tag == BoolType || overall_t->tag == IntType || overall_t->tag == ByteType)
return Texts("(", lhs, " ^ ", rhs, ")");
- else if (overall_t->tag == SetType)
+ else if (overall_t->tag == TableType)
return Texts("Table$xor(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")");
else
code_err(ast, "The 'xor' operator isn't supported between ", type_to_text(lhs_t), " and ",
diff --git a/src/compile/compilation.h b/src/compile/compilation.h
index c034295f..d881684b 100644
--- a/src/compile/compilation.h
+++ b/src/compile/compilation.h
@@ -26,7 +26,6 @@
#include "pointers.h" // IWYU pragma: export
#include "promotions.h" // IWYU pragma: export
#include "reductions.h" // IWYU pragma: export
-#include "sets.h" // IWYU pragma: export
#include "statements.h" // IWYU pragma: export
#include "structs.h" // IWYU pragma: export
#include "tables.h" // IWYU pragma: export
diff --git a/src/compile/conditionals.c b/src/compile/conditionals.c
index 7fcd6cc8..caebdbde 100644
--- a/src/compile/conditionals.c
+++ b/src/compile/conditionals.c
@@ -18,7 +18,7 @@ Text_t compile_condition(env_t *env, ast_t *ast) {
return Texts("(", compile(env, ast), ").length");
} else if (t->tag == ListType) {
return Texts("(", compile(env, ast), ").length");
- } else if (t->tag == TableType || t->tag == SetType) {
+ } else if (t->tag == TableType) {
return Texts("(", compile(env, ast), ").entries.length");
} else if (t->tag == OptionalType) {
return Texts("!", check_none(t, compile(env, ast)));
diff --git a/src/compile/expressions.c b/src/compile/expressions.c
index 16b94d73..c511bea1 100644
--- a/src/compile/expressions.c
+++ b/src/compile/expressions.c
@@ -13,8 +13,7 @@ public
Text_t compile_maybe_incref(env_t *env, ast_t *ast, type_t *t) {
if (is_idempotent(ast) && can_be_mutated(env, ast)) {
if (t->tag == ListType) return Texts("LIST_COPY(", compile_to_type(env, ast, t), ")");
- else if (t->tag == TableType || t->tag == SetType)
- return Texts("TABLE_COPY(", compile_to_type(env, ast, t), ")");
+ else if (t->tag == TableType) return Texts("TABLE_COPY(", compile_to_type(env, ast, t), ")");
}
return compile_to_type(env, ast, t);
}
@@ -44,7 +43,6 @@ Text_t compile_empty(type_t *t) {
case BoolType: return Text("((Bool_t)no)");
case ListType: return Text("((List_t){})");
case TableType:
- case SetType: return Text("((Table_t){})");
case TextType: return Text("Text(\"\")");
case CStringType: return Text("\"\"");
case PointerType: {
@@ -93,8 +91,7 @@ Text_t compile(env_t *env, ast_t *ast) {
if (t->tag == BoolType) return Texts("!(", compile(env, value), ")");
else if (t->tag == IntType || t->tag == ByteType) return Texts("~(", compile(env, value), ")");
else if (t->tag == ListType) return Texts("((", compile(env, value), ").length == 0)");
- else if (t->tag == SetType || t->tag == TableType)
- return Texts("((", compile(env, value), ").entries.length == 0)");
+ else if (t->tag == TableType) return Texts("((", compile(env, value), ").entries.length == 0)");
else if (t->tag == TextType) return Texts("(", compile(env, value), ".length == 0)");
else if (t->tag == OptionalType) return check_none(t, compile(env, value));
@@ -197,13 +194,6 @@ Text_t compile(env_t *env, ast_t *ast) {
type_t *table_type = get_type(env, ast);
return compile_typed_table(env, ast, table_type);
}
- case Set: {
- DeclareMatch(set, ast, Set);
- if (!set->items) return Text("((Table_t){})");
-
- type_t *set_type = get_type(env, ast);
- return compile_typed_set(env, ast, set_type);
- }
case Comprehension: {
ast_t *base = Match(ast, Comprehension)->expr;
while (base->tag == Comprehension)
diff --git a/src/compile/fieldaccess.c b/src/compile/fieldaccess.c
index 24e091f0..65c8f92b 100644
--- a/src/compile/fieldaccess.c
+++ b/src/compile/fieldaccess.c
@@ -48,13 +48,6 @@ Text_t compile_field_access(env_t *env, ast_t *ast) {
return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)");
code_err(ast, "There is no ", f->field, " field on lists");
}
- case SetType: {
- if (streq(f->field, "items"))
- return Texts("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
- else if (streq(f->field, "length"))
- return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)");
- code_err(ast, "There is no '", f->field, "' field on sets");
- }
case TableType: {
if (streq(f->field, "length")) {
return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)");
diff --git a/src/compile/functions.c b/src/compile/functions.c
index d113316b..e2fa8a11 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -302,8 +302,7 @@ Text_t compile_lambda(env_t *env, ast_t *ast) {
assert(b);
Text_t binding_code = b->code;
if (entry->b->type->tag == ListType) userdata = Texts(userdata, ", LIST_COPY(", binding_code, ")");
- else if (entry->b->type->tag == TableType || entry->b->type->tag == SetType)
- userdata = Texts(userdata, ", TABLE_COPY(", binding_code, ")");
+ else if (entry->b->type->tag == TableType) userdata = Texts(userdata, ", TABLE_COPY(", binding_code, ")");
else userdata = Texts(userdata, ", ", binding_code);
}
userdata = Texts(userdata, ")");
@@ -388,11 +387,6 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
add_closed_vars(closed_vars, enclosing_scope, env, item->ast);
break;
}
- case Set: {
- for (ast_list_t *item = Match(ast, Set)->items; item; item = item->next)
- add_closed_vars(closed_vars, enclosing_scope, env, item->ast);
- break;
- }
case Table: {
add_closed_vars(closed_vars, enclosing_scope, env, Match(ast, Table)->default_value);
add_closed_vars(closed_vars, enclosing_scope, env, Match(ast, Table)->fallback);
@@ -413,7 +407,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);
}
- // List/Set/Table comprehension:
+ // List/Table comprehension:
ast_t *body = comp->expr;
if (comp->filter) body = WrapAST(comp->expr, If, .condition = comp->filter, .body = body);
ast_t *loop = WrapAST(ast, For, .vars = comp->vars, .iter = comp->iter, .body = body);
@@ -839,7 +833,6 @@ Text_t compile_method_call(env_t *env, ast_t *ast) {
switch (self_value_t->tag) {
case ListType: return compile_list_method_call(env, ast);
- case SetType: return compile_set_method_call(env, ast);
case TableType: return compile_table_method_call(env, ast);
default: {
DeclareMatch(methodcall, ast, MethodCall);
diff --git a/src/compile/indexing.c b/src/compile/indexing.c
index 771e9acd..af5056d7 100644
--- a/src/compile/indexing.c
+++ b/src/compile/indexing.c
@@ -22,7 +22,7 @@ Text_t compile_indexing(env_t *env, ast_t *ast, bool checked) {
DeclareMatch(ptr, indexed_type, PointerType);
if (ptr->pointed->tag == ListType) {
return Texts("*({ List_t *list = ", compile(env, indexing->indexed), "; LIST_INCREF(*list); list; })");
- } else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) {
+ } else if (ptr->pointed->tag == TableType) {
return Texts("*({ Table_t *t = ", compile(env, indexing->indexed), "; TABLE_INCREF(*t); t; })");
} else {
return Texts("*(", compile(env, indexing->indexed), ")");
diff --git a/src/compile/lists.c b/src/compile/lists.c
index d9d71278..4fe83d16 100644
--- a/src/compile/lists.c
+++ b/src/compile/lists.c
@@ -253,7 +253,7 @@ Text_t compile_list_method_call(env_t *env, ast_t *ast) {
} 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 Texts("Table$from_entries(", self, ", Set$info(", compile_type_info(item_t), "))");
+ return Texts("Table$from_entries(", self, ", Table$info(", compile_type_info(item_t), ", &Void$info)).items");
} else if (streq(call->name, "pop")) {
EXPECT_POINTER();
arg_t *arg_spec = new (arg_t, .name = "index", .type = INT_TYPE, .default_val = FakeAST(Int, "-1"));
diff --git a/src/compile/loops.c b/src/compile/loops.c
index b68c908f..588be4f0 100644
--- a/src/compile/loops.c
+++ b/src/compile/loops.c
@@ -188,33 +188,24 @@ Text_t compile_for_loop(env_t *env, ast_t *ast) {
}
return loop;
}
- case SetType:
case TableType: {
Text_t loop = Text("for (int64_t i = 0; i < iterating.length; ++i) {\n");
if (for_->vars) {
- if (iter_value_t->tag == SetType) {
- if (for_->vars->next) code_err(for_->vars->next->ast, "This is too many variables for this loop");
- Text_t item = compile(body_scope, for_->vars->ast);
- type_t *item_type = Match(iter_value_t, SetType)->item_type;
- loop = Texts(loop, compile_declaration(item_type, item), " = *(", compile_type(item_type), "*)(",
- "iterating.data + i*iterating.stride);\n");
- } else {
- Text_t key = compile(body_scope, for_->vars->ast);
- type_t *key_t = Match(iter_value_t, TableType)->key_type;
- loop = Texts(loop, compile_declaration(key_t, key), " = *(", compile_type(key_t), "*)(",
- "iterating.data + i*iterating.stride);\n");
-
- if (for_->vars->next) {
- if (for_->vars->next->next)
- code_err(for_->vars->next->next->ast, "This is too many variables for this loop");
-
- type_t *value_t = Match(iter_value_t, TableType)->value_type;
- Text_t value = compile(body_scope, for_->vars->next->ast);
- Text_t value_offset = Texts("offsetof(struct { ", compile_declaration(key_t, Text("k")), "; ",
- compile_declaration(value_t, Text("v")), "; }, v)");
- loop = Texts(loop, compile_declaration(value_t, value), " = *(", compile_type(value_t), "*)(",
- "iterating.data + i*iterating.stride + ", value_offset, ");\n");
- }
+ Text_t key = compile(body_scope, for_->vars->ast);
+ type_t *key_t = Match(iter_value_t, TableType)->key_type;
+ loop = Texts(loop, compile_declaration(key_t, key), " = *(", compile_type(key_t), "*)(",
+ "iterating.data + i*iterating.stride);\n");
+
+ if (for_->vars->next) {
+ if (for_->vars->next->next)
+ code_err(for_->vars->next->next->ast, "This is too many variables for this loop");
+
+ type_t *value_t = Match(iter_value_t, TableType)->value_type;
+ Text_t value = compile(body_scope, for_->vars->next->ast);
+ Text_t value_offset = Texts("offsetof(struct { ", compile_declaration(key_t, Text("k")), "; ",
+ compile_declaration(value_t, Text("v")), "; }, v)");
+ loop = Texts(loop, compile_declaration(value_t, value), " = *(", compile_type(value_t), "*)(",
+ "iterating.data + i*iterating.stride + ", value_offset, ");\n");
}
}
diff --git a/src/compile/optionals.c b/src/compile/optionals.c
index 234a1cd2..86b4f771 100644
--- a/src/compile/optionals.c
+++ b/src/compile/optionals.c
@@ -72,7 +72,6 @@ Text_t compile_none(type_t *t) {
case ByteType: return Text("NONE_BYTE");
case ListType: return Text("NONE_LIST");
case TableType: return Text("NONE_TABLE");
- case SetType: return Text("NONE_TABLE");
case TextType: return Text("NONE_TEXT");
case CStringType: return Text("NULL");
case PointerType: return Texts("((", compile_type(t), ")NULL)");
@@ -101,7 +100,7 @@ Text_t check_none(type_t *t, Text_t value) {
else if (t->tag == NumType)
return Texts(Match(t, NumType)->bits == TYPE_NBITS64 ? "Num$isnan(" : "Num32$isnan(", value, ")");
else if (t->tag == ListType) return Texts("((", value, ").length < 0)");
- else if (t->tag == TableType || t->tag == SetType) return Texts("((", value, ").entries.length < 0)");
+ else if (t->tag == TableType) return Texts("((", value, ").entries.length < 0)");
else if (t->tag == BoolType) return Texts("((", value, ") == NONE_BOOL)");
else if (t->tag == TextType) return Texts("((", value, ").length < 0)");
else if (t->tag == IntType || t->tag == ByteType || t->tag == StructType) return Texts("(", value, ").is_none");
diff --git a/src/compile/pointers.c b/src/compile/pointers.c
index 31687d78..11348330 100644
--- a/src/compile/pointers.c
+++ b/src/compile/pointers.c
@@ -44,7 +44,7 @@ Text_t compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bo
}
if (needs_incref && t->tag == ListType) val = Texts("LIST_COPY(", val, ")");
- else if (needs_incref && (t->tag == TableType || t->tag == SetType)) val = Texts("TABLE_COPY(", val, ")");
+ else if (needs_incref && t->tag == TableType) val = Texts("TABLE_COPY(", val, ")");
return val;
}
diff --git a/src/compile/promotions.c b/src/compile/promotions.c
index 3441632e..d453b764 100644
--- a/src/compile/promotions.c
+++ b/src/compile/promotions.c
@@ -101,13 +101,6 @@ bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t *neede
return true;
}
- // Set -> List promotion:
- if (needed->tag == ListType && actual->tag == SetType
- && type_eq(Match(needed, ListType)->item_type, Match(actual, SetType)->item_type)) {
- *code = Texts("(", *code, ").entries");
- return true;
- }
-
return false;
}
@@ -141,8 +134,6 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) {
return compile_typed_list(env, ast, t);
} else if (t->tag == TableType && ast->tag == Table) {
return compile_typed_table(env, ast, t);
- } else if (t->tag == SetType && ast->tag == Set) {
- return compile_typed_set(env, ast, t);
}
type_t *actual = get_type(env, ast);
diff --git a/src/compile/sets.c b/src/compile/sets.c
deleted file mode 100644
index 3346a9aa..00000000
--- a/src/compile/sets.c
+++ /dev/null
@@ -1,138 +0,0 @@
-// This file defines how to compile sets
-
-#include "../ast.h"
-#include "../environment.h"
-#include "../stdlib/datatypes.h"
-#include "../stdlib/text.h"
-#include "../typecheck.h"
-#include "../types.h"
-#include "compilation.h"
-
-static ast_t *add_to_set_comprehension(ast_t *item, ast_t *subject) {
- return WrapAST(item, MethodCall, .name = "add", .self = subject, .args = new (arg_ast_t, .value = item));
-}
-
-Text_t compile_typed_set(env_t *env, ast_t *ast, type_t *set_type) {
- DeclareMatch(set, ast, Set);
- if (!set->items) return Text("((Table_t){})");
-
- type_t *item_type = Match(set_type, SetType)->item_type;
-
- int64_t n = 0;
- for (ast_list_t *item = set->items; item; item = item->next) {
- ++n;
- if (item->ast->tag == Comprehension) goto set_comprehension;
- }
-
- { // No comprehension:
- Text_t code = Texts("Set(", compile_type(item_type), ", ", compile_type_info(item_type), ", ", n);
- env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env;
- for (ast_list_t *item = set->items; item; item = item->next) {
- code = Texts(code, ", ", compile_to_type(scope, item->ast, item_type));
- }
- return Texts(code, ")");
- }
-
-set_comprehension: {
- static int64_t comp_num = 1;
- env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env);
- const char *comprehension_name = String("set$", comp_num++);
- ast_t *comprehension_var =
- LiteralCode(Texts("&", comprehension_name), .type = Type(PointerType, .pointed = set_type, .is_stack = true));
- Text_t code = Texts("({ Table_t ", comprehension_name, " = {};");
- Closure_t comp_action = {.fn = add_to_set_comprehension, .userdata = comprehension_var};
- scope->comprehension_action = &comp_action;
- for (ast_list_t *item = set->items; item; item = item->next) {
- if (item->ast->tag == Comprehension) code = Texts(code, "\n", compile_statement(scope, item->ast));
- else code = Texts(code, compile_statement(env, add_to_set_comprehension(item->ast, comprehension_var)));
- }
- code = Texts(code, " ", comprehension_name, "; })");
- return code;
-}
-}
-
-public
-Text_t compile_set_method_call(env_t *env, ast_t *ast) {
- DeclareMatch(call, ast, MethodCall);
- type_t *self_t = get_type(env, call->self);
-
- int64_t pointer_depth = 0;
- type_t *self_value_t = self_t;
- for (; self_value_t->tag == PointerType; self_value_t = Match(self_value_t, PointerType)->pointed)
- pointer_depth += 1;
-
- Text_t self = compile(env, call->self);
-#define EXPECT_POINTER() \
- do { \
- if (pointer_depth < 1) code_err(call->self, "I expected a set pointer here, not a set value"); \
- else if (pointer_depth > 1) code_err(call->self, "I expected a set pointer here, not a nested set pointer"); \
- } while (0)
- DeclareMatch(set, self_value_t, SetType);
- if (streq(call->name, "has")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec = new (arg_t, .name = "key", .type = set->item_type);
- return Texts("Table$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "add")) {
- EXPECT_POINTER();
- arg_t *arg_spec = new (arg_t, .name = "item", .type = set->item_type);
- return Texts("Table$set_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", NULL, ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "add_all")) {
- EXPECT_POINTER();
- arg_t *arg_spec =
- new (arg_t, .name = "items", .type = Type(ListType, .item_type = Match(self_value_t, SetType)->item_type));
- return Texts("({ Table_t *set = ", self, "; ",
- "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; })");
- } else if (streq(call->name, "remove")) {
- EXPECT_POINTER();
- arg_t *arg_spec = new (arg_t, .name = "item", .type = set->item_type);
- return Texts("Table$remove_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "remove_all")) {
- EXPECT_POINTER();
- arg_t *arg_spec =
- new (arg_t, .name = "items", .type = Type(ListType, .item_type = Match(self_value_t, SetType)->item_type));
- return Texts("({ Table_t *set = ", self, "; ",
- "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; })");
- } else if (streq(call->name, "clear")) {
- EXPECT_POINTER();
- (void)compile_arguments(env, ast, NULL, call->args);
- return Texts("Table$clear(", self, ")");
- } else if (streq(call->name, "with")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec = new (arg_t, .name = "other", .type = self_value_t);
- return Texts("Table$with(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "overlap")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec = new (arg_t, .name = "other", .type = self_value_t);
- return Texts("Table$overlap(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "without")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec = new (arg_t, .name = "other", .type = self_value_t);
- return Texts("Table$without(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "is_subset_of")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec =
- new (arg_t, .name = "other", .type = self_value_t,
- .next = new (arg_t, .name = "strict", .type = Type(BoolType), .default_val = FakeAST(Bool, false)));
- return Texts("Table$is_subset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else if (streq(call->name, "is_superset_of")) {
- self = compile_to_pointer_depth(env, call->self, 0, false);
- arg_t *arg_spec =
- new (arg_t, .name = "other", .type = self_value_t,
- .next = new (arg_t, .name = "strict", .type = Type(BoolType), .default_val = FakeAST(Bool, false)));
- return Texts("Table$is_superset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
- compile_type_info(self_value_t), ")");
- } else code_err(ast, "There is no '", call->name, "' method for tables");
-}
diff --git a/src/compile/sets.h b/src/compile/sets.h
deleted file mode 100644
index 1582e3cd..00000000
--- a/src/compile/sets.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// This file defines how to compile sets
-
-#pragma once
-
-#include "../ast.h"
-#include "../environment.h"
-#include "../stdlib/datatypes.h"
-#include "../types.h"
-
-Text_t compile_typed_set(env_t *env, ast_t *ast, type_t *set_type);
-Text_t compile_set_method_call(env_t *env, ast_t *ast);
diff --git a/src/compile/text.c b/src/compile/text.c
index afb412e9..637ad60c 100644
--- a/src/compile/text.c
+++ b/src/compile/text.c
@@ -30,7 +30,6 @@ Text_t expr_as_text(Text_t expr, type_t *t, Text_t color) {
}
case TextType: return Texts("Text$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")");
case ListType: return Texts("List$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")");
- case SetType: return Texts("Table$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")");
case TableType: return Texts("Table$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")");
case FunctionType:
case ClosureType: return Texts("Func$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")");
diff --git a/src/compile/types.c b/src/compile/types.c
index 6b6f48f8..e407a6d0 100644
--- a/src/compile/types.c
+++ b/src/compile/types.c
@@ -33,7 +33,6 @@ Text_t compile_type(type_t *t) {
else return namespace_name(text->env, text->env->namespace, Text("$type"));
}
case ListType: return Text("List_t");
- case SetType: return Text("Table_t");
case TableType: return Text("Table_t");
case FunctionType: {
DeclareMatch(fn, t, FunctionType);
@@ -71,8 +70,7 @@ Text_t compile_type(type_t *t) {
case BoolType:
case ByteType:
case ListType:
- case TableType:
- case SetType: return Texts("Optional", compile_type(nonnull));
+ case TableType: return Texts("Optional", compile_type(nonnull));
case StructType: {
if (nonnull == PATH_TYPE) return Text("OptionalPath_t");
if (nonnull == PATH_TYPE_TYPE) return Text("OptionalPathType_t");
@@ -118,10 +116,6 @@ Text_t compile_type_info(type_t *t) {
type_t *item_t = Match(t, ListType)->item_type;
return Texts("List$info(", compile_type_info(item_t), ")");
}
- case SetType: {
- type_t *item_type = Match(t, SetType)->item_type;
- return Texts("Set$info(", compile_type_info(item_type), ")");
- }
case TableType: {
DeclareMatch(table, t, TableType);
type_t *key_type = table->key_type;
diff --git a/src/environment.c b/src/environment.c
index 045cf6d7..603a04d9 100644
--- a/src/environment.c
+++ b/src/environment.c
@@ -610,15 +610,6 @@ env_t *for_scope(env_t *env, ast_t *ast) {
}
return scope;
}
- case SetType: {
- if (for_->vars) {
- if (for_->vars->next) code_err(for_->vars->next->ast, "This is too many variables for this loop");
- type_t *item_type = Match(iter_t, SetType)->item_type;
- const char *name = Match(for_->vars->ast, Var)->name;
- set_binding(scope, name, item_type, Texts("_$", name));
- }
- return scope;
- }
case TableType: {
const char *vars[2] = {};
int64_t num_vars = 0;
diff --git a/src/formatter/formatter.c b/src/formatter/formatter.c
index 07a70afa..52a6303c 100644
--- a/src/formatter/formatter.c
+++ b/src/formatter/formatter.c
@@ -203,15 +203,14 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) {
if (comp->filter) code = Texts(code, " if ", fmt_inline(comp->filter, comments));
return code;
}
- /*inline*/ case List:
- /*inline*/ case Set: {
- ast_list_t *items = ast->tag == List ? Match(ast, List)->items : Match(ast, Set)->items;
+ /*inline*/ case List: {
+ ast_list_t *items = Match(ast, List)->items;
Text_t code = EMPTY_TEXT;
for (ast_list_t *item = items; item; item = item->next) {
code = Texts(code, fmt_inline(item->ast, comments));
if (item->next) code = Texts(code, ", ");
}
- return ast->tag == List ? Texts("[", code, "]") : Texts("|", code, "|");
+ return Texts("[", code, "]");
}
/*inline*/ case Table: {
DeclareMatch(table, ast, Table);
@@ -587,10 +586,9 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) {
}
/*multiline*/ case Defer:
return Texts("defer ", format_namespace(Match(ast, Defer)->body, comments, indent));
- /*multiline*/ case List:
- /*multiline*/ case Set: {
+ /*multiline*/ case List: {
if (inlined_fits) return inlined;
- ast_list_t *items = ast->tag == List ? Match(ast, List)->items : Match(ast, Set)->items;
+ ast_list_t *items = Match(ast, List)->items;
Text_t code = ast->tag == List ? Text("[") : Text("|");
const char *comment_pos = ast->start;
for (ast_list_t *item = items; item; item = item->next) {
@@ -610,7 +608,7 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) {
for (OptionalText_t comment; (comment = next_comment(comments, &comment_pos, ast->end)).length > 0;) {
add_line(&code, Text$trim(comment, Text(" \t\r\n"), false, true), Texts(indent, single_indent));
}
- return ast->tag == List ? Texts(code, "\n", indent, "]") : Texts(code, "\n", indent, "|");
+ return Texts(code, "\n", indent, "]");
}
/*multiline*/ case Table: {
if (inlined_fits) return inlined;
diff --git a/src/formatter/types.c b/src/formatter/types.c
index e52faf70..0cff38f0 100644
--- a/src/formatter/types.c
+++ b/src/formatter/types.c
@@ -17,9 +17,6 @@ Text_t format_type(type_ast_t *type) {
case ListTypeAST: {
return Texts("[", format_type(Match(type, ListTypeAST)->item), "]");
}
- case SetTypeAST: {
- return Texts("|", format_type(Match(type, SetTypeAST)->item), "|");
- }
case TableTypeAST: {
DeclareMatch(table, type, TableTypeAST);
Text_t code = Texts("{", format_type(table->key), "=", format_type(table->value));
diff --git a/src/parse/containers.c b/src/parse/containers.c
index 73d30ecd..b7378b18 100644
--- a/src/parse/containers.c
+++ b/src/parse/containers.c
@@ -96,33 +96,3 @@ ast_t *parse_table(parse_ctx_t *ctx, const char *pos) {
return NewAST(ctx->file, start, pos, Table, .default_value = default_value, .entries = entries,
.fallback = fallback);
}
-
-ast_t *parse_set(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- if (match(&pos, "||")) return NewAST(ctx->file, start, pos, Set);
-
- if (!match(&pos, "|")) return NULL;
- whitespace(ctx, &pos);
-
- ast_list_t *items = NULL;
- for (;;) {
- ast_t *item = optional(ctx, &pos, parse_extended_expr);
- if (!item) break;
- whitespace(ctx, &pos);
- ast_t *suffixed = parse_comprehension_suffix(ctx, item);
- while (suffixed) {
- item = suffixed;
- pos = suffixed->end;
- suffixed = parse_comprehension_suffix(ctx, item);
- }
- items = new (ast_list_t, .ast = item, .next = items);
- if (!match_separator(ctx, &pos)) break;
- }
-
- REVERSE_LIST(items);
-
- whitespace(ctx, &pos);
- expect_closing(ctx, &pos, "|", "I wasn't able to parse the rest of this set");
-
- return NewAST(ctx->file, start, pos, Set, .items = items);
-}
diff --git a/src/parse/containers.h b/src/parse/containers.h
index 6bf75274..4ea23380 100644
--- a/src/parse/containers.h
+++ b/src/parse/containers.h
@@ -5,5 +5,4 @@
#include "context.h"
ast_t *parse_list(parse_ctx_t *ctx, const char *pos);
-ast_t *parse_set(parse_ctx_t *ctx, const char *pos);
ast_t *parse_table(parse_ctx_t *ctx, const char *pos);
diff --git a/src/parse/expressions.c b/src/parse/expressions.c
index df0a10a7..606c7b4e 100644
--- a/src/parse/expressions.c
+++ b/src/parse/expressions.c
@@ -193,11 +193,10 @@ ast_t *parse_term_no_suffix(parse_ctx_t *ctx, const char *pos) {
|| (term = parse_heap_alloc(ctx, pos)) || (term = parse_stack_reference(ctx, pos))
|| (term = parse_bool(ctx, pos)) || (term = parse_text(ctx, pos)) || (term = parse_path(ctx, pos))
|| (term = parse_lambda(ctx, pos)) || (term = parse_parens(ctx, pos)) || (term = parse_table(ctx, pos))
- || (term = parse_set(ctx, pos)) || (term = parse_deserialize(ctx, pos)) || (term = parse_var(ctx, pos))
- || (term = parse_list(ctx, pos)) || (term = parse_reduction(ctx, pos)) || (term = parse_pass(ctx, pos))
- || (term = parse_defer(ctx, pos)) || (term = parse_skip(ctx, pos)) || (term = parse_stop(ctx, pos))
- || (term = parse_return(ctx, pos)) || (term = parse_not(ctx, pos)) || (term = parse_extern(ctx, pos))
- || (term = parse_inline_c(ctx, pos)));
+ || (term = parse_deserialize(ctx, pos)) || (term = parse_var(ctx, pos)) || (term = parse_list(ctx, pos))
+ || (term = parse_reduction(ctx, pos)) || (term = parse_pass(ctx, pos)) || (term = parse_defer(ctx, pos))
+ || (term = parse_skip(ctx, pos)) || (term = parse_stop(ctx, pos)) || (term = parse_return(ctx, pos))
+ || (term = parse_not(ctx, pos)) || (term = parse_extern(ctx, pos)) || (term = parse_inline_c(ctx, pos)));
return term;
}
diff --git a/src/parse/types.c b/src/parse/types.c
index d87fc628..f08578e9 100644
--- a/src/parse/types.c
+++ b/src/parse/types.c
@@ -43,18 +43,6 @@ type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
.default_value = default_value);
}
-type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- if (!match(&pos, "|")) return NULL;
- whitespace(ctx, &pos);
- type_ast_t *item_type = parse_type(ctx, pos);
- if (!item_type) return NULL;
- pos = item_type->end;
- whitespace(ctx, &pos);
- expect_closing(ctx, &pos, "|", "I wasn't able to parse the rest of this set type");
- return NewTypeAST(ctx->file, start, pos, SetTypeAST, .item = item_type);
-}
-
type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match_word(&pos, "func")) return NULL;
@@ -158,9 +146,8 @@ type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
type_ast_t *type = NULL;
bool success = (false || (type = parse_pointer_type(ctx, pos)) || (type = parse_list_type(ctx, pos))
- || (type = parse_table_type(ctx, pos)) || (type = parse_set_type(ctx, pos))
- || (type = parse_enum_type(ctx, pos)) || (type = parse_type_name(ctx, pos))
- || (type = parse_func_type(ctx, pos)));
+ || (type = parse_table_type(ctx, pos)) || (type = parse_enum_type(ctx, pos))
+ || (type = parse_type_name(ctx, pos)) || (type = parse_func_type(ctx, pos)));
if (!success && match(&pos, "(")) {
whitespace(ctx, &pos);
type = optional(ctx, &pos, parse_type);
diff --git a/src/parse/types.h b/src/parse/types.h
index ac6c22fb..f13ec6ed 100644
--- a/src/parse/types.h
+++ b/src/parse/types.h
@@ -11,7 +11,6 @@ type_ast_t *parse_func_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_list_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_non_optional_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_pointer_type(parse_ctx_t *ctx, const char *pos);
-type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos);
type_ast_t *parse_type_name(parse_ctx_t *ctx, const char *pos);
diff --git a/src/stdlib/tables.c b/src/stdlib/tables.c
index 974e3542..7d5ff4ef 100644
--- a/src/stdlib/tables.c
+++ b/src/stdlib/tables.c
@@ -579,9 +579,9 @@ Table_t Table$from_entries(List_t entries, const TypeInfo_t *type) {
return t;
}
-// Overlap is "set intersection" in formal terms
+// And is "set intersection" in formal terms
public
-Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type) {
+Table_t Table$and(Table_t a, Table_t b, const TypeInfo_t *type) {
// Return a table such that t[k]==a[k] for all k such that a.has(k), b.has(k), and a[k]==b[k]
Table_t result = {};
const size_t offset = value_offset(type);
@@ -597,9 +597,9 @@ Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type) {
return result;
}
-// With is "set union" in formal terms
+// Or is "set union" in formal terms
public
-Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type) {
+Table_t Table$or(Table_t a, Table_t b, const TypeInfo_t *type) {
// return a table such that t[k]==b[k] for all k such that b.has(k), and t[k]==a[k] for all k such that a.has(k) and
// not b.has(k)
Table_t result = {};
@@ -640,9 +640,9 @@ Table_t Table$xor(Table_t a, Table_t b, const TypeInfo_t *type) {
return result;
}
-// Without is "set difference" in formal terms
+// Minus is "set difference" in formal terms
public
-Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type) {
+Table_t Table$minus(Table_t a, Table_t b, const TypeInfo_t *type) {
// Return a table such that t[k]==a[k] for all k such that not b.has(k) or b[k] != a[k]
Table_t result = {};
const size_t offset = value_offset(type);
diff --git a/src/stdlib/tables.h b/src/stdlib/tables.h
index 129aa5ec..4364530a 100644
--- a/src/stdlib/tables.h
+++ b/src/stdlib/tables.h
@@ -27,18 +27,6 @@
table.fallback = fb; \
table; \
})
-#define Set(item_t, item_info, N, ...) \
- ({ \
- item_t ents[N] = {__VA_ARGS__}; \
- 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(List_t entries, const TypeInfo_t *type);
void *Table$get(Table_t t, const void *key, const TypeInfo_t *type);
@@ -103,13 +91,11 @@ void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type);
Table$remove(t, &k, type); \
})
-Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type);
-Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type);
-Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type);
+Table_t Table$and(Table_t a, Table_t b, const TypeInfo_t *type);
+Table_t Table$or(Table_t a, Table_t b, const TypeInfo_t *type);
+Table_t Table$minus(Table_t a, Table_t b, const TypeInfo_t *type);
Table_t Table$xor(Table_t a, Table_t b, const TypeInfo_t *type);
Table_t Table$with_fallback(Table_t t, OptionalTable_t fallback);
-PUREFUNC bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type);
-PUREFUNC bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type);
void Table$clear(Table_t *t);
Table_t Table$sorted(Table_t t, const TypeInfo_t *type);
diff --git a/src/typecheck.c b/src/typecheck.c
index 87ed474a..c018c04e 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -65,18 +65,6 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) {
" bytes. Consider using a list of pointers instead.");
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 list may outlive the stack frame.");
- if (type_size(item_t) > LIST_MAX_STRIDE)
- code_err(ast, "This set holds items that take up ", (uint64_t)type_size(item_t),
- " bytes, but the maximum supported size is ", (int64_t)LIST_MAX_STRIDE,
- " bytes. Consider using an set of pointers instead.");
- return Type(SetType, .item_type = item_t);
- }
case TableTypeAST: {
DeclareMatch(table_type, ast, TableTypeAST);
type_ast_t *key_type_ast = table_type->key;
@@ -872,29 +860,6 @@ type_t *get_type(env_t *env, ast_t *ast) {
return Type(ListType, .item_type = item_type);
}
- case Set: {
- DeclareMatch(set, ast, Set);
- type_t *item_type = NULL;
- for (ast_list_t *item = set->items; item; item = item->next) {
- ast_t *item_ast = item->ast;
- env_t *scope = env;
- while (item_ast->tag == Comprehension) {
- DeclareMatch(comp, item_ast, Comprehension);
- scope = for_scope(scope, FakeAST(For, .iter = comp->iter, .vars = comp->vars));
- item_ast = comp->expr;
- }
-
- type_t *this_item_type = get_type(scope, item_ast);
- type_t *item_merged = type_or_type(item_type, this_item_type);
- if (!item_merged) return Type(SetType, .item_type = NULL);
- item_type = item_merged;
- }
-
- if (item_type && has_stack_memory(item_type))
- code_err(ast, "Sets cannot hold stack references because the set may outlive the reference's stack frame.");
-
- return Type(SetType, .item_type = item_type);
- }
case Table: {
DeclareMatch(table, ast, Table);
type_t *key_type = NULL, *value_type = NULL;
@@ -1076,23 +1041,9 @@ type_t *get_type(env_t *env, ast_t *ast) {
else if (streq(call->name, "sort")) return Type(VoidType);
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 if (streq(call->name, "unique")) return Type(ListType, .item_type = item_type);
else code_err(ast, "There is no '", call->name, "' method for lists");
}
- case SetType: {
- if (streq(call->name, "add")) return Type(VoidType);
- else if (streq(call->name, "add_all")) return Type(VoidType);
- else if (streq(call->name, "clear")) return Type(VoidType);
- else if (streq(call->name, "has")) return Type(BoolType);
- else if (streq(call->name, "is_subset_of")) return Type(BoolType);
- else if (streq(call->name, "is_superset_of")) return Type(BoolType);
- else if (streq(call->name, "overlap")) return self_value_t;
- else if (streq(call->name, "remove")) return Type(VoidType);
- else if (streq(call->name, "remove_all")) return Type(VoidType);
- else if (streq(call->name, "with")) return self_value_t;
- else if (streq(call->name, "without")) return self_value_t;
- else code_err(ast, "There is no '", call->name, "' method for sets");
- }
case TableType: {
DeclareMatch(table, self_value_t, TableType);
if (streq(call->name, "clear")) return Type(VoidType);
@@ -1229,7 +1180,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
type_t *rhs_t = get_type(env, binop.rhs);
type_t *lhs_val = value_type(lhs_t), *rhs_val = value_type(rhs_t);
- if (type_eq(lhs_val, rhs_val) && lhs_val->tag == SetType) return lhs_val;
+ if (type_eq(lhs_val, rhs_val) && lhs_val->tag == TableType) return lhs_val;
if (binop.lhs->tag == Int && is_int_type(rhs_t)) return rhs_t;
else if (binop.rhs->tag == Int && is_int_type(lhs_t)) return lhs_t;
@@ -1263,7 +1214,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
&& rhs_t->tag != NumType) {
if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t;
else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t;
- } else if (lhs_t->tag == SetType && rhs_t->tag == SetType && type_eq(lhs_t, rhs_t)) {
+ } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) {
return lhs_t;
}
code_err(ast, "I couldn't figure out how to do `or` between ", type_to_text(lhs_t), " and ",
@@ -1275,7 +1226,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
type_t *rhs_t = get_type(env, binop.rhs);
type_t *lhs_val = value_type(lhs_t), *rhs_val = value_type(rhs_t);
- if (type_eq(lhs_val, rhs_val) && lhs_val->tag == SetType) return lhs_val;
+ if (type_eq(lhs_val, rhs_val) && lhs_val->tag == TableType) return lhs_val;
if (binop.lhs->tag == Int && is_int_type(rhs_t)) return rhs_t;
else if (binop.rhs->tag == Int && is_int_type(lhs_t)) return lhs_t;
@@ -1296,7 +1247,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
&& lhs_t->tag != NumType && rhs_t->tag != NumType) {
if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t;
else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t;
- } else if (lhs_t->tag == SetType && rhs_t->tag == SetType && type_eq(lhs_t, rhs_t)) {
+ } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) {
return lhs_t;
}
code_err(ast, "I couldn't figure out how to do `and` between ", type_to_text(lhs_t), " and ",
@@ -1308,7 +1259,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
type_t *rhs_t = get_type(env, binop.rhs);
type_t *lhs_val = value_type(lhs_t), *rhs_val = value_type(rhs_t);
- if (type_eq(lhs_val, rhs_val) && lhs_val->tag == SetType) return lhs_val;
+ if (type_eq(lhs_val, rhs_val) && lhs_val->tag == TableType) return lhs_val;
if (binop.lhs->tag == Int && is_int_type(rhs_t)) return rhs_t;
else if (binop.rhs->tag == Int && is_int_type(lhs_t)) return lhs_t;
@@ -1329,7 +1280,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
&& lhs_t->tag != NumType && rhs_t->tag != NumType) {
if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t;
else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t;
- } else if (lhs_t->tag == SetType && rhs_t->tag == SetType && type_eq(lhs_t, rhs_t)) {
+ } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) {
return lhs_t;
}
code_err(ast, "I couldn't figure out how to do `xor` between ", type_to_text(lhs_t), " and ",
@@ -1369,7 +1320,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
if (ast->tag == Minus) {
type_t *lhs_val = value_type(lhs_t), *rhs_val = value_type(rhs_t);
- if (type_eq(lhs_val, rhs_val) && lhs_val->tag == SetType) return lhs_val;
+ if (type_eq(lhs_val, rhs_val) && lhs_val->tag == TableType) return lhs_val;
}
if (ast->tag == LeftShift || ast->tag == UnsignedLeftShift || ast->tag == RightShift
@@ -1457,7 +1408,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
binding_t *b = get_metamethod_binding(env, ast->tag, binop.lhs, binop.rhs, overall_t);
if (b) return overall_t;
- if (overall_t->tag == ListType || overall_t->tag == SetType || overall_t->tag == TextType) return overall_t;
+ if (overall_t->tag == ListType || overall_t->tag == TableType || overall_t->tag == TextType) return overall_t;
code_err(ast, "I don't know how to do concatenation between ", type_to_text(lhs_t), " and ",
type_to_text(rhs_t));
@@ -1847,12 +1798,6 @@ PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed) {
if (!can_compile_to_type(env, item->ast, item_type)) return false;
}
return true;
- } else if (needed->tag == SetType && ast->tag == Set) {
- type_t *item_type = Match(needed, SetType)->item_type;
- for (ast_list_t *item = Match(ast, Set)->items; item; item = item->next) {
- if (!can_compile_to_type(env, item->ast, item_type)) return false;
- }
- return true;
} else if (needed->tag == TableType && ast->tag == Table) {
type_t *key_type = Match(needed, TableType)->key_type;
type_t *value_type = Match(needed, TableType)->value_type;
diff --git a/src/types.c b/src/types.c
index 7db46b27..b4466b3b 100644
--- a/src/types.c
+++ b/src/types.c
@@ -39,10 +39,6 @@ Text_t type_to_text(type_t *t) {
DeclareMatch(table, t, TableType);
return Texts("{", type_to_text(table->key_type), "=", type_to_text(table->value_type), "}");
}
- case SetType: {
- DeclareMatch(set, t, SetType);
- return Texts("{", type_to_text(set->item_type), "}");
- }
case ClosureType: {
return type_to_text(Match(t, ClosureType)->fn);
}
@@ -227,7 +223,6 @@ PUREFUNC bool has_heap_memory(type_t *t) {
switch (t->tag) {
case ListType: return true;
case TableType: return true;
- case SetType: return true;
case PointerType: return true;
case OptionalType: return has_heap_memory(Match(t, OptionalType)->type);
case BigIntType: return true;
@@ -337,8 +332,6 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) {
// Empty literals:
if (actual->tag == ListType && needed->tag == ListType && Match(actual, ListType)->item_type == NULL)
return true; // [] -> [T]
- if (actual->tag == SetType && needed->tag == SetType && Match(actual, SetType)->item_type == NULL)
- return true; // || -> |T|
if (actual->tag == TableType && needed->tag == TableType && Match(actual, TableType)->key_type == NULL
&& Match(actual, TableType)->value_type == NULL)
return true; // {} -> {K=V}
@@ -378,11 +371,6 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) {
&& can_promote(actual_ret, needed_ret)));
}
- // 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;
}
@@ -472,7 +460,6 @@ 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 ListType: return sizeof(List_t);
- case SetType: return sizeof(Table_t);
case TableType: return sizeof(Table_t);
case FunctionType: return sizeof(void *);
case ClosureType: return sizeof(struct { void *fn, *userdata; });
@@ -563,7 +550,6 @@ 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 ListType: return __alignof__(List_t);
case TableType: return __alignof__(Table_t);
case FunctionType: return __alignof__(void *);
@@ -637,11 +623,6 @@ type_t *get_field_type(type_t *t, const char *field_name) {
}
return NULL;
}
- case SetType: {
- if (streq(field_name, "length")) return INT_TYPE;
- else if (streq(field_name, "items")) 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(ListType, Match(t, TableType)->key_type);
@@ -663,7 +644,6 @@ PUREFUNC type_t *get_iterated_type(type_t *t) {
case BigIntType:
case IntType: return iter_value_t; 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: {
@@ -684,7 +664,6 @@ CONSTFUNC bool is_incomplete_type(type_t *t) {
case ReturnType: return is_incomplete_type(Match(t, ReturnType)->ret);
case OptionalType: return is_incomplete_type(Match(t, OptionalType)->type);
case ListType: return is_incomplete_type(Match(t, ListType)->item_type);
- case SetType: return is_incomplete_type(Match(t, SetType)->item_type);
case TableType: {
DeclareMatch(table, t, TableType);
return is_incomplete_type(table->key_type) || is_incomplete_type(table->value_type);
@@ -724,10 +703,6 @@ CONSTFUNC type_t *most_complete_type(type_t *t1, type_t *t2) {
type_t *item = most_complete_type(Match(t1, ListType)->item_type, Match(t2, ListType)->item_type);
return item ? Type(ListType, item) : NULL;
}
- case SetType: {
- type_t *item = most_complete_type(Match(t1, SetType)->item_type, Match(t2, SetType)->item_type);
- return item ? Type(SetType, item) : NULL;
- }
case TableType: {
DeclareMatch(table1, t1, TableType);
DeclareMatch(table2, t2, TableType);
diff --git a/src/types.h b/src/types.h
index 24c4e621..05a97333 100644
--- a/src/types.h
+++ b/src/types.h
@@ -50,7 +50,6 @@ struct type_s {
CStringType,
TextType,
ListType,
- SetType,
TableType,
FunctionType,
ClosureType,
@@ -88,9 +87,6 @@ struct type_s {
type_t *item_type;
} ListType;
struct {
- type_t *item_type;
- } SetType;
- struct {
type_t *key_type, *value_type;
struct env_s *env;
ast_t *default_value;