From 391df593a26ab8c42141d74282172ce8c5e71737 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 11 Feb 2023 10:32:11 +0100 Subject: [PATCH] Trying to do some code generation --- core_compiler.cpp | 293 +++++++++++++++++++++++++++++------- core_compiler.h | 1 + core_compiler_interface.hpp | 2 +- core_typechecking.cpp | 5 +- 4 files changed, 240 insertions(+), 61 deletions(-) diff --git a/core_compiler.cpp b/core_compiler.cpp index f8aa511..0d31e58 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -272,6 +272,15 @@ add_module(Token *pos, Intern_String filename, B32 command_line_module, bool str return result; } +CORE_Static Ast_File * +custom_parse_string(String string) { + Ast_Module *module = pctx->custom_module; + Ast_File *file = get(&module->all_loaded_files, 0); + file->filecontent = string; + parse_file(file); + return file; +} + CORE_Static void resolve_everything_in_module(Ast_Module *module) { if (module->state == MODULE_RESOLVED) @@ -292,10 +301,12 @@ resolve_everything_in_module(Ast_Module *module) { CORE_Static void init_language_core() { - { - Ast_Module *module = add_module(0, pctx->intern("Language.core"_s), false, true); - get(&module->all_loaded_files, 0)->filecontent = - R"( + pctx->custom_module = add_module(0, pctx->intern("Custom.core"_s), false, true); + pctx->custom_module->state = MODULE_RESOLVED; + + Ast_Module *module = add_module(0, pctx->intern("Language.core"_s), false, true); + get(&module->all_loaded_files, 0)->filecontent = + R"( Any :: struct data: *void type: Type @@ -360,62 +371,229 @@ GetTypeInfo :: (type: Type): *Type_Info return type_infos + id )"_s; - { - insert_builtin_type_into_scope(module, "S64"_s, pctx->type_s64); - insert_builtin_type_into_scope(module, "S32"_s, pctx->type_s32); - insert_builtin_type_into_scope(module, "S16"_s, pctx->type_s16); - insert_builtin_type_into_scope(module, "S8"_s, pctx->type_s8); - insert_builtin_type_into_scope(module, "int"_s, pctx->type_int); - insert_builtin_type_into_scope(module, "char"_s, pctx->type_char); - insert_builtin_type_into_scope(module, "U64"_s, pctx->type_u64); - insert_builtin_type_into_scope(module, "U32"_s, pctx->type_u32); - insert_builtin_type_into_scope(module, "U16"_s, pctx->type_u16); - insert_builtin_type_into_scope(module, "U8"_s, pctx->type_u8); - insert_builtin_type_into_scope(module, "F64"_s, pctx->type_f64); - insert_builtin_type_into_scope(module, "F32"_s, pctx->type_f32); - insert_builtin_type_into_scope(module, "void"_s, pctx->type_void); - insert_builtin_type_into_scope(module, "Bool"_s, pctx->type_bool); - // insert_builtin_type_into_scope(module, "String"_s, pctx->type_string); - insert_builtin_type_into_scope(module, "Type"_s, pctx->type_type); + { + insert_builtin_type_into_scope(module, "S64"_s, pctx->type_s64); + insert_builtin_type_into_scope(module, "S32"_s, pctx->type_s32); + insert_builtin_type_into_scope(module, "S16"_s, pctx->type_s16); + insert_builtin_type_into_scope(module, "S8"_s, pctx->type_s8); + insert_builtin_type_into_scope(module, "int"_s, pctx->type_int); + insert_builtin_type_into_scope(module, "char"_s, pctx->type_char); + insert_builtin_type_into_scope(module, "U64"_s, pctx->type_u64); + insert_builtin_type_into_scope(module, "U32"_s, pctx->type_u32); + insert_builtin_type_into_scope(module, "U16"_s, pctx->type_u16); + insert_builtin_type_into_scope(module, "U8"_s, pctx->type_u8); + insert_builtin_type_into_scope(module, "F64"_s, pctx->type_f64); + insert_builtin_type_into_scope(module, "F32"_s, pctx->type_f32); + insert_builtin_type_into_scope(module, "void"_s, pctx->type_void); + insert_builtin_type_into_scope(module, "Bool"_s, pctx->type_bool); + // insert_builtin_type_into_scope(module, "String"_s, pctx->type_string); + insert_builtin_type_into_scope(module, "Type"_s, pctx->type_type); + } + + { + Ast_Scope *scope = ast_decl_scope(&pctx->null_token, pctx->perm, get(&module->all_loaded_files, 0)); + Ast_Decl * decl = ast_namespace(&pctx->null_token, scope, pctx->intern("Const"_s)); + decl->state = DECL_RESOLVED; + + Value v1 = {}; + v1.type = pctx->untyped_string; + v1.intern_val = pctx->intern(OS_NAME); + Ast_Decl *const_os1 = ast_const(&pctx->null_token, pctx->intern("OSName"_s), v1); + const_os1->state = DECL_RESOLVED; + insert_into_scope(scope, const_os1); + + Value v2 = {}; + v1.type = pctx->untyped_string; + v1.intern_val = pctx->intern(OS_NAME_LOWER); + Ast_Decl *const_os2 = ast_const(&pctx->null_token, pctx->intern("OSNameLower"_s), v2); + const_os2->state = DECL_RESOLVED; + insert_into_scope(scope, const_os2); + + insert_into_scope(module, decl); + } + + pctx->language_base_module = module; + + parse_all_modules(); + resolve_everything_in_module(module); + + // @note: language stuff needs to be declared before type_info data + // so we mark where it ends + pctx->base_language_ordered_decl_len = length(&pctx->ordered_decls); + Ast_Decl *any_decl = search_for_single_decl(module, pctx->intern("Any"_s)); + assert(any_decl->type == pctx->type_type); + pctx->type_any = any_decl->type_val; + + Ast_Decl *string_decl = search_for_single_decl(module, pctx->intern("String"_s)); + assert(string_decl->type == pctx->type_type); + pctx->type_string = string_decl->type_val; +} + +typedef void Ast_Visit_Callback(Ast *ast); +// @todo: We are traversing the modules multiple times cause they can have multiple connections, need to add visit id +void ast_list_rewrite_callback(Ast *ast) { + switch(ast->kind) { + CASE(CALL, Call) { + if (node->name->kind == AST_IDENT) { + Ast_Atom *ident = (Ast_Atom *)node->name; + if (pctx->intern("List_Insert"_s) == ident->intern_val) { + Ast_Decl *list_insert = search_for_single_decl(pctx->custom_module, pctx->intern("List_Insert"_s), false); + if (!list_insert) { + custom_parse_string(R"( +List_Insert :: (list: List, node: Node) + if list.first == 0 + list.first = node + list.last = node + else + list.last.next = node + list.last = node + )"_s); + list_insert = search_for_single_decl(pctx->custom_module, pctx->intern("List_Insert"_s), false); + } + assert(list_insert); + } + } + BREAK(); } + } +} - { - Ast_Scope *scope = ast_decl_scope(&pctx->null_token, pctx->perm, get(&module->all_loaded_files, 0)); - Ast_Decl * decl = ast_namespace(&pctx->null_token, scope, pctx->intern("Const"_s)); - decl->state = DECL_RESOLVED; +void ast_visit(uint32_t visit_id, Ast_Visit_Callback *callback, Ast *ast) { + if (!ast) return; - Value v1 = {}; - v1.type = pctx->untyped_string; - v1.intern_val = pctx->intern(OS_NAME); - Ast_Decl *const_os1 = ast_const(&pctx->null_token, pctx->intern("OSName"_s), v1); - const_os1->state = DECL_RESOLVED; - insert_into_scope(scope, const_os1); - - Value v2 = {}; - v1.type = pctx->untyped_string; - v1.intern_val = pctx->intern(OS_NAME_LOWER); - Ast_Decl *const_os2 = ast_const(&pctx->null_token, pctx->intern("OSNameLower"_s), v2); - const_os2->state = DECL_RESOLVED; - insert_into_scope(scope, const_os2); - - insert_into_scope(module, decl); + callback(ast); + switch(ast->kind) { + CASE(MODULE, Module) { + if (node->visit_id == visit_id) return; + node->visit_id = visit_id; + For(node->decls) ast_visit(visit_id, callback, it); + For(node->implicit_imports) ast_visit(visit_id, callback, it); + For(node->stmts) ast_visit(visit_id, callback, it); + For(node->all_loaded_files) ast_visit(visit_id, callback, it); + BREAK(); } - - pctx->language_base_module = module; - - parse_all_modules(); - resolve_everything_in_module(module); - - // @note: language stuff needs to be declared before type_info data - // so we mark where it ends - pctx->base_language_ordered_decl_len = length(&pctx->ordered_decls); - Ast_Decl *any_decl = search_for_single_decl(module, pctx->intern("Any"_s)); - assert(any_decl->type == pctx->type_type); - pctx->type_any = any_decl->type_val; - - Ast_Decl *string_decl = search_for_single_decl(module, pctx->intern("String"_s)); - assert(string_decl->type == pctx->type_type); - pctx->type_string = string_decl->type_val; + CASE(FILE, File) { + if (node->visit_id == visit_id) return; + node->visit_id = visit_id; + For(node->decls) ast_visit(visit_id, callback, it); + For(node->implicit_imports) ast_visit(visit_id, callback, it); + For(node->stmts) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(SCOPE, Scope) { + if (node->visit_id == visit_id) return; + node->visit_id = visit_id; + For(node->decls) ast_visit(visit_id, callback, it); + For(node->implicit_imports) ast_visit(visit_id, callback, it); + For(node->stmts) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(LAMBDA, Decl){ + Ast_Lambda *lambda = node->lambda; + For(lambda->ret) ast_visit(visit_id, callback, it); + For(lambda->args) ast_visit(visit_id, callback, it); + ast_visit(visit_id, callback, node->typespec); + ast_visit(visit_id, callback, node->scope); + ast_visit(visit_id, callback, lambda->scope); + BREAK(); + } + CASE(CONST, Decl){ + ast_visit(visit_id, callback, node->expr); + ast_visit(visit_id, callback, node->typespec); + ast_visit(visit_id, callback, node->scope); + BREAK(); + } + CASE(VAR, Decl){ + ast_visit(visit_id, callback, node->expr); + ast_visit(visit_id, callback, node->typespec); + ast_visit(visit_id, callback, node->scope); + BREAK(); + } + case AST_NAMESPACE: + CASE(ENUM, Decl){ + ast_visit(visit_id, callback, node->typespec); + For(node->scope->decls) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(INDEX, Index) { + ast_visit(visit_id, callback, node->expr); + ast_visit(visit_id, callback, node->index); + BREAK(); + } + CASE(STRUCT, Decl) { + // @todo + BREAK(); + } + CASE(ARRAY, Array) { + ast_visit(visit_id, callback, node->base); + ast_visit(visit_id, callback, node->expr); + BREAK(); + } + CASE(BINARY, Binary) { + ast_visit(visit_id, callback, node->left); + ast_visit(visit_id, callback, node->right); + BREAK(); + } + CASE(VAR_UNPACK, Var_Unpack) { + For(node->vars) ast_visit(visit_id, callback, it); + ast_visit(visit_id, callback, node->expr); + BREAK(); + } + CASE(UNARY, Unary) { + ast_visit(visit_id, callback, node->expr); + BREAK(); + } + case AST_COMPOUND: + CASE(CALL, Call){ + ast_visit(visit_id, callback, node->name); // @union + For(node->exprs) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(CALL_ITEM, Call_Item){ + ast_visit(visit_id, callback, node->item); + ast_visit(visit_id, callback, node->name); // @union + BREAK(); + } + case AST_CONSTANT_ASSERT: + CASE(RUNTIME_ASSERT, Builtin){ + ast_visit(visit_id, callback, node->expr); + BREAK(); + } + CASE(RETURN, Return){ + For(node->expr) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(FOR, For) { + ast_visit(visit_id, callback, node->init); + ast_visit(visit_id, callback, node->cond); + ast_visit(visit_id, callback, node->iter); + ast_visit(visit_id, callback, node->scope); + ast_visit(visit_id, callback, node->array_traversal_var); + BREAK(); + } + CASE(IF, If) { + For(node->ifs) ast_visit(visit_id, callback, it); + BREAK(); + } + CASE(IF_NODE, If_Node) { + ast_visit(visit_id, callback, node->expr); + ast_visit(visit_id, callback, node->scope); + ast_visit(visit_id, callback, node->init); + BREAK(); + } + CASE(SWITCH_CASE, Switch_Case) { + For(node->labels) ast_visit(visit_id, callback, it); + ast_visit(visit_id, callback, node->scope); + BREAK(); + } + CASE(SWITCH, Switch) { + ast_visit(visit_id, callback, node->value); + For(node->cases) ast_visit(visit_id, callback, it); + ast_visit(visit_id, callback, node->default_scope); + BREAK(); + } + case AST_VALUE: case AST_IDENT: case AST_PASS: case AST_BREAK: break; + invalid_default_case; } } @@ -430,10 +608,9 @@ compile_file_to_string(Allocator *allocator, String filename) { Ast_Module *module = add_module(0, pctx->intern(filename), true); parse_all_modules(); assert(module); + resolve_everything_in_module(module); - - pctx->stage_arena->len = 0; String result = compile_to_c_code(); pctx->time.total = os_time() - pctx->time.total; diff --git a/core_compiler.h b/core_compiler.h index 5ef0e50..e6322a8 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -41,6 +41,7 @@ struct Core_Ctx{ U64 unique_ids; // @Debug Map type_map; + Ast_Module *custom_module; Ast_Module *language_base_module; List files; diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index 2fe7c60..d0bce28 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -399,7 +399,7 @@ struct Ast_Atom: Ast_Expr{ Ast_Decl *resolved_decl; union { bool bool_val; - double f64_val; + double f64_val; Intern_String intern_val; BigInt big_int_val; Ast_Type *type_val; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index e749adc..8bab5dc 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -501,7 +501,7 @@ make_scope_search(Allocator *arena, Ast_Scope *scope, Intern_String name){ } CORE_Static Ast_Decl * -search_for_single_decl(Ast_Scope *scope, Intern_String name){ +search_for_single_decl(Ast_Scope *scope, Intern_String name, bool error_if_no_matches = true){ Arena *scratch = pctx->scratch; Scratch_Scope _scope(scratch); @@ -509,7 +509,8 @@ search_for_single_decl(Ast_Scope *scope, Intern_String name){ scope_search(&search); if(search.results.len == 0){ - compiler_error(0, "Unidentified name [%s]", name.str); + if (error_if_no_matches) compiler_error(0, "Unidentified name [%s]", name.str); + return 0; } if(search.results.len > 1){ compiler_error(search.results.data[0]->pos, search.results.data[1]->pos, "Found multiple definitions of name [%s]", name.str);