aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp380
1 files changed, 4 insertions, 376 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 06b65c1ec..55df36fb4 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1,150 +1,6 @@
#include "entity.cpp"
-
-enum ExprKind {
- Expr_Expr,
- Expr_Stmt,
-};
-
-// Statements and Declarations
-enum StmtFlag {
- Stmt_BreakAllowed = 1<<0,
- Stmt_ContinueAllowed = 1<<1,
- Stmt_FallthroughAllowed = 1<<2,
-
- Stmt_CheckScopeDecls = 1<<5,
-};
-
-struct BuiltinProc {
- String name;
- isize arg_count;
- bool variadic;
- ExprKind kind;
-};
-enum BuiltinProcId {
- BuiltinProc_Invalid,
-
- BuiltinProc_len,
- BuiltinProc_cap,
-
- // BuiltinProc_new,
- BuiltinProc_make,
- // BuiltinProc_free,
-
- // BuiltinProc_reserve,
- // BuiltinProc_clear,
- // BuiltinProc_append,
- // BuiltinProc_delete,
-
- BuiltinProc_size_of,
- BuiltinProc_align_of,
- BuiltinProc_offset_of,
- BuiltinProc_type_of,
- BuiltinProc_type_info_of,
-
- BuiltinProc_compile_assert,
-
- BuiltinProc_swizzle,
-
- BuiltinProc_complex,
- BuiltinProc_real,
- BuiltinProc_imag,
- BuiltinProc_conj,
-
- // BuiltinProc_slice_ptr,
- // BuiltinProc_slice_to_bytes,
-
- BuiltinProc_expand_to_tuple,
-
- BuiltinProc_min,
- BuiltinProc_max,
- BuiltinProc_abs,
- BuiltinProc_clamp,
-
- BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
-
- BuiltinProc_COUNT,
-};
-gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
- {STR_LIT(""), 0, false, Expr_Stmt},
-
- {STR_LIT("len"), 1, false, Expr_Expr},
- {STR_LIT("cap"), 1, false, Expr_Expr},
-
- // {STR_LIT("new"), 1, false, Expr_Expr},
- {STR_LIT("make"), 1, true, Expr_Expr},
- // {STR_LIT("free"), 1, false, Expr_Stmt},
-
- // {STR_LIT("reserve"), 2, false, Expr_Stmt},
- // {STR_LIT("clear"), 1, false, Expr_Stmt},
- // {STR_LIT("append"), 1, true, Expr_Expr},
- // {STR_LIT("delete"), 2, false, Expr_Stmt},
-
- {STR_LIT("size_of"), 1, false, Expr_Expr},
- {STR_LIT("align_of"), 1, false, Expr_Expr},
- {STR_LIT("offset_of"), 2, false, Expr_Expr},
- {STR_LIT("type_of"), 1, false, Expr_Expr},
- {STR_LIT("type_info_of"), 1, false, Expr_Expr},
-
- {STR_LIT("compile_assert"), 1, false, Expr_Expr},
-
- {STR_LIT("swizzle"), 1, true, Expr_Expr},
-
- {STR_LIT("complex"), 2, false, Expr_Expr},
- {STR_LIT("real"), 1, false, Expr_Expr},
- {STR_LIT("imag"), 1, false, Expr_Expr},
- {STR_LIT("conj"), 1, false, Expr_Expr},
-
- // {STR_LIT("slice_ptr"), 2, true, Expr_Expr},
- // {STR_LIT("slice_to_bytes"), 1, false, Expr_Expr},
-
- {STR_LIT("expand_to_tuple"), 1, false, Expr_Expr},
-
- {STR_LIT("min"), 2, false, Expr_Expr},
- {STR_LIT("max"), 2, false, Expr_Expr},
- {STR_LIT("abs"), 1, false, Expr_Expr},
- {STR_LIT("clamp"), 3, false, Expr_Expr},
-
- {STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
-};
-
-
#include "types.cpp"
-enum AddressingMode {
- Addressing_Invalid, // invalid addressing mode
- Addressing_NoValue, // no value (void in C)
- Addressing_Value, // computed value (rvalue)
- Addressing_Immutable, // immutable computed value (const rvalue)
- Addressing_Variable, // addressable variable (lvalue)
- Addressing_Constant, // constant
- Addressing_Type, // type
- Addressing_Builtin, // built-in procedure
- Addressing_ProcGroup, // procedure group (overloaded procedure)
- Addressing_MapIndex, // map index expression -
- // lhs: acts like a Variable
- // rhs: acts like OptionalOk
- Addressing_OptionalOk, // rhs: acts like a value with an optional boolean part (for existence check)
-};
-
-// Operand is used as an intermediate value whilst checking
-// Operands store an addressing mode, the expression being evaluated,
-// its type and node, and other specific information for certain
-// addressing modes
-// Its zero-value is a valid "invalid operand"
-struct Operand {
- AddressingMode mode;
- Type * type;
- ExactValue value;
- AstNode * expr;
- BuiltinProcId builtin_id;
- Entity * proc_group;
-};
-
-struct TypeAndValue {
- AddressingMode mode;
- Type * type;
- ExactValue value;
-};
bool is_operand_value(Operand o) {
switch (o.mode) {
@@ -166,79 +22,6 @@ bool is_operand_undef(Operand o) {
-struct BlockLabel {
- String name;
- AstNode *label; // AstNode_Label;
-};
-
-// DeclInfo is used to store information of certain declarations to allow for "any order" usage
-struct DeclInfo {
- DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment
- Scope * scope;
-
- Entity ** entities;
- isize entity_count;
-
- AstNode * type_expr;
- AstNode * init_expr;
- Array<AstNode *> init_expr_list;
- Array<AstNode *> attributes;
- AstNode * proc_lit; // AstNode_ProcLit
- Type * gen_proc_type; // Precalculated
-
- PtrSet<Entity *> deps;
- Array<BlockLabel> labels;
-};
-
-// ProcedureInfo stores the information needed for checking a procedure
-
-
-struct ProcedureInfo {
- AstFile * file;
- Token token;
- DeclInfo * decl;
- Type * type; // Type_Procedure
- AstNode * body; // AstNode_BlockStmt
- u64 tags;
- bool generated_from_polymorphic;
-};
-
-// ExprInfo stores information used for "untyped" expressions
-struct ExprInfo {
- bool is_lhs; // Debug info
- AddressingMode mode;
- Type * type; // Type_Basic
- ExactValue value;
-};
-
-ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue value) {
- ExprInfo ei = {is_lhs, mode, type, value};
- return ei;
-}
-
-
-
-struct Scope {
- AstNode * node;
- Scope * parent;
- Scope * prev, *next;
- Scope * first_child;
- Scope * last_child;
- Map<Entity *> elements; // Key: String
- PtrSet<Entity *> implicit;
-
- Array<Scope *> shared;
- Array<AstNode *> delayed_file_decls;
- PtrSet<Scope *> imported;
- PtrSet<Scope *> exported; // NOTE(bhall): Contains 'using import' too
- bool is_proc;
- bool is_global;
- bool is_file;
- bool is_init;
- bool is_struct;
- bool has_been_imported; // This is only applicable to file scopes
- AstFile * file;
-};
gb_global Scope *universal_scope = nullptr;
void scope_reset(Scope *scope) {
@@ -257,7 +40,7 @@ i32 is_scope_an_ancestor(Scope *parent, Scope *child) {
isize i = 0;
while (child != nullptr) {
if (parent == child) {
- return true;
+ return i;
}
child = child->parent;
i++;
@@ -265,18 +48,6 @@ i32 is_scope_an_ancestor(Scope *parent, Scope *child) {
return -1;
}
-
-struct EntityGraphNode;
-typedef PtrSet<EntityGraphNode *> EntityGraphNodeSet;
-
-struct EntityGraphNode {
- Entity * entity; // Procedure, Variable, Constant
- EntityGraphNodeSet pred;
- EntityGraphNodeSet succ;
- isize index; // Index in array/queue
- isize dep_count;
-};
-
void entity_graph_node_set_destroy(EntityGraphNodeSet *s) {
if (s->hashes.data != nullptr) {
ptr_set_destroy(s);
@@ -326,9 +97,6 @@ void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) {
-struct ImportGraphNode;
-typedef PtrSet<ImportGraphNode *> ImportGraphNodeSet;
-
void import_graph_node_set_destroy(ImportGraphNodeSet *s) {
if (s->hashes.data != nullptr) {
ptr_set_destroy(s);
@@ -350,16 +118,6 @@ void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) {
ptr_set_remove(s, n);
}
-struct ImportGraphNode {
- Scope * scope;
- String path;
- isize file_id;
- ImportGraphNodeSet pred;
- ImportGraphNodeSet succ;
- isize index; // Index in array/queue
- isize dep_count;
-};
-
ImportGraphNode *import_graph_node_create(gbAllocator a, Scope *scope) {
ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode);
n->scope = scope;
@@ -368,7 +126,6 @@ ImportGraphNode *import_graph_node_create(gbAllocator a, Scope *scope) {
return n;
}
-
void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) {
import_graph_node_set_destroy(&n->pred);
import_graph_node_set_destroy(&n->succ);
@@ -409,118 +166,10 @@ GB_COMPARE_PROC(ast_node_cmp) {
return token_pos_cmp(i.pos, j.pos);
}
-struct ForeignContext {
- AstNode * curr_library;
- ProcCallingConvention default_cc;
- String link_prefix;
- bool in_export;
-};
-
-struct CheckerContext {
- Scope * file_scope;
- Scope * scope;
- DeclInfo * decl;
- u32 stmt_state_flags;
- bool in_defer; // TODO(bill): Actually handle correctly
- String proc_name;
- Type * type_hint;
- DeclInfo * curr_proc_decl;
- ForeignContext foreign_context;
-
- bool collect_delayed_decls;
- bool allow_polymorphic_types;
- bool no_polymorphic_errors;
- Scope * polymorphic_scope;
-};
-
-
-// CheckerInfo stores all the symbol information for a type-checked program
-struct CheckerInfo {
- Map<TypeAndValue> types; // Key: AstNode * | Expression -> Type (and value)
- Map<ExprInfo> untyped; // Key: AstNode * | Expression -> ExprInfo
- Map<AstFile *> files; // Key: String (full path)
- Map<Entity *> foreigns; // Key: String
- Array<Entity *> definitions;
- Array<Entity *> entities;
- Array<DeclInfo *> variable_init_order;
-
- Map<Array<Entity *> > gen_procs; // Key: AstNode * | Identifier -> Entity
- Map<Array<Entity *> > gen_types; // Key: Type *
-
- Map<isize> type_info_map; // Key: Type *
- isize type_info_count;
-
- Scope * init_scope;
- Entity * entry_point;
- PtrSet<Entity *> minimum_dependency_set;
-};
-
-struct Checker {
- Parser * parser;
- CheckerInfo info;
- gbMutex mutex;
-
- AstFile * curr_ast_file;
- Scope * global_scope;
- // NOTE(bill): Procedures to check
- Array<ProcedureInfo> procs;
- Map<Scope *> file_scopes; // Key: String (fullpath)
- Array<ImportGraphNode *> file_order;
-
- gbAllocator allocator;
- gbArena arena;
- gbArena tmp_arena;
- gbAllocator tmp_allocator;
-
- CheckerContext context;
-
- Array<Type *> proc_stack;
- bool done_preload;
-
- PtrSet<AstFile *> checked_files;
-
-};
-
-
-
-HashKey hash_node (AstNode *node) { return hash_pointer(node); }
-HashKey hash_ast_file (AstFile *file) { return hash_pointer(file); }
-HashKey hash_entity (Entity *e) { return hash_pointer(e); }
-HashKey hash_type (Type *t) { return hash_pointer(t); }
-HashKey hash_decl_info(DeclInfo *decl) { return hash_pointer(decl); }
-
-// CheckerInfo API
-TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
-Type * type_of_expr (CheckerInfo *i, AstNode *expr);
-Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier);
-Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
-Scope * scope_of_node (CheckerInfo *i, AstNode *node);
-DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
-DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
-AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
-// IMPORTANT: Only to use once checking is done
-isize type_info_index (CheckerInfo *i, Type * type, bool error_on_failure = true);
-Entity *current_scope_lookup_entity(Scope *s, String name);
-Entity *scope_lookup_entity (Scope *s, String name);
-void scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
-Entity *scope_insert_entity (Scope *s, Entity *entity);
-ExprInfo *check_get_expr_info (CheckerInfo *i, AstNode *expr);
-void check_set_expr_info (CheckerInfo *i, AstNode *expr, ExprInfo info);
-void check_remove_expr_info (CheckerInfo *i, AstNode *expr);
-void add_untyped (CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value);
-void add_type_and_value (CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value);
-void add_entity_use (Checker *c, AstNode *identifier, Entity *entity);
-void add_implicit_entity (Checker *c, AstNode *node, Entity *e);
-void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d);
-
-void check_add_import_decl(Checker *c, AstNodeImportDecl *id);
-void check_add_export_decl(Checker *c, AstNodeExportDecl *ed);
-void check_add_foreign_import_decl(Checker *c, AstNode *decl);
-
void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
d->parent = parent;
@@ -771,6 +420,9 @@ Entity *scope_lookup_entity(Scope *s, String name) {
Entity *scope_insert_entity(Scope *s, Entity *entity) {
String name = entity->token.string;
+ if (name == "") {
+ return nullptr;
+ }
HashKey key = hash_string(name);
Entity **found = map_get(&s->elements, key);
@@ -1742,30 +1394,6 @@ void init_preload(Checker *c) {
-bool check_arity_match(Checker *c, AstNodeValueDecl *vd, bool is_global = false);
-void check_collect_entities(Checker *c, Array<AstNode *> nodes);
-void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws);
-void check_delayed_file_import_entity(Checker *c, AstNode *decl);
-
-struct AttributeContext {
- String link_name;
- String link_prefix;
- isize init_expr_list_count;
- String thread_local_model;
-};
-
-AttributeContext make_attribute_context(String link_prefix) {
- AttributeContext ac = {};
- ac.link_prefix = link_prefix;
- return ac;
-}
-
-#define DECL_ATTRIBUTE_PROC(_name) bool _name(Checker *c, AstNode *elem, String name, ExactValue value, AttributeContext *ac)
-typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
-
-
-void check_decl_attributes(Checker *c, Array<AstNode *> attributes, DeclAttributeProc *proc, AttributeContext *ac);
-
DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
if (name == "default_calling_convention") {
if (value.kind == ExactValue_String) {