Files
Odin/src/checker/entity.cpp
Ginger Bill 50301557b2 Untyped nil
2016-10-06 17:11:17 +01:00

172 lines
4.4 KiB
C++

struct Scope;
struct Checker;
enum BuiltinProcId;
#define ENTITY_KINDS \
ENTITY_KIND(Invalid), \
ENTITY_KIND(Constant), \
ENTITY_KIND(Variable), \
ENTITY_KIND(TypeName), \
ENTITY_KIND(Procedure), \
ENTITY_KIND(Builtin), \
ENTITY_KIND(ImportName), \
ENTITY_KIND(Nil), \
ENTITY_KIND(Count),
enum EntityKind {
#define ENTITY_KIND(k) GB_JOIN2(Entity_, k)
ENTITY_KINDS
#undef ENTITY_KIND
};
String const entity_strings[] = {
#define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1}
ENTITY_KINDS
#undef ENTITY_KIND
};
typedef struct Type Type;
struct Entity {
EntityKind kind;
Scope * scope;
Token token;
Type * type;
AstNode * identifier; // Can be NULL
Entity * using_parent;
AstNode * using_expr;
union {
struct {
ExactValue value;
} Constant;
struct {
b8 visited; // Cycle detection
b8 used; // Variable is used
b8 anonymous; // Variable is an anonymous
b8 is_using; // `using` variable
i32 field_index;
i32 field_src_index;
b8 is_field; // Is struct field
} Variable;
struct {
b32 used;
} TypeName;
struct {
b32 used;
} Procedure;
struct {
BuiltinProcId id;
} Builtin;
struct {
String path;
String name;
Scope *scope;
b32 used;
} ImportName;
struct {
} Nil;
};
};
b32 is_entity_exported(Entity *e) {
if (e->kind == Entity_ImportName) {
return false;
}
// TODO(bill): Do I really want non-exported entities?
// if (e->token.string.len >= 1 &&
// e->token.string.text[0] == '_') {
// return false;
// }
return true;
}
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
Entity *entity = gb_alloc_item(a, Entity);
entity->kind = kind;
entity->scope = scope;
entity->token = token;
entity->type = type;
return entity;
}
Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type) {
Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type);
return entity;
}
Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, Type *type) {
GB_ASSERT(parent != NULL);
Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
entity->using_parent = parent;
entity->Variable.is_using = true;
return entity;
}
Entity *make_entity_constant(gbAllocator a, Scope *scope, Token token, Type *type, ExactValue value) {
Entity *entity = alloc_entity(a, Entity_Constant, scope, token, type);
entity->Constant.value = value;
return entity;
}
Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type) {
Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type);
return entity;
}
Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, b32 is_anonymous) {
Entity *entity = make_entity_variable(a, scope, token, type);
entity->Variable.used = true;
entity->Variable.anonymous = cast(b8)is_anonymous;
return entity;
}
Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, b32 is_anonymous, i32 field_src_index) {
Entity *entity = make_entity_variable(a, scope, token, type);
entity->Variable.field_src_index = field_src_index;
entity->Variable.field_index = field_src_index;
entity->Variable.is_field = true;
entity->Variable.anonymous = cast(b8)is_anonymous;
entity->Variable.is_using = cast(b8)is_anonymous;
return entity;
}
Entity *make_entity_procedure(gbAllocator a, Scope *scope, Token token, Type *signature_type) {
Entity *entity = alloc_entity(a, Entity_Procedure, scope, token, signature_type);
return entity;
}
Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, BuiltinProcId id) {
Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type);
entity->Builtin.id = id;
return entity;
}
Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *type,
String path, String name, Scope *import_scope) {
Entity *entity = alloc_entity(a, Entity_ImportName, scope, token, type);
entity->ImportName.path = path;
entity->ImportName.name = name;
entity->ImportName.scope = import_scope;
return entity;
}
Entity *make_entity_nil(gbAllocator a, Scope *scope, Token token, Type *type) {
Entity *entity = alloc_entity(a, Entity_Nil, scope, token, type);
return entity;
}
Entity *make_entity_dummy_variable(gbAllocator a, Scope *file_scope, Token token) {
token.string = make_string("_");
return make_entity_variable(a, file_scope, token, NULL);
}