Types, Fixed personal arena

This commit is contained in:
Krzosa Karol
2022-05-13 22:02:55 +02:00
parent ea0b1c352d
commit d993623a50
4 changed files with 197 additions and 13 deletions

View File

@@ -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<T> copy(Allocator *a){
Array<T> 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();

View File

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

View File

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

153
new_type.cpp Normal file
View File

@@ -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<Type*> 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<Type *> 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<Type*> 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<Type*> 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);
}