aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compile.c17
-rw-r--r--src/environment.c3
-rw-r--r--src/typecheck.c3
-rw-r--r--src/types.c11
-rw-r--r--src/types.h2
5 files changed, 21 insertions, 15 deletions
diff --git a/src/compile.c b/src/compile.c
index 5c033ef4..1df56f3e 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -3018,8 +3018,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD comparison;
if (call->args) {
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
- type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=TYPE_IBITS32));
+ type_t *fn_t = NewFunctionType(Type(IntType, .bits=TYPE_IBITS32), {.name="x", .type=item_ptr}, {.name="y", .type=item_ptr});
arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t));
comparison = compile_arguments(env, ast, arg_spec, call->args);
} else {
@@ -3031,8 +3030,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD comparison;
if (call->args) {
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
- type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=TYPE_IBITS32));
+ type_t *fn_t = NewFunctionType(Type(IntType, .bits=TYPE_IBITS32), {.name="x", .type=item_ptr}, {.name="y", .type=item_ptr});
arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t));
comparison = compile_arguments(env, ast, arg_spec, call->args);
} else {
@@ -3042,8 +3040,7 @@ CORD compile(env_t *env, ast_t *ast)
} else if (streq(call->name, "heap_push")) {
EXPECT_POINTER("an", "array");
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
- type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=TYPE_IBITS32));
+ type_t *fn_t = NewFunctionType(Type(IntType, .bits=TYPE_IBITS32), {.name="x", .type=item_ptr}, {.name="y", .type=item_ptr});
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((Closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(item_t), "})"),
@@ -3055,8 +3052,7 @@ CORD compile(env_t *env, ast_t *ast)
} else if (streq(call->name, "heap_pop")) {
EXPECT_POINTER("an", "array");
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
- type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=TYPE_IBITS32));
+ type_t *fn_t = NewFunctionType(Type(IntType, .bits=TYPE_IBITS32), {.name="x", .type=item_ptr}, {.name="y", .type=item_ptr});
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((Closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(item_t), "})"),
@@ -3068,8 +3064,7 @@ CORD compile(env_t *env, ast_t *ast)
} else if (streq(call->name, "binary_search")) {
self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL);
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
- type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=TYPE_IBITS32));
+ type_t *fn_t = NewFunctionType(Type(IntType, .bits=TYPE_IBITS32), {.name="x", .type=item_ptr}, {.name="y", .type=item_ptr});
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((Closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(item_t), "})"),
@@ -3091,7 +3086,7 @@ CORD compile(env_t *env, ast_t *ast)
self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL);
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *predicate_type = Type(
- ClosureType, .fn=Type(FunctionType, .args=new(arg_t, .name="item", .type=item_ptr), .ret=Type(BoolType)));
+ ClosureType, .fn=NewFunctionType(Type(BoolType), {.name="item", .type=item_ptr}));
arg_t *arg_spec = new(arg_t, .name="predicate", .type=predicate_type);
return CORD_all("Array$first(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")");
} else if (streq(call->name, "from")) {
diff --git a/src/environment.c b/src/environment.c
index a6a450e8..21d3db9b 100644
--- a/src/environment.c
+++ b/src/environment.c
@@ -497,8 +497,7 @@ env_t *global_env(void)
#undef ADD_CONSTRUCTORS
set_binding(namespace_env(env, "Path"), "from_text",
- Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
- .ret=PATH_TYPE),
+ NewFunctionType(PATH_TYPE, {.name="text", .type=TEXT_TYPE}),
"Path$from_text");
struct {
diff --git a/src/typecheck.c b/src/typecheck.c
index a1a77b5f..fed02ec6 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -443,8 +443,7 @@ void bind_statement(env_t *env, ast_t *statement)
type_t *type = Type(TextType, .lang=def->name, .env=ns_env);
Table$str_set(env->types, def->name, type);
- set_binding(ns_env, "from_text",
- Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type),
+ set_binding(ns_env, "from_text", NewFunctionType(type, {.name="text", .type=TEXT_TYPE}),
CORD_all("(", namespace_prefix(env, env->namespace), def->name, "$$type)"));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
diff --git a/src/types.c b/src/types.c
index 0b69a8c4..0433cc48 100644
--- a/src/types.c
+++ b/src/types.c
@@ -822,4 +822,15 @@ CONSTFUNC type_t *most_complete_type(type_t *t1, type_t *t2)
}
}
+type_t *_make_function_type(type_t *ret, int n, arg_t args[n])
+{
+ arg_t *arg_pointers = GC_MALLOC(sizeof(arg_t[n]));
+ for (int i = 0; i < n; i++) {
+ arg_pointers[i] = args[i];
+ if (i + 1 < n)
+ arg_pointers[i].next = &arg_pointers[i+1];
+ }
+ return Type(FunctionType, .ret=ret, .args=&arg_pointers[0]);
+}
+
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/types.h b/src/types.h
index 53488584..2d2bd2a3 100644
--- a/src/types.h
+++ b/src/types.h
@@ -130,6 +130,7 @@ struct type_s {
#define Type(typetag, ...) new(type_t, .tag=typetag, .__data.typetag={__VA_ARGS__})
#define INT_TYPE Type(BigIntType)
#define NUM_TYPE Type(NumType, .bits=TYPE_NBITS64)
+#define NewFunctionType(ret, ...) _make_function_type(ret, sizeof((arg_t[]){__VA_ARGS__})/sizeof(arg_t), (arg_t[]){__VA_ARGS__})
CORD type_to_cord(type_t *t);
const char *type_to_str(type_t *t);
@@ -155,5 +156,6 @@ PUREFUNC size_t unpadded_struct_size(type_t *t);
PUREFUNC type_t *non_optional(type_t *t);
type_t *get_field_type(type_t *t, const char *field_name);
PUREFUNC type_t *get_iterated_type(type_t *t);
+type_t *_make_function_type(type_t *ret, int n, arg_t args[n]);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0