diff --git a/base_math.cpp b/base_math.cpp index b9d57fb..3f7a18c 100644 --- a/base_math.cpp +++ b/base_math.cpp @@ -38,7 +38,9 @@ api F32 absolute(F32 value) { return value; } -api S32 square(S32 val) { return val * val; } +api S32 square(S32 val) { + return val * val; +} api S32 clamp01(S32 val) { S32 result = clamp(0, val, 1); diff --git a/core_ast.cpp b/core_ast.cpp index 0a03ea2..71471b4 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -227,10 +227,12 @@ How does current declaration order resolver works: */ struct Ast_Scope: Ast{ + String debug_name; // Dont use Array implicit_imports; Array decls; Array stmts; + U32 visit_id; U32 scope_id; Ast_Scope *file; // Self referential for scope and module Ast_Module *module; @@ -264,7 +266,7 @@ enum Ast_Decl_State{ struct Ast_Decl: Ast{ Ast_Decl_State state; 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_Expr *typespec; @@ -463,6 +465,7 @@ begin_decl_scope(Allocator *scratch, Token *pos){ result->file = pctx->currently_parsed_file; result->module = pctx->currently_parsed_file->module; result->scope_id = pctx->scope_ids++; + result->debug_name = pos->string; assert(result->file); pctx->currently_parsed_scope = result; return result; @@ -482,6 +485,7 @@ begin_stmt_scope(Allocator *scratch, Token *pos){ result->file = pctx->currently_parsed_file; result->module = pctx->currently_parsed_file->module; result->scope_id = pctx->scope_ids++; + result->debug_name = pos->string; assert(result->file); pctx->currently_parsed_scope = result; return result; @@ -547,6 +551,7 @@ ast_decl_scope(Token *pos, Allocator *allocator, Ast_File *file){ AST_NEW(Scope, SCOPE, pos, AST_DECL); result->decls = {allocator}; result->file = file; + result->scope_id = pctx->scope_ids++; assert(result->file); return result; diff --git a/core_compiler.cpp b/core_compiler.cpp index e77789d..c48bfac 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -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); result->absolute_file_path = string_copy(pctx->perm, absolute_file_path); 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); result->module = 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 // so we mark where it ends 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); type_any = any_decl->type_val; } diff --git a/core_compiler.h b/core_compiler.h index ec54f34..db2d65d 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -201,6 +201,7 @@ struct Parse_Ctx:Lexer{ Ast_Scope *currently_parsed_scope; Ast_File *currently_parsed_file; U32 scope_ids; + U32 scope_visit_id; Array module_folders; String module_folder; diff --git a/core_main.cpp b/core_main.cpp index 84b13cb..2544c80 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -1,15 +1,12 @@ /* - [ ] Basic - - [ ] 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. + - [ ] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly? - [ ] 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 - [ ] Builtin data structures - - [ ] Fix Length etc. they should be function calls not operators - [ ] Strings probably should have len() instead of string.len - [ ] Slices - [ ] Some way to take slice of data @@ -18,7 +15,6 @@ - [ ] Hash tables - [ ] C Codegen - - [ ] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable - [ ] Programming constructs - [ ] Defer statement @@ -135,6 +131,9 @@ For modules it's a bit different cause they should be distributed as valid. ## 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] Calculate size and alignment of struct data types - [x] Consider changing syntax of scopes to use braces { } NO diff --git a/core_parsing.cpp b/core_parsing.cpp index cfceb62..c1c3904 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -751,6 +751,7 @@ register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32 file->decls = {pctx->heap}; file->implicit_imports = {pctx->heap}; file->pos = pos; + file->debug_name = string_skip_to_last_slash(absolute_file_path); file->module->all_loaded_files.add(file); file->scope_id = pctx->scope_ids++; pctx->files.add(file); @@ -891,6 +892,10 @@ parse_file(Ast_File *file){ continue; } + if(!file->pos){ + file->pos = token_get(); + } + Ast_Decl *decl = parse_decl(true); if(!decl) break; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index f5177d8..7b74272 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -409,46 +409,104 @@ _rewrite_into_const(Ast *node, U64 ast_size, Value value){ ast->resolved_type = value.type; } -function Ast_Decl * -_search_for_decl(Ast_Scope *scope, Intern_String name, S32 level){ +struct Scope_Search { + Array 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){ - if(it->name == name){ - return it; + if(it->name == search->name){ + search->results.add(it); + if(search->exit_on_find){ + return; + } } } - For(scope->implicit_imports){ - Ast_Decl *result = 0; - if(scope->kind != AST_MODULE || level < 2) - result = _search_for_decl(it, name, level+1); - if(result) return result; - } + // Search for declarations in imported implicitly scopes + if(level < 2 || scope->kind != AST_FILE){ + For(scope->implicit_imports){ + inside_scope_search(search, it, level + 1); - return 0; + if(search->exit_on_find && search->results.len){ + return; + } + } + } } -function Ast_Decl * -search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){ - Ast_Decl *result = 0; +function void +scope_search(Scope_Search *search){ + // 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){ - result = _search_for_decl(it, name, 0); - if(result) break; - if(is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)) break; - } + inside_scope_search(search, it, 0); - if(!result && !is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)){ - result = _search_for_decl(scope->module, name, 0); + if(search->exit_on_find && search->results.len){ + 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; } function Ast_Decl * -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); +search_for_single_decl(Ast_Scope *scope, Intern_String name){ + Scratch scratch; + Scope_Search search = make_scope_search(scratch, scope, name); + 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); 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 // as such we probably don't want to call any resolve stuff here - Ast_Decl *find = search_for_decl(scope, decl->name); - if(find){ - // if(find->kind != AST_LAMBDA) - compiler_error(find->pos, decl->pos, "[%s] is already defined", decl->name.str); + Scratch scratch; + Scope_Search search = make_scope_search(scratch, scope, decl->name); + search.search_only_current_scope = true; + 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); } diff --git a/core_typechecking.h b/core_typechecking.h index b0ab1ab..17147af 100644 --- a/core_typechecking.h +++ b/core_typechecking.h @@ -2,8 +2,8 @@ struct Operand{ INLINE_VALUE_FIELDS; Ast_Decl *resolved_decl; - U8 is_const : 1; - U8 is_lvalue: 1; + U8 is_const : 1; + U8 is_lvalue : 1; U8 pound_strict: 1; }; diff --git a/modules/math.kl b/modules/math.kl index 3716ccd..da81c21 100644 --- a/modules/math.kl +++ b/modules/math.kl @@ -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_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 if value > max;; return max if value < min;; return min