Parsing complete mostly, ordering, resolving, C++ tests
This commit is contained in:
208
common.c
208
common.c
@@ -5,26 +5,10 @@ clamp_top_s64(S64 val, S64 max){
|
||||
return val;
|
||||
}
|
||||
|
||||
function SizeU
|
||||
clamp_top_sizeu(SizeU val, SizeU max){
|
||||
if(val>max)return max;
|
||||
return val;
|
||||
}
|
||||
|
||||
function SizeU
|
||||
get_align_offset(SizeU size, SizeU align){
|
||||
SizeU mask = align - 1;
|
||||
SizeU val = size & mask;
|
||||
if(val){
|
||||
val = align - val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function SizeU
|
||||
align_up(SizeU size, SizeU align){
|
||||
SizeU result = size + get_align_offset(size, align);
|
||||
return result;
|
||||
function SizeU
|
||||
max_sizeu(SizeU a, SizeU b){
|
||||
if(a>b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
function U64
|
||||
@@ -37,6 +21,26 @@ hash_fnv(String string) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
function U64
|
||||
hash_u64(U64 x) {
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= x >> 32;
|
||||
return x;
|
||||
}
|
||||
|
||||
function U64
|
||||
hash_ptr(const void *ptr) {
|
||||
return hash_u64((uintptr_t)ptr);
|
||||
}
|
||||
|
||||
function U64
|
||||
hash_mix(U64 x, U64 y) {
|
||||
x ^= y;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= x >> 32;
|
||||
return x;
|
||||
}
|
||||
|
||||
function U64
|
||||
is_pow2(U64 x) {
|
||||
assert(x != 0);
|
||||
@@ -96,6 +100,166 @@ string_to_lower(Arena *arena, String string){
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Per Vognsen's like Map to pointers
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct Map_Key_Val{
|
||||
U64 key;
|
||||
void *value;
|
||||
}Map_Key_Val;
|
||||
|
||||
typedef struct Map{
|
||||
Map_Key_Val *data;
|
||||
int len;
|
||||
int cap;
|
||||
}Map;
|
||||
|
||||
function void map_insert_u64(Map *map, U64 key, void *val);
|
||||
function int max_int(int a, int b);
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
function void
|
||||
map_grow(Map *map, int new_size){
|
||||
new_size = max_int(16, new_size);
|
||||
assert(new_size > map->cap);
|
||||
assert(is_pow2(new_size));
|
||||
Map new_map = {
|
||||
.data = calloc(new_size, sizeof(Map_Key_Val)),
|
||||
.cap = new_size,
|
||||
};
|
||||
for(int i = 0; i < map->cap; i++){
|
||||
if(map->data[i].key){
|
||||
map_insert_u64(&new_map, map->data[i].key, map->data[i].value);
|
||||
}
|
||||
}
|
||||
if(map->data) free(map->data);
|
||||
*map = new_map;
|
||||
}
|
||||
|
||||
function void
|
||||
map_insert_u64(Map *map, U64 key, void *val){
|
||||
assert(val);
|
||||
if(key == 0) key++;
|
||||
if((2*map->len) + 1 > map->cap){
|
||||
map_grow(map, 2*map->cap);
|
||||
}
|
||||
U64 hash = hash_u64(key);
|
||||
U64 index = wrap_around_pow2(hash, map->cap);
|
||||
U64 i = index;
|
||||
for(;;){
|
||||
if(map->data[i].key == 0){
|
||||
map->len++;
|
||||
map->data[i].key = key;
|
||||
map->data[i].value = val;
|
||||
return;
|
||||
}
|
||||
else if(map->data[i].key == key){
|
||||
map->data[i].value = val;
|
||||
return;
|
||||
}
|
||||
|
||||
i = wrap_around_pow2(i+1, map->cap);
|
||||
if(i == map->cap){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function void *
|
||||
map_get_u64(Map *map, U64 key){
|
||||
if(map->len == 0) return 0;
|
||||
if(key == 0) key++;
|
||||
U64 hash = hash_u64(key);
|
||||
U64 index = wrap_around_pow2(hash, map->cap);
|
||||
U64 i = index;
|
||||
for(;;){
|
||||
if(map->data[i].key == key){
|
||||
return map->data[i].value;
|
||||
}
|
||||
else if(map->data[i].key == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = wrap_around_pow2(i+1, map->cap);
|
||||
if(i == map->cap){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function void *
|
||||
map_get(Map *map, void *pointer){
|
||||
return map_get_u64(map, (U64)pointer);
|
||||
}
|
||||
|
||||
function void
|
||||
map_insert(Map *map, void *key, void *value){
|
||||
map_insert_u64(map, (U64)key, value);
|
||||
}
|
||||
|
||||
function void
|
||||
map_test(){
|
||||
Map map = {0};
|
||||
const SizeU size = 1025;
|
||||
for(SizeU i = 1; i < size; i++){
|
||||
map_insert_u64(&map, i, (void *)i);
|
||||
}
|
||||
for(SizeU i = 1; i < size; i++){
|
||||
SizeU val = (SizeU)map_get_u64(&map, i);
|
||||
assert(val == i);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Array
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct Array_Head{
|
||||
int cap, len;
|
||||
}Array_Head;
|
||||
|
||||
#define array_get_head(x) (((Array_Head *)(x)) - 1)
|
||||
#define array_cap(x) array_get_head(x)->cap
|
||||
#define array_len(x) array_get_head(x)->len
|
||||
#define array_push(arr,i) (array_grow((void **)&arr, sizeof(arr[0])), (arr)[array_len(arr)++] = (i))
|
||||
#define array_init(arr,cap) array__init((void **)&arr,sizeof(arr[0]), cap)
|
||||
|
||||
|
||||
function void
|
||||
array__init(void **array, SizeU sizeof_item, int cap){
|
||||
Array_Head *head = malloc(sizeof_item*cap + sizeof(Array_Head));
|
||||
head->cap = cap;
|
||||
head->len = 0;
|
||||
*array = head + 1;
|
||||
}
|
||||
|
||||
function void
|
||||
array_grow(void **array, SizeU sizeof_item){
|
||||
if(*array == 0){
|
||||
array__init(array, sizeof_item, 16);
|
||||
}
|
||||
else if(array_len(*array) + 1 > array_cap(*array)){
|
||||
Array_Head *head = array_get_head(*array);
|
||||
SizeU len = head->len;
|
||||
SizeU cap = head->cap * 2;
|
||||
head = realloc(head, sizeof_item*cap + sizeof(Array_Head));
|
||||
head->cap = cap;
|
||||
head->len = len;
|
||||
*array = head + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
array_test(){
|
||||
int *array = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
array_push(array, i);
|
||||
}
|
||||
for(int i = 0; i < 100; i++){
|
||||
assert(array[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String interning
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -195,3 +359,7 @@ intern_test(){
|
||||
intern_string(&table, lit("No_Thing"))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user