Change the decl searching api while figuring out how to implement

function overloading
This commit is contained in:
Krzosa Karol
2022-09-29 12:04:21 +02:00
parent a7524a0071
commit 5f11a11f0f
9 changed files with 113 additions and 53 deletions

View File

@@ -38,7 +38,9 @@ api F32 absolute(F32 value) {
return value; return value;
} }
api S32 square(S32 val) { return val * val; } api S32 square(S32 val) {
return val * val;
}
api S32 clamp01(S32 val) { api S32 clamp01(S32 val) {
S32 result = clamp(0, val, 1); S32 result = clamp(0, val, 1);

View File

@@ -227,10 +227,12 @@ How does current declaration order resolver works:
*/ */
struct Ast_Scope: Ast{ struct Ast_Scope: Ast{
String debug_name; // Dont use
Array<Ast_Scope *> implicit_imports; Array<Ast_Scope *> implicit_imports;
Array<Ast_Decl *> decls; Array<Ast_Decl *> decls;
Array<Ast *> stmts; Array<Ast *> stmts;
U32 visit_id;
U32 scope_id; U32 scope_id;
Ast_Scope *file; // Self referential for scope and module Ast_Scope *file; // Self referential for scope and module
Ast_Module *module; Ast_Module *module;
@@ -264,7 +266,7 @@ enum Ast_Decl_State{
struct Ast_Decl: Ast{ struct Ast_Decl: Ast{
Ast_Decl_State state; Ast_Decl_State state;
Intern_String name; Intern_String name;
Intern_String unique_name; // For code generation Intern_String unique_name; // For code generation, currently only present on lambdas
Ast_Scope *scope; Ast_Scope *scope;
Ast_Expr *typespec; Ast_Expr *typespec;
@@ -463,6 +465,7 @@ begin_decl_scope(Allocator *scratch, Token *pos){
result->file = pctx->currently_parsed_file; result->file = pctx->currently_parsed_file;
result->module = pctx->currently_parsed_file->module; result->module = pctx->currently_parsed_file->module;
result->scope_id = pctx->scope_ids++; result->scope_id = pctx->scope_ids++;
result->debug_name = pos->string;
assert(result->file); assert(result->file);
pctx->currently_parsed_scope = result; pctx->currently_parsed_scope = result;
return result; return result;
@@ -482,6 +485,7 @@ begin_stmt_scope(Allocator *scratch, Token *pos){
result->file = pctx->currently_parsed_file; result->file = pctx->currently_parsed_file;
result->module = pctx->currently_parsed_file->module; result->module = pctx->currently_parsed_file->module;
result->scope_id = pctx->scope_ids++; result->scope_id = pctx->scope_ids++;
result->debug_name = pos->string;
assert(result->file); assert(result->file);
pctx->currently_parsed_scope = result; pctx->currently_parsed_scope = result;
return result; return result;
@@ -547,6 +551,7 @@ ast_decl_scope(Token *pos, Allocator *allocator, Ast_File *file){
AST_NEW(Scope, SCOPE, pos, AST_DECL); AST_NEW(Scope, SCOPE, pos, AST_DECL);
result->decls = {allocator}; result->decls = {allocator};
result->file = file; result->file = file;
result->scope_id = pctx->scope_ids++; result->scope_id = pctx->scope_ids++;
assert(result->file); assert(result->file);
return result; return result;

View File

@@ -123,6 +123,7 @@ add_module(Token *pos, Intern_String filename, B32 command_line_module){
Ast_Module *result = ast_new(Ast_Module, AST_MODULE, pos, 0); Ast_Module *result = ast_new(Ast_Module, AST_MODULE, pos, 0);
result->absolute_file_path = string_copy(pctx->perm, absolute_file_path); result->absolute_file_path = string_copy(pctx->perm, absolute_file_path);
result->absolute_base_folder = string_copy(pctx->perm, absolute_base_folder); result->absolute_base_folder = string_copy(pctx->perm, absolute_base_folder);
result->debug_name = string_skip_to_last_slash(result->absolute_file_path);
// log_info("Adding module: %Q\n", filename); // log_info("Adding module: %Q\n", filename);
result->module = result; // @warning: self referential result->module = result; // @warning: self referential
result->file = result; // @warning: self referential result->file = result; // @warning: self referential
@@ -170,7 +171,7 @@ compile_file_to_string(String filename){
// @note: language stuff needs to be declared before type_info data // @note: language stuff needs to be declared before type_info data
// so we mark where it ends // so we mark where it ends
pctx->base_language_ordered_decl_len = pctx->ordered_decls.len; pctx->base_language_ordered_decl_len = pctx->ordered_decls.len;
Ast_Decl *any_decl = search_for_decl(module, pctx->intern("Any"_s)); Ast_Decl *any_decl = search_for_single_decl(module, pctx->intern("Any"_s));
assert(any_decl->type == type_type); assert(any_decl->type == type_type);
type_any = any_decl->type_val; type_any = any_decl->type_val;
} }

View File

@@ -201,6 +201,7 @@ struct Parse_Ctx:Lexer{
Ast_Scope *currently_parsed_scope; Ast_Scope *currently_parsed_scope;
Ast_File *currently_parsed_file; Ast_File *currently_parsed_file;
U32 scope_ids; U32 scope_ids;
U32 scope_visit_id;
Array<String> module_folders; Array<String> module_folders;
String module_folder; String module_folder;

View File

@@ -1,15 +1,12 @@
/* /*
- [ ] Basic - [ ] Basic
- [ ] Idea to fix overshoot when debugging and it goes to the - [ ] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly?
close bracket and there is not enough line directives.
- Store the last outputed line and propagate it on the close brace etc.
- [ ] Detecting if return was called - [ ] Detecting if return was called
- [ ] Fix . operator lookups - [ ] '.' Operator doesn't handle expressions inside the dot chain, no good, so casts don't work
- [ ] Combining casts with . operator - [ ] Combining casts with . operator
- [ ] Builtin data structures - [ ] Builtin data structures
- [ ] Fix Length etc. they should be function calls not operators
- [ ] Strings probably should have len() instead of string.len - [ ] Strings probably should have len() instead of string.len
- [ ] Slices - [ ] Slices
- [ ] Some way to take slice of data - [ ] Some way to take slice of data
@@ -18,7 +15,6 @@
- [ ] Hash tables - [ ] Hash tables
- [ ] C Codegen - [ ] C Codegen
- [ ] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
- [ ] Programming constructs - [ ] Programming constructs
- [ ] Defer statement - [ ] Defer statement
@@ -135,6 +131,9 @@ For modules it's a bit different cause they should be distributed as valid.
## Done ## Done
- [x] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
- [x] Fix Length etc. they should be function calls not operators
- [x] Idea to fix overshoot when debugging and it goes to the close bracket and there is not enough line directives. Store the last outputed line and propagate it on the close brace etc.
- [x] Disable .len for Strings, are there other things that use this convention? - [x] Disable .len for Strings, are there other things that use this convention?
- [x] Calculate size and alignment of struct data types - [x] Calculate size and alignment of struct data types
- [x] Consider changing syntax of scopes to use braces { } NO - [x] Consider changing syntax of scopes to use braces { } NO

View File

@@ -751,6 +751,7 @@ register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32
file->decls = {pctx->heap}; file->decls = {pctx->heap};
file->implicit_imports = {pctx->heap}; file->implicit_imports = {pctx->heap};
file->pos = pos; file->pos = pos;
file->debug_name = string_skip_to_last_slash(absolute_file_path);
file->module->all_loaded_files.add(file); file->module->all_loaded_files.add(file);
file->scope_id = pctx->scope_ids++; file->scope_id = pctx->scope_ids++;
pctx->files.add(file); pctx->files.add(file);
@@ -891,6 +892,10 @@ parse_file(Ast_File *file){
continue; continue;
} }
if(!file->pos){
file->pos = token_get();
}
Ast_Decl *decl = parse_decl(true); Ast_Decl *decl = parse_decl(true);
if(!decl) break; if(!decl) break;

View File

@@ -409,46 +409,104 @@ _rewrite_into_const(Ast *node, U64 ast_size, Value value){
ast->resolved_type = value.type; ast->resolved_type = value.type;
} }
function Ast_Decl * struct Scope_Search {
_search_for_decl(Ast_Scope *scope, Intern_String name, S32 level){ Array<Ast_Decl *> results;
Intern_String name;
Ast_Scope *scope;
bool exit_on_find;
bool search_only_current_scope;
U32 scope_visit_id;
};
function void
inside_scope_search(Scope_Search *search, Ast_Scope *scope, int level){
if(scope->visit_id == search->scope_visit_id) return;
scope->visit_id = search->scope_visit_id;
// Search for declarations in current scope
For(scope->decls){ For(scope->decls){
if(it->name == name){ if(it->name == search->name){
return it; search->results.add(it);
if(search->exit_on_find){
return;
}
} }
} }
For(scope->implicit_imports){ // Search for declarations in imported implicitly scopes
Ast_Decl *result = 0; if(level < 2 || scope->kind != AST_FILE){
if(scope->kind != AST_MODULE || level < 2) For(scope->implicit_imports){
result = _search_for_decl(it, name, level+1); inside_scope_search(search, it, level + 1);
if(result) return result;
}
return 0; if(search->exit_on_find && search->results.len){
return;
}
}
}
} }
function Ast_Decl * function void
search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){ scope_search(Scope_Search *search){
Ast_Decl *result = 0; // Climb the scope tree and search each scope in module and also
// search in implicitly imported scopes
Ast_Scope *scope = search->scope;
for(Ast_Scope *it = scope; it; it=it->parent_scope){ for(Ast_Scope *it = scope; it; it=it->parent_scope){
result = _search_for_decl(it, name, 0); inside_scope_search(search, it, 0);
if(result) break;
if(is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)) break;
}
if(!result && !is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)){ if(search->exit_on_find && search->results.len){
result = _search_for_decl(scope->module, name, 0); return;
}
if(search->search_only_current_scope){
return;
}
} }
inside_scope_search(search, scope->module, 0);
}
function Scope_Search
make_scope_search(Arena *arena, Ast_Scope *scope, Intern_String name){
Scope_Search result = {};
result.results.allocator = arena;
result.name = name;
result.scope_visit_id = ++pctx->scope_visit_id;
result.scope = scope;
result.exit_on_find = true;
return result; return result;
} }
function Ast_Decl * function Ast_Decl *
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){ search_for_single_decl(Ast_Scope *scope, Intern_String name){
Ast_Decl *decl = search_for_decl(scope, name, search_flags); Scratch scratch;
if(!decl) { Scope_Search search = make_scope_search(scratch, scope, name);
compiler_error(pos, "Unidentified name [%s]", name.str); scope_search(&search);
if(search.results.len == 0){
compiler_error(0, "Unidentified name [%s]", name.str);
}
if(search.results.len > 1){
compiler_error(0, "Found multiple definitions of name [%s]", name.str);
} }
return search.results.data[0];
}
function Ast_Decl *
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){
Scratch scratch;
Scope_Search search = make_scope_search(scratch, scope, name);
search.search_only_current_scope = search_flags & SEARCH_ONLY_CURRENT_SCOPE;
scope_search(&search);
if(search.results.len == 0){
compiler_error(pos, "Unidentified name [%s]", name.str);
}
if(search.results.len > 1){
compiler_error(pos, "Found multiple definitions of name [%s]", name.str);
}
Ast_Decl *decl = *search.results.data;
resolve_decl(decl); resolve_decl(decl);
return decl; return decl;
} }
@@ -460,11 +518,14 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
// //
// It's also called when scanning top level declarations of a module // It's also called when scanning top level declarations of a module
// as such we probably don't want to call any resolve stuff here // as such we probably don't want to call any resolve stuff here
Ast_Decl *find = search_for_decl(scope, decl->name); Scratch scratch;
if(find){ Scope_Search search = make_scope_search(scratch, scope, decl->name);
// if(find->kind != AST_LAMBDA) search.search_only_current_scope = true;
compiler_error(find->pos, decl->pos, "[%s] is already defined", decl->name.str); scope_search(&search);
if(search.results.len != 0){
compiler_error(search.results.data[0]->pos, decl->pos, "[%s] is already defined", decl->name.str);
} }
scope->decls.add(decl); scope->decls.add(decl);
} }

View File

@@ -2,8 +2,8 @@
struct Operand{ struct Operand{
INLINE_VALUE_FIELDS; INLINE_VALUE_FIELDS;
Ast_Decl *resolved_decl; Ast_Decl *resolved_decl;
U8 is_const : 1; U8 is_const : 1;
U8 is_lvalue: 1; U8 is_lvalue : 1;
U8 pound_strict: 1; U8 pound_strict: 1;
}; };

View File

@@ -50,20 +50,6 @@ Vec3_Add :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.
Vec3_Div :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x/b.x, a.y/b.y, a.z/b.z} Vec3_Div :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x/b.x, a.y/b.y, a.z/b.z}
Vec3_Sub :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x-b.x, a.y-b.y, a.z-b.z} Vec3_Sub :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x-b.x, a.y-b.y, a.z-b.z}
/*
@todo: Add function overloading
Current plan:
* allow insert_into_scope to insert multiple lambdas
* change resolve_name and search_for_decl to something
that can seek multiple lambda declarations
resolve them and return a match to hash or type
* change the order of lambda call resolution, probably would have to
hash the arguments first to match the lambda call
*/
// Add :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.z}
// Add :: (a: Vec2, b: Vec2): Vec2 ;; return Vec2{a.x+b.x, a.y+b.y}
F32_Clamp :: (min: F32, value: F32, max: F32): F32 F32_Clamp :: (min: F32, value: F32, max: F32): F32
if value > max;; return max if value > max;; return max
if value < min;; return min if value < min;; return min