From 89754ac89dd1d568ab0ff14d145cae259d9db66f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 6 Apr 2025 18:04:35 -0400 Subject: Make it a bit more ergonomic to make function types --- src/compile.c | 17 ++++++----------- src/environment.c | 3 +-- src/typecheck.c | 3 +-- src/types.c | 11 +++++++++++ src/types.h | 2 ++ 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 -- cgit v1.2.3