aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compile.c50
-rw-r--r--src/compile.h1
-rw-r--r--src/compile/list.c61
-rw-r--r--src/compile/list.h5
-rw-r--r--src/environment.h1
5 files changed, 70 insertions, 48 deletions
diff --git a/src/compile.c b/src/compile.c
index 262608c5..b5e22342 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -8,6 +8,7 @@
#include "ast.h"
#include "compile.h"
+#include "compile/list.h"
#include "config.h"
#include "enums.h"
#include "environment.h"
@@ -35,14 +36,11 @@ static Text_t promote_to_optional(type_t *t, Text_t code);
static Text_t compile_none(type_t *t);
static Text_t compile_empty(type_t *t);
static Text_t compile_declared_value(env_t *env, ast_t *declaration_ast);
-static Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t);
-static Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type);
static Text_t compile_typed_set(env_t *env, ast_t *ast, type_t *set_type);
static Text_t compile_typed_table(env_t *env, ast_t *ast, type_t *table_type);
static Text_t compile_typed_allocation(env_t *env, ast_t *ast, type_t *pointer_type);
static Text_t check_none(type_t *t, Text_t value);
static Text_t optional_into_nonnone(type_t *t, Text_t value);
-static ast_t *add_to_list_comprehension(ast_t *item, ast_t *subject);
static ast_t *add_to_table_comprehension(ast_t *entry, ast_t *subject);
static ast_t *add_to_set_comprehension(ast_t *item, ast_t *subject);
static Text_t compile_lvalue(env_t *env, ast_t *ast);
@@ -2111,6 +2109,7 @@ Text_t compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bo
return val;
}
+public
Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) {
assert(!is_incomplete_type(t));
if (ast->tag == Int && is_numeric_type(non_optional(t))) {
@@ -2188,47 +2187,6 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) {
code_err(ast, "I expected a ", type_to_str(t), " here, but this is a ", type_to_str(actual));
}
-Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) {
- DeclareMatch(list, ast, List);
- if (!list->items) return Text("(List_t){.length=0}");
-
- type_t *item_type = Match(list_type, ListType)->item_type;
-
- int64_t n = 0;
- for (ast_list_t *item = list->items; item; item = item->next) {
- ++n;
- if (item->ast->tag == Comprehension) goto list_comprehension;
- }
-
- {
- env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env;
- if (is_incomplete_type(item_type)) code_err(ast, "This list's type can't be inferred!");
- Text_t code = Texts("TypedListN(", compile_type(item_type), ", ", String(n));
- for (ast_list_t *item = list->items; item; item = item->next) {
- code = Texts(code, ", ", compile_to_type(scope, item->ast, item_type));
- }
- return Texts(code, ")");
- }
-
-list_comprehension: {
- env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env);
- static int64_t comp_num = 1;
- const char *comprehension_name = String("list$", comp_num++);
- ast_t *comprehension_var =
- LiteralCode(Texts("&", comprehension_name), .type = Type(PointerType, .pointed = list_type, .is_stack = true));
- Closure_t comp_action = {.fn = add_to_list_comprehension, .userdata = comprehension_var};
- scope->comprehension_action = &comp_action;
- Text_t code = Texts("({ List_t ", comprehension_name, " = {};");
- // set_binding(scope, comprehension_name, list_type, comprehension_name);
- for (ast_list_t *item = list->items; item; item = item->next) {
- if (item->ast->tag == Comprehension) code = Texts(code, "\n", compile_statement(scope, item->ast));
- else code = Texts(code, compile_statement(env, add_to_list_comprehension(item->ast, comprehension_var)));
- }
- code = Texts(code, " ", comprehension_name, "; })");
- return code;
-}
-}
-
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){})");
@@ -2667,10 +2625,6 @@ ast_t *add_to_table_comprehension(ast_t *entry, ast_t *subject) {
.args = new (arg_ast_t, .value = e->key, .next = new (arg_ast_t, .value = e->value)));
}
-ast_t *add_to_list_comprehension(ast_t *item, ast_t *subject) {
- return WrapAST(item, MethodCall, .name = "insert", .self = subject, .args = new (arg_ast_t, .value = item));
-}
-
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));
}
diff --git a/src/compile.h b/src/compile.h
index 21176395..56b522c7 100644
--- a/src/compile.h
+++ b/src/compile.h
@@ -7,6 +7,7 @@
#include "environment.h"
#include "stdlib/datatypes.h"
+Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t);
Text_t expr_as_text(Text_t expr, type_t *t, Text_t color);
Text_t compile_file(env_t *env, ast_t *ast);
Text_t compile_file_header(env_t *env, Path_t header_path, ast_t *ast);
diff --git a/src/compile/list.c b/src/compile/list.c
new file mode 100644
index 00000000..01036cda
--- /dev/null
+++ b/src/compile/list.c
@@ -0,0 +1,61 @@
+// Compilation logic for lists
+
+#include <gc.h>
+#include <glob.h>
+#include <gmp.h>
+#include <uninorm.h>
+
+#include "../ast.h"
+#include "../compile.h"
+#include "../config.h"
+#include "../environment.h"
+#include "../stdlib/text.h"
+#include "../stdlib/util.h"
+
+static ast_t *add_to_list_comprehension(ast_t *item, ast_t *subject) {
+ return WrapAST(item, MethodCall, .name = "insert", .self = subject, .args = new (arg_ast_t, .value = item));
+}
+
+public
+Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) {
+ DeclareMatch(list, ast, List);
+ if (!list->items) return Text("(List_t){.length=0}");
+
+ type_t *item_type = Match(list_type, ListType)->item_type;
+
+ int64_t n = 0;
+ for (ast_list_t *item = list->items; item; item = item->next) {
+ ++n;
+ if (item->ast->tag == Comprehension) goto list_comprehension;
+ }
+
+ {
+ env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : env;
+ if (is_incomplete_type(item_type)) code_err(ast, "This list's type can't be inferred!");
+ Text_t code = Texts("TypedListN(", compile_type(item_type), ", ", String(n));
+ for (ast_list_t *item = list->items; item; item = item->next) {
+ code = Texts(code, ", ", compile_to_type(scope, item->ast, item_type));
+ }
+ return Texts(code, ")");
+ }
+
+list_comprehension: {
+ env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env);
+ static int64_t comp_num = 1;
+ const char *comprehension_name = String("list$", comp_num++);
+ ast_t *comprehension_var =
+ LiteralCode(Texts("&", comprehension_name), .type = Type(PointerType, .pointed = list_type, .is_stack = true));
+ Closure_t comp_action = {.fn = add_to_list_comprehension, .userdata = comprehension_var};
+ scope->comprehension_action = &comp_action;
+ Text_t code = Texts("({ List_t ", comprehension_name, " = {};");
+ // set_binding(scope, comprehension_name, list_type, comprehension_name);
+ for (ast_list_t *item = list->items; item; item = item->next) {
+ if (item->ast->tag == Comprehension) code = Texts(code, "\n", compile_statement(scope, item->ast));
+ else code = Texts(code, compile_statement(env, add_to_list_comprehension(item->ast, comprehension_var)));
+ }
+ code = Texts(code, " ", comprehension_name, "; })");
+ return code;
+}
+}
+
+// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/compile/list.h b/src/compile/list.h
new file mode 100644
index 00000000..b9bf74d6
--- /dev/null
+++ b/src/compile/list.h
@@ -0,0 +1,5 @@
+#include "../ast.h"
+#include "../environment.h"
+#include "../stdlib/datatypes.h"
+
+Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type);
diff --git a/src/environment.h b/src/environment.h
index ca10dbae..2c646ad3 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -4,6 +4,7 @@
#include "stdlib/datatypes.h"
#include "stdlib/print.h"
+#include "stdlib/stdlib.h"
#include "types.h"
typedef struct {