aboutsummaryrefslogtreecommitdiff
path: root/src/compile/sets.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile/sets.c')
-rw-r--r--src/compile/sets.c138
1 files changed, 0 insertions, 138 deletions
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");
-}