From ca63883f78321dd1d4fbfa2c8547d88bb4aa0aa8 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 5 May 2024 02:43:27 -0400 Subject: [PATCH] TYPE_KINDs macro swappable with codegen/gen_src.cpp --- codegen/ast_kinds.hpp | 2 +- codegen/gen_src.cpp | 159 +++++++++++++++++++++++++++++++++++-- codegen/gencpp/gen.dep.hpp | 2 +- codegen/type_kinds.hpp | 132 ++++++++++++++++++++++++++++++ 4 files changed, 288 insertions(+), 7 deletions(-) diff --git a/codegen/ast_kinds.hpp b/codegen/ast_kinds.hpp index 70c234acf..1f9f206f5 100644 --- a/codegen/ast_kinds.hpp +++ b/codegen/ast_kinds.hpp @@ -1,5 +1,5 @@ /* -Ast_KINDS swap content +AST_KINDS swap content These are not to be used directly. They are parsed by gen_src.cpp Everything within the Ast_Kinds region has a specific format pair: diff --git a/codegen/gen_src.cpp b/codegen/gen_src.cpp index b57b28a44..2896a86b9 100644 --- a/codegen/gen_src.cpp +++ b/codegen/gen_src.cpp @@ -125,6 +125,33 @@ Array get_odin_ast_kinds() return kinds; } +Array get_odin_type_kinds() +{ + local_persist Array types = Array::init_reserve(GlobalAllocator, kilobytes(64)); + { + local_persist s32 done_once = 0; + if (done_once) + return types; + ++ done_once; + } + + CodeBody ast_types_header = parse_file( path_codegen "type_kinds.hpp" ); + for ( Code code = ast_types_header.begin(); code != ast_types_header.end(); ++ code ) switch (code->Type) + { + case ECode::Comment: + case ECode::Preprocess_Pragma: + // Ignore + continue; + + case ECode::Typedef: + case ECode::Struct: + { + types.append(code); + } + } + return types; +} + int gen_main() { gen::init(); @@ -134,6 +161,7 @@ int gen_main() PreprocessorDefines.append( get_cached_string(str_GB_STATIC_ASSERT) ); // Remove TOKEN_KINDS usage in tokenizer.cpp + // Note this doesn't account for an already swapped file. Make sure to discard changes or shut this path off if already generated. if (1) { CSV_Object csv_nodes; @@ -203,9 +231,9 @@ int gen_main() continue; } - Builder header = Builder::open( path_src "tokenizer.cpp" ); - header.print(body); - header.write(); + Builder src = Builder::open( path_src "tokenizer.cpp" ); + src.print(body); + src.write(); format_file( path_src "tokenizer.cpp" ); } @@ -241,7 +269,10 @@ int gen_main() case ECode::Untyped: if (code->Content.starts_with(txt("AST_KINDS"))) - break; + continue; + + body.append(code); + continue; case ECode::Enum: { @@ -358,9 +389,127 @@ int gen_main() } // Remove TYPE_KINDS usage in types.cpp - if (0) + // Note this doesn't account for an already swapped file. Make sure to discard changes or shut this path off if already generated. + if (1) { + CodeBody src_types_cpp = parse_file( path_src "types.cpp" ); + CodeBody body = def_body( ECode::Global_Body ); + body.append( def_comment(txt("NOTICE(github: Ed94): This is a generated variant of types.cpp using /codegen/gen_src.cpp"))); + body.append(fmt_newline); + + Array type_kinds = get_odin_type_kinds(); + + for (Code code = src_types_cpp.begin(); code != src_types_cpp.end(); ++ code) switch (code->Type) + { + case ECode::Preprocess_Define: + { + if ( code->Name.starts_with( txt("TYPE_KINDS"))) { + // Skip, we don't want it. + continue; + } + if ( code->Name.starts_with( txt("TYPE_KIND"))) { + // Skip the next 3 definitions + ++ code; + ++ code; + continue; + } + body.append(code); + } + continue; + + case ECode::Enum: + { + if ( code->Name.starts_with( txt("TypeKind"))) + { + CodeBody swap_body = def_body( ECode::Enum_Body); + { + swap_body.append( code_str(Type_Invalid, )); + { + for (Code type : type_kinds) + swap_body.append( untyped_str( String::fmt_buf(GlobalAllocator, "Type_%S,", type->Name ))); + swap_body.append( code_str(Type_COUNT)); + } + CodeEnum swapped_enum = code.cast().duplicate(); + swapped_enum->Body = swap_body; + body.append(swapped_enum); + } + } + else + body.append(code); + } + continue; + + case ECode::Variable: + { + if (code->Name.starts_with(txt("type_strings"))) + { + // Swap with generated table + String generated_table = String::make_reserve(GlobalAllocator, kilobytes(32)); + { + for (Code type : type_kinds) + generated_table.append(token_fmt("type", (StrC)type->Name, stringize( + { cast(u8 *) "", gb_size_of("") -1 }, + ))); + } + CodeVar swapped_table = code.cast().duplicate(); + swapped_table->Value = code_fmt( "types", (StrC)generated_table, stringize( + { + {cast(u8 *)"invalid node", gb_size_of("invalid node")},\n + + })); + body.append(swapped_table); + body.append(fmt_newline); + // Right after is where the struct definitions were defined, we'll insert them here + body.append(def_pragma(txt("region TYPE_KINDS"))); + body.append(fmt_newline); + for (Code type : type_kinds) + { + Code def = type.duplicate(); + def->Name = get_cached_string( String::fmt_buf(GlobalAllocator, "Type%S", type->Name)); + body.append( def ); + body.append(fmt_newline); + } + body.append(def_pragma(txt("endregion TYPE_KINDS"))); + continue; + } + body.append(code); + } + continue; + + case ECode::Struct: + { + CodeStruct code_struct = code.cast(); + if ( String::are_equal(code->Name, txt("Type"))) + for (Code type_code : code_struct->Body) switch (type_code->Type) + { + case ECode::Union: + { + // Swap out the union's contents with the generated member definitions + CodeBody body_swap = def_body(ECode::Union_Body); + for (Code type : type_kinds) + body_swap.append( parse_variable( token_fmt( "name", (StrC)type->Name, stringize( + Type ; + )))); + type_code->Body = rcast(AST*, body_swap.ast); + } + break; + default: + continue; + } + body.append(code); + } + continue; + + default: + body.append(code); + continue; + } + + Builder src = Builder::open( path_src "types.cpp" ); + src.print(body); + src.write(); + format_file( path_src "types.cpp" ); } // gen::deinit(); diff --git a/codegen/gencpp/gen.dep.hpp b/codegen/gencpp/gen.dep.hpp index cf2d6d5c0..e4ccd5534 100644 --- a/codegen/gencpp/gen.dep.hpp +++ b/codegen/gencpp/gen.dep.hpp @@ -2155,7 +2155,7 @@ struct String static bool are_equal( String lhs, StrC rhs ) { - if ( lhs.length() != (rhs.Len - 1) ) + if ( lhs.length() != (rhs.Len) ) return false; for ( sw idx = 0; idx < lhs.length(); ++idx ) diff --git a/codegen/type_kinds.hpp b/codegen/type_kinds.hpp index e69de29bb..83bd4b674 100644 --- a/codegen/type_kinds.hpp +++ b/codegen/type_kinds.hpp @@ -0,0 +1,132 @@ +/* +TYPE_KINDS swap content +These are not to be used directly. They are parsed by gen_src.cpp +*/ + +typedef BasicType Basic; + +struct Named { + String name; + Type *base; + Entity *type_name; /* Entity_TypeName */ +}; + +struct Generic { + i64 id; + String name; + Type *specialized; + Scope *scope; + Entity *entity; +}; + +struct Pointer { + Type *elem; +}; + +struct MultiPointer { + Type *elem; +}; + +struct Array { + Type *elem; + i64 count; + Type *generic_count; +}; + +struct EnumeratedArray { + Type *elem; + Type *index; + ExactValue *min_value; + ExactValue *max_value; + i64 count; + TokenKind op; + bool is_sparse; +}; + +struct Slice { + Type *elem; +}; + +struct DynamicArray { + Type *elem; +}; + +struct Map { + Type *key; + Type *value; + Type *lookup_result_type; + Type *debug_metadata_type; +}; + +typedef TypeStruct Struct; +typedef TypeUnion Union; + +struct Enum { + Array fields; + Ast *node; + Scope *scope; + Type *base_type; + ExactValue *min_value; + ExactValue *max_value; + isize min_value_index; + isize max_value_index; +}; + +struct Tuple { + Slice variables; /* Entity_Variable */ + i64 *offsets; + BlockingMutex mutex; /* for settings offsets */ + bool are_offsets_being_processed; + bool are_offsets_set; + bool is_packed; +}; + +typedef TypeProc Proc; + +struct BitSet { + Type *elem; + Type *underlying; + i64 lower; + i64 upper; + Ast *node; +}; + +struct SimdVector { + i64 count; + Type *elem; + Type *generic_count; +}; + +struct RelativePointer { + Type *pointer_type; + Type *base_integer; +}; + +struct RelativeMultiPointer { + Type *pointer_type; + Type *base_integer; +}; + +struct Matrix { + Type *elem; + i64 row_count; + i64 column_count; + Type *generic_row_count; + Type *generic_column_count; + i64 stride_in_bytes; + bool is_row_major; +}; + +struct BitField { + Scope *scope; + Type *backing_type; + Slice fields; + String *tags; /*count == fields.count*/ + Slice bit_sizes; + Slice bit_offsets; + Ast *node; +}; + +struct SoaPointer { + Type* elem; +};