From 71f73d8b3ce63f9a3685bc1a1686ef4fab3294a6 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 21 Sep 2025 15:43:59 -0400 Subject: Deprecate sets --- src/ast.c | 6 -- src/ast.h | 8 --- src/compile/binops.c | 18 +++--- src/compile/compilation.h | 1 - src/compile/conditionals.c | 2 +- src/compile/expressions.c | 14 +---- src/compile/fieldaccess.c | 7 --- src/compile/functions.c | 11 +--- src/compile/indexing.c | 2 +- src/compile/lists.c | 2 +- src/compile/loops.c | 39 +++++-------- src/compile/optionals.c | 3 +- src/compile/pointers.c | 2 +- src/compile/promotions.c | 9 --- src/compile/sets.c | 138 --------------------------------------------- src/compile/sets.h | 11 ---- src/compile/text.c | 1 - src/compile/types.c | 8 +-- src/environment.c | 9 --- src/formatter/formatter.c | 14 ++--- src/formatter/types.c | 3 - src/parse/containers.c | 30 ---------- src/parse/containers.h | 1 - src/parse/expressions.c | 9 ++- src/parse/types.c | 17 +----- src/parse/types.h | 1 - src/stdlib/tables.c | 12 ++-- src/stdlib/tables.h | 20 +------ src/typecheck.c | 73 +++--------------------- src/types.c | 25 -------- src/types.h | 4 -- test/enums.tm | 2 +- test/optionals.tm | 6 +- test/serialization.tm | 5 -- test/sets.tm | 52 ----------------- test/structs.tm | 4 +- test/tables.tm | 3 - 37 files changed, 70 insertions(+), 502 deletions(-) delete mode 100644 src/compile/sets.c delete mode 100644 src/compile/sets.h delete mode 100644 test/sets.tm 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, @@ -120,9 +119,6 @@ struct type_ast_s { type_ast_t *key, *value; ast_t *default_value; } TableTypeAST; - struct { - type_ast_t *item; - } SetTypeAST; struct { arg_ast_t *args; type_ast_t *ret; @@ -248,7 +244,6 @@ typedef enum { Min, Max, List, - Set, Table, TableEntry, Comprehension, @@ -342,9 +337,6 @@ struct ast_s { struct { ast_list_t *items; } List; - struct { - ast_list_t *items; - } Set; struct { ast_t *default_value; ast_t *fallback; 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, @@ -87,9 +86,6 @@ struct type_s { struct { type_t *item_type; } ListType; - struct { - type_t *item_type; - } SetType; struct { type_t *key_type, *value_type; struct env_s *env; diff --git a/test/enums.tm b/test/enums.tm index d07182cc..0cef37cf 100644 --- a/test/enums.tm +++ b/test/enums.tm @@ -53,7 +53,7 @@ func main() assert Foo.One(10) < Foo.Two(1, 2) >> x := Foo.One(123) - >> t := |x| + >> t := {x=yes} >> t.has(x) = yes >> t.has(Foo.Zero) diff --git a/test/optionals.tm b/test/optionals.tm index 7bdd2fd1..1f7d640e 100644 --- a/test/optionals.tm +++ b/test/optionals.tm @@ -243,9 +243,9 @@ func main() # Test comparisons, hashing, equality: assert none != 5? assert 5? == 5? - >> nones : |Int?| = |none, none| - >> also_nones : |Int?| = |none| - >> nones == also_nones + >> nones : {Int?=Bool} = {none=yes, none=yes} + >> nones.keys + = [none] >> [5?, none, none, 6?].sorted() = [none, none, 5, 6] diff --git a/test/serialization.tm b/test/serialization.tm index 8e1a4a1c..e2fa38a3 100644 --- a/test/serialization.tm +++ b/test/serialization.tm @@ -66,11 +66,6 @@ func main() >> bytes := obj.serialized() assert deserialize(bytes -> Text?) == obj - do - >> obj := |10, 20, 30| - >> bytes := obj.serialized() - assert deserialize(bytes -> |Int|) == obj - do >> obj : Num? = none >> bytes := obj.serialized() diff --git a/test/sets.tm b/test/sets.tm deleted file mode 100644 index b30c2ce3..00000000 --- a/test/sets.tm +++ /dev/null @@ -1,52 +0,0 @@ - -func main() - t1 := @|10, 20, 30, 10| - >> t1[] - = |10, 20, 30| - >> t1.has(10) - = yes - >> t1.has(-999) - = no - - >> t2 := |30, 40| - - >> t1.with(t2) - >> |10, 20, 30, 40| - - >> t1.without(t2) - >> |10, 20| - - >> t1.overlap(t2) - >> |30| - - - >> |1,2|.is_subset_of(|2,3|) - = no - >> |1,2|.is_subset_of(|1,2,3|) - = yes - >> |1,2|.is_subset_of(|1,2|) - = yes - >> |1,2|.is_subset_of(|1,2|, strict=yes) - = no - - >> t1.add_all(t2) - >> t1[] - = |10, 20, 30, 40| - >> t1.remove_all(t2) - >> t1[] - = |10, 20| - - >> |3, i for i in 5| - = |3, 1, 2, 4, 5| - - >> empty : |Int| = || - = || - - >> |1,2,3| or |3,4| - = |1,2,3,4| - >> |1,2,3| and |3,4| - = |3| - >> |1,2,3| xor |3,4| - = |1,2,4| - >> |1,2,3| - |3,4| - >> |1,2| diff --git a/test/structs.tm b/test/structs.tm index 40c1b566..2440911b 100644 --- a/test/structs.tm +++ b/test/structs.tm @@ -27,7 +27,7 @@ func test_metamethods() assert x != Pair(10, 30) assert x < Pair(11, 20) - >> set := |x| + >> set := {x=yes} >> set.has(x) = yes >> set.has(y) @@ -41,7 +41,7 @@ func test_mixed() assert x == Mixed(10, "Hello") assert x != Mixed(10, "Bye") assert x < Mixed(11, "Hello") - >> set := |x| + >> set := {x=yes} >> set.has(x) = yes >> set.has(y) diff --git a/test/tables.tm b/test/tables.tm index 1f4244f9..587a02c8 100644 --- a/test/tables.tm +++ b/test/tables.tm @@ -97,9 +97,6 @@ func main() >> ints : [{Int=Int}] = [{}, {0=0}, {99=99}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 2=-99, 3=3}, {1=1, 99=-99, 3=4}].sorted() = [{}, {0=0}, {1=1, 2=-99, 3=3}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 99=-99, 3=4}, {99=99}] - >> other_ints : [|Int|] = [||, |1|, |2|, |99|, |0, 3|, |1, 2|, |99|].sorted() - = [||, |0, 3|, |1|, |1, 2|, |2|, |99|, |99|] - do # Default values: counter := &{"x"=10; default=0} -- cgit v1.2.3