Fix cyclic structs/enums
This commit is contained in:
parent
e29aa52460
commit
103edd6362
@ -112,7 +112,7 @@ public bool generic_equal(const void *x, const void *y, const TypeInfo *type)
|
||||
public CORD generic_as_text(const void *obj, bool colorize, const TypeInfo *type)
|
||||
{
|
||||
switch (type->tag) {
|
||||
case PointerInfo: return Pointer__cord(obj, colorize, type);
|
||||
case PointerInfo: return Pointer__as_text(obj, colorize, type);
|
||||
case FunctionInfo: return Func__as_text(obj, colorize, type);
|
||||
case ArrayInfo: return Array__as_text(obj, colorize, type);
|
||||
case TableInfo: return Table_as_text(obj, colorize, type);
|
||||
|
@ -18,7 +18,7 @@ typedef struct recursion_s {
|
||||
struct recursion_s *next;
|
||||
} recursion_t;
|
||||
|
||||
public CORD Pointer__cord(const void *x, bool colorize, const TypeInfo *type) {
|
||||
public CORD Pointer__as_text(const void *x, bool colorize, const TypeInfo *type) {
|
||||
auto ptr_info = type->PointerInfo;
|
||||
if (!x) {
|
||||
CORD typename = generic_as_text(NULL, false, ptr_info.pointed);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
CORD Pointer__cord(const void *x, bool colorize, const TypeInfo *type);
|
||||
CORD Pointer__as_text(const void *x, bool colorize, const TypeInfo *type);
|
||||
int32_t Pointer__compare(const void *x, const void *y, const TypeInfo *type);
|
||||
bool Pointer__equal(const void *x, const void *y, const TypeInfo *type);
|
||||
uint32_t Pointer__hash(const void *x, const TypeInfo *type);
|
||||
|
16
typecheck.c
16
typecheck.c
@ -118,14 +118,18 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
env_t *ns_env = namespace_env(env, def->name);
|
||||
|
||||
arg_t *fields = NULL;
|
||||
type_t *type = Type(StructType, .name=def->name, .fields=fields); // placeholder
|
||||
type_t *type = Type(StructType, .name=def->name, .fields=fields, .opaque=true); // placeholder
|
||||
Table_str_set(env->types, def->name, type);
|
||||
for (arg_ast_t *field_ast = def->fields; field_ast; field_ast = field_ast->next) {
|
||||
type_t *field_t = parse_type_ast(env, field_ast->type);
|
||||
if ((field_t->tag == StructType && Match(field_t, StructType)->opaque)
|
||||
|| (field_t->tag == EnumType && Match(field_t, EnumType)->opaque))
|
||||
code_err(field_ast->type, "This type is recursive and would create an infinitely sized struct. Try using a pointer.");
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields);
|
||||
}
|
||||
REVERSE_LIST(fields);
|
||||
type->__data.StructType.fields = fields; // populate placeholder
|
||||
Table_str_set(env->types, def->name, type);
|
||||
type->__data.StructType.opaque = false;
|
||||
|
||||
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) {
|
||||
bind_statement(ns_env, stmt->ast);
|
||||
@ -141,11 +145,15 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
env_t *ns_env = namespace_env(env, def->name);
|
||||
|
||||
tag_t *tags = NULL;
|
||||
type_t *type = Type(EnumType, .name=def->name, .tags=tags); // placeholder
|
||||
type_t *type = Type(EnumType, .name=def->name, .tags=tags, .opaque=true); // placeholder
|
||||
Table_str_set(env->types, def->name, type);
|
||||
for (tag_ast_t *tag_ast = def->tags; tag_ast; tag_ast = tag_ast->next) {
|
||||
arg_t *fields = NULL;
|
||||
for (arg_ast_t *field_ast = tag_ast->fields; field_ast; field_ast = field_ast->next) {
|
||||
type_t *field_t = parse_type_ast(env, field_ast->type);
|
||||
if ((field_t->tag == StructType && Match(field_t, StructType)->opaque)
|
||||
|| (field_t->tag == EnumType && Match(field_t, EnumType)->opaque))
|
||||
code_err(field_ast->type, "This type is recursive and would create an infinitely sized struct. Try using a pointer.");
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields);
|
||||
}
|
||||
REVERSE_LIST(fields);
|
||||
@ -154,13 +162,13 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
}
|
||||
REVERSE_LIST(tags);
|
||||
type->__data.EnumType.tags = tags;
|
||||
type->__data.EnumType.opaque = false;
|
||||
|
||||
for (tag_t *tag = tags; tag; tag = tag->next) {
|
||||
type_t *constructor_t = Type(FunctionType, .args=Match(tag->type, StructType)->fields, .ret=type);
|
||||
set_binding(ns_env, tag->name, new(binding_t, .type=constructor_t, .code=CORD_all(def->name, "$tagged$", tag->name)));
|
||||
Table_str_set(env->types, heap_strf("%s$%s", def->name, tag->name), tag->type);
|
||||
}
|
||||
Table_str_set(env->types, def->name, type);
|
||||
|
||||
type_t *typeinfo_type = Type(TypeInfoType, .name=def->name, .type=type);
|
||||
Table_str_set(env->globals, def->name, new(binding_t, .type=typeinfo_type));
|
||||
|
Loading…
Reference in New Issue
Block a user