New concept of AST_MODULE, Ast_File and Ast_Module are now both scopes.
Concept of loading and importing.
This commit is contained in:
39
ast.cpp
39
ast.cpp
@@ -6,7 +6,10 @@ enum Ast_Kind: U32{
|
|||||||
AST_NONE,
|
AST_NONE,
|
||||||
|
|
||||||
AST_FILE_NAMESPACE,
|
AST_FILE_NAMESPACE,
|
||||||
|
AST_MODULE_NAMESPACE,
|
||||||
|
|
||||||
|
AST_MODULE,
|
||||||
|
AST_FILE,
|
||||||
AST_SCOPE,
|
AST_SCOPE,
|
||||||
AST_VALUE,
|
AST_VALUE,
|
||||||
AST_CAST,
|
AST_CAST,
|
||||||
@@ -196,11 +199,28 @@ enum Ast_Decl_State{
|
|||||||
DECL_RESOLVING,
|
DECL_RESOLVING,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Decl;
|
|
||||||
struct Ast_Scope: Ast{
|
struct Ast_Scope: Ast{
|
||||||
Array<Ast_Decl *> decls;
|
Array<Ast_Module *> implicit_imports;
|
||||||
Array<Ast *> stmts;
|
Array<Ast_File *> implicit_loads;
|
||||||
Ast_File *file;
|
Array<Ast_Decl *> decls;
|
||||||
|
Array<Ast *> stmts;
|
||||||
|
|
||||||
|
Ast_File *file; // Null for module scope, file scope
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Ast_Module: Ast_Scope{
|
||||||
|
Intern_String name;
|
||||||
|
Array<Ast_File *> all_loaded_files;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_File: Ast_Scope{
|
||||||
|
Intern_String filename;
|
||||||
|
Ast_Module *module;
|
||||||
|
|
||||||
|
B32 global_implicit_load;
|
||||||
|
String filecontent;
|
||||||
|
Intern_String name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Decl: Ast{
|
struct Ast_Decl: Ast{
|
||||||
@@ -483,8 +503,15 @@ ast_decl_scope(Token *pos, Allocator *allocator, Ast_File *file){
|
|||||||
function Ast_Decl *
|
function Ast_Decl *
|
||||||
ast_file_namespace(Token *pos, Ast_File *file, Intern_String name){
|
ast_file_namespace(Token *pos, Ast_File *file, Intern_String name){
|
||||||
AST_NEW(Decl, FILE_NAMESPACE, pos, AST_DECL);
|
AST_NEW(Decl, FILE_NAMESPACE, pos, AST_DECL);
|
||||||
result->kind = AST_FILE_NAMESPACE;
|
result->scope = file;
|
||||||
result->scope = file->scope;
|
result->name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Decl *
|
||||||
|
ast_module_namespace(Token *pos, Ast_Module *module, Intern_String name){
|
||||||
|
AST_NEW(Decl, MODULE_NAMESPACE, pos, AST_DECL);
|
||||||
|
result->scope = module;
|
||||||
result->name = name;
|
result->name = name;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
73
ccodegen.cpp
73
ccodegen.cpp
@@ -400,6 +400,7 @@ gen_ast(Ast *ast){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AST_MODULE_NAMESPACE:
|
||||||
CASE(FILE_NAMESPACE, File_Namespace){unused(node); BREAK();}
|
CASE(FILE_NAMESPACE, File_Namespace){unused(node); BREAK();}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
@@ -423,12 +424,15 @@ parse_file(Ast_File *file){
|
|||||||
String name = string_chop_last_period(file->filename.s);
|
String name = string_chop_last_period(file->filename.s);
|
||||||
file->name = pctx->intern(name);
|
file->name = pctx->intern(name);
|
||||||
|
|
||||||
pctx->currently_parsed_scope = file->scope;
|
pctx->currently_parsed_scope = file;
|
||||||
lex_restream(pctx, file->filecontent, file->filename.s);
|
lex_restream(pctx, file->filecontent, file->filename.s);
|
||||||
while(token_expect(SAME_SCOPE)){
|
while(token_expect(SAME_SCOPE)){
|
||||||
if(token_match_pound(pctx->intern("load"_s))){
|
if(token_match_pound(pctx->intern("load"_s))){
|
||||||
parse_load(true);
|
parse_load(true);
|
||||||
continue;
|
continue;
|
||||||
|
} else if(token_match_pound(pctx->intern("import"_s))){
|
||||||
|
parse_import(true);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Decl *decl = parse_decl(true);
|
Ast_Decl *decl = parse_decl(true);
|
||||||
@@ -441,31 +445,19 @@ parse_file(Ast_File *file){
|
|||||||
decl->state = DECL_RESOLVED;
|
decl->state = DECL_RESOLVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_into_scope(file->scope, decl);
|
insert_into_scope(file, decl);
|
||||||
}
|
}
|
||||||
pctx->currently_parsed_scope = 0;
|
pctx->currently_parsed_scope = 0;
|
||||||
pctx->currently_parsed_file = 0;
|
pctx->currently_parsed_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
global F64 parsing_time_begin;
|
|
||||||
global F64 parsing_time_end;
|
|
||||||
function void
|
|
||||||
parse_files(Ast_Module *module){
|
|
||||||
parsing_time_begin = os_time();
|
|
||||||
for(S64 i = 0; i < module->files.len; i++){
|
|
||||||
auto it = module->files.data[i];
|
|
||||||
parse_file(it);
|
|
||||||
}
|
|
||||||
parsing_time_end = os_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
function void
|
||||||
insert_type_into_file(Ast_File *p, String name, Ast_Type *type){
|
insert_type_into_file(Ast_File *p, String name, Ast_Type *type){
|
||||||
Intern_String string = pctx->intern(name);
|
Intern_String string = pctx->intern(name);
|
||||||
Ast_Decl *decl = ast_type(&null_token, string, type);
|
Ast_Decl *decl = ast_type(&null_token, string, type);
|
||||||
decl->parent_scope = p->scope;
|
decl->parent_scope = p;
|
||||||
decl->state = DECL_RESOLVED;
|
decl->state = DECL_RESOLVED;
|
||||||
insert_into_scope(p->scope, decl);
|
insert_into_scope(p, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
@@ -487,14 +479,43 @@ insert_builtin_types_into_file(Ast_File *p){
|
|||||||
insert_type_into_file(p, "F64"_s, type_f64);
|
insert_type_into_file(p, "F64"_s, type_f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global F64 parsing_time_begin;
|
||||||
|
global F64 parsing_time_end;
|
||||||
|
function void
|
||||||
|
parse_files(Ast_Module *module){
|
||||||
|
for(S64 i = 0; i < module->all_loaded_files.len; i++){
|
||||||
|
auto it = module->all_loaded_files.data[i];
|
||||||
|
parse_file(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parse_all_modules(){
|
||||||
|
parsing_time_begin = os_time();
|
||||||
|
For(pctx->modules){
|
||||||
|
parse_files(it);
|
||||||
|
// @todo maybe add module?
|
||||||
|
insert_builtin_types_into_file(it->all_loaded_files[0]);
|
||||||
|
}
|
||||||
|
parsing_time_end = os_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function Ast_Module *
|
function Ast_Module *
|
||||||
parse_module(String filename){
|
add_module(Intern_String filename){
|
||||||
|
For(pctx->modules){
|
||||||
|
if(it->name == filename)
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
Ast_Module *result = exp_alloc_type(pctx->perm, Ast_Module);
|
Ast_Module *result = exp_alloc_type(pctx->perm, Ast_Module);
|
||||||
result->name = pctx->intern(filename);
|
result->kind = AST_MODULE;
|
||||||
result->files = {pctx->heap};
|
result->name = filename;
|
||||||
Ast_File *file = register_ast_file(result->name, result, true);
|
result->all_loaded_files = {pctx->heap};
|
||||||
parse_files(result);
|
result->implicit_loads = {pctx->heap};
|
||||||
insert_builtin_types_into_file(file);
|
result->implicit_imports = {pctx->heap};
|
||||||
|
|
||||||
|
register_ast_file(result->name, result, true);
|
||||||
pctx->modules.add(result);
|
pctx->modules.add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -504,10 +525,10 @@ global F64 resolving_time_end;
|
|||||||
function void
|
function void
|
||||||
resolve_everything_in_module(Ast_Module *module){
|
resolve_everything_in_module(Ast_Module *module){
|
||||||
resolving_time_begin = os_time();
|
resolving_time_begin = os_time();
|
||||||
for(S64 i = 0; i < module->files.len; i++){
|
for(S64 i = 0; i < module->all_loaded_files.len; i++){
|
||||||
Ast_File *it = module->files[i];
|
Ast_File *it = module->all_loaded_files[i];
|
||||||
For_Named(it->scope->decls, jt){
|
For_Named(it->decls, jt){
|
||||||
resolve_name(it->scope, jt->pos, jt->name);
|
resolve_name(it, jt->pos, jt->name);
|
||||||
if(jt->kind == AST_STRUCT){
|
if(jt->kind == AST_STRUCT){
|
||||||
type_complete(jt->type);
|
type_complete(jt->type);
|
||||||
}
|
}
|
||||||
|
|||||||
17
compiler.h
17
compiler.h
@@ -167,21 +167,7 @@ struct Ast_Scope;
|
|||||||
struct Ast_Decl;
|
struct Ast_Decl;
|
||||||
struct Ast_File_Namespace;
|
struct Ast_File_Namespace;
|
||||||
struct Ast_File;
|
struct Ast_File;
|
||||||
struct Ast_Module{
|
struct Ast_Module;
|
||||||
Intern_String name;
|
|
||||||
Array<Ast_File *> files;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_File{
|
|
||||||
Intern_String filename;
|
|
||||||
Ast_Module *module;
|
|
||||||
|
|
||||||
B32 global_implicit_load;
|
|
||||||
String filecontent;
|
|
||||||
Intern_String name;
|
|
||||||
Ast_Scope *scope;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Parse_Ctx:Lexer{
|
struct Parse_Ctx:Lexer{
|
||||||
Allocator *perm; // Stores: AST, tokens, interns
|
Allocator *perm; // Stores: AST, tokens, interns
|
||||||
Allocator *heap;
|
Allocator *heap;
|
||||||
@@ -190,7 +176,6 @@ struct Parse_Ctx:Lexer{
|
|||||||
Map type_map;
|
Map type_map;
|
||||||
|
|
||||||
Array<Ast_Module *> modules;
|
Array<Ast_Module *> modules;
|
||||||
Array<Ast_File_Namespace *> packages;
|
|
||||||
Ast_Scope *currently_parsed_scope;
|
Ast_Scope *currently_parsed_scope;
|
||||||
Ast_File *currently_parsed_file;
|
Ast_File *currently_parsed_file;
|
||||||
Array<Ast_Decl *> ordered_decls;
|
Array<Ast_Decl *> ordered_decls;
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
lambdas :: #load "lambdas.kl"
|
lambdas :: #load "lambdas.kl"
|
||||||
Memory :: #load "enums.kl"
|
Memory :: #load "enums.kl"
|
||||||
|
order :: #import "order1.kl"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
test_load :: ()
|
test_load :: ()
|
||||||
new_types :: #load "new_types.kl"
|
new_types :: #load "new_types.kl"
|
||||||
new_types.basic_type_assignment()
|
new_types.basic_type_assignment()
|
||||||
|
arena: order.order2.Arena
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Function types
|
// Function types
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
15
main.cpp
15
main.cpp
@@ -172,20 +172,11 @@ int main(int argument_count, char **arguments){
|
|||||||
system((const char *)run_program.str);
|
system((const char *)run_program.str);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Scratch scratch;
|
|
||||||
// Array<String> files = {scratch};
|
|
||||||
// files.add("lambdas.kl"_s);
|
|
||||||
// files.add("order1.kl"_s);
|
|
||||||
// files.add("order2.kl"_s);
|
|
||||||
// files.add("new_types.kl"_s);
|
|
||||||
// files.add("enums.kl"_s);
|
|
||||||
// files.add("Windows.kl"_s);
|
|
||||||
// files.add("euler.kl"_s);
|
|
||||||
// String result = compile_files(files);
|
|
||||||
|
|
||||||
F64 total_time = os_time();
|
F64 total_time = os_time();
|
||||||
begin_compilation();
|
begin_compilation();
|
||||||
Ast_Module *module = parse_module("Windows.kl"_s);
|
add_module(pctx->intern("order1.kl"_s));
|
||||||
|
Ast_Module *module = add_module(pctx->intern("Windows.kl"_s));
|
||||||
|
parse_all_modules();
|
||||||
assert(module);
|
assert(module);
|
||||||
resolve_everything_in_module(module);
|
resolve_everything_in_module(module);
|
||||||
String result = end_compilation();
|
String result = end_compilation();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
order2 :: #load "order2.kl"
|
||||||
|
|
||||||
recursive_lambda :: (thing: S64)
|
recursive_lambda :: (thing: S64)
|
||||||
in_val := recursive_lambda
|
in_val := recursive_lambda
|
||||||
some_value := thing + const_in_lambda
|
some_value := thing + const_in_lambda
|
||||||
|
|||||||
31
parsing.cpp
31
parsing.cpp
@@ -585,7 +585,7 @@ parse_enum(Token *pos){
|
|||||||
function Ast_File *
|
function Ast_File *
|
||||||
register_ast_file(Intern_String filename, Ast_Module *module, B32 global_implicit_load){
|
register_ast_file(Intern_String filename, Ast_Module *module, B32 global_implicit_load){
|
||||||
Ast_File *file = 0;
|
Ast_File *file = 0;
|
||||||
For(module->files){
|
For(module->all_loaded_files){
|
||||||
if(it->filename == filename){
|
if(it->filename == filename){
|
||||||
file = it;
|
file = it;
|
||||||
break;
|
break;
|
||||||
@@ -593,13 +593,20 @@ register_ast_file(Intern_String filename, Ast_Module *module, B32 global_implici
|
|||||||
}
|
}
|
||||||
if(!file){
|
if(!file){
|
||||||
file = exp_alloc_type(pctx->perm, Ast_File, AF_ZeroMemory);
|
file = exp_alloc_type(pctx->perm, Ast_File, AF_ZeroMemory);
|
||||||
|
file->kind = AST_FILE;
|
||||||
file->filename = filename;
|
file->filename = filename;
|
||||||
file->module = module;
|
file->module = module;
|
||||||
file->scope = ast_decl_scope(0, pctx->heap, file);
|
file->file = file; // @warning: self referential!
|
||||||
file->module->files.add(file);
|
file->decls = {pctx->heap};
|
||||||
|
file->implicit_loads = {pctx->heap};
|
||||||
|
file->implicit_imports = {pctx->heap};
|
||||||
|
file->module->all_loaded_files.add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(global_implicit_load) file->global_implicit_load = true;
|
if(global_implicit_load) {
|
||||||
|
file->global_implicit_load = true;
|
||||||
|
module->implicit_loads.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -611,6 +618,17 @@ parse_load(B32 global_implicit_load){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Module *add_module(Intern_String filename);
|
||||||
|
function Ast_Module *
|
||||||
|
parse_import(B32 global_implicit_import){
|
||||||
|
Token *file = token_expect(TK_StringLit);
|
||||||
|
Ast_Module *result = add_module(file->intern_val);
|
||||||
|
if(global_implicit_import){
|
||||||
|
pctx->currently_parsed_file->module->implicit_imports.add(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Needs peeking only because I didn't want to duplicate code
|
Needs peeking only because I didn't want to duplicate code
|
||||||
for parsing statements and it makes code nicer.
|
for parsing statements and it makes code nicer.
|
||||||
@@ -648,6 +666,11 @@ parse_decl(B32 is_global){
|
|||||||
result = ast_file_namespace(tname, file, tname->intern_val);
|
result = ast_file_namespace(tname, file, tname->intern_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(token_match_pound(pctx->intern("import"_s))){
|
||||||
|
Ast_Module *module = parse_import(false);
|
||||||
|
result = ast_module_namespace(tname, module, tname->intern_val);
|
||||||
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
Ast_Expr *expr = parse_expr();
|
Ast_Expr *expr = parse_expr();
|
||||||
result = ast_const(tname, tname->intern_val, expr);
|
result = ast_const(tname, tname->intern_val, expr);
|
||||||
|
|||||||
@@ -319,6 +319,17 @@ _search_for_decl(Ast_Scope *scope, Intern_String name){
|
|||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
For(scope->implicit_loads){
|
||||||
|
Ast_Decl *result = _search_for_decl(it, name);
|
||||||
|
if(result) return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
For(scope->implicit_imports){
|
||||||
|
Ast_Decl *result = _search_for_decl(it, name);
|
||||||
|
if(result) return result;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,15 +343,7 @@ search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!result && !is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)){
|
if(!result && !is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)){
|
||||||
For(scope->file->module->files){
|
result = _search_for_decl(scope->file->module, name);
|
||||||
if(scope->file != it){
|
|
||||||
// If parsing the scope can be invalid
|
|
||||||
if(it->scope == 0 && pctx->currently_parsed_file != 0) continue;
|
|
||||||
if(it->global_implicit_load == false) continue;
|
|
||||||
result = _search_for_decl(it->scope, name);
|
|
||||||
if(result) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -647,7 +650,7 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
|||||||
Ast_Scope *scope = context ? context : node->parent_scope;
|
Ast_Scope *scope = context ? context : node->parent_scope;
|
||||||
Search_Flag flag = context ? SEARCH_ONLY_CURRENT_SCOPE : 0;
|
Search_Flag flag = context ? SEARCH_ONLY_CURRENT_SCOPE : 0;
|
||||||
Ast_Decl *decl = resolve_name(scope, node->pos, ident->intern_val, flag);
|
Ast_Decl *decl = resolve_name(scope, node->pos, ident->intern_val, flag);
|
||||||
if(decl->kind == AST_FILE_NAMESPACE){
|
if(decl->kind == AST_FILE_NAMESPACE || decl->kind == AST_MODULE_NAMESPACE){
|
||||||
assert(next);
|
assert(next);
|
||||||
return resolve_field_access(next, decl->scope);
|
return resolve_field_access(next, decl->scope);
|
||||||
}
|
}
|
||||||
@@ -675,7 +678,7 @@ function Operand
|
|||||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||||
assert(is_flag_set(ast->flags, AST_EXPR));
|
assert(is_flag_set(ast->flags, AST_EXPR));
|
||||||
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_FILE_NAMESPACE);
|
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_FILE);
|
||||||
|
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
|
|
||||||
@@ -962,6 +965,7 @@ resolve_decl(Ast_Decl *ast){
|
|||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AST_MODULE_NAMESPACE:
|
||||||
CASE(FILE_NAMESPACE, File_Namespace){
|
CASE(FILE_NAMESPACE, File_Namespace){
|
||||||
unused(node);
|
unused(node);
|
||||||
BREAK();
|
BREAK();
|
||||||
|
|||||||
Reference in New Issue
Block a user