commit 7ddee65caba586b6d5e7004762cd754e21f1d19c
parent 2f027c25a33eb5827d05f65f7fd123609c03b2f9
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 18 Dec 2020 12:24:12 -0500
Scan function types
Diffstat:
5 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -46,7 +46,7 @@ struct ast_function_parameters {
struct ast_function_type {
struct ast_type *result;
- struct ast_function_parameters *parameters;
+ struct ast_function_parameters *params;
enum variadism variadism;
unsigned int flags; // enum function_flags (types.h)
};
@@ -74,7 +74,7 @@ struct ast_type {
struct identifier alias;
struct ast_list_type array;
struct ast_enum_type _enum;
- struct ast_function_type function;
+ struct ast_function_type func;
struct ast_pointer_type pointer;
struct ast_list_type slice;
struct ast_struct_union_type _struct;
diff --git a/include/types.h b/include/types.h
@@ -52,7 +52,7 @@ enum function_flags {
struct type_func_param {
const struct type *type;
- struct type_func_parameter *next;
+ struct type_func_param *next;
};
struct type_func {
@@ -80,6 +80,7 @@ struct type {
unsigned int flags;
size_t size, align;
union {
+ struct type_func func;
struct type_pointer pointer;
};
};
diff --git a/src/check.c b/src/check.c
@@ -14,11 +14,11 @@ scan_function(struct context *ctx, const struct ast_function_decl *decl)
const struct ast_type fn_atype = {
.storage = TYPE_STORAGE_FUNCTION,
.flags = TYPE_CONST,
- .function = decl->prototype,
+ .func = decl->prototype,
};
const struct type *fntype = type_store_lookup_atype(
&ctx->store, &fn_atype);
- assert(fntype);
+ assert(fntype); // TODO: Forward references
}
static void
@@ -47,8 +47,13 @@ check(const struct ast_unit *aunit, struct unit *unit)
struct context ctx = {0};
const struct ast_subunit *su = &aunit->subunits;
assert(su); // At least one is required
+
+ // First pass populates the type graph
while (su) {
scan_declarations(&ctx, &su->decls);
su = su->next;
}
+
+ // Second pass populates the expression graph
+ // TODO
}
diff --git a/src/parse.c b/src/parse.c
@@ -161,7 +161,7 @@ parse_parameter_list(struct parser *par, struct ast_function_type *type)
trenter(TR_PARSE, "parameter-list");
struct token tok = {0};
bool more = true;
- struct ast_function_parameters **next = &type->parameters;
+ struct ast_function_parameters **next = &type->params;
while (more) {
*next = calloc(1, sizeof(struct ast_function_parameters));
(*next)->type = calloc(1, sizeof(struct ast_type));
@@ -218,8 +218,8 @@ parse_prototype(struct parser *par, struct ast_function_type *type)
type->result = calloc(1, sizeof(struct ast_type));
parse_type(par, type->result);
size_t ctr = 0;
- for (struct ast_function_parameters *param = type->parameters; param;
- param = param->next) {
+ for (struct ast_function_parameters *param = type->params;
+ param; param = param->next) {
ctr++;
}
trace(TR_PARSE, "[%zu parameters] [type]", ctr);
@@ -317,12 +317,12 @@ parse_type(struct parser *par, struct ast_type *type)
case T_LBRACKET:
assert(0); // TODO: Slices/arrays
case T_ATTR_NORETURN:
- type->function.flags |= FN_NORETURN;
+ type->func.flags |= FN_NORETURN;
want(par, T_FN, NULL);
/* fallthrough */
case T_FN:
type->storage = TYPE_STORAGE_FUNCTION;
- parse_prototype(par, &type->function);
+ parse_prototype(par, &type->func);
break;
default:
unlex(par->lex, &tok);
diff --git a/src/type_store.c b/src/type_store.c
@@ -32,6 +32,14 @@ atype_hash(struct type_store *store, const struct ast_type *type)
case TYPE_STORAGE_ALIAS:
case TYPE_STORAGE_ARRAY:
case TYPE_STORAGE_FUNCTION:
+ hash = djb2(hash, atype_hash(store, type->func.result));
+ hash = djb2(hash, type->func.variadism);
+ hash = djb2(hash, type->func.flags);
+ for (struct ast_function_parameters *param = type->func.params;
+ param; param = param->next) {
+ hash = djb2(hash, atype_hash(store, param->type));
+ }
+ break;
case TYPE_STORAGE_POINTER:
case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_STRING:
@@ -72,6 +80,14 @@ type_hash(struct type_store *store, const struct type *type)
case TYPE_STORAGE_ALIAS:
case TYPE_STORAGE_ARRAY:
case TYPE_STORAGE_FUNCTION:
+ hash = djb2(hash, type_hash(store, type->func.result));
+ hash = djb2(hash, type->func.variadism);
+ hash = djb2(hash, type->func.flags);
+ for (struct type_func_param *param = type->func.params;
+ param; param = param->next) {
+ hash = djb2(hash, type_hash(store, param->type));
+ }
+ break;
case TYPE_STORAGE_POINTER:
case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_STRING:
@@ -218,7 +234,14 @@ type_init_from_atype(struct type_store *store,
assert(0); // Invariant
case TYPE_STORAGE_ALIAS:
case TYPE_STORAGE_ARRAY:
+ assert(0); // TODO
case TYPE_STORAGE_FUNCTION:
+ type->func.result =
+ type_store_lookup_atype(store, atype->func.result);
+ type->func.variadism = atype->func.variadism;
+ type->func.flags = atype->func.flags;
+ assert(!atype->func.params); // TODO
+ break;
case TYPE_STORAGE_POINTER:
case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_STRING: