From d993623a50064b3445248055d71e4e906bd6a933 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 13 May 2022 22:02:55 +0200 Subject: [PATCH] Types, Fixed personal arena --- main.cpp | 55 ++++++++++++++---- new_ast.cpp | 1 + new_parse.cpp | 1 - new_type.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 13 deletions(-) create mode 100644 new_type.cpp diff --git a/main.cpp b/main.cpp index bd5dc11..961ba86 100644 --- a/main.cpp +++ b/main.cpp @@ -29,11 +29,10 @@ typedef double F64; #define mib(x) (kib(x)*1024llu) #define gib(x) (mib(x)*1024llu) struct String{U8 *str;S64 len;}; -union Intern_String{ - String s; - struct{ U8 *str; S64 len; }; -}; +union Intern_String{ String s; struct{ U8 *str; S64 len; }; }; // Basically just String +#define JOIN1(X,Y) X##Y // helper macro +#define JOIN(X,Y) JOIN1(X,Y) //----------------------------------------------------------------------------- // Utilities //----------------------------------------------------------------------------- @@ -287,6 +286,11 @@ struct Arena:Allocator{ OS_Memory memory; SizeU alignment; SizeU len; + + // Personal arena memes so we can compute correct size when resizing + // Also a pointer so that we can make sure it didn't change + SizeU old_size; + void *debug_prev_pointer; }; function void arena_init(Arena *arena, String debug_name); @@ -347,7 +351,24 @@ force_inline void * personal_arena_allocator_proc(Allocator *a, Allocation_Kind kind, void *old_pointer, SizeU size){ Arena *arena = (Arena *)a; arena->alignment = 1; - return arena_allocator_proc(a, kind, old_pointer, size); + + void *result = 0; + switch(kind){ + case Allocation_Resize: { + assert(arena->old_size); + assert(arena->old_size < size); + assert(arena->debug_prev_pointer == old_pointer); + result = arena_push_size(arena, size - arena->old_size); + result = old_pointer; + } break; + default: { + result = arena_allocator_proc(a, kind, old_pointer, size); + arena->debug_prev_pointer = result; + } + } + + arena->old_size = size; + return result; } function void @@ -447,8 +468,8 @@ report__file_and_line(const char *file, int line){ //----------------------------------------------------------------------------- // Implicit scratch stack //----------------------------------------------------------------------------- -#define Set_Scratch() Scoped_Scratch scratch_##__LINE__ -#define Set_Backup_Scratch() Scoped_Scratch scratch_##__LINE__(true) +#define Set_Scratch() Scoped_Scratch JOIN(scratch, __LINE__) +#define Set_Backup_Scratch() Scoped_Scratch JOIN(scratch, __LINE__)(true) struct Scoped_Scratch{ SizeU saved_pos; Allocator *saved_allocator; @@ -470,7 +491,7 @@ struct Scoped_Scratch{ //----------------------------------------------------------------------------- // Implicit allocator stack //----------------------------------------------------------------------------- -#define Set_Allocator(a) Scoped_Allocator scoped_##__LINE__(a) +#define Set_Allocator(a) Scoped_Allocator JOIN(scoped,__LINE__)(a) struct Scoped_Allocator{ Allocator *allocator; Scoped_Allocator(Allocator *a){ @@ -492,7 +513,7 @@ thread_ctx_get_user_ctx(U64 id){ } #define Get_Ctx(T) T *ctx = (T *)thread_ctx_get_user_ctx(T##_ID) -#define Set_Ctx(ctx, id) Scoped_Ctx scoped_ctx_##__LINE__((void *)ctx, id) +#define Set_Ctx(ctx, id) Scoped_Ctx JOIN(scoped_ctx, __LINE__)((void *)ctx, id) struct Scoped_Ctx{ void *prev_ctx; U64 prev_id; @@ -699,7 +720,6 @@ test_custom_context(){ assert(thread_ctx.ctx == 0); } - //----------------------------------------------------------------------------- // Defer // http://www.gingerbill.org/article/2015/08/19/defer-in-cpp/ @@ -757,6 +777,16 @@ struct Array{ len = 0; } + Array copy(Allocator *a){ + Array result = {}; + result.len = len; + result.cap = len; + result.allocator = 0; + result.data = exp_alloc_array(a, T, len); + memory_copy(result.data, data, sizeof(T)*len); + return result; + } + T *begin(){ return data; } T *end (){ return data + len; } T &operator[](S64 i){ return data[i]; } @@ -1089,17 +1119,18 @@ test_intern_table(){ Set_Scratch(); #include "new_lex.cpp" #include "new_ast.cpp" #include "new_parse.cpp" +#include "new_type.cpp" int main(){ test_custom_context(); test_heap_allocator(); test_os_memory(); thread_ctx_init(); - map_test(); - + test_types(); test_parse_decl(); test_parse_expr(); + map_test(); test_array(); test_string_builder(); test_intern_table(); diff --git a/new_ast.cpp b/new_ast.cpp index f84d96d..d0c6733 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -16,6 +16,7 @@ struct Parse_Ctx:Lexer{ Token empty_token; S64 indent; S64 pt[256]; // precedence table + Map type_map; void init(){ const S64 addp = 1; diff --git a/new_parse.cpp b/new_parse.cpp index 67f5a91..0bc164a 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -244,4 +244,3 @@ test_parse_decl(){ lex_restream(&ctx, "thing := 24252\nanother_thing := \"string\"\n\nref := thing"_s, "test_parse_decl"_s); Ast_Package *result = parse_file(); } - diff --git a/new_type.cpp b/new_type.cpp new file mode 100644 index 0000000..1e8cd39 --- /dev/null +++ b/new_type.cpp @@ -0,0 +1,153 @@ + +enum Type_Kind{ + TYPE_None, + TYPE_Int, + TYPE_String, + TYPE_Void, + TYPE_Pointer, + TYPE_Array, + TYPE_Func, + TYPE_Struct, + TYPE_Union, + TYPE_Enum, +}; + +struct Type{ + Type_Kind kind; + SizeU size; + SizeU align; + union{ + Type *base; + struct{ + Type *base; + SizeU size; + }arr; + struct{ + Type *ret; + Array args; + }func; + }; +}; + +const SizeU pointer_size = sizeof(SizeU); +const SizeU pointer_align = __alignof(SizeU); + +global Type type__void = {TYPE_Void}; +global Type type__int = {TYPE_Int, sizeof(int), __alignof(int)}; +global Type type__string = {TYPE_String, sizeof(String), __alignof(String)}; + +global Type *type_void = &type__void; +global Type *type_int = &type__int; +global Type *type_string = &type__string; + +function Type * +type_new(Allocator *allocator, Type_Kind kind, SizeU size, SizeU align){ + Type *result = exp_alloc_type(allocator, Type); + result->kind = kind; + result->size = size; + result->align = align; + return result; +} + +function Type * +type_copy(Allocator *a, Type *type){ + Type *result = exp_alloc_type(a, Type); + memory_copy(result, type, sizeof(Type)); + return result; +} + +function Type * +type_pointer(Type *base){ + Get_Ctx(Parse_Ctx); + Type *result = (Type *)map_get(&ctx->type_map, (void *)base); + if(!result){ + result = type_new(&ctx->ast_arena, TYPE_Pointer, pointer_size, pointer_align); + result->base = base; + map_insert(&ctx->type_map, base, result); + } + assert(result->kind == TYPE_Pointer); + return result; +} + +function Type * +type_array(Type *base, SizeU size){ + Get_Ctx(Parse_Ctx); + U64 hash = hash_mix(hash_ptr(base), hash_u64(size)); + Type *result = (Type *)map_get_u64(&ctx->type_map, hash); + if(result){ + assert(result->kind == TYPE_Array); + assert(result->arr.size == size); + assert(result->arr.base == base); + return result; + } + + result = type_new(&ctx->ast_arena, TYPE_Array, pointer_size, pointer_align); + result->arr.base = base; + result->arr.size = size; + map_insert_u64(&ctx->type_map, hash, result); + return result; +} + +function Type * +type_function(Type *ret, Array args){ + Get_Ctx(Parse_Ctx); + + U64 hash = hash_ptr(ret); + IFor(args){ + hash = hash_mix(hash, hash_ptr(*it)); + } + + Type *result = (Type *)map_get_u64(&ctx->type_map, hash); + if(result){ + assert(result->kind == TYPE_Func); + assert(result->func.ret == ret); + assert(result->func.args.len == args.len); + return result; + } + result = type_new(&ctx->ast_arena, TYPE_Func, pointer_size, pointer_align); + result->func.ret = ret; + result->func.args = args.copy(&ctx->ast_arena); + map_insert_u64(&ctx->type_map, hash, result); + + return result; +} + +function void +test_types(){ + Set_Backup_Scratch(); + Set_Scratch(); + Parse_Ctx ctx = {}; + Set_Ctx(&ctx, Parse_Ctx_ID); + ctx.ast_arena = thread_ctx.scratch[1]; + + Type *array_type1 = type_array(type_int, 32); + Type *array_type2 = type_array(type_int, 32); + Type *array_type3 = type_array(type_int, 48); + assert(array_type1 == array_type2); + assert(array_type2 != array_type3); + Type *pointer_type1 = type_pointer(type_int); + Type *pointer_type2 = type_pointer(type_int); + assert(pointer_type2 == pointer_type1); + Type *pointer_type3 = type_pointer(pointer_type1); + Type *pointer_type4 = type_pointer(pointer_type2); + assert(pointer_type3 != pointer_type1); + assert(pointer_type3 == pointer_type4); + + Array types = {}; + types.add(type_array(type_int, 32)); + Type *func_type1 = type_function(types[0], types); + Type *func_type2 = type_function(types[0], types); + assert(func_type1 == func_type2); + + Array types2 = {}; + { + types2.add(type_array(type_int, 32)); + types2.add(type_int); + } + types.add(type_int); + Type *func_type3 = type_function(types[0], types); + Type *func_type4 = type_function(types[0], types2); + assert(func_type1 != func_type3); + assert(func_type3 == func_type4); +} +