Referencing other packages works!!
This commit is contained in:
2
ast.cpp
2
ast.cpp
@@ -60,7 +60,7 @@ struct Ast{
|
||||
};
|
||||
|
||||
struct Ast_Resolved_Type;
|
||||
struct Ast_Expr:Ast{};
|
||||
struct Ast_Expr:Ast{ };
|
||||
|
||||
#define VALUE_FIELDS \
|
||||
Ast_Resolved_Type *type; \
|
||||
|
||||
@@ -178,7 +178,6 @@ struct Parse_Ctx:Lexer{
|
||||
|
||||
Array<Ast_Package *> packages;
|
||||
Ast_Scope *currently_parsed_scope;
|
||||
Ast_Package *resolving_package;
|
||||
Array<Ast_Decl *> ordered_decls;
|
||||
|
||||
S64 indent;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package lambdas
|
||||
|
||||
Test :: struct
|
||||
len: S64
|
||||
|
||||
test: Test
|
||||
member := test.len
|
||||
|
||||
a_type :: S64
|
||||
pointer_type :: *S64
|
||||
// null_pointer: pointer_type = null
|
||||
|
||||
@@ -17,4 +17,5 @@ CONSTANT_VAL :: 10
|
||||
|
||||
global_thing: a_type = 10
|
||||
|
||||
// arena: order2.Arena
|
||||
arena: *order2.Arena
|
||||
order1_arena: order2.Arena
|
||||
|
||||
@@ -17,6 +17,7 @@ String16 :: struct
|
||||
len : S64
|
||||
|
||||
with_type: Arena = order2_arena
|
||||
test_dot := with_type.len
|
||||
pointer := &with_type
|
||||
deref := *pointer
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ parse_decl(B32 is_global){
|
||||
}
|
||||
}
|
||||
else if(token_match(TK_Identifier, TK_Colon)){
|
||||
Ast_Expr *typespec = typespec = parse_expr();
|
||||
Ast_Expr *typespec = parse_expr();
|
||||
Ast_Expr *expr = parse_assign_expr();
|
||||
result = ast_var(tname, typespec, tname->intern_val, expr);
|
||||
}
|
||||
|
||||
121
typechecking.cpp
121
typechecking.cpp
@@ -420,10 +420,15 @@ _search_for_decl(Ast_Scope *scope, Intern_String name){
|
||||
return 0;
|
||||
}
|
||||
|
||||
FLAG32(Search_Flag) {
|
||||
SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1),
|
||||
SEARCH_ALSO_FOR_PACKAGE = bit_flag(2),
|
||||
};
|
||||
function Ast_Package *
|
||||
search_for_package(Intern_String name){
|
||||
For(pctx->packages){
|
||||
if(name == it->name){
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Ast_Decl *
|
||||
search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){
|
||||
@@ -434,12 +439,7 @@ search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){
|
||||
if(is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)) break;
|
||||
}
|
||||
if(!result && is_flag_set(flags, SEARCH_ALSO_FOR_PACKAGE)){
|
||||
For(pctx->packages){
|
||||
if(name == it->name){
|
||||
result = (Ast_Decl *)it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = (Ast_Decl *)search_for_package(name);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -638,6 +638,50 @@ resolve_cast(Ast_Cast *node){
|
||||
return expr;
|
||||
}
|
||||
|
||||
global Ast_Scope *field_access_scope; // @memes
|
||||
|
||||
function Operand
|
||||
resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
||||
Ast_Binary *current = 0;
|
||||
Ast_Expr *next = 0;
|
||||
if(node->kind == AST_BINARY){
|
||||
current = (Ast_Binary *)node;
|
||||
next = current->right;
|
||||
node = current->left;
|
||||
}
|
||||
|
||||
Ast_Scope *new_context = 0;
|
||||
if(!context && node->kind == AST_IDENT){
|
||||
auto ident = (Ast_Atom *)node;
|
||||
Ast_Package *package = search_for_package(ident->intern_val);
|
||||
if(package) {
|
||||
new_context = package;
|
||||
}
|
||||
}
|
||||
|
||||
if(!new_context){
|
||||
field_access_scope = context;
|
||||
Operand op = resolve_expr(node, AST_CANT_BE_NULL);
|
||||
field_access_scope = 0;
|
||||
|
||||
if(current) current->type = op.type;
|
||||
if(is_pointer(op.type)) op.type = op.type->base;
|
||||
type_complete(op.type);
|
||||
|
||||
if(next && !is_struct(op.type)){
|
||||
compiler_error(node->pos, "Dot access");
|
||||
}
|
||||
|
||||
if(!next)
|
||||
return op;
|
||||
|
||||
new_context = ((Ast_Decl *)op.type->ast)->scope;
|
||||
}
|
||||
|
||||
assert(next);
|
||||
return resolve_field_access(next, new_context);
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||
@@ -646,6 +690,28 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
|
||||
switch(ast->kind){
|
||||
|
||||
CASE(IDENT, Atom){
|
||||
Ast_Scope *scope = node->parent_scope;
|
||||
Search_Flag flags = 0;
|
||||
if(field_access_scope){
|
||||
set_flag(flags, SEARCH_ONLY_CURRENT_SCOPE);
|
||||
scope = field_access_scope;
|
||||
}
|
||||
Ast_Decl *decl = resolve_name(scope, node->pos, node->intern_val, flags);
|
||||
|
||||
node->resolved_decl = decl;
|
||||
Operand result = operand(decl);
|
||||
if(decl->kind != AST_VAR){
|
||||
if(decl->kind == AST_CONST){
|
||||
rewrite_into_const(node, Ast_Atom, decl->value);
|
||||
}
|
||||
result.is_const = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(VALUE, Atom){
|
||||
return operand_const_rvalue(node->value);
|
||||
BREAK();
|
||||
@@ -677,28 +743,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(IDENT, Atom){
|
||||
Ast_Decl *decl = resolve_name(node->parent_scope, node->pos, node->intern_val);
|
||||
|
||||
node->resolved_decl = decl;
|
||||
Operand result = operand(decl);
|
||||
if(decl->kind != AST_VAR){
|
||||
// @note
|
||||
// There might be some problem with types getting rewritten
|
||||
// I would like decls to be resolved to be of AST_TYPE ??
|
||||
//
|
||||
// assert(decl->value.type != type_type);
|
||||
// assert(!is_lambda(decl->value.type));
|
||||
if(decl->kind == AST_CONST){
|
||||
rewrite_into_const(node, Ast_Atom, decl->value);
|
||||
}
|
||||
result.is_const = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(BINARY, Binary){
|
||||
if(token_is_assign(node->op)){
|
||||
assert(is_flag_set(node->flags, AST_STMT));
|
||||
@@ -708,8 +752,12 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
|
||||
right.value = convert_untyped_to_typed(node->pos, right.value, left.type);
|
||||
if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %s and right is %s", docname(left.type), docname(right.type));
|
||||
node->type = right.type;
|
||||
return {};
|
||||
}
|
||||
else if(node->op == TK_Dot){
|
||||
return resolve_field_access(node, 0);
|
||||
}
|
||||
else{
|
||||
Operand left = resolve_expr(node->left, AST_CANT_BE_NULL);
|
||||
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL);
|
||||
@@ -837,9 +885,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
|
||||
function void
|
||||
resolve_decl(Ast_Decl *ast){
|
||||
if(ast->state == DECL_RESOLVED){
|
||||
return;
|
||||
}
|
||||
if(ast->kind == AST_PACKAGE) return;
|
||||
else if(ast->state == DECL_RESOLVED) return;
|
||||
else if(ast->state == DECL_RESOLVING){
|
||||
compiler_error(ast->pos, "Cyclic dependency of %s", ast->name.str);
|
||||
return;
|
||||
@@ -947,8 +994,8 @@ resolve_decl(Ast_Decl *ast){
|
||||
}
|
||||
|
||||
function Ast_Decl *
|
||||
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name){
|
||||
Ast_Decl *decl = search_for_decl(scope, name);
|
||||
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){
|
||||
Ast_Decl *decl = search_for_decl(scope, name, search_flags);
|
||||
if(!decl) compiler_error(pos, "Unidentified name [%s]", name.str);
|
||||
resolve_decl(decl);
|
||||
return decl;
|
||||
|
||||
@@ -11,9 +11,14 @@ FLAG32(Resolve_Flag){
|
||||
RESOLVE_TYPESPEC_COMPLETE = bit_flag(2),
|
||||
};
|
||||
|
||||
FLAG32(Search_Flag){
|
||||
SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1),
|
||||
SEARCH_ALSO_FOR_PACKAGE = bit_flag(2),
|
||||
};
|
||||
|
||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags);
|
||||
function void resolve_decl(Ast_Decl *ast);
|
||||
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name);
|
||||
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
|
||||
function Ast_Resolved_Type *resolve_typespec(Ast_Expr *ast, Resolve_Flag flags);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user