aboutsummaryrefslogtreecommitdiff
path: root/src/checker.c
diff options
context:
space:
mode:
authorZac Pierson <zacpiersonhehe@gmail.com>2017-02-15 10:21:38 -0600
committerZac Pierson <zacpiersonhehe@gmail.com>2017-02-15 10:21:38 -0600
commitaaa4dd5c363f2cb4643cd6489108d5be7c9d17de (patch)
treecb6b93596135d2a7f868acc73fcea1536e3d7ab9 /src/checker.c
parent9d19ee7e4c285d5d881570be3328d81bdff40368 (diff)
parent71100ed427ee2eec8d8a9d4d9616102738097e80 (diff)
Merge https://github.com/gingerBill/odin
Diffstat (limited to 'src/checker.c')
-rw-r--r--src/checker.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/src/checker.c b/src/checker.c
index 7c37f0601..3bb76245f 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -106,29 +106,29 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
};
+#include "types.c"
typedef enum AddressingMode {
- Addressing_Invalid,
-
- Addressing_NoValue,
- Addressing_Value,
- Addressing_Variable,
- Addressing_Constant,
- Addressing_Type,
- Addressing_Builtin,
- Addressing_Overload,
- Addressing_MapIndex,
-
- Addressing_Count,
+ 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 & type will be a of Type_Basic (stripping Type_Named)
+ Addressing_Type, // type
+ Addressing_Builtin, // built in procedure
+ Addressing_Overload, // 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)
} AddressingMode;
-#include "types.c"
-
-#define MAP_TYPE Entity *
-#define MAP_PROC map_entity_
-#define MAP_NAME MapEntity
-#include "map.c"
-
+// 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"
typedef struct Operand {
AddressingMode mode;
Type * type;
@@ -149,7 +149,9 @@ bool is_operand_value(Operand o) {
switch (o.mode) {
case Addressing_Value:
case Addressing_Variable:
+ case Addressing_Immutable:
case Addressing_Constant:
+ case Addressing_MapIndex:
return true;
}
return false;
@@ -159,7 +161,7 @@ bool is_operand_nil(Operand o) {
}
-
+// DeclInfo is used to store information of certain declarations to allow for "any order" usage
typedef struct DeclInfo {
Scope *scope;
@@ -173,6 +175,17 @@ typedef struct DeclInfo {
MapBool deps; // Key: Entity *
} DeclInfo;
+// ProcedureInfo stores the information needed for checking a procedure
+typedef struct ProcedureInfo {
+ AstFile * file;
+ Token token;
+ DeclInfo *decl;
+ Type * type; // Type_Procedure
+ AstNode * body; // AstNode_BlockStmt
+ u32 tags;
+} ProcedureInfo;
+
+// ExprInfo stores information used for "untyped" expressions
typedef struct ExprInfo {
bool is_lhs; // Debug info
AddressingMode mode;
@@ -185,14 +198,12 @@ ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue
return ei;
}
-typedef struct ProcedureInfo {
- AstFile * file;
- Token token;
- DeclInfo *decl;
- Type * type; // Type_Procedure
- AstNode * body; // AstNode_BlockStmt
- u32 tags;
-} ProcedureInfo;
+
+
+#define MAP_TYPE Entity *
+#define MAP_PROC map_entity_
+#define MAP_NAME MapEntity
+#include "map.c"
typedef struct Scope {
Scope * parent;
@@ -256,7 +267,7 @@ typedef struct CheckerContext {
Type * type_hint;
} CheckerContext;
-// NOTE(bill): Symbol tables
+// CheckerInfo stores all the symbol information for a type-checked program
typedef struct CheckerInfo {
MapTypeAndValue types; // Key: AstNode * | Expression -> Type (and value)
MapEntity definitions; // Key: AstNode * | Identifier -> Entity
@@ -389,9 +400,7 @@ void check_open_scope(Checker *c, AstNode *node) {
node = unparen_expr(node);
GB_ASSERT(node->kind == AstNode_Invalid ||
is_ast_node_stmt(node) ||
- is_ast_node_type(node) ||
- node->kind == AstNode_BlockExpr ||
- node->kind == AstNode_IfExpr );
+ is_ast_node_type(node));
Scope *scope = make_scope(c->context.scope, c->allocator);
add_scope(c, node, scope);
if (node->kind == AstNode_ProcType) {