Add .hash to integer types. Fixup of make and tmake. Updated map.c3 to become a working example. Fix bug in subarray -> pointer conversion. Search extension methods in std::core. Fix slice <-> slice copy.

This commit is contained in:
Christoffer Lerno
2022-09-21 10:08:37 +02:00
committed by Christoffer Lerno
parent 4d5821408d
commit ad18d9ba48
18 changed files with 836 additions and 108 deletions

97
resources/examples/map.c3 Normal file
View File

@@ -0,0 +1,97 @@
module std::container::map <Key, Type>;
import std::core::builtin;
import std::io;
fault MapResult
{
KEY_NOT_FOUND
}
struct Entry
{
Key key;
Type value;
usize hash;
Entry* next;
bool used;
}
struct Map
{
usize size;
Entry* map;
uint mod;
}
/**
* @require map != null
**/
fn void Map.init(Map *map, uint capacity = 128)
{
if (capacity < 16) capacity = 4;
capacity = math::next_power_of_2(capacity);
map.map = calloc(Entry.sizeof * capacity);
map.mod = capacity - 1;
}
fn Type! Map.valueForKey(Map *map, Key key)
{
if (!map.map) return MapResult.KEY_NOT_FOUND!;
uint hash = key.hash();
usize pos = hash & map.mod;
Entry* entry = &map.map[pos];
if (!entry) return MapResult.KEY_NOT_FOUND!;
while (entry)
{
if (entry.hash == hash && entry.key == key) return entry.value;
entry = entry.next;
}
return MapResult.KEY_NOT_FOUND!;
}
fn Type! Map.set(Map *map, Key key, Type value) @maydiscard
{
if (!map.map)
{
map.map = calloc(Entry.sizeof * 16);
map.mod = 0x0F;
}
uint hash = key.hash();
uint pos = hash & map.mod;
Entry *entry = &map.map[pos];
while (1)
{
if (!entry.used)
{
entry.used = true;
entry.value = value;
entry.hash = hash;
entry.key = key;
return MapResult.KEY_NOT_FOUND!;
}
if (entry.hash == hash && entry.key == key)
{
Type old = entry.value;
entry.value = value;
return old;
}
if (entry.next)
{
entry = entry.next;
continue;
}
Entry* new = mem::calloc(Entry.sizeof);
new.hash = hash;
new.key = key;
new.value = value;
new.next = null;
new.used = true;
entry.next = new;
return MapResult.KEY_NOT_FOUND!;
}
}
fn usize Map.size(Map* map)
{
return map.size;
}

View File

@@ -1,87 +0,0 @@
module std::container::map <Key, Type>;
fault MapResult
{
KEY_NOT_FOUND
}
public struct Entry
{
Key key;
Type value;
usize hash;
Entry* next;
}
public struct Map
{
usize size;
void* map;
uint mod;
Allocator allocator;
}
/**
* @require map != null
**/
public fn void Map.init(Map *map, Allocator allocator)
{
map.allocator = allocator;
}
public fn Type! Map.valueForKey(Map *map, Key key)
{
if (!map.map) return null;
usize hash = key.hash();
usize pos = hash & map.mod;
Entry* entry = &map.map[pop];
if (!entry) return MapResult.KEY_NOT_FOUND!;
while (entry)
{
if (entry.hash == hash && entry.key == key) return entry.value;
entry = entry.next;
}
return MapResult.KEY_NOT_FOUND!;
}
public fn Type *Map.set(Map *map, Key key, Type value)
{
if (!map.map)
{
map.map = allocator.calloc(Entry, 16);
map.mod = 0x0F;
}
usize hash = key.hash();
usize pos = hash & map.mod;
Entry *entry = &map.map[pop];
while (1)
{
if (!entry.value)
{
entry.value = value;
entry.hash = hash;
entry.key = key;
return nil;
}
if (entry.hash == hash && entry.key == key)
{
Type *old = entry.value;
entry.value = value;
return old;
}
if (entry.next)
{
entry = entry.next;
}
entry.next = allocator.alloc(Entry);
entry = entry.next;
}
}
public fn usize Map.size(Map* map)
{
return map.size;
}