Trying to do some code generation

This commit is contained in:
Krzosa Karol
2023-02-11 10:32:11 +01:00
parent 27d9ad3ddc
commit 391df593a2
4 changed files with 240 additions and 61 deletions

View File

@@ -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,7 +301,9 @@ resolve_everything_in_module(Ast_Module *module) {
CORE_Static void
init_language_core() {
{
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"(
@@ -416,6 +427,173 @@ GetTypeInfo :: (type: Type): *Type_Info
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();
}
}
}
void ast_visit(uint32_t visit_id, Ast_Visit_Callback *callback, Ast *ast) {
if (!ast) return;
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();
}
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;

View File

@@ -41,6 +41,7 @@ struct Core_Ctx{
U64 unique_ids; // @Debug
Map type_map;
Ast_Module *custom_module;
Ast_Module *language_base_module;
List<Ast_File *> files;

View File

@@ -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);